@dxos/react-ui-editor 0.7.4 → 0.7.5-feature-compute.4d9d99a

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