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

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 (80) hide show
  1. package/README.md +85 -55
  2. package/dist/_chunks/{RichTextInput-BZQ2iVqa.mjs → RichTextInput-COGVRWOW.mjs} +786 -596
  3. package/dist/_chunks/RichTextInput-COGVRWOW.mjs.map +1 -0
  4. package/dist/_chunks/{RichTextInput-BlxoJMa2.js → RichTextInput-Wc2q__HY.js} +785 -595
  5. package/dist/_chunks/RichTextInput-Wc2q__HY.js.map +1 -0
  6. package/dist/admin/index.js +23 -1
  7. package/dist/admin/index.js.map +1 -1
  8. package/dist/admin/index.mjs +23 -1
  9. package/dist/admin/index.mjs.map +1 -1
  10. package/dist/admin/src/components/BaseTiptapInput.d.ts +1 -0
  11. package/dist/admin/src/components/EditorErrorBoundary.d.ts +23 -0
  12. package/dist/admin/src/components/FeatureGuard.d.ts +15 -0
  13. package/dist/admin/src/components/PresetSelect.d.ts +7 -0
  14. package/dist/admin/src/extensions/Heading.d.ts +1 -0
  15. package/dist/admin/src/fields/richTextField.d.ts +18 -0
  16. package/dist/admin/src/hooks/usePresetConfig.d.ts +6 -0
  17. package/dist/admin/src/utils/buildExtensions.d.ts +3 -0
  18. package/dist/server/index.js +154 -6
  19. package/dist/server/index.js.map +1 -1
  20. package/dist/server/index.mjs +153 -6
  21. package/dist/server/index.mjs.map +1 -1
  22. package/dist/server/src/config/index.d.ts +7 -4
  23. package/dist/server/src/controllers/index.d.ts +8 -1
  24. package/dist/server/src/controllers/preset.d.ts +8 -0
  25. package/dist/server/src/index.d.ts +43 -5
  26. package/dist/server/src/routes/index.d.ts +15 -1
  27. package/dist/server/src/services/index.d.ts +9 -1
  28. package/dist/server/src/services/preset.d.ts +10 -0
  29. package/dist/shared/types.d.ts +54 -0
  30. package/package.json +11 -3
  31. package/dist/_chunks/AccentCursive-CpAPpH9C.mjs +0 -3383
  32. package/dist/_chunks/AccentCursive-CpAPpH9C.mjs.map +0 -1
  33. package/dist/_chunks/AccentCursive-D6sTlhub.js +0 -3384
  34. package/dist/_chunks/AccentCursive-D6sTlhub.js.map +0 -1
  35. package/dist/_chunks/FormattedHeadingInput-DycgfIze.mjs +0 -101
  36. package/dist/_chunks/FormattedHeadingInput-DycgfIze.mjs.map +0 -1
  37. package/dist/_chunks/FormattedHeadingInput-FFjiRSEJ.js +0 -101
  38. package/dist/_chunks/FormattedHeadingInput-FFjiRSEJ.js.map +0 -1
  39. package/dist/_chunks/RichTextInput-BZQ2iVqa.mjs.map +0 -1
  40. package/dist/_chunks/RichTextInput-BbbQxPc-.js +0 -4414
  41. package/dist/_chunks/RichTextInput-BbbQxPc-.js.map +0 -1
  42. package/dist/_chunks/RichTextInput-BjLR2pi0.js +0 -4416
  43. package/dist/_chunks/RichTextInput-BjLR2pi0.js.map +0 -1
  44. package/dist/_chunks/RichTextInput-BlxoJMa2.js.map +0 -1
  45. package/dist/_chunks/RichTextInput-Bm3X8fR2.mjs +0 -4400
  46. package/dist/_chunks/RichTextInput-Bm3X8fR2.mjs.map +0 -1
  47. package/dist/_chunks/RichTextInput-Bms-gSvK.js +0 -4407
  48. package/dist/_chunks/RichTextInput-Bms-gSvK.js.map +0 -1
  49. package/dist/_chunks/RichTextInput-BtNjPJRN.mjs +0 -4400
  50. package/dist/_chunks/RichTextInput-BtNjPJRN.mjs.map +0 -1
  51. package/dist/_chunks/RichTextInput-Bw3tcXfp.js +0 -4407
  52. package/dist/_chunks/RichTextInput-Bw3tcXfp.js.map +0 -1
  53. package/dist/_chunks/RichTextInput-CsgNpoxq.mjs +0 -4409
  54. package/dist/_chunks/RichTextInput-CsgNpoxq.mjs.map +0 -1
  55. package/dist/_chunks/RichTextInput-CwTvEMda.js +0 -4407
  56. package/dist/_chunks/RichTextInput-CwTvEMda.js.map +0 -1
  57. package/dist/_chunks/RichTextInput-DG-36krM.js +0 -1181
  58. package/dist/_chunks/RichTextInput-DG-36krM.js.map +0 -1
  59. package/dist/_chunks/RichTextInput-DLac-zNQ.mjs +0 -4400
  60. package/dist/_chunks/RichTextInput-DLac-zNQ.mjs.map +0 -1
  61. package/dist/_chunks/RichTextInput-DSXttrvi.js +0 -4407
  62. package/dist/_chunks/RichTextInput-DSXttrvi.js.map +0 -1
  63. package/dist/_chunks/RichTextInput-DeJ6Exto.mjs +0 -4400
  64. package/dist/_chunks/RichTextInput-DeJ6Exto.mjs.map +0 -1
  65. package/dist/_chunks/RichTextInput-DgT88AkO.mjs +0 -1175
  66. package/dist/_chunks/RichTextInput-DgT88AkO.mjs.map +0 -1
  67. package/dist/_chunks/RichTextInput-DlMaDJQF.mjs +0 -4400
  68. package/dist/_chunks/RichTextInput-DlMaDJQF.mjs.map +0 -1
  69. package/dist/_chunks/RichTextInput-DtaYdjCs.mjs +0 -4400
  70. package/dist/_chunks/RichTextInput-DtaYdjCs.mjs.map +0 -1
  71. package/dist/_chunks/RichTextInput-YTKXo5oq.js +0 -4407
  72. package/dist/_chunks/RichTextInput-YTKXo5oq.js.map +0 -1
  73. package/dist/_chunks/RichTextInput-tmg-oMJk.mjs +0 -4407
  74. package/dist/_chunks/RichTextInput-tmg-oMJk.mjs.map +0 -1
  75. package/dist/_chunks/RichTextInput-umhMsI5o.js +0 -4407
  76. package/dist/_chunks/RichTextInput-umhMsI5o.js.map +0 -1
  77. package/dist/admin/src/components/FormattedHeadingInput.d.ts +0 -4
  78. package/dist/admin/src/extensions/AccentCursive.d.ts +0 -18
  79. package/dist/admin/src/fields/formattedHeadingField.d.ts +0 -20
  80. package/dist/admin/src/pluginId.d.ts +0 -1
@@ -1,1181 +0,0 @@
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