@dxos/react-ui-editor 0.7.5-main.9d26e3a → 0.7.5-main.9d2a38b

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 (74) hide show
  1. package/dist/lib/browser/index.mjs +1105 -1127
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +1128 -1164
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +1105 -1127
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/InputMode.stories.d.ts.map +1 -1
  11. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +4 -0
  12. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -0
  13. package/dist/types/src/components/EditorToolbar/blocks.d.ts +18 -0
  14. package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -0
  15. package/dist/types/src/components/EditorToolbar/comment.d.ts +17 -0
  16. package/dist/types/src/components/EditorToolbar/comment.d.ts.map +1 -0
  17. package/dist/types/src/components/EditorToolbar/formatting.d.ts +18 -0
  18. package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -0
  19. package/dist/types/src/components/EditorToolbar/headings.d.ts +18 -0
  20. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -0
  21. package/dist/types/src/components/EditorToolbar/index.d.ts +3 -0
  22. package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -0
  23. package/dist/types/src/components/EditorToolbar/lists.d.ts +18 -0
  24. package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -0
  25. package/dist/types/src/components/EditorToolbar/util.d.ts +58 -0
  26. package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -0
  27. package/dist/types/src/components/EditorToolbar/viewMode.d.ts +18 -0
  28. package/dist/types/src/components/EditorToolbar/viewMode.d.ts.map +1 -0
  29. package/dist/types/src/components/index.d.ts +1 -1
  30. package/dist/types/src/components/index.d.ts.map +1 -1
  31. package/dist/types/src/extensions/comments.d.ts +3 -4
  32. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  33. package/dist/types/src/extensions/markdown/editorAction.d.ts +12 -0
  34. package/dist/types/src/extensions/markdown/editorAction.d.ts.map +1 -0
  35. package/dist/types/src/extensions/markdown/formatting.d.ts +14 -12
  36. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  37. package/dist/types/src/extensions/markdown/index.d.ts +1 -1
  38. package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
  39. package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
  40. package/dist/types/src/hooks/useActionHandler.d.ts +2 -2
  41. package/dist/types/src/hooks/useActionHandler.d.ts.map +1 -1
  42. package/dist/types/src/index.d.ts +1 -0
  43. package/dist/types/src/index.d.ts.map +1 -1
  44. package/dist/types/src/styles/stack-item-content-class-names.d.ts +3 -0
  45. package/dist/types/src/styles/stack-item-content-class-names.d.ts.map +1 -0
  46. package/dist/types/tsconfig.tsbuildinfo +1 -1
  47. package/package.json +28 -27
  48. package/src/InputMode.stories.tsx +7 -10
  49. package/src/components/EditorToolbar/EditorToolbar.tsx +106 -0
  50. package/src/components/EditorToolbar/blocks.ts +41 -0
  51. package/src/components/EditorToolbar/comment.ts +20 -0
  52. package/src/components/EditorToolbar/formatting.ts +41 -0
  53. package/src/components/EditorToolbar/headings.ts +59 -0
  54. package/src/components/EditorToolbar/index.ts +6 -0
  55. package/src/components/EditorToolbar/lists.ts +40 -0
  56. package/src/components/EditorToolbar/util.ts +65 -0
  57. package/src/components/EditorToolbar/viewMode.ts +48 -0
  58. package/src/components/index.ts +1 -1
  59. package/src/extensions/comments.ts +8 -15
  60. package/src/extensions/markdown/{action.ts → editorAction.ts} +22 -20
  61. package/src/extensions/markdown/formatting.ts +20 -24
  62. package/src/extensions/markdown/index.ts +1 -1
  63. package/src/extensions/markdown/styles.ts +21 -0
  64. package/src/hooks/useActionHandler.ts +4 -4
  65. package/src/index.ts +4 -0
  66. package/src/styles/stack-item-content-class-names.ts +17 -0
  67. package/dist/types/src/components/Toolbar/Toolbar.d.ts +0 -34
  68. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +0 -1
  69. package/dist/types/src/components/Toolbar/index.d.ts +0 -2
  70. package/dist/types/src/components/Toolbar/index.d.ts.map +0 -1
  71. package/dist/types/src/extensions/markdown/action.d.ts +0 -9
  72. package/dist/types/src/extensions/markdown/action.d.ts.map +0 -1
  73. package/src/components/Toolbar/Toolbar.tsx +0 -522
  74. package/src/components/Toolbar/index.ts +0 -5
@@ -39,259 +39,856 @@ import { EditorView as EditorView21, keymap as keymap11 } from "@codemirror/view
39
39
  import { tags as tags2 } from "@lezer/highlight";
40
40
  import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
41
41
 
42
- // packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
43
- import { ChatText, Code, CodeBlock, Image, Link, ListBullets, ListChecks, ListNumbers, MagnifyingGlass, Paragraph, Quotes, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, CaretDown, Check, PencilSimpleSlash, MarkdownLogo, PencilSimple } from "@phosphor-icons/react";
44
- import { createContext } from "@radix-ui/react-context";
45
- import React3, { useEffect as useEffect2, useRef, useState as useState3 } from "react";
46
- import { useDropzone } from "react-dropzone";
47
- import { Button, DropdownMenu, ElevationProvider, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
48
- import { getSize } from "@dxos/react-ui-theme";
42
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
43
+ import React, { useCallback } from "react";
44
+ import { ElevationProvider } from "@dxos/react-ui";
45
+ import { ToolbarMenu, MenuProvider, useMenuActions, createGapSeparator } from "@dxos/react-ui-menu";
46
+ import { textBlockWidth } from "@dxos/react-ui-theme";
49
47
 
50
- // packages/ui/react-ui-editor/src/extensions/annotations.ts
51
- import { StateField } from "@codemirror/state";
52
- import { Decoration, EditorView } from "@codemirror/view";
53
- import { isNotFalsy } from "@dxos/util";
54
-
55
- // packages/ui/react-ui-editor/src/util/facet.ts
56
- import { Facet } from "@codemirror/state";
57
- var singleValueFacet = (defaultValue) => Facet.define({
58
- // Called immediately.
59
- combine: (providers) => {
60
- return providers[0] ?? defaultValue;
48
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/util.ts
49
+ import { useMemo } from "react";
50
+ import { create } from "@dxos/live-object";
51
+ import { createMenuAction, createMenuItemGroup } from "@dxos/react-ui-menu";
52
+ var useEditorToolbarState = (initialState = {}) => {
53
+ return useMemo(() => create(initialState), []);
54
+ };
55
+ var createEditorAction = (payload, icon, label = [
56
+ `${payload.type} label`,
57
+ {
58
+ ns: translationKey
61
59
  }
60
+ ], id = payload.type) => createMenuAction(id, {
61
+ icon,
62
+ label,
63
+ ...payload
64
+ });
65
+ var createEditorActionGroup = (id, props, icon) => createMenuItemGroup(id, {
66
+ icon,
67
+ iconOnly: true,
68
+ ...props
62
69
  });
70
+ var editorToolbarSearch = createEditorAction({
71
+ type: "search"
72
+ }, "ph--magnifying-glass--regular");
63
73
 
64
- // packages/ui/react-ui-editor/src/util/cursor.ts
65
- var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
66
- var defaultCursorConverter = {
67
- toCursor: (position) => position.toString(),
68
- fromCursor: (cursor) => parseInt(cursor)
69
- };
70
- var Cursor = class _Cursor {
71
- static {
72
- this.converter = singleValueFacet(defaultCursorConverter);
73
- }
74
- static {
75
- this.getCursorFromRange = (state, range) => {
76
- const cursorConverter2 = state.facet(_Cursor.converter);
77
- const from = cursorConverter2.toCursor(range.from);
78
- const to = cursorConverter2.toCursor(range.to, -1);
79
- return [
80
- from,
81
- to
82
- ].join(":");
83
- };
84
- }
85
- static {
86
- this.getRangeFromCursor = (state, cursor) => {
87
- const cursorConverter2 = state.facet(_Cursor.converter);
88
- const parts = cursor.split(":");
89
- const from = cursorConverter2.fromCursor(parts[0]);
90
- const to = cursorConverter2.fromCursor(parts[1]);
91
- return from !== void 0 && to !== void 0 ? {
92
- from,
93
- to
94
- } : void 0;
95
- };
96
- }
74
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/blocks.ts
75
+ var createBlockGroupAction = (value) => createEditorActionGroup("block", {
76
+ variant: "toggleGroup",
77
+ selectCardinality: "single",
78
+ value
79
+ });
80
+ var createBlockActions = (value, blankLine) => Object.entries({
81
+ blockquote: "ph--quotes--regular",
82
+ codeblock: "ph--code-block--regular",
83
+ table: "ph--table--regular"
84
+ }).map(([type, icon]) => {
85
+ return createEditorAction({
86
+ type,
87
+ checked: type === value,
88
+ ...type === "table" && {
89
+ disabled: !!blankLine
90
+ }
91
+ }, icon);
92
+ });
93
+ var createBlocks = (state) => {
94
+ const value = state?.blockQuote ? "blockquote" : state.blockType ?? "";
95
+ const blockGroupAction = createBlockGroupAction(value);
96
+ const blockActions = createBlockActions(value, state.blankLine);
97
+ return {
98
+ nodes: [
99
+ blockGroupAction,
100
+ ...blockActions
101
+ ],
102
+ edges: [
103
+ {
104
+ source: "root",
105
+ target: "block"
106
+ },
107
+ ...blockActions.map(({ id }) => ({
108
+ source: blockGroupAction.id,
109
+ target: id
110
+ }))
111
+ ]
112
+ };
97
113
  };
98
114
 
99
- // packages/ui/react-ui-editor/src/util/debug.ts
100
- import { log } from "@dxos/log";
101
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
102
- var wrapWithCatch = (fn) => {
103
- return (...args) => {
104
- try {
105
- return fn(...args);
106
- } catch (err) {
107
- log.catch(err, void 0, {
108
- F: __dxlog_file,
109
- L: 15,
110
- S: void 0,
111
- C: (f, a) => f(...a)
112
- });
115
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/comment.ts
116
+ var commentLabel = (comment, selection) => comment ? "selection overlaps existing comment label" : selection === false ? "select text to comment label" : "comment label";
117
+ var createCommentAction = (label) => createEditorAction({
118
+ type: "comment",
119
+ testId: "editor.toolbar.comment"
120
+ }, "ph--chat-text--regular", label);
121
+ var createComment = (state) => ({
122
+ nodes: [
123
+ createCommentAction(commentLabel(state.comment, state.selection))
124
+ ],
125
+ edges: [
126
+ {
127
+ source: "root",
128
+ target: "comment"
113
129
  }
130
+ ]
131
+ });
132
+
133
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/formatting.ts
134
+ var formats = {
135
+ strong: "ph--text-b--regular",
136
+ emphasis: "ph--text-italic--regular",
137
+ strikethrough: "ph--text-strikethrough--regular",
138
+ code: "ph--code--regular",
139
+ link: "ph--link--regular"
140
+ };
141
+ var createFormattingGroup = (formatting) => createEditorActionGroup("formatting", {
142
+ variant: "toggleGroup",
143
+ selectCardinality: "multiple",
144
+ value: Object.keys(formats).filter((key) => !!formatting[key])
145
+ });
146
+ var createFormattingActions = (formatting) => Object.entries(formats).map(([type, icon]) => createEditorAction({
147
+ type,
148
+ checked: !!formatting[type]
149
+ }, icon));
150
+ var createFormatting = (state) => {
151
+ const formattingGroupAction = createFormattingGroup(state);
152
+ const formattingActions = createFormattingActions(state);
153
+ return {
154
+ nodes: [
155
+ formattingGroupAction,
156
+ ...formattingActions
157
+ ],
158
+ edges: [
159
+ {
160
+ source: "root",
161
+ target: "formatting"
162
+ },
163
+ ...formattingActions.map(({ id }) => ({
164
+ source: formattingGroupAction.id,
165
+ target: id
166
+ }))
167
+ ]
114
168
  };
115
169
  };
116
- var callbackWrapper = (fn) => (...args) => {
117
- try {
118
- return fn(...args);
119
- } catch (err) {
120
- log.catch(err, void 0, {
121
- F: __dxlog_file,
122
- L: 29,
123
- S: void 0,
124
- C: (f, a) => f(...a)
125
- });
126
- }
170
+
171
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/headings.ts
172
+ var createHeadingGroupAction = (value) => createEditorActionGroup("heading", {
173
+ variant: "dropdownMenu",
174
+ applyActive: true,
175
+ selectCardinality: "single",
176
+ value
177
+ }, "ph--text-h--regular");
178
+ var createHeadingActions = (value) => Object.entries({
179
+ "0": "ph--paragraph--regular",
180
+ "1": "ph--text-h-one--regular",
181
+ "2": "ph--text-h-two--regular",
182
+ "3": "ph--text-h-three--regular",
183
+ "4": "ph--text-h-four--regular",
184
+ "5": "ph--text-h-five--regular",
185
+ "6": "ph--text-h-six--regular"
186
+ }).map(([levelStr, icon]) => {
187
+ const level = parseInt(levelStr);
188
+ return createEditorAction({
189
+ type: "heading",
190
+ data: level,
191
+ checked: value === levelStr
192
+ }, icon, [
193
+ "heading level label",
194
+ {
195
+ count: level,
196
+ ns: translationKey
197
+ }
198
+ ], `heading--${levelStr}`);
199
+ });
200
+ var computeHeadingValue = (state) => {
201
+ const blockType = state ? state.blockType : "paragraph";
202
+ const header = blockType && /heading(\d)/.exec(blockType);
203
+ return header ? header[1] : blockType === "paragraph" || !blockType ? "0" : "";
127
204
  };
128
- var debugDispatcher = (trs, view) => {
129
- logChanges(trs);
130
- view.update(trs);
205
+ var createHeadings = (state) => {
206
+ const headingValue = computeHeadingValue(state);
207
+ const headingGroupAction = createHeadingGroupAction(headingValue);
208
+ const headingActions = createHeadingActions(headingValue);
209
+ return {
210
+ nodes: [
211
+ headingGroupAction,
212
+ ...headingActions
213
+ ],
214
+ edges: [
215
+ {
216
+ source: "root",
217
+ target: "heading"
218
+ },
219
+ ...headingActions.map(({ id }) => ({
220
+ source: headingGroupAction.id,
221
+ target: id
222
+ }))
223
+ ]
224
+ };
131
225
  };
132
- var logChanges = (trs) => {
133
- const changes = trs.flatMap((tr) => {
134
- if (tr.changes.empty) {
135
- return void 0;
226
+
227
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/lists.ts
228
+ var listStyles = {
229
+ bullet: "ph--list-bullets--regular",
230
+ ordered: "ph--list-numbers--regular",
231
+ task: "ph--list-checks--regular"
232
+ };
233
+ var createListGroupAction = (value) => createEditorActionGroup("list", {
234
+ variant: "toggleGroup",
235
+ selectCardinality: "single",
236
+ value
237
+ });
238
+ var createListActions = (value) => Object.entries(listStyles).map(([listStyle, icon]) => createEditorAction({
239
+ type: `list-${listStyle}`,
240
+ checked: value === listStyle
241
+ }, icon));
242
+ var createLists = (state) => {
243
+ const value = state.listStyle ?? "";
244
+ const listGroupAction = createListGroupAction(value);
245
+ const listActionsMap = createListActions(value);
246
+ return {
247
+ nodes: [
248
+ listGroupAction,
249
+ ...listActionsMap
250
+ ],
251
+ edges: [
252
+ {
253
+ source: "root",
254
+ target: "list"
255
+ },
256
+ ...listActionsMap.map(({ id }) => ({
257
+ source: listGroupAction.id,
258
+ target: id
259
+ }))
260
+ ]
261
+ };
262
+ };
263
+
264
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/viewMode.ts
265
+ var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
266
+ variant: "dropdownMenu",
267
+ applyActive: true,
268
+ selectCardinality: "single",
269
+ value
270
+ }, "ph--eye--regular");
271
+ var createViewModeActions = (value) => Object.entries({
272
+ preview: "ph--eye--regular",
273
+ source: "ph--pencil-simple--regular",
274
+ readonly: "ph--pencil-slash--regular"
275
+ }).map(([viewMode, icon]) => {
276
+ return createEditorAction({
277
+ type: "view-mode",
278
+ data: viewMode,
279
+ checked: viewMode === value
280
+ }, icon, [
281
+ `${viewMode} mode label`,
282
+ {
283
+ ns: translationKey
136
284
  }
137
- const changes2 = [];
138
- tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
139
- fromA,
140
- toA,
141
- fromB,
142
- toB,
143
- inserted: inserted.toString()
144
- })));
145
- return changes2;
146
- }).filter(Boolean);
147
- if (changes.length) {
148
- log.info("changes", {
149
- changes
150
- }, {
151
- F: __dxlog_file,
152
- L: 62,
153
- S: void 0,
154
- C: (f, a) => f(...a)
155
- });
156
- }
285
+ ], `view-mode--${viewMode}`);
286
+ });
287
+ var createViewMode = (state) => {
288
+ const value = state.viewMode ?? "source";
289
+ const viewModeGroupAction = createViewModeGroupAction(value);
290
+ const viewModeActions = createViewModeActions(value);
291
+ return {
292
+ nodes: [
293
+ viewModeGroupAction,
294
+ ...viewModeActions
295
+ ],
296
+ edges: [
297
+ {
298
+ source: "root",
299
+ target: "viewMode"
300
+ },
301
+ ...viewModeActions.map(({ id }) => ({
302
+ source: viewModeGroupAction.id,
303
+ target: id
304
+ }))
305
+ ]
306
+ };
157
307
  };
158
308
 
159
- // packages/ui/react-ui-editor/src/util/dom.ts
160
- var flattenRect = (rect, left) => {
161
- const x = left ? rect.left : rect.right;
309
+ // packages/ui/react-ui-editor/src/styles/stack-item-content-class-names.ts
310
+ import { mx } from "@dxos/react-ui-theme";
311
+ var stackItemContentEditorClassNames = (role) => mx("ch-focus-ring-inset data-[toolbar=disabled]:pbs-2 attention-surface", role === "article" ? "min-bs-0" : "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24");
312
+ var stackItemContentToolbarClassNames = (role) => mx("attention-surface is-full border-be !border-separator", role === "section" && "sticky block-start-0 z-[1] -mbe-px min-is-0");
313
+
314
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
315
+ var createToolbar = ({ state, customActions, ...features }) => {
316
+ const nodes = [];
317
+ const edges = [];
318
+ if (features.headings ?? true) {
319
+ const headings2 = createHeadings(state);
320
+ nodes.push(...headings2.nodes);
321
+ edges.push(...headings2.edges);
322
+ }
323
+ if (features.formatting ?? true) {
324
+ const formatting = createFormatting(state);
325
+ nodes.push(...formatting.nodes);
326
+ edges.push(...formatting.edges);
327
+ }
328
+ if (features.lists ?? true) {
329
+ const lists = createLists(state);
330
+ nodes.push(...lists.nodes);
331
+ edges.push(...lists.edges);
332
+ }
333
+ if (features.blocks ?? true) {
334
+ const blocks = createBlocks(state);
335
+ nodes.push(...blocks.nodes);
336
+ edges.push(...blocks.edges);
337
+ }
338
+ if (customActions) {
339
+ const custom = customActions();
340
+ nodes.push(...custom.nodes);
341
+ edges.push(...custom.edges);
342
+ }
343
+ const editorToolbarGap = createGapSeparator();
344
+ nodes.push(...editorToolbarGap.nodes);
345
+ edges.push(...editorToolbarGap.edges);
346
+ if (features.comment ?? true) {
347
+ const comment = createComment(state);
348
+ nodes.push(...comment.nodes);
349
+ edges.push(...comment.edges);
350
+ }
351
+ if (features.search ?? true) {
352
+ nodes.push(editorToolbarSearch);
353
+ edges.push({
354
+ source: "root",
355
+ target: editorToolbarSearch.id
356
+ });
357
+ }
358
+ if (features.viewMode ?? true) {
359
+ const viewMode = createViewMode(state);
360
+ nodes.push(...viewMode.nodes);
361
+ edges.push(...viewMode.edges);
362
+ }
162
363
  return {
163
- left: x,
164
- right: x,
165
- top: rect.top,
166
- bottom: rect.bottom
364
+ nodes,
365
+ edges
167
366
  };
168
367
  };
169
- var scratchRange;
170
- var textRange = (node, from, to = from) => {
171
- const range = scratchRange || (scratchRange = document.createRange());
172
- range.setEnd(node, to);
173
- range.setStart(node, from);
174
- return range;
368
+ var useEditorToolbarActionGraph = ({ onAction, ...props }) => {
369
+ const menuCreator = useCallback(() => createToolbar(props), [
370
+ props
371
+ ]);
372
+ const { resolveGroupItems } = useMenuActions(menuCreator);
373
+ return {
374
+ resolveGroupItems,
375
+ onAction
376
+ };
175
377
  };
176
- var clientRectsFor = (dom) => {
177
- if (dom.nodeType === 3) {
178
- return textRange(dom, 0, dom.nodeValue.length).getClientRects();
179
- } else if (dom.nodeType === 1) {
180
- return dom.getClientRects();
181
- } else {
182
- return [];
183
- }
378
+ var EditorToolbar = ({ classNames, attendableId, role, ...props }) => {
379
+ const menuProps = useEditorToolbarActionGraph(props);
380
+ return /* @__PURE__ */ React.createElement("div", {
381
+ role: "none",
382
+ className: stackItemContentToolbarClassNames(role)
383
+ }, /* @__PURE__ */ React.createElement(ElevationProvider, {
384
+ elevation: role === "section" ? "positioned" : "base"
385
+ }, /* @__PURE__ */ React.createElement(MenuProvider, {
386
+ ...menuProps,
387
+ attendableId
388
+ }, /* @__PURE__ */ React.createElement(ToolbarMenu, {
389
+ classNames: [
390
+ textBlockWidth,
391
+ "!bg-transparent",
392
+ classNames
393
+ ]
394
+ }))));
184
395
  };
185
396
 
186
- // packages/ui/react-ui-editor/src/util/react.tsx
187
- import React from "react";
188
- import { createRoot } from "react-dom/client";
189
- import { ThemeProvider } from "@dxos/react-ui";
190
- import { defaultTx } from "@dxos/react-ui-theme";
191
- var createElement = (tag, options, children) => {
192
- const el = document.createElement(tag);
193
- if (options?.className) {
194
- el.className = options.className;
195
- }
196
- if (children) {
197
- el.append(...Array.isArray(children) ? children : [
198
- children
199
- ]);
397
+ // packages/ui/react-ui-editor/src/defaults.ts
398
+ import { EditorView } from "@codemirror/view";
399
+ import { mx as mx3 } from "@dxos/react-ui-theme";
400
+
401
+ // packages/ui/react-ui-editor/src/styles/markdown.ts
402
+ import { mx as mx2 } from "@dxos/react-ui-theme";
403
+ var headings = {
404
+ 1: "text-4xl",
405
+ 2: "text-3xl",
406
+ 3: "text-2xl",
407
+ 4: "text-xl",
408
+ 5: "text-lg",
409
+ 6: "text-md"
410
+ };
411
+ var theme = {
412
+ code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
413
+ codeMark: "font-mono text-primary-500",
414
+ mark: "opacity-50",
415
+ heading: (level) => {
416
+ return mx2(headings[level], "dark:text-primary-400");
200
417
  }
201
- return el;
202
418
  };
203
- var renderRoot = (root, node) => {
204
- createRoot(root).render(/* @__PURE__ */ React.createElement(ThemeProvider, {
205
- tx: defaultTx
206
- }, node));
207
- return root;
419
+
420
+ // packages/ui/react-ui-editor/src/styles/tokens.ts
421
+ import get from "lodash.get";
422
+ import { tokens } from "@dxos/react-ui-theme";
423
+ var getToken = (path, defaultValue) => {
424
+ const value = get(tokens, path, defaultValue);
425
+ return value?.toString() ?? "";
208
426
  };
427
+ var fontBody = getToken("fontFamily.body");
428
+ var fontMono = getToken("fontFamily.mono");
209
429
 
210
- // packages/ui/react-ui-editor/src/extensions/annotations.ts
211
- var annotationMark = Decoration.mark({
212
- class: "cm-annotation"
213
- });
214
- var annotations = (options = {}) => {
215
- const match = (state) => {
216
- const annotations2 = [];
217
- const text = state.doc.toString();
218
- if (options.match) {
219
- const matches = text.matchAll(options.match);
220
- for (const match2 of matches) {
221
- const from = match2.index;
222
- const to = from + match2[0].length;
223
- const cursor = Cursor.getCursorFromRange(state, {
224
- from,
225
- to
226
- });
227
- annotations2.push({
228
- cursor
229
- });
230
- }
231
- }
232
- return annotations2;
233
- };
234
- const annotationsState = StateField.define({
235
- create: (state) => {
236
- return match(state);
237
- },
238
- update: (value, tr) => {
239
- if (!tr.changes.empty) {
240
- return match(tr.state);
241
- }
242
- return value;
430
+ // packages/ui/react-ui-editor/src/styles/theme.ts
431
+ var defaultTheme = {
432
+ "&": {},
433
+ "&.cm-focused": {
434
+ outline: "none"
435
+ },
436
+ /**
437
+ * Scroller
438
+ */
439
+ ".cm-scroller": {
440
+ overflowY: "auto"
441
+ },
442
+ /**
443
+ * Content
444
+ * NOTE: Apply margins to content so that scrollbar is at the edge of the container.
445
+ */
446
+ ".cm-content": {
447
+ padding: "unset",
448
+ fontFamily: fontBody,
449
+ // NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
450
+ fontSize: "16px",
451
+ lineHeight: 1.5,
452
+ color: "unset"
453
+ },
454
+ /**
455
+ * Gutters
456
+ * NOTE: Gutters should have the same top margin as the content.
457
+ * NOTE: They can't be transparent since the content needs to scroll below.
458
+ */
459
+ ".cm-gutters": {
460
+ background: "var(--surface-bg)",
461
+ borderRight: "none"
462
+ },
463
+ ".cm-gutter": {},
464
+ ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
465
+ minWidth: "40px",
466
+ alignContent: "center"
467
+ },
468
+ /**
469
+ * Height is set to match the corresponding line.
470
+ */
471
+ ".cm-gutterElement": {
472
+ alignItems: "center",
473
+ fontSize: "16px"
474
+ },
475
+ /**
476
+ * Line.
477
+ */
478
+ ".cm-line": {
479
+ paddingInline: 0
480
+ },
481
+ ".cm-activeLine": {
482
+ background: "var(--dx-cmActiveLine)"
483
+ },
484
+ /**
485
+ * Cursor (layer).
486
+ */
487
+ ".cm-cursor, .cm-dropCursor": {
488
+ borderLeft: "2px solid var(--dx-cmCursor)"
489
+ },
490
+ ".cm-placeholder": {
491
+ color: "var(--dx-subdued)"
492
+ },
493
+ /**
494
+ * Selection (layer).
495
+ */
496
+ ".cm-selectionBackground": {
497
+ background: "var(--dx-cmSelection)"
498
+ },
499
+ /**
500
+ * Search.
501
+ * NOTE: Matches comment.
502
+ */
503
+ ".cm-searchMatch": {
504
+ margin: "0 -3px",
505
+ padding: "3px",
506
+ borderRadius: "3px",
507
+ background: "var(--dx-cmHighlightSurface)",
508
+ color: "var(--dx-cmHighlight)"
509
+ },
510
+ ".cm-searchMatch-selected": {
511
+ textDecoration: "underline"
512
+ },
513
+ /**
514
+ * Link.
515
+ */
516
+ ".cm-link": {
517
+ textDecorationLine: "underline",
518
+ textDecorationThickness: "1px",
519
+ textUnderlineOffset: "2px",
520
+ borderRadius: ".125rem"
521
+ },
522
+ ".cm-link > span": {
523
+ color: "var(--dx-accentText)"
524
+ },
525
+ /**
526
+ * Tooltip.
527
+ */
528
+ ".cm-tooltip": {
529
+ background: "var(--dx-base)"
530
+ },
531
+ ".cm-tooltip-below": {},
532
+ /**
533
+ * Autocomplete.
534
+ * https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
535
+ */
536
+ ".cm-tooltip.cm-tooltip-autocomplete": {
537
+ marginTop: "4px",
538
+ marginLeft: "-3px"
539
+ },
540
+ ".cm-tooltip.cm-tooltip-autocomplete > ul": {
541
+ maxHeight: "20em"
542
+ },
543
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
544
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
545
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
546
+ paddingLeft: "4px !important",
547
+ borderBottom: "none !important",
548
+ color: "var(--dx-accentText)"
549
+ },
550
+ ".cm-tooltip.cm-completionInfo": {
551
+ width: "360px !important",
552
+ margin: "-10px 1px 0 1px",
553
+ padding: "8px !important",
554
+ borderColor: "var(--dx-separator)"
555
+ },
556
+ ".cm-completionIcon": {
557
+ display: "none"
558
+ },
559
+ ".cm-completionLabel": {
560
+ fontFamily: fontBody
561
+ },
562
+ ".cm-completionMatchedText": {
563
+ textDecoration: "none !important",
564
+ opacity: 0.5
565
+ },
566
+ /**
567
+ * Panels
568
+ * https://github.com/codemirror/search/blob/main/src/search.ts#L745
569
+ *
570
+ * Find/replace panel.
571
+ * <div class="cm-announced">...</div>
572
+ * <div class="cm-scroller">...</div>
573
+ * <div class="cm-panels cm-panels-bottom">
574
+ * <div class="cm-search cm-panel">
575
+ * <input class="cm-textfield" />
576
+ * <button class="cm-button">...</button>
577
+ * <label><input type="checkbox" />...</label>
578
+ * </div>
579
+ * </div
580
+ */
581
+ // TODO(burdon): Implement custom panel (with icon buttons).
582
+ ".cm-panels": {},
583
+ ".cm-panel": {
584
+ fontFamily: fontBody,
585
+ backgroundColor: "var(--surface-bg)"
586
+ },
587
+ ".cm-panel input, .cm-panel button, .cm-panel label": {
588
+ color: "var(--dx-subdued)",
589
+ fontFamily: fontBody,
590
+ fontSize: "14px",
591
+ all: "unset",
592
+ margin: "3px !important",
593
+ padding: "2px 6px !important",
594
+ outline: "1px solid transparent"
595
+ },
596
+ ".cm-panel input, .cm-panel button": {
597
+ backgroundColor: "var(--dx-input)"
598
+ },
599
+ ".cm-panel input:focus, .cm-panel button:focus": {
600
+ outline: "1px solid var(--dx-accentFocusIndicator)"
601
+ },
602
+ ".cm-panel label": {
603
+ display: "inline-flex",
604
+ alignItems: "center",
605
+ cursor: "pointer"
606
+ },
607
+ ".cm-panel input.cm-textfield": {},
608
+ ".cm-panel input[type=checkbox]": {
609
+ width: "8px",
610
+ height: "8px",
611
+ marginRight: "6px !important",
612
+ padding: "2px !important",
613
+ color: "var(--dx-accentFocusIndicator)"
614
+ },
615
+ ".cm-panel button": {
616
+ "&:hover": {
617
+ backgroundColor: "var(--dx-accentSurfaceHover) !important"
618
+ },
619
+ "&:active": {
620
+ backgroundColor: "var(--dx-accentSurfaceHover)"
243
621
  }
244
- });
245
- return [
246
- annotationsState,
247
- EditorView.decorations.compute([
248
- annotationsState
249
- ], (state) => {
250
- const annotations2 = state.field(annotationsState);
251
- const decorations = annotations2.map((annotation) => {
252
- const range = Cursor.getRangeFromCursor(state, annotation.cursor);
253
- return range && annotationMark.range(range.from, range.to);
254
- }).filter(isNotFalsy);
255
- return Decoration.set(decorations);
256
- }),
257
- styles
258
- ];
622
+ },
623
+ ".cm-panel.cm-search": {
624
+ padding: "4px",
625
+ borderTop: "1px solid var(--dx-separator)"
626
+ }
259
627
  };
260
- var styles = EditorView.theme({
261
- ".cm-annotation": {
262
- textDecoration: "underline",
263
- textDecorationStyle: "wavy",
264
- textDecorationColor: "var(--dx-error)"
628
+
629
+ // packages/ui/react-ui-editor/src/defaults.ts
630
+ var margin = "!mt-[1rem]";
631
+ var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
632
+ var editorFullWidth = mx3(margin);
633
+ var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
634
+ var editorGutter = EditorView.theme({
635
+ // Match margin from content.
636
+ ".cm-gutters": {
637
+ marginTop: "16px",
638
+ paddingRight: "1rem"
639
+ }
640
+ });
641
+ var editorMonospace = EditorView.theme({
642
+ ".cm-content": {
643
+ fontFamily: fontMono
265
644
  }
266
645
  });
267
646
 
268
- // packages/ui/react-ui-editor/src/extensions/autocomplete.ts
269
- import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
270
- import { markdownLanguage } from "@codemirror/lang-markdown";
271
- import { keymap } from "@codemirror/view";
272
- var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
273
- const extensions = [
274
- // https://codemirror.net/docs/ref/#view.keymap
275
- // https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
276
- // TODO(burdon): Set custom keymap.
277
- keymap.of(completionKeymap),
278
- // https://codemirror.net/examples/autocompletion
279
- // https://codemirror.net/docs/ref/#autocomplete.autocompletion
280
- autocompletion({
281
- activateOnTyping,
282
- override,
283
- closeOnBlur: !debug,
284
- tooltipClass: () => "shadow rounded"
285
- })
286
- ];
287
- if (onSearch) {
288
- extensions.push(
289
- // TODO(burdon): Optional decoration via addToOptions
290
- markdownLanguage.data.of({
291
- autocomplete: (context) => {
292
- const match = context.matchBefore(/\w*/);
293
- if (!match || match.from === match.to && !context.explicit) {
294
- return null;
647
+ // packages/ui/react-ui-editor/src/extensions/annotations.ts
648
+ import { StateField } from "@codemirror/state";
649
+ import { Decoration, EditorView as EditorView2 } from "@codemirror/view";
650
+ import { isNotFalsy } from "@dxos/util";
651
+
652
+ // packages/ui/react-ui-editor/src/util/facet.ts
653
+ import { Facet } from "@codemirror/state";
654
+ var singleValueFacet = (defaultValue) => Facet.define({
655
+ // Called immediately.
656
+ combine: (providers) => {
657
+ return providers[0] ?? defaultValue;
658
+ }
659
+ });
660
+
661
+ // packages/ui/react-ui-editor/src/util/cursor.ts
662
+ var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
663
+ var defaultCursorConverter = {
664
+ toCursor: (position) => position.toString(),
665
+ fromCursor: (cursor) => parseInt(cursor)
666
+ };
667
+ var Cursor = class _Cursor {
668
+ static {
669
+ this.converter = singleValueFacet(defaultCursorConverter);
670
+ }
671
+ static {
672
+ this.getCursorFromRange = (state, range) => {
673
+ const cursorConverter2 = state.facet(_Cursor.converter);
674
+ const from = cursorConverter2.toCursor(range.from);
675
+ const to = cursorConverter2.toCursor(range.to, -1);
676
+ return [
677
+ from,
678
+ to
679
+ ].join(":");
680
+ };
681
+ }
682
+ static {
683
+ this.getRangeFromCursor = (state, cursor) => {
684
+ const cursorConverter2 = state.facet(_Cursor.converter);
685
+ const parts = cursor.split(":");
686
+ const from = cursorConverter2.fromCursor(parts[0]);
687
+ const to = cursorConverter2.fromCursor(parts[1]);
688
+ return from !== void 0 && to !== void 0 ? {
689
+ from,
690
+ to
691
+ } : void 0;
692
+ };
693
+ }
694
+ };
695
+
696
+ // packages/ui/react-ui-editor/src/util/debug.ts
697
+ import { log } from "@dxos/log";
698
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
699
+ var wrapWithCatch = (fn) => {
700
+ return (...args) => {
701
+ try {
702
+ return fn(...args);
703
+ } catch (err) {
704
+ log.catch(err, void 0, {
705
+ F: __dxlog_file,
706
+ L: 15,
707
+ S: void 0,
708
+ C: (f, a) => f(...a)
709
+ });
710
+ }
711
+ };
712
+ };
713
+ var callbackWrapper = (fn) => (...args) => {
714
+ try {
715
+ return fn(...args);
716
+ } catch (err) {
717
+ log.catch(err, void 0, {
718
+ F: __dxlog_file,
719
+ L: 29,
720
+ S: void 0,
721
+ C: (f, a) => f(...a)
722
+ });
723
+ }
724
+ };
725
+ var debugDispatcher = (trs, view) => {
726
+ logChanges(trs);
727
+ view.update(trs);
728
+ };
729
+ var logChanges = (trs) => {
730
+ const changes = trs.flatMap((tr) => {
731
+ if (tr.changes.empty) {
732
+ return void 0;
733
+ }
734
+ const changes2 = [];
735
+ tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
736
+ fromA,
737
+ toA,
738
+ fromB,
739
+ toB,
740
+ inserted: inserted.toString()
741
+ })));
742
+ return changes2;
743
+ }).filter(Boolean);
744
+ if (changes.length) {
745
+ log.info("changes", {
746
+ changes
747
+ }, {
748
+ F: __dxlog_file,
749
+ L: 62,
750
+ S: void 0,
751
+ C: (f, a) => f(...a)
752
+ });
753
+ }
754
+ };
755
+
756
+ // packages/ui/react-ui-editor/src/util/dom.ts
757
+ var flattenRect = (rect, left) => {
758
+ const x = left ? rect.left : rect.right;
759
+ return {
760
+ left: x,
761
+ right: x,
762
+ top: rect.top,
763
+ bottom: rect.bottom
764
+ };
765
+ };
766
+ var scratchRange;
767
+ var textRange = (node, from, to = from) => {
768
+ const range = scratchRange || (scratchRange = document.createRange());
769
+ range.setEnd(node, to);
770
+ range.setStart(node, from);
771
+ return range;
772
+ };
773
+ var clientRectsFor = (dom) => {
774
+ if (dom.nodeType === 3) {
775
+ return textRange(dom, 0, dom.nodeValue.length).getClientRects();
776
+ } else if (dom.nodeType === 1) {
777
+ return dom.getClientRects();
778
+ } else {
779
+ return [];
780
+ }
781
+ };
782
+
783
+ // packages/ui/react-ui-editor/src/util/react.tsx
784
+ import React2 from "react";
785
+ import { createRoot } from "react-dom/client";
786
+ import { ThemeProvider } from "@dxos/react-ui";
787
+ import { defaultTx } from "@dxos/react-ui-theme";
788
+ var createElement = (tag, options, children) => {
789
+ const el = document.createElement(tag);
790
+ if (options?.className) {
791
+ el.className = options.className;
792
+ }
793
+ if (children) {
794
+ el.append(...Array.isArray(children) ? children : [
795
+ children
796
+ ]);
797
+ }
798
+ return el;
799
+ };
800
+ var renderRoot = (root, node) => {
801
+ createRoot(root).render(/* @__PURE__ */ React2.createElement(ThemeProvider, {
802
+ tx: defaultTx
803
+ }, node));
804
+ return root;
805
+ };
806
+
807
+ // packages/ui/react-ui-editor/src/extensions/annotations.ts
808
+ var annotationMark = Decoration.mark({
809
+ class: "cm-annotation"
810
+ });
811
+ var annotations = (options = {}) => {
812
+ const match = (state) => {
813
+ const annotations2 = [];
814
+ const text = state.doc.toString();
815
+ if (options.match) {
816
+ const matches = text.matchAll(options.match);
817
+ for (const match2 of matches) {
818
+ const from = match2.index;
819
+ const to = from + match2[0].length;
820
+ const cursor = Cursor.getCursorFromRange(state, {
821
+ from,
822
+ to
823
+ });
824
+ annotations2.push({
825
+ cursor
826
+ });
827
+ }
828
+ }
829
+ return annotations2;
830
+ };
831
+ const annotationsState = StateField.define({
832
+ create: (state) => {
833
+ return match(state);
834
+ },
835
+ update: (value, tr) => {
836
+ if (!tr.changes.empty) {
837
+ return match(tr.state);
838
+ }
839
+ return value;
840
+ }
841
+ });
842
+ return [
843
+ annotationsState,
844
+ EditorView2.decorations.compute([
845
+ annotationsState
846
+ ], (state) => {
847
+ const annotations2 = state.field(annotationsState);
848
+ const decorations = annotations2.map((annotation) => {
849
+ const range = Cursor.getRangeFromCursor(state, annotation.cursor);
850
+ return range && annotationMark.range(range.from, range.to);
851
+ }).filter(isNotFalsy);
852
+ return Decoration.set(decorations);
853
+ }),
854
+ styles
855
+ ];
856
+ };
857
+ var styles = EditorView2.theme({
858
+ ".cm-annotation": {
859
+ textDecoration: "underline",
860
+ textDecorationStyle: "wavy",
861
+ textDecorationColor: "var(--dx-error)"
862
+ }
863
+ });
864
+
865
+ // packages/ui/react-ui-editor/src/extensions/autocomplete.ts
866
+ import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
867
+ import { markdownLanguage } from "@codemirror/lang-markdown";
868
+ import { keymap } from "@codemirror/view";
869
+ var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
870
+ const extensions = [
871
+ // https://codemirror.net/docs/ref/#view.keymap
872
+ // https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
873
+ // TODO(burdon): Set custom keymap.
874
+ keymap.of(completionKeymap),
875
+ // https://codemirror.net/examples/autocompletion
876
+ // https://codemirror.net/docs/ref/#autocomplete.autocompletion
877
+ autocompletion({
878
+ activateOnTyping,
879
+ override,
880
+ closeOnBlur: !debug,
881
+ tooltipClass: () => "shadow rounded"
882
+ })
883
+ ];
884
+ if (onSearch) {
885
+ extensions.push(
886
+ // TODO(burdon): Optional decoration via addToOptions
887
+ markdownLanguage.data.of({
888
+ autocomplete: (context) => {
889
+ const match = context.matchBefore(/\w*/);
890
+ if (!match || match.from === match.to && !context.explicit) {
891
+ return null;
295
892
  }
296
893
  return {
297
894
  from: match.from,
@@ -306,7 +903,7 @@ var autocomplete = ({ debug, activateOnTyping, override, onSearch } = {}) => {
306
903
 
307
904
  // packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
308
905
  import { StateField as StateField2 } from "@codemirror/state";
309
- import { EditorView as EditorView2, ViewPlugin } from "@codemirror/view";
906
+ import { EditorView as EditorView3, ViewPlugin } from "@codemirror/view";
310
907
  import { next as A3 } from "@dxos/automerge/automerge";
311
908
 
312
909
  // packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
@@ -590,7 +1187,7 @@ var automerge = (accessor) => {
590
1187
  }
591
1188
  }),
592
1189
  // Reconcile local updates.
593
- EditorView2.updateListener.of(({ view, changes }) => {
1190
+ EditorView3.updateListener.of(({ view, changes }) => {
594
1191
  if (!changes.empty) {
595
1192
  syncer.reconcile(view, true);
596
1193
  }
@@ -600,7 +1197,7 @@ var automerge = (accessor) => {
600
1197
 
601
1198
  // packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts
602
1199
  import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
603
- import { Decoration as Decoration2, EditorView as EditorView3, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
1200
+ import { Decoration as Decoration2, EditorView as EditorView4, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
604
1201
  import { Event } from "@dxos/async";
605
1202
  import { Context } from "@dxos/context";
606
1203
  var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts";
@@ -774,7 +1371,7 @@ var RemoteCaretWidget = class extends WidgetType {
774
1371
  return true;
775
1372
  }
776
1373
  };
777
- var styles2 = EditorView3.theme({
1374
+ var styles2 = EditorView4.theme({
778
1375
  ".cm-collab-selection": {},
779
1376
  ".cm-collab-selectionLine": {
780
1377
  padding: 0,
@@ -940,7 +1537,7 @@ var SpaceAwarenessProvider = class {
940
1537
  };
941
1538
 
942
1539
  // packages/ui/react-ui-editor/src/extensions/blast.ts
943
- import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
1540
+ import { EditorView as EditorView5, keymap as keymap2 } from "@codemirror/view";
944
1541
  import defaultsDeep from "lodash.defaultsdeep";
945
1542
  import { invariant as invariant2 } from "@dxos/invariant";
946
1543
  var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
@@ -988,7 +1585,7 @@ var blast = (options = defaultOptions) => {
988
1585
  };
989
1586
  return [
990
1587
  // Cursor moved.
991
- EditorView4.updateListener.of((update2) => {
1588
+ EditorView5.updateListener.of((update2) => {
992
1589
  if (blaster?.node !== update2.view.scrollDOM) {
993
1590
  if (blaster) {
994
1591
  blaster.destroy();
@@ -1250,11 +1847,11 @@ var random = (min, max) => {
1250
1847
  };
1251
1848
 
1252
1849
  // packages/ui/react-ui-editor/src/extensions/command/command.ts
1253
- import { EditorView as EditorView6, keymap as keymap3 } from "@codemirror/view";
1850
+ import { EditorView as EditorView7, keymap as keymap3 } from "@codemirror/view";
1254
1851
 
1255
1852
  // packages/ui/react-ui-editor/src/extensions/command/hint.ts
1256
1853
  import { RangeSetBuilder } from "@codemirror/state";
1257
- import { Decoration as Decoration3, EditorView as EditorView5, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
1854
+ import { Decoration as Decoration3, EditorView as EditorView6, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
1258
1855
 
1259
1856
  // packages/ui/react-ui-editor/src/extensions/command/state.ts
1260
1857
  import { StateEffect as StateEffect2, StateField as StateField3 } from "@codemirror/state";
@@ -1420,7 +2017,7 @@ var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
1420
2017
  }
1421
2018
  }, {
1422
2019
  provide: (plugin) => [
1423
- EditorView5.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
2020
+ EditorView6.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
1424
2021
  ]
1425
2022
  });
1426
2023
 
@@ -1431,7 +2028,7 @@ var command = (options) => {
1431
2028
  commandState,
1432
2029
  keymap3.of(commandKeyBindings),
1433
2030
  hintViewPlugin(options),
1434
- EditorView6.focusChangeEffect.of((_, focusing) => {
2031
+ EditorView7.focusChangeEffect.of((_, focusing) => {
1435
2032
  return focusing ? closeEffect.of(null) : null;
1436
2033
  })
1437
2034
  ];
@@ -1440,16 +2037,16 @@ var command = (options) => {
1440
2037
  // packages/ui/react-ui-editor/src/extensions/comments.ts
1441
2038
  import { invertedEffects } from "@codemirror/commands";
1442
2039
  import { StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
1443
- import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as EditorView8, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
2040
+ import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as EditorView9, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
1444
2041
  import sortBy from "lodash.sortby";
1445
- import { useEffect, useMemo, useState } from "react";
2042
+ import { useEffect, useMemo as useMemo2 } from "react";
1446
2043
  import { debounce as debounce2 } from "@dxos/async";
1447
2044
  import { log as log4 } from "@dxos/log";
1448
2045
  import { nonNullable } from "@dxos/util";
1449
2046
 
1450
2047
  // packages/ui/react-ui-editor/src/extensions/selection.ts
1451
2048
  import { Transaction } from "@codemirror/state";
1452
- import { EditorView as EditorView7, keymap as keymap4 } from "@codemirror/view";
2049
+ import { EditorView as EditorView8, keymap as keymap4 } from "@codemirror/view";
1453
2050
  import { debounce } from "@dxos/async";
1454
2051
  import { invariant as invariant3 } from "@dxos/invariant";
1455
2052
  import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
@@ -1460,7 +2057,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
1460
2057
  return {
1461
2058
  selection,
1462
2059
  scrollIntoView: !scrollTo,
1463
- effects: scrollTo ? EditorView7.scrollIntoView(scrollTo, {
2060
+ effects: scrollTo ? EditorView8.scrollIntoView(scrollTo, {
1464
2061
  yMargin: 96
1465
2062
  }) : void 0,
1466
2063
  annotations: Transaction.userEvent.of(stateRestoreAnnotation)
@@ -1502,7 +2099,7 @@ var selectionState = ({ getState, setState } = {}) => {
1502
2099
  // setStateDebounced(id, {});
1503
2100
  // },
1504
2101
  // }),
1505
- EditorView7.updateListener.of(({ view, transactions }) => {
2102
+ EditorView8.updateListener.of(({ view, transactions }) => {
1506
2103
  const id = view.state.facet(documentId);
1507
2104
  if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
1508
2105
  return;
@@ -1583,7 +2180,7 @@ var commentsState = StateField4.define({
1583
2180
  return value;
1584
2181
  }
1585
2182
  });
1586
- var styles3 = EditorView8.theme({
2183
+ var styles3 = EditorView9.theme({
1587
2184
  ".cm-comment, .cm-comment-current": {
1588
2185
  margin: "0 -3px",
1589
2186
  padding: "3px",
@@ -1603,7 +2200,7 @@ var createCommentMark = (id, isCurrent) => Decoration4.mark({
1603
2200
  "data-comment-id": id
1604
2201
  }
1605
2202
  });
1606
- var commentsDecorations = EditorView8.decorations.compute([
2203
+ var commentsDecorations = EditorView9.decorations.compute([
1607
2204
  commentsState
1608
2205
  ], (state) => {
1609
2206
  const { selection: { current }, comments: comments2 } = state.field(commentsState);
@@ -1612,7 +2209,7 @@ var commentsDecorations = EditorView8.decorations.compute([
1612
2209
  if (!range) {
1613
2210
  log4.warn("Invalid range:", range, {
1614
2211
  F: __dxlog_file7,
1615
- L: 142,
2212
+ L: 144,
1616
2213
  S: void 0,
1617
2214
  C: (f, a) => f(...a)
1618
2215
  });
@@ -1626,7 +2223,7 @@ var commentsDecorations = EditorView8.decorations.compute([
1626
2223
  return Decoration4.set(decorations);
1627
2224
  });
1628
2225
  var commentClickedEffect = StateEffect3.define();
1629
- var handleCommentClick = EditorView8.domEventHandlers({
2226
+ var handleCommentClick = EditorView9.domEventHandlers({
1630
2227
  click: (event, view) => {
1631
2228
  let target = event.target;
1632
2229
  const editorRoot = view.dom;
@@ -1665,7 +2262,7 @@ var trackPastedComments = (onUpdate) => {
1665
2262
  }
1666
2263
  };
1667
2264
  return [
1668
- EditorView8.domEventHandlers({
2265
+ EditorView9.domEventHandlers({
1669
2266
  cut: handleTrack,
1670
2267
  copy: handleTrack
1671
2268
  }),
@@ -1687,7 +2284,7 @@ var trackPastedComments = (onUpdate) => {
1687
2284
  return effects;
1688
2285
  }),
1689
2286
  // Handle paste or the undo of comment deletion.
1690
- EditorView8.updateListener.of((update2) => {
2287
+ EditorView9.updateListener.of((update2) => {
1691
2288
  const restore = [];
1692
2289
  for (let i = 0; i < update2.transactions.length; i++) {
1693
2290
  const tr = update2.transactions[i];
@@ -1746,7 +2343,7 @@ var mapTrackedComment = (comment, changes) => ({
1746
2343
  var restoreCommentEffect = StateEffect3.define({
1747
2344
  map: mapTrackedComment
1748
2345
  });
1749
- var createComment = (view) => {
2346
+ var createComment2 = (view) => {
1750
2347
  const options = view.state.facet(optionsFacet);
1751
2348
  const { from, to } = view.state.selection.main;
1752
2349
  if (from === to) {
@@ -1791,7 +2388,7 @@ var comments = (options = {}) => {
1791
2388
  options.onCreate && keymap5.of([
1792
2389
  {
1793
2390
  key: shortcut,
1794
- run: callbackWrapper(createComment)
2391
+ run: callbackWrapper(createComment2)
1795
2392
  }
1796
2393
  ]),
1797
2394
  //
@@ -1827,7 +2424,7 @@ var comments = (options = {}) => {
1827
2424
  //
1828
2425
  // Track deleted ranges and update ranges for decorations.
1829
2426
  //
1830
- EditorView8.updateListener.of(({ view, state, changes }) => {
2427
+ EditorView9.updateListener.of(({ view, state, changes }) => {
1831
2428
  let mod = false;
1832
2429
  const { comments: comments2, ...value } = state.field(commentsState);
1833
2430
  changes.iterChanges((from, to, from2, to2) => {
@@ -1859,7 +2456,7 @@ var comments = (options = {}) => {
1859
2456
  //
1860
2457
  // Track selection/proximity.
1861
2458
  //
1862
- EditorView8.updateListener.of(({ view, state }) => {
2459
+ EditorView9.updateListener.of(({ view, state }) => {
1863
2460
  let min = Infinity;
1864
2461
  const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
1865
2462
  const { head } = state.selection.main;
@@ -1913,7 +2510,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
1913
2510
  anchor: range.from
1914
2511
  } : void 0,
1915
2512
  effects: [
1916
- needsScroll ? EditorView8.scrollIntoView(range.from, center ? {
2513
+ needsScroll ? EditorView9.scrollIntoView(range.from, center ? {
1917
2514
  y: "center"
1918
2515
  } : void 0) : [],
1919
2516
  needsSelectionUpdate ? setSelection.of({
@@ -1924,415 +2521,179 @@ var scrollThreadIntoView = (view, id, center = true) => {
1924
2521
  }
1925
2522
  }
1926
2523
  };
1927
- var selectionOverlapsComment = (state) => {
1928
- const commentState = state.field(commentsState, false);
1929
- if (commentState === void 0) {
1930
- return false;
1931
- }
1932
- const { selection } = state;
1933
- for (const range of selection.ranges) {
1934
- if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
1935
- return true;
1936
- }
1937
- }
1938
- return false;
1939
- };
1940
- var hasActiveSelection = (state) => {
1941
- return state.selection.ranges.some((range) => !range.empty);
1942
- };
1943
- var ExternalCommentSync = class {
1944
- constructor(view, id, subscribe, getComments) {
1945
- this.destroy = () => {
1946
- this.unsubscribe();
1947
- };
1948
- const updateComments = () => {
1949
- const comments2 = getComments();
1950
- if (id === view.state.facet(documentId)) {
1951
- queueMicrotask(() => view.dispatch({
1952
- effects: setComments.of({
1953
- id,
1954
- comments: comments2
1955
- })
1956
- }));
1957
- }
1958
- };
1959
- this.unsubscribe = subscribe(updateComments);
1960
- }
1961
- };
1962
- var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin4.fromClass(class {
1963
- constructor(view) {
1964
- return new ExternalCommentSync(view, id, subscribe, getComments);
1965
- }
1966
- });
1967
- var useCommentState = () => {
1968
- const [state, setState] = useState({
1969
- comment: false,
1970
- selection: false
1971
- });
1972
- const observer = useMemo(() => EditorView8.updateListener.of((update2) => {
1973
- if (update2.docChanged || update2.selectionSet) {
1974
- setState({
1975
- comment: selectionOverlapsComment(update2.state),
1976
- selection: hasActiveSelection(update2.state)
1977
- });
1978
- }
1979
- }), []);
1980
- return [
1981
- state,
1982
- observer
1983
- ];
1984
- };
1985
- var useComments = (view, id, comments2) => {
1986
- useEffect(() => {
1987
- if (view) {
1988
- if (id === view.state.facet(documentId)) {
1989
- view.dispatch({
1990
- effects: setComments.of({
1991
- id,
1992
- comments: comments2 ?? []
1993
- })
1994
- });
1995
- }
1996
- }
1997
- });
1998
- };
1999
- var useCommentClickListener = (onCommentClick) => {
2000
- return useMemo(() => EditorView8.updateListener.of((update2) => {
2001
- update2.transactions.forEach((transaction) => {
2002
- transaction.effects.forEach((effect) => {
2003
- if (effect.is(commentClickedEffect)) {
2004
- onCommentClick(effect.value);
2005
- }
2006
- });
2007
- });
2008
- }), [
2009
- onCommentClick
2010
- ]);
2011
- };
2012
-
2013
- // packages/ui/react-ui-editor/src/extensions/debug.ts
2014
- import { syntaxTree } from "@codemirror/language";
2015
- import { StateField as StateField5 } from "@codemirror/state";
2016
- var debugNodeLogger = (log8 = console.log) => {
2017
- const logTokens = (state) => syntaxTree(state).iterate({
2018
- enter: (node) => log8(node.type)
2019
- });
2020
- return StateField5.define({
2021
- create: (state) => logTokens(state),
2022
- update: (_, tr) => logTokens(tr.state)
2023
- });
2024
- };
2025
-
2026
- // packages/ui/react-ui-editor/src/extensions/dnd.ts
2027
- import { dropCursor, EditorView as EditorView9 } from "@codemirror/view";
2028
- var styles4 = EditorView9.theme({
2029
- ".cm-dropCursor": {
2030
- borderLeft: "2px solid var(--dx-accentText)",
2031
- color: "var(--dx-accentText)",
2032
- padding: "0 4px"
2033
- },
2034
- ".cm-dropCursor:after": {
2035
- content: '"\u2190"'
2036
- }
2037
- });
2038
- var dropFile = (options = {}) => {
2039
- return [
2040
- styles4,
2041
- dropCursor(),
2042
- EditorView9.domEventHandlers({
2043
- drop: (event, view) => {
2044
- event.preventDefault();
2045
- const files = event.dataTransfer?.files;
2046
- const pos = view.posAtCoords(event);
2047
- if (files?.length && pos !== null) {
2048
- view.dispatch({
2049
- selection: {
2050
- anchor: pos
2051
- }
2052
- });
2053
- options.onDrop?.(view, {
2054
- files
2055
- });
2056
- }
2057
- }
2058
- })
2059
- ];
2060
- };
2061
-
2062
- // packages/ui/react-ui-editor/src/extensions/factories.ts
2063
- import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
2064
- import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
2065
- import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
2066
- import { searchKeymap } from "@codemirror/search";
2067
- import { EditorState } from "@codemirror/state";
2068
- import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
2069
- import { EditorView as EditorView11, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
2070
- import defaultsDeep2 from "lodash.defaultsdeep";
2071
- import merge from "lodash.merge";
2072
- import { generateName } from "@dxos/display-name";
2073
- import { log as log5 } from "@dxos/log";
2074
- import { hueTokens } from "@dxos/react-ui-theme";
2075
- import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
2076
-
2077
- // packages/ui/react-ui-editor/src/extensions/focus.ts
2078
- import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
2079
- import { EditorView as EditorView10 } from "@codemirror/view";
2080
- var focusEffect = StateEffect4.define();
2081
- var focusField = StateField6.define({
2082
- create: () => false,
2083
- update: (value, tr) => {
2084
- for (const effect of tr.effects) {
2085
- if (effect.is(focusEffect)) {
2086
- return effect.value;
2087
- }
2088
- }
2089
- return value;
2090
- }
2091
- });
2092
- var focus = [
2093
- focusField,
2094
- EditorView10.domEventHandlers({
2095
- focus: (event, view) => {
2096
- setTimeout(() => view.dispatch({
2097
- effects: focusEffect.of(true)
2098
- }));
2099
- },
2100
- blur: (event, view) => {
2101
- setTimeout(() => view.dispatch({
2102
- effects: focusEffect.of(false)
2103
- }));
2104
- }
2105
- })
2106
- ];
2107
-
2108
- // packages/ui/react-ui-editor/src/styles/markdown.ts
2109
- import { mx } from "@dxos/react-ui-theme";
2110
- var headings = {
2111
- 1: "text-4xl",
2112
- 2: "text-3xl",
2113
- 3: "text-2xl",
2114
- 4: "text-xl",
2115
- 5: "text-lg",
2116
- 6: "text-md"
2117
- };
2118
- var theme = {
2119
- code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
2120
- codeMark: "font-mono text-primary-500",
2121
- mark: "opacity-50",
2122
- heading: (level) => {
2123
- return mx(headings[level], "dark:text-primary-400");
2124
- }
2125
- };
2126
-
2127
- // packages/ui/react-ui-editor/src/styles/tokens.ts
2128
- import get from "lodash.get";
2129
- import { tokens } from "@dxos/react-ui-theme";
2130
- var getToken = (path, defaultValue) => {
2131
- const value = get(tokens, path, defaultValue);
2132
- return value?.toString() ?? "";
2133
- };
2134
- var fontBody = getToken("fontFamily.body");
2135
- var fontMono = getToken("fontFamily.mono");
2136
-
2137
- // packages/ui/react-ui-editor/src/styles/theme.ts
2138
- var defaultTheme = {
2139
- "&": {},
2140
- "&.cm-focused": {
2141
- outline: "none"
2142
- },
2143
- /**
2144
- * Scroller
2145
- */
2146
- ".cm-scroller": {
2147
- overflowY: "auto"
2148
- },
2149
- /**
2150
- * Content
2151
- * NOTE: Apply margins to content so that scrollbar is at the edge of the container.
2152
- */
2153
- ".cm-content": {
2154
- padding: "unset",
2155
- fontFamily: fontBody,
2156
- // NOTE: Base font size (otherwise defined by HTML tag, which might be different for storybook).
2157
- fontSize: "16px",
2158
- lineHeight: 1.5,
2159
- color: "unset"
2160
- },
2161
- /**
2162
- * Gutters
2163
- * NOTE: Gutters should have the same top margin as the content.
2164
- * NOTE: They can't be transparent since the content needs to scroll below.
2165
- */
2166
- ".cm-gutters": {
2167
- background: "var(--surface-bg)",
2168
- borderRight: "none"
2169
- },
2170
- ".cm-gutter": {},
2171
- ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
2172
- minWidth: "40px",
2173
- alignContent: "center"
2174
- },
2175
- /**
2176
- * Height is set to match the corresponding line.
2177
- */
2178
- ".cm-gutterElement": {
2179
- alignItems: "center",
2180
- fontSize: "16px"
2181
- },
2182
- /**
2183
- * Line.
2184
- */
2185
- ".cm-line": {
2186
- paddingInline: 0
2187
- },
2188
- ".cm-activeLine": {
2189
- background: "var(--dx-cmActiveLine)"
2190
- },
2191
- /**
2192
- * Cursor (layer).
2193
- */
2194
- ".cm-cursor, .cm-dropCursor": {
2195
- borderLeft: "2px solid var(--dx-cmCursor)"
2196
- },
2197
- ".cm-placeholder": {
2198
- color: "var(--dx-subdued)"
2199
- },
2200
- /**
2201
- * Selection (layer).
2202
- */
2203
- ".cm-selectionBackground": {
2204
- background: "var(--dx-cmSelection)"
2205
- },
2206
- /**
2207
- * Search.
2208
- * NOTE: Matches comment.
2209
- */
2210
- ".cm-searchMatch": {
2211
- margin: "0 -3px",
2212
- padding: "3px",
2213
- borderRadius: "3px",
2214
- background: "var(--dx-cmHighlightSurface)",
2215
- color: "var(--dx-cmHighlight)"
2216
- },
2217
- ".cm-searchMatch-selected": {
2218
- textDecoration: "underline"
2219
- },
2220
- /**
2221
- * Link.
2222
- */
2223
- ".cm-link": {
2224
- textDecorationLine: "underline",
2225
- textDecorationThickness: "1px",
2226
- textUnderlineOffset: "2px",
2227
- borderRadius: ".125rem"
2228
- },
2229
- ".cm-link > span": {
2230
- color: "var(--dx-accentText)"
2231
- },
2232
- /**
2233
- * Tooltip.
2234
- */
2235
- ".cm-tooltip": {
2236
- background: "var(--dx-base)"
2237
- },
2238
- ".cm-tooltip-below": {},
2239
- /**
2240
- * Autocomplete.
2241
- * https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
2242
- */
2243
- ".cm-tooltip.cm-tooltip-autocomplete": {
2244
- marginTop: "4px",
2245
- marginLeft: "-3px"
2246
- },
2247
- ".cm-tooltip.cm-tooltip-autocomplete > ul": {
2248
- maxHeight: "20em"
2249
- },
2250
- ".cm-tooltip.cm-tooltip-autocomplete > ul > li": {},
2251
- ".cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]": {},
2252
- ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
2253
- paddingLeft: "4px !important",
2254
- borderBottom: "none !important",
2255
- color: "var(--dx-accentText)"
2256
- },
2257
- ".cm-tooltip.cm-completionInfo": {
2258
- width: "360px !important",
2259
- margin: "-10px 1px 0 1px",
2260
- padding: "8px !important",
2261
- borderColor: "var(--dx-separator)"
2262
- },
2263
- ".cm-completionIcon": {
2264
- display: "none"
2265
- },
2266
- ".cm-completionLabel": {
2267
- fontFamily: fontBody
2268
- },
2269
- ".cm-completionMatchedText": {
2270
- textDecoration: "none !important",
2271
- opacity: 0.5
2272
- },
2273
- /**
2274
- * Panels
2275
- * https://github.com/codemirror/search/blob/main/src/search.ts#L745
2276
- *
2277
- * Find/replace panel.
2278
- * <div class="cm-announced">...</div>
2279
- * <div class="cm-scroller">...</div>
2280
- * <div class="cm-panels cm-panels-bottom">
2281
- * <div class="cm-search cm-panel">
2282
- * <input class="cm-textfield" />
2283
- * <button class="cm-button">...</button>
2284
- * <label><input type="checkbox" />...</label>
2285
- * </div>
2286
- * </div
2287
- */
2288
- // TODO(burdon): Implement custom panel (with icon buttons).
2289
- ".cm-panels": {},
2290
- ".cm-panel": {
2291
- fontFamily: fontBody,
2292
- backgroundColor: "var(--surface-bg)"
2293
- },
2294
- ".cm-panel input, .cm-panel button, .cm-panel label": {
2295
- color: "var(--dx-subdued)",
2296
- fontFamily: fontBody,
2297
- fontSize: "14px",
2298
- all: "unset",
2299
- margin: "3px !important",
2300
- padding: "2px 6px !important",
2301
- outline: "1px solid transparent"
2302
- },
2303
- ".cm-panel input, .cm-panel button": {
2304
- backgroundColor: "var(--dx-input)"
2305
- },
2306
- ".cm-panel input:focus, .cm-panel button:focus": {
2307
- outline: "1px solid var(--dx-accentFocusIndicator)"
2308
- },
2309
- ".cm-panel label": {
2310
- display: "inline-flex",
2311
- alignItems: "center",
2312
- cursor: "pointer"
2313
- },
2314
- ".cm-panel input.cm-textfield": {},
2315
- ".cm-panel input[type=checkbox]": {
2316
- width: "8px",
2317
- height: "8px",
2318
- marginRight: "6px !important",
2319
- padding: "2px !important",
2320
- color: "var(--dx-accentFocusIndicator)"
2321
- },
2322
- ".cm-panel button": {
2323
- "&:hover": {
2324
- backgroundColor: "var(--dx-accentSurfaceHover) !important"
2325
- },
2326
- "&:active": {
2327
- backgroundColor: "var(--dx-accentSurfaceHover)"
2524
+ var selectionOverlapsComment = (state) => {
2525
+ const commentState = state.field(commentsState, false);
2526
+ if (commentState === void 0) {
2527
+ return false;
2528
+ }
2529
+ const { selection } = state;
2530
+ for (const range of selection.ranges) {
2531
+ if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
2532
+ return true;
2533
+ }
2534
+ }
2535
+ return false;
2536
+ };
2537
+ var hasActiveSelection = (state) => {
2538
+ return state.selection.ranges.some((range) => !range.empty);
2539
+ };
2540
+ var ExternalCommentSync = class {
2541
+ constructor(view, id, subscribe, getComments) {
2542
+ this.destroy = () => {
2543
+ this.unsubscribe();
2544
+ };
2545
+ const updateComments = () => {
2546
+ const comments2 = getComments();
2547
+ if (id === view.state.facet(documentId)) {
2548
+ queueMicrotask(() => view.dispatch({
2549
+ effects: setComments.of({
2550
+ id,
2551
+ comments: comments2
2552
+ })
2553
+ }));
2554
+ }
2555
+ };
2556
+ this.unsubscribe = subscribe(updateComments);
2557
+ }
2558
+ };
2559
+ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin4.fromClass(class {
2560
+ constructor(view) {
2561
+ return new ExternalCommentSync(view, id, subscribe, getComments);
2562
+ }
2563
+ });
2564
+ var useCommentState = (state) => {
2565
+ return useMemo2(() => EditorView9.updateListener.of((update2) => {
2566
+ if (update2.docChanged || update2.selectionSet) {
2567
+ state.comment = selectionOverlapsComment(update2.state);
2568
+ state.selection = hasActiveSelection(update2.state);
2569
+ }
2570
+ }), [
2571
+ state
2572
+ ]);
2573
+ };
2574
+ var useComments = (view, id, comments2) => {
2575
+ useEffect(() => {
2576
+ if (view) {
2577
+ if (id === view.state.facet(documentId)) {
2578
+ view.dispatch({
2579
+ effects: setComments.of({
2580
+ id,
2581
+ comments: comments2 ?? []
2582
+ })
2583
+ });
2584
+ }
2328
2585
  }
2586
+ });
2587
+ };
2588
+ var useCommentClickListener = (onCommentClick) => {
2589
+ return useMemo2(() => EditorView9.updateListener.of((update2) => {
2590
+ update2.transactions.forEach((transaction) => {
2591
+ transaction.effects.forEach((effect) => {
2592
+ if (effect.is(commentClickedEffect)) {
2593
+ onCommentClick(effect.value);
2594
+ }
2595
+ });
2596
+ });
2597
+ }), [
2598
+ onCommentClick
2599
+ ]);
2600
+ };
2601
+
2602
+ // packages/ui/react-ui-editor/src/extensions/debug.ts
2603
+ import { syntaxTree } from "@codemirror/language";
2604
+ import { StateField as StateField5 } from "@codemirror/state";
2605
+ var debugNodeLogger = (log8 = console.log) => {
2606
+ const logTokens = (state) => syntaxTree(state).iterate({
2607
+ enter: (node) => log8(node.type)
2608
+ });
2609
+ return StateField5.define({
2610
+ create: (state) => logTokens(state),
2611
+ update: (_, tr) => logTokens(tr.state)
2612
+ });
2613
+ };
2614
+
2615
+ // packages/ui/react-ui-editor/src/extensions/dnd.ts
2616
+ import { dropCursor, EditorView as EditorView10 } from "@codemirror/view";
2617
+ var styles4 = EditorView10.theme({
2618
+ ".cm-dropCursor": {
2619
+ borderLeft: "2px solid var(--dx-accentText)",
2620
+ color: "var(--dx-accentText)",
2621
+ padding: "0 4px"
2329
2622
  },
2330
- ".cm-panel.cm-search": {
2331
- padding: "4px",
2332
- borderTop: "1px solid var(--dx-separator)"
2623
+ ".cm-dropCursor:after": {
2624
+ content: '"\u2190"'
2333
2625
  }
2626
+ });
2627
+ var dropFile = (options = {}) => {
2628
+ return [
2629
+ styles4,
2630
+ dropCursor(),
2631
+ EditorView10.domEventHandlers({
2632
+ drop: (event, view) => {
2633
+ event.preventDefault();
2634
+ const files = event.dataTransfer?.files;
2635
+ const pos = view.posAtCoords(event);
2636
+ if (files?.length && pos !== null) {
2637
+ view.dispatch({
2638
+ selection: {
2639
+ anchor: pos
2640
+ }
2641
+ });
2642
+ options.onDrop?.(view, {
2643
+ files
2644
+ });
2645
+ }
2646
+ }
2647
+ })
2648
+ ];
2334
2649
  };
2335
2650
 
2651
+ // packages/ui/react-ui-editor/src/extensions/factories.ts
2652
+ import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
2653
+ import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
2654
+ import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
2655
+ import { searchKeymap } from "@codemirror/search";
2656
+ import { EditorState } from "@codemirror/state";
2657
+ import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
2658
+ import { EditorView as EditorView12, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
2659
+ import defaultsDeep2 from "lodash.defaultsdeep";
2660
+ import merge from "lodash.merge";
2661
+ import { generateName } from "@dxos/display-name";
2662
+ import { log as log5 } from "@dxos/log";
2663
+ import { hueTokens } from "@dxos/react-ui-theme";
2664
+ import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
2665
+
2666
+ // packages/ui/react-ui-editor/src/extensions/focus.ts
2667
+ import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
2668
+ import { EditorView as EditorView11 } from "@codemirror/view";
2669
+ var focusEffect = StateEffect4.define();
2670
+ var focusField = StateField6.define({
2671
+ create: () => false,
2672
+ update: (value, tr) => {
2673
+ for (const effect of tr.effects) {
2674
+ if (effect.is(focusEffect)) {
2675
+ return effect.value;
2676
+ }
2677
+ }
2678
+ return value;
2679
+ }
2680
+ });
2681
+ var focus = [
2682
+ focusField,
2683
+ EditorView11.domEventHandlers({
2684
+ focus: (event, view) => {
2685
+ setTimeout(() => view.dispatch({
2686
+ effects: focusEffect.of(true)
2687
+ }));
2688
+ },
2689
+ blur: (event, view) => {
2690
+ setTimeout(() => view.dispatch({
2691
+ effects: focusEffect.of(false)
2692
+ }));
2693
+ }
2694
+ })
2695
+ ];
2696
+
2336
2697
  // packages/ui/react-ui-editor/src/extensions/factories.ts
2337
2698
  var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
2338
2699
  var preventNewline = EditorState.transactionFilter.of((tr) => tr.newDoc.lines > 1 ? [] : tr);
@@ -2358,7 +2719,7 @@ var createBasicExtensions = (_props) => {
2358
2719
  const props = defaultsDeep2({}, _props, defaultBasicOptions);
2359
2720
  return [
2360
2721
  // NOTE: Doesn't catch errors in keymap functions.
2361
- EditorView11.exceptionSink.of((err) => {
2722
+ EditorView12.exceptionSink.of((err) => {
2362
2723
  log5.catch(err, void 0, {
2363
2724
  F: __dxlog_file8,
2364
2725
  L: 96,
@@ -2377,11 +2738,11 @@ var createBasicExtensions = (_props) => {
2377
2738
  props.highlightActiveLine && highlightActiveLine(),
2378
2739
  props.history && history(),
2379
2740
  props.lineNumbers && lineNumbers(),
2380
- props.lineWrapping && EditorView11.lineWrapping,
2741
+ props.lineWrapping && EditorView12.lineWrapping,
2381
2742
  props.placeholder && placeholder(props.placeholder),
2382
2743
  props.readonly && [
2383
2744
  EditorState.readOnly.of(true),
2384
- EditorView11.editable.of(false)
2745
+ EditorView12.editable.of(false)
2385
2746
  ],
2386
2747
  props.scrollPastEnd && scrollPastEnd(),
2387
2748
  props.tabSize && EditorState.tabSize.of(props.tabSize),
@@ -2410,14 +2771,14 @@ var defaultThemeSlots = {
2410
2771
  var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
2411
2772
  const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
2412
2773
  return [
2413
- EditorView11.darkTheme.of(themeMode === "dark"),
2414
- EditorView11.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2774
+ EditorView12.darkTheme.of(themeMode === "dark"),
2775
+ EditorView12.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2415
2776
  // https://github.com/codemirror/theme-one-dark
2416
2777
  _syntaxHighlighting && (themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)),
2417
- slots.editor?.className && EditorView11.editorAttributes.of({
2778
+ slots.editor?.className && EditorView12.editorAttributes.of({
2418
2779
  class: slots.editor.className
2419
2780
  }),
2420
- slots.content?.className && EditorView11.contentAttributes.of({
2781
+ slots.content?.className && EditorView12.contentAttributes.of({
2421
2782
  class: slots.content.className
2422
2783
  })
2423
2784
  ].filter(isNotFalsy3);
@@ -2446,8 +2807,8 @@ var createDataExtensions = ({ id, text, space, identity }) => {
2446
2807
 
2447
2808
  // packages/ui/react-ui-editor/src/extensions/folding.tsx
2448
2809
  import { codeFolding, foldGutter } from "@codemirror/language";
2449
- import { EditorView as EditorView12 } from "@codemirror/view";
2450
- import React2 from "react";
2810
+ import { EditorView as EditorView13 } from "@codemirror/view";
2811
+ import React3 from "react";
2451
2812
  import { Icon } from "@dxos/react-ui";
2452
2813
  var folding = (_props = {}) => [
2453
2814
  codeFolding({
@@ -2460,7 +2821,7 @@ var folding = (_props = {}) => [
2460
2821
  const el = createElement("div", {
2461
2822
  className: "flex h-full items-center"
2462
2823
  });
2463
- return renderRoot(el, /* @__PURE__ */ React2.createElement(Icon, {
2824
+ return renderRoot(el, /* @__PURE__ */ React3.createElement(Icon, {
2464
2825
  icon: "ph--caret-right--regular",
2465
2826
  size: 3,
2466
2827
  classNames: [
@@ -2470,7 +2831,7 @@ var folding = (_props = {}) => [
2470
2831
  }));
2471
2832
  }
2472
2833
  }),
2473
- EditorView12.theme({
2834
+ EditorView13.theme({
2474
2835
  ".cm-foldGutter": {
2475
2836
  opacity: 0.3,
2476
2837
  transition: "opacity 0.3s",
@@ -2483,14 +2844,14 @@ var folding = (_props = {}) => [
2483
2844
  ];
2484
2845
 
2485
2846
  // packages/ui/react-ui-editor/src/extensions/listener.ts
2486
- import { EditorView as EditorView13 } from "@codemirror/view";
2847
+ import { EditorView as EditorView14 } from "@codemirror/view";
2487
2848
  var listener = ({ onFocus, onChange }) => {
2488
2849
  const extensions = [];
2489
- onFocus && extensions.push(EditorView13.focusChangeEffect.of((_, focusing) => {
2850
+ onFocus && extensions.push(EditorView14.focusChangeEffect.of((_, focusing) => {
2490
2851
  onFocus(focusing);
2491
2852
  return null;
2492
2853
  }));
2493
- onChange && extensions.push(EditorView13.updateListener.of((update2) => {
2854
+ onChange && extensions.push(EditorView14.updateListener.of((update2) => {
2494
2855
  onChange(update2.state.doc.toString(), update2.state.facet(documentId));
2495
2856
  }));
2496
2857
  return extensions;
@@ -2500,8 +2861,8 @@ var listener = ({ onFocus, onChange }) => {
2500
2861
  import { snippet } from "@codemirror/autocomplete";
2501
2862
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
2502
2863
  import { EditorSelection } from "@codemirror/state";
2503
- import { EditorView as EditorView14, keymap as keymap7 } from "@codemirror/view";
2504
- import { useMemo as useMemo2, useState as useState2 } from "react";
2864
+ import { EditorView as EditorView15, keymap as keymap7 } from "@codemirror/view";
2865
+ import { useMemo as useMemo3 } from "react";
2505
2866
  var formattingEquals = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
2506
2867
  var Inline;
2507
2868
  (function(Inline2) {
@@ -3588,65 +3949,56 @@ var getFormatting = (state) => {
3588
3949
  listStyle: listStyle || null
3589
3950
  };
3590
3951
  };
3591
- var useFormattingState = () => {
3592
- const [state, setState] = useState2();
3593
- const observer = useMemo2(() => EditorView14.updateListener.of((update2) => {
3952
+ var useFormattingState = (state) => {
3953
+ return useMemo3(() => EditorView15.updateListener.of((update2) => {
3594
3954
  if (update2.docChanged || update2.selectionSet) {
3595
- setState((prevState) => {
3596
- const newState = getFormatting(update2.state);
3597
- if (!prevState || !formattingEquals(prevState, newState)) {
3598
- return newState;
3599
- }
3600
- return prevState;
3955
+ Object.entries(getFormatting(update2.state)).forEach(([key, active]) => {
3956
+ state[key] = active;
3601
3957
  });
3602
3958
  }
3603
3959
  }), []);
3604
- return [
3605
- state,
3606
- observer
3607
- ];
3608
3960
  };
3609
3961
 
3610
- // packages/ui/react-ui-editor/src/extensions/markdown/action.ts
3611
- var processAction = (view, action) => {
3962
+ // packages/ui/react-ui-editor/src/extensions/markdown/editorAction.ts
3963
+ var processEditorPayload = (view, { type, data }) => {
3612
3964
  let inlineType, listType;
3613
- switch (action.type) {
3965
+ switch (type) {
3614
3966
  case "heading":
3615
- setHeading(parseInt(action.data))(view);
3967
+ setHeading(parseInt(data))(view);
3616
3968
  break;
3617
3969
  case "strong":
3618
3970
  case "emphasis":
3619
3971
  case "strikethrough":
3620
3972
  case "code":
3621
- inlineType = action.type === "strong" ? Inline.Strong : action.type === "emphasis" ? Inline.Emphasis : action.type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
3622
- (typeof action.data === "boolean" ? setStyle(inlineType, action.data) : toggleStyle(inlineType))(view);
3973
+ inlineType = type === "strong" ? Inline.Strong : type === "emphasis" ? Inline.Emphasis : type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
3974
+ (typeof data === "boolean" ? setStyle(inlineType, data) : toggleStyle(inlineType))(view);
3623
3975
  break;
3624
3976
  case "list-ordered":
3625
3977
  case "list-bullet":
3626
3978
  case "list-task":
3627
- listType = action.type === "list-ordered" ? List.Ordered : action.type === "list-bullet" ? List.Bullet : List.Task;
3628
- (action.data === false ? removeList(listType) : action.data === true ? addList(listType) : toggleList(listType))(view);
3979
+ listType = type === "list-ordered" ? List.Ordered : type === "list-bullet" ? List.Bullet : List.Task;
3980
+ (data === false ? removeList(listType) : data === true ? addList(listType) : toggleList(listType))(view);
3629
3981
  break;
3630
3982
  case "blockquote":
3631
- (action.data === false ? removeBlockquote : action.data === true ? addBlockquote : toggleBlockquote)(view);
3983
+ (data === false ? removeBlockquote : data === true ? addBlockquote : toggleBlockquote)(view);
3632
3984
  break;
3633
3985
  case "codeblock":
3634
- (action.data === false ? removeCodeblock : addCodeblock)(view);
3986
+ (data === false ? removeCodeblock : addCodeblock)(view);
3635
3987
  break;
3636
3988
  case "table":
3637
3989
  insertTable(view);
3638
3990
  break;
3639
3991
  case "link":
3640
- (action.data === false ? removeLink : addLink())(view);
3992
+ (data === false ? removeLink : addLink())(view);
3641
3993
  break;
3642
3994
  case "image":
3643
3995
  addLink({
3644
- url: action.data,
3996
+ url: data,
3645
3997
  image: true
3646
3998
  })(view);
3647
3999
  break;
3648
4000
  case "comment":
3649
- createComment(view);
4001
+ createComment2(view);
3650
4002
  break;
3651
4003
  }
3652
4004
  requestAnimationFrame(() => {
@@ -3910,9 +4262,9 @@ var convertTreeToJson = (state) => {
3910
4262
  // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
3911
4263
  import { syntaxTree as syntaxTree7 } from "@codemirror/language";
3912
4264
  import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect5 } from "@codemirror/state";
3913
- import { EditorView as EditorView18, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
4265
+ import { EditorView as EditorView19, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
3914
4266
  import { invariant as invariant4 } from "@dxos/invariant";
3915
- import { mx as mx2 } from "@dxos/react-ui-theme";
4267
+ import { mx as mx4 } from "@dxos/react-ui-theme";
3916
4268
 
3917
4269
  // packages/ui/react-ui-editor/src/extensions/markdown/changes.ts
3918
4270
  import { syntaxTree as syntaxTree4 } from "@codemirror/language";
@@ -4061,7 +4413,7 @@ var getValidUrl = (str) => {
4061
4413
  // packages/ui/react-ui-editor/src/extensions/markdown/image.ts
4062
4414
  import { syntaxTree as syntaxTree5 } from "@codemirror/language";
4063
4415
  import { StateField as StateField8 } from "@codemirror/state";
4064
- import { Decoration as Decoration5, EditorView as EditorView15, WidgetType as WidgetType3 } from "@codemirror/view";
4416
+ import { Decoration as Decoration5, EditorView as EditorView16, WidgetType as WidgetType3 } from "@codemirror/view";
4065
4417
  var image = (_options = {}) => {
4066
4418
  return [
4067
4419
  StateField8.define({
@@ -4089,7 +4441,7 @@ var image = (_options = {}) => {
4089
4441
  add: buildDecorations(from, to, tr.state)
4090
4442
  });
4091
4443
  },
4092
- provide: (field) => EditorView15.decorations.from(field)
4444
+ provide: (field) => EditorView16.decorations.from(field)
4093
4445
  })
4094
4446
  ];
4095
4447
  };
@@ -4149,10 +4501,10 @@ var ImageWidget = class extends WidgetType3 {
4149
4501
  };
4150
4502
 
4151
4503
  // packages/ui/react-ui-editor/src/extensions/markdown/styles.ts
4152
- import { EditorView as EditorView16 } from "@codemirror/view";
4504
+ import { EditorView as EditorView17 } from "@codemirror/view";
4153
4505
  var bulletListIndentationWidth = 24;
4154
4506
  var orderedListIndentationWidth = 36;
4155
- var formattingStyles = EditorView16.theme({
4507
+ var formattingStyles = EditorView17.theme({
4156
4508
  /**
4157
4509
  * Horizontal rule.
4158
4510
  */
@@ -4246,18 +4598,39 @@ var formattingStyles = EditorView16.theme({
4246
4598
  height: "auto",
4247
4599
  borderTop: "0.5rem solid transparent",
4248
4600
  borderBottom: "0.5rem solid transparent"
4601
+ },
4602
+ ".cm-image-with-loader": {
4603
+ display: "block",
4604
+ opacity: "0",
4605
+ transitionDuration: "350ms",
4606
+ transitionProperty: "opacity"
4607
+ },
4608
+ ".cm-image-with-loader.cm-loaded-image": {
4609
+ opacity: "1"
4610
+ },
4611
+ ".cm-image-wrapper": {
4612
+ "grid-template-columns": "1fr",
4613
+ display: "grid",
4614
+ margin: "0.5rem 0",
4615
+ overflow: "hidden",
4616
+ transitionDuration: "350ms",
4617
+ transitionProperty: "height",
4618
+ "& > *": {
4619
+ "grid-row-start": 1,
4620
+ "grid-column-start": 1
4621
+ }
4249
4622
  }
4250
4623
  });
4251
4624
 
4252
4625
  // packages/ui/react-ui-editor/src/extensions/markdown/table.ts
4253
4626
  import { syntaxTree as syntaxTree6 } from "@codemirror/language";
4254
4627
  import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField9 } from "@codemirror/state";
4255
- import { Decoration as Decoration6, EditorView as EditorView17, WidgetType as WidgetType4 } from "@codemirror/view";
4628
+ import { Decoration as Decoration6, EditorView as EditorView18, WidgetType as WidgetType4 } from "@codemirror/view";
4256
4629
  var table = (options = {}) => {
4257
4630
  return StateField9.define({
4258
4631
  create: (state) => update(state, options),
4259
4632
  update: (_, tr) => update(tr.state, options),
4260
- provide: (field) => EditorView17.decorations.from(field)
4633
+ provide: (field) => EditorView18.decorations.from(field)
4261
4634
  });
4262
4635
  };
4263
4636
  var update = (state, _options) => {
@@ -4441,16 +4814,16 @@ var TextWidget = class extends WidgetType5 {
4441
4814
  };
4442
4815
  var hide = Decoration7.replace({});
4443
4816
  var blockQuote = Decoration7.line({
4444
- class: mx2("cm-blockquote")
4817
+ class: mx4("cm-blockquote")
4445
4818
  });
4446
4819
  var fencedCodeLine = Decoration7.line({
4447
- class: mx2("cm-code cm-codeblock-line")
4820
+ class: mx4("cm-code cm-codeblock-line")
4448
4821
  });
4449
4822
  var fencedCodeLineFirst = Decoration7.line({
4450
- class: mx2("cm-code cm-codeblock-line", "cm-codeblock-first")
4823
+ class: mx4("cm-code cm-codeblock-line", "cm-codeblock-first")
4451
4824
  });
4452
4825
  var fencedCodeLineLast = Decoration7.line({
4453
- class: mx2("cm-code cm-codeblock-line", "cm-codeblock-last")
4826
+ class: mx4("cm-code cm-codeblock-line", "cm-codeblock-last")
4454
4827
  });
4455
4828
  var commentBlockLine = fencedCodeLine;
4456
4829
  var commentBlockLineFirst = fencedCodeLineFirst;
@@ -4791,9 +5164,9 @@ var decorateMarkdown = (options = {}) => {
4791
5164
  }
4792
5165
  }, {
4793
5166
  provide: (plugin) => [
4794
- EditorView18.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4795
- EditorView18.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4796
- EditorView18.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
5167
+ EditorView19.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
5168
+ EditorView19.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
5169
+ EditorView19.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
4797
5170
  ]
4798
5171
  }),
4799
5172
  image(),
@@ -4980,428 +5353,29 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
4980
5353
  ];
4981
5354
  };
4982
5355
 
4983
- // packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
4984
- var iconStyles = getSize(5);
4985
- var buttonStyles = "min-bs-0 p-1";
4986
- var tooltipProps = {
4987
- side: "top",
4988
- classNames: "z-10"
4989
- };
4990
- var ToolbarSeparator = () => /* @__PURE__ */ React3.createElement("div", {
4991
- role: "separator",
4992
- className: "grow"
4993
- });
4994
- var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
4995
- var ToolbarRoot = ({ children, onAction, classNames, state }) => {
4996
- return /* @__PURE__ */ React3.createElement(ToolbarContextProvider, {
4997
- onAction,
4998
- state
4999
- }, /* @__PURE__ */ React3.createElement(ElevationProvider, {
5000
- elevation: "positioned"
5001
- }, /* @__PURE__ */ React3.createElement(NaturalToolbar.Root, {
5002
- classNames: [
5003
- "p-1 is-full shrink-0 overflow-x-auto overflow-y-hidden",
5004
- classNames
5005
- ],
5006
- style: {
5007
- contain: "layout"
5008
- }
5009
- }, children)));
5010
- };
5011
- var ToolbarToggleButton = ({ Icon: Icon2, children, ...props }) => {
5012
- return /* @__PURE__ */ React3.createElement(Tooltip.Root, null, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
5013
- asChild: true
5014
- }, /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroupItem, {
5015
- variant: "ghost",
5016
- ...props,
5017
- classNames: buttonStyles
5018
- }, /* @__PURE__ */ React3.createElement(Icon2, {
5019
- className: iconStyles
5020
- }), /* @__PURE__ */ React3.createElement("span", {
5021
- className: "sr-only"
5022
- }, children))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
5023
- };
5024
- var ToolbarButton = ({ Icon: Icon2, children, ...props }) => {
5025
- return /* @__PURE__ */ React3.createElement(Tooltip.Root, null, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
5026
- asChild: true
5027
- }, /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
5028
- variant: "ghost",
5029
- ...props,
5030
- classNames: buttonStyles
5031
- }, /* @__PURE__ */ React3.createElement(Icon2, {
5032
- className: iconStyles
5033
- }), /* @__PURE__ */ React3.createElement("span", {
5034
- className: "sr-only"
5035
- }, children))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
5036
- };
5037
- var HeadingIcons = {
5038
- "0": Paragraph,
5039
- "1": TextHOne,
5040
- "2": TextHTwo,
5041
- "3": TextHThree,
5042
- "4": TextHFour,
5043
- "5": TextHFive,
5044
- "6": TextHSix
5045
- };
5046
- var MarkdownHeading = () => {
5047
- const { t } = useTranslation(translationKey);
5048
- const { onAction, state } = useToolbarContext("MarkdownFormatting");
5049
- const blockType = state ? state.blockType : "paragraph";
5050
- const header = blockType && /heading(\d)/.exec(blockType);
5051
- const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
5052
- const HeadingIcon = HeadingIcons[value ?? "0"];
5053
- const suppressNextTooltip = useRef(false);
5054
- const [tooltipOpen, setTooltipOpen] = useState3(false);
5055
- const [selectOpen, setSelectOpen] = useState3(false);
5056
- return /* @__PURE__ */ React3.createElement(Tooltip.Root, {
5057
- open: tooltipOpen,
5058
- onOpenChange: (nextOpen) => {
5059
- if (nextOpen && suppressNextTooltip.current) {
5060
- suppressNextTooltip.current = false;
5061
- return setTooltipOpen(false);
5062
- } else {
5063
- return setTooltipOpen(nextOpen);
5064
- }
5065
- }
5066
- }, /* @__PURE__ */ React3.createElement(DropdownMenu.Root, {
5067
- open: selectOpen,
5068
- onOpenChange: (nextOpen) => {
5069
- if (!nextOpen) {
5070
- suppressNextTooltip.current = true;
5071
- }
5072
- return setSelectOpen(nextOpen);
5073
- }
5074
- }, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
5075
- asChild: true
5076
- }, /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
5077
- asChild: true
5078
- }, /* @__PURE__ */ React3.createElement(DropdownMenu.Trigger, {
5079
- asChild: true
5080
- }, /* @__PURE__ */ React3.createElement(Button, {
5081
- variant: "ghost",
5082
- classNames: buttonStyles,
5083
- disabled: value === null
5084
- }, /* @__PURE__ */ React3.createElement("span", {
5085
- className: "sr-only"
5086
- }, t("heading label")), /* @__PURE__ */ React3.createElement(HeadingIcon, {
5087
- className: iconStyles
5088
- }), /* @__PURE__ */ React3.createElement(CaretDown, null))))), /* @__PURE__ */ React3.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React3.createElement(DropdownMenu.Content, {
5089
- classNames: "is-min md:is-min",
5090
- onCloseAutoFocus: (e) => e.preventDefault()
5091
- }, /* @__PURE__ */ React3.createElement(DropdownMenu.Viewport, null, Object.keys(HeadingIcons).map((level) => {
5092
- const Icon2 = HeadingIcons[level];
5093
- return /* @__PURE__ */ React3.createElement(DropdownMenu.CheckboxItem, {
5094
- key: level,
5095
- checked: value === level,
5096
- onClick: () => onAction?.({
5097
- type: "heading",
5098
- data: level
5099
- })
5100
- }, /* @__PURE__ */ React3.createElement("span", {
5101
- className: "sr-only"
5102
- }, t("heading level label", {
5103
- count: parseInt(level)
5104
- })), /* @__PURE__ */ React3.createElement(Icon2, {
5105
- className: iconStyles
5106
- }), /* @__PURE__ */ React3.createElement(DropdownMenu.ItemIndicator, null, /* @__PURE__ */ React3.createElement(Check, null)));
5107
- })), /* @__PURE__ */ React3.createElement(DropdownMenu.Arrow, null)))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, t("heading label"), /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
5108
- };
5109
- var markdownStyles = [
5110
- {
5111
- type: "strong",
5112
- Icon: TextB,
5113
- getState: (state) => !!state?.strong
5114
- },
5115
- {
5116
- type: "emphasis",
5117
- Icon: TextItalic,
5118
- getState: (state) => !!state?.emphasis
5119
- },
5120
- {
5121
- type: "strikethrough",
5122
- Icon: TextStrikethrough,
5123
- getState: (state) => !!state?.strikethrough
5124
- },
5125
- {
5126
- type: "code",
5127
- Icon: Code,
5128
- getState: (state) => !!state?.code
5129
- },
5130
- {
5131
- type: "link",
5132
- Icon: Link,
5133
- getState: (state) => !!state?.link
5134
- }
5135
- ];
5136
- var MarkdownStyles = () => {
5137
- const { onAction, state } = useToolbarContext("MarkdownStyles");
5138
- const { t } = useTranslation(translationKey);
5139
- return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
5140
- type: "multiple",
5141
- value: markdownStyles.filter(({ getState }) => state && getState(state)).map(({ type }) => type)
5142
- }, markdownStyles.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
5143
- key: type,
5144
- value: type,
5145
- Icon: Icon2,
5146
- disabled: state?.blockType === "codeblock",
5147
- onClick: state ? () => onAction?.({
5148
- type,
5149
- data: !getState(state)
5150
- }) : void 0
5151
- }, t(`${type} label`))));
5152
- };
5153
- var markdownLists = [
5154
- {
5155
- type: "list-bullet",
5156
- Icon: ListBullets,
5157
- getState: (state) => state.listStyle === "bullet"
5158
- },
5159
- {
5160
- type: "list-ordered",
5161
- Icon: ListNumbers,
5162
- getState: (state) => state.listStyle === "ordered"
5163
- },
5164
- {
5165
- type: "list-task",
5166
- Icon: ListChecks,
5167
- getState: (state) => state.listStyle === "task"
5168
- }
5169
- ];
5170
- var MarkdownLists = () => {
5171
- const { onAction, state } = useToolbarContext("MarkdownStyles");
5172
- const { t } = useTranslation(translationKey);
5173
- return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
5174
- type: "single",
5175
- value: state?.listStyle ? `list-${state.listStyle}` : ""
5176
- }, markdownLists.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
5177
- key: type,
5178
- value: type,
5179
- Icon: Icon2,
5180
- onClick: state ? () => onAction?.({
5181
- type,
5182
- data: !getState(state)
5183
- }) : void 0
5184
- }, t(`${type} label`))));
5185
- };
5186
- var markdownBlocks = [
5187
- {
5188
- type: "blockquote",
5189
- Icon: Quotes,
5190
- getState: (state) => !!state?.blockQuote
5191
- },
5192
- {
5193
- type: "codeblock",
5194
- Icon: CodeBlock,
5195
- getState: (state) => state.blockType === "codeblock"
5196
- },
5197
- {
5198
- type: "table",
5199
- Icon: Table2,
5200
- getState: (state) => state.blockType === "tablecell",
5201
- disabled: (state) => !state.blankLine
5202
- }
5203
- ];
5204
- var MarkdownBlocks = () => {
5205
- const { onAction, state } = useToolbarContext("MarkdownStyles");
5206
- const { t } = useTranslation(translationKey);
5207
- const value = markdownBlocks.find(({ getState }) => state && getState(state));
5208
- return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
5209
- type: "single",
5210
- value: value?.type ?? ""
5211
- }, markdownBlocks.map(({ type, disabled, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
5212
- key: type,
5213
- value: type,
5214
- Icon: Icon2,
5215
- disabled: !state || disabled?.(state),
5216
- onClick: state ? () => onAction?.({
5217
- type,
5218
- data: !getState(state)
5219
- }) : void 0
5220
- }, t(`${type} label`))));
5221
- };
5222
- var MarkdownStandard = () => /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(MarkdownHeading, null), /* @__PURE__ */ React3.createElement(MarkdownStyles, null), /* @__PURE__ */ React3.createElement(MarkdownLists, null), /* @__PURE__ */ React3.createElement(MarkdownBlocks, null));
5223
- var MarkdownCustom = ({ onUpload } = {}) => {
5224
- const { onAction } = useToolbarContext("MarkdownStyles");
5225
- const { t } = useTranslation(translationKey);
5226
- const { acceptedFiles, getInputProps, open } = useDropzone({
5227
- multiple: false,
5228
- noDrag: true,
5229
- accept: {
5230
- "image/*": [
5231
- ".jpg",
5232
- ".jpeg",
5233
- ".png",
5234
- ".gif"
5235
- ]
5236
- }
5237
- });
5238
- useEffect2(() => {
5239
- if (onUpload && acceptedFiles.length) {
5240
- requestAnimationFrame(async () => {
5241
- const f = acceptedFiles[0];
5242
- const file = new File([
5243
- f
5244
- ], f.name, {
5245
- type: f.type,
5246
- lastModified: f.lastModified
5247
- });
5248
- const info = await onUpload(file);
5249
- if (info) {
5250
- onAction?.({
5251
- type: "image",
5252
- data: info.url
5253
- });
5254
- }
5255
- });
5256
- }
5257
- }, [
5258
- acceptedFiles
5259
- ]);
5260
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("input", getInputProps()), /* @__PURE__ */ React3.createElement(ToolbarButton, {
5261
- value: "image",
5262
- Icon: Image,
5263
- onClick: () => open()
5264
- }, t("image label")));
5265
- };
5266
- var ViewModeIcons = {
5267
- preview: PencilSimple,
5268
- readonly: PencilSimpleSlash,
5269
- source: MarkdownLogo
5270
- };
5271
- var MarkdownView = ({ mode }) => {
5272
- const { t } = useTranslation(translationKey);
5273
- const { onAction } = useToolbarContext("ViewMode");
5274
- const ModeIcon = ViewModeIcons[mode ?? "preview"];
5275
- const suppressNextTooltip = useRef(false);
5276
- const [tooltipOpen, setTooltipOpen] = useState3(false);
5277
- const [selectOpen, setSelectOpen] = useState3(false);
5278
- return /* @__PURE__ */ React3.createElement(Tooltip.Root, {
5279
- open: tooltipOpen,
5280
- onOpenChange: (nextOpen) => {
5281
- if (nextOpen && suppressNextTooltip.current) {
5282
- suppressNextTooltip.current = false;
5283
- return setTooltipOpen(false);
5284
- } else {
5285
- return setTooltipOpen(nextOpen);
5286
- }
5287
- }
5288
- }, /* @__PURE__ */ React3.createElement(DropdownMenu.Root, {
5289
- open: selectOpen,
5290
- onOpenChange: (nextOpen) => {
5291
- if (!nextOpen) {
5292
- suppressNextTooltip.current = true;
5293
- }
5294
- return setSelectOpen(nextOpen);
5295
- }
5296
- }, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
5297
- asChild: true
5298
- }, /* @__PURE__ */ React3.createElement(NaturalToolbar.Button, {
5299
- asChild: true
5300
- }, /* @__PURE__ */ React3.createElement(DropdownMenu.Trigger, {
5301
- asChild: true
5302
- }, /* @__PURE__ */ React3.createElement(Button, {
5303
- variant: "ghost",
5304
- classNames: buttonStyles
5305
- }, /* @__PURE__ */ React3.createElement("span", {
5306
- className: "sr-only"
5307
- }, t("mode label")), /* @__PURE__ */ React3.createElement(ModeIcon, {
5308
- className: iconStyles
5309
- }), /* @__PURE__ */ React3.createElement(CaretDown, null))))), /* @__PURE__ */ React3.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React3.createElement(DropdownMenu.Content, {
5310
- classNames: "is-min md:is-min",
5311
- onCloseAutoFocus: (e) => e.preventDefault()
5312
- }, /* @__PURE__ */ React3.createElement(DropdownMenu.Viewport, null, EditorViewModes.map((value) => {
5313
- const Icon2 = ViewModeIcons[value];
5314
- return /* @__PURE__ */ React3.createElement(DropdownMenu.CheckboxItem, {
5315
- key: value,
5316
- checked: value === mode,
5317
- onClick: () => onAction?.({
5318
- type: "view-mode",
5319
- data: value
5320
- })
5321
- }, /* @__PURE__ */ React3.createElement(Icon2, {
5322
- className: iconStyles
5323
- }), /* @__PURE__ */ React3.createElement("span", {
5324
- className: "whitespace-nowrap grow"
5325
- }, t(`${value} mode label`)), /* @__PURE__ */ React3.createElement(Check, {
5326
- className: value === mode ? "visible" : "invisible"
5327
- }));
5328
- })), /* @__PURE__ */ React3.createElement(DropdownMenu.Arrow, null)))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, t("view mode label"), /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
5329
- };
5330
- var MarkdownActions = () => {
5331
- const { onAction, state } = useToolbarContext("MarkdownActions");
5332
- const { t } = useTranslation(translationKey);
5333
- let commentToolTipKey = "comment label";
5334
- if (state?.comment) {
5335
- commentToolTipKey = "selection overlaps existing comment label";
5336
- } else if (state?.selection === false) {
5337
- commentToolTipKey = "select text to comment label";
5338
- }
5339
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(ToolbarButton, {
5340
- value: "search",
5341
- Icon: MagnifyingGlass,
5342
- onClick: () => onAction?.({
5343
- type: "search"
5344
- })
5345
- }, t("search label")), /* @__PURE__ */ React3.createElement(ToolbarButton, {
5346
- value: "comment",
5347
- Icon: ChatText,
5348
- "data-testid": "editor.toolbar.comment",
5349
- onClick: () => onAction?.({
5350
- type: "comment"
5351
- }),
5352
- disabled: !state || state.comment || !state.selection
5353
- }, t(commentToolTipKey)));
5354
- };
5355
- var Toolbar = {
5356
- Root: ToolbarRoot,
5357
- Button: ToolbarToggleButton,
5358
- Separator: ToolbarSeparator,
5359
- View: MarkdownView,
5360
- Markdown: MarkdownStandard,
5361
- Custom: MarkdownCustom,
5362
- Actions: MarkdownActions
5363
- };
5364
-
5365
- // packages/ui/react-ui-editor/src/defaults.ts
5366
- import { EditorView as EditorView19 } from "@codemirror/view";
5367
- import { mx as mx3 } from "@dxos/react-ui-theme";
5368
- var margin = "!mt-[1rem]";
5369
- var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
5370
- var editorFullWidth = mx3(margin);
5371
- var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
5372
- var editorGutter = EditorView19.theme({
5373
- // Match margin from content.
5374
- ".cm-gutters": {
5375
- marginTop: "16px",
5376
- paddingRight: "1rem"
5377
- }
5378
- });
5379
- var editorMonospace = EditorView19.theme({
5380
- ".cm-content": {
5381
- fontFamily: fontMono
5382
- }
5383
- });
5384
-
5385
5356
  // packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
5357
+ import { useCallback as useCallback2 } from "react";
5386
5358
  var useActionHandler = (view) => {
5387
- return (action) => view && processAction(view, action);
5359
+ return useCallback2((action) => view && processEditorPayload(view, action.properties), [
5360
+ view
5361
+ ]);
5388
5362
  };
5389
5363
 
5390
5364
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
5391
5365
  import { EditorState as EditorState2 } from "@codemirror/state";
5392
5366
  import { EditorView as EditorView20 } from "@codemirror/view";
5393
5367
  import { useFocusableGroup } from "@fluentui/react-tabster";
5394
- import { useCallback, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2, useState as useState4 } from "react";
5368
+ import { useCallback as useCallback3, useEffect as useEffect2, useMemo as useMemo4, useRef, useState } from "react";
5395
5369
  import { log as log7 } from "@dxos/log";
5396
5370
  import { getProviderValue, isNotFalsy as isNotFalsy4 } from "@dxos/util";
5397
5371
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
5398
5372
  var instanceCount = 0;
5399
5373
  var useTextEditor = (props = {}, deps = []) => {
5400
- const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo3(() => getProviderValue(props), deps ?? []);
5401
- const [instanceId] = useState4(() => `text-editor-${++instanceCount}`);
5402
- const [view, setView] = useState4();
5403
- const parentRef = useRef2(null);
5404
- useEffect3(() => {
5374
+ const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo4(() => getProviderValue(props), deps ?? []);
5375
+ const [instanceId] = useState(() => `text-editor-${++instanceCount}`);
5376
+ const [view, setView] = useState();
5377
+ const parentRef = useRef(null);
5378
+ useEffect2(() => {
5405
5379
  let view2;
5406
5380
  if (parentRef.current) {
5407
5381
  log7("create", {
@@ -5475,7 +5449,7 @@ var useTextEditor = (props = {}, deps = []) => {
5475
5449
  view2?.destroy();
5476
5450
  };
5477
5451
  }, deps);
5478
- useEffect3(() => {
5452
+ useEffect2(() => {
5479
5453
  if (view) {
5480
5454
  if (scrollTo || selection) {
5481
5455
  if (selection && selection.anchor > view.state.doc.length) {
@@ -5502,7 +5476,7 @@ var useTextEditor = (props = {}, deps = []) => {
5502
5476
  scrollTo,
5503
5477
  selection
5504
5478
  ]);
5505
- useEffect3(() => {
5479
+ useEffect2(() => {
5506
5480
  if (view && autoFocus) {
5507
5481
  view.focus();
5508
5482
  }
@@ -5516,7 +5490,7 @@ var useTextEditor = (props = {}, deps = []) => {
5516
5490
  Escape: view?.state.facet(editorInputMode).noTabster
5517
5491
  }
5518
5492
  });
5519
- const handleKeyUp = useCallback((event) => {
5493
+ const handleKeyUp = useCallback3((event) => {
5520
5494
  const { key, target, currentTarget } = event;
5521
5495
  if (target === currentTarget) {
5522
5496
  switch (key) {
@@ -5545,6 +5519,7 @@ export {
5545
5519
  EditorInputMode,
5546
5520
  EditorInputModes,
5547
5521
  EditorState3 as EditorState,
5522
+ EditorToolbar,
5548
5523
  EditorView21 as EditorView,
5549
5524
  EditorViewMode,
5550
5525
  EditorViewModes,
@@ -5554,7 +5529,6 @@ export {
5554
5529
  RemoteSelectionsDecorator,
5555
5530
  SpaceAwarenessProvider,
5556
5531
  TextKind,
5557
- Toolbar,
5558
5532
  addBlockquote,
5559
5533
  addCodeblock,
5560
5534
  addLink,
@@ -5573,8 +5547,10 @@ export {
5573
5547
  commentsState,
5574
5548
  convertTreeToJson,
5575
5549
  createBasicExtensions,
5576
- createComment,
5550
+ createComment2 as createComment,
5577
5551
  createDataExtensions,
5552
+ createEditorAction,
5553
+ createEditorActionGroup,
5578
5554
  createEditorStateStore,
5579
5555
  createEditorStateTransaction,
5580
5556
  createElement,
@@ -5613,7 +5589,7 @@ export {
5613
5589
  mention,
5614
5590
  overlap,
5615
5591
  preventNewline,
5616
- processAction,
5592
+ processEditorPayload,
5617
5593
  removeBlockquote,
5618
5594
  removeCodeblock,
5619
5595
  removeLink,
@@ -5629,6 +5605,8 @@ export {
5629
5605
  setSelection,
5630
5606
  setStyle,
5631
5607
  singleValueFacet,
5608
+ stackItemContentEditorClassNames,
5609
+ stackItemContentToolbarClassNames,
5632
5610
  table,
5633
5611
  tags2 as tags,
5634
5612
  textRange,
@@ -5646,9 +5624,9 @@ export {
5646
5624
  useCommentClickListener,
5647
5625
  useCommentState,
5648
5626
  useComments,
5627
+ useEditorToolbarState,
5649
5628
  useFormattingState,
5650
5629
  useTextEditor,
5651
- useToolbarContext,
5652
5630
  wrapWithCatch
5653
5631
  };
5654
5632
  //# sourceMappingURL=index.mjs.map