@notum-cz/strapi-plugin-tiptap-editor 1.0.1

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 (104) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +160 -0
  3. package/dist/_chunks/AccentCursive-CpAPpH9C.mjs +3383 -0
  4. package/dist/_chunks/AccentCursive-CpAPpH9C.mjs.map +1 -0
  5. package/dist/_chunks/AccentCursive-D6sTlhub.js +3384 -0
  6. package/dist/_chunks/AccentCursive-D6sTlhub.js.map +1 -0
  7. package/dist/_chunks/FormattedHeadingInput-DycgfIze.mjs +101 -0
  8. package/dist/_chunks/FormattedHeadingInput-DycgfIze.mjs.map +1 -0
  9. package/dist/_chunks/FormattedHeadingInput-FFjiRSEJ.js +101 -0
  10. package/dist/_chunks/FormattedHeadingInput-FFjiRSEJ.js.map +1 -0
  11. package/dist/_chunks/RichTextInput-BZQ2iVqa.mjs +4481 -0
  12. package/dist/_chunks/RichTextInput-BZQ2iVqa.mjs.map +1 -0
  13. package/dist/_chunks/RichTextInput-BbbQxPc-.js +4414 -0
  14. package/dist/_chunks/RichTextInput-BbbQxPc-.js.map +1 -0
  15. package/dist/_chunks/RichTextInput-BjLR2pi0.js +4416 -0
  16. package/dist/_chunks/RichTextInput-BjLR2pi0.js.map +1 -0
  17. package/dist/_chunks/RichTextInput-BlxoJMa2.js +4488 -0
  18. package/dist/_chunks/RichTextInput-BlxoJMa2.js.map +1 -0
  19. package/dist/_chunks/RichTextInput-Bm3X8fR2.mjs +4400 -0
  20. package/dist/_chunks/RichTextInput-Bm3X8fR2.mjs.map +1 -0
  21. package/dist/_chunks/RichTextInput-Bms-gSvK.js +4407 -0
  22. package/dist/_chunks/RichTextInput-Bms-gSvK.js.map +1 -0
  23. package/dist/_chunks/RichTextInput-BtNjPJRN.mjs +4400 -0
  24. package/dist/_chunks/RichTextInput-BtNjPJRN.mjs.map +1 -0
  25. package/dist/_chunks/RichTextInput-Bw3tcXfp.js +4407 -0
  26. package/dist/_chunks/RichTextInput-Bw3tcXfp.js.map +1 -0
  27. package/dist/_chunks/RichTextInput-CsgNpoxq.mjs +4409 -0
  28. package/dist/_chunks/RichTextInput-CsgNpoxq.mjs.map +1 -0
  29. package/dist/_chunks/RichTextInput-CwTvEMda.js +4407 -0
  30. package/dist/_chunks/RichTextInput-CwTvEMda.js.map +1 -0
  31. package/dist/_chunks/RichTextInput-DG-36krM.js +1181 -0
  32. package/dist/_chunks/RichTextInput-DG-36krM.js.map +1 -0
  33. package/dist/_chunks/RichTextInput-DLac-zNQ.mjs +4400 -0
  34. package/dist/_chunks/RichTextInput-DLac-zNQ.mjs.map +1 -0
  35. package/dist/_chunks/RichTextInput-DSXttrvi.js +4407 -0
  36. package/dist/_chunks/RichTextInput-DSXttrvi.js.map +1 -0
  37. package/dist/_chunks/RichTextInput-DeJ6Exto.mjs +4400 -0
  38. package/dist/_chunks/RichTextInput-DeJ6Exto.mjs.map +1 -0
  39. package/dist/_chunks/RichTextInput-DgT88AkO.mjs +1175 -0
  40. package/dist/_chunks/RichTextInput-DgT88AkO.mjs.map +1 -0
  41. package/dist/_chunks/RichTextInput-DlMaDJQF.mjs +4400 -0
  42. package/dist/_chunks/RichTextInput-DlMaDJQF.mjs.map +1 -0
  43. package/dist/_chunks/RichTextInput-DtaYdjCs.mjs +4400 -0
  44. package/dist/_chunks/RichTextInput-DtaYdjCs.mjs.map +1 -0
  45. package/dist/_chunks/RichTextInput-YTKXo5oq.js +4407 -0
  46. package/dist/_chunks/RichTextInput-YTKXo5oq.js.map +1 -0
  47. package/dist/_chunks/RichTextInput-tmg-oMJk.mjs +4407 -0
  48. package/dist/_chunks/RichTextInput-tmg-oMJk.mjs.map +1 -0
  49. package/dist/_chunks/RichTextInput-umhMsI5o.js +4407 -0
  50. package/dist/_chunks/RichTextInput-umhMsI5o.js.map +1 -0
  51. package/dist/_chunks/en-B4KWt_jN.js +5 -0
  52. package/dist/_chunks/en-B4KWt_jN.js.map +1 -0
  53. package/dist/_chunks/en-Byx4XI2L.mjs +5 -0
  54. package/dist/_chunks/en-Byx4XI2L.mjs.map +1 -0
  55. package/dist/admin/index.js +71 -0
  56. package/dist/admin/index.js.map +1 -0
  57. package/dist/admin/index.mjs +72 -0
  58. package/dist/admin/index.mjs.map +1 -0
  59. package/dist/admin/src/components/BaseTiptapInput.d.ts +12 -0
  60. package/dist/admin/src/components/FormattedHeadingInput.d.ts +4 -0
  61. package/dist/admin/src/components/Initializer.d.ts +5 -0
  62. package/dist/admin/src/components/LinkDialog.d.ts +14 -0
  63. package/dist/admin/src/components/RichTextInput.d.ts +4 -0
  64. package/dist/admin/src/components/Spacer.d.ts +3 -0
  65. package/dist/admin/src/components/TableSizeDialog.d.ts +10 -0
  66. package/dist/admin/src/components/TiptapInput.d.ts +7 -0
  67. package/dist/admin/src/components/TiptapInputStyles.d.ts +2 -0
  68. package/dist/admin/src/components/ToolbarButton.d.ts +11 -0
  69. package/dist/admin/src/extensions/AccentCursive.d.ts +18 -0
  70. package/dist/admin/src/extensions/Heading.d.ts +8 -0
  71. package/dist/admin/src/extensions/Link.d.ts +7 -0
  72. package/dist/admin/src/extensions/Script.d.ts +7 -0
  73. package/dist/admin/src/extensions/StarterKit.d.ts +13 -0
  74. package/dist/admin/src/extensions/Table.d.ts +11 -0
  75. package/dist/admin/src/extensions/TextAlign.d.ts +9 -0
  76. package/dist/admin/src/fields/formattedHeadingField.d.ts +20 -0
  77. package/dist/admin/src/fields/richTextField.d.ts +20 -0
  78. package/dist/admin/src/icons/TextAlignCenter.d.ts +2 -0
  79. package/dist/admin/src/icons/TextAlignJustify.d.ts +2 -0
  80. package/dist/admin/src/icons/TextAlignLeft.d.ts +2 -0
  81. package/dist/admin/src/icons/TextAlignRight.d.ts +2 -0
  82. package/dist/admin/src/index.d.ts +10 -0
  83. package/dist/admin/src/pluginId.d.ts +1 -0
  84. package/dist/admin/src/utils/getTranslation.d.ts +2 -0
  85. package/dist/admin/src/utils/tiptapUtils.d.ts +18 -0
  86. package/dist/server/index.js +44 -0
  87. package/dist/server/index.js.map +1 -0
  88. package/dist/server/index.mjs +45 -0
  89. package/dist/server/index.mjs.map +1 -0
  90. package/dist/server/src/bootstrap.d.ts +5 -0
  91. package/dist/server/src/config/index.d.ts +5 -0
  92. package/dist/server/src/content-types/index.d.ts +2 -0
  93. package/dist/server/src/controllers/index.d.ts +2 -0
  94. package/dist/server/src/destroy.d.ts +5 -0
  95. package/dist/server/src/fields/richTextField.d.ts +2 -0
  96. package/dist/server/src/index.d.ts +25 -0
  97. package/dist/server/src/middlewares/index.d.ts +2 -0
  98. package/dist/server/src/policies/index.d.ts +2 -0
  99. package/dist/server/src/register.d.ts +5 -0
  100. package/dist/server/src/routes/index.d.ts +2 -0
  101. package/dist/server/src/services/index.d.ts +2 -0
  102. package/dist/shared/fields.d.ts +1 -0
  103. package/dist/shared/pluginId.d.ts +1 -0
  104. package/package.json +80 -0
@@ -0,0 +1,1181 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const AccentCursive = require("./AccentCursive-D6sTlhub.js");
5
+ const StarterKit = require("@tiptap/starter-kit");
6
+ const react = require("@tiptap/react");
7
+ const icons = require("@strapi/icons");
8
+ const React = require("react");
9
+ const designSystem = require("@strapi/design-system");
10
+ const Superscript = require("@tiptap/extension-superscript");
11
+ const Subscript = require("@tiptap/extension-subscript");
12
+ const extensionTable = require("@tiptap/extension-table");
13
+ const state = require("@tiptap/pm/state");
14
+ const dropcursor = require("@tiptap/pm/dropcursor");
15
+ const view = require("@tiptap/pm/view");
16
+ const gapcursor = require("@tiptap/pm/gapcursor");
17
+ const history = require("@tiptap/pm/history");
18
+ const TextAlign = require("@tiptap/extension-text-align");
19
+ const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
20
+ const StarterKit__default = /* @__PURE__ */ _interopDefault(StarterKit);
21
+ const React__default = /* @__PURE__ */ _interopDefault(React);
22
+ const Superscript__default = /* @__PURE__ */ _interopDefault(Superscript);
23
+ const Subscript__default = /* @__PURE__ */ _interopDefault(Subscript);
24
+ const TextAlign__default = /* @__PURE__ */ _interopDefault(TextAlign);
25
+ function useStarterKit(editor, props = { disabled: false }) {
26
+ const editorState = react.useEditorState({
27
+ editor,
28
+ selector: (ctx) => {
29
+ return {
30
+ isBold: ctx.editor.isActive("bold") ?? false,
31
+ canBold: ctx.editor.can().chain().toggleBold().run() ?? false,
32
+ isItalic: ctx.editor.isActive("italic") ?? false,
33
+ canItalic: ctx.editor.can().chain().toggleItalic().run() ?? false,
34
+ isUnderline: ctx.editor.isActive("underline") ?? false,
35
+ canUnderline: ctx.editor.can().chain().toggleUnderline().run() ?? false,
36
+ isStrike: ctx.editor.isActive("strike") ?? false,
37
+ canStrike: ctx.editor.can().chain().toggleStrike().run() ?? false,
38
+ isCode: ctx.editor.isActive("code") ?? false,
39
+ canCode: ctx.editor.can().chain().toggleCode().run() ?? false,
40
+ isBulletList: ctx.editor.isActive("bulletList") ?? false,
41
+ canToggleBulletList: ctx.editor.can().chain().toggleBulletList().run() ?? false,
42
+ isOrderedList: ctx.editor.isActive("orderedList") ?? false,
43
+ canToggleOrderedList: ctx.editor.can().chain().toggleOrderedList().run() ?? false,
44
+ isBlockquote: ctx.editor.isActive("blockquote") ?? false,
45
+ canToggleBlockquote: ctx.editor.can().chain().toggleBlockquote().run() ?? false
46
+ };
47
+ }
48
+ });
49
+ const toggleBold = () => editor?.chain().focus().toggleBold().run();
50
+ const toggleItalic = () => editor?.chain().focus().toggleItalic().run();
51
+ const toggleUnderline = () => editor?.chain().focus().toggleUnderline().run();
52
+ const toggleStrike = () => editor?.chain().focus().toggleStrike().run();
53
+ const toggleCode = () => editor?.chain().focus().toggleCode().run();
54
+ const toggleBulletList = () => editor?.chain().focus().toggleBulletList().run();
55
+ const toggleOrderedList = () => editor?.chain().focus().toggleOrderedList().run();
56
+ const toggleBlockquote = () => editor?.chain().focus().toggleBlockquote().run();
57
+ return {
58
+ boldButton: AccentCursive.toolbarButton("bold", {
59
+ onClick: toggleBold,
60
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Bold, {}),
61
+ active: editorState.isBold,
62
+ disabled: props.disabled || !editor || !editorState.canBold,
63
+ tooltip: "Bold"
64
+ }),
65
+ italicButton: AccentCursive.toolbarButton("italic", {
66
+ onClick: toggleItalic,
67
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Italic, {}),
68
+ active: editorState.isItalic,
69
+ disabled: props.disabled || !editor || !editorState.canItalic,
70
+ tooltip: "Italic"
71
+ }),
72
+ underlineButton: AccentCursive.toolbarButton("underline", {
73
+ onClick: toggleUnderline,
74
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Underline, {}),
75
+ active: editorState.isUnderline,
76
+ disabled: props.disabled || !editor || !editorState.canUnderline,
77
+ tooltip: "Underline"
78
+ }),
79
+ strikeButton: AccentCursive.toolbarButton("strike", {
80
+ onClick: toggleStrike,
81
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.StrikeThrough, {}),
82
+ active: editorState.isStrike,
83
+ disabled: props.disabled || !editor || !editorState.canStrike,
84
+ tooltip: "Strikethrough"
85
+ }),
86
+ bulletButton: AccentCursive.toolbarButton("bullet", {
87
+ onClick: toggleBulletList,
88
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.BulletList, {}),
89
+ active: editorState.isBulletList,
90
+ disabled: props.disabled || !editor || !editorState.canToggleBulletList,
91
+ tooltip: "Bullet list"
92
+ }),
93
+ orderedButton: AccentCursive.toolbarButton("ordered", {
94
+ onClick: toggleOrderedList,
95
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.NumberList, {}),
96
+ active: editorState.isOrderedList,
97
+ disabled: props.disabled || !editor || !editorState.canToggleOrderedList,
98
+ tooltip: "Numbered list"
99
+ }),
100
+ codeButton: AccentCursive.toolbarButton("code", {
101
+ onClick: toggleCode,
102
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Code, {}),
103
+ active: editorState.isCode,
104
+ disabled: props.disabled || !editor || !editorState.canCode,
105
+ tooltip: "Inline code"
106
+ }),
107
+ blockquoteButton: AccentCursive.toolbarButton("quote", {
108
+ onClick: toggleBlockquote,
109
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Quotes, {}),
110
+ active: editorState.isBlockquote,
111
+ disabled: props.disabled || !editor || !editorState.canToggleBlockquote,
112
+ tooltip: "Quote"
113
+ })
114
+ };
115
+ }
116
+ const LinkDialog = ({
117
+ open,
118
+ url,
119
+ mode,
120
+ onClose,
121
+ onSave,
122
+ onRemove
123
+ }) => {
124
+ const [value, setValue] = React__default.default.useState(url || "");
125
+ React__default.default.useEffect(() => {
126
+ if (open) {
127
+ setValue(url || "");
128
+ }
129
+ }, [open, url, mode]);
130
+ const handleSave = () => {
131
+ onSave({ url: value.trim() });
132
+ };
133
+ const isSaveDisabled = mode === "add" ? value.trim() === "" : false;
134
+ return /* @__PURE__ */ jsxRuntime.jsx(
135
+ designSystem.Dialog.Root,
136
+ {
137
+ open,
138
+ onOpenChange: (v) => {
139
+ if (!v) onClose();
140
+ },
141
+ children: open && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
142
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: mode === "add" ? "Add link" : "Edit link" }),
143
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { width: "100%", children: [
144
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "URL" }),
145
+ /* @__PURE__ */ jsxRuntime.jsx(
146
+ designSystem.TextInput,
147
+ {
148
+ name: "link-url",
149
+ placeholder: "https://example.com",
150
+ value,
151
+ onChange: (e) => setValue(e.target.value)
152
+ }
153
+ )
154
+ ] }) }),
155
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
156
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", fullWidth: true, onClick: onClose, children: "Cancel" }) }),
157
+ mode === "edit" && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "danger-light", fullWidth: true, onClick: onRemove, children: "Remove link" }),
158
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Action, { children: /* @__PURE__ */ jsxRuntime.jsx(
159
+ designSystem.Button,
160
+ {
161
+ fullWidth: true,
162
+ variant: "success-light",
163
+ onClick: handleSave,
164
+ disabled: isSaveDisabled,
165
+ children: "Save"
166
+ }
167
+ ) })
168
+ ] })
169
+ ] })
170
+ }
171
+ );
172
+ };
173
+ function useLink(editor, props = { disabled: false }) {
174
+ const editorState = react.useEditorState({
175
+ editor,
176
+ selector: (ctx) => {
177
+ return {
178
+ isLink: ctx.editor.isActive("link") ?? false,
179
+ canSetLink: ctx.editor.can().setLink?.({ href: "https://example.com" }) ?? true
180
+ };
181
+ }
182
+ });
183
+ const [showLinkDialog, setShowLinkDialog] = React.useState(false);
184
+ const [currentLinkUrl, setCurrentLinkUrl] = React.useState("");
185
+ const [linkDialogMode, setLinkDialogMode] = React.useState("add");
186
+ const selectionRef = React.useRef(null);
187
+ const openAddLinkDialog = () => {
188
+ if (!editor) return;
189
+ const { from, to } = editor.state.selection;
190
+ selectionRef.current = { from, to };
191
+ setCurrentLinkUrl("");
192
+ setLinkDialogMode("add");
193
+ setShowLinkDialog(true);
194
+ };
195
+ const openEditLinkDialog = () => {
196
+ if (!editor) return;
197
+ const { from, to } = editor.state.selection;
198
+ selectionRef.current = { from, to };
199
+ const currentHref = editor.getAttributes("link").href || "";
200
+ setCurrentLinkUrl(currentHref);
201
+ setLinkDialogMode("edit");
202
+ setShowLinkDialog(true);
203
+ };
204
+ const toggleLink = () => {
205
+ if (!editor) return;
206
+ if (editorState.isLink) {
207
+ openEditLinkDialog();
208
+ } else {
209
+ openAddLinkDialog();
210
+ }
211
+ };
212
+ const restoreSelection = () => {
213
+ if (!editor) return;
214
+ const sel = selectionRef.current;
215
+ if (sel) {
216
+ editor.chain().setTextSelection({ from: sel.from, to: sel.to }).run();
217
+ }
218
+ };
219
+ const handleSaveEditedLink = ({ url }) => {
220
+ if (!editor) return;
221
+ restoreSelection();
222
+ const chain = editor.chain().focus().extendMarkRange("link");
223
+ if (url === "") {
224
+ chain.unsetLink().run();
225
+ } else {
226
+ chain.updateAttributes("link", { href: url }).run();
227
+ }
228
+ setShowLinkDialog(false);
229
+ };
230
+ const handleRemoveLink = () => {
231
+ if (!editor) return;
232
+ restoreSelection();
233
+ editor.chain().focus().extendMarkRange("link").unsetLink().run();
234
+ setShowLinkDialog(false);
235
+ };
236
+ const handleSaveNewLink = ({ url }) => {
237
+ if (!editor) return;
238
+ restoreSelection();
239
+ editor.chain().focus().setLink({ href: url }).run();
240
+ setShowLinkDialog(false);
241
+ };
242
+ return {
243
+ linkButton: AccentCursive.toolbarButton("link", {
244
+ onClick: toggleLink,
245
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Link, {}),
246
+ active: editorState.isLink,
247
+ disabled: props.disabled || !editor || !editorState.canSetLink,
248
+ tooltip: editorState.isLink ? "Edit or remove link" : "Add link"
249
+ }),
250
+ linkDialog: /* @__PURE__ */ jsxRuntime.jsx(
251
+ LinkDialog,
252
+ {
253
+ open: showLinkDialog,
254
+ url: currentLinkUrl,
255
+ mode: linkDialogMode,
256
+ onClose: () => setShowLinkDialog(false),
257
+ onSave: linkDialogMode === "add" ? handleSaveNewLink : handleSaveEditedLink,
258
+ onRemove: handleRemoveLink
259
+ }
260
+ )
261
+ };
262
+ }
263
+ var Heading = AccentCursive.Node3.create({
264
+ name: "heading",
265
+ addOptions() {
266
+ return {
267
+ levels: [1, 2, 3, 4, 5, 6],
268
+ HTMLAttributes: {}
269
+ };
270
+ },
271
+ content: "inline*",
272
+ group: "block",
273
+ defining: true,
274
+ addAttributes() {
275
+ return {
276
+ level: {
277
+ default: 1,
278
+ rendered: false
279
+ }
280
+ };
281
+ },
282
+ parseHTML() {
283
+ return this.options.levels.map((level) => ({
284
+ tag: `h${level}`,
285
+ attrs: { level }
286
+ }));
287
+ },
288
+ renderHTML({ node, HTMLAttributes }) {
289
+ const hasLevel = this.options.levels.includes(node.attrs.level);
290
+ const level = hasLevel ? node.attrs.level : this.options.levels[0];
291
+ return [`h${level}`, AccentCursive.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
292
+ },
293
+ parseMarkdown: (token, helpers) => {
294
+ return helpers.createNode("heading", { level: token.depth || 1 }, helpers.parseInline(token.tokens || []));
295
+ },
296
+ renderMarkdown: (node, h) => {
297
+ var _a;
298
+ const level = ((_a = node.attrs) == null ? void 0 : _a.level) ? parseInt(node.attrs.level, 10) : 1;
299
+ const headingChars = "#".repeat(level);
300
+ if (!node.content) {
301
+ return "";
302
+ }
303
+ return `${headingChars} ${h.renderChildren(node.content)}`;
304
+ },
305
+ addCommands() {
306
+ return {
307
+ setHeading: (attributes) => ({ commands }) => {
308
+ if (!this.options.levels.includes(attributes.level)) {
309
+ return false;
310
+ }
311
+ return commands.setNode(this.name, attributes);
312
+ },
313
+ toggleHeading: (attributes) => ({ commands }) => {
314
+ if (!this.options.levels.includes(attributes.level)) {
315
+ return false;
316
+ }
317
+ return commands.toggleNode(this.name, "paragraph", attributes);
318
+ }
319
+ };
320
+ },
321
+ addKeyboardShortcuts() {
322
+ return this.options.levels.reduce(
323
+ (items, level) => ({
324
+ ...items,
325
+ ...{
326
+ [`Mod-Alt-${level}`]: () => this.editor.commands.toggleHeading({ level })
327
+ }
328
+ }),
329
+ {}
330
+ );
331
+ },
332
+ addInputRules() {
333
+ return this.options.levels.map((level) => {
334
+ return AccentCursive.textblockTypeInputRule({
335
+ find: new RegExp(`^(#{${Math.min(...this.options.levels)},${level}})\\s$`),
336
+ type: this.type,
337
+ getAttributes: {
338
+ level
339
+ }
340
+ });
341
+ });
342
+ }
343
+ });
344
+ var index_default = Heading;
345
+ const HeadingWithSEOTag = index_default.extend({
346
+ addAttributes() {
347
+ return {
348
+ ...this.parent?.(),
349
+ // must cast to any to avoid TS error
350
+ tag: { default: null }
351
+ };
352
+ }
353
+ }).configure({ levels: [1, 2, 3, 4] });
354
+ function useHeading(editor, props = { disabled: false }) {
355
+ const editorState = react.useEditorState({
356
+ editor,
357
+ selector: (ctx) => {
358
+ return {
359
+ headingLevel: ctx.editor.getAttributes("heading").level,
360
+ headingTag: ctx.editor.getAttributes("heading").tag,
361
+ isParagraph: ctx.editor.isActive("paragraph") ?? false
362
+ };
363
+ }
364
+ });
365
+ const onChangeHeading = (value) => {
366
+ if (!editor) return;
367
+ editor.chain().focus();
368
+ if (value === "p") {
369
+ editor.chain().focus().setParagraph().run();
370
+ return;
371
+ }
372
+ const level = Number(value[1]);
373
+ editor.chain().focus().setHeading({ level }).run();
374
+ if (!editorState.headingTag) {
375
+ editor.chain().focus().updateAttributes("heading", { tag: `h${level}` }).run();
376
+ }
377
+ };
378
+ const onChangeHeadingTag = (value) => {
379
+ if (!editor) return;
380
+ if (!editorState.headingLevel) return;
381
+ editor.chain().focus().updateAttributes("heading", { tag: value }).run();
382
+ };
383
+ return {
384
+ headingSelect: /* @__PURE__ */ jsxRuntime.jsxs(
385
+ designSystem.SingleSelect,
386
+ {
387
+ placeholder: "Style",
388
+ "aria-label": "Text style",
389
+ value: editorState.headingLevel ? `h${editorState.headingLevel}` : "p",
390
+ onChange: (v) => v && onChangeHeading(v),
391
+ disabled: !editor || props.disabled,
392
+ size: "S",
393
+ children: [
394
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "p", children: "Paragraph" }),
395
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "h1", children: "Heading 1" }),
396
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "h2", children: "Heading 2" }),
397
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "h3", children: "Heading 3" }),
398
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "h4", children: "Heading 4" })
399
+ ]
400
+ }
401
+ ),
402
+ headingTagSelect: /* @__PURE__ */ jsxRuntime.jsxs(
403
+ designSystem.SingleSelect,
404
+ {
405
+ placeholder: "SEO Tag",
406
+ "aria-label": "Heading's HTML tag for SEO purposes",
407
+ value: editorState.headingTag,
408
+ onChange: (v) => v && onChangeHeadingTag(v),
409
+ disabled: !editor || props.disabled || !editorState.headingLevel,
410
+ size: "S",
411
+ children: [
412
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "h1", children: "h1" }),
413
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "h2", children: "h2" }),
414
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "h3", children: "h3" }),
415
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "h4", children: "h4" }),
416
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "h5", children: "h5" }),
417
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "h6", children: "h6" })
418
+ ]
419
+ }
420
+ )
421
+ };
422
+ }
423
+ function useScript(editor, props = { disabled: false }) {
424
+ const editorState = react.useEditorState({
425
+ editor,
426
+ selector: (ctx) => {
427
+ return {
428
+ isSuperscript: ctx.editor.isActive("superscript") ?? false,
429
+ canToggleSuperscript: ctx.editor.can().chain().toggleSuperscript().run() ?? false,
430
+ isSubscript: ctx.editor.isActive("subscript") ?? false,
431
+ canToggleSubscript: ctx.editor.can().chain().toggleSubscript().run() ?? false
432
+ };
433
+ }
434
+ });
435
+ const toggleSuperscript = () => {
436
+ editor?.chain().focus().toggleSuperscript().run();
437
+ };
438
+ const toggleSubscript = () => {
439
+ editor?.chain().focus().toggleSubscript().run();
440
+ };
441
+ return {
442
+ superscriptButton: AccentCursive.toolbarButton("superscript", {
443
+ onClick: toggleSuperscript,
444
+ icon: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
445
+ "x",
446
+ /* @__PURE__ */ jsxRuntime.jsx("sup", { children: "2" })
447
+ ] }),
448
+ active: editorState.isSuperscript,
449
+ disabled: props.disabled || !editor || !editorState.canToggleSuperscript,
450
+ tooltip: "Superscript"
451
+ }),
452
+ subscriptButton: AccentCursive.toolbarButton("subscript", {
453
+ onClick: toggleSubscript,
454
+ icon: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
455
+ "x",
456
+ /* @__PURE__ */ jsxRuntime.jsx("sub", { children: "2" })
457
+ ] }),
458
+ active: editorState.isSubscript,
459
+ disabled: props.disabled || !editor || !editorState.canToggleSubscript,
460
+ tooltip: "Subscript"
461
+ })
462
+ };
463
+ }
464
+ AccentCursive.Extension.create({
465
+ name: "characterCount",
466
+ addOptions() {
467
+ return {
468
+ limit: null,
469
+ mode: "textSize",
470
+ textCounter: (text) => text.length,
471
+ wordCounter: (text) => text.split(" ").filter((word) => word !== "").length
472
+ };
473
+ },
474
+ addStorage() {
475
+ return {
476
+ characters: () => 0,
477
+ words: () => 0
478
+ };
479
+ },
480
+ onBeforeCreate() {
481
+ this.storage.characters = (options) => {
482
+ const node = (options == null ? void 0 : options.node) || this.editor.state.doc;
483
+ const mode = (options == null ? void 0 : options.mode) || this.options.mode;
484
+ if (mode === "textSize") {
485
+ const text = node.textBetween(0, node.content.size, void 0, " ");
486
+ return this.options.textCounter(text);
487
+ }
488
+ return node.nodeSize;
489
+ };
490
+ this.storage.words = (options) => {
491
+ const node = (options == null ? void 0 : options.node) || this.editor.state.doc;
492
+ const text = node.textBetween(0, node.content.size, " ", " ");
493
+ return this.options.wordCounter(text);
494
+ };
495
+ },
496
+ addProseMirrorPlugins() {
497
+ let initialEvaluationDone = false;
498
+ return [
499
+ new state.Plugin({
500
+ key: new state.PluginKey("characterCount"),
501
+ appendTransaction: (transactions, oldState, newState) => {
502
+ if (initialEvaluationDone) {
503
+ return;
504
+ }
505
+ const limit = this.options.limit;
506
+ if (limit === null || limit === void 0 || limit === 0) {
507
+ initialEvaluationDone = true;
508
+ return;
509
+ }
510
+ const initialContentSize = this.storage.characters({ node: newState.doc });
511
+ if (initialContentSize > limit) {
512
+ const over = initialContentSize - limit;
513
+ const from = 0;
514
+ const to = over;
515
+ console.warn(
516
+ `[CharacterCount] Initial content exceeded limit of ${limit} characters. Content was automatically trimmed.`
517
+ );
518
+ const tr = newState.tr.deleteRange(from, to);
519
+ initialEvaluationDone = true;
520
+ return tr;
521
+ }
522
+ initialEvaluationDone = true;
523
+ },
524
+ filterTransaction: (transaction, state2) => {
525
+ const limit = this.options.limit;
526
+ if (!transaction.docChanged || limit === 0 || limit === null || limit === void 0) {
527
+ return true;
528
+ }
529
+ const oldSize = this.storage.characters({ node: state2.doc });
530
+ const newSize = this.storage.characters({ node: transaction.doc });
531
+ if (newSize <= limit) {
532
+ return true;
533
+ }
534
+ if (oldSize > limit && newSize > limit && newSize <= oldSize) {
535
+ return true;
536
+ }
537
+ if (oldSize > limit && newSize > limit && newSize > oldSize) {
538
+ return false;
539
+ }
540
+ const isPaste = transaction.getMeta("paste");
541
+ if (!isPaste) {
542
+ return false;
543
+ }
544
+ const pos = transaction.selection.$head.pos;
545
+ const over = newSize - limit;
546
+ const from = pos - over;
547
+ const to = pos;
548
+ transaction.deleteRange(from, to);
549
+ const updatedSize = this.storage.characters({ node: transaction.doc });
550
+ if (updatedSize > limit) {
551
+ return false;
552
+ }
553
+ return true;
554
+ }
555
+ })
556
+ ];
557
+ }
558
+ });
559
+ AccentCursive.Extension.create({
560
+ name: "dropCursor",
561
+ addOptions() {
562
+ return {
563
+ color: "currentColor",
564
+ width: 1,
565
+ class: void 0
566
+ };
567
+ },
568
+ addProseMirrorPlugins() {
569
+ return [dropcursor.dropCursor(this.options)];
570
+ }
571
+ });
572
+ AccentCursive.Extension.create({
573
+ name: "focus",
574
+ addOptions() {
575
+ return {
576
+ className: "has-focus",
577
+ mode: "all"
578
+ };
579
+ },
580
+ addProseMirrorPlugins() {
581
+ return [
582
+ new state.Plugin({
583
+ key: new state.PluginKey("focus"),
584
+ props: {
585
+ decorations: ({ doc, selection }) => {
586
+ const { isEditable, isFocused } = this.editor;
587
+ const { anchor } = selection;
588
+ const decorations = [];
589
+ if (!isEditable || !isFocused) {
590
+ return view.DecorationSet.create(doc, []);
591
+ }
592
+ let maxLevels = 0;
593
+ if (this.options.mode === "deepest") {
594
+ doc.descendants((node, pos) => {
595
+ if (node.isText) {
596
+ return;
597
+ }
598
+ const isCurrent = anchor >= pos && anchor <= pos + node.nodeSize - 1;
599
+ if (!isCurrent) {
600
+ return false;
601
+ }
602
+ maxLevels += 1;
603
+ });
604
+ }
605
+ let currentLevel = 0;
606
+ doc.descendants((node, pos) => {
607
+ if (node.isText) {
608
+ return false;
609
+ }
610
+ const isCurrent = anchor >= pos && anchor <= pos + node.nodeSize - 1;
611
+ if (!isCurrent) {
612
+ return false;
613
+ }
614
+ currentLevel += 1;
615
+ const outOfScope = this.options.mode === "deepest" && maxLevels - currentLevel > 0 || this.options.mode === "shallowest" && currentLevel > 1;
616
+ if (outOfScope) {
617
+ return this.options.mode === "deepest";
618
+ }
619
+ decorations.push(
620
+ view.Decoration.node(pos, pos + node.nodeSize, {
621
+ class: this.options.className
622
+ })
623
+ );
624
+ });
625
+ return view.DecorationSet.create(doc, decorations);
626
+ }
627
+ }
628
+ })
629
+ ];
630
+ }
631
+ });
632
+ var Gapcursor = AccentCursive.Extension.create({
633
+ name: "gapCursor",
634
+ addProseMirrorPlugins() {
635
+ return [gapcursor.gapCursor()];
636
+ },
637
+ extendNodeSchema(extension) {
638
+ var _a;
639
+ const context = {
640
+ name: extension.name,
641
+ options: extension.options,
642
+ storage: extension.storage
643
+ };
644
+ return {
645
+ allowGapCursor: (_a = AccentCursive.callOrReturn(AccentCursive.getExtensionField(extension, "allowGapCursor", context))) != null ? _a : null
646
+ };
647
+ }
648
+ });
649
+ var DEFAULT_DATA_ATTRIBUTE = "placeholder";
650
+ function preparePlaceholderAttribute(attr) {
651
+ return attr.replace(/\s+/g, "-").replace(/[^a-zA-Z0-9-]/g, "").replace(/^[0-9-]+/, "").replace(/^-+/, "").toLowerCase();
652
+ }
653
+ AccentCursive.Extension.create({
654
+ name: "placeholder",
655
+ addOptions() {
656
+ return {
657
+ emptyEditorClass: "is-editor-empty",
658
+ emptyNodeClass: "is-empty",
659
+ dataAttribute: DEFAULT_DATA_ATTRIBUTE,
660
+ placeholder: "Write something …",
661
+ showOnlyWhenEditable: true,
662
+ showOnlyCurrent: true,
663
+ includeChildren: false
664
+ };
665
+ },
666
+ addProseMirrorPlugins() {
667
+ const dataAttribute = this.options.dataAttribute ? `data-${preparePlaceholderAttribute(this.options.dataAttribute)}` : `data-${DEFAULT_DATA_ATTRIBUTE}`;
668
+ return [
669
+ new state.Plugin({
670
+ key: new state.PluginKey("placeholder"),
671
+ props: {
672
+ decorations: ({ doc, selection }) => {
673
+ const active = this.editor.isEditable || !this.options.showOnlyWhenEditable;
674
+ const { anchor } = selection;
675
+ const decorations = [];
676
+ if (!active) {
677
+ return null;
678
+ }
679
+ const isEmptyDoc = this.editor.isEmpty;
680
+ doc.descendants((node, pos) => {
681
+ const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize;
682
+ const isEmpty = !node.isLeaf && AccentCursive.isNodeEmpty(node);
683
+ if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) {
684
+ const classes = [this.options.emptyNodeClass];
685
+ if (isEmptyDoc) {
686
+ classes.push(this.options.emptyEditorClass);
687
+ }
688
+ const decoration = view.Decoration.node(pos, pos + node.nodeSize, {
689
+ class: classes.join(" "),
690
+ [dataAttribute]: typeof this.options.placeholder === "function" ? this.options.placeholder({
691
+ editor: this.editor,
692
+ node,
693
+ pos,
694
+ hasAnchor
695
+ }) : this.options.placeholder
696
+ });
697
+ decorations.push(decoration);
698
+ }
699
+ return this.options.includeChildren;
700
+ });
701
+ return view.DecorationSet.create(doc, decorations);
702
+ }
703
+ }
704
+ })
705
+ ];
706
+ }
707
+ });
708
+ AccentCursive.Extension.create({
709
+ name: "selection",
710
+ addOptions() {
711
+ return {
712
+ className: "selection"
713
+ };
714
+ },
715
+ addProseMirrorPlugins() {
716
+ const { editor, options } = this;
717
+ return [
718
+ new state.Plugin({
719
+ key: new state.PluginKey("selection"),
720
+ props: {
721
+ decorations(state2) {
722
+ if (state2.selection.empty || editor.isFocused || !editor.isEditable || AccentCursive.isNodeSelection(state2.selection) || editor.view.dragging) {
723
+ return null;
724
+ }
725
+ return view.DecorationSet.create(state2.doc, [
726
+ view.Decoration.inline(state2.selection.from, state2.selection.to, {
727
+ class: options.className
728
+ })
729
+ ]);
730
+ }
731
+ }
732
+ })
733
+ ];
734
+ }
735
+ });
736
+ function nodeEqualsType({ types, node }) {
737
+ return node && Array.isArray(types) && types.includes(node.type) || (node == null ? void 0 : node.type) === types;
738
+ }
739
+ AccentCursive.Extension.create({
740
+ name: "trailingNode",
741
+ addOptions() {
742
+ return {
743
+ node: void 0,
744
+ notAfter: []
745
+ };
746
+ },
747
+ addProseMirrorPlugins() {
748
+ var _a;
749
+ const plugin = new state.PluginKey(this.name);
750
+ const defaultNode = this.options.node || ((_a = this.editor.schema.topNodeType.contentMatch.defaultType) == null ? void 0 : _a.name) || "paragraph";
751
+ const disabledNodes = Object.entries(this.editor.schema.nodes).map(([, value]) => value).filter((node) => (this.options.notAfter || []).concat(defaultNode).includes(node.name));
752
+ return [
753
+ new state.Plugin({
754
+ key: plugin,
755
+ appendTransaction: (_, __, state2) => {
756
+ const { doc, tr, schema } = state2;
757
+ const shouldInsertNodeAtEnd = plugin.getState(state2);
758
+ const endPosition = doc.content.size;
759
+ const type = schema.nodes[defaultNode];
760
+ if (!shouldInsertNodeAtEnd) {
761
+ return;
762
+ }
763
+ return tr.insert(endPosition, type.create());
764
+ },
765
+ state: {
766
+ init: (_, state2) => {
767
+ const lastNode = state2.tr.doc.lastChild;
768
+ return !nodeEqualsType({ node: lastNode, types: disabledNodes });
769
+ },
770
+ apply: (tr, value) => {
771
+ if (!tr.docChanged) {
772
+ return value;
773
+ }
774
+ if (tr.getMeta("__uniqueIDTransaction")) {
775
+ return value;
776
+ }
777
+ const lastNode = tr.doc.lastChild;
778
+ return !nodeEqualsType({ node: lastNode, types: disabledNodes });
779
+ }
780
+ }
781
+ })
782
+ ];
783
+ }
784
+ });
785
+ AccentCursive.Extension.create({
786
+ name: "undoRedo",
787
+ addOptions() {
788
+ return {
789
+ depth: 100,
790
+ newGroupDelay: 500
791
+ };
792
+ },
793
+ addCommands() {
794
+ return {
795
+ undo: () => ({ state: state2, dispatch }) => {
796
+ return history.undo(state2, dispatch);
797
+ },
798
+ redo: () => ({ state: state2, dispatch }) => {
799
+ return history.redo(state2, dispatch);
800
+ }
801
+ };
802
+ },
803
+ addProseMirrorPlugins() {
804
+ return [history.history(this.options)];
805
+ },
806
+ addKeyboardShortcuts() {
807
+ return {
808
+ "Mod-z": () => this.editor.commands.undo(),
809
+ "Shift-Mod-z": () => this.editor.commands.redo(),
810
+ "Mod-y": () => this.editor.commands.redo(),
811
+ // Russian keyboard layouts
812
+ "Mod-я": () => this.editor.commands.undo(),
813
+ "Shift-Mod-я": () => this.editor.commands.redo()
814
+ };
815
+ }
816
+ });
817
+ const clamp = (val, min, max) => Math.max(min, Math.min(max, val));
818
+ const parseNum = (value, fallback) => {
819
+ const n = Number(value);
820
+ return Number.isFinite(n) ? n : fallback;
821
+ };
822
+ const TableSizeDialog = ({
823
+ open,
824
+ defaultRows = 3,
825
+ defaultCols = 3,
826
+ onClose,
827
+ onSave
828
+ }) => {
829
+ const [rows, setRows] = React.useState(defaultRows);
830
+ const [cols, setCols] = React.useState(defaultCols);
831
+ React.useEffect(() => {
832
+ if (open) {
833
+ setRows(defaultRows);
834
+ setCols(defaultCols);
835
+ }
836
+ }, [open, defaultRows, defaultCols]);
837
+ const min = 1;
838
+ const max = 10;
839
+ const isValid = rows >= min && rows <= max && cols >= min && cols <= max;
840
+ const handleSave = () => {
841
+ if (!isValid) return;
842
+ onSave(clamp(rows, min, max), clamp(cols, min, max));
843
+ };
844
+ return /* @__PURE__ */ jsxRuntime.jsx(
845
+ designSystem.Dialog.Root,
846
+ {
847
+ open,
848
+ onOpenChange: (v) => {
849
+ if (!v) onClose();
850
+ },
851
+ children: open && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
852
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: "Insert table" }),
853
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, alignItems: "flex-end", children: [
854
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { width: "100%", children: [
855
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Rows" }),
856
+ /* @__PURE__ */ jsxRuntime.jsx(
857
+ designSystem.TextInput,
858
+ {
859
+ name: "table-rows",
860
+ type: "number",
861
+ value: String(rows),
862
+ onChange: (e) => setRows(clamp(parseNum(e.target.value, rows), min, max)),
863
+ placeholder: String(defaultRows)
864
+ }
865
+ ),
866
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Hint, { children: [
867
+ "Min ",
868
+ min,
869
+ ", max ",
870
+ max
871
+ ] })
872
+ ] }),
873
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { width: "100%", children: [
874
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Columns" }),
875
+ /* @__PURE__ */ jsxRuntime.jsx(
876
+ designSystem.TextInput,
877
+ {
878
+ name: "table-cols",
879
+ type: "number",
880
+ value: String(cols),
881
+ onChange: (e) => setCols(clamp(parseNum(e.target.value, cols), min, max)),
882
+ placeholder: String(defaultCols)
883
+ }
884
+ ),
885
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Hint, { children: [
886
+ "Min ",
887
+ min,
888
+ ", max ",
889
+ max
890
+ ] })
891
+ ] })
892
+ ] }) }),
893
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
894
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", fullWidth: true, onClick: onClose, children: "Cancel" }) }),
895
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Action, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { fullWidth: true, variant: "success-light", onClick: handleSave, disabled: !isValid, children: "Insert" }) })
896
+ ] })
897
+ ] })
898
+ }
899
+ );
900
+ };
901
+ function useTable(editor, props = { disabled: false }) {
902
+ const editorState = react.useEditorState({
903
+ editor,
904
+ selector: (ctx) => {
905
+ return {
906
+ isTable: ctx.editor.isActive("table") ?? false,
907
+ canInsertTable: ctx.editor.can().chain().insertTable().run() ?? false,
908
+ canAddColumn: ctx.editor.can().chain().addColumnAfter().run() ?? false,
909
+ canDeleteColumn: ctx.editor.can().chain().deleteColumn().run() ?? false,
910
+ canAddRow: ctx.editor.can().chain().addRowAfter().run() ?? false,
911
+ canDeleteRow: ctx.editor.can().chain().deleteRow().run() ?? false
912
+ };
913
+ }
914
+ });
915
+ const [open, setOpen] = React.useState(false);
916
+ const handleOpenDialog = () => {
917
+ if (!editor) return;
918
+ setOpen(true);
919
+ };
920
+ const handleInsert = (rows, cols) => {
921
+ if (!editor) return;
922
+ editor.chain().focus().insertTable({ rows, cols, withHeaderRow: true }).run();
923
+ setOpen(false);
924
+ };
925
+ const addColumn = () => editor?.chain().focus().addColumnAfter().run();
926
+ const removeColumn = () => editor?.chain().focus().deleteColumn().run();
927
+ const addRow = () => editor?.chain().focus().addRowAfter().run();
928
+ const removeRow = () => editor?.chain().focus().deleteRow().run();
929
+ return {
930
+ tableButton: AccentCursive.toolbarButton("table", {
931
+ onClick: handleOpenDialog,
932
+ icon: /* @__PURE__ */ jsxRuntime.jsx(icons.GridNine, {}),
933
+ active: editorState.isTable,
934
+ disabled: props.disabled || !editor || !editorState.canInsertTable,
935
+ tooltip: "Table"
936
+ }),
937
+ // Adding table manipulation buttons
938
+ addColumnButton: AccentCursive.toolbarButton("tableAddColumn", {
939
+ onClick: addColumn,
940
+ icon: /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: "+Col" }),
941
+ active: false,
942
+ hidden: props.disabled || !editor || !editorState.canAddColumn,
943
+ tooltip: "Add column (to the right)"
944
+ }),
945
+ removeColumnButton: AccentCursive.toolbarButton("tableRemoveColumn", {
946
+ onClick: removeColumn,
947
+ icon: /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: "-Col" }),
948
+ active: false,
949
+ hidden: props.disabled || !editor || !editorState.canDeleteColumn,
950
+ tooltip: "Remove column"
951
+ }),
952
+ addRowButton: AccentCursive.toolbarButton("tableAddRow", {
953
+ onClick: addRow,
954
+ icon: /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: "+Row" }),
955
+ active: false,
956
+ hidden: props.disabled || !editor || !editorState.canAddRow,
957
+ tooltip: "Add row (below)"
958
+ }),
959
+ removeRowButton: AccentCursive.toolbarButton("tableRemoveRow", {
960
+ onClick: removeRow,
961
+ icon: /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: "-Row" }),
962
+ active: false,
963
+ hidden: props.disabled || !editor || !editorState.canDeleteRow,
964
+ tooltip: "Remove row"
965
+ }),
966
+ tableDialog: /* @__PURE__ */ jsxRuntime.jsx(
967
+ TableSizeDialog,
968
+ {
969
+ open,
970
+ onClose: () => setOpen(false),
971
+ onSave: handleInsert,
972
+ defaultRows: 3,
973
+ defaultCols: 3
974
+ }
975
+ )
976
+ };
977
+ }
978
+ function TextAlignLeft(props) {
979
+ return /* @__PURE__ */ jsxRuntime.jsx(
980
+ "svg",
981
+ {
982
+ width: "16",
983
+ height: "16",
984
+ viewBox: "0 0 24 24",
985
+ fill: "currentColor",
986
+ xmlns: "http://www.w3.org/2000/svg",
987
+ ...props,
988
+ children: /* @__PURE__ */ jsxRuntime.jsx(
989
+ "path",
990
+ {
991
+ d: "M3 10H16M3 14H21M3 18H16M3 6H21",
992
+ stroke: "#000000",
993
+ "stroke-width": "2",
994
+ "stroke-linecap": "round",
995
+ "stroke-linejoin": "round"
996
+ }
997
+ )
998
+ }
999
+ );
1000
+ }
1001
+ function TextAlignJustify(props) {
1002
+ return /* @__PURE__ */ jsxRuntime.jsx(
1003
+ "svg",
1004
+ {
1005
+ width: "16",
1006
+ height: "16",
1007
+ viewBox: "0 0 24 24",
1008
+ fill: "currentColor",
1009
+ xmlns: "http://www.w3.org/2000/svg",
1010
+ ...props,
1011
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1012
+ "path",
1013
+ {
1014
+ d: "M3 10H21M3 14H21M3 18H21M3 6H21",
1015
+ stroke: "#000000",
1016
+ "stroke-width": "2",
1017
+ "stroke-linecap": "round",
1018
+ "stroke-linejoin": "round"
1019
+ }
1020
+ )
1021
+ }
1022
+ );
1023
+ }
1024
+ function TextAlignRight(props) {
1025
+ return /* @__PURE__ */ jsxRuntime.jsx(
1026
+ "svg",
1027
+ {
1028
+ width: "16",
1029
+ height: "16",
1030
+ viewBox: "0 0 24 24",
1031
+ fill: "currentColor",
1032
+ xmlns: "http://www.w3.org/2000/svg",
1033
+ ...props,
1034
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1035
+ "path",
1036
+ {
1037
+ d: "M8 10H21M3 14H21M8 18H21M3 6H21",
1038
+ stroke: "#000000",
1039
+ "stroke-width": "2",
1040
+ "stroke-linecap": "round",
1041
+ "stroke-linejoin": "round"
1042
+ }
1043
+ )
1044
+ }
1045
+ );
1046
+ }
1047
+ function TextAlignCenter(props) {
1048
+ return /* @__PURE__ */ jsxRuntime.jsx(
1049
+ "svg",
1050
+ {
1051
+ width: "16",
1052
+ height: "16",
1053
+ viewBox: "0 0 24 24",
1054
+ fill: "currentColor",
1055
+ xmlns: "http://www.w3.org/2000/svg",
1056
+ ...props,
1057
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1058
+ "path",
1059
+ {
1060
+ d: "M3 6H21M3 14H21M17 10H7M17 18H7",
1061
+ stroke: "#000000",
1062
+ "stroke-width": "2",
1063
+ "stroke-linecap": "round",
1064
+ "stroke-linejoin": "round"
1065
+ }
1066
+ )
1067
+ }
1068
+ );
1069
+ }
1070
+ function useTextAlign(editor, props = { disabled: false }) {
1071
+ const editorState = react.useEditorState({
1072
+ editor,
1073
+ selector: (ctx) => {
1074
+ return {
1075
+ isTextAlignLeft: ctx.editor.isActive({ textAlign: "left" }) ?? false,
1076
+ isTextAlignRight: ctx.editor.isActive({ textAlign: "right" }) ?? false,
1077
+ isTextAlignCenter: ctx.editor.isActive({ textAlign: "center" }) ?? false,
1078
+ isTextAlignJustify: ctx.editor.isActive({ textAlign: "justify" }) ?? false,
1079
+ canToggleAlign: ctx.editor.can().chain().setTextAlign("left").run() ?? false
1080
+ };
1081
+ }
1082
+ });
1083
+ const setTextAlign = (alignment) => {
1084
+ editor.chain().focus().setTextAlign(alignment).run();
1085
+ };
1086
+ return {
1087
+ textAlignLeftButton: AccentCursive.toolbarButton("text-align-left", {
1088
+ onClick: () => setTextAlign("left"),
1089
+ icon: /* @__PURE__ */ jsxRuntime.jsx(TextAlignLeft, {}),
1090
+ active: editorState.isTextAlignLeft,
1091
+ disabled: props.disabled || !editor || !editorState.canToggleAlign,
1092
+ tooltip: "Text Align Left"
1093
+ }),
1094
+ textAlignCenterButton: AccentCursive.toolbarButton("text-align-center", {
1095
+ onClick: () => setTextAlign("center"),
1096
+ icon: /* @__PURE__ */ jsxRuntime.jsx(TextAlignCenter, {}),
1097
+ active: editorState.isTextAlignCenter,
1098
+ disabled: props.disabled || !editor || !editorState.canToggleAlign,
1099
+ tooltip: "Text Align Center"
1100
+ }),
1101
+ textAlignRightButton: AccentCursive.toolbarButton("text-align-right", {
1102
+ onClick: () => setTextAlign("right"),
1103
+ icon: /* @__PURE__ */ jsxRuntime.jsx(TextAlignRight, {}),
1104
+ active: editorState.isTextAlignRight,
1105
+ disabled: props.disabled || !editor || !editorState.canToggleAlign,
1106
+ tooltip: "Text Align Right"
1107
+ }),
1108
+ textAlignJustifyButton: AccentCursive.toolbarButton("text-align-justify", {
1109
+ onClick: () => setTextAlign("justify"),
1110
+ icon: /* @__PURE__ */ jsxRuntime.jsx(TextAlignJustify, {}),
1111
+ active: editorState.isTextAlignJustify,
1112
+ disabled: props.disabled || !editor || !editorState.canToggleAlign,
1113
+ tooltip: "Text Align Justify"
1114
+ })
1115
+ };
1116
+ }
1117
+ const extensions = [
1118
+ StarterKit__default.default.configure({
1119
+ heading: false,
1120
+ // disable default so we can use our custom version
1121
+ link: {
1122
+ openOnClick: false
1123
+ }
1124
+ }),
1125
+ HeadingWithSEOTag,
1126
+ AccentCursive.AccentCursiveMark,
1127
+ Superscript__default.default,
1128
+ Subscript__default.default,
1129
+ Gapcursor,
1130
+ // cursor for resizing tables
1131
+ extensionTable.TableKit.configure({
1132
+ table: { resizable: true }
1133
+ }),
1134
+ TextAlign__default.default.configure({
1135
+ types: ["heading", "paragraph"]
1136
+ })
1137
+ ];
1138
+ const RichTextInput = React.forwardRef((props, forwardedRef) => {
1139
+ const { editor, field } = AccentCursive.useTiptapEditor(props.name, "", extensions);
1140
+ const starterKit = useStarterKit(editor, { disabled: props.disabled });
1141
+ const heading = useHeading(editor, { disabled: props.disabled });
1142
+ const accentCursive = AccentCursive.useAccentCursive(editor, { disabled: props.disabled });
1143
+ const link = useLink(editor, { disabled: props.disabled });
1144
+ const script = useScript(editor, { disabled: props.disabled });
1145
+ const table = useTable(editor, { disabled: props.disabled });
1146
+ const textAlign = useTextAlign(editor, { disabled: props.disabled });
1147
+ return /* @__PURE__ */ jsxRuntime.jsxs(AccentCursive.BaseTiptapInput, { editor, field, ...props, ref: forwardedRef, children: [
1148
+ heading.headingSelect,
1149
+ heading.headingTagSelect,
1150
+ AccentCursive.spacer(8),
1151
+ starterKit.boldButton,
1152
+ starterKit.italicButton,
1153
+ accentCursive.button,
1154
+ starterKit.underlineButton,
1155
+ starterKit.strikeButton,
1156
+ script.superscriptButton,
1157
+ script.subscriptButton,
1158
+ AccentCursive.spacer(8),
1159
+ textAlign.textAlignLeftButton,
1160
+ textAlign.textAlignCenterButton,
1161
+ textAlign.textAlignRightButton,
1162
+ textAlign.textAlignJustifyButton,
1163
+ AccentCursive.spacer(8),
1164
+ starterKit.bulletButton,
1165
+ starterKit.orderedButton,
1166
+ AccentCursive.spacer(8),
1167
+ starterKit.codeButton,
1168
+ starterKit.blockquoteButton,
1169
+ link.linkButton,
1170
+ link.linkDialog,
1171
+ AccentCursive.spacer(8),
1172
+ table.tableButton,
1173
+ table.addColumnButton,
1174
+ table.removeColumnButton,
1175
+ table.addRowButton,
1176
+ table.removeRowButton,
1177
+ table.tableDialog
1178
+ ] });
1179
+ });
1180
+ exports.default = RichTextInput;
1181
+ //# sourceMappingURL=RichTextInput-DG-36krM.js.map