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