@firecms/core 3.3.0 → 3.4.0-canary.1faa2a9

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 (220) hide show
  1. package/README.md +4 -0
  2. package/dist/app/useApp.d.ts +1 -0
  3. package/dist/components/EntityCollectionTable/column_utils.d.ts +4 -3
  4. package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +6 -1
  5. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +3 -1
  6. package/dist/components/EntityCollectionView/EntityCollectionBoardView.d.ts +3 -1
  7. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +8 -0
  8. package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +3 -1
  9. package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +3 -1
  10. package/dist/components/EntityCollectionView/FiltersDialog.d.ts +2 -1
  11. package/dist/components/EntityCollectionView/useBoardDataController.d.ts +3 -1
  12. package/dist/components/EntityPreview.d.ts +3 -1
  13. package/dist/components/ErrorBoundary.d.ts +1 -3
  14. package/dist/components/LicenseBanner.d.ts +23 -0
  15. package/dist/components/ReferenceTable/ReferenceSelectionTable.d.ts +10 -1
  16. package/dist/components/SelectableTable/filters/filter_text_input.d.ts +30 -0
  17. package/dist/components/SelectableTable/filters/filter_text_input.test.d.ts +1 -0
  18. package/dist/components/common/table_url_params.d.ts +24 -0
  19. package/dist/components/common/useDataSourceTableController.d.ts +9 -1
  20. package/dist/components/common/useTableSearchHelper.d.ts +9 -1
  21. package/dist/components/index.d.ts +1 -0
  22. package/dist/contexts/LicenseStatusContext.d.ts +16 -0
  23. package/dist/core/DefaultDrawer.d.ts +10 -3
  24. package/dist/core/EntityEditView.d.ts +9 -1
  25. package/dist/core/EntityEditViewFormActions.d.ts +1 -1
  26. package/dist/core/field_configs.d.ts +1 -1
  27. package/dist/core/index.d.ts +1 -0
  28. package/dist/core/plugin_translations.d.ts +38 -0
  29. package/dist/core/pro_plugins.d.ts +40 -0
  30. package/dist/de-KtBROUvS.js +700 -0
  31. package/dist/de-KtBROUvS.js.map +1 -0
  32. package/dist/editor/extensions/Image.d.ts +11 -0
  33. package/dist/editor/index.d.ts +2 -1
  34. package/dist/editor/lazy_editor.d.ts +6 -0
  35. package/dist/editor-BSo_aS1I.js +4563 -0
  36. package/dist/editor-BSo_aS1I.js.map +1 -0
  37. package/dist/form/EntityForm.d.ts +8 -1
  38. package/dist/form/EntityFormActions.d.ts +2 -0
  39. package/dist/form/field_bindings/GeopointFieldBinding.d.ts +5 -0
  40. package/dist/form/index.d.ts +1 -0
  41. package/dist/fr-BRFSBaVh.js +700 -0
  42. package/dist/fr-BRFSBaVh.js.map +1 -0
  43. package/dist/hi-DwCkga5X.js +700 -0
  44. package/dist/hi-DwCkga5X.js.map +1 -0
  45. package/dist/hooks/data/delete.d.ts +1 -1
  46. package/dist/hooks/data/save.d.ts +1 -1
  47. package/dist/hooks/data/useCollectionFetch.d.ts +7 -1
  48. package/dist/hooks/data/useEntityFetch.d.ts +9 -1
  49. package/dist/hooks/index.d.ts +2 -0
  50. package/dist/hooks/useLicenseStatus.d.ts +16 -0
  51. package/dist/hooks/useProjectLog.d.ts +11 -6
  52. package/dist/hooks/useTranslation.d.ts +1 -1
  53. package/dist/i18n/__tests__/FireCMSi18nProvider.test.d.ts +1 -0
  54. package/dist/i18n/__tests__/nested_provider_lifecycle.test.d.ts +1 -0
  55. package/dist/index.es.js +4509 -10665
  56. package/dist/index.es.js.map +1 -1
  57. package/dist/index.umd.js +9378 -6771
  58. package/dist/index.umd.js.map +1 -1
  59. package/dist/it-B2YGgDsx.js +700 -0
  60. package/dist/it-B2YGgDsx.js.map +1 -0
  61. package/dist/locales/pl.d.ts +2 -0
  62. package/dist/pl-BxHkywK8.js +702 -0
  63. package/dist/pl-BxHkywK8.js.map +1 -0
  64. package/dist/preview/index.d.ts +1 -0
  65. package/dist/preview/property_previews/GeopointPropertyPreview.d.ts +4 -0
  66. package/dist/pt-q6UV4diT.js +702 -0
  67. package/dist/pt-q6UV4diT.js.map +1 -0
  68. package/dist/types/analytics.d.ts +1 -1
  69. package/dist/types/collections.d.ts +31 -0
  70. package/dist/types/datasource.d.ts +67 -4
  71. package/dist/types/entities.d.ts +21 -1
  72. package/dist/types/entity_actions.d.ts +6 -0
  73. package/dist/types/entity_callbacks.d.ts +21 -0
  74. package/dist/types/firecms.d.ts +18 -1
  75. package/dist/types/firecms_context.d.ts +8 -0
  76. package/dist/types/index.d.ts +1 -0
  77. package/dist/types/license.d.ts +54 -0
  78. package/dist/types/navigation.d.ts +34 -5
  79. package/dist/types/plugins.d.ts +22 -1
  80. package/dist/types/properties.d.ts +17 -1
  81. package/dist/types/side_entity_controller.d.ts +7 -0
  82. package/dist/types/translations.d.ts +37 -2
  83. package/dist/util/__tests__/collections.test.d.ts +1 -0
  84. package/dist/util/__tests__/urls.test.d.ts +1 -0
  85. package/dist/util/collections.d.ts +1 -1
  86. package/dist/util/date_fns_locales.d.ts +18 -0
  87. package/dist/util/entities.d.ts +1 -0
  88. package/dist/util/entity_cache.d.ts +11 -0
  89. package/dist/util/geopoint.d.ts +22 -0
  90. package/dist/util/index.d.ts +3 -0
  91. package/dist/util/lazy_eager.d.ts +3 -3
  92. package/dist/util/navigation_blocking.d.ts +22 -0
  93. package/dist/util/navigation_from_path.d.ts +17 -0
  94. package/dist/util/navigation_utils.d.ts +107 -3
  95. package/dist/util/parent_references_from_path.d.ts +16 -0
  96. package/dist/util/paths.d.ts +28 -0
  97. package/dist/util/permissions.d.ts +10 -4
  98. package/dist/util/urls.d.ts +22 -0
  99. package/package.json +17 -10
  100. package/src/app/Scaffold.tsx +41 -44
  101. package/src/app/useApp.tsx +1 -0
  102. package/src/components/DeleteEntityDialog.tsx +2 -0
  103. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +2 -2
  104. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +3 -1
  105. package/src/components/EntityCollectionTable/column_utils.tsx +11 -19
  106. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +1 -1
  107. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +7 -0
  108. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +5 -1
  109. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +12 -0
  110. package/src/components/EntityCollectionView/EntityCollectionView.tsx +66 -15
  111. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +6 -2
  112. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +8 -1
  113. package/src/components/EntityCollectionView/FiltersDialog.tsx +39 -28
  114. package/src/components/EntityCollectionView/useBoardDataController.tsx +17 -1
  115. package/src/components/EntityPreview.tsx +45 -41
  116. package/src/components/ErrorBoundary.tsx +12 -18
  117. package/src/components/LicenseBanner.tsx +209 -0
  118. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +19 -2
  119. package/src/components/ReferenceWidget.tsx +1 -1
  120. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +2 -2
  121. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +33 -7
  122. package/src/components/SelectableTable/filters/filter_text_input.test.ts +184 -0
  123. package/src/components/SelectableTable/filters/filter_text_input.ts +71 -0
  124. package/src/components/VirtualTable/VirtualTable.tsx +19 -8
  125. package/src/components/common/default_entity_actions.tsx +22 -2
  126. package/src/components/common/table_url_params.ts +172 -0
  127. package/src/components/common/useDataSourceTableController.tsx +126 -163
  128. package/src/components/common/useTableSearchHelper.ts +26 -2
  129. package/src/components/index.tsx +1 -0
  130. package/src/contexts/LicenseStatusContext.tsx +50 -0
  131. package/src/contexts/SnackbarProvider.tsx +14 -1
  132. package/src/core/DefaultAppBar.tsx +28 -16
  133. package/src/core/DefaultDrawer.tsx +150 -64
  134. package/src/core/DrawerNavigationGroup.tsx +27 -29
  135. package/src/core/DrawerNavigationItem.tsx +10 -12
  136. package/src/core/EntityEditView.tsx +77 -35
  137. package/src/core/EntityEditViewFormActions.tsx +3 -2
  138. package/src/core/EntitySidePanel.tsx +8 -4
  139. package/src/core/FireCMS.tsx +73 -47
  140. package/src/core/SideDialogs.tsx +44 -1
  141. package/src/core/field_configs.tsx +15 -0
  142. package/src/core/index.tsx +1 -0
  143. package/src/core/plugin_translations.ts +87 -0
  144. package/src/core/pro_plugins.ts +79 -0
  145. package/src/editor/components/SlashCommandMenu.tsx +4 -1
  146. package/src/editor/extensions/Image.ts +17 -1
  147. package/src/editor/hooks/useProseMirror.ts +5 -0
  148. package/src/editor/index.ts +11 -1
  149. package/src/editor/lazy_editor.tsx +33 -0
  150. package/src/form/EntityForm.tsx +31 -10
  151. package/src/form/EntityFormActions.tsx +2 -0
  152. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +1 -1
  153. package/src/form/field_bindings/GeopointFieldBinding.tsx +139 -0
  154. package/src/form/index.tsx +1 -0
  155. package/src/hooks/data/delete.ts +8 -0
  156. package/src/hooks/data/save.ts +6 -1
  157. package/src/hooks/data/useCollectionFetch.tsx +21 -1
  158. package/src/hooks/data/useEntityFetch.tsx +35 -4
  159. package/src/hooks/index.tsx +2 -0
  160. package/src/hooks/useBuildNavigationController.tsx +70 -15
  161. package/src/hooks/useFireCMSContext.tsx +7 -3
  162. package/src/hooks/useLicenseStatus.tsx +32 -0
  163. package/src/hooks/useProjectLog.tsx +27 -9
  164. package/src/hooks/useResolvedNavigationFrom.tsx +3 -1
  165. package/src/hooks/useTranslation.ts +3 -1
  166. package/src/hooks/useValidateAuthenticator.tsx +4 -0
  167. package/src/i18n/FireCMSi18nProvider.tsx +199 -23
  168. package/src/i18n/__tests__/FireCMSi18nProvider.test.tsx +91 -0
  169. package/src/i18n/__tests__/nested_provider_lifecycle.test.tsx +67 -0
  170. package/src/internal/useBuildDataSource.ts +37 -15
  171. package/src/internal/useBuildSideEntityController.tsx +20 -5
  172. package/src/locales/de.ts +23 -4
  173. package/src/locales/en.ts +25 -4
  174. package/src/locales/es.ts +23 -4
  175. package/src/locales/fr.ts +23 -4
  176. package/src/locales/hi.ts +23 -4
  177. package/src/locales/it.ts +23 -4
  178. package/src/locales/pl.ts +749 -0
  179. package/src/locales/pt.ts +23 -4
  180. package/src/preview/PropertyPreview.tsx +12 -0
  181. package/src/preview/components/DatePreview.tsx +2 -4
  182. package/src/preview/components/ReferencePreview.tsx +7 -3
  183. package/src/preview/components/StorageThumbnail.tsx +24 -2
  184. package/src/preview/index.ts +1 -0
  185. package/src/preview/property_previews/GeopointPropertyPreview.tsx +23 -0
  186. package/src/routes/FireCMSRoute.tsx +54 -27
  187. package/src/types/analytics.ts +3 -0
  188. package/src/types/collections.ts +34 -0
  189. package/src/types/datasource.ts +67 -4
  190. package/src/types/entities.ts +24 -1
  191. package/src/types/entity_actions.tsx +6 -0
  192. package/src/types/entity_callbacks.ts +24 -0
  193. package/src/types/firecms.tsx +19 -1
  194. package/src/types/firecms_context.tsx +9 -0
  195. package/src/types/index.ts +1 -0
  196. package/src/types/license.ts +62 -0
  197. package/src/types/navigation.ts +35 -5
  198. package/src/types/plugins.tsx +23 -1
  199. package/src/types/properties.ts +17 -0
  200. package/src/types/side_entity_controller.tsx +7 -0
  201. package/src/types/translations.ts +37 -2
  202. package/src/util/__tests__/collections.test.ts +32 -0
  203. package/src/util/__tests__/urls.test.ts +131 -0
  204. package/src/util/collections.ts +1 -1
  205. package/src/util/date_fns_locales.ts +168 -0
  206. package/src/util/entities.ts +16 -1
  207. package/src/util/entity_cache.ts +18 -0
  208. package/src/util/geopoint.ts +81 -0
  209. package/src/util/index.ts +3 -0
  210. package/src/util/lazy_eager.tsx +30 -8
  211. package/src/util/navigation_blocking.ts +45 -0
  212. package/src/util/navigation_from_path.ts +47 -7
  213. package/src/util/navigation_utils.ts +244 -4
  214. package/src/util/parent_references_from_path.ts +45 -4
  215. package/src/util/paths.ts +40 -3
  216. package/src/util/permissions.ts +22 -10
  217. package/src/util/previews.ts +8 -1
  218. package/src/util/resolutions.ts +8 -0
  219. package/src/util/urls.ts +52 -0
  220. package/src/util/useStorageUploadController.tsx +6 -1
@@ -0,0 +1,4563 @@
1
+ import { jsx, jsxs, Fragment as Fragment$1 } from "react/jsx-runtime";
2
+ import { c } from "react-compiler-runtime";
3
+ import React__default, { createContext, useContext, forwardRef, useRef, useState, useEffect, useLayoutEffect } from "react";
4
+ import { defaultBorderMixin, cls, TextFieldsIcon, CheckBoxIcon, LooksOneIcon, LooksTwoIcon, Looks3Icon, FormatListBulletedIcon, FormatListNumberedIcon, FormatQuoteIcon, CodeIcon, ImageIcon, TableChartIcon, AutoFixHighIcon, TextField, Tooltip, IconButton, CheckIcon, Popover, Button, KeyboardArrowDownIcon, focusedDisabled, DeleteIcon, FormatBoldIcon, FormatItalicIcon, FormatUnderlinedIcon, FormatStrikethroughIcon, useInjectStyles, Separator, TextareaAutosize } from "@firecms/ui";
5
+ import { useTranslation } from "./index.es.js";
6
+ import { autoUpdate, computePosition, offset, flip, shift } from "@floating-ui/dom";
7
+ import { NodeSelection, Plugin, PluginKey, TextSelection, EditorState } from "prosemirror-state";
8
+ import { Slot } from "@radix-ui/react-slot";
9
+ import { Schema, Fragment, DOMParser, DOMSerializer } from "prosemirror-model";
10
+ import { setBlockType, wrapIn, toggleMark, baseKeymap } from "prosemirror-commands";
11
+ import { wrapInList, sinkListItem, liftListItem, splitListItem } from "prosemirror-schema-list";
12
+ import { tableNodes, addRowBefore, addRowAfter, deleteRow, addColumnBefore, addColumnAfter, deleteColumn, deleteTable, goToNextCell, columnResizing, tableEditing } from "prosemirror-tables";
13
+ import { DecorationSet, Decoration, EditorView } from "prosemirror-view";
14
+ import { MarkdownParser, MarkdownSerializer, defaultMarkdownParser, defaultMarkdownSerializer } from "prosemirror-markdown";
15
+ import markdownIt from "markdown-it";
16
+ import markdownItTaskLists from "markdown-it-task-lists";
17
+ import markdownItMark from "markdown-it-mark";
18
+ import markdownItIns from "markdown-it-ins";
19
+ import { keymap } from "prosemirror-keymap";
20
+ import { history, redo, undo } from "prosemirror-history";
21
+ import { dropPoint } from "prosemirror-transform";
22
+ import { gapCursor } from "prosemirror-gapcursor";
23
+ import { inputRules, smartQuotes, ellipsis, emDash, InputRule, wrappingInputRule, textblockTypeInputRule } from "prosemirror-inputrules";
24
+ import { createRoot } from "react-dom/client";
25
+ const ProseMirrorContext = createContext({
26
+ state: null,
27
+ view: null
28
+ });
29
+ const useProseMirrorContext = () => {
30
+ return useContext(ProseMirrorContext);
31
+ };
32
+ const EditorBubble = forwardRef((t0, ref) => {
33
+ const $ = c(19);
34
+ const {
35
+ children,
36
+ options,
37
+ className
38
+ } = t0;
39
+ const {
40
+ view,
41
+ state
42
+ } = useProseMirrorContext();
43
+ const menuRef = useRef(null);
44
+ const [show, setShow] = useState(false);
45
+ let t1;
46
+ let t2;
47
+ if ($[0] !== state || $[1] !== view) {
48
+ t1 = () => {
49
+ if (!view || !state) {
50
+ return;
51
+ }
52
+ const timer = setTimeout(() => {
53
+ const {
54
+ selection
55
+ } = state;
56
+ const {
57
+ empty
58
+ } = selection;
59
+ let isImage;
60
+ isImage = false;
61
+ state.doc.nodesBetween(selection.from, selection.to, (node) => {
62
+ if (node.type.name === "image") {
63
+ isImage = true;
64
+ }
65
+ });
66
+ if (isImage || empty || selection instanceof NodeSelection) {
67
+ setShow(false);
68
+ return;
69
+ }
70
+ setShow(true);
71
+ }, 0);
72
+ return () => clearTimeout(timer);
73
+ };
74
+ t2 = [view, state];
75
+ $[0] = state;
76
+ $[1] = view;
77
+ $[2] = t1;
78
+ $[3] = t2;
79
+ } else {
80
+ t1 = $[2];
81
+ t2 = $[3];
82
+ }
83
+ useEffect(t1, t2);
84
+ let t3;
85
+ if ($[4] !== options?.offset || $[5] !== options?.placement || $[6] !== show || $[7] !== state || $[8] !== view) {
86
+ t3 = () => {
87
+ if (!show || !view || !state || !menuRef.current) {
88
+ return;
89
+ }
90
+ const {
91
+ from,
92
+ to
93
+ } = state.selection;
94
+ let start;
95
+ start = view.coordsAtPos(from);
96
+ let end;
97
+ end = view.coordsAtPos(to);
98
+ const virtualEl = {
99
+ getBoundingClientRect() {
100
+ const top = Math.min(start.top, end.top);
101
+ const bottom = Math.max(start.bottom, end.bottom);
102
+ const left = Math.min(start.left, end.left);
103
+ const right = Math.max(start.right, end.right);
104
+ return {
105
+ width: right - left,
106
+ height: bottom - top,
107
+ x: left,
108
+ y: top,
109
+ top,
110
+ left,
111
+ right,
112
+ bottom
113
+ };
114
+ }
115
+ };
116
+ const cleanup = autoUpdate(virtualEl, menuRef.current, () => {
117
+ if (!menuRef.current) {
118
+ return;
119
+ }
120
+ try {
121
+ start = view.coordsAtPos(state.selection.from);
122
+ end = view.coordsAtPos(state.selection.to);
123
+ } catch (t42) {
124
+ }
125
+ computePosition(virtualEl, menuRef.current, {
126
+ placement: options?.placement || "top",
127
+ middleware: [offset(options?.offset || 8), flip(), shift()],
128
+ strategy: "fixed"
129
+ }).then((t52) => {
130
+ const {
131
+ x,
132
+ y
133
+ } = t52;
134
+ if (menuRef.current) {
135
+ Object.assign(menuRef.current.style, {
136
+ left: `${x}px`,
137
+ top: `${y}px`,
138
+ visibility: "visible"
139
+ });
140
+ }
141
+ });
142
+ });
143
+ return () => cleanup();
144
+ };
145
+ $[4] = options?.offset;
146
+ $[5] = options?.placement;
147
+ $[6] = show;
148
+ $[7] = state;
149
+ $[8] = view;
150
+ $[9] = t3;
151
+ } else {
152
+ t3 = $[9];
153
+ }
154
+ let t4;
155
+ if ($[10] !== options || $[11] !== show || $[12] !== state || $[13] !== view) {
156
+ t4 = [show, view, state, options];
157
+ $[10] = options;
158
+ $[11] = show;
159
+ $[12] = state;
160
+ $[13] = view;
161
+ $[14] = t4;
162
+ } else {
163
+ t4 = $[14];
164
+ }
165
+ useEffect(t3, t4);
166
+ if (!show) {
167
+ return null;
168
+ }
169
+ let t5;
170
+ if ($[15] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
171
+ t5 = {
172
+ position: "fixed",
173
+ zIndex: 9999,
174
+ visibility: "hidden"
175
+ };
176
+ $[15] = t5;
177
+ } else {
178
+ t5 = $[15];
179
+ }
180
+ let t6;
181
+ if ($[16] !== children || $[17] !== className) {
182
+ t6 = /* @__PURE__ */ jsx("div", { ref: menuRef, className, style: t5, onMouseDown: _temp$5, children });
183
+ $[16] = children;
184
+ $[17] = className;
185
+ $[18] = t6;
186
+ } else {
187
+ t6 = $[18];
188
+ }
189
+ return t6;
190
+ });
191
+ EditorBubble.displayName = "EditorBubble";
192
+ function _temp$5(e_0) {
193
+ e_0.preventDefault();
194
+ }
195
+ const EditorBubbleItem = forwardRef((t0, ref) => {
196
+ const $ = c(13);
197
+ let asChild;
198
+ let children;
199
+ let onSelect;
200
+ let rest;
201
+ if ($[0] !== t0) {
202
+ ({
203
+ children,
204
+ asChild,
205
+ onSelect,
206
+ ...rest
207
+ } = t0);
208
+ $[0] = t0;
209
+ $[1] = asChild;
210
+ $[2] = children;
211
+ $[3] = onSelect;
212
+ $[4] = rest;
213
+ } else {
214
+ asChild = $[1];
215
+ children = $[2];
216
+ onSelect = $[3];
217
+ rest = $[4];
218
+ }
219
+ const {
220
+ view
221
+ } = useProseMirrorContext();
222
+ const Comp = asChild ? Slot : "div";
223
+ if (!view) {
224
+ return null;
225
+ }
226
+ let t1;
227
+ if ($[5] !== onSelect) {
228
+ t1 = () => onSelect?.();
229
+ $[5] = onSelect;
230
+ $[6] = t1;
231
+ } else {
232
+ t1 = $[6];
233
+ }
234
+ let t2;
235
+ if ($[7] !== Comp || $[8] !== children || $[9] !== ref || $[10] !== rest || $[11] !== t1) {
236
+ t2 = /* @__PURE__ */ jsx(Comp, { ref, ...rest, onMouseDown: _temp$4, onClick: t1, children });
237
+ $[7] = Comp;
238
+ $[8] = children;
239
+ $[9] = ref;
240
+ $[10] = rest;
241
+ $[11] = t1;
242
+ $[12] = t2;
243
+ } else {
244
+ t2 = $[12];
245
+ }
246
+ return t2;
247
+ });
248
+ EditorBubbleItem.displayName = "EditorBubbleItem";
249
+ function _temp$4(e) {
250
+ e.preventDefault();
251
+ }
252
+ const SlashCommandPluginKey = new PluginKey("slash-command");
253
+ function slashCommandPlugin() {
254
+ return new Plugin({
255
+ key: SlashCommandPluginKey,
256
+ state: {
257
+ init() {
258
+ return {
259
+ active: false
260
+ };
261
+ },
262
+ apply(tr, value, oldState, newState) {
263
+ const meta = tr.getMeta(SlashCommandPluginKey);
264
+ if (meta !== void 0) {
265
+ return meta;
266
+ }
267
+ const {
268
+ selection
269
+ } = newState;
270
+ if (!(selection instanceof TextSelection) || !selection.empty) {
271
+ return {
272
+ active: false
273
+ };
274
+ }
275
+ const $anchor = selection.$anchor;
276
+ if ($anchor.parent.type.name === "code_block") {
277
+ return {
278
+ active: false
279
+ };
280
+ }
281
+ const textBefore = $anchor.parent.textBetween(Math.max(0, $anchor.parentOffset - 20), $anchor.parentOffset, void 0, "");
282
+ const match = textBefore.match(/(?:\s|^)(\/)([a-zA-Z0-9]*)$/);
283
+ if (!match) {
284
+ return {
285
+ active: false
286
+ };
287
+ }
288
+ if (value.dismissed) {
289
+ return {
290
+ active: false,
291
+ dismissed: true
292
+ };
293
+ }
294
+ const query = match[2];
295
+ const from = $anchor.pos - query.length - 1;
296
+ const to = $anchor.pos;
297
+ return {
298
+ active: true,
299
+ range: {
300
+ from,
301
+ to
302
+ },
303
+ query
304
+ };
305
+ }
306
+ }
307
+ });
308
+ }
309
+ const marks = {
310
+ link: {
311
+ attrs: {
312
+ href: {},
313
+ title: {
314
+ default: null
315
+ },
316
+ target: {
317
+ default: "_blank"
318
+ }
319
+ },
320
+ inclusive: false,
321
+ parseDOM: [{
322
+ tag: "a[href]",
323
+ getAttrs(dom) {
324
+ if (typeof dom === "string") return false;
325
+ return {
326
+ href: dom.getAttribute("href"),
327
+ title: dom.getAttribute("title"),
328
+ target: dom.getAttribute("target") || "_blank"
329
+ };
330
+ }
331
+ }],
332
+ toDOM(node) {
333
+ let {
334
+ href,
335
+ title,
336
+ target
337
+ } = node.attrs;
338
+ return ["a", {
339
+ href,
340
+ title,
341
+ target,
342
+ class: "text-surface-700 dark:text-surface-accent-200 underline underline-offset-[3px] hover:text-primary transition-colors cursor-pointer"
343
+ }, 0];
344
+ }
345
+ },
346
+ bold: {
347
+ parseDOM: [{
348
+ tag: "strong"
349
+ }, {
350
+ tag: "b",
351
+ getAttrs: (node) => typeof node !== "string" && node.style.fontWeight !== "normal" && null
352
+ }, {
353
+ style: "font-weight=400",
354
+ clearMark: (m) => m.type.name === "bold"
355
+ }, {
356
+ style: "font-weight",
357
+ getAttrs: (value) => typeof value === "string" && /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null
358
+ }],
359
+ toDOM() {
360
+ return ["strong", 0];
361
+ }
362
+ },
363
+ italic: {
364
+ parseDOM: [{
365
+ tag: "i"
366
+ }, {
367
+ tag: "em"
368
+ }, {
369
+ style: "font-style=italic"
370
+ }],
371
+ toDOM() {
372
+ return ["em", 0];
373
+ }
374
+ },
375
+ strike: {
376
+ parseDOM: [{
377
+ tag: "s"
378
+ }, {
379
+ tag: "del"
380
+ }, {
381
+ tag: "strike"
382
+ }, {
383
+ style: "text-decoration=line-through"
384
+ }],
385
+ toDOM() {
386
+ return ["s", 0];
387
+ }
388
+ },
389
+ underline: {
390
+ parseDOM: [{
391
+ tag: "u"
392
+ }, {
393
+ style: "text-decoration=underline"
394
+ }],
395
+ toDOM() {
396
+ return ["u", 0];
397
+ }
398
+ },
399
+ code: {
400
+ parseDOM: [{
401
+ tag: "code"
402
+ }],
403
+ toDOM() {
404
+ return ["code", {
405
+ class: "rounded-md bg-surface-accent-50 dark:bg-surface-700 px-1.5 py-1 font-mono font-medium",
406
+ spellcheck: "false"
407
+ }, 0];
408
+ }
409
+ },
410
+ textStyle: {
411
+ attrs: {
412
+ color: {
413
+ default: null
414
+ }
415
+ },
416
+ parseDOM: [{
417
+ style: "color",
418
+ getAttrs: (value) => {
419
+ if (typeof value === "string") return {
420
+ color: value
421
+ };
422
+ return false;
423
+ }
424
+ }],
425
+ toDOM(mark) {
426
+ let style = "";
427
+ if (mark.attrs.color) style += `color: ${mark.attrs.color};`;
428
+ return ["span", {
429
+ style
430
+ }, 0];
431
+ }
432
+ },
433
+ highlight: {
434
+ attrs: {
435
+ color: {
436
+ default: null
437
+ }
438
+ },
439
+ parseDOM: [{
440
+ tag: "mark",
441
+ getAttrs: (dom) => {
442
+ if (typeof dom === "string") return false;
443
+ return {
444
+ color: dom.style.backgroundColor || dom.getAttribute("data-color")
445
+ };
446
+ }
447
+ }],
448
+ toDOM(mark) {
449
+ return ["mark", mark.attrs.color ? {
450
+ style: `background-color: ${mark.attrs.color}; color: inherit;`,
451
+ "data-color": mark.attrs.color
452
+ } : {}, 0];
453
+ }
454
+ }
455
+ };
456
+ const nodes = {
457
+ doc: {
458
+ content: "block+"
459
+ },
460
+ paragraph: {
461
+ content: "inline*",
462
+ group: "block",
463
+ parseDOM: [{
464
+ tag: "p"
465
+ }],
466
+ toDOM() {
467
+ return ["p", 0];
468
+ }
469
+ },
470
+ text: {
471
+ group: "inline"
472
+ },
473
+ blockquote: {
474
+ content: "block+",
475
+ group: "block",
476
+ defining: true,
477
+ parseDOM: [{
478
+ tag: "blockquote"
479
+ }],
480
+ toDOM() {
481
+ return ["blockquote", {
482
+ class: "border-l-4 border-primary"
483
+ }, 0];
484
+ }
485
+ },
486
+ heading: {
487
+ attrs: {
488
+ level: {
489
+ default: 1
490
+ }
491
+ },
492
+ content: "inline*",
493
+ group: "block",
494
+ defining: true,
495
+ parseDOM: [{
496
+ tag: "h1",
497
+ attrs: {
498
+ level: 1
499
+ }
500
+ }, {
501
+ tag: "h2",
502
+ attrs: {
503
+ level: 2
504
+ }
505
+ }, {
506
+ tag: "h3",
507
+ attrs: {
508
+ level: 3
509
+ }
510
+ }, {
511
+ tag: "h4",
512
+ attrs: {
513
+ level: 4
514
+ }
515
+ }, {
516
+ tag: "h5",
517
+ attrs: {
518
+ level: 5
519
+ }
520
+ }, {
521
+ tag: "h6",
522
+ attrs: {
523
+ level: 6
524
+ }
525
+ }],
526
+ toDOM(node) {
527
+ return ["h" + node.attrs.level, 0];
528
+ }
529
+ },
530
+ horizontal_rule: {
531
+ group: "block",
532
+ parseDOM: [{
533
+ tag: "hr"
534
+ }],
535
+ toDOM() {
536
+ return ["hr", {
537
+ class: "mt-4 mb-6 border-t border-solid border-gray-200 dark:border-gray-800"
538
+ }];
539
+ }
540
+ },
541
+ code_block: {
542
+ content: "text*",
543
+ marks: "",
544
+ group: "block",
545
+ code: true,
546
+ defining: true,
547
+ attrs: {
548
+ language: {
549
+ default: null
550
+ }
551
+ },
552
+ parseDOM: [{
553
+ tag: "pre",
554
+ preserveWhitespace: "full"
555
+ }],
556
+ toDOM(node) {
557
+ return ["pre", {
558
+ class: "rounded bg-blue-50 dark:bg-surface-700 border border-solid border-gray-200 dark:border-gray-800 p-5 font-mono font-medium"
559
+ }, ["code", 0]];
560
+ }
561
+ },
562
+ image: {
563
+ inline: false,
564
+ group: "block",
565
+ attrs: {
566
+ src: {},
567
+ alt: {
568
+ default: null
569
+ },
570
+ title: {
571
+ default: null
572
+ }
573
+ },
574
+ draggable: true,
575
+ parseDOM: [{
576
+ tag: "img[src]",
577
+ getAttrs(dom) {
578
+ if (typeof dom === "string") return false;
579
+ return {
580
+ src: dom.getAttribute("src"),
581
+ title: dom.getAttribute("title"),
582
+ alt: dom.getAttribute("alt")
583
+ };
584
+ }
585
+ }],
586
+ toDOM(node) {
587
+ let {
588
+ src,
589
+ alt,
590
+ title
591
+ } = node.attrs;
592
+ return ["img", {
593
+ src,
594
+ alt,
595
+ title,
596
+ class: "rounded-lg max-w-full !m-0"
597
+ }];
598
+ }
599
+ },
600
+ bullet_list: {
601
+ content: "list_item+",
602
+ group: "block",
603
+ parseDOM: [{
604
+ tag: "ul"
605
+ }],
606
+ toDOM() {
607
+ return ["ul", {
608
+ class: "list-disc list-outside leading-3 -mt-2"
609
+ }, 0];
610
+ }
611
+ },
612
+ ordered_list: {
613
+ content: "list_item+",
614
+ group: "block",
615
+ attrs: {
616
+ order: {
617
+ default: 1
618
+ }
619
+ },
620
+ parseDOM: [{
621
+ tag: "ol",
622
+ getAttrs(dom) {
623
+ if (typeof dom === "string") return false;
624
+ return {
625
+ order: dom.hasAttribute("start") ? +dom.getAttribute("start") : 1
626
+ };
627
+ }
628
+ }],
629
+ toDOM(node) {
630
+ return node.attrs.order === 1 ? ["ol", {
631
+ class: "list-decimal list-outside leading-3 -mt-2"
632
+ }, 0] : ["ol", {
633
+ start: node.attrs.order,
634
+ class: "list-decimal list-outside leading-3 -mt-2"
635
+ }, 0];
636
+ }
637
+ },
638
+ list_item: {
639
+ content: "paragraph block*",
640
+ parseDOM: [{
641
+ tag: "li"
642
+ }],
643
+ toDOM() {
644
+ return ["li", {
645
+ class: "leading-normal -mb-2"
646
+ }, 0];
647
+ },
648
+ defining: true
649
+ },
650
+ task_list: {
651
+ group: "block",
652
+ content: "task_item+",
653
+ parseDOM: [{
654
+ tag: 'ul[data-type="taskList"]'
655
+ }],
656
+ toDOM() {
657
+ return ["ul", {
658
+ "data-type": "taskList",
659
+ class: "not-prose"
660
+ }, 0];
661
+ }
662
+ },
663
+ task_item: {
664
+ content: "paragraph block*",
665
+ defining: true,
666
+ attrs: {
667
+ checked: {
668
+ default: false
669
+ }
670
+ },
671
+ parseDOM: [{
672
+ tag: 'li[data-type="taskItem"]',
673
+ getAttrs(dom) {
674
+ if (typeof dom === "string") return false;
675
+ return {
676
+ checked: dom.getAttribute("data-checked") === "true"
677
+ };
678
+ }
679
+ }],
680
+ toDOM(node) {
681
+ return ["li", {
682
+ "data-type": "taskItem",
683
+ "data-checked": node.attrs.checked ? "true" : "false",
684
+ class: "flex items-start my-4"
685
+ }, 0];
686
+ }
687
+ },
688
+ hard_break: {
689
+ inline: true,
690
+ group: "inline",
691
+ selectable: false,
692
+ parseDOM: [{
693
+ tag: "br"
694
+ }],
695
+ toDOM() {
696
+ return ["br"];
697
+ }
698
+ },
699
+ ...tableNodes({
700
+ tableGroup: "block",
701
+ cellContent: "block+",
702
+ cellAttributes: {
703
+ background: {
704
+ default: null,
705
+ getFromDOM(dom) {
706
+ return dom.style.backgroundColor || null;
707
+ },
708
+ setDOMAttr(value, attrs) {
709
+ if (value) attrs.style = (attrs.style || "") + `background-color: ${value};`;
710
+ }
711
+ }
712
+ }
713
+ })
714
+ };
715
+ const schema = new Schema({
716
+ nodes,
717
+ marks
718
+ });
719
+ async function onFileRead(view, readerEvent, pos, upload, image) {
720
+ if (view.isDestroyed) return;
721
+ const plugin = view.state.plugins.find((p) => p.key === ImagePluginKey.key);
722
+ if (!plugin) {
723
+ console.error("Image plugin not found");
724
+ return;
725
+ }
726
+ const decoId = Math.random().toString(36).substring(7);
727
+ const placeholder = document.createElement("div");
728
+ const imageElement = document.createElement("img");
729
+ imageElement.setAttribute("class", "opacity-40 rounded-lg border " + defaultBorderMixin);
730
+ imageElement.src = readerEvent.target?.result;
731
+ placeholder.appendChild(imageElement);
732
+ const deco = Decoration.widget(pos, placeholder, {
733
+ id: decoId
734
+ });
735
+ let decorationSet = plugin.getState(view.state);
736
+ decorationSet = decorationSet?.add(view.state.doc, [deco]);
737
+ view.dispatch(view.state.tr.setMeta(plugin, {
738
+ decorationSet
739
+ }));
740
+ const src = await upload(image);
741
+ console.debug("Uploaded image", src);
742
+ if (view.isDestroyed) return;
743
+ const replacePlaceholder = () => {
744
+ if (view.isDestroyed) return;
745
+ let currentDecos = plugin.getState(view.state);
746
+ const foundDecos = currentDecos.find(void 0, void 0, (spec) => spec.id === decoId);
747
+ if (foundDecos.length === 0) {
748
+ console.warn("Image placeholder removed before upload completed.");
749
+ return;
750
+ }
751
+ const currentPos = foundDecos[0].from;
752
+ const imageNode = view.state.schema.nodes.image.create({
753
+ src
754
+ });
755
+ const tr = view.state.tr.replaceWith(currentPos, currentPos, imageNode);
756
+ currentDecos = currentDecos.remove(foundDecos);
757
+ tr.setMeta(plugin, {
758
+ decorationSet: currentDecos
759
+ });
760
+ view.dispatch(tr);
761
+ };
762
+ const preloader = new Image();
763
+ preloader.src = src;
764
+ preloader.onload = replacePlaceholder;
765
+ preloader.onerror = replacePlaceholder;
766
+ }
767
+ const ImagePluginKey = new PluginKey("imagePlugin");
768
+ const createDropImagePlugin = (upload) => {
769
+ const plugin = new Plugin({
770
+ key: ImagePluginKey,
771
+ state: {
772
+ // Initialize the plugin state with an empty DecorationSet
773
+ init: () => DecorationSet.empty,
774
+ // Apply transactions to update the state
775
+ apply: (tr, old) => {
776
+ const meta = tr.getMeta(plugin);
777
+ if (meta && meta.decorationSet) {
778
+ return meta.decorationSet;
779
+ }
780
+ return old.map(tr.mapping, tr.doc);
781
+ }
782
+ },
783
+ props: {
784
+ handleDOMEvents: {
785
+ dragover: (view, event) => {
786
+ if (event.dataTransfer?.types?.includes("Files")) {
787
+ event.preventDefault();
788
+ return true;
789
+ }
790
+ return false;
791
+ },
792
+ drop: (view, event) => {
793
+ if (!event.dataTransfer?.files || event.dataTransfer?.files.length === 0) {
794
+ return false;
795
+ }
796
+ event.preventDefault();
797
+ const files = Array.from(event.dataTransfer.files);
798
+ const images = files.filter((file) => /image/i.test(file.type));
799
+ if (images.length === 0) {
800
+ console.log("No images found in dropped files");
801
+ return false;
802
+ }
803
+ images.forEach((image) => {
804
+ const position = view.posAtCoords({
805
+ left: event.clientX,
806
+ top: event.clientY
807
+ });
808
+ if (!position) return;
809
+ const reader = new FileReader();
810
+ reader.onload = async (readerEvent) => {
811
+ await onFileRead(view, readerEvent, position.pos, upload, image);
812
+ };
813
+ reader.readAsDataURL(image);
814
+ });
815
+ return true;
816
+ }
817
+ },
818
+ handlePaste(view, event, slice) {
819
+ const html = event.clipboardData?.getData("text/html");
820
+ if (html && html.includes("<img")) {
821
+ return false;
822
+ }
823
+ const items2 = Array.from(event.clipboardData?.items || []);
824
+ const pos = view.state.selection.from;
825
+ let anyImageFound = false;
826
+ items2.filter((item) => item.type.startsWith("image/")).forEach((item) => {
827
+ const image = item.getAsFile();
828
+ if (image) {
829
+ anyImageFound = true;
830
+ const reader = new FileReader();
831
+ reader.onload = async (readerEvent) => {
832
+ await onFileRead(view, readerEvent, pos, upload, image);
833
+ };
834
+ reader.readAsDataURL(image);
835
+ }
836
+ });
837
+ return anyImageFound;
838
+ },
839
+ decorations(state) {
840
+ return plugin.getState(state);
841
+ }
842
+ }
843
+ });
844
+ return plugin;
845
+ };
846
+ const loadingDecorationKey = new PluginKey("loadingDecoration");
847
+ const textLoadingCommands = {
848
+ toggleLoadingDecoration: (state, dispatch, loadingHtml) => {
849
+ const {
850
+ selection
851
+ } = state;
852
+ const pos = selection.from;
853
+ if (!dispatch) return false;
854
+ const tr = state.tr.setMeta(loadingDecorationKey, {
855
+ pos,
856
+ type: "loadingDecoration",
857
+ remove: false,
858
+ loadingHtml
859
+ });
860
+ dispatch(tr);
861
+ return true;
862
+ },
863
+ removeLoadingDecoration: (state, dispatch) => {
864
+ if (!dispatch) return false;
865
+ const tr = state.tr.setMeta(loadingDecorationKey, {
866
+ pos: 0,
867
+ // We can pass any position as it will remove the entire decoration set
868
+ type: "loadingDecoration",
869
+ remove: true
870
+ });
871
+ dispatch(tr);
872
+ return true;
873
+ }
874
+ };
875
+ const textLoadingDecorationPlugin = () => {
876
+ return new Plugin({
877
+ key: loadingDecorationKey,
878
+ state: {
879
+ init() {
880
+ return {
881
+ decorationSet: DecorationSet.empty,
882
+ hasDecoration: false
883
+ };
884
+ },
885
+ apply(tr, oldState) {
886
+ const action = tr.getMeta(loadingDecorationKey);
887
+ if (action?.type === "loadingDecoration") {
888
+ const {
889
+ pos,
890
+ remove,
891
+ loadingHtml
892
+ } = action;
893
+ if (remove) {
894
+ return {
895
+ decorationSet: DecorationSet.empty,
896
+ hasDecoration: false
897
+ };
898
+ }
899
+ const decoration = Decoration.widget(pos, () => {
900
+ const container = document.createElement("span");
901
+ container.className = "loading-decoration";
902
+ if (loadingHtml) {
903
+ container.innerHTML = loadingHtml;
904
+ } else {
905
+ const span = document.createElement("span");
906
+ span.innerText = "loading...";
907
+ container.appendChild(span);
908
+ }
909
+ return container;
910
+ });
911
+ return {
912
+ decorationSet: DecorationSet.empty.add(tr.doc, [decoration]),
913
+ hasDecoration: true
914
+ };
915
+ }
916
+ return {
917
+ decorationSet: oldState.decorationSet.map(tr.mapping, tr.doc),
918
+ hasDecoration: oldState.hasDecoration
919
+ };
920
+ }
921
+ },
922
+ props: {
923
+ decorations(state) {
924
+ return this.getState(state)?.decorationSet || DecorationSet.empty;
925
+ }
926
+ }
927
+ });
928
+ };
929
+ const parserTokens = {
930
+ ...defaultMarkdownParser.tokens,
931
+ em: {
932
+ mark: "italic"
933
+ },
934
+ strong: {
935
+ mark: "bold"
936
+ },
937
+ html_inline: {
938
+ ignore: true,
939
+ noCloseToken: true
940
+ },
941
+ html_block: {
942
+ ignore: true,
943
+ noCloseToken: true
944
+ },
945
+ s: {
946
+ mark: "strike"
947
+ },
948
+ task_list: {
949
+ block: "task_list"
950
+ },
951
+ task_item: {
952
+ block: "task_item",
953
+ getAttrs: (tok) => ({
954
+ checked: tok.attrGet("checked") === "true"
955
+ })
956
+ },
957
+ mark: {
958
+ mark: "highlight"
959
+ },
960
+ ins: {
961
+ mark: "underline"
962
+ },
963
+ table: {
964
+ block: "table"
965
+ },
966
+ thead: {
967
+ ignore: true
968
+ },
969
+ tbody: {
970
+ ignore: true
971
+ },
972
+ tr: {
973
+ block: "table_row"
974
+ },
975
+ th: {
976
+ block: "table_header"
977
+ },
978
+ td: {
979
+ block: "table_cell"
980
+ }
981
+ };
982
+ const md = markdownIt({
983
+ html: false
984
+ }).use(markdownItTaskLists).use(markdownItMark).use(markdownItIns);
985
+ md.inline.ruler.at("escape", function escapeOverride(state, silent) {
986
+ let pos = state.pos;
987
+ const max = state.posMax;
988
+ if (state.src.charCodeAt(pos) !== 92) return false;
989
+ pos++;
990
+ if (pos >= max) return false;
991
+ const ch1 = state.src.charCodeAt(pos);
992
+ if (ch1 === 10) {
993
+ if (!silent) {
994
+ state.pending += "\\";
995
+ }
996
+ state.pos = pos;
997
+ return true;
998
+ }
999
+ let escapedStr = state.src[pos];
1000
+ if (ch1 >= 55296 && ch1 <= 56319 && pos + 1 < max) {
1001
+ const ch2 = state.src.charCodeAt(pos + 1);
1002
+ if (ch2 >= 56320 && ch2 <= 57343) {
1003
+ escapedStr += state.src[pos + 1];
1004
+ pos++;
1005
+ }
1006
+ }
1007
+ const origStr = "\\" + escapedStr;
1008
+ if (!silent) {
1009
+ const isEscapable = ch1 < 256 && /[\\!"#$%&'()*+,./:;<=>?@[\]^_`{|}~-]/.test(String.fromCharCode(ch1));
1010
+ const token = state.push("text_special", "", 0);
1011
+ if (isEscapable) {
1012
+ token.content = escapedStr;
1013
+ } else {
1014
+ token.content = origStr;
1015
+ }
1016
+ token.markup = origStr;
1017
+ token.info = "escape";
1018
+ }
1019
+ state.pos = pos + 1;
1020
+ return true;
1021
+ });
1022
+ md.inline.ruler.disable(["newline"]);
1023
+ md.core.ruler.after("inline", "image-to-block", (state) => {
1024
+ const tokens = state.tokens;
1025
+ for (let i = tokens.length - 2; i >= 1; i--) {
1026
+ if (tokens[i - 1] && tokens[i - 1].type === "paragraph_open" && tokens[i] && tokens[i].type === "inline" && tokens[i + 1] && tokens[i + 1].type === "paragraph_close") {
1027
+ const inlineTokens = tokens[i].children || [];
1028
+ if (inlineTokens.length === 1 && inlineTokens[0].type === "image") {
1029
+ state.tokens.splice(i - 1, 3, inlineTokens[0]);
1030
+ }
1031
+ }
1032
+ }
1033
+ });
1034
+ md.core.ruler.after("inline", "tables-wrap-paragraphs", (state) => {
1035
+ const tokens = state.tokens;
1036
+ for (let i = tokens.length - 1; i >= 0; i--) {
1037
+ if (tokens[i].type === "td_open" || tokens[i].type === "th_open") {
1038
+ let closeIndex = i + 1;
1039
+ while (closeIndex < tokens.length && tokens[closeIndex].type !== "td_close" && tokens[closeIndex].type !== "th_close") {
1040
+ closeIndex++;
1041
+ }
1042
+ if (closeIndex < tokens.length) {
1043
+ const pOpen = new state.Token("paragraph_open", "p", 1);
1044
+ pOpen.block = true;
1045
+ const pClose = new state.Token("paragraph_close", "p", -1);
1046
+ pClose.block = true;
1047
+ state.tokens.splice(closeIndex, 0, pClose);
1048
+ state.tokens.splice(i + 1, 0, pOpen);
1049
+ }
1050
+ }
1051
+ }
1052
+ });
1053
+ const markdownParser = new MarkdownParser(schema, md, parserTokens);
1054
+ const markdownSerializer = new MarkdownSerializer({
1055
+ ...defaultMarkdownSerializer.nodes,
1056
+ // Add custom serialization for task lists
1057
+ task_list(state, node) {
1058
+ state.renderList(node, " ", () => "- ");
1059
+ },
1060
+ task_item(state, node) {
1061
+ state.write(`[${node.attrs.checked ? "x" : " "}] `);
1062
+ state.renderContent(node);
1063
+ },
1064
+ horizontal_rule(state, node) {
1065
+ state.write(node.attrs.markup || "---");
1066
+ state.closeBlock(node);
1067
+ },
1068
+ image(state, node) {
1069
+ const rawSrc = node.attrs.src || "";
1070
+ const src = rawSrc.replace(/ /g, "%20");
1071
+ state.write("![" + state.esc(node.attrs.alt || "") + "](" + src.replace(/[\(\)]/g, "\\$&") + (node.attrs.title ? ' "' + node.attrs.title.replace(/"/g, '\\"') + '"' : "") + ")");
1072
+ state.closeBlock(node);
1073
+ },
1074
+ table(state, node) {
1075
+ node.forEach((row, _, i) => {
1076
+ row.forEach((cell, _2, j) => {
1077
+ state.write(j === 0 ? "| " : " ");
1078
+ let cellContent = "";
1079
+ const oldWrite = state.write.bind(state);
1080
+ state.write = (s) => {
1081
+ cellContent += s;
1082
+ };
1083
+ let first = true;
1084
+ cell.forEach((block) => {
1085
+ if (!first) cellContent += "<br>";
1086
+ state.renderInline(block);
1087
+ first = false;
1088
+ });
1089
+ state.write = oldWrite;
1090
+ state.write(cellContent.replace(/\|/g, "\\|"));
1091
+ state.write(" |");
1092
+ });
1093
+ state.write("\n");
1094
+ if (i === 0) {
1095
+ row.forEach((cell, _2, j) => {
1096
+ state.write(j === 0 ? "|---|" : "---|");
1097
+ });
1098
+ state.write("\n");
1099
+ }
1100
+ });
1101
+ state.closeBlock(node);
1102
+ },
1103
+ table_row() {
1104
+ },
1105
+ table_cell() {
1106
+ },
1107
+ table_header() {
1108
+ },
1109
+ // Custom text serializer: since our parser override keeps `\` as
1110
+ // literal text (instead of consuming it), we must avoid the default
1111
+ // esc() from double-escaping it. We escape all standard markdown
1112
+ // specials *except* the backslash itself.
1113
+ text(state, node) {
1114
+ const escaped = node.text.replace(/[`*~\[\]_]/g, (m, i) => {
1115
+ if (m === "_" && i > 0 && i + 1 < node.text.length && /\w/.test(node.text[i - 1]) && /\w/.test(node.text[i + 1])) {
1116
+ return m;
1117
+ }
1118
+ return "\\" + m;
1119
+ });
1120
+ const lines = escaped.split("\n");
1121
+ for (let i = 0; i < lines.length; i++) {
1122
+ state.write();
1123
+ let line = lines[i];
1124
+ if (state.atBlockStart || i > 0) {
1125
+ line = line.replace(/^(\+[ ]|[-*>])/, "\\$&").replace(/^(\s*)(#{1,6})(\s|$)/, "$1\\$2$3").replace(/^(\s*\d+)\.\s/, "$1\\. ");
1126
+ }
1127
+ state.out += line;
1128
+ if (i !== lines.length - 1) state.out += "\n";
1129
+ }
1130
+ }
1131
+ }, {
1132
+ ...defaultMarkdownSerializer.marks,
1133
+ bold: defaultMarkdownSerializer.marks.strong,
1134
+ italic: defaultMarkdownSerializer.marks.em,
1135
+ strike: {
1136
+ open: "~~",
1137
+ close: "~~",
1138
+ mixable: true,
1139
+ expelEnclosingWhitespace: true
1140
+ },
1141
+ highlight: {
1142
+ open: "==",
1143
+ close: "==",
1144
+ mixable: true,
1145
+ expelEnclosingWhitespace: true
1146
+ },
1147
+ underline: {
1148
+ open: "++",
1149
+ close: "++",
1150
+ mixable: true,
1151
+ expelEnclosingWhitespace: true
1152
+ },
1153
+ link: {
1154
+ ...defaultMarkdownSerializer.marks.link,
1155
+ close(state, mark, parent, index) {
1156
+ const inAutolink = state.inAutolink;
1157
+ state.inAutolink = void 0;
1158
+ const href = mark.attrs.href.replace(/ /g, "%20");
1159
+ return inAutolink ? ">" : "](" + href.replace(/[\(\)"]/g, "\\$&") + (mark.attrs.title ? ` "${mark.attrs.title.replace(/"/g, '\\"')}"` : "") + ")";
1160
+ }
1161
+ },
1162
+ // textStyle (colored text from HTML) has no markdown equivalent — emit content as-is
1163
+ textStyle: {
1164
+ open: "",
1165
+ close: "",
1166
+ mixable: true,
1167
+ expelEnclosingWhitespace: true
1168
+ }
1169
+ });
1170
+ const parser = markdownParser;
1171
+ const serializer = markdownSerializer;
1172
+ const suggestionItems = [{
1173
+ title: "Text",
1174
+ description: "Just start typing with plain text.",
1175
+ searchTerms: ["p", "paragraph"],
1176
+ icon: /* @__PURE__ */ jsx(TextFieldsIcon, { size: 18 }),
1177
+ command: (view, range) => {
1178
+ view.dispatch(view.state.tr.deleteRange(range.from, range.to));
1179
+ setBlockType(schema.nodes.paragraph)(view.state, view.dispatch);
1180
+ }
1181
+ }, {
1182
+ title: "To-do List",
1183
+ description: "Track tasks with a to-do list.",
1184
+ searchTerms: ["todo", "task", "list", "check", "checkbox"],
1185
+ icon: /* @__PURE__ */ jsx(CheckBoxIcon, { size: 18 }),
1186
+ command: (view, range) => {
1187
+ view.dispatch(view.state.tr.deleteRange(range.from, range.to));
1188
+ wrapInList(schema.nodes.task_list)(view.state, view.dispatch);
1189
+ }
1190
+ }, {
1191
+ title: "Heading 1",
1192
+ description: "Big section heading.",
1193
+ searchTerms: ["title", "big", "large"],
1194
+ icon: /* @__PURE__ */ jsx(LooksOneIcon, { size: 18 }),
1195
+ command: (view, range) => {
1196
+ view.dispatch(view.state.tr.deleteRange(range.from, range.to));
1197
+ setBlockType(schema.nodes.heading, {
1198
+ level: 1
1199
+ })(view.state, view.dispatch);
1200
+ }
1201
+ }, {
1202
+ title: "Heading 2",
1203
+ description: "Medium section heading.",
1204
+ searchTerms: ["subtitle", "medium"],
1205
+ icon: /* @__PURE__ */ jsx(LooksTwoIcon, { size: 18 }),
1206
+ command: (view, range) => {
1207
+ view.dispatch(view.state.tr.deleteRange(range.from, range.to));
1208
+ setBlockType(schema.nodes.heading, {
1209
+ level: 2
1210
+ })(view.state, view.dispatch);
1211
+ }
1212
+ }, {
1213
+ title: "Heading 3",
1214
+ description: "Small section heading.",
1215
+ searchTerms: ["subtitle", "small"],
1216
+ icon: /* @__PURE__ */ jsx(Looks3Icon, { size: 18 }),
1217
+ command: (view, range) => {
1218
+ view.dispatch(view.state.tr.deleteRange(range.from, range.to));
1219
+ setBlockType(schema.nodes.heading, {
1220
+ level: 3
1221
+ })(view.state, view.dispatch);
1222
+ }
1223
+ }, {
1224
+ title: "Bullet List",
1225
+ description: "Create a simple bullet list.",
1226
+ searchTerms: ["unordered", "point"],
1227
+ icon: /* @__PURE__ */ jsx(FormatListBulletedIcon, { size: 18 }),
1228
+ command: (view, range) => {
1229
+ view.dispatch(view.state.tr.deleteRange(range.from, range.to));
1230
+ wrapInList(schema.nodes.bullet_list)(view.state, view.dispatch);
1231
+ }
1232
+ }, {
1233
+ title: "Numbered List",
1234
+ description: "Create a list with numbering.",
1235
+ searchTerms: ["ordered"],
1236
+ icon: /* @__PURE__ */ jsx(FormatListNumberedIcon, { size: 18 }),
1237
+ command: (view, range) => {
1238
+ view.dispatch(view.state.tr.deleteRange(range.from, range.to));
1239
+ wrapInList(schema.nodes.ordered_list)(view.state, view.dispatch);
1240
+ }
1241
+ }, {
1242
+ title: "Quote",
1243
+ description: "Capture a quote.",
1244
+ searchTerms: ["blockquote"],
1245
+ icon: /* @__PURE__ */ jsx(FormatQuoteIcon, { size: 18 }),
1246
+ command: (view, range) => {
1247
+ view.dispatch(view.state.tr.deleteRange(range.from, range.to));
1248
+ wrapIn(schema.nodes.blockquote)(view.state, view.dispatch);
1249
+ }
1250
+ }, {
1251
+ title: "Code",
1252
+ description: "Capture a code snippet.",
1253
+ searchTerms: ["codeblock"],
1254
+ icon: /* @__PURE__ */ jsx(CodeIcon, { size: 18 }),
1255
+ command: (view, range) => {
1256
+ view.dispatch(view.state.tr.deleteRange(range.from, range.to));
1257
+ setBlockType(schema.nodes.code_block)(view.state, view.dispatch);
1258
+ }
1259
+ }, {
1260
+ title: "Image",
1261
+ description: "Upload an image from your computer.",
1262
+ searchTerms: ["photo", "picture", "media", "upload", "file"],
1263
+ icon: /* @__PURE__ */ jsx(ImageIcon, { size: 18 }),
1264
+ command: (view, range, upload) => {
1265
+ view.dispatch(view.state.tr.deleteRange(range.from, range.to));
1266
+ const input = document.createElement("input");
1267
+ input.type = "file";
1268
+ input.accept = "image/*";
1269
+ input.onchange = async () => {
1270
+ if (input.files?.length) {
1271
+ const file = input.files[0];
1272
+ if (!file) return;
1273
+ const pos = view.state.selection.from;
1274
+ const images = Array.from(input.files).filter((f) => /image/i.test(f.type));
1275
+ if (images.length === 0) return false;
1276
+ images.forEach((image) => {
1277
+ const reader = new FileReader();
1278
+ reader.onload = async (readerEvent) => {
1279
+ await onFileRead(view, readerEvent, pos, upload, image);
1280
+ };
1281
+ reader.readAsDataURL(image);
1282
+ });
1283
+ }
1284
+ return true;
1285
+ };
1286
+ input.click();
1287
+ }
1288
+ }, {
1289
+ title: "Table",
1290
+ description: "Insert a custom grid table.",
1291
+ searchTerms: ["table", "grid", "row", "col"],
1292
+ icon: /* @__PURE__ */ jsx(TableChartIcon, { size: 18 }),
1293
+ command: (view, range, upload, aiController, setSubView) => {
1294
+ if (setSubView) setSubView("table-grid");
1295
+ }
1296
+ }];
1297
+ const autocompleteSuggestionItem = {
1298
+ title: "Autocomplete",
1299
+ description: "Add text based on the context.",
1300
+ searchTerms: ["ai"],
1301
+ icon: /* @__PURE__ */ jsx(AutoFixHighIcon, { size: 18 }),
1302
+ command: async (view, range, upload, aiController) => {
1303
+ if (!aiController) throw Error("No AiController");
1304
+ view.dispatch(view.state.tr.deleteRange(range.from, range.to));
1305
+ setBlockType(schema.nodes.paragraph)(view.state, view.dispatch);
1306
+ const {
1307
+ state
1308
+ } = view;
1309
+ const {
1310
+ from,
1311
+ to
1312
+ } = state.selection;
1313
+ const textBeforeCursor = state.doc.textBetween(0, from, "\n");
1314
+ const textAfterCursor = state.doc.textBetween(to, state.doc.content.size, "\n");
1315
+ let buffer = "";
1316
+ const result = await aiController.autocomplete(textBeforeCursor, textAfterCursor, (delta) => {
1317
+ buffer += delta;
1318
+ if (delta.length !== 0 && !view.isDestroyed) {
1319
+ textLoadingCommands.toggleLoadingDecoration(view.state, view.dispatch, buffer);
1320
+ }
1321
+ });
1322
+ if (view.isDestroyed) return;
1323
+ try {
1324
+ const unescapedResult = result.replace(/\\n/g, "\n").replace(/\\t/g, " ");
1325
+ const isHTML = /<\/?[a-z][\s\S]*>/i.test(unescapedResult);
1326
+ let parsedDoc;
1327
+ if (isHTML) {
1328
+ const div = document.createElement("div");
1329
+ div.innerHTML = unescapedResult;
1330
+ parsedDoc = DOMParser.fromSchema(view.state.schema).parse(div);
1331
+ } else {
1332
+ parsedDoc = parser.parse(unescapedResult);
1333
+ }
1334
+ if (parsedDoc) {
1335
+ const tr = view.state.tr.replaceWith(view.state.selection.from, view.state.selection.from, parsedDoc.content);
1336
+ view.dispatch(tr);
1337
+ } else {
1338
+ view.dispatch(view.state.tr.insertText(unescapedResult));
1339
+ }
1340
+ } catch (e) {
1341
+ console.error(e);
1342
+ view.dispatch(view.state.tr.insertText(result));
1343
+ }
1344
+ }
1345
+ };
1346
+ const SlashCommandMenu = ({
1347
+ upload,
1348
+ aiController
1349
+ }) => {
1350
+ const {
1351
+ view,
1352
+ state
1353
+ } = useProseMirrorContext();
1354
+ const menuRef = useRef(null);
1355
+ const [selectedIndex, setSelectedIndex] = useState(0);
1356
+ const [subView, setSubView] = useState(null);
1357
+ const [tableGridCoords, setTableGridCoords] = useState({
1358
+ r: 0,
1359
+ c: 0
1360
+ });
1361
+ const pluginState = state ? SlashCommandPluginKey.getState(state) : null;
1362
+ const isActive = pluginState?.active;
1363
+ const query = pluginState?.query || "";
1364
+ const range = pluginState?.range;
1365
+ const filteredItems = React__default.useMemo(() => {
1366
+ if (!isActive) return [];
1367
+ const availableItems = [...suggestionItems];
1368
+ if (aiController) availableItems.push(autocompleteSuggestionItem);
1369
+ return availableItems.filter((item) => {
1370
+ const inTitle = item.title.toLowerCase().includes(query.toLowerCase());
1371
+ if (inTitle) return inTitle;
1372
+ return item.searchTerms?.some((term) => term.toLowerCase().includes(query.toLowerCase()));
1373
+ });
1374
+ }, [query, isActive, aiController]);
1375
+ useEffect(() => {
1376
+ setSelectedIndex(0);
1377
+ }, [query]);
1378
+ useEffect(() => {
1379
+ if (!isActive) setSubView(null);
1380
+ }, [isActive]);
1381
+ useEffect(() => {
1382
+ if (!view || !isActive || !range || !menuRef.current) return;
1383
+ const start = view.coordsAtPos(range.from);
1384
+ const virtualEl = {
1385
+ getBoundingClientRect() {
1386
+ return {
1387
+ width: 0,
1388
+ height: start.bottom - start.top,
1389
+ x: start.left,
1390
+ y: start.top,
1391
+ top: start.top,
1392
+ left: start.left,
1393
+ right: start.left,
1394
+ bottom: start.bottom
1395
+ };
1396
+ }
1397
+ };
1398
+ const cleanup = autoUpdate(virtualEl, menuRef.current, () => {
1399
+ if (!menuRef.current) return;
1400
+ computePosition(virtualEl, menuRef.current, {
1401
+ placement: "bottom-start",
1402
+ middleware: [offset(4), flip(), shift()],
1403
+ strategy: "fixed"
1404
+ }).then(({
1405
+ x,
1406
+ y
1407
+ }) => {
1408
+ if (menuRef.current) {
1409
+ Object.assign(menuRef.current.style, {
1410
+ left: `${x}px`,
1411
+ top: `${y}px`,
1412
+ visibility: "visible"
1413
+ });
1414
+ }
1415
+ });
1416
+ });
1417
+ return () => cleanup();
1418
+ }, [view, isActive, range]);
1419
+ useEffect(() => {
1420
+ if (!isActive || !view) return;
1421
+ const handleKeyDown = (e) => {
1422
+ if (subView === "table-grid") {
1423
+ if (e.key === "Escape") {
1424
+ e.preventDefault();
1425
+ e.stopPropagation();
1426
+ e.stopImmediatePropagation();
1427
+ setSubView(null);
1428
+ setTableGridCoords({
1429
+ r: 0,
1430
+ c: 0
1431
+ });
1432
+ } else if (e.key === "ArrowUp") {
1433
+ e.preventDefault();
1434
+ e.stopPropagation();
1435
+ setTableGridCoords((prev) => ({
1436
+ r: Math.max(0, prev.r - 1),
1437
+ c: prev.c
1438
+ }));
1439
+ } else if (e.key === "ArrowDown") {
1440
+ e.preventDefault();
1441
+ e.stopPropagation();
1442
+ setTableGridCoords((prev_0) => ({
1443
+ r: Math.min(4, prev_0.r + 1),
1444
+ c: prev_0.c
1445
+ }));
1446
+ } else if (e.key === "ArrowLeft") {
1447
+ e.preventDefault();
1448
+ e.stopPropagation();
1449
+ setTableGridCoords((prev_1) => ({
1450
+ r: prev_1.r,
1451
+ c: Math.max(0, prev_1.c - 1)
1452
+ }));
1453
+ } else if (e.key === "ArrowRight") {
1454
+ e.preventDefault();
1455
+ e.stopPropagation();
1456
+ setTableGridCoords((prev_2) => ({
1457
+ r: prev_2.r,
1458
+ c: Math.min(4, prev_2.c + 1)
1459
+ }));
1460
+ } else if (e.key === "Enter") {
1461
+ e.preventDefault();
1462
+ e.stopPropagation();
1463
+ if (range) {
1464
+ const tableNode = createTableNode(view.state.schema, tableGridCoords.r + 1, tableGridCoords.c + 1);
1465
+ const tr = view.state.tr.replaceWith(range.from, range.to, tableNode);
1466
+ try {
1467
+ const selection = TextSelection.create(tr.doc, range.from + 4);
1468
+ tr.setSelection(selection);
1469
+ } catch (e_0) {
1470
+ console.warn("Could not select first cell", e_0);
1471
+ }
1472
+ tr.setMeta(SlashCommandPluginKey, {
1473
+ active: false
1474
+ });
1475
+ view.dispatch(tr);
1476
+ view.focus();
1477
+ setSubView(null);
1478
+ setTableGridCoords({
1479
+ r: 0,
1480
+ c: 0
1481
+ });
1482
+ }
1483
+ }
1484
+ return;
1485
+ }
1486
+ if (e.key === "ArrowUp") {
1487
+ e.preventDefault();
1488
+ e.stopPropagation();
1489
+ setSelectedIndex((prev_3) => (prev_3 + filteredItems.length - 1) % filteredItems.length);
1490
+ } else if (e.key === "ArrowDown") {
1491
+ e.preventDefault();
1492
+ e.stopPropagation();
1493
+ setSelectedIndex((prev_4) => (prev_4 + 1) % filteredItems.length);
1494
+ } else if (e.key === "Enter") {
1495
+ e.preventDefault();
1496
+ e.stopPropagation();
1497
+ if (filteredItems[selectedIndex] && range) {
1498
+ filteredItems[selectedIndex].command(view, range, upload, aiController, setSubView);
1499
+ setTimeout(() => {
1500
+ }, 0);
1501
+ }
1502
+ } else if (e.key === "Escape") {
1503
+ e.preventDefault();
1504
+ e.stopPropagation();
1505
+ e.stopImmediatePropagation();
1506
+ view.dispatch(view.state.tr.setMeta(SlashCommandPluginKey, {
1507
+ active: false,
1508
+ dismissed: true
1509
+ }));
1510
+ }
1511
+ };
1512
+ window.addEventListener("keydown", handleKeyDown, {
1513
+ capture: true
1514
+ });
1515
+ return () => window.removeEventListener("keydown", handleKeyDown, {
1516
+ capture: true
1517
+ });
1518
+ }, [isActive, selectedIndex, filteredItems, view, range, upload, aiController, subView, tableGridCoords]);
1519
+ const itemRefs = useRef([]);
1520
+ useEffect(() => {
1521
+ if (itemRefs.current[selectedIndex]) {
1522
+ itemRefs.current[selectedIndex]?.scrollIntoView({
1523
+ block: "nearest"
1524
+ });
1525
+ }
1526
+ }, [selectedIndex]);
1527
+ useEffect(() => {
1528
+ if (!subView) {
1529
+ setTableGridCoords({
1530
+ r: 0,
1531
+ c: 0
1532
+ });
1533
+ }
1534
+ }, [subView]);
1535
+ if (!isActive || filteredItems.length === 0) return null;
1536
+ if (subView === "table-grid" && range && view) {
1537
+ return /* @__PURE__ */ jsx("div", { ref: menuRef, onMouseDown: (e_1) => e_1.preventDefault(), style: {
1538
+ position: "fixed",
1539
+ zIndex: 9999,
1540
+ visibility: "hidden"
1541
+ }, className: cls("text-surface-900 dark:text-white rounded-md border bg-white dark:bg-surface-900 p-2 shadow transition-none", defaultBorderMixin), children: /* @__PURE__ */ jsx(TableGridPicker, { hoveredRow: tableGridCoords.r, hoveredCol: tableGridCoords.c, onHover: (r, c2) => setTableGridCoords({
1542
+ r,
1543
+ c: c2
1544
+ }), onSelect: (rows, cols) => {
1545
+ const tableNode_0 = createTableNode(view.state.schema, rows, cols);
1546
+ const tr_0 = view.state.tr.replaceWith(range.from, range.to, tableNode_0);
1547
+ try {
1548
+ const selection_0 = TextSelection.create(tr_0.doc, range.from + 4);
1549
+ tr_0.setSelection(selection_0);
1550
+ } catch (e_2) {
1551
+ console.warn("Could not select first cell", e_2);
1552
+ }
1553
+ tr_0.setMeta(SlashCommandPluginKey, {
1554
+ active: false
1555
+ });
1556
+ view.dispatch(tr_0);
1557
+ view.focus();
1558
+ setSubView(null);
1559
+ } }) });
1560
+ }
1561
+ return /* @__PURE__ */ jsx("div", { ref: menuRef, style: {
1562
+ position: "fixed",
1563
+ zIndex: 9999,
1564
+ visibility: "hidden"
1565
+ }, className: cls("text-surface-900 dark:text-white max-h-[280px] w-72 overflow-y-auto rounded-md border bg-white dark:bg-surface-900 px-1 py-2 shadow transition-none", defaultBorderMixin), children: filteredItems.map((item_0, index) => /* @__PURE__ */ jsxs("button", { ref: (el) => {
1566
+ itemRefs.current[index] = el;
1567
+ }, onClick: (e_3) => {
1568
+ e_3.preventDefault();
1569
+ if (range && view) {
1570
+ item_0.command(view, range, upload, aiController, setSubView);
1571
+ if (!subView) view.focus();
1572
+ }
1573
+ }, onMouseDown: (e_4) => e_4.preventDefault(), className: cls("flex w-full items-center space-x-2 rounded-md px-2 py-1 text-left text-sm hover:bg-blue-50 hover:dark:bg-surface-700", index === selectedIndex ? "bg-blue-100 dark:bg-surface-accent-950" : ""), children: [
1574
+ /* @__PURE__ */ jsx("div", { className: cls("flex h-10 w-10 shrink-0 items-center justify-center rounded-md border bg-white dark:bg-surface-900", defaultBorderMixin), children: item_0.icon }),
1575
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col overflow-hidden", children: [
1576
+ /* @__PURE__ */ jsx("p", { className: "font-medium truncate", children: item_0.title }),
1577
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-surface-700 dark:text-surface-accent-300 truncate", children: item_0.description })
1578
+ ] })
1579
+ ] }, item_0.title)) });
1580
+ };
1581
+ const createTableNode = (schema2, rowsCount, colsCount) => {
1582
+ const rows = [];
1583
+ for (let r = 0; r < rowsCount; r++) {
1584
+ const cells = [];
1585
+ for (let c2 = 0; c2 < colsCount; c2++) {
1586
+ const isHeader = r === 0;
1587
+ const cellType = isHeader ? schema2.nodes.table_header : schema2.nodes.table_cell;
1588
+ const cell = cellType.createAndFill();
1589
+ if (cell) cells.push(cell);
1590
+ }
1591
+ const row = schema2.nodes.table_row.create(null, Fragment.from(cells));
1592
+ rows.push(row);
1593
+ }
1594
+ return schema2.nodes.table.create(null, Fragment.from(rows));
1595
+ };
1596
+ const TableGridPicker = (t0) => {
1597
+ const $ = c(12);
1598
+ const {
1599
+ hoveredRow,
1600
+ hoveredCol,
1601
+ onHover,
1602
+ onSelect
1603
+ } = t0;
1604
+ const t1 = hoveredCol + 1;
1605
+ const t2 = hoveredRow + 1;
1606
+ let t3;
1607
+ if ($[0] !== t1 || $[1] !== t2) {
1608
+ t3 = /* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-500 font-medium mb-1", children: [
1609
+ t1,
1610
+ " x ",
1611
+ t2,
1612
+ " Table"
1613
+ ] });
1614
+ $[0] = t1;
1615
+ $[1] = t2;
1616
+ $[2] = t3;
1617
+ } else {
1618
+ t3 = $[2];
1619
+ }
1620
+ let t4;
1621
+ if ($[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
1622
+ t4 = Array.from({
1623
+ length: 5
1624
+ });
1625
+ $[3] = t4;
1626
+ } else {
1627
+ t4 = $[3];
1628
+ }
1629
+ let t5;
1630
+ if ($[4] !== hoveredCol || $[5] !== hoveredRow || $[6] !== onHover || $[7] !== onSelect) {
1631
+ t5 = /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children: t4.map((_, r) => /* @__PURE__ */ jsx("div", { className: "flex gap-1", children: Array.from({
1632
+ length: 5
1633
+ }).map((__0, c2) => /* @__PURE__ */ jsx("div", { className: cls("w-5 h-5 border rounded-sm cursor-pointer transition-colors duration-75", r <= hoveredRow && c2 <= hoveredCol ? "bg-blue-100 border-blue-400 dark:bg-blue-900 dark:border-blue-500" : "bg-white dark:bg-surface-800 border-gray-200 dark:border-gray-700 hover:border-blue-300"), onMouseEnter: () => onHover(r, c2), onClick: () => onSelect(hoveredRow + 1, hoveredCol + 1) }, c2)) }, r)) });
1634
+ $[4] = hoveredCol;
1635
+ $[5] = hoveredRow;
1636
+ $[6] = onHover;
1637
+ $[7] = onSelect;
1638
+ $[8] = t5;
1639
+ } else {
1640
+ t5 = $[8];
1641
+ }
1642
+ let t6;
1643
+ if ($[9] !== t3 || $[10] !== t5) {
1644
+ t6 = /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 items-center justify-center p-1 w-fit", children: [
1645
+ t3,
1646
+ t5
1647
+ ] });
1648
+ $[9] = t3;
1649
+ $[10] = t5;
1650
+ $[11] = t6;
1651
+ } else {
1652
+ t6 = $[11];
1653
+ }
1654
+ return t6;
1655
+ };
1656
+ const ImageBubble = forwardRef((t0, ref) => {
1657
+ const $ = c(36);
1658
+ const {
1659
+ options,
1660
+ className
1661
+ } = t0;
1662
+ const {
1663
+ view,
1664
+ state
1665
+ } = useProseMirrorContext();
1666
+ const menuRef = useRef(null);
1667
+ const [show, setShow] = useState(false);
1668
+ const [alt, setAlt] = useState("");
1669
+ const [title, setTitle] = useState("");
1670
+ const [imagePos, setImagePos] = useState(null);
1671
+ let t1;
1672
+ let t2;
1673
+ if ($[0] !== view) {
1674
+ t1 = () => {
1675
+ if (!view) {
1676
+ return;
1677
+ }
1678
+ const handleContextMenu = (e) => {
1679
+ const posInfo = view.posAtCoords({
1680
+ left: e.clientX,
1681
+ top: e.clientY
1682
+ });
1683
+ if (posInfo && posInfo.inside >= 0) {
1684
+ const node = view.state.doc.nodeAt(posInfo.inside);
1685
+ if (node && node.type.name === "image") {
1686
+ e.preventDefault();
1687
+ const tr = view.state.tr.setSelection(NodeSelection.create(view.state.doc, posInfo.inside));
1688
+ view.dispatch(tr);
1689
+ setShow(true);
1690
+ setAlt(node.attrs.alt || "");
1691
+ setTitle(node.attrs.title || "");
1692
+ setImagePos(posInfo.inside);
1693
+ }
1694
+ }
1695
+ };
1696
+ view.dom.addEventListener("contextmenu", handleContextMenu);
1697
+ const handleMousedown = (e_0) => {
1698
+ if (menuRef.current && !menuRef.current.contains(e_0.target) && e_0.button !== 2) {
1699
+ setShow(false);
1700
+ }
1701
+ };
1702
+ document.addEventListener("mousedown", handleMousedown);
1703
+ return () => {
1704
+ view.dom.removeEventListener("contextmenu", handleContextMenu);
1705
+ document.removeEventListener("mousedown", handleMousedown);
1706
+ };
1707
+ };
1708
+ t2 = [view];
1709
+ $[0] = view;
1710
+ $[1] = t1;
1711
+ $[2] = t2;
1712
+ } else {
1713
+ t1 = $[1];
1714
+ t2 = $[2];
1715
+ }
1716
+ useEffect(t1, t2);
1717
+ let t3;
1718
+ if ($[3] !== options?.offset || $[4] !== options?.placement || $[5] !== show || $[6] !== state || $[7] !== view) {
1719
+ t3 = () => {
1720
+ if (!show || !view || !state || !menuRef.current) {
1721
+ return;
1722
+ }
1723
+ const {
1724
+ from,
1725
+ to
1726
+ } = state.selection;
1727
+ let start;
1728
+ start = view.coordsAtPos(from);
1729
+ let end;
1730
+ end = view.coordsAtPos(to);
1731
+ const virtualEl = {
1732
+ getBoundingClientRect() {
1733
+ const top = Math.min(start.top, end.top);
1734
+ const bottom = Math.max(start.bottom, end.bottom);
1735
+ const left = Math.min(start.left, end.left);
1736
+ const right = Math.max(start.right, end.right);
1737
+ return {
1738
+ width: right - left,
1739
+ height: bottom - top,
1740
+ x: left,
1741
+ y: top,
1742
+ top,
1743
+ left,
1744
+ right,
1745
+ bottom
1746
+ };
1747
+ }
1748
+ };
1749
+ const cleanup = autoUpdate(virtualEl, menuRef.current, () => {
1750
+ if (!menuRef.current) {
1751
+ return;
1752
+ }
1753
+ try {
1754
+ start = view.coordsAtPos(state.selection.from);
1755
+ end = view.coordsAtPos(state.selection.to);
1756
+ } catch (t42) {
1757
+ }
1758
+ computePosition(virtualEl, menuRef.current, {
1759
+ placement: options?.placement || "bottom",
1760
+ middleware: [offset(options?.offset || 8), flip(), shift()],
1761
+ strategy: "fixed"
1762
+ }).then((t52) => {
1763
+ const {
1764
+ x,
1765
+ y
1766
+ } = t52;
1767
+ if (menuRef.current) {
1768
+ Object.assign(menuRef.current.style, {
1769
+ left: `${x}px`,
1770
+ top: `${y}px`,
1771
+ visibility: "visible"
1772
+ });
1773
+ }
1774
+ });
1775
+ });
1776
+ return () => cleanup();
1777
+ };
1778
+ $[3] = options?.offset;
1779
+ $[4] = options?.placement;
1780
+ $[5] = show;
1781
+ $[6] = state;
1782
+ $[7] = view;
1783
+ $[8] = t3;
1784
+ } else {
1785
+ t3 = $[8];
1786
+ }
1787
+ let t4;
1788
+ if ($[9] !== options || $[10] !== show || $[11] !== state || $[12] !== view) {
1789
+ t4 = [show, view, state, options];
1790
+ $[9] = options;
1791
+ $[10] = show;
1792
+ $[11] = state;
1793
+ $[12] = view;
1794
+ $[13] = t4;
1795
+ } else {
1796
+ t4 = $[13];
1797
+ }
1798
+ useEffect(t3, t4);
1799
+ let t5;
1800
+ if ($[14] !== imagePos || $[15] !== view) {
1801
+ t5 = (newAlt, newTitle) => {
1802
+ if (imagePos !== null && view) {
1803
+ const node_0 = view.state.doc.nodeAt(imagePos);
1804
+ if (node_0 && node_0.type.name === "image") {
1805
+ const tr_0 = view.state.tr.setNodeMarkup(imagePos, void 0, {
1806
+ ...node_0.attrs,
1807
+ alt: newAlt,
1808
+ title: newTitle
1809
+ });
1810
+ tr_0.setSelection(NodeSelection.create(tr_0.doc, imagePos));
1811
+ view.dispatch(tr_0);
1812
+ }
1813
+ }
1814
+ };
1815
+ $[14] = imagePos;
1816
+ $[15] = view;
1817
+ $[16] = t5;
1818
+ } else {
1819
+ t5 = $[16];
1820
+ }
1821
+ const handleSave = t5;
1822
+ if (!show) {
1823
+ return null;
1824
+ }
1825
+ let t6;
1826
+ if ($[17] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
1827
+ t6 = {
1828
+ visibility: "hidden",
1829
+ position: "fixed",
1830
+ zIndex: 50
1831
+ };
1832
+ $[17] = t6;
1833
+ } else {
1834
+ t6 = $[17];
1835
+ }
1836
+ let t7;
1837
+ if ($[18] !== className) {
1838
+ t7 = cls("flex flex-col gap-1.5 p-2 w-56 max-w-[90vw] rounded-lg border bg-white dark:bg-surface-900 shadow-lg", defaultBorderMixin, className);
1839
+ $[18] = className;
1840
+ $[19] = t7;
1841
+ } else {
1842
+ t7 = $[19];
1843
+ }
1844
+ let t8;
1845
+ if ($[20] !== handleSave || $[21] !== title) {
1846
+ t8 = (e_3) => {
1847
+ setAlt(e_3.target.value);
1848
+ handleSave(e_3.target.value, title);
1849
+ };
1850
+ $[20] = handleSave;
1851
+ $[21] = title;
1852
+ $[22] = t8;
1853
+ } else {
1854
+ t8 = $[22];
1855
+ }
1856
+ let t9;
1857
+ if ($[23] !== alt || $[24] !== t8) {
1858
+ t9 = /* @__PURE__ */ jsx(TextField, { size: "small", placeholder: "Alt text", value: alt, onChange: t8 });
1859
+ $[23] = alt;
1860
+ $[24] = t8;
1861
+ $[25] = t9;
1862
+ } else {
1863
+ t9 = $[25];
1864
+ }
1865
+ let t10;
1866
+ if ($[26] !== alt || $[27] !== handleSave) {
1867
+ t10 = (e_4) => {
1868
+ setTitle(e_4.target.value);
1869
+ handleSave(alt, e_4.target.value);
1870
+ };
1871
+ $[26] = alt;
1872
+ $[27] = handleSave;
1873
+ $[28] = t10;
1874
+ } else {
1875
+ t10 = $[28];
1876
+ }
1877
+ let t11;
1878
+ if ($[29] !== t10 || $[30] !== title) {
1879
+ t11 = /* @__PURE__ */ jsx(TextField, { size: "small", placeholder: "Title", value: title, onChange: t10 });
1880
+ $[29] = t10;
1881
+ $[30] = title;
1882
+ $[31] = t11;
1883
+ } else {
1884
+ t11 = $[31];
1885
+ }
1886
+ let t12;
1887
+ if ($[32] !== t11 || $[33] !== t7 || $[34] !== t9) {
1888
+ t12 = /* @__PURE__ */ jsxs("div", { ref: menuRef, style: t6, className: t7, onMouseDown: _temp$3, children: [
1889
+ t9,
1890
+ t11
1891
+ ] });
1892
+ $[32] = t11;
1893
+ $[33] = t7;
1894
+ $[34] = t9;
1895
+ $[35] = t12;
1896
+ } else {
1897
+ t12 = $[35];
1898
+ }
1899
+ return t12;
1900
+ });
1901
+ function _temp$3(e_2) {
1902
+ if (e_2.target === e_2.currentTarget) {
1903
+ e_2.preventDefault();
1904
+ }
1905
+ }
1906
+ const isSelectionInTable = (state) => {
1907
+ const {
1908
+ $from
1909
+ } = state.selection;
1910
+ for (let d = $from.depth; d > 0; d--) {
1911
+ if ($from.node(d).type.name === "table") {
1912
+ return true;
1913
+ }
1914
+ }
1915
+ return false;
1916
+ };
1917
+ const TableBubble = forwardRef((t0, ref) => {
1918
+ const $ = c(69);
1919
+ const {
1920
+ options,
1921
+ className
1922
+ } = t0;
1923
+ const {
1924
+ view,
1925
+ state
1926
+ } = useProseMirrorContext();
1927
+ const menuRef = useRef(null);
1928
+ const [show, setShow] = useState(false);
1929
+ let t1;
1930
+ if ($[0] !== state) {
1931
+ t1 = () => {
1932
+ if (!state) {
1933
+ return;
1934
+ }
1935
+ setShow(isSelectionInTable(state));
1936
+ };
1937
+ $[0] = state;
1938
+ $[1] = t1;
1939
+ } else {
1940
+ t1 = $[1];
1941
+ }
1942
+ const t2 = state?.selection;
1943
+ let t3;
1944
+ if ($[2] !== t2) {
1945
+ t3 = [t2];
1946
+ $[2] = t2;
1947
+ $[3] = t3;
1948
+ } else {
1949
+ t3 = $[3];
1950
+ }
1951
+ useEffect(t1, t3);
1952
+ let t4;
1953
+ if ($[4] !== options?.offset || $[5] !== options?.placement || $[6] !== show || $[7] !== state || $[8] !== view) {
1954
+ t4 = () => {
1955
+ if (!show || !view || !state || !menuRef.current) {
1956
+ return;
1957
+ }
1958
+ const {
1959
+ from,
1960
+ to
1961
+ } = state.selection;
1962
+ if (view.isDestroyed) {
1963
+ return;
1964
+ }
1965
+ let start;
1966
+ start = view.coordsAtPos(from);
1967
+ let end;
1968
+ end = view.coordsAtPos(to);
1969
+ const virtualEl = {
1970
+ getBoundingClientRect() {
1971
+ const top = Math.min(start.top, end.top);
1972
+ const bottom = Math.max(start.bottom, end.bottom);
1973
+ const left = Math.min(start.left, end.left);
1974
+ const right = Math.max(start.right, end.right);
1975
+ return {
1976
+ width: right - left,
1977
+ height: bottom - top,
1978
+ x: left,
1979
+ y: top,
1980
+ top,
1981
+ bottom,
1982
+ left,
1983
+ right
1984
+ };
1985
+ }
1986
+ };
1987
+ const cleanup = autoUpdate(virtualEl, menuRef.current, () => {
1988
+ if (!menuRef.current || view.isDestroyed) {
1989
+ return;
1990
+ }
1991
+ try {
1992
+ start = view.coordsAtPos(state.selection.from);
1993
+ end = view.coordsAtPos(state.selection.to);
1994
+ } catch (t52) {
1995
+ }
1996
+ computePosition(virtualEl, menuRef.current, {
1997
+ placement: options?.placement || "top",
1998
+ middleware: [offset(options?.offset || 8), flip(), shift()],
1999
+ strategy: "fixed"
2000
+ }).then((t62) => {
2001
+ const {
2002
+ x,
2003
+ y
2004
+ } = t62;
2005
+ if (menuRef.current) {
2006
+ Object.assign(menuRef.current.style, {
2007
+ left: `${x}px`,
2008
+ top: `${y}px`,
2009
+ visibility: "visible"
2010
+ });
2011
+ }
2012
+ });
2013
+ });
2014
+ return () => cleanup();
2015
+ };
2016
+ $[4] = options?.offset;
2017
+ $[5] = options?.placement;
2018
+ $[6] = show;
2019
+ $[7] = state;
2020
+ $[8] = view;
2021
+ $[9] = t4;
2022
+ } else {
2023
+ t4 = $[9];
2024
+ }
2025
+ let t5;
2026
+ if ($[10] !== options || $[11] !== show || $[12] !== state || $[13] !== view) {
2027
+ t5 = [show, view, state, options];
2028
+ $[10] = options;
2029
+ $[11] = show;
2030
+ $[12] = state;
2031
+ $[13] = view;
2032
+ $[14] = t5;
2033
+ } else {
2034
+ t5 = $[14];
2035
+ }
2036
+ useEffect(t4, t5);
2037
+ if (!show || !view || !state) {
2038
+ return null;
2039
+ }
2040
+ let t6;
2041
+ if ($[15] !== state || $[16] !== view) {
2042
+ t6 = (cmd) => {
2043
+ cmd(state, view.dispatch);
2044
+ view.focus();
2045
+ };
2046
+ $[15] = state;
2047
+ $[16] = view;
2048
+ $[17] = t6;
2049
+ } else {
2050
+ t6 = $[17];
2051
+ }
2052
+ const executeCommand = t6;
2053
+ let t7;
2054
+ if ($[18] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2055
+ t7 = {
2056
+ visibility: "hidden",
2057
+ position: "fixed",
2058
+ zIndex: 50
2059
+ };
2060
+ $[18] = t7;
2061
+ } else {
2062
+ t7 = $[18];
2063
+ }
2064
+ let t8;
2065
+ if ($[19] !== className) {
2066
+ t8 = cls("flex flex-row gap-1 p-1 rounded-lg border bg-white dark:bg-surface-900 shadow-lg", defaultBorderMixin, className);
2067
+ $[19] = className;
2068
+ $[20] = t8;
2069
+ } else {
2070
+ t8 = $[20];
2071
+ }
2072
+ let t9;
2073
+ if ($[21] !== executeCommand) {
2074
+ t9 = () => executeCommand(addRowBefore);
2075
+ $[21] = executeCommand;
2076
+ $[22] = t9;
2077
+ } else {
2078
+ t9 = $[22];
2079
+ }
2080
+ let t10;
2081
+ if ($[23] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2082
+ t10 = /* @__PURE__ */ jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2083
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }),
2084
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "8", x2: "12", y2: "16" }),
2085
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "12", x2: "16", y2: "12" }),
2086
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "9", x2: "21", y2: "9" })
2087
+ ] });
2088
+ $[23] = t10;
2089
+ } else {
2090
+ t10 = $[23];
2091
+ }
2092
+ let t11;
2093
+ if ($[24] !== t9) {
2094
+ t11 = /* @__PURE__ */ jsx(Tooltip, { title: "Add row before", children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: t9, children: t10 }) });
2095
+ $[24] = t9;
2096
+ $[25] = t11;
2097
+ } else {
2098
+ t11 = $[25];
2099
+ }
2100
+ let t12;
2101
+ if ($[26] !== executeCommand) {
2102
+ t12 = () => executeCommand(addRowAfter);
2103
+ $[26] = executeCommand;
2104
+ $[27] = t12;
2105
+ } else {
2106
+ t12 = $[27];
2107
+ }
2108
+ let t13;
2109
+ if ($[28] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2110
+ t13 = /* @__PURE__ */ jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2111
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }),
2112
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "12", x2: "12", y2: "20" }),
2113
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "16", x2: "16", y2: "16" }),
2114
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "15", x2: "21", y2: "15" })
2115
+ ] });
2116
+ $[28] = t13;
2117
+ } else {
2118
+ t13 = $[28];
2119
+ }
2120
+ let t14;
2121
+ if ($[29] !== t12) {
2122
+ t14 = /* @__PURE__ */ jsx(Tooltip, { title: "Add row after", children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: t12, children: t13 }) });
2123
+ $[29] = t12;
2124
+ $[30] = t14;
2125
+ } else {
2126
+ t14 = $[30];
2127
+ }
2128
+ let t15;
2129
+ if ($[31] !== executeCommand) {
2130
+ t15 = () => executeCommand(deleteRow);
2131
+ $[31] = executeCommand;
2132
+ $[32] = t15;
2133
+ } else {
2134
+ t15 = $[32];
2135
+ }
2136
+ let t16;
2137
+ if ($[33] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2138
+ t16 = /* @__PURE__ */ jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2139
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }),
2140
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "12", x2: "21", y2: "12" }),
2141
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "12", x2: "16", y2: "12" })
2142
+ ] });
2143
+ $[33] = t16;
2144
+ } else {
2145
+ t16 = $[33];
2146
+ }
2147
+ let t17;
2148
+ if ($[34] !== t15) {
2149
+ t17 = /* @__PURE__ */ jsx(Tooltip, { title: "Delete row", children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: t15, children: t16 }) });
2150
+ $[34] = t15;
2151
+ $[35] = t17;
2152
+ } else {
2153
+ t17 = $[35];
2154
+ }
2155
+ let t18;
2156
+ if ($[36] !== t11 || $[37] !== t14 || $[38] !== t17) {
2157
+ t18 = /* @__PURE__ */ jsxs("div", { className: "flex gap-1 border-r pr-1 mr-1 dark:border-gray-700", children: [
2158
+ t11,
2159
+ t14,
2160
+ t17
2161
+ ] });
2162
+ $[36] = t11;
2163
+ $[37] = t14;
2164
+ $[38] = t17;
2165
+ $[39] = t18;
2166
+ } else {
2167
+ t18 = $[39];
2168
+ }
2169
+ let t19;
2170
+ if ($[40] !== executeCommand) {
2171
+ t19 = () => executeCommand(addColumnBefore);
2172
+ $[40] = executeCommand;
2173
+ $[41] = t19;
2174
+ } else {
2175
+ t19 = $[41];
2176
+ }
2177
+ let t20;
2178
+ if ($[42] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2179
+ t20 = /* @__PURE__ */ jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2180
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }),
2181
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "12", x2: "16", y2: "12" }),
2182
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "8", x2: "12", y2: "16" }),
2183
+ /* @__PURE__ */ jsx("line", { x1: "9", y1: "3", x2: "9", y2: "21" })
2184
+ ] });
2185
+ $[42] = t20;
2186
+ } else {
2187
+ t20 = $[42];
2188
+ }
2189
+ let t21;
2190
+ if ($[43] !== t19) {
2191
+ t21 = /* @__PURE__ */ jsx(Tooltip, { title: "Add column before", children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: t19, children: t20 }) });
2192
+ $[43] = t19;
2193
+ $[44] = t21;
2194
+ } else {
2195
+ t21 = $[44];
2196
+ }
2197
+ let t22;
2198
+ if ($[45] !== executeCommand) {
2199
+ t22 = () => executeCommand(addColumnAfter);
2200
+ $[45] = executeCommand;
2201
+ $[46] = t22;
2202
+ } else {
2203
+ t22 = $[46];
2204
+ }
2205
+ let t23;
2206
+ if ($[47] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2207
+ t23 = /* @__PURE__ */ jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2208
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }),
2209
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "12", x2: "20", y2: "12" }),
2210
+ /* @__PURE__ */ jsx("line", { x1: "16", y1: "8", x2: "16", y2: "16" }),
2211
+ /* @__PURE__ */ jsx("line", { x1: "15", y1: "3", x2: "15", y2: "21" })
2212
+ ] });
2213
+ $[47] = t23;
2214
+ } else {
2215
+ t23 = $[47];
2216
+ }
2217
+ let t24;
2218
+ if ($[48] !== t22) {
2219
+ t24 = /* @__PURE__ */ jsx(Tooltip, { title: "Add column after", children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: t22, children: t23 }) });
2220
+ $[48] = t22;
2221
+ $[49] = t24;
2222
+ } else {
2223
+ t24 = $[49];
2224
+ }
2225
+ let t25;
2226
+ if ($[50] !== executeCommand) {
2227
+ t25 = () => executeCommand(deleteColumn);
2228
+ $[50] = executeCommand;
2229
+ $[51] = t25;
2230
+ } else {
2231
+ t25 = $[51];
2232
+ }
2233
+ let t26;
2234
+ if ($[52] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2235
+ t26 = /* @__PURE__ */ jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2236
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }),
2237
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "3", x2: "12", y2: "21" }),
2238
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "8", x2: "12", y2: "16" })
2239
+ ] });
2240
+ $[52] = t26;
2241
+ } else {
2242
+ t26 = $[52];
2243
+ }
2244
+ let t27;
2245
+ if ($[53] !== t25) {
2246
+ t27 = /* @__PURE__ */ jsx(Tooltip, { title: "Delete column", children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: t25, children: t26 }) });
2247
+ $[53] = t25;
2248
+ $[54] = t27;
2249
+ } else {
2250
+ t27 = $[54];
2251
+ }
2252
+ let t28;
2253
+ if ($[55] !== t21 || $[56] !== t24 || $[57] !== t27) {
2254
+ t28 = /* @__PURE__ */ jsxs("div", { className: "flex gap-1 border-r pr-1 mr-1 dark:border-gray-700", children: [
2255
+ t21,
2256
+ t24,
2257
+ t27
2258
+ ] });
2259
+ $[55] = t21;
2260
+ $[56] = t24;
2261
+ $[57] = t27;
2262
+ $[58] = t28;
2263
+ } else {
2264
+ t28 = $[58];
2265
+ }
2266
+ let t29;
2267
+ if ($[59] !== executeCommand) {
2268
+ t29 = () => executeCommand(deleteTable);
2269
+ $[59] = executeCommand;
2270
+ $[60] = t29;
2271
+ } else {
2272
+ t29 = $[60];
2273
+ }
2274
+ let t30;
2275
+ if ($[61] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2276
+ t30 = /* @__PURE__ */ jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2277
+ /* @__PURE__ */ jsx("polyline", { points: "3 6 5 6 21 6" }),
2278
+ /* @__PURE__ */ jsx("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }),
2279
+ /* @__PURE__ */ jsx("line", { x1: "10", y1: "11", x2: "10", y2: "17" }),
2280
+ /* @__PURE__ */ jsx("line", { x1: "14", y1: "11", x2: "14", y2: "17" })
2281
+ ] });
2282
+ $[61] = t30;
2283
+ } else {
2284
+ t30 = $[61];
2285
+ }
2286
+ let t31;
2287
+ if ($[62] !== t29) {
2288
+ t31 = /* @__PURE__ */ jsx(Tooltip, { title: "Delete table", children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: t29, children: t30 }) });
2289
+ $[62] = t29;
2290
+ $[63] = t31;
2291
+ } else {
2292
+ t31 = $[63];
2293
+ }
2294
+ let t32;
2295
+ if ($[64] !== t18 || $[65] !== t28 || $[66] !== t31 || $[67] !== t8) {
2296
+ t32 = /* @__PURE__ */ jsxs("div", { ref: menuRef, style: t7, className: t8, onMouseDown: _temp$2, children: [
2297
+ t18,
2298
+ t28,
2299
+ t31
2300
+ ] });
2301
+ $[64] = t18;
2302
+ $[65] = t28;
2303
+ $[66] = t31;
2304
+ $[67] = t8;
2305
+ $[68] = t32;
2306
+ } else {
2307
+ t32 = $[68];
2308
+ }
2309
+ return t32;
2310
+ });
2311
+ function _temp$2(e_0) {
2312
+ e_0.preventDefault();
2313
+ }
2314
+ function isMarkActive(state, type) {
2315
+ if (!state || !type) return false;
2316
+ const {
2317
+ from,
2318
+ $from,
2319
+ to,
2320
+ empty
2321
+ } = state.selection;
2322
+ if (empty) return !!type.isInSet(state.storedMarks || $from.marks());
2323
+ return state.doc.rangeHasMark(from, to, type);
2324
+ }
2325
+ function isNodeActive(state, type, attrs = {}) {
2326
+ if (!state || !type) return false;
2327
+ const {
2328
+ $from,
2329
+ to,
2330
+ node
2331
+ } = state.selection;
2332
+ if (node) {
2333
+ return node.type === type && (!attrs || Object.keys(attrs).every((key) => node.attrs[key] === attrs[key]));
2334
+ }
2335
+ return to <= $from.end() && $from.parent.type === type && (!attrs || Object.keys(attrs).every((key) => $from.parent.attrs[key] === attrs[key]));
2336
+ }
2337
+ function getMarkAttributes(state, type) {
2338
+ if (!state || !type) return {};
2339
+ const {
2340
+ from,
2341
+ $from,
2342
+ to,
2343
+ empty
2344
+ } = state.selection;
2345
+ let mark;
2346
+ if (empty) {
2347
+ mark = type.isInSet(state.storedMarks || $from.marks());
2348
+ } else {
2349
+ let found = false;
2350
+ state.doc.nodesBetween(from, to, (node) => {
2351
+ if (found) return false;
2352
+ const m = type.isInSet(node.marks);
2353
+ if (m) {
2354
+ mark = m;
2355
+ found = true;
2356
+ }
2357
+ return true;
2358
+ });
2359
+ }
2360
+ return mark ? mark.attrs : {};
2361
+ }
2362
+ function setMark(type, attrs) {
2363
+ return (state, dispatch) => {
2364
+ const {
2365
+ empty,
2366
+ $cursor,
2367
+ ranges
2368
+ } = state.selection;
2369
+ if (empty && !$cursor || !type) return false;
2370
+ if (dispatch) {
2371
+ if ($cursor) {
2372
+ dispatch(state.tr.addStoredMark(type.create(attrs)));
2373
+ } else {
2374
+ let tr = state.tr;
2375
+ for (let i = 0; i < ranges.length; i++) {
2376
+ let {
2377
+ $from,
2378
+ $to
2379
+ } = ranges[i];
2380
+ tr.addMark($from.pos, $to.pos, type.create(attrs));
2381
+ }
2382
+ dispatch(tr.scrollIntoView());
2383
+ }
2384
+ }
2385
+ return true;
2386
+ };
2387
+ }
2388
+ function unsetMark(type) {
2389
+ return (state, dispatch) => {
2390
+ const {
2391
+ empty,
2392
+ $cursor,
2393
+ ranges
2394
+ } = state.selection;
2395
+ if (empty && !$cursor || !type) return false;
2396
+ if (dispatch) {
2397
+ let tr = state.tr;
2398
+ if ($cursor) {
2399
+ const parent = $cursor.parent;
2400
+ let markStart = -1;
2401
+ let markEnd = -1;
2402
+ let currentMarkStart = -1;
2403
+ parent.forEach((child, offset2) => {
2404
+ const childStart = $cursor.start() + offset2;
2405
+ const childEnd = childStart + child.nodeSize;
2406
+ if (type.isInSet(child.marks)) {
2407
+ if (currentMarkStart === -1) currentMarkStart = childStart;
2408
+ if ($cursor.pos >= childStart && $cursor.pos <= childEnd) {
2409
+ markStart = currentMarkStart;
2410
+ }
2411
+ } else {
2412
+ if (currentMarkStart !== -1) {
2413
+ if (markStart !== -1 && markEnd === -1) markEnd = childStart;
2414
+ currentMarkStart = -1;
2415
+ }
2416
+ }
2417
+ });
2418
+ if (markStart !== -1 && markEnd === -1) {
2419
+ markEnd = $cursor.end();
2420
+ }
2421
+ if (markStart !== -1 && markEnd !== -1) {
2422
+ tr.removeMark(markStart, markEnd, type);
2423
+ }
2424
+ tr.removeStoredMark(type);
2425
+ dispatch(tr.scrollIntoView());
2426
+ } else {
2427
+ for (let i = 0; i < ranges.length; i++) {
2428
+ let {
2429
+ $from,
2430
+ $to
2431
+ } = ranges[i];
2432
+ tr.removeMark($from.pos, $to.pos, type);
2433
+ }
2434
+ dispatch(tr.scrollIntoView());
2435
+ }
2436
+ }
2437
+ return true;
2438
+ };
2439
+ }
2440
+ const items = [{
2441
+ name: "Text",
2442
+ labelKey: "editor_text",
2443
+ icon: TextFieldsIcon,
2444
+ command: (state, dispatch) => setBlockType(schema.nodes.paragraph)(state, dispatch),
2445
+ isActive: (state) => isNodeActive(state, schema.nodes.paragraph) && !isNodeActive(state, schema.nodes.bullet_list) && !isNodeActive(state, schema.nodes.ordered_list)
2446
+ }, {
2447
+ name: "Heading 1",
2448
+ labelKey: "editor_heading_1",
2449
+ icon: LooksOneIcon,
2450
+ command: (state, dispatch) => setBlockType(schema.nodes.heading, {
2451
+ level: 1
2452
+ })(state, dispatch),
2453
+ isActive: (state) => isNodeActive(state, schema.nodes.heading, {
2454
+ level: 1
2455
+ })
2456
+ }, {
2457
+ name: "Heading 2",
2458
+ labelKey: "editor_heading_2",
2459
+ icon: LooksTwoIcon,
2460
+ command: (state, dispatch) => setBlockType(schema.nodes.heading, {
2461
+ level: 2
2462
+ })(state, dispatch),
2463
+ isActive: (state) => isNodeActive(state, schema.nodes.heading, {
2464
+ level: 2
2465
+ })
2466
+ }, {
2467
+ name: "Heading 3",
2468
+ labelKey: "editor_heading_3",
2469
+ icon: Looks3Icon,
2470
+ command: (state, dispatch) => setBlockType(schema.nodes.heading, {
2471
+ level: 3
2472
+ })(state, dispatch),
2473
+ isActive: (state) => isNodeActive(state, schema.nodes.heading, {
2474
+ level: 3
2475
+ })
2476
+ }, {
2477
+ name: "To-do List",
2478
+ labelKey: "editor_todo_list",
2479
+ icon: CheckBoxIcon,
2480
+ command: (state, dispatch) => wrapInList(schema.nodes.task_list)(state, dispatch),
2481
+ isActive: (state) => isNodeActive(state, schema.nodes.task_item)
2482
+ }, {
2483
+ name: "Bullet List",
2484
+ labelKey: "editor_bullet_list",
2485
+ icon: FormatListBulletedIcon,
2486
+ command: (state, dispatch) => wrapInList(schema.nodes.bullet_list)(state, dispatch),
2487
+ isActive: (state) => isNodeActive(state, schema.nodes.bullet_list)
2488
+ }, {
2489
+ name: "Numbered List",
2490
+ labelKey: "editor_numbered_list",
2491
+ icon: FormatListNumberedIcon,
2492
+ command: (state, dispatch) => wrapInList(schema.nodes.ordered_list)(state, dispatch),
2493
+ isActive: (state) => isNodeActive(state, schema.nodes.ordered_list)
2494
+ }, {
2495
+ name: "Quote",
2496
+ labelKey: "editor_quote",
2497
+ icon: FormatQuoteIcon,
2498
+ command: (state, dispatch) => wrapIn(schema.nodes.blockquote)(state, dispatch),
2499
+ isActive: (state) => isNodeActive(state, schema.nodes.blockquote)
2500
+ }, {
2501
+ name: "Code",
2502
+ labelKey: "editor_code",
2503
+ icon: CodeIcon,
2504
+ command: (state, dispatch) => setBlockType(schema.nodes.code_block)(state, dispatch),
2505
+ isActive: (state) => isNodeActive(state, schema.nodes.code_block)
2506
+ }];
2507
+ const NodeSelector = (t0) => {
2508
+ const $ = c(40);
2509
+ const {
2510
+ open,
2511
+ onOpenChange,
2512
+ portalContainer
2513
+ } = t0;
2514
+ const {
2515
+ state,
2516
+ view
2517
+ } = useProseMirrorContext();
2518
+ const {
2519
+ t
2520
+ } = useTranslation();
2521
+ if (!state || !view) {
2522
+ return null;
2523
+ }
2524
+ let T0;
2525
+ let T1;
2526
+ let activeItem;
2527
+ let t1;
2528
+ let t2;
2529
+ let t3;
2530
+ let t4;
2531
+ let t5;
2532
+ let t6;
2533
+ let t7;
2534
+ let t8;
2535
+ let t9;
2536
+ if ($[0] !== portalContainer || $[1] !== state || $[2] !== t) {
2537
+ activeItem = items.filter((item) => item.isActive(state)).pop() ?? {
2538
+ name: "Multiple",
2539
+ labelKey: "editor_multiple"
2540
+ };
2541
+ T1 = Popover;
2542
+ t6 = 5;
2543
+ t7 = "start";
2544
+ t8 = portalContainer;
2545
+ t9 = "w-48 p-1";
2546
+ T0 = Button;
2547
+ t3 = "text";
2548
+ t4 = "gap-2 rounded-none";
2549
+ t5 = "text";
2550
+ t1 = "whitespace-nowrap text-sm";
2551
+ t2 = t(activeItem.labelKey);
2552
+ $[0] = portalContainer;
2553
+ $[1] = state;
2554
+ $[2] = t;
2555
+ $[3] = T0;
2556
+ $[4] = T1;
2557
+ $[5] = activeItem;
2558
+ $[6] = t1;
2559
+ $[7] = t2;
2560
+ $[8] = t3;
2561
+ $[9] = t4;
2562
+ $[10] = t5;
2563
+ $[11] = t6;
2564
+ $[12] = t7;
2565
+ $[13] = t8;
2566
+ $[14] = t9;
2567
+ } else {
2568
+ T0 = $[3];
2569
+ T1 = $[4];
2570
+ activeItem = $[5];
2571
+ t1 = $[6];
2572
+ t2 = $[7];
2573
+ t3 = $[8];
2574
+ t4 = $[9];
2575
+ t5 = $[10];
2576
+ t6 = $[11];
2577
+ t7 = $[12];
2578
+ t8 = $[13];
2579
+ t9 = $[14];
2580
+ }
2581
+ let t10;
2582
+ if ($[15] !== t1 || $[16] !== t2) {
2583
+ t10 = /* @__PURE__ */ jsx("span", { className: t1, children: t2 });
2584
+ $[15] = t1;
2585
+ $[16] = t2;
2586
+ $[17] = t10;
2587
+ } else {
2588
+ t10 = $[17];
2589
+ }
2590
+ let t11;
2591
+ if ($[18] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2592
+ t11 = /* @__PURE__ */ jsx(KeyboardArrowDownIcon, { size: "small" });
2593
+ $[18] = t11;
2594
+ } else {
2595
+ t11 = $[18];
2596
+ }
2597
+ let t12;
2598
+ if ($[19] !== T0 || $[20] !== t10 || $[21] !== t3 || $[22] !== t4 || $[23] !== t5) {
2599
+ t12 = /* @__PURE__ */ jsxs(T0, { variant: t3, className: t4, color: t5, children: [
2600
+ t10,
2601
+ t11
2602
+ ] });
2603
+ $[19] = T0;
2604
+ $[20] = t10;
2605
+ $[21] = t3;
2606
+ $[22] = t4;
2607
+ $[23] = t5;
2608
+ $[24] = t12;
2609
+ } else {
2610
+ t12 = $[24];
2611
+ }
2612
+ let t13;
2613
+ if ($[25] !== activeItem || $[26] !== onOpenChange || $[27] !== t || $[28] !== view) {
2614
+ t13 = items.map((item_0, index) => /* @__PURE__ */ jsxs(EditorBubbleItem, { onSelect: () => {
2615
+ item_0.command(view.state, view.dispatch);
2616
+ view.focus();
2617
+ onOpenChange(false);
2618
+ }, className: "flex cursor-pointer items-center justify-between rounded px-2 py-1 text-sm hover:bg-blue-50 hover:dark:bg-surface-700 text-surface-900 dark:text-white", children: [
2619
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
2620
+ /* @__PURE__ */ jsx(item_0.icon, { size: "smallest" }),
2621
+ /* @__PURE__ */ jsx("span", { children: t(item_0.labelKey) })
2622
+ ] }),
2623
+ activeItem.name === item_0.name && /* @__PURE__ */ jsx(CheckIcon, { size: "smallest" })
2624
+ ] }, index));
2625
+ $[25] = activeItem;
2626
+ $[26] = onOpenChange;
2627
+ $[27] = t;
2628
+ $[28] = view;
2629
+ $[29] = t13;
2630
+ } else {
2631
+ t13 = $[29];
2632
+ }
2633
+ let t14;
2634
+ if ($[30] !== T1 || $[31] !== onOpenChange || $[32] !== open || $[33] !== t12 || $[34] !== t13 || $[35] !== t6 || $[36] !== t7 || $[37] !== t8 || $[38] !== t9) {
2635
+ t14 = /* @__PURE__ */ jsx(T1, { sideOffset: t6, align: t7, portalContainer: t8, className: t9, trigger: t12, modal: true, open, onOpenChange, children: t13 });
2636
+ $[30] = T1;
2637
+ $[31] = onOpenChange;
2638
+ $[32] = open;
2639
+ $[33] = t12;
2640
+ $[34] = t13;
2641
+ $[35] = t6;
2642
+ $[36] = t7;
2643
+ $[37] = t8;
2644
+ $[38] = t9;
2645
+ $[39] = t14;
2646
+ } else {
2647
+ t14 = $[39];
2648
+ }
2649
+ return t14;
2650
+ };
2651
+ function isValidUrl(url) {
2652
+ try {
2653
+ new URL(url);
2654
+ return true;
2655
+ } catch (e) {
2656
+ return false;
2657
+ }
2658
+ }
2659
+ function getUrlFromString(str) {
2660
+ if (isValidUrl(str)) return str;
2661
+ try {
2662
+ if (str.includes(".") && !str.includes(" ")) {
2663
+ return new URL(`https://${str}`).toString();
2664
+ }
2665
+ return null;
2666
+ } catch (e) {
2667
+ return null;
2668
+ }
2669
+ }
2670
+ const LinkSelector = (t0) => {
2671
+ const $ = c(58);
2672
+ const {
2673
+ open,
2674
+ onOpenChange
2675
+ } = t0;
2676
+ const inputRef = useRef(null);
2677
+ const {
2678
+ state,
2679
+ view
2680
+ } = useProseMirrorContext();
2681
+ const {
2682
+ t
2683
+ } = useTranslation();
2684
+ let t1;
2685
+ let t2;
2686
+ if ($[0] !== open) {
2687
+ t1 = () => {
2688
+ if (open && inputRef.current) {
2689
+ inputRef.current.focus();
2690
+ }
2691
+ };
2692
+ t2 = [open];
2693
+ $[0] = open;
2694
+ $[1] = t1;
2695
+ $[2] = t2;
2696
+ } else {
2697
+ t1 = $[1];
2698
+ t2 = $[2];
2699
+ }
2700
+ useEffect(t1, t2);
2701
+ if (!state || !view) {
2702
+ return null;
2703
+ }
2704
+ let t3;
2705
+ if ($[3] !== onOpenChange || $[4] !== view) {
2706
+ t3 = (e) => {
2707
+ e.preventDefault();
2708
+ const value = inputRef.current?.value;
2709
+ if (!value) {
2710
+ return;
2711
+ }
2712
+ const url = getUrlFromString(value);
2713
+ if (url) {
2714
+ setMark(schema.marks.link, {
2715
+ href: url
2716
+ })(view.state, view.dispatch);
2717
+ view.focus();
2718
+ onOpenChange(false);
2719
+ }
2720
+ };
2721
+ $[3] = onOpenChange;
2722
+ $[4] = view;
2723
+ $[5] = t3;
2724
+ } else {
2725
+ t3 = $[5];
2726
+ }
2727
+ const handleSubmit = t3;
2728
+ let t4;
2729
+ if ($[6] !== onOpenChange || $[7] !== view) {
2730
+ t4 = () => {
2731
+ unsetMark(schema.marks.link)(view.state, view.dispatch);
2732
+ view.focus();
2733
+ onOpenChange(false);
2734
+ };
2735
+ $[6] = onOpenChange;
2736
+ $[7] = view;
2737
+ $[8] = t4;
2738
+ } else {
2739
+ t4 = $[8];
2740
+ }
2741
+ const handleRemoveLink = t4;
2742
+ let T0;
2743
+ let T1;
2744
+ let href;
2745
+ let t10;
2746
+ let t11;
2747
+ let t12;
2748
+ let t5;
2749
+ let t6;
2750
+ let t7;
2751
+ let t8;
2752
+ let t9;
2753
+ if ($[9] !== onOpenChange || $[10] !== open || $[11] !== state) {
2754
+ const isActive = isMarkActive(state, schema.marks.link);
2755
+ let t132;
2756
+ if ($[23] !== state) {
2757
+ t132 = getMarkAttributes(state, schema.marks.link).href || "";
2758
+ $[23] = state;
2759
+ $[24] = t132;
2760
+ } else {
2761
+ t132 = $[24];
2762
+ }
2763
+ href = t132;
2764
+ T1 = Popover;
2765
+ t10 = true;
2766
+ t11 = open;
2767
+ t12 = onOpenChange;
2768
+ T0 = Button;
2769
+ t6 = "text";
2770
+ t7 = "button";
2771
+ t8 = "gap-2 rounded-none";
2772
+ t9 = "text";
2773
+ t5 = cls("underline decoration-stone-400 underline-offset-4", {
2774
+ "text-blue-500": isActive
2775
+ });
2776
+ $[9] = onOpenChange;
2777
+ $[10] = open;
2778
+ $[11] = state;
2779
+ $[12] = T0;
2780
+ $[13] = T1;
2781
+ $[14] = href;
2782
+ $[15] = t10;
2783
+ $[16] = t11;
2784
+ $[17] = t12;
2785
+ $[18] = t5;
2786
+ $[19] = t6;
2787
+ $[20] = t7;
2788
+ $[21] = t8;
2789
+ $[22] = t9;
2790
+ } else {
2791
+ T0 = $[12];
2792
+ T1 = $[13];
2793
+ href = $[14];
2794
+ t10 = $[15];
2795
+ t11 = $[16];
2796
+ t12 = $[17];
2797
+ t5 = $[18];
2798
+ t6 = $[19];
2799
+ t7 = $[20];
2800
+ t8 = $[21];
2801
+ t9 = $[22];
2802
+ }
2803
+ let t13;
2804
+ if ($[25] !== t) {
2805
+ t13 = t("editor_link");
2806
+ $[25] = t;
2807
+ $[26] = t13;
2808
+ } else {
2809
+ t13 = $[26];
2810
+ }
2811
+ let t14;
2812
+ if ($[27] !== t13 || $[28] !== t5) {
2813
+ t14 = /* @__PURE__ */ jsx("p", { className: t5, children: t13 });
2814
+ $[27] = t13;
2815
+ $[28] = t5;
2816
+ $[29] = t14;
2817
+ } else {
2818
+ t14 = $[29];
2819
+ }
2820
+ let t15;
2821
+ if ($[30] !== T0 || $[31] !== t14 || $[32] !== t6 || $[33] !== t7 || $[34] !== t8 || $[35] !== t9) {
2822
+ t15 = /* @__PURE__ */ jsx(T0, { variant: t6, type: t7, className: t8, color: t9, children: t14 });
2823
+ $[30] = T0;
2824
+ $[31] = t14;
2825
+ $[32] = t6;
2826
+ $[33] = t7;
2827
+ $[34] = t8;
2828
+ $[35] = t9;
2829
+ $[36] = t15;
2830
+ } else {
2831
+ t15 = $[36];
2832
+ }
2833
+ let t16;
2834
+ if ($[37] !== t) {
2835
+ t16 = t("editor_paste_or_type_link");
2836
+ $[37] = t;
2837
+ $[38] = t16;
2838
+ } else {
2839
+ t16 = $[38];
2840
+ }
2841
+ let t17;
2842
+ if ($[39] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
2843
+ t17 = cls("text-surface-900 dark:text-white flex-grow bg-transparent p-1 text-sm outline-none", focusedDisabled);
2844
+ $[39] = t17;
2845
+ } else {
2846
+ t17 = $[39];
2847
+ }
2848
+ let t18;
2849
+ if ($[40] !== href || $[41] !== open || $[42] !== t16) {
2850
+ t18 = /* @__PURE__ */ jsx("input", { ref: inputRef, autoFocus: open, placeholder: t16, defaultValue: href, className: t17 });
2851
+ $[40] = href;
2852
+ $[41] = open;
2853
+ $[42] = t16;
2854
+ $[43] = t18;
2855
+ } else {
2856
+ t18 = $[43];
2857
+ }
2858
+ let t19;
2859
+ if ($[44] !== handleRemoveLink || $[45] !== href) {
2860
+ t19 = href ? /* @__PURE__ */ jsx(Button, { size: "small", variant: "text", type: "button", color: "text", className: "flex items-center", onClick: handleRemoveLink, children: /* @__PURE__ */ jsx(DeleteIcon, { size: "small" }) }) : /* @__PURE__ */ jsx(Button, { size: "small", type: "submit", variant: "text", children: /* @__PURE__ */ jsx(CheckIcon, { size: "small" }) });
2861
+ $[44] = handleRemoveLink;
2862
+ $[45] = href;
2863
+ $[46] = t19;
2864
+ } else {
2865
+ t19 = $[46];
2866
+ }
2867
+ let t20;
2868
+ if ($[47] !== handleSubmit || $[48] !== t18 || $[49] !== t19) {
2869
+ t20 = /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "flex p-1 gap-1", children: [
2870
+ t18,
2871
+ t19
2872
+ ] });
2873
+ $[47] = handleSubmit;
2874
+ $[48] = t18;
2875
+ $[49] = t19;
2876
+ $[50] = t20;
2877
+ } else {
2878
+ t20 = $[50];
2879
+ }
2880
+ let t21;
2881
+ if ($[51] !== T1 || $[52] !== t10 || $[53] !== t11 || $[54] !== t12 || $[55] !== t15 || $[56] !== t20) {
2882
+ t21 = /* @__PURE__ */ jsx(T1, { modal: t10, open: t11, onOpenChange: t12, trigger: t15, children: t20 });
2883
+ $[51] = T1;
2884
+ $[52] = t10;
2885
+ $[53] = t11;
2886
+ $[54] = t12;
2887
+ $[55] = t15;
2888
+ $[56] = t20;
2889
+ $[57] = t21;
2890
+ } else {
2891
+ t21 = $[57];
2892
+ }
2893
+ return t21;
2894
+ };
2895
+ const TextButtons = () => {
2896
+ const $ = c(3);
2897
+ const {
2898
+ state,
2899
+ view
2900
+ } = useProseMirrorContext();
2901
+ if (!state || !view) {
2902
+ return null;
2903
+ }
2904
+ let t0;
2905
+ if ($[0] !== state || $[1] !== view) {
2906
+ const items2 = [{
2907
+ name: "bold",
2908
+ labelKey: "editor_bold",
2909
+ isActive: _temp$1,
2910
+ command: _temp2,
2911
+ icon: FormatBoldIcon
2912
+ }, {
2913
+ name: "italic",
2914
+ labelKey: "editor_italic",
2915
+ isActive: _temp3,
2916
+ command: _temp4,
2917
+ icon: FormatItalicIcon
2918
+ }, {
2919
+ name: "underline",
2920
+ labelKey: "editor_underline",
2921
+ isActive: _temp5,
2922
+ command: _temp6,
2923
+ icon: FormatUnderlinedIcon
2924
+ }, {
2925
+ name: "strike",
2926
+ labelKey: "editor_strikethrough",
2927
+ isActive: _temp7,
2928
+ command: _temp8,
2929
+ icon: FormatStrikethroughIcon
2930
+ }, {
2931
+ name: "code",
2932
+ labelKey: "editor_code",
2933
+ isActive: _temp9,
2934
+ command: _temp0,
2935
+ icon: CodeIcon
2936
+ }];
2937
+ t0 = /* @__PURE__ */ jsx("div", { className: "flex", children: items2.map((item, index) => /* @__PURE__ */ jsx(EditorBubbleItem, { onSelect: () => {
2938
+ item.command(view.state, view.dispatch);
2939
+ view.focus();
2940
+ }, children: /* @__PURE__ */ jsx(Button, { size: "small", color: "text", className: "gap-2 rounded-none h-full", variant: "text", children: /* @__PURE__ */ jsx(item.icon, { className: cls({
2941
+ "text-inherit": !item.isActive(state),
2942
+ "text-blue-500": item.isActive(state)
2943
+ }) }) }) }, index)) });
2944
+ $[0] = state;
2945
+ $[1] = view;
2946
+ $[2] = t0;
2947
+ } else {
2948
+ t0 = $[2];
2949
+ }
2950
+ return t0;
2951
+ };
2952
+ function _temp$1(s) {
2953
+ return isMarkActive(s, schema.marks.bold);
2954
+ }
2955
+ function _temp2(s_0, dispatch) {
2956
+ return toggleMark(schema.marks.bold)(s_0, dispatch);
2957
+ }
2958
+ function _temp3(s_1) {
2959
+ return isMarkActive(s_1, schema.marks.italic);
2960
+ }
2961
+ function _temp4(s_2, dispatch_0) {
2962
+ return toggleMark(schema.marks.italic)(s_2, dispatch_0);
2963
+ }
2964
+ function _temp5(s_3) {
2965
+ return isMarkActive(s_3, schema.marks.underline);
2966
+ }
2967
+ function _temp6(s_4, dispatch_1) {
2968
+ return toggleMark(schema.marks.underline)(s_4, dispatch_1);
2969
+ }
2970
+ function _temp7(s_5) {
2971
+ return isMarkActive(s_5, schema.marks.strike);
2972
+ }
2973
+ function _temp8(s_6, dispatch_2) {
2974
+ return toggleMark(schema.marks.strike)(s_6, dispatch_2);
2975
+ }
2976
+ function _temp9(s_7) {
2977
+ return isMarkActive(s_7, schema.marks.code);
2978
+ }
2979
+ function _temp0(s_8, dispatch_3) {
2980
+ return toggleMark(schema.marks.code)(s_8, dispatch_3);
2981
+ }
2982
+ function removeClassesFromJson(jsonObj) {
2983
+ if (Array.isArray(jsonObj)) {
2984
+ return jsonObj.map((item) => removeClassesFromJson(item));
2985
+ } else if (typeof jsonObj === "object" && jsonObj !== null) {
2986
+ if (jsonObj.attrs && typeof jsonObj.attrs === "object" && "class" in jsonObj.attrs) {
2987
+ delete jsonObj.attrs.class;
2988
+ }
2989
+ Object.keys(jsonObj).forEach((key) => {
2990
+ jsonObj[key] = removeClassesFromJson(jsonObj[key]);
2991
+ });
2992
+ }
2993
+ return jsonObj;
2994
+ }
2995
+ function serializeForClipboard(view, slice) {
2996
+ view.someProp("transformCopied", (f) => {
2997
+ slice = f(slice, view);
2998
+ });
2999
+ const context = [];
3000
+ let {
3001
+ content,
3002
+ openStart,
3003
+ openEnd
3004
+ } = slice;
3005
+ while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild.childCount == 1) {
3006
+ openStart--;
3007
+ openEnd--;
3008
+ const node = content.firstChild;
3009
+ context.push(node.type.name, node.attrs != node.type.defaultAttrs ? node.attrs : null);
3010
+ content = node.content;
3011
+ }
3012
+ const serializer2 = view.someProp("clipboardSerializer") || DOMSerializer.fromSchema(view.state.schema);
3013
+ const doc = detachedDoc(), wrap = doc.createElement("div");
3014
+ wrap.appendChild(serializer2.serializeFragment(content, {
3015
+ document: doc
3016
+ }));
3017
+ let firstChild = wrap.firstChild, needsWrap, wrappers = 0;
3018
+ while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) {
3019
+ for (let i = needsWrap.length - 1; i >= 0; i--) {
3020
+ const wrapper = doc.createElement(needsWrap[i]);
3021
+ while (wrap.firstChild) wrapper.appendChild(wrap.firstChild);
3022
+ wrap.appendChild(wrapper);
3023
+ wrappers++;
3024
+ }
3025
+ firstChild = wrap.firstChild;
3026
+ }
3027
+ if (firstChild && firstChild.nodeType == 1) firstChild.setAttribute("data-pm-slice", `${openStart} ${openEnd}${wrappers ? ` -${wrappers}` : ""} ${JSON.stringify(context)}`);
3028
+ const text = view.someProp("clipboardTextSerializer", (f) => f(slice, view)) || slice.content.textBetween(0, slice.content.size, "\n\n");
3029
+ return {
3030
+ dom: wrap,
3031
+ text,
3032
+ slice
3033
+ };
3034
+ }
3035
+ const wrapMap = {
3036
+ thead: ["table"],
3037
+ tbody: ["table"],
3038
+ tfoot: ["table"],
3039
+ caption: ["table"],
3040
+ colgroup: ["table"],
3041
+ col: ["table", "colgroup"],
3042
+ tr: ["table", "tbody"],
3043
+ td: ["table", "tbody", "tr"],
3044
+ th: ["table", "tbody", "tr"]
3045
+ };
3046
+ let _detachedDoc = null;
3047
+ function detachedDoc() {
3048
+ return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title"));
3049
+ }
3050
+ function absoluteRect(element) {
3051
+ const data = element.getBoundingClientRect();
3052
+ let ancestor = element.parentElement;
3053
+ while (ancestor && window.getComputedStyle(ancestor).position === "static") {
3054
+ ancestor = ancestor.parentElement;
3055
+ }
3056
+ const ancestorRect = ancestor?.getBoundingClientRect();
3057
+ return {
3058
+ top: data.top - (ancestorRect?.top ?? 0),
3059
+ left: data.left - (ancestorRect?.left ?? 0),
3060
+ width: data.width
3061
+ };
3062
+ }
3063
+ function nodeDOMAtCoords(coords, view) {
3064
+ const editorRect = view.dom.getBoundingClientRect();
3065
+ if (coords.y < editorRect.top || coords.y > editorRect.bottom) return void 0;
3066
+ if (coords.x < editorRect.left - 100 || coords.x > editorRect.right + 50) return void 0;
3067
+ let elem = document.elementFromPoint(coords.x, coords.y);
3068
+ let block = elem?.closest('li, p:not(:first-child), pre, blockquote, h1, h2, h3, h4, h5, h6, img, [data-type="taskList"]');
3069
+ if (block && view.dom.contains(block)) {
3070
+ return block.closest("li") || block;
3071
+ }
3072
+ const probeX = editorRect.left + Math.min(60, editorRect.width / 4);
3073
+ if (coords.x > probeX) return void 0;
3074
+ let probeElem = document.elementFromPoint(probeX, coords.y);
3075
+ let probeBlock = probeElem?.closest('li, p:not(:first-child), pre, blockquote, h1, h2, h3, h4, h5, h6, img, [data-type="taskList"]');
3076
+ if (probeBlock) {
3077
+ if (view.dom.contains(probeBlock)) {
3078
+ return probeBlock.closest("li") || probeBlock;
3079
+ }
3080
+ }
3081
+ return void 0;
3082
+ }
3083
+ function nodePosAtDOM(node, view, options) {
3084
+ try {
3085
+ if (!view.dom.contains(node)) return null;
3086
+ const pos = view.posAtDOM(node, 0);
3087
+ const $pos = view.state.doc.resolve(pos);
3088
+ if ($pos.depth > 0) {
3089
+ return $pos.before();
3090
+ }
3091
+ return pos;
3092
+ } catch (e) {
3093
+ return null;
3094
+ }
3095
+ }
3096
+ function dragHandlePlugin(options = {
3097
+ dragHandleWidth: 24
3098
+ }) {
3099
+ function handleDragStart(event, view) {
3100
+ view.focus();
3101
+ if (!event.dataTransfer) return;
3102
+ const node = nodeDOMAtCoords({
3103
+ x: event.clientX,
3104
+ y: event.clientY
3105
+ }, view);
3106
+ if (!(node instanceof Element)) return;
3107
+ const nodePos = nodePosAtDOM(node, view);
3108
+ if (nodePos == null || nodePos < 0) return;
3109
+ const draggedNodeSelection = NodeSelection.create(view.state.doc, nodePos);
3110
+ view.dispatch(view.state.tr.setSelection(draggedNodeSelection));
3111
+ const slice = view.state.selection.content();
3112
+ const {
3113
+ dom,
3114
+ text
3115
+ } = serializeForClipboard(view, slice);
3116
+ event.dataTransfer.clearData();
3117
+ event.dataTransfer.setData("text/html", dom.innerHTML);
3118
+ event.dataTransfer.setData("text/plain", text);
3119
+ event.dataTransfer.effectAllowed = "copyMove";
3120
+ event.dataTransfer.setDragImage(node, 0, 0);
3121
+ view.dragging = {
3122
+ slice,
3123
+ move: true,
3124
+ node: draggedNodeSelection
3125
+ };
3126
+ }
3127
+ function handleClick(event, view) {
3128
+ view.focus();
3129
+ view.dom.classList.remove("dragging");
3130
+ const node = nodeDOMAtCoords({
3131
+ x: event.clientX,
3132
+ y: event.clientY
3133
+ }, view);
3134
+ if (!(node instanceof Element)) return;
3135
+ const nodePos = nodePosAtDOM(node, view);
3136
+ if (!nodePos) return;
3137
+ view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, nodePos)));
3138
+ }
3139
+ let dragHandleElement = null;
3140
+ function hideDragHandle() {
3141
+ if (dragHandleElement) {
3142
+ dragHandleElement.classList.add("hide");
3143
+ }
3144
+ }
3145
+ function showDragHandle() {
3146
+ if (dragHandleElement) {
3147
+ dragHandleElement.classList.remove("hide");
3148
+ }
3149
+ }
3150
+ return new Plugin({
3151
+ view: (view) => {
3152
+ dragHandleElement = document.createElement("div");
3153
+ dragHandleElement.draggable = true;
3154
+ dragHandleElement.dataset.dragHandle = "";
3155
+ dragHandleElement.classList.add("drag-handle");
3156
+ dragHandleElement.addEventListener("dragstart", (e) => {
3157
+ handleDragStart(e, view);
3158
+ });
3159
+ dragHandleElement.addEventListener("click", (e) => {
3160
+ handleClick(e, view);
3161
+ });
3162
+ const onMouseMove = (event) => {
3163
+ if (!view.editable) {
3164
+ return;
3165
+ }
3166
+ const node = nodeDOMAtCoords({
3167
+ x: event.clientX,
3168
+ y: event.clientY
3169
+ }, view);
3170
+ if (!(node instanceof Element)) {
3171
+ hideDragHandle();
3172
+ return;
3173
+ }
3174
+ const compStyle = window.getComputedStyle(node);
3175
+ const lineHeight = parseInt(compStyle.lineHeight, 10);
3176
+ const paddingTop = parseInt(compStyle.paddingTop, 10);
3177
+ const rect = absoluteRect(node);
3178
+ if (!rect) {
3179
+ hideDragHandle();
3180
+ return;
3181
+ }
3182
+ rect.top += (lineHeight - 24) / 2;
3183
+ rect.top += paddingTop;
3184
+ if (node.matches("ul:not([data-type=taskList]) li, ol li")) {
3185
+ rect.left -= options.dragHandleWidth;
3186
+ }
3187
+ rect.width = options.dragHandleWidth;
3188
+ if (!dragHandleElement) return;
3189
+ dragHandleElement.style.left = `${rect.left - rect.width}px`;
3190
+ dragHandleElement.style.top = `${rect.top}px`;
3191
+ showDragHandle();
3192
+ };
3193
+ window.addEventListener("mousemove", onMouseMove);
3194
+ hideDragHandle();
3195
+ view?.dom?.parentElement?.appendChild(dragHandleElement);
3196
+ return {
3197
+ destroy: () => {
3198
+ window.removeEventListener("mousemove", onMouseMove);
3199
+ dragHandleElement?.remove?.();
3200
+ dragHandleElement = null;
3201
+ }
3202
+ };
3203
+ },
3204
+ props: {
3205
+ handleDOMEvents: {
3206
+ keydown: () => {
3207
+ hideDragHandle();
3208
+ },
3209
+ mousewheel: () => {
3210
+ hideDragHandle();
3211
+ },
3212
+ // dragging class is used for CSS
3213
+ dragstart: (view) => {
3214
+ view.dom.classList.add("dragging");
3215
+ },
3216
+ drop: (view) => {
3217
+ view.dom.classList.remove("dragging");
3218
+ },
3219
+ dragend: (view) => {
3220
+ view.dom.classList.remove("dragging");
3221
+ }
3222
+ }
3223
+ }
3224
+ });
3225
+ }
3226
+ function globalDragDropPlugin() {
3227
+ let dropCursorElement = null;
3228
+ let cleanup = null;
3229
+ function updateDropCursorColor(el) {
3230
+ const isDark = document.documentElement.getAttribute("data-theme") === "dark";
3231
+ const varName = isDark ? "--color-surface-accent-300" : "--color-surface-accent-600";
3232
+ const color = getComputedStyle(document.documentElement).getPropertyValue(varName).trim();
3233
+ el.style.backgroundColor = color || (isDark ? "#cbd5e1" : "#475569");
3234
+ }
3235
+ return new Plugin({
3236
+ view(editorView) {
3237
+ dropCursorElement = document.createElement("div");
3238
+ dropCursorElement.className = "prosemirror-dropcursor-block";
3239
+ dropCursorElement.style.cssText = "position: absolute; z-index: 50; pointer-events: none; height: 2px;";
3240
+ updateDropCursorColor(dropCursorElement);
3241
+ const observer = new MutationObserver(() => {
3242
+ if (dropCursorElement) updateDropCursorColor(dropCursorElement);
3243
+ });
3244
+ observer.observe(document.documentElement, {
3245
+ attributes: true,
3246
+ attributeFilter: ["data-theme"]
3247
+ });
3248
+ const removeCursor = () => {
3249
+ if (dropCursorElement && dropCursorElement.parentNode) {
3250
+ dropCursorElement.parentNode.removeChild(dropCursorElement);
3251
+ }
3252
+ };
3253
+ const getBlockInsertionPoint = (event, clampedX) => {
3254
+ const pos = editorView.posAtCoords({
3255
+ left: clampedX,
3256
+ top: event.clientY
3257
+ });
3258
+ if (!pos) return null;
3259
+ let $pos = editorView.state.doc.resolve(pos.pos);
3260
+ let blockDepth = 0;
3261
+ for (let i = $pos.depth; i > 0; i--) {
3262
+ const name = $pos.node(i).type.name;
3263
+ if (name === "list_item" || name === "taskItem") {
3264
+ blockDepth = i;
3265
+ break;
3266
+ }
3267
+ if ($pos.node(i).isBlock && name !== "bullet_list" && name !== "ordered_list" && name !== "taskList") {
3268
+ blockDepth = i;
3269
+ }
3270
+ }
3271
+ if (blockDepth === 0) return pos.pos;
3272
+ const nodeBeforePos = $pos.before(blockDepth);
3273
+ const nodeAfterPos = $pos.after(blockDepth);
3274
+ const domNode = editorView.nodeDOM(nodeBeforePos);
3275
+ if (domNode instanceof HTMLElement) {
3276
+ const rect = domNode.getBoundingClientRect();
3277
+ const isTopHalf = event.clientY < rect.top + rect.height / 2;
3278
+ return isTopHalf ? nodeBeforePos : nodeAfterPos;
3279
+ }
3280
+ return pos.pos;
3281
+ };
3282
+ const handleDragOver = (event) => {
3283
+ if (!editorView.editable || !editorView.dragging) return;
3284
+ if (!editorView.dragging.node) {
3285
+ removeCursor();
3286
+ return;
3287
+ }
3288
+ event.preventDefault();
3289
+ const editorRect = editorView.dom.getBoundingClientRect();
3290
+ const clampedX = Math.max(editorRect.left + 10, Math.min(event.clientX, editorRect.right - 10));
3291
+ let target = getBlockInsertionPoint(event, clampedX);
3292
+ if (target === null) {
3293
+ removeCursor();
3294
+ return;
3295
+ }
3296
+ const $pos = editorView.state.doc.resolve(target);
3297
+ let rect;
3298
+ const before = $pos.nodeBefore;
3299
+ const after = $pos.nodeAfter;
3300
+ if (before || after) {
3301
+ const nodeDOM = editorView.nodeDOM(target - (before ? before.nodeSize : 0));
3302
+ if (nodeDOM && nodeDOM instanceof HTMLElement) {
3303
+ const nodeRect = nodeDOM.getBoundingClientRect();
3304
+ let top = before ? nodeRect.bottom : nodeRect.top;
3305
+ if (before && after) {
3306
+ const afterDOM = editorView.nodeDOM(target);
3307
+ if (afterDOM && afterDOM instanceof HTMLElement) {
3308
+ top = (top + afterDOM.getBoundingClientRect().top) / 2;
3309
+ }
3310
+ }
3311
+ rect = {
3312
+ left: nodeRect.left,
3313
+ right: nodeRect.right,
3314
+ top: top - 1,
3315
+ bottom: top + 1
3316
+ };
3317
+ }
3318
+ }
3319
+ if (!rect) {
3320
+ const coords = editorView.coordsAtPos(target);
3321
+ rect = {
3322
+ left: editorRect.left + 50,
3323
+ right: editorRect.right - 50,
3324
+ top: coords.top - 1,
3325
+ bottom: coords.top + 1
3326
+ };
3327
+ }
3328
+ const parent = editorView.dom.offsetParent;
3329
+ let parentLeft = 0;
3330
+ let parentTop = 0;
3331
+ if (parent && parent !== document.body && getComputedStyle(parent).position !== "static") {
3332
+ const parentRect = parent.getBoundingClientRect();
3333
+ parentLeft = parentRect.left - parent.scrollLeft;
3334
+ parentTop = parentRect.top - parent.scrollTop;
3335
+ }
3336
+ if (!dropCursorElement.parentNode) {
3337
+ parent.appendChild(dropCursorElement);
3338
+ }
3339
+ dropCursorElement.style.left = `${rect.left - parentLeft}px`;
3340
+ dropCursorElement.style.top = `${rect.top - parentTop}px`;
3341
+ dropCursorElement.style.width = `${rect.right - rect.left}px`;
3342
+ };
3343
+ const handleDrop = (event) => {
3344
+ if (!editorView.editable || !editorView.dragging) return;
3345
+ if (!editorView.dragging.node) {
3346
+ removeCursor();
3347
+ return;
3348
+ }
3349
+ event.preventDefault();
3350
+ removeCursor();
3351
+ editorView.dom.classList.remove("dragging");
3352
+ const editorRect = editorView.dom.getBoundingClientRect();
3353
+ const clampedX = Math.max(editorRect.left + 10, Math.min(event.clientX, editorRect.right - 10));
3354
+ let targetPos = getBlockInsertionPoint(event, clampedX);
3355
+ if (targetPos === null) return;
3356
+ const dragging = editorView.dragging;
3357
+ if (dragging && dragging.slice) {
3358
+ let tr = editorView.state.tr;
3359
+ if (dragging.move) {
3360
+ const {
3361
+ node: node2
3362
+ } = dragging;
3363
+ if (node2) {
3364
+ node2.replace(tr);
3365
+ } else {
3366
+ tr = tr.deleteSelection();
3367
+ }
3368
+ }
3369
+ const mappedTarget = tr.mapping.map(targetPos);
3370
+ const beforeInsert = tr.doc;
3371
+ let {
3372
+ node,
3373
+ slice
3374
+ } = dragging;
3375
+ if (node && node.node) {
3376
+ let nodeToInsert = node.node;
3377
+ const $mapped = tr.doc.resolve(mappedTarget);
3378
+ const parentName = $mapped.parent.type.name;
3379
+ const isTargetList = parentName === "bullet_list" || parentName === "ordered_list";
3380
+ const isTargetTaskList = parentName === "taskList";
3381
+ if (nodeToInsert.type.name === "list_item" && !isTargetList) {
3382
+ nodeToInsert = nodeToInsert.content;
3383
+ } else if (nodeToInsert.type.name === "taskItem" && !isTargetTaskList) {
3384
+ nodeToInsert = nodeToInsert.content;
3385
+ }
3386
+ const isFragment = !nodeToInsert.type;
3387
+ const needsWrap = isFragment || nodeToInsert.type.name !== "list_item" && nodeToInsert.type.name !== "taskItem";
3388
+ if (needsWrap) {
3389
+ if (isTargetList) {
3390
+ const listItemType = editorView.state.schema.nodes.list_item;
3391
+ if (listItemType) nodeToInsert = listItemType.create(null, nodeToInsert);
3392
+ } else if (isTargetTaskList) {
3393
+ const taskItemType = editorView.state.schema.nodes.taskItem;
3394
+ if (taskItemType) nodeToInsert = taskItemType.create({
3395
+ checked: false
3396
+ }, nodeToInsert);
3397
+ }
3398
+ }
3399
+ try {
3400
+ tr = tr.insert(mappedTarget, nodeToInsert);
3401
+ } catch (e) {
3402
+ console.warn("Could not insert dragged node exactly at target. Attempting fallback.", e);
3403
+ const point = dropPoint(tr.doc, mappedTarget, slice);
3404
+ if (point !== null) {
3405
+ tr = tr.replace(point, point, slice);
3406
+ }
3407
+ }
3408
+ } else if (slice) {
3409
+ const point = dropPoint(tr.doc, mappedTarget, slice);
3410
+ const finalTarget = point !== null ? point : mappedTarget;
3411
+ tr = tr.replace(finalTarget, finalTarget, slice);
3412
+ }
3413
+ if (!tr.doc.eq(beforeInsert)) {
3414
+ editorView.dispatch(tr.setMeta("uiEvent", "drop"));
3415
+ editorView.focus();
3416
+ }
3417
+ }
3418
+ editorView.dragging = null;
3419
+ };
3420
+ const handleDragEnd = () => {
3421
+ removeCursor();
3422
+ };
3423
+ window.addEventListener("dragover", handleDragOver, {
3424
+ capture: true
3425
+ });
3426
+ window.addEventListener("drop", handleDrop, {
3427
+ capture: true
3428
+ });
3429
+ window.addEventListener("dragend", handleDragEnd, {
3430
+ capture: true
3431
+ });
3432
+ cleanup = () => {
3433
+ removeCursor();
3434
+ observer.disconnect();
3435
+ window.removeEventListener("dragover", handleDragOver, {
3436
+ capture: true
3437
+ });
3438
+ window.removeEventListener("drop", handleDrop, {
3439
+ capture: true
3440
+ });
3441
+ window.removeEventListener("dragend", handleDragEnd, {
3442
+ capture: true
3443
+ });
3444
+ };
3445
+ return {
3446
+ destroy() {
3447
+ if (cleanup) cleanup();
3448
+ }
3449
+ };
3450
+ }
3451
+ });
3452
+ }
3453
+ const highlightDecorationKey = new PluginKey("highlightDecoration");
3454
+ function buildDecorationSet(highlight, doc) {
3455
+ const decorations = [];
3456
+ if (highlight) {
3457
+ decorations.push(Decoration.inline(highlight.from, highlight.to, {
3458
+ class: "dark:bg-surface-accent-700 bg-surface-accent-300"
3459
+ }));
3460
+ }
3461
+ const decorationSet = DecorationSet.create(doc, decorations);
3462
+ return decorationSet;
3463
+ }
3464
+ const highlightCommands = {
3465
+ toggleAutocompleteHighlight: (range) => (state, dispatch) => {
3466
+ const {
3467
+ selection
3468
+ } = state;
3469
+ const pos = selection.from;
3470
+ if (!dispatch) return false;
3471
+ const tr = state.tr.setMeta(highlightDecorationKey, {
3472
+ pos,
3473
+ type: "highlightDecoration",
3474
+ remove: false,
3475
+ range
3476
+ });
3477
+ dispatch(tr);
3478
+ return true;
3479
+ },
3480
+ removeAutocompleteHighlight: () => (state, dispatch) => {
3481
+ if (!dispatch) return false;
3482
+ const tr = state.tr.setMeta(highlightDecorationKey, {
3483
+ pos: 0,
3484
+ type: "highlightDecoration",
3485
+ remove: true
3486
+ });
3487
+ dispatch(tr);
3488
+ return true;
3489
+ }
3490
+ };
3491
+ const highlightDecorationPlugin = (initialHighlight) => {
3492
+ return new Plugin({
3493
+ key: highlightDecorationKey,
3494
+ state: {
3495
+ init: (_, {
3496
+ doc
3497
+ }) => {
3498
+ const decorationSet = DecorationSet.empty;
3499
+ return {
3500
+ decorationSet,
3501
+ highlight: initialHighlight
3502
+ };
3503
+ },
3504
+ apply(transaction, oldState) {
3505
+ const action = transaction.getMeta(highlightDecorationKey);
3506
+ const highlight = action?.range;
3507
+ if (action?.type === "highlightDecoration") {
3508
+ const doc = transaction.doc;
3509
+ const {
3510
+ remove
3511
+ } = action;
3512
+ if (remove) {
3513
+ return {
3514
+ decorationSet: DecorationSet.empty
3515
+ };
3516
+ }
3517
+ const decorationSet = buildDecorationSet(highlight, doc);
3518
+ return {
3519
+ decorationSet,
3520
+ highlight
3521
+ };
3522
+ } else {
3523
+ return oldState;
3524
+ }
3525
+ }
3526
+ },
3527
+ props: {
3528
+ decorations(state) {
3529
+ const autocompleteState = this.getState(state);
3530
+ if (autocompleteState?.decorationSet) {
3531
+ return autocompleteState.decorationSet;
3532
+ } else {
3533
+ return DecorationSet.empty;
3534
+ }
3535
+ }
3536
+ }
3537
+ });
3538
+ };
3539
+ const blockQuoteRule = wrappingInputRule(/^\s*>\s$/, schema.nodes.blockquote);
3540
+ const orderedListRule = wrappingInputRule(/^(\d+)\.\s$/, schema.nodes.ordered_list, (match) => ({
3541
+ order: +match[1]
3542
+ }), (match, node) => node.childCount + node.attrs.order === +match[1]);
3543
+ const bulletListRule = wrappingInputRule(/^\s*([-+*])\s$/, schema.nodes.bullet_list);
3544
+ const taskListRule = wrappingInputRule(/^\s*(\[ \])\s$/, schema.nodes.task_list);
3545
+ const codeBlockRule = textblockTypeInputRule(/^```$/, schema.nodes.code_block);
3546
+ const headingRule = textblockTypeInputRule(new RegExp("^(#{1,6})\\s$"), schema.nodes.heading, (match) => ({
3547
+ level: match[1].length
3548
+ }));
3549
+ const horizontalRuleInputRule = new InputRule(/^(?:---|—-|___\s|\*\*\*\s)$/, (state, match, start, end) => {
3550
+ const tr = state.tr;
3551
+ tr.replaceWith(start - 1, end, schema.nodes.horizontal_rule.create());
3552
+ return tr;
3553
+ });
3554
+ function markInputRule(regexp, markType, getAttrs) {
3555
+ return new InputRule(regexp, (state, match, start, end) => {
3556
+ const attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs;
3557
+ const tr = state.tr;
3558
+ if (match[1]) {
3559
+ const textStart = start + match[0].indexOf(match[1]);
3560
+ const textEnd = textStart + match[1].length;
3561
+ if (textEnd < end) tr.delete(textEnd, end);
3562
+ if (textStart > start) tr.delete(start, textStart);
3563
+ end = start + match[1].length;
3564
+ }
3565
+ tr.addMark(start, end, markType.create(attrs));
3566
+ tr.removeStoredMark(markType);
3567
+ return tr;
3568
+ });
3569
+ }
3570
+ const strongRule = markInputRule(/(?:\*\*|__)([^*_]+)(?:\*\*|__)$/, schema.marks.bold);
3571
+ const emRule = markInputRule(/(?:^|[^*_])(?:\*|_)([^*_]+)(?:\*|_)$/, schema.marks.italic);
3572
+ const codeRule = markInputRule(/(?:`)([^`]+)(?:`)$/, schema.marks.code);
3573
+ const strikeRule = markInputRule(/(?:~~)([^~]+)(?:~~)$/, schema.marks.strike);
3574
+ const markdownInputRules = inputRules({
3575
+ rules: [...smartQuotes, ellipsis, emDash, blockQuoteRule, orderedListRule, bulletListRule, codeBlockRule, headingRule, taskListRule, horizontalRuleInputRule, strongRule, emRule, codeRule, strikeRule]
3576
+ });
3577
+ const placeholderPluginKey = new PluginKey("placeholderPlugin");
3578
+ function isNodeEmpty(node) {
3579
+ const defaultContent = node.type.createAndFill();
3580
+ if (!defaultContent) return true;
3581
+ return node.content.eq(defaultContent.content);
3582
+ }
3583
+ function placeholderPlugin(text) {
3584
+ return new Plugin({
3585
+ key: placeholderPluginKey,
3586
+ props: {
3587
+ decorations: (state) => {
3588
+ const doc = state.doc;
3589
+ const decorations = [];
3590
+ const isEmptyDoc = doc.childCount === 1 && doc.firstChild?.isTextblock && doc.firstChild.content.size === 0;
3591
+ const {
3592
+ anchor
3593
+ } = state.selection;
3594
+ doc.descendants((node, pos) => {
3595
+ const isEmpty = !node.isLeaf && isNodeEmpty(node);
3596
+ if (isEmpty) {
3597
+ const nodeEnd = pos + node.nodeSize;
3598
+ const hasCursor = anchor >= pos && anchor <= nodeEnd;
3599
+ if (!hasCursor && !isEmptyDoc) {
3600
+ return false;
3601
+ }
3602
+ const classes = ["is-empty"];
3603
+ if (isEmptyDoc) {
3604
+ classes.push("is-editor-empty");
3605
+ }
3606
+ decorations.push(Decoration.node(pos, pos + node.nodeSize, {
3607
+ class: classes.join(" "),
3608
+ "data-placeholder": text
3609
+ }));
3610
+ }
3611
+ return false;
3612
+ });
3613
+ return DecorationSet.create(doc, decorations);
3614
+ }
3615
+ }
3616
+ });
3617
+ }
3618
+ const customKeymap = {
3619
+ "Tab": goToNextCell(1),
3620
+ "Shift-Tab": goToNextCell(-1),
3621
+ "Mod-z": undo,
3622
+ "Mod-y": redo,
3623
+ "Shift-Mod-z": redo,
3624
+ "Mod-b": toggleMark(schema.marks.bold),
3625
+ "Mod-i": toggleMark(schema.marks.italic),
3626
+ "Mod-u": toggleMark(schema.marks.underline),
3627
+ "Mod-Shift-s": toggleMark(schema.marks.strike),
3628
+ "Mod-e": toggleMark(schema.marks.code),
3629
+ "Mod-Shift-h": toggleMark(schema.marks.highlight),
3630
+ "Enter": splitListItem(schema.nodes.list_item),
3631
+ "Shift-Enter": splitListItem(schema.nodes.task_item),
3632
+ "Mod-[": liftListItem(schema.nodes.list_item),
3633
+ "Mod-]": sinkListItem(schema.nodes.list_item),
3634
+ "Shift-Mod-8": setBlockType(schema.nodes.bullet_list),
3635
+ "Shift-Mod-9": setBlockType(schema.nodes.ordered_list),
3636
+ "Mod-Alt-1": setBlockType(schema.nodes.heading, {
3637
+ level: 1
3638
+ }),
3639
+ "Mod-Alt-2": setBlockType(schema.nodes.heading, {
3640
+ level: 2
3641
+ }),
3642
+ "Mod-Alt-3": setBlockType(schema.nodes.heading, {
3643
+ level: 3
3644
+ }),
3645
+ "Mod-Alt-0": setBlockType(schema.nodes.paragraph)
3646
+ };
3647
+ const corePlugins = [history(), keymap(customKeymap), keymap(baseKeymap), globalDragDropPlugin(), gapCursor(), slashCommandPlugin(), dragHandlePlugin(), highlightDecorationPlugin(), textLoadingDecorationPlugin(), markdownInputRules, placeholderPlugin("Press '/' for commands")];
3648
+ class ReactNodeView {
3649
+ node;
3650
+ view;
3651
+ getPos;
3652
+ dom;
3653
+ contentDOM;
3654
+ root;
3655
+ Component;
3656
+ constructor(node, view, getPos, Component, as = "div", className, contentDOMElement) {
3657
+ this.node = node;
3658
+ this.view = view;
3659
+ this.getPos = getPos;
3660
+ this.Component = Component;
3661
+ this.dom = document.createElement(as);
3662
+ if (className) this.dom.className = className;
3663
+ if (contentDOMElement) {
3664
+ this.contentDOM = contentDOMElement;
3665
+ }
3666
+ const container = document.createElement("div");
3667
+ this.dom.appendChild(container);
3668
+ if (this.contentDOM) {
3669
+ this.dom.appendChild(this.contentDOM);
3670
+ }
3671
+ this.root = createRoot(container);
3672
+ this.render();
3673
+ }
3674
+ render() {
3675
+ this.root.render(/* @__PURE__ */ jsx(this.Component, { node: this.node, view: this.view, getPos: this.getPos }));
3676
+ }
3677
+ update(node) {
3678
+ if (node.type !== this.node.type) {
3679
+ return false;
3680
+ }
3681
+ this.node = node;
3682
+ this.render();
3683
+ return true;
3684
+ }
3685
+ destroy() {
3686
+ this.root.unmount();
3687
+ }
3688
+ ignoreMutation(mutation) {
3689
+ if (!this.contentDOM) {
3690
+ return true;
3691
+ }
3692
+ return !this.contentDOM.contains(mutation.target);
3693
+ }
3694
+ }
3695
+ const TaskItemComponent = (t0) => {
3696
+ const $ = c(7);
3697
+ const {
3698
+ node,
3699
+ view,
3700
+ getPos
3701
+ } = t0;
3702
+ const checked = node.attrs.checked;
3703
+ let t1;
3704
+ if ($[0] !== getPos || $[1] !== node.attrs || $[2] !== view) {
3705
+ t1 = (e) => {
3706
+ const pos = getPos();
3707
+ if (typeof pos !== "number") {
3708
+ return;
3709
+ }
3710
+ view.dispatch(view.state.tr.setNodeMarkup(pos, void 0, {
3711
+ ...node.attrs,
3712
+ checked: e.target.checked
3713
+ }));
3714
+ };
3715
+ $[0] = getPos;
3716
+ $[1] = node.attrs;
3717
+ $[2] = view;
3718
+ $[3] = t1;
3719
+ } else {
3720
+ t1 = $[3];
3721
+ }
3722
+ const handleChange = t1;
3723
+ let t2;
3724
+ if ($[4] !== checked || $[5] !== handleChange) {
3725
+ t2 = /* @__PURE__ */ jsx("label", { contentEditable: false, className: "flex items-start select-none px-1", children: /* @__PURE__ */ jsx("input", { type: "checkbox", checked, onChange: handleChange, className: "mt-1 flex-shrink-0 cursor-pointer" }) });
3726
+ $[4] = checked;
3727
+ $[5] = handleChange;
3728
+ $[6] = t2;
3729
+ } else {
3730
+ t2 = $[6];
3731
+ }
3732
+ return t2;
3733
+ };
3734
+ const ImageComponent = (t0) => {
3735
+ const $ = c(7);
3736
+ const {
3737
+ node,
3738
+ view,
3739
+ getPos
3740
+ } = t0;
3741
+ const selected = view.state.selection.from === getPos();
3742
+ const t1 = node.attrs.src;
3743
+ const t2 = node.attrs.alt || "";
3744
+ const t3 = node.attrs.title || "";
3745
+ const t4 = selected ? "" : "";
3746
+ let t5;
3747
+ if ($[0] !== t4) {
3748
+ t5 = cls("rounded-lg max-w-full !m-0", t4);
3749
+ $[0] = t4;
3750
+ $[1] = t5;
3751
+ } else {
3752
+ t5 = $[1];
3753
+ }
3754
+ let t6;
3755
+ if ($[2] !== node.attrs.src || $[3] !== t2 || $[4] !== t3 || $[5] !== t5) {
3756
+ t6 = /* @__PURE__ */ jsx("img", { src: t1, alt: t2, title: t3, className: t5 });
3757
+ $[2] = node.attrs.src;
3758
+ $[3] = t2;
3759
+ $[4] = t3;
3760
+ $[5] = t5;
3761
+ $[6] = t6;
3762
+ } else {
3763
+ t6 = $[6];
3764
+ }
3765
+ return t6;
3766
+ };
3767
+ function createReactNodeView(Component, as = "div", className, createContentDOM) {
3768
+ return (node, view, getPos) => {
3769
+ const contentDOM = createContentDOM ? createContentDOM() : void 0;
3770
+ return new ReactNodeView(node, view, getPos, Component, as, className, contentDOM);
3771
+ };
3772
+ }
3773
+ const nodeViews = {
3774
+ task_item: createReactNodeView(TaskItemComponent, "li", "flex items-start", () => {
3775
+ const dom = document.createElement("div");
3776
+ dom.className = "flex-grow min-w-0";
3777
+ return dom;
3778
+ }),
3779
+ image: createReactNodeView(ImageComponent, "span", "inline-block w-full")
3780
+ };
3781
+ const trailingNodePlugin = new Plugin({
3782
+ appendTransaction: (_, oldState, newState) => {
3783
+ const doc = newState.doc;
3784
+ if (doc.lastChild && doc.lastChild.type.name !== "paragraph") {
3785
+ return newState.tr.insert(doc.content.size, newState.schema.nodes.paragraph.create());
3786
+ }
3787
+ return null;
3788
+ }
3789
+ });
3790
+ function useProseMirror(t0) {
3791
+ const $ = c(13);
3792
+ const {
3793
+ initialContent,
3794
+ editable: t1,
3795
+ handleImageUpload
3796
+ } = t0;
3797
+ const editable = t1 === void 0 ? true : t1;
3798
+ let t2;
3799
+ if ($[0] !== handleImageUpload || $[1] !== initialContent) {
3800
+ const plugins = [...corePlugins, columnResizing(), tableEditing(), trailingNodePlugin];
3801
+ if (handleImageUpload) {
3802
+ plugins.push(createDropImagePlugin(handleImageUpload));
3803
+ }
3804
+ t2 = EditorState.create({
3805
+ doc: typeof initialContent === "string" ? parser.parse(initialContent) : initialContent ? schema.nodeFromJSON(initialContent) : schema.node("doc", null, [schema.node("paragraph")]),
3806
+ schema,
3807
+ plugins
3808
+ });
3809
+ $[0] = handleImageUpload;
3810
+ $[1] = initialContent;
3811
+ $[2] = t2;
3812
+ } else {
3813
+ t2 = $[2];
3814
+ }
3815
+ const defaultState = t2;
3816
+ const [state, setState] = useState(defaultState);
3817
+ const [view, setView] = useState(null);
3818
+ const editorRef = useRef(null);
3819
+ const viewRef = useRef(null);
3820
+ let t3;
3821
+ if ($[3] !== defaultState || $[4] !== editable) {
3822
+ t3 = () => {
3823
+ if (!editorRef.current) {
3824
+ return;
3825
+ }
3826
+ const editorView = new EditorView(editorRef.current, {
3827
+ state: defaultState,
3828
+ editable: () => editable,
3829
+ dispatchTransaction: (tr) => {
3830
+ if (editorView.isDestroyed) {
3831
+ return;
3832
+ }
3833
+ const newState = editorView.state.apply(tr);
3834
+ editorView.updateState(newState);
3835
+ setState(newState);
3836
+ },
3837
+ nodeViews,
3838
+ transformPastedHTML(html) {
3839
+ const div = document.createElement("div");
3840
+ div.innerHTML = html;
3841
+ div.querySelectorAll("*").forEach(_temp);
3842
+ return div.innerHTML;
3843
+ }
3844
+ });
3845
+ const originalPosAtCoords = editorView.posAtCoords.bind(editorView);
3846
+ editorView.posAtCoords = (coords) => {
3847
+ const res = originalPosAtCoords(coords);
3848
+ if (!res) {
3849
+ const editorRect = editorView.dom.getBoundingClientRect();
3850
+ if (coords.left <= editorRect.left) {
3851
+ const probeX = editorRect.left + Math.min(60, editorRect.width / 4);
3852
+ return originalPosAtCoords({
3853
+ left: probeX,
3854
+ top: coords.top
3855
+ });
3856
+ }
3857
+ if (coords.left >= editorRect.right) {
3858
+ const probeX_0 = editorRect.right - Math.min(60, editorRect.width / 4);
3859
+ return originalPosAtCoords({
3860
+ left: probeX_0,
3861
+ top: coords.top
3862
+ });
3863
+ }
3864
+ }
3865
+ return res;
3866
+ };
3867
+ viewRef.current = editorView;
3868
+ setView(editorView);
3869
+ return () => {
3870
+ editorView.destroy();
3871
+ viewRef.current = null;
3872
+ };
3873
+ };
3874
+ $[3] = defaultState;
3875
+ $[4] = editable;
3876
+ $[5] = t3;
3877
+ } else {
3878
+ t3 = $[5];
3879
+ }
3880
+ let t4;
3881
+ if ($[6] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
3882
+ t4 = [];
3883
+ $[6] = t4;
3884
+ } else {
3885
+ t4 = $[6];
3886
+ }
3887
+ useLayoutEffect(t3, t4);
3888
+ let t5;
3889
+ let t6;
3890
+ if ($[7] !== editable) {
3891
+ t5 = () => {
3892
+ if (viewRef.current) {
3893
+ viewRef.current.setProps({
3894
+ editable: () => editable
3895
+ });
3896
+ }
3897
+ };
3898
+ t6 = [editable];
3899
+ $[7] = editable;
3900
+ $[8] = t5;
3901
+ $[9] = t6;
3902
+ } else {
3903
+ t5 = $[8];
3904
+ t6 = $[9];
3905
+ }
3906
+ useEffect(t5, t6);
3907
+ let t7;
3908
+ if ($[10] !== state || $[11] !== view) {
3909
+ t7 = {
3910
+ state,
3911
+ view,
3912
+ editorRef
3913
+ };
3914
+ $[10] = state;
3915
+ $[11] = view;
3916
+ $[12] = t7;
3917
+ } else {
3918
+ t7 = $[12];
3919
+ }
3920
+ return t7;
3921
+ }
3922
+ function _temp(el) {
3923
+ el.removeAttribute("style");
3924
+ el.removeAttribute("class");
3925
+ el.removeAttribute("color");
3926
+ el.removeAttribute("bgcolor");
3927
+ el.removeAttribute("face");
3928
+ }
3929
+ const proseClasses = {
3930
+ "sm": "prose-sm",
3931
+ "base": "prose-base",
3932
+ "lg": "prose-lg"
3933
+ };
3934
+ const FireCMSEditor = (t0) => {
3935
+ const $ = c(78);
3936
+ const {
3937
+ content,
3938
+ onJsonContentChange,
3939
+ onMarkdownContentChange,
3940
+ textSize: t1,
3941
+ highlight,
3942
+ handleImageUpload,
3943
+ aiController,
3944
+ disabled
3945
+ } = t0;
3946
+ const textSize = t1 === void 0 ? "base" : t1;
3947
+ useTranslation();
3948
+ const [openNode, setOpenNode] = useState(false);
3949
+ const [openLink, setOpenLink] = useState(false);
3950
+ const [isMarkdownMode, setIsMarkdownMode] = useState(false);
3951
+ const [internalMarkdown, setInternalMarkdown] = useState("");
3952
+ let t2;
3953
+ if ($[0] !== internalMarkdown || $[1] !== isMarkdownMode) {
3954
+ t2 = [internalMarkdown, isMarkdownMode];
3955
+ $[0] = internalMarkdown;
3956
+ $[1] = isMarkdownMode;
3957
+ $[2] = t2;
3958
+ } else {
3959
+ t2 = $[2];
3960
+ }
3961
+ useEffect(() => {
3962
+ if (!isMarkdownMode) {
3963
+ return;
3964
+ }
3965
+ const timeout = setTimeout(() => {
3966
+ if (callbacksRef.current.onMarkdownContentChange) {
3967
+ callbacksRef.current.onMarkdownContentChange(internalMarkdown);
3968
+ }
3969
+ }, 250);
3970
+ return () => clearTimeout(timeout);
3971
+ }, t2);
3972
+ const handleToggleMarkdown = () => {
3973
+ if (!isMarkdownMode) {
3974
+ if (view) {
3975
+ setInternalMarkdown(serializer.serialize(view.state.doc));
3976
+ }
3977
+ setIsMarkdownMode(true);
3978
+ } else {
3979
+ if (view) {
3980
+ const newDoc = parser.parse(internalMarkdown);
3981
+ if (newDoc) {
3982
+ const tr = view.state.tr.replaceWith(0, view.state.doc.content.size, newDoc.content);
3983
+ view.dispatch(tr);
3984
+ }
3985
+ }
3986
+ setIsMarkdownMode(false);
3987
+ }
3988
+ };
3989
+ let t3;
3990
+ if ($[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
3991
+ t3 = (e) => {
3992
+ setInternalMarkdown(e.target.value);
3993
+ };
3994
+ $[3] = t3;
3995
+ } else {
3996
+ t3 = $[3];
3997
+ }
3998
+ const handleMarkdownChange = t3;
3999
+ const handleMarkdownBlur = () => {
4000
+ const {
4001
+ onMarkdownContentChange: onMarkdownContentChange_0,
4002
+ onJsonContentChange: onJsonContentChange_0
4003
+ } = callbacksRef.current;
4004
+ if (onMarkdownContentChange_0) {
4005
+ onMarkdownContentChange_0(internalMarkdown);
4006
+ }
4007
+ if (onJsonContentChange_0) {
4008
+ try {
4009
+ const newDoc_0 = parser.parse(internalMarkdown);
4010
+ if (newDoc_0) {
4011
+ onJsonContentChange_0(removeClassesFromJson(newDoc_0.toJSON()));
4012
+ }
4013
+ } catch (t4) {
4014
+ const e_0 = t4;
4015
+ console.warn("Could not parse markdown to JSON", e_0);
4016
+ }
4017
+ }
4018
+ };
4019
+ useInjectStyles("Editor", cssStyles);
4020
+ let t5;
4021
+ if ($[4] !== onJsonContentChange || $[5] !== onMarkdownContentChange) {
4022
+ t5 = {
4023
+ onMarkdownContentChange,
4024
+ onJsonContentChange
4025
+ };
4026
+ $[4] = onJsonContentChange;
4027
+ $[5] = onMarkdownContentChange;
4028
+ $[6] = t5;
4029
+ } else {
4030
+ t5 = $[6];
4031
+ }
4032
+ const callbacksRef = useRef(t5);
4033
+ let t6;
4034
+ if ($[7] !== callbacksRef || $[8] !== onJsonContentChange || $[9] !== onMarkdownContentChange) {
4035
+ t6 = () => {
4036
+ callbacksRef.current = {
4037
+ onMarkdownContentChange,
4038
+ onJsonContentChange
4039
+ };
4040
+ };
4041
+ $[7] = callbacksRef;
4042
+ $[8] = onJsonContentChange;
4043
+ $[9] = onMarkdownContentChange;
4044
+ $[10] = t6;
4045
+ } else {
4046
+ t6 = $[10];
4047
+ }
4048
+ let t7;
4049
+ if ($[11] !== onJsonContentChange || $[12] !== onMarkdownContentChange) {
4050
+ t7 = [onMarkdownContentChange, onJsonContentChange];
4051
+ $[11] = onJsonContentChange;
4052
+ $[12] = onMarkdownContentChange;
4053
+ $[13] = t7;
4054
+ } else {
4055
+ t7 = $[13];
4056
+ }
4057
+ useEffect(t6, t7);
4058
+ let t8;
4059
+ if ($[14] !== callbacksRef) {
4060
+ t8 = (currentState) => {
4061
+ const {
4062
+ onMarkdownContentChange: onMarkdownContentChange_1,
4063
+ onJsonContentChange: onJsonContentChange_1
4064
+ } = callbacksRef.current;
4065
+ if (onMarkdownContentChange_1) {
4066
+ try {
4067
+ const markdown = serializer.serialize(currentState.doc);
4068
+ onMarkdownContentChange_1(markdown);
4069
+ } catch (t92) {
4070
+ const e_1 = t92;
4071
+ console.warn("[FireCMSEditor] Could not serialize editor state to markdown:", e_1);
4072
+ }
4073
+ }
4074
+ if (onJsonContentChange_1) {
4075
+ const jsonContent = removeClassesFromJson(currentState.doc.toJSON());
4076
+ onJsonContentChange_1(jsonContent);
4077
+ }
4078
+ };
4079
+ $[14] = callbacksRef;
4080
+ $[15] = t8;
4081
+ } else {
4082
+ t8 = $[15];
4083
+ }
4084
+ const flushChanges = t8;
4085
+ const t9 = !disabled;
4086
+ let t10;
4087
+ if ($[16] !== content || $[17] !== handleImageUpload || $[18] !== t9) {
4088
+ t10 = {
4089
+ initialContent: content,
4090
+ editable: t9,
4091
+ handleImageUpload
4092
+ };
4093
+ $[16] = content;
4094
+ $[17] = handleImageUpload;
4095
+ $[18] = t9;
4096
+ $[19] = t10;
4097
+ } else {
4098
+ t10 = $[19];
4099
+ }
4100
+ const {
4101
+ state,
4102
+ view: t11,
4103
+ editorRef
4104
+ } = useProseMirror(t10);
4105
+ const view = t11;
4106
+ const doc = state?.doc;
4107
+ const mountedRef = useRef(false);
4108
+ let t12;
4109
+ let t13;
4110
+ if ($[20] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
4111
+ t12 = () => {
4112
+ const raf = requestAnimationFrame(() => {
4113
+ mountedRef.current = true;
4114
+ });
4115
+ return () => cancelAnimationFrame(raf);
4116
+ };
4117
+ t13 = [];
4118
+ $[20] = t12;
4119
+ $[21] = t13;
4120
+ } else {
4121
+ t12 = $[20];
4122
+ t13 = $[21];
4123
+ }
4124
+ useEffect(t12, t13);
4125
+ let t14;
4126
+ if ($[22] !== flushChanges || $[23] !== state) {
4127
+ t14 = () => {
4128
+ if (!state) {
4129
+ return;
4130
+ }
4131
+ if (!mountedRef.current) {
4132
+ return;
4133
+ }
4134
+ const timeout_0 = setTimeout(() => {
4135
+ flushChanges(state);
4136
+ }, 250);
4137
+ return () => clearTimeout(timeout_0);
4138
+ };
4139
+ $[22] = flushChanges;
4140
+ $[23] = state;
4141
+ $[24] = t14;
4142
+ } else {
4143
+ t14 = $[24];
4144
+ }
4145
+ let t15;
4146
+ if ($[25] !== doc) {
4147
+ t15 = [doc];
4148
+ $[25] = doc;
4149
+ $[26] = t15;
4150
+ } else {
4151
+ t15 = $[26];
4152
+ }
4153
+ useEffect(t14, t15);
4154
+ let t16;
4155
+ if ($[27] !== flushChanges || $[28] !== view) {
4156
+ t16 = () => {
4157
+ if (!view) {
4158
+ return;
4159
+ }
4160
+ const dom = view.dom;
4161
+ const handleBlur = () => {
4162
+ if (!mountedRef.current) {
4163
+ return;
4164
+ }
4165
+ flushChanges(view.state);
4166
+ };
4167
+ dom.addEventListener("blur", handleBlur);
4168
+ return () => dom.removeEventListener("blur", handleBlur);
4169
+ };
4170
+ $[27] = flushChanges;
4171
+ $[28] = view;
4172
+ $[29] = t16;
4173
+ } else {
4174
+ t16 = $[29];
4175
+ }
4176
+ let t17;
4177
+ if ($[30] !== view) {
4178
+ t17 = [view];
4179
+ $[30] = view;
4180
+ $[31] = t17;
4181
+ } else {
4182
+ t17 = $[31];
4183
+ }
4184
+ useEffect(t16, t17);
4185
+ let t18;
4186
+ if ($[32] !== highlight || $[33] !== view) {
4187
+ t18 = () => {
4188
+ if (view) {
4189
+ if (highlight) {
4190
+ highlightCommands.toggleAutocompleteHighlight(highlight)(view.state, view.dispatch);
4191
+ } else {
4192
+ highlightCommands.removeAutocompleteHighlight()(view.state, view.dispatch);
4193
+ }
4194
+ }
4195
+ };
4196
+ $[32] = highlight;
4197
+ $[33] = view;
4198
+ $[34] = t18;
4199
+ } else {
4200
+ t18 = $[34];
4201
+ }
4202
+ const t19 = highlight?.from;
4203
+ const t20 = highlight?.to;
4204
+ let t21;
4205
+ if ($[35] !== t19 || $[36] !== t20) {
4206
+ t21 = [t19, t20];
4207
+ $[35] = t19;
4208
+ $[36] = t20;
4209
+ $[37] = t21;
4210
+ } else {
4211
+ t21 = $[37];
4212
+ }
4213
+ useEffect(t18, t21);
4214
+ const proseClass = proseClasses[textSize];
4215
+ const t22 = isMarkdownMode ? "Switch to Visual Editor" : "Switch to Markdown";
4216
+ const t23 = isMarkdownMode ? "Visual" : "Markdown";
4217
+ let t24;
4218
+ if ($[38] !== handleToggleMarkdown || $[39] !== t22 || $[40] !== t23) {
4219
+ t24 = /* @__PURE__ */ jsx("button", { type: "button", onClick: handleToggleMarkdown, title: t22, className: "absolute top-2 right-2 z-10 px-2 py-1 text-xs font-medium text-surface-400 hover:text-surface-700 dark:text-surface-600 dark:hover:text-surface-300 transition-colors opacity-50 hover:opacity-100 bg-transparent rounded", children: t23 });
4220
+ $[38] = handleToggleMarkdown;
4221
+ $[39] = t22;
4222
+ $[40] = t23;
4223
+ $[41] = t24;
4224
+ } else {
4225
+ t24 = $[41];
4226
+ }
4227
+ let t25;
4228
+ if ($[42] !== state || $[43] !== view) {
4229
+ t25 = {
4230
+ state,
4231
+ view
4232
+ };
4233
+ $[42] = state;
4234
+ $[43] = view;
4235
+ $[44] = t25;
4236
+ } else {
4237
+ t25 = $[44];
4238
+ }
4239
+ const t26 = isMarkdownMode ? "none" : "block";
4240
+ let t27;
4241
+ if ($[45] !== t26) {
4242
+ t27 = {
4243
+ display: t26
4244
+ };
4245
+ $[45] = t26;
4246
+ $[46] = t27;
4247
+ } else {
4248
+ t27 = $[46];
4249
+ }
4250
+ let t28;
4251
+ if ($[47] !== proseClass) {
4252
+ t28 = cls(proseClass, "prose-headings:font-title font-default focus:outline-none max-w-full p-12");
4253
+ $[47] = proseClass;
4254
+ $[48] = t28;
4255
+ } else {
4256
+ t28 = $[48];
4257
+ }
4258
+ let t29;
4259
+ if ($[49] !== editorRef || $[50] !== t28) {
4260
+ t29 = /* @__PURE__ */ jsx("div", { ref: editorRef, className: t28 });
4261
+ $[49] = editorRef;
4262
+ $[50] = t28;
4263
+ $[51] = t29;
4264
+ } else {
4265
+ t29 = $[51];
4266
+ }
4267
+ let t30;
4268
+ if ($[52] !== editorRef || $[53] !== openLink || $[54] !== openNode || $[55] !== view) {
4269
+ t30 = view && /* @__PURE__ */ jsxs(Fragment$1, { children: [
4270
+ /* @__PURE__ */ jsxs(EditorBubble, { options: {
4271
+ placement: "top",
4272
+ offset: 6
4273
+ }, className: cls("flex w-fit max-w-[90vw] h-10 overflow-hidden rounded border bg-white dark:bg-surface-900 shadow", defaultBorderMixin), children: [
4274
+ /* @__PURE__ */ jsx(NodeSelector, { portalContainer: editorRef.current, open: openNode, onOpenChange: setOpenNode }),
4275
+ /* @__PURE__ */ jsx(Separator, { orientation: "vertical" }),
4276
+ /* @__PURE__ */ jsx(LinkSelector, { open: openLink, onOpenChange: setOpenLink }),
4277
+ /* @__PURE__ */ jsx(Separator, { orientation: "vertical" }),
4278
+ /* @__PURE__ */ jsx(TextButtons, {})
4279
+ ] }),
4280
+ /* @__PURE__ */ jsx(ImageBubble, { options: {
4281
+ placement: "bottom",
4282
+ offset: 6
4283
+ } }),
4284
+ /* @__PURE__ */ jsx(TableBubble, {})
4285
+ ] });
4286
+ $[52] = editorRef;
4287
+ $[53] = openLink;
4288
+ $[54] = openNode;
4289
+ $[55] = view;
4290
+ $[56] = t30;
4291
+ } else {
4292
+ t30 = $[56];
4293
+ }
4294
+ let t31;
4295
+ if ($[57] !== aiController || $[58] !== handleImageUpload) {
4296
+ t31 = /* @__PURE__ */ jsx(SlashCommandMenu, { upload: handleImageUpload, aiController });
4297
+ $[57] = aiController;
4298
+ $[58] = handleImageUpload;
4299
+ $[59] = t31;
4300
+ } else {
4301
+ t31 = $[59];
4302
+ }
4303
+ let t32;
4304
+ if ($[60] !== t27 || $[61] !== t29 || $[62] !== t30 || $[63] !== t31) {
4305
+ t32 = /* @__PURE__ */ jsxs("div", { style: t27, children: [
4306
+ t29,
4307
+ t30,
4308
+ t31
4309
+ ] });
4310
+ $[60] = t27;
4311
+ $[61] = t29;
4312
+ $[62] = t30;
4313
+ $[63] = t31;
4314
+ $[64] = t32;
4315
+ } else {
4316
+ t32 = $[64];
4317
+ }
4318
+ let t33;
4319
+ if ($[65] !== handleMarkdownBlur || $[66] !== handleMarkdownChange || $[67] !== internalMarkdown || $[68] !== isMarkdownMode || $[69] !== proseClass) {
4320
+ t33 = isMarkdownMode && /* @__PURE__ */ jsx(TextareaAutosize, { value: internalMarkdown, onChange: handleMarkdownChange, onBlur: handleMarkdownBlur, className: cls("w-full min-h-[300px] p-12 bg-transparent resize-none font-mono focus:ring-0 focus:outline-none outline-none", proseClass), style: {
4321
+ tabSize: 4,
4322
+ outline: "none",
4323
+ border: "none",
4324
+ boxShadow: "none"
4325
+ } });
4326
+ $[65] = handleMarkdownBlur;
4327
+ $[66] = handleMarkdownChange;
4328
+ $[67] = internalMarkdown;
4329
+ $[68] = isMarkdownMode;
4330
+ $[69] = proseClass;
4331
+ $[70] = t33;
4332
+ } else {
4333
+ t33 = $[70];
4334
+ }
4335
+ let t34;
4336
+ if ($[71] !== t25 || $[72] !== t32 || $[73] !== t33) {
4337
+ t34 = /* @__PURE__ */ jsxs(ProseMirrorContext.Provider, { value: t25, children: [
4338
+ t32,
4339
+ t33
4340
+ ] });
4341
+ $[71] = t25;
4342
+ $[72] = t32;
4343
+ $[73] = t33;
4344
+ $[74] = t34;
4345
+ } else {
4346
+ t34 = $[74];
4347
+ }
4348
+ let t35;
4349
+ if ($[75] !== t24 || $[76] !== t34) {
4350
+ t35 = /* @__PURE__ */ jsxs("div", { className: "relative min-h-[300px] w-full", children: [
4351
+ t24,
4352
+ t34
4353
+ ] });
4354
+ $[75] = t24;
4355
+ $[76] = t34;
4356
+ $[77] = t35;
4357
+ } else {
4358
+ t35 = $[77];
4359
+ }
4360
+ return t35;
4361
+ };
4362
+ const cssStyles = `
4363
+ .ProseMirror {
4364
+ box-shadow: none !important;
4365
+ }
4366
+ .ProseMirror .is-editor-empty:first-child::before {
4367
+ content: attr(data-placeholder);
4368
+ float: left;
4369
+ color: rgb(100 116 139); //500
4370
+ pointer-events: none;
4371
+ height: 0;
4372
+ }
4373
+ .ProseMirror .is-empty::before {
4374
+ content: attr(data-placeholder);
4375
+ float: left;
4376
+ color: rgb(100 116 139); //500
4377
+ pointer-events: none;
4378
+ height: 0;
4379
+ }
4380
+
4381
+ [data-theme="dark"] {
4382
+ .ProseMirror .is-empty::before {
4383
+ color: rgb(100 116 139); //500
4384
+ }
4385
+ }
4386
+
4387
+ .is-empty {
4388
+ cursor: text;
4389
+ color: rgb(100 116 139); //500
4390
+ }
4391
+
4392
+ .ProseMirror img {
4393
+ transition: filter 0.1s ease-in-out;
4394
+ &:hover {
4395
+ cursor: pointer;
4396
+ filter: brightness(90%);
4397
+ }
4398
+ &.ProseMirror-selectednode {
4399
+ filter: brightness(90%);
4400
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000) !important;
4401
+ }
4402
+ }
4403
+
4404
+ ul[data-type="taskList"] li > label {
4405
+ margin-right: 0.2rem;
4406
+ user-select: none;
4407
+ }
4408
+ @media screen and (max-width: 768px) {
4409
+ ul[data-type="taskList"] li > label {
4410
+ margin-right: 0.5rem;
4411
+ }
4412
+ }
4413
+ [data-theme="dark"] {
4414
+ ul[data-type="taskList"] li > label input[type="checkbox"] {
4415
+ background-color: rgb(30 41 59);
4416
+ border: 2px solid #666;
4417
+ &:hover { background-color: rgb(51 65 85); }
4418
+ &:active { background-color: rgb(71 85 105); }
4419
+ }
4420
+ }
4421
+ ul[data-type="taskList"] li > label input[type="checkbox"] {
4422
+ -webkit-appearance: none;
4423
+ appearance: none;
4424
+ background-color: white;
4425
+ margin: 0;
4426
+ cursor: pointer;
4427
+ width: 1.2em;
4428
+ height: 1.2em;
4429
+ position: relative;
4430
+ top: 5px;
4431
+ border: 2px solid #777;
4432
+ border-radius: 0.25em;
4433
+ margin-right: 0.3rem;
4434
+ display: grid;
4435
+ place-content: center;
4436
+ &:hover { background-color: rgb(241 245 249); }
4437
+ &:active { background-color: rgb(226 232 240); }
4438
+ &::before {
4439
+ content: "";
4440
+ width: 0.65em;
4441
+ height: 0.65em;
4442
+ transform: scale(0);
4443
+ transition: 120ms transform ease-in-out;
4444
+ box-shadow: inset 1em 1em;
4445
+ transform-origin: center;
4446
+ clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
4447
+ }
4448
+ &:checked::before { transform: scale(1); }
4449
+ }
4450
+
4451
+ [data-theme="dark"] {
4452
+ ul[data-type="taskList"] li[data-checked="true"] > div > p {
4453
+ color: rgb(226 232 240);
4454
+ text-decoration: line-through;
4455
+ text-decoration-thickness: 2px;
4456
+ }
4457
+ }
4458
+ ul[data-type="taskList"] li[data-checked="true"] > div > p {
4459
+ color: rgb(51 65 85);
4460
+ text-decoration: line-through;
4461
+ text-decoration-thickness: 2px;
4462
+ }
4463
+ .tippy-box { max-width: 400px !important; }
4464
+
4465
+ .ProseMirror:not(.dragging) .ProseMirror-selectednode {
4466
+ background-color: rgb(219 234 254);
4467
+ transition: background-color 0.2s;
4468
+ box-shadow: none;
4469
+ }
4470
+ [data-theme="dark"] .ProseMirror:not(.dragging) .ProseMirror-selectednode {
4471
+ background-color: rgb(51 65 85);
4472
+ }
4473
+ .prose-base table p { margin: 0; }
4474
+
4475
+ .drag-handle {
4476
+ position: absolute;
4477
+ opacity: 1;
4478
+ transition: opacity ease-in 0.2s;
4479
+ border-radius: 0.25rem;
4480
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10' style='fill: rgba(128, 128, 128, 0.9)'%3E%3Cpath d='M3,2 C2.44771525,2 2,1.55228475 2,1 C2,0.44771525 2.44771525,0 3,0 C3.55228475,0 4,0.44771525 4,1 C4,1.55228475 3.55228475,2 3,2 Z M3,6 C2.44771525,6 2,5.55228475 2,5 C2,4.44771525 2.44771525,4 3,4 C3.55228475,4 4,4.44771525 4,5 C4,5.55228475 3.55228475,6 3,6 Z M3,10 C2.44771525,10 2,9.55228475 2,9 C2,8.44771525 2.44771525,8 3,8 C3.55228475,8 4,8.44771525 4,9 C4,9.55228475 3.55228475,10 3,10 Z M7,2 C6.44771525,2 6,1.55228475 6,1 C6,0.44771525 6.44771525,0 7,0 C7.55228475,0 8,0.44771525 8,1 C8,1.55228475 7.55228475,2 7,2 Z M7,6 C6.44771525,6 6,5.55228475 6,5 C6,4.44771525 6.44771525,4 7,4 C7.55228475,4 8,4.44771525 8,5 C8,5.55228475 7.55228475,6 7,6 Z M7,10 C6.44771525,10 6,9.55228475 6,9 C6,8.44771525 6.44771525,8 7,8 C7,8.44771525 7,9 7,9 C7,9.55228475 7,10 7,10 Z'%3E%3C/path%3E%3C/svg%3E");
4481
+ background-size: calc(0.5em + 0.375rem) calc(0.5em + 0.375rem);
4482
+ background-repeat: no-repeat;
4483
+ background-position: center;
4484
+ width: 1.2rem;
4485
+ height: 1.5rem;
4486
+ z-index: 100;
4487
+ cursor: grab;
4488
+
4489
+ /* Create a hover area around the handle itself that doesn't overlap text */
4490
+ &::before {
4491
+ content: '';
4492
+ position: absolute;
4493
+ top: -10px;
4494
+ bottom: -10px;
4495
+ left: -20px;
4496
+ right: 0px;
4497
+ z-index: -1;
4498
+ }
4499
+
4500
+ &:hover { background-color: rgb(241 245 249); transition: background-color 0.2s; }
4501
+ &:active { background-color: rgb(226 232 240); transition: background-color 0.2s; }
4502
+ &.hide { opacity: 0; pointer-events: none; }
4503
+ @media screen and (max-width: 600px) { display: none; pointer-events: none; }
4504
+ }
4505
+ [data-theme="dark"] .drag-handle {
4506
+ &:hover { background-color: rgb(51 65 85); }
4507
+ &:active { background-color: rgb(51 65 85); }
4508
+ }
4509
+ .prosemirror-dropcursor-block {
4510
+ background-color: var(--color-surface-accent-600);
4511
+ }
4512
+ [data-theme="dark"] .prosemirror-dropcursor-block {
4513
+ background-color: var(--color-surface-accent-300);
4514
+ }
4515
+
4516
+ .ProseMirror table {
4517
+ border-collapse: separate;
4518
+ border-spacing: 0;
4519
+ table-layout: fixed;
4520
+ width: 100%;
4521
+ margin: 1em 0;
4522
+ overflow: hidden;
4523
+ border-radius: 0.375rem;
4524
+ border: 1px solid #e5e7eb;
4525
+ }
4526
+ [data-theme="dark"] .ProseMirror table {
4527
+ border-color: #374151;
4528
+ }
4529
+
4530
+ .ProseMirror td, .ProseMirror th {
4531
+ min-width: 1em;
4532
+ padding: 8px 10px;
4533
+ vertical-align: top;
4534
+ box-sizing: border-box;
4535
+ position: relative;
4536
+ border-right: 1px solid #e5e7eb;
4537
+ border-bottom: 1px solid #e5e7eb;
4538
+ }
4539
+ [data-theme="dark"] .ProseMirror td, [data-theme="dark"] .ProseMirror th {
4540
+ border-right-color: #374151;
4541
+ border-bottom-color: #374151;
4542
+ }
4543
+
4544
+ .ProseMirror tr:last-child td, .ProseMirror tr:last-child th {
4545
+ border-bottom: none;
4546
+ }
4547
+ .ProseMirror th:last-child, .ProseMirror td:last-child {
4548
+ border-right: none;
4549
+ }
4550
+
4551
+ .ProseMirror th {
4552
+ font-weight: 600;
4553
+ text-align: left;
4554
+ background-color: #f9fafb;
4555
+ }
4556
+ [data-theme="dark"] .ProseMirror th {
4557
+ background-color: #1f2937;
4558
+ }
4559
+ `;
4560
+ export {
4561
+ FireCMSEditor
4562
+ };
4563
+ //# sourceMappingURL=editor-BSo_aS1I.js.map