@dxos/react-ui-editor 0.7.4 → 0.7.5-labs.071a3e2

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