@uva-glass/component-library 3.53.9 → 3.53.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/{chunk-MDLQUVZN-BSRMHXbx.js → chunk-MDLQUVZN-Dk02kWJ8.js} +2 -5
  2. package/dist/{chunk-MDLQUVZN-BSRMHXbx.js.map → chunk-MDLQUVZN-Dk02kWJ8.js.map} +1 -1
  3. package/dist/{client-DdSuZDnt.js → client-3XNwBsl7.js} +43 -111
  4. package/dist/{client-DdSuZDnt.js.map → client-3XNwBsl7.js.map} +1 -1
  5. package/dist/components/Accordion/Accordion.test.js +3 -3
  6. package/dist/components/AccordionCard/AccordionCard.test.js +3 -3
  7. package/dist/components/ActionList/ActionList.test.js +3 -3
  8. package/dist/components/AppStatusBar/AppStatusBar.test.js +2 -2
  9. package/dist/components/Attention/Attention.test.js +2 -2
  10. package/dist/components/Backdrop/Backdrop.test.js +2 -2
  11. package/dist/components/Buttons/Button.stories.js +1 -1
  12. package/dist/components/Buttons/Button.test.js +2 -2
  13. package/dist/components/Buttons/LinkButton.stories.js +1 -1
  14. package/dist/components/Buttons/LinkButton.test.js +2 -2
  15. package/dist/components/Buttons/MenuButton.stories.js +1 -1
  16. package/dist/components/Buttons/MenuButton.test.js +2 -2
  17. package/dist/components/Card/Card.test.js +2 -2
  18. package/dist/components/Checkbox/Checkbox.stories.js +1 -1
  19. package/dist/components/Checkbox/Checkbox.test.js +3 -3
  20. package/dist/components/CheckboxButtonBar/CheckboxButtonBar.stories.js +1 -1
  21. package/dist/components/CheckboxButtonBar/CheckboxButtonBar.test.js +2 -2
  22. package/dist/components/CheckboxTree/CheckboxTree.stories.js +2 -2
  23. package/dist/components/Chip/Chip.stories.js +1 -1
  24. package/dist/components/ControlsButton/ControlsButton.stories.js +1 -1
  25. package/dist/components/Drawer/Drawer.stories.js +1 -1
  26. package/dist/components/FeedbackBar/FeedbackBar.test.js +2 -2
  27. package/dist/components/FormInput/FormInput.stories.js +1 -1
  28. package/dist/components/IconButton/IconButton.stories.js +1 -1
  29. package/dist/components/InputField/InputField.stories.js +1 -1
  30. package/dist/components/Label/Label.test.js +2 -2
  31. package/dist/components/MetaDataBar/MetaDataBar.test.js +1 -1
  32. package/dist/components/ModalDialog/ModalDialog.stories.js +1 -1
  33. package/dist/components/MultiSelect/MultiSelect.stories.js +1 -1
  34. package/dist/components/MultiSelectBox/MultiSelectBox.stories.js +1 -1
  35. package/dist/components/MultiSelectBox/MultiSelectBox.test.js +2 -2
  36. package/dist/components/Notification/Notification.stories.js +1 -1
  37. package/dist/components/Notification/Notification.test.js +2 -2
  38. package/dist/components/OverlayCloseButton/OverlayCloseButton.stories.js +1 -1
  39. package/dist/components/PeriodSelector/PeriodSelector.stories.js +1 -1
  40. package/dist/components/ProgrammeCard/ProgrammeCard.js.map +1 -1
  41. package/dist/components/RadioGroup/RadioGroup.stories.js +1 -1
  42. package/dist/components/RadioGroup/Radiogroup.test.js +2 -2
  43. package/dist/components/RadioTabSelector/RadioTabSelector.stories.js +1 -1
  44. package/dist/components/RteEditor/Plugins/CourseCataloguePlugin/CourseCataloguePlugin.js +135 -125
  45. package/dist/components/RteEditor/Plugins/CourseCataloguePlugin/CourseCataloguePlugin.js.map +1 -1
  46. package/dist/components/RteEditor/RteEditor.js +215 -238
  47. package/dist/components/RteEditor/RteEditor.js.map +1 -1
  48. package/dist/components/RteEditor/translations.js +4 -4
  49. package/dist/components/RteEditor/translations.js.map +1 -1
  50. package/dist/components/SelectListbox/SelectListBox.stories.js +1 -1
  51. package/dist/components/Sortable/Sortable.stories.js +1 -1
  52. package/dist/components/StatusBadge/StatusBadge.test.js +2 -2
  53. package/dist/components/TextArea/TextArea.stories.js +1 -1
  54. package/dist/components/TextArea/TextArea.test.js +3 -3
  55. package/dist/components/ToggleSwitch/ToggleSwitch.stories.js +1 -1
  56. package/dist/components/VarIndicator/VarIndicator.stories.js +1 -1
  57. package/dist/components/VarIndicator/VarIndicator.test.js +3 -3
  58. package/dist/{index-DcECbqp4.js → index-CLNHDZVV.js} +2 -2
  59. package/dist/{index-DcECbqp4.js.map → index-CLNHDZVV.js.map} +1 -1
  60. package/dist/{index-ApPj4mI1.js → index-CULNJwuI.js} +5 -13
  61. package/dist/{index-ApPj4mI1.js.map → index-CULNJwuI.js.map} +1 -1
  62. package/dist/{index-Cfzi-sRQ.js → index-CdPMY4ux.js} +8 -19
  63. package/dist/{index-Cfzi-sRQ.js.map → index-CdPMY4ux.js.map} +1 -1
  64. package/dist/{react-18-plvLTuyc.js → react-18-D3e2aqkg.js} +2 -2
  65. package/dist/{react-18-plvLTuyc.js.map → react-18-D3e2aqkg.js.map} +1 -1
  66. package/dist/{react.esm-BpII5CMY.js → react.esm-QW7uOFDD.js} +5 -8
  67. package/dist/{react.esm-BpII5CMY.js.map → react.esm-QW7uOFDD.js.map} +1 -1
  68. package/dist/setupTests.js +1 -1
  69. package/dist/storybook__react.d.js +6 -9
  70. package/dist/storybook__react.d.js.map +1 -1
  71. package/package.json +10 -10
@@ -1,174 +1,184 @@
1
- import { jsx as p, jsxs as O } from "react/jsx-runtime";
2
- import { useState as C, useRef as L, useEffect as I } from "react";
3
- import { c as U } from "../../../../clsx-OuTLNxxd.js";
4
- import { o as W } from "../../../../LexicalComposerContext.prod-DOyoZx0P.js";
5
- import { aF as F, ah as v, c as T, b as A, p as z, _ as S, aG as X, Y as q, a7 as J, l as Q } from "../../../../Lexical.prod-Dgzi-S1E.js";
6
- import { x as E } from "../../../../LexicalUtils.prod-D1mwAww-.js";
7
- import { AddCatalogueLinkForm as Z } from "./AddCatalogueLinkForm/AddCatalogueLinkForm.js";
8
- import { s as i } from "../../../../RteEditor.module-DaBh86FK.js";
9
- import { useTranslation as tt } from "../../hooks/useTranslation.js";
10
- import { CourseCatalogueNode as g, $getLinkTypeFromNode as P, REMOVE_COURSE_CATALOGUE_LINK as et, INSERT_COURSE_CATALOGUE_LINK as ot } from "../../nodes/CourseCatalogueNode/CourseCatalogueNode.js";
11
- import { useOnClickOutside as rt } from "../../../hooks/useOnClickOutside.js";
12
- const gt = ({
13
- onSearch: D,
14
- searchResponse: G,
15
- parentScrollPosition: H
1
+ import { jsx as b, jsxs as O } from "react/jsx-runtime";
2
+ import { useState as k, useRef as _, useEffect as x } from "react";
3
+ import { c as z } from "../../../../clsx-OuTLNxxd.js";
4
+ import { o as J } from "../../../../LexicalComposerContext.prod-DOyoZx0P.js";
5
+ import { aF as I, ah as U, c as E, b as T, p as F, _ as S, aG as Q, Y as X, a7 as Z, l as ee } from "../../../../Lexical.prod-Dgzi-S1E.js";
6
+ import { x as A } from "../../../../LexicalUtils.prod-D1mwAww-.js";
7
+ import { AddCatalogueLinkForm as te } from "./AddCatalogueLinkForm/AddCatalogueLinkForm.js";
8
+ import { s as l } from "../../../../RteEditor.module-DaBh86FK.js";
9
+ import { useTranslation as oe } from "../../hooks/useTranslation.js";
10
+ import { CourseCatalogueNode as y, $getLinkTypeFromNode as P, REMOVE_COURSE_CATALOGUE_LINK as re, INSERT_COURSE_CATALOGUE_LINK as ne } from "../../nodes/CourseCatalogueNode/CourseCatalogueNode.js";
11
+ import { useOnClickOutside as se } from "../../../hooks/useOnClickOutside.js";
12
+ import { setScrollableContainers as G, removeScrollableContainers as ae } from "../../helpers.js";
13
+ const ke = ({
14
+ onSearch: v,
15
+ searchResponse: H,
16
+ parentScrollPosition: j
16
17
  }) => {
17
- const [s] = W(), c = tt(), [j, k] = C(!1), [Y, _] = C(!1), K = L(null), w = L(null), B = L(null), [b, h] = C(null), [R, M] = C("course"), y = (f) => {
18
- M(f);
19
- const u = f === "course" ? K.current?.getBoundingClientRect() : w.current?.getBoundingClientRect();
20
- u && h({ top: u.bottom + window.scrollY, left: u.left + window.scrollX });
21
- }, N = () => {
22
- D("", R), h(null);
18
+ const [s] = J(), m = oe(), [M, L] = k(!1), [V, h] = k(!1), D = _(null), K = _(null), R = _(null), [d, w] = k(null), [B, Y] = k("course"), $ = _(d !== null), C = (c) => {
19
+ Y(c);
20
+ const r = c === "course" ? D.current?.getBoundingClientRect() : K.current?.getBoundingClientRect();
21
+ r && w({ top: r.bottom, left: r.left });
22
+ }, p = () => {
23
+ v("", B), w(null);
23
24
  };
24
- return I(() => {
25
- b && N();
26
- }, [H]), I(() => {
27
- const f = s.registerCommand(
28
- F,
29
- (t) => t.ctrlKey && t.shiftKey && t.altKey && t.key === "C" ? (t.preventDefault(), y("course"), !0) : t.ctrlKey && t.shiftKey && t.altKey && t.key === "P" ? (t.preventDefault(), y("programme"), !0) : !1,
30
- v
31
- ), u = s.registerUpdateListener(({ editorState: t }) => {
32
- t.read(() => {
33
- const r = T();
34
- if (A(r)) {
35
- const e = r.anchor.getNode(), n = r.anchor.offset;
36
- if (z(e) && n === e.getTextContentSize() && e.getNextSibling() instanceof g) {
37
- const o = e.getNextSibling();
25
+ return x(() => {
26
+ const c = s.registerCommand(
27
+ I,
28
+ (e) => e.ctrlKey && e.shiftKey && e.altKey && e.key === "C" ? (e.preventDefault(), C("course"), !0) : e.ctrlKey && e.shiftKey && e.altKey && e.key === "P" ? (e.preventDefault(), C("programme"), !0) : !1,
29
+ U
30
+ ), r = s.registerUpdateListener(({ editorState: e }) => {
31
+ e.read(() => {
32
+ const n = E();
33
+ if (T(n)) {
34
+ const t = n.anchor.getNode(), a = n.anchor.offset;
35
+ if (F(t) && a === t.getTextContentSize() && t.getNextSibling() instanceof y) {
36
+ const o = t.getNextSibling();
38
37
  if (o) {
39
- const d = P(o);
40
- k(d === "course"), _(d === "programme");
38
+ const g = P(o);
39
+ L(g === "course"), h(g === "programme");
41
40
  return;
42
41
  }
43
42
  }
44
- const a = E(e, g);
45
- if (a) {
46
- const o = P(a);
47
- k(o === "course"), _(o === "programme");
43
+ const i = A(t, y);
44
+ if (i) {
45
+ const o = P(i);
46
+ L(o === "course"), h(o === "programme");
48
47
  return;
49
48
  }
50
- k(!1), _(!1);
49
+ L(!1), h(!1);
51
50
  }
52
51
  });
53
- }), m = (t) => {
54
- const r = J(), e = t.getTextContentSize();
55
- r.setTextNodeRange(t, e, t, e), Q(r);
56
- }, x = (t, r) => z(t) && r === t.getTextContentSize() && t.getNextSibling() instanceof g, $ = s.registerCommand(
57
- F,
58
- (t) => {
59
- const r = T();
60
- if (A(r)) {
61
- const e = t.key, n = r.anchor.getNode(), a = r.anchor.offset;
62
- let o = E(n, g);
63
- if (x(n, a) && (o = n.getNextSibling()), !o)
52
+ }), u = (e) => {
53
+ const n = Z(), t = e.getTextContentSize();
54
+ n.setTextNodeRange(e, t, e, t), ee(n);
55
+ }, N = (e, n) => F(e) && n === e.getTextContentSize() && e.getNextSibling() instanceof y, W = s.registerCommand(
56
+ I,
57
+ (e) => {
58
+ const n = E();
59
+ if (T(n)) {
60
+ const t = e.key, a = n.anchor.getNode(), i = n.anchor.offset;
61
+ let o = A(a, y);
62
+ if (N(a, i) && (o = a.getNextSibling()), !o)
64
63
  return !1;
65
- const d = o?.getTextContentSize();
66
- if (o && t.key === "Enter")
67
- return t.preventDefault(), s.update(() => {
68
- if (x(n, a)) {
69
- const l = S(`
64
+ const g = o?.getTextContentSize();
65
+ if (o && e.key === "Enter")
66
+ return e.preventDefault(), s.update(() => {
67
+ if (N(a, i)) {
68
+ const f = S(`
70
69
  `);
71
- o.insertBefore(l);
70
+ o.insertBefore(f);
72
71
  }
73
- if (a === d) {
74
- const l = S(`
72
+ if (i === g) {
73
+ const f = S(`
75
74
  `);
76
- o.insertAfter(l), m(l);
75
+ o.insertAfter(f), u(f);
77
76
  }
78
77
  }), !0;
79
- if (o && (e === " " || t.code === "Space"))
80
- return t.preventDefault(), s.update(() => {
81
- const l = S(" ");
82
- x(n, a) && (o.insertBefore(l), m(l)), a === d && (o.insertAfter(l), m(l));
78
+ if (o && (t === " " || e.code === "Space"))
79
+ return e.preventDefault(), s.update(() => {
80
+ const f = S(" ");
81
+ N(a, i) && (o.insertBefore(f), u(f)), i === g && (o.insertAfter(f), u(f));
83
82
  }), !0;
84
- if (o && (e === "Backspace" || e === "Delete"))
85
- return t.preventDefault(), s.update(
83
+ if (o && (t === "Backspace" || t === "Delete"))
84
+ return e.preventDefault(), s.update(
86
85
  () => {
87
- s.dispatchCommand(et, void 0);
86
+ s.dispatchCommand(re, void 0);
88
87
  },
89
88
  { discrete: !0 }
90
89
  ), !0;
91
- if (o && e !== "ArrowLeft" && e !== "ArrowRight" && e !== "ArrowUp" && e !== "ArrowDown" && e !== "Home" && e !== "End" && !(t.ctrlKey && (e.toLowerCase() === "z" || e.toLowerCase() === "y")) && !(t.ctrlKey && e.toLowerCase() === "c"))
92
- return t.preventDefault(), !0;
90
+ if (o && t !== "ArrowLeft" && t !== "ArrowRight" && t !== "ArrowUp" && t !== "ArrowDown" && t !== "Home" && t !== "End" && !(e.ctrlKey && (t.toLowerCase() === "z" || t.toLowerCase() === "y")) && !(e.ctrlKey && t.toLowerCase() === "c"))
91
+ return e.preventDefault(), !0;
93
92
  }
94
93
  return !1;
95
94
  },
96
- v
97
- ), V = s.registerCommand(
98
- X,
99
- (t) => {
100
- const r = T();
101
- if (A(r)) {
102
- const e = r.anchor.getNode(), n = E(e, g);
103
- if (n) {
104
- t.preventDefault();
105
- const a = s.getElementByKey(n.getKey());
106
- return a && (t.clipboardData?.setData("text/html", a.outerHTML), t.clipboardData?.setData("text/plain", n.getTextContent())), !0;
95
+ U
96
+ ), q = s.registerCommand(
97
+ Q,
98
+ (e) => {
99
+ const n = E();
100
+ if (T(n)) {
101
+ const t = n.anchor.getNode(), a = A(t, y);
102
+ if (a) {
103
+ e.preventDefault();
104
+ const i = s.getElementByKey(a.getKey());
105
+ return i && (e.clipboardData?.setData("text/html", i.outerHTML), e.clipboardData?.setData("text/plain", a.getTextContent())), !0;
107
106
  }
108
107
  }
109
108
  return !1;
110
109
  },
111
- q
110
+ X
112
111
  );
113
112
  return () => {
114
- f(), u(), $(), V();
113
+ c(), r(), W(), q();
114
+ };
115
+ }, [s]), se(R, () => w(null)), x(() => {
116
+ const c = (u) => (G(r), u.key === "Escape" && $.current && (u.preventDefault(), u.stopPropagation(), p()), !0);
117
+ window.addEventListener("keydown", c, { capture: !0 });
118
+ const r = () => {
119
+ p();
115
120
  };
116
- }, [s]), rt(B, () => h(null)), /* @__PURE__ */ p("div", { className: i["editor__toolbar-button-group"], children: /* @__PURE__ */ O("div", { className: i["editor__toolbar-button-flyoutwrapper"], children: [
117
- /* @__PURE__ */ O("div", { className: i["editor__toolbar-button-group--text"], children: [
118
- /* @__PURE__ */ p(
121
+ return G(r), window.addEventListener("scroll", r), window.addEventListener("resize", r), () => {
122
+ window.removeEventListener("keydown", c), window.removeEventListener("scroll", r), window.removeEventListener("resize", r), ae(r);
123
+ };
124
+ }, []), x(() => {
125
+ d && p();
126
+ }, [j]), /* @__PURE__ */ b("div", { className: l["editor__toolbar-button-group"], children: /* @__PURE__ */ O("div", { className: l["editor__toolbar-button-flyoutwrapper"], children: [
127
+ /* @__PURE__ */ O("div", { className: l["editor__toolbar-button-group--text"], children: [
128
+ /* @__PURE__ */ b(
119
129
  "button",
120
130
  {
121
- onClick: () => y("course"),
122
- title: c.cataloguelinks.courseTooltip,
123
- className: U(
124
- i["editor__toolbar-button"],
125
- i["editor__toolbar-button--text"],
126
- j && i["editor__toolbar-button--active"]
131
+ onClick: () => C("course"),
132
+ title: m.cataloguelinks.courseTooltip,
133
+ className: z(
134
+ l["editor__toolbar-button"],
135
+ l["editor__toolbar-button--text"],
136
+ M && l["editor__toolbar-button--active"]
127
137
  ),
128
- "aria-label": c.aria.labels.courselink,
129
- "aria-keyshortcuts": c.aria.keyshortcuts.courselink,
138
+ "aria-label": m.aria.labels.courselink,
139
+ "aria-keyshortcuts": m.aria.keyshortcuts.courselink,
130
140
  type: "button",
131
- ref: K,
132
- children: c.cataloguelinks.courseButtonLabel
141
+ ref: D,
142
+ children: m.cataloguelinks.courseButtonLabel
133
143
  }
134
144
  ),
135
- /* @__PURE__ */ p(
145
+ /* @__PURE__ */ b(
136
146
  "button",
137
147
  {
138
- onClick: () => y("programme"),
139
- title: c.cataloguelinks.programmeTooltip,
140
- className: U(
141
- i["editor__toolbar-button"],
142
- i["editor__toolbar-button--text"],
143
- Y && i["editor__toolbar-button--active"]
148
+ onClick: () => C("programme"),
149
+ title: m.cataloguelinks.programmeTooltip,
150
+ className: z(
151
+ l["editor__toolbar-button"],
152
+ l["editor__toolbar-button--text"],
153
+ V && l["editor__toolbar-button--active"]
144
154
  ),
145
- "aria-label": c.aria.labels.programmelink,
146
- "aria-keyshortcuts": c.aria.keyshortcuts.programmelink,
155
+ "aria-label": m.aria.labels.programmelink,
156
+ "aria-keyshortcuts": m.aria.keyshortcuts.programmelink,
147
157
  type: "button",
148
- ref: w,
149
- children: c.cataloguelinks.programmeButtonLabel
158
+ ref: K,
159
+ children: m.cataloguelinks.programmeButtonLabel
150
160
  }
151
161
  )
152
162
  ] }),
153
- b && /* @__PURE__ */ p(
163
+ d && /* @__PURE__ */ b(
154
164
  "div",
155
165
  {
156
- className: i["editor__toolbar-flyout-wrapper"],
157
- style: { top: b.top, left: b.left },
158
- ref: B,
159
- children: /* @__PURE__ */ p(
160
- Z,
166
+ className: l["editor__toolbar-flyout-wrapper"],
167
+ style: { top: d.top, left: d.left },
168
+ ref: R,
169
+ children: /* @__PURE__ */ b(
170
+ te,
161
171
  {
162
- linkType: R,
163
- onCloseHandler: N,
164
- onSearchHandler: D,
165
- searchResponse: G,
166
- onSelect: (f, u, m) => {
167
- s.dispatchCommand(ot, {
168
- linkType: m,
169
- code: f,
170
- label: u
171
- }), N();
172
+ linkType: B,
173
+ onCloseHandler: p,
174
+ onSearchHandler: v,
175
+ searchResponse: H,
176
+ onSelect: (c, r, u) => {
177
+ s.dispatchCommand(ne, {
178
+ linkType: u,
179
+ code: c,
180
+ label: r
181
+ }), p();
172
182
  }
173
183
  }
174
184
  )
@@ -177,6 +187,6 @@ const gt = ({
177
187
  ] }) });
178
188
  };
179
189
  export {
180
- gt as CourseCataloguePlugin
190
+ ke as CourseCataloguePlugin
181
191
  };
182
192
  //# sourceMappingURL=CourseCataloguePlugin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CourseCataloguePlugin.js","sources":["../../../../../src/components/RteEditor/Plugins/CourseCataloguePlugin/CourseCataloguePlugin.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\r\nimport { clsx } from 'clsx';\r\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\r\nimport {\r\n $createRangeSelection,\r\n $createTextNode,\r\n $getSelection,\r\n $isRangeSelection,\r\n $isTextNode,\r\n $setSelection,\r\n COMMAND_PRIORITY_CRITICAL,\r\n COMMAND_PRIORITY_LOW,\r\n COPY_COMMAND,\r\n KEY_DOWN_COMMAND,\r\n} from 'lexical';\r\nimport { $getNearestNodeOfType } from '@lexical/utils';\r\n\r\nimport type { RefObject } from 'react';\r\nimport type { LexicalNode, TextNode } from 'lexical';\r\nimport type { SearchResponse } from './AddCatalogueLinkForm';\r\n\r\nimport { AddCatalogueLinkForm } from './AddCatalogueLinkForm';\r\n\r\nimport styles from 'components/RteEditor/RteEditor.module.css';\r\nimport { useTranslation } from 'components/RteEditor/hooks/useTranslation';\r\nimport {\r\n $getLinkTypeFromNode,\r\n CourseCatalogueNode,\r\n INSERT_COURSE_CATALOGUE_LINK,\r\n REMOVE_COURSE_CATALOGUE_LINK,\r\n} from 'components/RteEditor/nodes/CourseCatalogueNode';\r\nimport { useOnClickOutside } from 'components/hooks/useOnClickOutside';\r\n\r\ninterface CourseCataloguePluginProps {\r\n onSearch: (query: string, linkType: 'course' | 'programme') => void;\r\n searchResponse: SearchResponse;\r\n parentScrollPosition: number;\r\n}\r\n\r\nexport const CourseCataloguePlugin = ({\r\n onSearch,\r\n searchResponse,\r\n parentScrollPosition,\r\n}: CourseCataloguePluginProps) => {\r\n const [editor] = useLexicalComposerContext();\r\n const t = useTranslation();\r\n const [courseIsActive, setCourseIsActive] = useState(false);\r\n const [programmeIsActive, setProgrammeIsActive] = useState(false);\r\n const courseButtonRef = useRef<HTMLButtonElement>(null);\r\n const programmeButtonRef = useRef<HTMLButtonElement>(null);\r\n const flyoutRef = useRef<HTMLDivElement>(null);\r\n const [flyoutPosition, setFlyoutPosition] = useState<{ top: number; left: number } | null>(null);\r\n const [type, setType] = useState<'course' | 'programme'>('course');\r\n\r\n const openFlyout = (type: 'course' | 'programme') => {\r\n setType(type);\r\n const rect =\r\n type === 'course'\r\n ? courseButtonRef.current?.getBoundingClientRect()\r\n : programmeButtonRef.current?.getBoundingClientRect();\r\n if (rect) {\r\n setFlyoutPosition({ top: rect.bottom + window.scrollY, left: rect.left + window.scrollX });\r\n }\r\n };\r\n\r\n const closeFlyout = () => {\r\n onSearch('', type);\r\n setFlyoutPosition(null);\r\n };\r\n\r\n useEffect(() => {\r\n if (flyoutPosition) {\r\n closeFlyout();\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [parentScrollPosition]);\r\n\r\n useEffect(() => {\r\n const removeKeyboardShortcut = editor.registerCommand(\r\n KEY_DOWN_COMMAND,\r\n (event: KeyboardEvent) => {\r\n if (event.ctrlKey && event.shiftKey && event.altKey && event.key === 'C') {\r\n event.preventDefault();\r\n openFlyout('course');\r\n return true;\r\n }\r\n if (event.ctrlKey && event.shiftKey && event.altKey && event.key === 'P') {\r\n event.preventDefault();\r\n openFlyout('programme');\r\n return true;\r\n }\r\n return false;\r\n },\r\n COMMAND_PRIORITY_CRITICAL\r\n );\r\n\r\n const removeStatusListener = editor.registerUpdateListener(({ editorState }) => {\r\n editorState.read(() => {\r\n const selection = $getSelection();\r\n if ($isRangeSelection(selection)) {\r\n const anchorNode = selection.anchor.getNode();\r\n const offset = selection.anchor.offset;\r\n\r\n if (\r\n $isTextNode(anchorNode) &&\r\n offset === anchorNode.getTextContentSize() &&\r\n anchorNode.getNextSibling() instanceof CourseCatalogueNode\r\n ) {\r\n // Cursor staat aan het begin van de link!\r\n const courseCatalogueLink = anchorNode.getNextSibling();\r\n if (courseCatalogueLink) {\r\n const linkType = $getLinkTypeFromNode(courseCatalogueLink);\r\n setCourseIsActive(linkType === 'course');\r\n setProgrammeIsActive(linkType === 'programme');\r\n return;\r\n }\r\n }\r\n\r\n const courseCatalogueLink = $getNearestNodeOfType(anchorNode, CourseCatalogueNode);\r\n if (courseCatalogueLink) {\r\n const linkType = $getLinkTypeFromNode(courseCatalogueLink);\r\n setCourseIsActive(linkType === 'course');\r\n setProgrammeIsActive(linkType === 'programme');\r\n return;\r\n }\r\n setCourseIsActive(false);\r\n setProgrammeIsActive(false);\r\n }\r\n });\r\n });\r\n\r\n const moveToEndOfWhiteSpace = (whiteSpace: TextNode) => {\r\n const selection = $createRangeSelection();\r\n const endOffset = whiteSpace.getTextContentSize();\r\n selection.setTextNodeRange(whiteSpace, endOffset, whiteSpace, endOffset);\r\n $setSelection(selection);\r\n };\r\n\r\n const isCursorBeforeLink = (anchorNode: LexicalNode, offset: number) =>\r\n $isTextNode(anchorNode) &&\r\n offset === anchorNode.getTextContentSize() &&\r\n anchorNode.getNextSibling() instanceof CourseCatalogueNode;\r\n\r\n const removeUnEditable = editor.registerCommand(\r\n KEY_DOWN_COMMAND,\r\n (event: KeyboardEvent) => {\r\n const selection = $getSelection();\r\n if ($isRangeSelection(selection)) {\r\n const key = event.key;\r\n const anchorNode = selection.anchor.getNode();\r\n const offset = selection.anchor.offset;\r\n let courseCatalogueLink = $getNearestNodeOfType(anchorNode, CourseCatalogueNode);\r\n\r\n // Detect if cursor is right before the link\r\n if (isCursorBeforeLink(anchorNode, offset)) {\r\n courseCatalogueLink = anchorNode.getNextSibling();\r\n }\r\n\r\n if (!courseCatalogueLink) {\r\n return false;\r\n }\r\n\r\n const nodeLength = courseCatalogueLink?.getTextContentSize();\r\n\r\n // Prevent Enter if in the middle of the link, allow only at start or end\r\n if (courseCatalogueLink && event.key === 'Enter') {\r\n event.preventDefault();\r\n editor.update(() => {\r\n if (isCursorBeforeLink(anchorNode, offset)) {\r\n const brNode = $createTextNode('\\n');\r\n courseCatalogueLink.insertBefore(brNode);\r\n }\r\n if (offset === nodeLength) {\r\n const brNode = $createTextNode('\\n');\r\n courseCatalogueLink.insertAfter(brNode);\r\n moveToEndOfWhiteSpace(brNode);\r\n }\r\n });\r\n return true;\r\n }\r\n\r\n // Allow add space before or after the link\r\n if (courseCatalogueLink && (key === ' ' || event.code === 'Space')) {\r\n event.preventDefault();\r\n editor.update(() => {\r\n const spaceToAdd = $createTextNode(' ');\r\n if (isCursorBeforeLink(anchorNode, offset)) {\r\n courseCatalogueLink.insertBefore(spaceToAdd);\r\n moveToEndOfWhiteSpace(spaceToAdd);\r\n }\r\n if (offset === nodeLength) {\r\n courseCatalogueLink.insertAfter(spaceToAdd);\r\n moveToEndOfWhiteSpace(spaceToAdd);\r\n }\r\n });\r\n return true;\r\n }\r\n\r\n // Delete link if selected and Backspace or Del is pressed\r\n if (courseCatalogueLink && (key === 'Backspace' || key === 'Delete')) {\r\n event.preventDefault();\r\n editor.update(\r\n () => {\r\n editor.dispatchCommand(REMOVE_COURSE_CATALOGUE_LINK, undefined);\r\n },\r\n { discrete: true }\r\n );\r\n return true;\r\n }\r\n\r\n // Allow Home, End and Arrow navigation\r\n if (\r\n courseCatalogueLink &&\r\n key !== 'ArrowLeft' &&\r\n key !== 'ArrowRight' &&\r\n key !== 'ArrowUp' &&\r\n key !== 'ArrowDown' &&\r\n key !== 'Home' &&\r\n key !== 'End' &&\r\n !(event.ctrlKey && (key.toLowerCase() === 'z' || key.toLowerCase() === 'y')) &&\r\n !(event.ctrlKey && key.toLowerCase() === 'c')\r\n ) {\r\n event.preventDefault();\r\n return true;\r\n }\r\n }\r\n return false;\r\n },\r\n COMMAND_PRIORITY_CRITICAL\r\n );\r\n\r\n const removeCopy = editor.registerCommand(\r\n COPY_COMMAND,\r\n (event: ClipboardEvent) => {\r\n const selection = $getSelection();\r\n if ($isRangeSelection(selection)) {\r\n const anchorNode = selection.anchor.getNode();\r\n const courseCatalogueLink = $getNearestNodeOfType(anchorNode, CourseCatalogueNode);\r\n if (courseCatalogueLink) {\r\n event.preventDefault();\r\n const domElement = editor.getElementByKey(courseCatalogueLink.getKey());\r\n if (domElement) {\r\n event.clipboardData?.setData('text/html', domElement.outerHTML);\r\n event.clipboardData?.setData('text/plain', courseCatalogueLink.getTextContent());\r\n }\r\n return true;\r\n }\r\n }\r\n return false;\r\n },\r\n COMMAND_PRIORITY_LOW\r\n );\r\n return () => {\r\n removeKeyboardShortcut();\r\n removeStatusListener();\r\n removeUnEditable();\r\n removeCopy();\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [editor]);\r\n\r\n useOnClickOutside(flyoutRef as RefObject<HTMLElement>, () => setFlyoutPosition(null));\r\n\r\n return (\r\n <div className={styles['editor__toolbar-button-group']}>\r\n <div className={styles['editor__toolbar-button-flyoutwrapper']}>\r\n <div className={styles['editor__toolbar-button-group--text']}>\r\n <button\r\n onClick={() => openFlyout('course')}\r\n title={t.cataloguelinks.courseTooltip}\r\n className={clsx(\r\n styles['editor__toolbar-button'],\r\n styles['editor__toolbar-button--text'],\r\n courseIsActive && styles[`editor__toolbar-button--active`]\r\n )}\r\n aria-label={t.aria.labels.courselink}\r\n aria-keyshortcuts={t.aria.keyshortcuts.courselink}\r\n type=\"button\"\r\n ref={courseButtonRef}\r\n >\r\n {t.cataloguelinks.courseButtonLabel}\r\n </button>\r\n <button\r\n onClick={() => openFlyout('programme')}\r\n title={t.cataloguelinks.programmeTooltip}\r\n className={clsx(\r\n styles['editor__toolbar-button'],\r\n styles['editor__toolbar-button--text'],\r\n programmeIsActive && styles[`editor__toolbar-button--active`]\r\n )}\r\n aria-label={t.aria.labels.programmelink}\r\n aria-keyshortcuts={t.aria.keyshortcuts.programmelink}\r\n type=\"button\"\r\n ref={programmeButtonRef}\r\n >\r\n {t.cataloguelinks.programmeButtonLabel}\r\n </button>\r\n </div>\r\n {flyoutPosition && (\r\n <div\r\n className={styles['editor__toolbar-flyout-wrapper']}\r\n style={{ top: flyoutPosition.top, left: flyoutPosition.left }}\r\n ref={flyoutRef}\r\n >\r\n <AddCatalogueLinkForm\r\n linkType={type}\r\n onCloseHandler={closeFlyout}\r\n onSearchHandler={onSearch}\r\n searchResponse={searchResponse}\r\n onSelect={(code, label, linkType) => {\r\n editor.dispatchCommand(INSERT_COURSE_CATALOGUE_LINK, {\r\n linkType,\r\n code,\r\n label,\r\n });\r\n closeFlyout();\r\n }}\r\n />\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n};\r\n"],"names":["CourseCataloguePlugin","onSearch","searchResponse","parentScrollPosition","editor","useLexicalComposerContext","t","useTranslation","courseIsActive","setCourseIsActive","useState","programmeIsActive","setProgrammeIsActive","courseButtonRef","useRef","programmeButtonRef","flyoutRef","flyoutPosition","setFlyoutPosition","type","setType","openFlyout","rect","closeFlyout","useEffect","removeKeyboardShortcut","KEY_DOWN_COMMAND","event","COMMAND_PRIORITY_CRITICAL","removeStatusListener","editorState","selection","$getSelection","$isRangeSelection","anchorNode","offset","$isTextNode","CourseCatalogueNode","courseCatalogueLink","linkType","$getLinkTypeFromNode","$getNearestNodeOfType","moveToEndOfWhiteSpace","whiteSpace","$createRangeSelection","endOffset","$setSelection","isCursorBeforeLink","removeUnEditable","key","nodeLength","brNode","$createTextNode","spaceToAdd","REMOVE_COURSE_CATALOGUE_LINK","removeCopy","COPY_COMMAND","domElement","COMMAND_PRIORITY_LOW","useOnClickOutside","jsx","styles","jsxs","clsx","AddCatalogueLinkForm","code","label","INSERT_COURSE_CATALOGUE_LINK"],"mappings":";;;;;;;;;;;AAuCO,MAAMA,KAAwB,CAAC;AAAA,EACpC,UAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,sBAAAC;AACF,MAAkC;AAChC,QAAM,CAACC,CAAM,IAAIC,EAAA,GACXC,IAAIC,GAAA,GACJ,CAACC,GAAgBC,CAAiB,IAAIC,EAAS,EAAK,GACpD,CAACC,GAAmBC,CAAoB,IAAIF,EAAS,EAAK,GAC1DG,IAAkBC,EAA0B,IAAI,GAChDC,IAAqBD,EAA0B,IAAI,GACnDE,IAAYF,EAAuB,IAAI,GACvC,CAACG,GAAgBC,CAAiB,IAAIR,EAA+C,IAAI,GACzF,CAACS,GAAMC,CAAO,IAAIV,EAAiC,QAAQ,GAE3DW,IAAa,CAACF,MAAiC;AACnD,IAAAC,EAAQD,CAAI;AACZ,UAAMG,IACJH,MAAS,WACLN,EAAgB,SAAS,0BACzBE,EAAmB,SAAS,sBAAA;AAClC,IAAIO,KACFJ,EAAkB,EAAE,KAAKI,EAAK,SAAS,OAAO,SAAS,MAAMA,EAAK,OAAO,OAAO,QAAA,CAAS;AAAA,EAE7F,GAEMC,IAAc,MAAM;AACxB,IAAAtB,EAAS,IAAIkB,CAAI,GACjBD,EAAkB,IAAI;AAAA,EACxB;AAEA,SAAAM,EAAU,MAAM;AACd,IAAIP,KACFM,EAAA;AAAA,EAGJ,GAAG,CAACpB,CAAoB,CAAC,GAEzBqB,EAAU,MAAM;AACd,UAAMC,IAAyBrB,EAAO;AAAA,MACpCsB;AAAAA,MACA,CAACC,MACKA,EAAM,WAAWA,EAAM,YAAYA,EAAM,UAAUA,EAAM,QAAQ,OACnEA,EAAM,eAAA,GACNN,EAAW,QAAQ,GACZ,MAELM,EAAM,WAAWA,EAAM,YAAYA,EAAM,UAAUA,EAAM,QAAQ,OACnEA,EAAM,eAAA,GACNN,EAAW,WAAW,GACf,MAEF;AAAA,MAETO;AAAAA,IAAA,GAGIC,IAAuBzB,EAAO,uBAAuB,CAAC,EAAE,aAAA0B,QAAkB;AAC9E,MAAAA,EAAY,KAAK,MAAM;AACrB,cAAMC,IAAYC,EAAA;AAClB,YAAIC,EAAkBF,CAAS,GAAG;AAChC,gBAAMG,IAAaH,EAAU,OAAO,QAAA,GAC9BI,IAASJ,EAAU,OAAO;AAEhC,cACEK,EAAYF,CAAU,KACtBC,MAAWD,EAAW,wBACtBA,EAAW,eAAA,aAA4BG,GACvC;AAEA,kBAAMC,IAAsBJ,EAAW,eAAA;AACvC,gBAAII,GAAqB;AACvB,oBAAMC,IAAWC,EAAqBF,CAAmB;AACzD,cAAA7B,EAAkB8B,MAAa,QAAQ,GACvC3B,EAAqB2B,MAAa,WAAW;AAC7C;AAAA,YACF;AAAA,UACF;AAEA,gBAAMD,IAAsBG,EAAsBP,GAAYG,CAAmB;AACjF,cAAIC,GAAqB;AACvB,kBAAMC,IAAWC,EAAqBF,CAAmB;AACzD,YAAA7B,EAAkB8B,MAAa,QAAQ,GACvC3B,EAAqB2B,MAAa,WAAW;AAC7C;AAAA,UACF;AACA,UAAA9B,EAAkB,EAAK,GACvBG,EAAqB,EAAK;AAAA,QAC5B;AAAA,MACF,CAAC;AAAA,IACH,CAAC,GAEK8B,IAAwB,CAACC,MAAyB;AACtD,YAAMZ,IAAYa,EAAA,GACZC,IAAYF,EAAW,mBAAA;AAC7B,MAAAZ,EAAU,iBAAiBY,GAAYE,GAAWF,GAAYE,CAAS,GACvEC,EAAcf,CAAS;AAAA,IACzB,GAEMgB,IAAqB,CAACb,GAAyBC,MACnDC,EAAYF,CAAU,KACtBC,MAAWD,EAAW,mBAAA,KACtBA,EAAW,4BAA4BG,GAEnCW,IAAmB5C,EAAO;AAAA,MAC9BsB;AAAAA,MACA,CAACC,MAAyB;AACxB,cAAMI,IAAYC,EAAA;AAClB,YAAIC,EAAkBF,CAAS,GAAG;AAChC,gBAAMkB,IAAMtB,EAAM,KACZO,IAAaH,EAAU,OAAO,QAAA,GAC9BI,IAASJ,EAAU,OAAO;AAChC,cAAIO,IAAsBG,EAAsBP,GAAYG,CAAmB;AAO/E,cAJIU,EAAmBb,GAAYC,CAAM,MACvCG,IAAsBJ,EAAW,eAAA,IAG/B,CAACI;AACH,mBAAO;AAGT,gBAAMY,IAAaZ,GAAqB,mBAAA;AAGxC,cAAIA,KAAuBX,EAAM,QAAQ;AACvC,mBAAAA,EAAM,eAAA,GACNvB,EAAO,OAAO,MAAM;AAClB,kBAAI2C,EAAmBb,GAAYC,CAAM,GAAG;AAC1C,sBAAMgB,IAASC,EAAgB;AAAA,CAAI;AACnC,gBAAAd,EAAoB,aAAaa,CAAM;AAAA,cACzC;AACA,kBAAIhB,MAAWe,GAAY;AACzB,sBAAMC,IAASC,EAAgB;AAAA,CAAI;AACnC,gBAAAd,EAAoB,YAAYa,CAAM,GACtCT,EAAsBS,CAAM;AAAA,cAC9B;AAAA,YACF,CAAC,GACM;AAIT,cAAIb,MAAwBW,MAAQ,OAAOtB,EAAM,SAAS;AACxD,mBAAAA,EAAM,eAAA,GACNvB,EAAO,OAAO,MAAM;AAClB,oBAAMiD,IAAaD,EAAgB,GAAG;AACtC,cAAIL,EAAmBb,GAAYC,CAAM,MACvCG,EAAoB,aAAae,CAAU,GAC3CX,EAAsBW,CAAU,IAE9BlB,MAAWe,MACbZ,EAAoB,YAAYe,CAAU,GAC1CX,EAAsBW,CAAU;AAAA,YAEpC,CAAC,GACM;AAIT,cAAIf,MAAwBW,MAAQ,eAAeA,MAAQ;AACzD,mBAAAtB,EAAM,eAAA,GACNvB,EAAO;AAAA,cACL,MAAM;AACJ,gBAAAA,EAAO,gBAAgBkD,IAA8B,MAAS;AAAA,cAChE;AAAA,cACA,EAAE,UAAU,GAAA;AAAA,YAAK,GAEZ;AAIT,cACEhB,KACAW,MAAQ,eACRA,MAAQ,gBACRA,MAAQ,aACRA,MAAQ,eACRA,MAAQ,UACRA,MAAQ,SACR,EAAEtB,EAAM,YAAYsB,EAAI,YAAA,MAAkB,OAAOA,EAAI,YAAA,MAAkB,SACvE,EAAEtB,EAAM,WAAWsB,EAAI,YAAA,MAAkB;AAEzC,mBAAAtB,EAAM,eAAA,GACC;AAAA,QAEX;AACA,eAAO;AAAA,MACT;AAAA,MACAC;AAAAA,IAAA,GAGI2B,IAAanD,EAAO;AAAA,MACxBoD;AAAAA,MACA,CAAC7B,MAA0B;AACzB,cAAMI,IAAYC,EAAA;AAClB,YAAIC,EAAkBF,CAAS,GAAG;AAChC,gBAAMG,IAAaH,EAAU,OAAO,QAAA,GAC9BO,IAAsBG,EAAsBP,GAAYG,CAAmB;AACjF,cAAIC,GAAqB;AACvB,YAAAX,EAAM,eAAA;AACN,kBAAM8B,IAAarD,EAAO,gBAAgBkC,EAAoB,QAAQ;AACtE,mBAAImB,MACF9B,EAAM,eAAe,QAAQ,aAAa8B,EAAW,SAAS,GAC9D9B,EAAM,eAAe,QAAQ,cAAcW,EAAoB,gBAAgB,IAE1E;AAAA,UACT;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MACAoB;AAAAA,IAAA;AAEF,WAAO,MAAM;AACX,MAAAjC,EAAA,GACAI,EAAA,GACAmB,EAAA,GACAO,EAAA;AAAA,IACF;AAAA,EAEF,GAAG,CAACnD,CAAM,CAAC,GAEXuD,GAAkB3C,GAAqC,MAAME,EAAkB,IAAI,CAAC,GAGlF,gBAAA0C,EAAC,OAAA,EAAI,WAAWC,EAAO,8BAA8B,GACnD,UAAA,gBAAAC,EAAC,OAAA,EAAI,WAAWD,EAAO,sCAAsC,GAC3D,UAAA;AAAA,IAAA,gBAAAC,EAAC,OAAA,EAAI,WAAWD,EAAO,oCAAoC,GACzD,UAAA;AAAA,MAAA,gBAAAD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAAS,MAAMvC,EAAW,QAAQ;AAAA,UAClC,OAAOf,EAAE,eAAe;AAAA,UACxB,WAAWyD;AAAA,YACTF,EAAO,wBAAwB;AAAA,YAC/BA,EAAO,8BAA8B;AAAA,YACrCrD,KAAkBqD,EAAO,gCAAgC;AAAA,UAAA;AAAA,UAE3D,cAAYvD,EAAE,KAAK,OAAO;AAAA,UAC1B,qBAAmBA,EAAE,KAAK,aAAa;AAAA,UACvC,MAAK;AAAA,UACL,KAAKO;AAAA,UAEJ,YAAE,eAAe;AAAA,QAAA;AAAA,MAAA;AAAA,MAEpB,gBAAA+C;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAAS,MAAMvC,EAAW,WAAW;AAAA,UACrC,OAAOf,EAAE,eAAe;AAAA,UACxB,WAAWyD;AAAA,YACTF,EAAO,wBAAwB;AAAA,YAC/BA,EAAO,8BAA8B;AAAA,YACrClD,KAAqBkD,EAAO,gCAAgC;AAAA,UAAA;AAAA,UAE9D,cAAYvD,EAAE,KAAK,OAAO;AAAA,UAC1B,qBAAmBA,EAAE,KAAK,aAAa;AAAA,UACvC,MAAK;AAAA,UACL,KAAKS;AAAA,UAEJ,YAAE,eAAe;AAAA,QAAA;AAAA,MAAA;AAAA,IACpB,GACF;AAAA,IACCE,KACC,gBAAA2C;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAWC,EAAO,gCAAgC;AAAA,QAClD,OAAO,EAAE,KAAK5C,EAAe,KAAK,MAAMA,EAAe,KAAA;AAAA,QACvD,KAAKD;AAAA,QAEL,UAAA,gBAAA4C;AAAA,UAACI;AAAA,UAAA;AAAA,YACC,UAAU7C;AAAA,YACV,gBAAgBI;AAAA,YAChB,iBAAiBtB;AAAA,YACjB,gBAAAC;AAAA,YACA,UAAU,CAAC+D,GAAMC,GAAO3B,MAAa;AACnC,cAAAnC,EAAO,gBAAgB+D,IAA8B;AAAA,gBACnD,UAAA5B;AAAA,gBACA,MAAA0B;AAAA,gBACA,OAAAC;AAAA,cAAA,CACD,GACD3C,EAAA;AAAA,YACF;AAAA,UAAA;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EACF,EAAA,CAEJ,EAAA,CACF;AAEJ;"}
1
+ {"version":3,"file":"CourseCataloguePlugin.js","sources":["../../../../../src/components/RteEditor/Plugins/CourseCataloguePlugin/CourseCataloguePlugin.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\r\nimport { clsx } from 'clsx';\r\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\r\nimport {\r\n $createRangeSelection,\r\n $createTextNode,\r\n $getSelection,\r\n $isRangeSelection,\r\n $isTextNode,\r\n $setSelection,\r\n COMMAND_PRIORITY_CRITICAL,\r\n COMMAND_PRIORITY_LOW,\r\n COPY_COMMAND,\r\n KEY_DOWN_COMMAND,\r\n} from 'lexical';\r\nimport { $getNearestNodeOfType } from '@lexical/utils';\r\n\r\nimport type { RefObject } from 'react';\r\nimport type { LexicalNode, TextNode } from 'lexical';\r\nimport type { SearchResponse } from './AddCatalogueLinkForm';\r\n\r\nimport { AddCatalogueLinkForm } from './AddCatalogueLinkForm';\r\n\r\nimport styles from 'components/RteEditor/RteEditor.module.css';\r\nimport { useTranslation } from 'components/RteEditor/hooks/useTranslation';\r\nimport {\r\n $getLinkTypeFromNode,\r\n CourseCatalogueNode,\r\n INSERT_COURSE_CATALOGUE_LINK,\r\n REMOVE_COURSE_CATALOGUE_LINK,\r\n} from 'components/RteEditor/nodes/CourseCatalogueNode';\r\nimport { useOnClickOutside } from 'components/hooks/useOnClickOutside';\r\nimport { removeScrollableContainers, setScrollableContainers } from 'components/RteEditor/helpers';\r\n\r\ninterface CourseCataloguePluginProps {\r\n onSearch: (query: string, linkType: 'course' | 'programme') => void;\r\n searchResponse: SearchResponse;\r\n parentScrollPosition: number;\r\n}\r\n\r\nexport const CourseCataloguePlugin = ({\r\n onSearch,\r\n searchResponse,\r\n parentScrollPosition,\r\n}: CourseCataloguePluginProps) => {\r\n const [editor] = useLexicalComposerContext();\r\n const t = useTranslation();\r\n const [courseIsActive, setCourseIsActive] = useState(false);\r\n const [programmeIsActive, setProgrammeIsActive] = useState(false);\r\n const courseButtonRef = useRef<HTMLButtonElement>(null);\r\n const programmeButtonRef = useRef<HTMLButtonElement>(null);\r\n const flyoutRef = useRef<HTMLDivElement>(null);\r\n const [flyoutPosition, setFlyoutPosition] = useState<{ top: number; left: number } | null>(null);\r\n const [type, setType] = useState<'course' | 'programme'>('course');\r\n const isVisibleRef = useRef(flyoutPosition !== null);\r\n\r\n const openFlyout = (type: 'course' | 'programme') => {\r\n setType(type);\r\n const rect =\r\n type === 'course'\r\n ? courseButtonRef.current?.getBoundingClientRect()\r\n : programmeButtonRef.current?.getBoundingClientRect();\r\n if (rect) {\r\n setFlyoutPosition({ top: rect.bottom, left: rect.left });\r\n }\r\n };\r\n\r\n const closeFlyout = () => {\r\n onSearch('', type);\r\n setFlyoutPosition(null);\r\n };\r\n\r\n useEffect(() => {\r\n const removeKeyboardShortcut = editor.registerCommand(\r\n KEY_DOWN_COMMAND,\r\n (event: KeyboardEvent) => {\r\n if (event.ctrlKey && event.shiftKey && event.altKey && event.key === 'C') {\r\n event.preventDefault();\r\n openFlyout('course');\r\n return true;\r\n }\r\n if (event.ctrlKey && event.shiftKey && event.altKey && event.key === 'P') {\r\n event.preventDefault();\r\n openFlyout('programme');\r\n return true;\r\n }\r\n return false;\r\n },\r\n COMMAND_PRIORITY_CRITICAL\r\n );\r\n\r\n const removeStatusListener = editor.registerUpdateListener(({ editorState }) => {\r\n editorState.read(() => {\r\n const selection = $getSelection();\r\n if ($isRangeSelection(selection)) {\r\n const anchorNode = selection.anchor.getNode();\r\n const offset = selection.anchor.offset;\r\n\r\n if (\r\n $isTextNode(anchorNode) &&\r\n offset === anchorNode.getTextContentSize() &&\r\n anchorNode.getNextSibling() instanceof CourseCatalogueNode\r\n ) {\r\n // Cursor staat aan het begin van de link!\r\n const courseCatalogueLink = anchorNode.getNextSibling();\r\n if (courseCatalogueLink) {\r\n const linkType = $getLinkTypeFromNode(courseCatalogueLink);\r\n setCourseIsActive(linkType === 'course');\r\n setProgrammeIsActive(linkType === 'programme');\r\n return;\r\n }\r\n }\r\n\r\n const courseCatalogueLink = $getNearestNodeOfType(anchorNode, CourseCatalogueNode);\r\n if (courseCatalogueLink) {\r\n const linkType = $getLinkTypeFromNode(courseCatalogueLink);\r\n setCourseIsActive(linkType === 'course');\r\n setProgrammeIsActive(linkType === 'programme');\r\n return;\r\n }\r\n setCourseIsActive(false);\r\n setProgrammeIsActive(false);\r\n }\r\n });\r\n });\r\n\r\n const moveToEndOfWhiteSpace = (whiteSpace: TextNode) => {\r\n const selection = $createRangeSelection();\r\n const endOffset = whiteSpace.getTextContentSize();\r\n selection.setTextNodeRange(whiteSpace, endOffset, whiteSpace, endOffset);\r\n $setSelection(selection);\r\n };\r\n\r\n const isCursorBeforeLink = (anchorNode: LexicalNode, offset: number) =>\r\n $isTextNode(anchorNode) &&\r\n offset === anchorNode.getTextContentSize() &&\r\n anchorNode.getNextSibling() instanceof CourseCatalogueNode;\r\n\r\n const removeUnEditable = editor.registerCommand(\r\n KEY_DOWN_COMMAND,\r\n (event: KeyboardEvent) => {\r\n const selection = $getSelection();\r\n if ($isRangeSelection(selection)) {\r\n const key = event.key;\r\n const anchorNode = selection.anchor.getNode();\r\n const offset = selection.anchor.offset;\r\n let courseCatalogueLink = $getNearestNodeOfType(anchorNode, CourseCatalogueNode);\r\n\r\n // Detect if cursor is right before the link\r\n if (isCursorBeforeLink(anchorNode, offset)) {\r\n courseCatalogueLink = anchorNode.getNextSibling();\r\n }\r\n\r\n if (!courseCatalogueLink) {\r\n return false;\r\n }\r\n\r\n const nodeLength = courseCatalogueLink?.getTextContentSize();\r\n\r\n // Prevent Enter if in the middle of the link, allow only at start or end\r\n if (courseCatalogueLink && event.key === 'Enter') {\r\n event.preventDefault();\r\n editor.update(() => {\r\n if (isCursorBeforeLink(anchorNode, offset)) {\r\n const brNode = $createTextNode('\\n');\r\n courseCatalogueLink.insertBefore(brNode);\r\n }\r\n if (offset === nodeLength) {\r\n const brNode = $createTextNode('\\n');\r\n courseCatalogueLink.insertAfter(brNode);\r\n moveToEndOfWhiteSpace(brNode);\r\n }\r\n });\r\n return true;\r\n }\r\n\r\n // Allow add space before or after the link\r\n if (courseCatalogueLink && (key === ' ' || event.code === 'Space')) {\r\n event.preventDefault();\r\n editor.update(() => {\r\n const spaceToAdd = $createTextNode(' ');\r\n if (isCursorBeforeLink(anchorNode, offset)) {\r\n courseCatalogueLink.insertBefore(spaceToAdd);\r\n moveToEndOfWhiteSpace(spaceToAdd);\r\n }\r\n if (offset === nodeLength) {\r\n courseCatalogueLink.insertAfter(spaceToAdd);\r\n moveToEndOfWhiteSpace(spaceToAdd);\r\n }\r\n });\r\n return true;\r\n }\r\n\r\n // Delete link if selected and Backspace or Del is pressed\r\n if (courseCatalogueLink && (key === 'Backspace' || key === 'Delete')) {\r\n event.preventDefault();\r\n editor.update(\r\n () => {\r\n editor.dispatchCommand(REMOVE_COURSE_CATALOGUE_LINK, undefined);\r\n },\r\n { discrete: true }\r\n );\r\n return true;\r\n }\r\n\r\n // Allow Home, End and Arrow navigation\r\n if (\r\n courseCatalogueLink &&\r\n key !== 'ArrowLeft' &&\r\n key !== 'ArrowRight' &&\r\n key !== 'ArrowUp' &&\r\n key !== 'ArrowDown' &&\r\n key !== 'Home' &&\r\n key !== 'End' &&\r\n !(event.ctrlKey && (key.toLowerCase() === 'z' || key.toLowerCase() === 'y')) &&\r\n !(event.ctrlKey && key.toLowerCase() === 'c')\r\n ) {\r\n event.preventDefault();\r\n return true;\r\n }\r\n }\r\n return false;\r\n },\r\n COMMAND_PRIORITY_CRITICAL\r\n );\r\n\r\n const removeCopy = editor.registerCommand(\r\n COPY_COMMAND,\r\n (event: ClipboardEvent) => {\r\n const selection = $getSelection();\r\n if ($isRangeSelection(selection)) {\r\n const anchorNode = selection.anchor.getNode();\r\n const courseCatalogueLink = $getNearestNodeOfType(anchorNode, CourseCatalogueNode);\r\n if (courseCatalogueLink) {\r\n event.preventDefault();\r\n const domElement = editor.getElementByKey(courseCatalogueLink.getKey());\r\n if (domElement) {\r\n event.clipboardData?.setData('text/html', domElement.outerHTML);\r\n event.clipboardData?.setData('text/plain', courseCatalogueLink.getTextContent());\r\n }\r\n return true;\r\n }\r\n }\r\n return false;\r\n },\r\n COMMAND_PRIORITY_LOW\r\n );\r\n return () => {\r\n removeKeyboardShortcut();\r\n removeStatusListener();\r\n removeUnEditable();\r\n removeCopy();\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [editor]);\r\n\r\n useOnClickOutside(flyoutRef as RefObject<HTMLElement>, () => setFlyoutPosition(null));\r\n\r\n useEffect(() => {\r\n const removeKeydown = (event: KeyboardEvent): boolean => {\r\n setScrollableContainers(handleResizeScroll);\r\n\r\n if (event.key === 'Escape' && isVisibleRef.current) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n closeFlyout();\r\n }\r\n return true;\r\n };\r\n\r\n window.addEventListener('keydown', removeKeydown, { capture: true });\r\n\r\n const handleResizeScroll = () => {\r\n closeFlyout();\r\n };\r\n\r\n setScrollableContainers(handleResizeScroll);\r\n\r\n window.addEventListener('scroll', handleResizeScroll);\r\n window.addEventListener('resize', handleResizeScroll);\r\n\r\n return () => {\r\n window.removeEventListener('keydown', removeKeydown);\r\n window.removeEventListener('scroll', handleResizeScroll);\r\n window.removeEventListener('resize', handleResizeScroll);\r\n removeScrollableContainers(handleResizeScroll);\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (flyoutPosition) {\r\n closeFlyout();\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [parentScrollPosition]);\r\n\r\n return (\r\n <div className={styles['editor__toolbar-button-group']}>\r\n <div className={styles['editor__toolbar-button-flyoutwrapper']}>\r\n <div className={styles['editor__toolbar-button-group--text']}>\r\n <button\r\n onClick={() => openFlyout('course')}\r\n title={t.cataloguelinks.courseTooltip}\r\n className={clsx(\r\n styles['editor__toolbar-button'],\r\n styles['editor__toolbar-button--text'],\r\n courseIsActive && styles[`editor__toolbar-button--active`]\r\n )}\r\n aria-label={t.aria.labels.courselink}\r\n aria-keyshortcuts={t.aria.keyshortcuts.courselink}\r\n type=\"button\"\r\n ref={courseButtonRef}\r\n >\r\n {t.cataloguelinks.courseButtonLabel}\r\n </button>\r\n <button\r\n onClick={() => openFlyout('programme')}\r\n title={t.cataloguelinks.programmeTooltip}\r\n className={clsx(\r\n styles['editor__toolbar-button'],\r\n styles['editor__toolbar-button--text'],\r\n programmeIsActive && styles[`editor__toolbar-button--active`]\r\n )}\r\n aria-label={t.aria.labels.programmelink}\r\n aria-keyshortcuts={t.aria.keyshortcuts.programmelink}\r\n type=\"button\"\r\n ref={programmeButtonRef}\r\n >\r\n {t.cataloguelinks.programmeButtonLabel}\r\n </button>\r\n </div>\r\n {flyoutPosition && (\r\n <div\r\n className={styles['editor__toolbar-flyout-wrapper']}\r\n style={{ top: flyoutPosition.top, left: flyoutPosition.left }}\r\n ref={flyoutRef}\r\n >\r\n <AddCatalogueLinkForm\r\n linkType={type}\r\n onCloseHandler={closeFlyout}\r\n onSearchHandler={onSearch}\r\n searchResponse={searchResponse}\r\n onSelect={(code, label, linkType) => {\r\n editor.dispatchCommand(INSERT_COURSE_CATALOGUE_LINK, {\r\n linkType,\r\n code,\r\n label,\r\n });\r\n closeFlyout();\r\n }}\r\n />\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n};\r\n"],"names":["CourseCataloguePlugin","onSearch","searchResponse","parentScrollPosition","editor","useLexicalComposerContext","t","useTranslation","courseIsActive","setCourseIsActive","useState","programmeIsActive","setProgrammeIsActive","courseButtonRef","useRef","programmeButtonRef","flyoutRef","flyoutPosition","setFlyoutPosition","type","setType","isVisibleRef","openFlyout","rect","closeFlyout","useEffect","removeKeyboardShortcut","KEY_DOWN_COMMAND","event","COMMAND_PRIORITY_CRITICAL","removeStatusListener","editorState","selection","$getSelection","$isRangeSelection","anchorNode","offset","$isTextNode","CourseCatalogueNode","courseCatalogueLink","linkType","$getLinkTypeFromNode","$getNearestNodeOfType","moveToEndOfWhiteSpace","whiteSpace","$createRangeSelection","endOffset","$setSelection","isCursorBeforeLink","removeUnEditable","key","nodeLength","brNode","$createTextNode","spaceToAdd","REMOVE_COURSE_CATALOGUE_LINK","removeCopy","COPY_COMMAND","domElement","COMMAND_PRIORITY_LOW","useOnClickOutside","removeKeydown","setScrollableContainers","handleResizeScroll","removeScrollableContainers","jsx","styles","jsxs","clsx","AddCatalogueLinkForm","code","label","INSERT_COURSE_CATALOGUE_LINK"],"mappings":"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"}