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