@dxos/react-ui-editor 0.6.14-main.7bd9c89 → 0.6.14-main.f49f251

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 (101) hide show
  1. package/dist/lib/browser/index.mjs +650 -479
  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 +726 -545
  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 +650 -478
  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/TextEditor.stories.d.ts.map +1 -1
  11. package/dist/types/src/extensions/automerge/cursor.d.ts +1 -1
  12. package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
  13. package/dist/types/src/extensions/comments.d.ts +1 -1
  14. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  15. package/dist/types/src/extensions/factories.d.ts +1 -0
  16. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  17. package/dist/types/src/extensions/focus.d.ts +7 -0
  18. package/dist/types/src/extensions/focus.d.ts.map +1 -0
  19. package/dist/types/src/extensions/index.d.ts +2 -0
  20. package/dist/types/src/extensions/index.d.ts.map +1 -1
  21. package/dist/types/src/extensions/markdown/image.d.ts +3 -6
  22. package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
  23. package/dist/types/src/extensions/selection.d.ts +24 -0
  24. package/dist/types/src/extensions/selection.d.ts.map +1 -0
  25. package/dist/types/src/hooks/useTextEditor.d.ts +1 -1
  26. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  27. package/dist/types/src/index.d.ts +1 -1
  28. package/dist/types/src/types.d.ts.map +1 -0
  29. package/dist/types/src/{state → util}/cursor.d.ts +7 -1
  30. package/dist/types/src/util/cursor.d.ts.map +1 -0
  31. package/dist/types/src/{util.d.ts → util/debug.d.ts} +6 -2
  32. package/dist/types/src/util/debug.d.ts.map +1 -0
  33. package/dist/types/src/util/dom.d.ts.map +1 -0
  34. package/dist/types/src/{state/util.d.ts → util/facet.d.ts} +1 -1
  35. package/dist/types/src/util/facet.d.ts.map +1 -0
  36. package/dist/types/src/util/index.d.ts +6 -0
  37. package/dist/types/src/util/index.d.ts.map +1 -0
  38. package/dist/types/src/util/react.d.ts.map +1 -0
  39. package/package.json +28 -42
  40. package/src/TextEditor.stories.tsx +8 -6
  41. package/src/extensions/annotations.ts +1 -1
  42. package/src/extensions/automerge/automerge.ts +1 -1
  43. package/src/extensions/automerge/cursor.ts +1 -1
  44. package/src/extensions/awareness/awareness.ts +1 -1
  45. package/src/extensions/command/hint.ts +1 -1
  46. package/src/extensions/command/state.ts +1 -1
  47. package/src/extensions/comments.ts +3 -4
  48. package/src/extensions/factories.ts +5 -1
  49. package/src/extensions/focus.ts +35 -0
  50. package/src/extensions/folding.tsx +1 -1
  51. package/src/extensions/index.ts +2 -0
  52. package/src/extensions/markdown/decorate.ts +1 -1
  53. package/src/extensions/markdown/image.ts +53 -42
  54. package/src/extensions/modes.ts +1 -1
  55. package/src/{state/state.ts → extensions/selection.ts} +22 -22
  56. package/src/hooks/useTextEditor.ts +2 -3
  57. package/src/index.ts +1 -1
  58. package/src/{state → util}/cursor.ts +9 -3
  59. package/src/{util.ts → util/debug.ts} +15 -2
  60. package/src/{extensions/util → util}/index.ts +3 -2
  61. package/dist/lib/browser/chunk-CIQSMP7K.mjs +0 -148
  62. package/dist/lib/browser/chunk-CIQSMP7K.mjs.map +0 -7
  63. package/dist/lib/browser/state/index.mjs +0 -17
  64. package/dist/lib/browser/state/index.mjs.map +0 -7
  65. package/dist/lib/node/chunk-GZWIENFM.cjs +0 -169
  66. package/dist/lib/node/chunk-GZWIENFM.cjs.map +0 -7
  67. package/dist/lib/node/state/index.cjs +0 -39
  68. package/dist/lib/node/state/index.cjs.map +0 -7
  69. package/dist/lib/node-esm/chunk-GP5RCZ3X.mjs +0 -150
  70. package/dist/lib/node-esm/chunk-GP5RCZ3X.mjs.map +0 -7
  71. package/dist/lib/node-esm/state/index.mjs +0 -18
  72. package/dist/lib/node-esm/state/index.mjs.map +0 -7
  73. package/dist/types/src/extensions/util/dom.d.ts.map +0 -1
  74. package/dist/types/src/extensions/util/error.d.ts +0 -2
  75. package/dist/types/src/extensions/util/error.d.ts.map +0 -1
  76. package/dist/types/src/extensions/util/index.d.ts +0 -5
  77. package/dist/types/src/extensions/util/index.d.ts.map +0 -1
  78. package/dist/types/src/extensions/util/overlap.d.ts +0 -8
  79. package/dist/types/src/extensions/util/overlap.d.ts.map +0 -1
  80. package/dist/types/src/extensions/util/react.d.ts.map +0 -1
  81. package/dist/types/src/state/cursor.d.ts.map +0 -1
  82. package/dist/types/src/state/doc.d.ts +0 -5
  83. package/dist/types/src/state/doc.d.ts.map +0 -1
  84. package/dist/types/src/state/index.d.ts +0 -6
  85. package/dist/types/src/state/index.d.ts.map +0 -1
  86. package/dist/types/src/state/state.d.ts +0 -20
  87. package/dist/types/src/state/state.d.ts.map +0 -1
  88. package/dist/types/src/state/types.d.ts.map +0 -1
  89. package/dist/types/src/state/util.d.ts.map +0 -1
  90. package/dist/types/src/util.d.ts.map +0 -1
  91. package/src/extensions/util/error.ts +0 -15
  92. package/src/extensions/util/overlap.ts +0 -12
  93. package/src/state/doc.ts +0 -10
  94. package/src/state/index.ts +0 -11
  95. /package/dist/types/src/{state/types.d.ts → types.d.ts} +0 -0
  96. /package/dist/types/src/{extensions/util → util}/dom.d.ts +0 -0
  97. /package/dist/types/src/{extensions/util → util}/react.d.ts +0 -0
  98. /package/src/{state/types.ts → types.ts} +0 -0
  99. /package/src/{extensions/util → util}/dom.ts +0 -0
  100. /package/src/{state/util.ts → util/facet.ts} +0 -0
  101. /package/src/{extensions/util → util}/react.tsx +0 -0
@@ -1,12 +1,4 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
- import {
3
- Cursor,
4
- createEditorStateTransaction,
5
- documentId,
6
- localStorageStateStoreAdapter,
7
- singleValueFacet,
8
- state
9
- } from "./chunk-GP5RCZ3X.mjs";
10
2
 
11
3
  // packages/ui/react-ui-editor/src/translations.ts
12
4
  var translationKey = "react-ui-editor";
@@ -44,7 +36,7 @@ var translations_default = [
44
36
  ];
45
37
 
46
38
  // packages/ui/react-ui-editor/src/index.ts
47
- import { keymap as keymap10 } from "@codemirror/view";
39
+ import { keymap as keymap11 } from "@codemirror/view";
48
40
  import { tags as tags2 } from "@lezer/highlight";
49
41
  import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
50
42
 
@@ -60,19 +52,176 @@ import { getSize } from "@dxos/react-ui-theme";
60
52
  import { StateField } from "@codemirror/state";
61
53
  import { Decoration, EditorView } from "@codemirror/view";
62
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;
62
+ }
63
+ });
64
+
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
+ }
98
+ };
99
+
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
+ });
114
+ }
115
+ };
116
+ };
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
+ }
128
+ };
129
+ var debugDispatcher = (trs, view) => {
130
+ logChanges(trs);
131
+ view.update(trs);
132
+ };
133
+ var logChanges = (trs) => {
134
+ const changes = trs.flatMap((tr) => {
135
+ if (tr.changes.empty) {
136
+ return void 0;
137
+ }
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
+ }
158
+ };
159
+
160
+ // packages/ui/react-ui-editor/src/util/dom.ts
161
+ var flattenRect = (rect, left) => {
162
+ const x = left ? rect.left : rect.right;
163
+ return {
164
+ left: x,
165
+ right: x,
166
+ top: rect.top,
167
+ bottom: rect.bottom
168
+ };
169
+ };
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;
176
+ };
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
+ }
185
+ };
186
+
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
+ ]);
201
+ }
202
+ return el;
203
+ };
204
+ var renderRoot = (root, node) => {
205
+ createRoot(root).render(/* @__PURE__ */ React.createElement(ThemeProvider, {
206
+ tx: defaultTx
207
+ }, node));
208
+ return root;
209
+ };
210
+
211
+ // packages/ui/react-ui-editor/src/extensions/annotations.ts
63
212
  var annotationMark = Decoration.mark({
64
213
  class: "cm-annotation"
65
214
  });
66
215
  var annotations = (options = {}) => {
67
- const match = (state2) => {
216
+ const match = (state) => {
68
217
  const annotations2 = [];
69
- const text = state2.doc.toString();
218
+ const text = state.doc.toString();
70
219
  if (options.match) {
71
220
  const matches = text.matchAll(options.match);
72
221
  for (const match2 of matches) {
73
222
  const from = match2.index;
74
223
  const to = from + match2[0].length;
75
- const cursor = Cursor.getCursorFromRange(state2, {
224
+ const cursor = Cursor.getCursorFromRange(state, {
76
225
  from,
77
226
  to
78
227
  });
@@ -84,8 +233,8 @@ var annotations = (options = {}) => {
84
233
  return annotations2;
85
234
  };
86
235
  const annotationsState = StateField.define({
87
- create: (state2) => {
88
- return match(state2);
236
+ create: (state) => {
237
+ return match(state);
89
238
  },
90
239
  update: (value, tr) => {
91
240
  if (!tr.changes.empty) {
@@ -98,10 +247,10 @@ var annotations = (options = {}) => {
98
247
  annotationsState,
99
248
  EditorView.decorations.compute([
100
249
  annotationsState
101
- ], (state2) => {
102
- const annotations2 = state2.field(annotationsState);
250
+ ], (state) => {
251
+ const annotations2 = state.field(annotationsState);
103
252
  const decorations = annotations2.map((annotation) => {
104
- const range = Cursor.getRangeFromCursor(state2, annotation.cursor);
253
+ const range = Cursor.getRangeFromCursor(state, annotation.cursor);
105
254
  return range && annotationMark.range(range.from, range.to);
106
255
  }).filter(isNotFalsy);
107
256
  return Decoration.set(decorations);
@@ -164,16 +313,16 @@ import { EditorView as EditorView2, ViewPlugin } from "@codemirror/view";
164
313
  import { next as A3 } from "@dxos/automerge/automerge";
165
314
 
166
315
  // packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
167
- import { log } from "@dxos/log";
316
+ import { log as log2 } from "@dxos/log";
168
317
  import { fromCursor, toCursor } from "@dxos/react-client/echo";
169
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts";
318
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts";
170
319
  var cursorConverter = (accessor) => ({
171
320
  toCursor: (pos, assoc) => {
172
321
  try {
173
322
  return toCursor(accessor, pos, assoc);
174
323
  } catch (err) {
175
- log.catch(err, void 0, {
176
- F: __dxlog_file,
324
+ log2.catch(err, void 0, {
325
+ F: __dxlog_file2,
177
326
  L: 15,
178
327
  S: void 0,
179
328
  C: (f, a) => f(...a)
@@ -185,8 +334,8 @@ var cursorConverter = (accessor) => ({
185
334
  try {
186
335
  return fromCursor(accessor, cursor);
187
336
  } catch (err) {
188
- log.catch(err, void 0, {
189
- F: __dxlog_file,
337
+ log2.catch(err, void 0, {
338
+ F: __dxlog_file2,
190
339
  L: 24,
191
340
  S: void 0,
192
341
  C: (f, a) => f(...a)
@@ -198,8 +347,8 @@ var cursorConverter = (accessor) => ({
198
347
 
199
348
  // packages/ui/react-ui-editor/src/extensions/automerge/defs.ts
200
349
  import { Annotation, StateEffect } from "@codemirror/state";
201
- var getPath = (state2, field) => state2.field(field).path;
202
- var getLastHeads = (state2, field) => state2.field(field).lastHeads;
350
+ var getPath = (state, field) => state.field(field).path;
351
+ var getLastHeads = (state, field) => state.field(field).lastHeads;
203
352
  var updateHeadsEffect = StateEffect.define({});
204
353
  var updateHeads = (newHeads) => updateHeadsEffect.of({
205
354
  newHeads
@@ -214,8 +363,8 @@ import { next as A2 } from "@dxos/automerge/automerge";
214
363
 
215
364
  // packages/ui/react-ui-editor/src/extensions/automerge/update-automerge.ts
216
365
  import { next as A } from "@dxos/automerge/automerge";
217
- var updateAutomerge = (field, handle, transactions, state2) => {
218
- const { lastHeads, path } = state2.field(field);
366
+ var updateAutomerge = (field, handle, transactions, state) => {
367
+ const { lastHeads, path } = state.field(field);
219
368
  let hasChanges = false;
220
369
  for (const tr of transactions) {
221
370
  tr.changes.iterChanges(() => {
@@ -262,7 +411,7 @@ var updateCodeMirror = (view, selection, target, patches) => {
262
411
  annotations: reconcileAnnotation.of(false)
263
412
  });
264
413
  };
265
- var handlePatch = (patch, target, state2) => {
414
+ var handlePatch = (patch, target, state) => {
266
415
  if (patch.action === "insert") {
267
416
  return handleInsert(target, patch);
268
417
  } else if (patch.action === "splice") {
@@ -270,7 +419,7 @@ var handlePatch = (patch, target, state2) => {
270
419
  } else if (patch.action === "del") {
271
420
  return handleDel(target, patch);
272
421
  } else if (patch.action === "put") {
273
- return handlePut(target, patch, state2);
422
+ return handlePut(target, patch, state);
274
423
  } else {
275
424
  return null;
276
425
  }
@@ -314,7 +463,7 @@ var handleDel = (target, patch) => {
314
463
  }
315
464
  ];
316
465
  };
317
- var handlePut = (target, patch, state2) => {
466
+ var handlePut = (target, patch, state) => {
318
467
  const index = charPath(target, [
319
468
  ...patch.path,
320
469
  0
@@ -322,7 +471,7 @@ var handlePut = (target, patch, state2) => {
322
471
  if (index == null) {
323
472
  return [];
324
473
  }
325
- const length = state2.doc.length;
474
+ const length = state.doc.length;
326
475
  if (typeof patch.value !== "string") {
327
476
  return [];
328
477
  }
@@ -457,7 +606,7 @@ import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
457
606
  import { Decoration as Decoration2, EditorView as EditorView3, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
458
607
  import { Event } from "@dxos/async";
459
608
  import { Context } from "@dxos/context";
460
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts";
609
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts";
461
610
  var dummyProvider = {
462
611
  remoteStateChange: new Event(),
463
612
  open: () => {
@@ -482,7 +631,7 @@ var awareness = (provider = dummyProvider) => {
482
631
  var RemoteSelectionsDecorator = class {
483
632
  constructor(view) {
484
633
  this._ctx = new Context(void 0, {
485
- F: __dxlog_file2,
634
+ F: __dxlog_file3,
486
635
  L: 80
487
636
  });
488
637
  this.decorations = RangeSet.of([]);
@@ -521,9 +670,9 @@ var RemoteSelectionsDecorator = class {
521
670
  _updateRemoteSelections(view) {
522
671
  const decorations = [];
523
672
  const awarenessStates = this._provider.getRemoteStates();
524
- for (const state2 of awarenessStates) {
525
- const anchor = state2.position?.anchor ? this._cursorConverter.fromCursor(state2.position.anchor) : null;
526
- const head = state2.position?.head ? this._cursorConverter.fromCursor(state2.position.head) : null;
673
+ for (const state of awarenessStates) {
674
+ const anchor = state.position?.anchor ? this._cursorConverter.fromCursor(state.position.anchor) : null;
675
+ const head = state.position?.head ? this._cursorConverter.fromCursor(state.position.head) : null;
527
676
  if (anchor == null || head == null) {
528
677
  continue;
529
678
  }
@@ -531,8 +680,8 @@ var RemoteSelectionsDecorator = class {
531
680
  const end = Math.min(Math.max(anchor, head), view.state.doc.length);
532
681
  const startLine = view.state.doc.lineAt(start);
533
682
  const endLine = view.state.doc.lineAt(end);
534
- const darkColor = state2.info.darkColor;
535
- const lightColor = state2.info.lightColor;
683
+ const darkColor = state.info.darkColor;
684
+ const lightColor = state.info.lightColor;
536
685
  if (startLine.number === endLine.number) {
537
686
  decorations.push({
538
687
  from: start,
@@ -585,7 +734,7 @@ var RemoteSelectionsDecorator = class {
585
734
  value: Decoration2.widget({
586
735
  side: head - anchor > 0 ? -1 : 1,
587
736
  block: false,
588
- widget: new RemoteCaretWidget(state2.info.displayName ?? "Anonymous", darkColor)
737
+ widget: new RemoteCaretWidget(state.info.displayName ?? "Anonymous", darkColor)
589
738
  })
590
739
  });
591
740
  }
@@ -690,8 +839,8 @@ var styles2 = EditorView3.theme({
690
839
  import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
691
840
  import { Context as Context2 } from "@dxos/context";
692
841
  import { invariant } from "@dxos/invariant";
693
- import { log as log2 } from "@dxos/log";
694
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness-provider.ts";
842
+ import { log as log3 } from "@dxos/log";
843
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness-provider.ts";
695
844
  var DEBOUNCE_INTERVAL = 100;
696
845
  var SpaceAwarenessProvider = class {
697
846
  constructor(params) {
@@ -704,7 +853,7 @@ var SpaceAwarenessProvider = class {
704
853
  }
705
854
  open() {
706
855
  this._ctx = new Context2(void 0, {
707
- F: __dxlog_file3,
856
+ F: __dxlog_file4,
708
857
  L: 57
709
858
  });
710
859
  this._postTask = new DeferredTask(this._ctx, async () => {
@@ -731,10 +880,10 @@ var SpaceAwarenessProvider = class {
731
880
  void this._space.postMessage(this._channel, {
732
881
  kind: "query"
733
882
  }).catch((err) => {
734
- log2.debug("failed to query awareness", {
883
+ log3.debug("failed to query awareness", {
735
884
  err
736
885
  }, {
737
- F: __dxlog_file3,
886
+ F: __dxlog_file4,
738
887
  L: 91,
739
888
  S: this,
740
889
  C: (f, a) => f(...a)
@@ -751,7 +900,7 @@ var SpaceAwarenessProvider = class {
751
900
  }
752
901
  update(position) {
753
902
  invariant(this._postTask, void 0, {
754
- F: __dxlog_file3,
903
+ F: __dxlog_file4,
755
904
  L: 106,
756
905
  S: this,
757
906
  A: [
@@ -768,7 +917,7 @@ var SpaceAwarenessProvider = class {
768
917
  }
769
918
  _handleQueryMessage() {
770
919
  invariant(this._postTask, void 0, {
771
- F: __dxlog_file3,
920
+ F: __dxlog_file4,
772
921
  L: 117,
773
922
  S: this,
774
923
  A: [
@@ -780,7 +929,7 @@ var SpaceAwarenessProvider = class {
780
929
  }
781
930
  _handlePostMessage(message) {
782
931
  invariant(message.kind === "post", void 0, {
783
- F: __dxlog_file3,
932
+ F: __dxlog_file4,
784
933
  L: 122,
785
934
  S: this,
786
935
  A: [
@@ -797,7 +946,7 @@ var SpaceAwarenessProvider = class {
797
946
  import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
798
947
  import defaultsDeep from "lodash.defaultsdeep";
799
948
  import { invariant as invariant2 } from "@dxos/invariant";
800
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
949
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
801
950
  var defaultOptions = {
802
951
  effect: 2,
803
952
  maxParticles: 200,
@@ -924,7 +1073,7 @@ var Blaster = class {
924
1073
  }
925
1074
  initialize() {
926
1075
  invariant2(!this._canvas && !this._ctx, void 0, {
927
- F: __dxlog_file4,
1076
+ F: __dxlog_file5,
928
1077
  L: 141,
929
1078
  S: this,
930
1079
  A: [
@@ -961,7 +1110,7 @@ var Blaster = class {
961
1110
  }
962
1111
  start() {
963
1112
  invariant2(this._canvas && this._ctx, void 0, {
964
- F: __dxlog_file4,
1113
+ F: __dxlog_file5,
965
1114
  L: 180,
966
1115
  S: this,
967
1116
  A: [
@@ -1116,7 +1265,7 @@ import { showTooltip } from "@codemirror/view";
1116
1265
  var commandConfig = singleValueFacet();
1117
1266
  var commandState = StateField3.define({
1118
1267
  create: () => ({}),
1119
- update: (state2, tr) => {
1268
+ update: (state, tr) => {
1120
1269
  for (const effect of tr.effects) {
1121
1270
  if (effect.is(closeEffect)) {
1122
1271
  return {};
@@ -1167,7 +1316,7 @@ var commandState = StateField3.define({
1167
1316
  };
1168
1317
  }
1169
1318
  }
1170
- return state2;
1319
+ return state;
1171
1320
  },
1172
1321
  provide: (field) => [
1173
1322
  showTooltip.from(field, (value) => value.tooltip ?? null)
@@ -1211,78 +1360,6 @@ var commandKeyBindings = [
1211
1360
  }
1212
1361
  ];
1213
1362
 
1214
- // packages/ui/react-ui-editor/src/extensions/util/dom.ts
1215
- var flattenRect = (rect, left) => {
1216
- const x = left ? rect.left : rect.right;
1217
- return {
1218
- left: x,
1219
- right: x,
1220
- top: rect.top,
1221
- bottom: rect.bottom
1222
- };
1223
- };
1224
- var scratchRange;
1225
- var textRange = (node, from, to = from) => {
1226
- const range = scratchRange || (scratchRange = document.createRange());
1227
- range.setEnd(node, to);
1228
- range.setStart(node, from);
1229
- return range;
1230
- };
1231
- var clientRectsFor = (dom) => {
1232
- if (dom.nodeType === 3) {
1233
- return textRange(dom, 0, dom.nodeValue.length).getClientRects();
1234
- } else if (dom.nodeType === 1) {
1235
- return dom.getClientRects();
1236
- } else {
1237
- return [];
1238
- }
1239
- };
1240
-
1241
- // packages/ui/react-ui-editor/src/extensions/util/error.ts
1242
- import { log as log3 } from "@dxos/log";
1243
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/util/error.ts";
1244
- var wrapWithCatch = (fn) => {
1245
- return (...args) => {
1246
- try {
1247
- return fn(...args);
1248
- } catch (err) {
1249
- log3.catch(err, void 0, {
1250
- F: __dxlog_file5,
1251
- L: 12,
1252
- S: void 0,
1253
- C: (f, a) => f(...a)
1254
- });
1255
- }
1256
- };
1257
- };
1258
-
1259
- // packages/ui/react-ui-editor/src/extensions/util/overlap.ts
1260
- var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
1261
-
1262
- // packages/ui/react-ui-editor/src/extensions/util/react.tsx
1263
- import React from "react";
1264
- import { createRoot } from "react-dom/client";
1265
- import { ThemeProvider } from "@dxos/react-ui";
1266
- import { defaultTx } from "@dxos/react-ui-theme";
1267
- var createElement = (tag, options, children) => {
1268
- const el = document.createElement(tag);
1269
- if (options?.className) {
1270
- el.className = options.className;
1271
- }
1272
- if (children) {
1273
- el.append(...Array.isArray(children) ? children : [
1274
- children
1275
- ]);
1276
- }
1277
- return el;
1278
- };
1279
- var renderRoot = (root, node) => {
1280
- createRoot(root).render(/* @__PURE__ */ React.createElement(ThemeProvider, {
1281
- tx: defaultTx
1282
- }, node));
1283
- return root;
1284
- };
1285
-
1286
1363
  // packages/ui/react-ui-editor/src/extensions/command/hint.ts
1287
1364
  var CommandHint = class extends WidgetType2 {
1288
1365
  constructor(content) {
@@ -1366,57 +1443,104 @@ var command = (options) => {
1366
1443
  // packages/ui/react-ui-editor/src/extensions/comments.ts
1367
1444
  import { invertedEffects } from "@codemirror/commands";
1368
1445
  import { StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
1369
- import { hoverTooltip, keymap as keymap4, Decoration as Decoration4, EditorView as EditorView7, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
1446
+ import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as EditorView8, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
1370
1447
  import sortBy from "lodash.sortby";
1371
1448
  import { useEffect, useMemo, useState } from "react";
1372
- import { debounce } from "@dxos/async";
1373
- import { log as log5 } from "@dxos/log";
1449
+ import { debounce as debounce2 } from "@dxos/async";
1450
+ import { log as log4 } from "@dxos/log";
1374
1451
  import { nonNullable } from "@dxos/util";
1375
1452
 
1376
- // packages/ui/react-ui-editor/src/util.ts
1377
- import { log as log4 } from "@dxos/log";
1378
- var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
1379
- var callbackWrapper = (fn) => (...args) => {
1380
- try {
1381
- return fn(...args);
1382
- } catch (err) {
1383
- log4.catch(err, void 0, {
1453
+ // packages/ui/react-ui-editor/src/extensions/selection.ts
1454
+ import { Transaction } from "@codemirror/state";
1455
+ import { EditorView as EditorView7, keymap as keymap4 } from "@codemirror/view";
1456
+ import { debounce } from "@dxos/async";
1457
+ import { invariant as invariant3 } from "@dxos/invariant";
1458
+ import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
1459
+ var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/selection.ts";
1460
+ var documentId = singleValueFacet();
1461
+ var stateRestoreAnnotation = "dxos.org/cm/state-restore";
1462
+ var createEditorStateTransaction = ({ scrollTo, selection }) => {
1463
+ return {
1464
+ selection,
1465
+ scrollIntoView: !scrollTo,
1466
+ effects: scrollTo ? EditorView7.scrollIntoView(scrollTo, {
1467
+ yMargin: 96
1468
+ }) : void 0,
1469
+ annotations: Transaction.userEvent.of(stateRestoreAnnotation)
1470
+ };
1471
+ };
1472
+ var createEditorStateStore = (keyPrefix) => ({
1473
+ getState: (id) => {
1474
+ invariant3(id, void 0, {
1384
1475
  F: __dxlog_file6,
1385
- L: 19,
1476
+ L: 47,
1386
1477
  S: void 0,
1387
- C: (f, a) => f(...a)
1478
+ A: [
1479
+ "id",
1480
+ ""
1481
+ ]
1388
1482
  });
1389
- }
1390
- };
1391
- var debugDispatcher = (trs, view) => {
1392
- logChanges(trs);
1393
- view.update(trs);
1394
- };
1395
- var logChanges = (trs) => {
1396
- const changes = trs.flatMap((tr) => {
1397
- if (tr.changes.empty) {
1398
- return void 0;
1399
- }
1400
- const changes2 = [];
1401
- tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
1402
- fromA,
1403
- toA,
1404
- fromB,
1405
- toB,
1406
- inserted: inserted.toString()
1407
- })));
1408
- return changes2;
1409
- }).filter(Boolean);
1410
- if (changes.length) {
1411
- log4.info("changes", {
1412
- changes
1413
- }, {
1483
+ const state = localStorage.getItem(`${keyPrefix}/${id}`);
1484
+ return state ? JSON.parse(state) : void 0;
1485
+ },
1486
+ setState: (id, state) => {
1487
+ invariant3(id, void 0, {
1414
1488
  F: __dxlog_file6,
1415
- L: 49,
1489
+ L: 53,
1416
1490
  S: void 0,
1417
- C: (f, a) => f(...a)
1491
+ A: [
1492
+ "id",
1493
+ ""
1494
+ ]
1418
1495
  });
1496
+ localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state));
1419
1497
  }
1498
+ });
1499
+ var selectionState = ({ getState, setState } = {}) => {
1500
+ const setStateDebounced = debounce(setState, 1e3);
1501
+ return [
1502
+ // TODO(burdon): Track scrolling (currently only updates when cursor moves).
1503
+ // EditorView.domEventHandlers({
1504
+ // scroll: (event) => {
1505
+ // setStateDebounced(id, {});
1506
+ // },
1507
+ // }),
1508
+ EditorView7.updateListener.of(({ view, transactions }) => {
1509
+ const id = view.state.facet(documentId);
1510
+ if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
1511
+ return;
1512
+ }
1513
+ if (setState) {
1514
+ const { scrollTop } = view.scrollDOM;
1515
+ const pos = view.posAtCoords({
1516
+ x: 0,
1517
+ y: scrollTop
1518
+ });
1519
+ if (pos !== null) {
1520
+ const { anchor, head } = view.state.selection.main;
1521
+ setStateDebounced(id, {
1522
+ scrollTo: pos,
1523
+ selection: {
1524
+ anchor,
1525
+ head
1526
+ }
1527
+ });
1528
+ }
1529
+ }
1530
+ }),
1531
+ getState && keymap4.of([
1532
+ {
1533
+ key: "ctrl-r",
1534
+ run: (view) => {
1535
+ const state = getState(view.state.facet(documentId));
1536
+ if (state) {
1537
+ view.dispatch(createEditorStateTransaction(state));
1538
+ }
1539
+ return true;
1540
+ }
1541
+ }
1542
+ ])
1543
+ ].filter(isNotFalsy2);
1420
1544
  };
1421
1545
 
1422
1546
  // packages/ui/react-ui-editor/src/extensions/comments.ts
@@ -1425,8 +1549,8 @@ var setComments = StateEffect3.define();
1425
1549
  var setSelection = StateEffect3.define();
1426
1550
  var setCommentState = StateEffect3.define();
1427
1551
  var commentsState = StateField4.define({
1428
- create: (state2) => ({
1429
- id: state2.facet(documentId),
1552
+ create: (state) => ({
1553
+ id: state.facet(documentId),
1430
1554
  comments: [],
1431
1555
  selection: {}
1432
1556
  }),
@@ -1462,7 +1586,7 @@ var commentsState = StateField4.define({
1462
1586
  return value;
1463
1587
  }
1464
1588
  });
1465
- var styles3 = EditorView7.theme({
1589
+ var styles3 = EditorView8.theme({
1466
1590
  ".cm-comment, .cm-comment-current": {
1467
1591
  margin: "0 -3px",
1468
1592
  padding: "3px",
@@ -1482,16 +1606,16 @@ var createCommentMark = (id, isCurrent) => Decoration4.mark({
1482
1606
  "data-comment-id": id
1483
1607
  }
1484
1608
  });
1485
- var commentsDecorations = EditorView7.decorations.compute([
1609
+ var commentsDecorations = EditorView8.decorations.compute([
1486
1610
  commentsState
1487
- ], (state2) => {
1488
- const { selection: { current }, comments: comments2 } = state2.field(commentsState);
1611
+ ], (state) => {
1612
+ const { selection: { current }, comments: comments2 } = state.field(commentsState);
1489
1613
  const decorations = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
1490
1614
  const range = comment.range;
1491
1615
  if (!range) {
1492
- log5.warn("Invalid range:", range, {
1616
+ log4.warn("Invalid range:", range, {
1493
1617
  F: __dxlog_file7,
1494
- L: 143,
1618
+ L: 142,
1495
1619
  S: void 0,
1496
1620
  C: (f, a) => f(...a)
1497
1621
  });
@@ -1505,7 +1629,7 @@ var commentsDecorations = EditorView7.decorations.compute([
1505
1629
  return Decoration4.set(decorations);
1506
1630
  });
1507
1631
  var commentClickedEffect = StateEffect3.define();
1508
- var handleCommentClick = EditorView7.domEventHandlers({
1632
+ var handleCommentClick = EditorView8.domEventHandlers({
1509
1633
  click: (event, view) => {
1510
1634
  let target = event.target;
1511
1635
  const editorRoot = view.dom;
@@ -1544,7 +1668,7 @@ var trackPastedComments = (onUpdate) => {
1544
1668
  }
1545
1669
  };
1546
1670
  return [
1547
- EditorView7.domEventHandlers({
1671
+ EditorView8.domEventHandlers({
1548
1672
  cut: handleTrack,
1549
1673
  copy: handleTrack
1550
1674
  }),
@@ -1566,7 +1690,7 @@ var trackPastedComments = (onUpdate) => {
1566
1690
  return effects;
1567
1691
  }),
1568
1692
  // Handle paste or the undo of comment deletion.
1569
- EditorView7.updateListener.of((update2) => {
1693
+ EditorView8.updateListener.of((update2) => {
1570
1694
  const restore = [];
1571
1695
  for (let i = 0; i < update2.transactions.length; i++) {
1572
1696
  const tr = update2.transactions[i];
@@ -1656,7 +1780,7 @@ var createComment = (view) => {
1656
1780
  var optionsFacet = singleValueFacet();
1657
1781
  var comments = (options = {}) => {
1658
1782
  const { key: shortcut = "meta-'" } = options;
1659
- const handleSelect = debounce((state2) => options.onSelect?.(state2), 200);
1783
+ const handleSelect = debounce2((state) => options.onSelect?.(state), 200);
1660
1784
  return [
1661
1785
  optionsFacet.of(options),
1662
1786
  options.id ? documentId.of(options.id) : void 0,
@@ -1667,7 +1791,7 @@ var comments = (options = {}) => {
1667
1791
  //
1668
1792
  // Keymap.
1669
1793
  //
1670
- options.onCreate && keymap4.of([
1794
+ options.onCreate && keymap5.of([
1671
1795
  {
1672
1796
  key: shortcut,
1673
1797
  run: callbackWrapper(createComment)
@@ -1706,9 +1830,9 @@ var comments = (options = {}) => {
1706
1830
  //
1707
1831
  // Track deleted ranges and update ranges for decorations.
1708
1832
  //
1709
- EditorView7.updateListener.of(({ view, state: state2, changes }) => {
1833
+ EditorView8.updateListener.of(({ view, state, changes }) => {
1710
1834
  let mod = false;
1711
- const { comments: comments2, ...value } = state2.field(commentsState);
1835
+ const { comments: comments2, ...value } = state.field(commentsState);
1712
1836
  changes.iterChanges((from, to, from2, to2) => {
1713
1837
  comments2.forEach(({ comment, range }) => {
1714
1838
  if (from2 === to2) {
@@ -1738,10 +1862,10 @@ var comments = (options = {}) => {
1738
1862
  //
1739
1863
  // Track selection/proximity.
1740
1864
  //
1741
- EditorView7.updateListener.of(({ view, state: state2 }) => {
1865
+ EditorView8.updateListener.of(({ view, state }) => {
1742
1866
  let min = Infinity;
1743
- const { selection: { current, closest }, comments: comments2 } = state2.field(commentsState);
1744
- const { head } = state2.selection.main;
1867
+ const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
1868
+ const { head } = state.selection.main;
1745
1869
  const selection = {};
1746
1870
  comments2.forEach(({ comment, range }) => {
1747
1871
  if (head >= range.from && head <= range.to) {
@@ -1762,7 +1886,7 @@ var comments = (options = {}) => {
1762
1886
  });
1763
1887
  handleSelect({
1764
1888
  selection,
1765
- id: state2.facet(documentId),
1889
+ id: state.facet(documentId),
1766
1890
  comments: comments2.map(({ comment, range }) => ({
1767
1891
  comment,
1768
1892
  range,
@@ -1792,7 +1916,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
1792
1916
  anchor: range.from
1793
1917
  } : void 0,
1794
1918
  effects: [
1795
- needsScroll ? EditorView7.scrollIntoView(range.from, center ? {
1919
+ needsScroll ? EditorView8.scrollIntoView(range.from, center ? {
1796
1920
  y: "center"
1797
1921
  } : void 0) : [],
1798
1922
  needsSelectionUpdate ? setSelection.of({
@@ -1803,12 +1927,12 @@ var scrollThreadIntoView = (view, id, center = true) => {
1803
1927
  }
1804
1928
  }
1805
1929
  };
1806
- var selectionOverlapsComment = (state2) => {
1807
- const commentState = state2.field(commentsState, false);
1930
+ var selectionOverlapsComment = (state) => {
1931
+ const commentState = state.field(commentsState, false);
1808
1932
  if (commentState === void 0) {
1809
1933
  return false;
1810
1934
  }
1811
- const { selection } = state2;
1935
+ const { selection } = state;
1812
1936
  for (const range of selection.ranges) {
1813
1937
  if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
1814
1938
  return true;
@@ -1816,8 +1940,8 @@ var selectionOverlapsComment = (state2) => {
1816
1940
  }
1817
1941
  return false;
1818
1942
  };
1819
- var hasActiveSelection = (state2) => {
1820
- return state2.selection.ranges.some((range) => !range.empty);
1943
+ var hasActiveSelection = (state) => {
1944
+ return state.selection.ranges.some((range) => !range.empty);
1821
1945
  };
1822
1946
  var ExternalCommentSync = class {
1823
1947
  constructor(view, id, subscribe, getComments) {
@@ -1844,11 +1968,11 @@ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin4.from
1844
1968
  }
1845
1969
  });
1846
1970
  var useCommentState = () => {
1847
- const [state2, setState] = useState({
1971
+ const [state, setState] = useState({
1848
1972
  comment: false,
1849
1973
  selection: false
1850
1974
  });
1851
- const observer = useMemo(() => EditorView7.updateListener.of((update2) => {
1975
+ const observer = useMemo(() => EditorView8.updateListener.of((update2) => {
1852
1976
  if (update2.docChanged || update2.selectionSet) {
1853
1977
  setState({
1854
1978
  comment: selectionOverlapsComment(update2.state),
@@ -1857,7 +1981,7 @@ var useCommentState = () => {
1857
1981
  }
1858
1982
  }), []);
1859
1983
  return [
1860
- state2,
1984
+ state,
1861
1985
  observer
1862
1986
  ];
1863
1987
  };
@@ -1876,7 +2000,7 @@ var useComments = (view, id, comments2) => {
1876
2000
  });
1877
2001
  };
1878
2002
  var useCommentClickListener = (onCommentClick) => {
1879
- return useMemo(() => EditorView7.updateListener.of((update2) => {
2003
+ return useMemo(() => EditorView8.updateListener.of((update2) => {
1880
2004
  update2.transactions.forEach((transaction) => {
1881
2005
  transaction.effects.forEach((effect) => {
1882
2006
  if (effect.is(commentClickedEffect)) {
@@ -1892,19 +2016,19 @@ var useCommentClickListener = (onCommentClick) => {
1892
2016
  // packages/ui/react-ui-editor/src/extensions/debug.ts
1893
2017
  import { syntaxTree } from "@codemirror/language";
1894
2018
  import { StateField as StateField5 } from "@codemirror/state";
1895
- var debugNodeLogger = (log9 = console.log) => {
1896
- const logTokens = (state2) => syntaxTree(state2).iterate({
1897
- enter: (node) => log9(node.type)
2019
+ var debugNodeLogger = (log8 = console.log) => {
2020
+ const logTokens = (state) => syntaxTree(state).iterate({
2021
+ enter: (node) => log8(node.type)
1898
2022
  });
1899
2023
  return StateField5.define({
1900
- create: (state2) => logTokens(state2),
2024
+ create: (state) => logTokens(state),
1901
2025
  update: (_, tr) => logTokens(tr.state)
1902
2026
  });
1903
2027
  };
1904
2028
 
1905
2029
  // packages/ui/react-ui-editor/src/extensions/dnd.ts
1906
- import { dropCursor, EditorView as EditorView8 } from "@codemirror/view";
1907
- var styles4 = EditorView8.theme({
2030
+ import { dropCursor, EditorView as EditorView9 } from "@codemirror/view";
2031
+ var styles4 = EditorView9.theme({
1908
2032
  ".cm-dropCursor": {
1909
2033
  borderLeft: "2px solid var(--dx-accentText)",
1910
2034
  color: "var(--dx-accentText)",
@@ -1918,7 +2042,7 @@ var dropFile = (options = {}) => {
1918
2042
  return [
1919
2043
  styles4,
1920
2044
  dropCursor(),
1921
- EditorView8.domEventHandlers({
2045
+ EditorView9.domEventHandlers({
1922
2046
  drop: (event, view) => {
1923
2047
  event.preventDefault();
1924
2048
  const files = event.dataTransfer?.files;
@@ -1945,13 +2069,44 @@ import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@cod
1945
2069
  import { searchKeymap } from "@codemirror/search";
1946
2070
  import { EditorState } from "@codemirror/state";
1947
2071
  import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
1948
- import { EditorView as EditorView9, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap5, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
2072
+ import { EditorView as EditorView11, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
1949
2073
  import defaultsDeep2 from "lodash.defaultsdeep";
1950
2074
  import merge from "lodash.merge";
1951
2075
  import { generateName } from "@dxos/display-name";
1952
- import { log as log6 } from "@dxos/log";
2076
+ import { log as log5 } from "@dxos/log";
1953
2077
  import { hueTokens } from "@dxos/react-ui-theme";
1954
- import { hexToHue, isNotFalsy as isNotFalsy2 } from "@dxos/util";
2078
+ import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
2079
+
2080
+ // packages/ui/react-ui-editor/src/extensions/focus.ts
2081
+ import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
2082
+ import { EditorView as EditorView10 } from "@codemirror/view";
2083
+ var focusEffect = StateEffect4.define();
2084
+ var focusField = StateField6.define({
2085
+ create: () => false,
2086
+ update: (value, tr) => {
2087
+ for (const effect of tr.effects) {
2088
+ if (effect.is(focusEffect)) {
2089
+ return effect.value;
2090
+ }
2091
+ }
2092
+ return value;
2093
+ }
2094
+ });
2095
+ var focus = [
2096
+ focusField,
2097
+ EditorView10.domEventHandlers({
2098
+ focus: (event, view) => {
2099
+ setTimeout(() => view.dispatch({
2100
+ effects: focusEffect.of(true)
2101
+ }));
2102
+ },
2103
+ blur: (event, view) => {
2104
+ setTimeout(() => view.dispatch({
2105
+ effects: focusEffect.of(false)
2106
+ }));
2107
+ }
2108
+ })
2109
+ ];
1955
2110
 
1956
2111
  // packages/ui/react-ui-editor/src/styles/markdown.ts
1957
2112
  import { mx } from "@dxos/react-ui-theme";
@@ -2190,6 +2345,7 @@ var defaultBasicOptions = {
2190
2345
  closeBrackets: true,
2191
2346
  drawSelection: true,
2192
2347
  editable: true,
2348
+ focus: true,
2193
2349
  history: true,
2194
2350
  keymap: "standard",
2195
2351
  lineWrapping: true,
@@ -2205,10 +2361,10 @@ var createBasicExtensions = (_props) => {
2205
2361
  const props = defaultsDeep2({}, _props, defaultBasicOptions);
2206
2362
  return [
2207
2363
  // NOTE: Doesn't catch errors in keymap functions.
2208
- EditorView9.exceptionSink.of((err) => {
2209
- log6.catch(err, void 0, {
2364
+ EditorView11.exceptionSink.of((err) => {
2365
+ log5.catch(err, void 0, {
2210
2366
  F: __dxlog_file8,
2211
- L: 93,
2367
+ L: 96,
2212
2368
  S: void 0,
2213
2369
  C: (f, a) => f(...a)
2214
2370
  });
@@ -2220,19 +2376,20 @@ var createBasicExtensions = (_props) => {
2220
2376
  props.drawSelection && drawSelection({
2221
2377
  cursorBlinkRate: 1200
2222
2378
  }),
2379
+ props.focus && focus,
2223
2380
  props.highlightActiveLine && highlightActiveLine(),
2224
2381
  props.history && history(),
2225
2382
  props.lineNumbers && lineNumbers(),
2226
- props.lineWrapping && EditorView9.lineWrapping,
2383
+ props.lineWrapping && EditorView11.lineWrapping,
2227
2384
  props.placeholder && placeholder(props.placeholder),
2228
2385
  props.readonly && [
2229
2386
  EditorState.readOnly.of(true),
2230
- EditorView9.editable.of(false)
2387
+ EditorView11.editable.of(false)
2231
2388
  ],
2232
2389
  props.scrollPastEnd && scrollPastEnd(),
2233
2390
  props.tabSize && EditorState.tabSize.of(props.tabSize),
2234
2391
  // https://codemirror.net/docs/ref/#view.KeyBinding
2235
- keymap5.of([
2392
+ keymap6.of([
2236
2393
  ...(props.keymap && keymaps[props.keymap]) ?? [],
2237
2394
  // NOTE: Tabs are also configured by markdown extension.
2238
2395
  // https://codemirror.net/docs/ref/#commands.indentWithTab
@@ -2245,8 +2402,8 @@ var createBasicExtensions = (_props) => {
2245
2402
  ...props.history ? historyKeymap : [],
2246
2403
  // https://codemirror.net/docs/ref/#search.searchKeymap
2247
2404
  ...props.search ? searchKeymap : []
2248
- ].filter(isNotFalsy2))
2249
- ].filter(isNotFalsy2);
2405
+ ].filter(isNotFalsy3))
2406
+ ].filter(isNotFalsy3);
2250
2407
  };
2251
2408
  var defaultThemeSlots = {
2252
2409
  editor: {
@@ -2256,17 +2413,17 @@ var defaultThemeSlots = {
2256
2413
  var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
2257
2414
  const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
2258
2415
  return [
2259
- EditorView9.darkTheme.of(themeMode === "dark"),
2260
- EditorView9.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2416
+ EditorView11.darkTheme.of(themeMode === "dark"),
2417
+ EditorView11.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2261
2418
  // https://github.com/codemirror/theme-one-dark
2262
2419
  _syntaxHighlighting && (themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)),
2263
- slots.editor?.className && EditorView9.editorAttributes.of({
2420
+ slots.editor?.className && EditorView11.editorAttributes.of({
2264
2421
  class: slots.editor.className
2265
2422
  }),
2266
- slots.content?.className && EditorView9.contentAttributes.of({
2423
+ slots.content?.className && EditorView11.contentAttributes.of({
2267
2424
  class: slots.content.className
2268
2425
  })
2269
- ].filter(isNotFalsy2);
2426
+ ].filter(isNotFalsy3);
2270
2427
  };
2271
2428
  var createDataExtensions = ({ id, text, space, identity }) => {
2272
2429
  const extensions = [];
@@ -2292,7 +2449,7 @@ var createDataExtensions = ({ id, text, space, identity }) => {
2292
2449
 
2293
2450
  // packages/ui/react-ui-editor/src/extensions/folding.tsx
2294
2451
  import { codeFolding, foldGutter } from "@codemirror/language";
2295
- import { EditorView as EditorView10 } from "@codemirror/view";
2452
+ import { EditorView as EditorView12 } from "@codemirror/view";
2296
2453
  import React2 from "react";
2297
2454
  import { Icon } from "@dxos/react-ui";
2298
2455
  var folding = (_props = {}) => [
@@ -2316,7 +2473,7 @@ var folding = (_props = {}) => [
2316
2473
  }));
2317
2474
  }
2318
2475
  }),
2319
- EditorView10.theme({
2476
+ EditorView12.theme({
2320
2477
  ".cm-foldGutter": {
2321
2478
  opacity: 0.3,
2322
2479
  transition: "opacity 0.3s",
@@ -2329,14 +2486,14 @@ var folding = (_props = {}) => [
2329
2486
  ];
2330
2487
 
2331
2488
  // packages/ui/react-ui-editor/src/extensions/listener.ts
2332
- import { EditorView as EditorView11 } from "@codemirror/view";
2489
+ import { EditorView as EditorView13 } from "@codemirror/view";
2333
2490
  var listener = ({ onFocus, onChange }) => {
2334
2491
  const extensions = [];
2335
- onFocus && extensions.push(EditorView11.focusChangeEffect.of((_, focusing) => {
2492
+ onFocus && extensions.push(EditorView13.focusChangeEffect.of((_, focusing) => {
2336
2493
  onFocus(focusing);
2337
2494
  return null;
2338
2495
  }));
2339
- onChange && extensions.push(EditorView11.updateListener.of((update2) => {
2496
+ onChange && extensions.push(EditorView13.updateListener.of((update2) => {
2340
2497
  onChange(update2.state.doc.toString());
2341
2498
  }));
2342
2499
  return extensions;
@@ -2346,7 +2503,7 @@ var listener = ({ onFocus, onChange }) => {
2346
2503
  import { snippet } from "@codemirror/autocomplete";
2347
2504
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
2348
2505
  import { EditorSelection } from "@codemirror/state";
2349
- import { EditorView as EditorView12, keymap as keymap6 } from "@codemirror/view";
2506
+ import { EditorView as EditorView14, keymap as keymap7 } from "@codemirror/view";
2350
2507
  import { useMemo as useMemo2, useState as useState2 } from "react";
2351
2508
  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;
2352
2509
  var Inline;
@@ -2363,13 +2520,13 @@ var List;
2363
2520
  List2[List2["Task"] = 2] = "Task";
2364
2521
  })(List || (List = {}));
2365
2522
  var setHeading = (level) => {
2366
- return ({ state: state2, dispatch }) => {
2367
- const { selection: { ranges }, doc } = state2;
2523
+ return ({ state, dispatch }) => {
2524
+ const { selection: { ranges }, doc } = state;
2368
2525
  const changes = [];
2369
2526
  let prevBlock = -1;
2370
2527
  for (const range of ranges) {
2371
2528
  let sawBlock = false;
2372
- syntaxTree2(state2).iterate({
2529
+ syntaxTree2(state).iterate({
2373
2530
  from: range.from,
2374
2531
  to: range.to,
2375
2532
  enter: (node) => {
@@ -2422,7 +2579,7 @@ var setHeading = (level) => {
2422
2579
  }
2423
2580
  });
2424
2581
  let line;
2425
- if (!sawBlock && range.empty && level > 0 && !/\S/.test((line = state2.doc.lineAt(range.from)).text)) {
2582
+ if (!sawBlock && range.empty && level > 0 && !/\S/.test((line = state.doc.lineAt(range.from)).text)) {
2426
2583
  changes.push({
2427
2584
  from: line.from,
2428
2585
  to: line.to,
@@ -2433,10 +2590,10 @@ var setHeading = (level) => {
2433
2590
  if (!changes.length) {
2434
2591
  return false;
2435
2592
  }
2436
- const changeSet = state2.changes(changes);
2437
- dispatch(state2.update({
2593
+ const changeSet = state.changes(changes);
2594
+ dispatch(state.update({
2438
2595
  changes: changeSet,
2439
- selection: state2.selection.map(changeSet, 1),
2596
+ selection: state.selection.map(changeSet, 1),
2440
2597
  userEvent: "format.setHeading",
2441
2598
  scrollIntoView: true
2442
2599
  }));
@@ -2444,14 +2601,14 @@ var setHeading = (level) => {
2444
2601
  };
2445
2602
  };
2446
2603
  var setStyle = (type, enable) => {
2447
- return ({ state: state2, dispatch }) => {
2604
+ return ({ state, dispatch }) => {
2448
2605
  const marker = inlineMarkerText(type);
2449
- const changes = state2.changeByRange((range) => {
2606
+ const changes = state.changeByRange((range) => {
2450
2607
  if (!enable && range.empty) {
2451
- const after = state2.doc.sliceString(range.head, range.head + 6);
2608
+ const after = state.doc.sliceString(range.head, range.head + 6);
2452
2609
  const found = after.indexOf(marker);
2453
2610
  if (found >= 0 && /^[*~`]*$/.test(after.slice(0, found))) {
2454
- const before = state2.doc.sliceString(range.head - 6, range.head);
2611
+ const before = state.doc.sliceString(range.head - 6, range.head);
2455
2612
  if (before.slice(before.length - found - marker.length, before.length - found) === marker && [
2456
2613
  ...before.slice(before.length - found)
2457
2614
  ].reverse().join("") === after.slice(0, found)) {
@@ -2478,14 +2635,14 @@ var setStyle = (type, enable) => {
2478
2635
  let startCovered = false;
2479
2636
  let endCovered = false;
2480
2637
  let { from, to } = range;
2481
- syntaxTree2(state2).iterate({
2638
+ syntaxTree2(state).iterate({
2482
2639
  from,
2483
2640
  to,
2484
2641
  enter: (node) => {
2485
2642
  const { name } = node;
2486
2643
  if (Object.hasOwn(Textblocks, name) && Textblocks[name] !== "codeblock") {
2487
2644
  blockStart = blockContentStart(node);
2488
- blockEnd = blockContentEnd(node, state2.doc);
2645
+ blockEnd = blockContentEnd(node, state.doc);
2489
2646
  startCovered = endCovered = false;
2490
2647
  } else if (name === "Link" || name === "Image" && enable) {
2491
2648
  if (from < node.from && to > node.from && to <= node.to) {
@@ -2530,7 +2687,7 @@ var setStyle = (type, enable) => {
2530
2687
  });
2531
2688
  if (markType !== type && closeStart >= to) {
2532
2689
  changesAtEnd.push({
2533
- from: skipSpaces(Math.min(to, blockEnd), state2.doc, 1, blockEnd),
2690
+ from: skipSpaces(Math.min(to, blockEnd), state.doc, 1, blockEnd),
2534
2691
  insert: inlineMarkerText(markType)
2535
2692
  });
2536
2693
  }
@@ -2542,7 +2699,7 @@ var setStyle = (type, enable) => {
2542
2699
  });
2543
2700
  if (markType !== type && openEnd <= from) {
2544
2701
  changes2.push({
2545
- from: skipSpaces(Math.max(from, blockStart), state2.doc, -1, blockStart),
2702
+ from: skipSpaces(Math.max(from, blockStart), state.doc, -1, blockStart),
2546
2703
  insert: inlineMarkerText(markType)
2547
2704
  });
2548
2705
  }
@@ -2572,7 +2729,7 @@ var setStyle = (type, enable) => {
2572
2729
  changes2.push(startCovered);
2573
2730
  } else if (startCovered) {
2574
2731
  changes2.push({
2575
- from: skipSpaces(rangeStart, state2.doc, -1, blockStart),
2732
+ from: skipSpaces(rangeStart, state.doc, -1, blockStart),
2576
2733
  insert: marker
2577
2734
  });
2578
2735
  }
@@ -2580,7 +2737,7 @@ var setStyle = (type, enable) => {
2580
2737
  changes2.push(endCovered);
2581
2738
  } else if (endCovered) {
2582
2739
  changes2.push({
2583
- from: skipSpaces(rangeEnd, state2.doc, 1, blockEnd),
2740
+ from: skipSpaces(rangeEnd, state.doc, 1, blockEnd),
2584
2741
  insert: marker
2585
2742
  });
2586
2743
  }
@@ -2588,7 +2745,7 @@ var setStyle = (type, enable) => {
2588
2745
  }
2589
2746
  }
2590
2747
  });
2591
- if (blockStart < 0 && range.empty && enable && !/\S/.test(state2.doc.lineAt(range.from).text)) {
2748
+ if (blockStart < 0 && range.empty && enable && !/\S/.test(state.doc.lineAt(range.from).text)) {
2592
2749
  return {
2593
2750
  changes: {
2594
2751
  from: range.head,
@@ -2597,13 +2754,13 @@ var setStyle = (type, enable) => {
2597
2754
  range: EditorSelection.cursor(range.head + marker.length)
2598
2755
  };
2599
2756
  }
2600
- const changeSet = state2.changes(changes2.concat(changesAtEnd));
2757
+ const changeSet = state.changes(changes2.concat(changesAtEnd));
2601
2758
  return {
2602
2759
  changes: changeSet,
2603
2760
  range: range.empty && !changeSet.empty ? EditorSelection.cursor(range.head + marker.length) : EditorSelection.range(changeSet.mapPos(range.from, 1), changeSet.mapPos(range.to, -1))
2604
2761
  };
2605
2762
  });
2606
- dispatch(state2.update(changes, {
2763
+ dispatch(state.update(changes, {
2607
2764
  userEvent: enable ? "format.style.add" : "format.style.remove",
2608
2765
  scrollIntoView: true
2609
2766
  }));
@@ -2680,8 +2837,8 @@ var insertTable = (view) => {
2680
2837
  const { from } = doc.line(number);
2681
2838
  snippets.table(view, null, from, from);
2682
2839
  };
2683
- var removeLinkInner = (from, to, changes, state2) => {
2684
- syntaxTree2(state2).iterate({
2840
+ var removeLinkInner = (from, to, changes, state) => {
2841
+ syntaxTree2(state).iterate({
2685
2842
  from,
2686
2843
  to,
2687
2844
  enter: (node) => {
@@ -2695,8 +2852,8 @@ var removeLinkInner = (from, to, changes, state2) => {
2695
2852
  });
2696
2853
  } else if (name === "LinkTitle" || name === "URL") {
2697
2854
  changes.push({
2698
- from: skipSpaces(node2.from, state2.doc, -1),
2699
- to: skipSpaces(node2.to, state2.doc, 1)
2855
+ from: skipSpaces(node2.from, state.doc, -1),
2856
+ to: skipSpaces(node2.to, state.doc, 1)
2700
2857
  });
2701
2858
  }
2702
2859
  });
@@ -2705,15 +2862,15 @@ var removeLinkInner = (from, to, changes, state2) => {
2705
2862
  }
2706
2863
  });
2707
2864
  };
2708
- var removeLink = ({ state: state2, dispatch }) => {
2865
+ var removeLink = ({ state, dispatch }) => {
2709
2866
  const changes = [];
2710
- for (const { from, to } of state2.selection.ranges) {
2711
- removeLinkInner(from, to, changes, state2);
2867
+ for (const { from, to } of state.selection.ranges) {
2868
+ removeLinkInner(from, to, changes, state);
2712
2869
  }
2713
2870
  if (!changes) {
2714
2871
  return false;
2715
2872
  }
2716
- dispatch(state2.update({
2873
+ dispatch(state.update({
2717
2874
  changes,
2718
2875
  userEvent: "format.link.remove",
2719
2876
  scrollIntoView: true
@@ -2721,17 +2878,17 @@ var removeLink = ({ state: state2, dispatch }) => {
2721
2878
  return true;
2722
2879
  };
2723
2880
  var addLink = ({ url, image: image2 } = {}) => {
2724
- return ({ state: state2, dispatch }) => {
2725
- const changes = state2.changeByRange((range) => {
2881
+ return ({ state, dispatch }) => {
2882
+ const changes = state.changeByRange((range) => {
2726
2883
  let { from, to } = range;
2727
2884
  const cutStyles = [];
2728
2885
  let okay = null;
2729
- syntaxTree2(state2).iterate({
2886
+ syntaxTree2(state).iterate({
2730
2887
  from,
2731
2888
  to,
2732
2889
  enter: (node) => {
2733
2890
  if (Object.hasOwn(Textblocks, node.name)) {
2734
- okay = Textblocks[node.name] !== "codeblock" && from >= blockContentStart(node) && to <= blockContentEnd(node, state2.doc);
2891
+ okay = Textblocks[node.name] !== "codeblock" && from >= blockContentStart(node) && to <= blockContentEnd(node, state.doc);
2735
2892
  } else if (Object.hasOwn(InlineMarker, node.name)) {
2736
2893
  const sNode = node.node;
2737
2894
  if (node.from < from && node.to <= to) {
@@ -2751,7 +2908,7 @@ var addLink = ({ url, image: image2 } = {}) => {
2751
2908
  }
2752
2909
  });
2753
2910
  if (okay === null) {
2754
- const line = state2.doc.lineAt(from);
2911
+ const line = state.doc.lineAt(from);
2755
2912
  okay = to <= line.to && !/\S/.test(line.text.slice(from - line.from));
2756
2913
  }
2757
2914
  if (!okay) {
@@ -2761,26 +2918,26 @@ var addLink = ({ url, image: image2 } = {}) => {
2761
2918
  }
2762
2919
  const changes2 = [];
2763
2920
  const changesAfter = [];
2764
- removeLinkInner(from, to, changesAfter, state2);
2921
+ removeLinkInner(from, to, changesAfter, state);
2765
2922
  let cursorOffset = 1;
2766
2923
  for (const style of cutStyles) {
2767
2924
  const type = InlineMarker[style.name];
2768
2925
  const mark = inlineMarkerText(type);
2769
2926
  if (style.from < from) {
2770
2927
  changes2.push({
2771
- from: skipSpaces(from, state2.doc, -1),
2928
+ from: skipSpaces(from, state.doc, -1),
2772
2929
  insert: mark
2773
2930
  });
2774
2931
  changesAfter.push({
2775
- from: skipSpaces(from, state2.doc, 1, to),
2932
+ from: skipSpaces(from, state.doc, 1, to),
2776
2933
  insert: mark
2777
2934
  });
2778
2935
  } else {
2779
2936
  changes2.push({
2780
- from: skipSpaces(to, state2.doc, -1, from),
2937
+ from: skipSpaces(to, state.doc, -1, from),
2781
2938
  insert: mark
2782
2939
  });
2783
- const after = skipSpaces(to, state2.doc, 1);
2940
+ const after = skipSpaces(to, state.doc, 1);
2784
2941
  if (after === to) {
2785
2942
  cursorOffset += mark.length;
2786
2943
  }
@@ -2797,7 +2954,7 @@ var addLink = ({ url, image: image2 } = {}) => {
2797
2954
  from: to,
2798
2955
  insert: `](${url ?? ""})`
2799
2956
  });
2800
- const changeSet = state2.changes(changes2.concat(changesAfter));
2957
+ const changeSet = state.changes(changes2.concat(changesAfter));
2801
2958
  return {
2802
2959
  changes: changeSet,
2803
2960
  range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset - (url ? url.length + 2 : 0))
@@ -2806,7 +2963,7 @@ var addLink = ({ url, image: image2 } = {}) => {
2806
2963
  if (changes.changes.empty) {
2807
2964
  return false;
2808
2965
  }
2809
- dispatch(state2.update(changes, {
2966
+ dispatch(state.update(changes, {
2810
2967
  userEvent: "format.link.add",
2811
2968
  scrollIntoView: true
2812
2969
  }));
@@ -2814,14 +2971,14 @@ var addLink = ({ url, image: image2 } = {}) => {
2814
2971
  };
2815
2972
  };
2816
2973
  var addList = (type) => {
2817
- return ({ state: state2, dispatch }) => {
2974
+ return ({ state, dispatch }) => {
2818
2975
  let lastBlock = -1;
2819
2976
  let counter = 1;
2820
2977
  let first = true;
2821
2978
  let parentColumn = null;
2822
2979
  const blocks = [];
2823
- for (const { from, to } of state2.selection.ranges) {
2824
- syntaxTree2(state2).iterate({
2980
+ for (const { from, to } of state.selection.ranges) {
2981
+ syntaxTree2(state).iterate({
2825
2982
  from,
2826
2983
  to,
2827
2984
  enter: (node) => {
@@ -2833,7 +2990,7 @@ var addList = (type) => {
2833
2990
  }
2834
2991
  if (before?.name === (type === 0 ? "OrderedList" : "BulletList")) {
2835
2992
  const item = before.lastChild;
2836
- const itemLine = state2.doc.lineAt(item.from);
2993
+ const itemLine = state.doc.lineAt(item.from);
2837
2994
  const itemText = itemLine.text.slice(item.from - itemLine.from);
2838
2995
  parentColumn = item.from - itemLine.from + /^\s*/.exec(itemText)[0].length;
2839
2996
  if (type === 0) {
@@ -2868,10 +3025,10 @@ var addList = (type) => {
2868
3025
  });
2869
3026
  }
2870
3027
  if (!blocks.length) {
2871
- const { from, to } = state2.doc.lineAt(state2.selection.main.anchor);
3028
+ const { from, to } = state.doc.lineAt(state.selection.main.anchor);
2872
3029
  if (from === to) {
2873
3030
  const insert = type === 1 ? "- " : type === 0 ? "1. " : "- [ ] ";
2874
- dispatch(state2.update({
3031
+ dispatch(state.update({
2875
3032
  changes: [
2876
3033
  {
2877
3034
  from,
@@ -2892,11 +3049,11 @@ var addList = (type) => {
2892
3049
  for (let i = 0; i < blocks.length; i++) {
2893
3050
  const { node, counter: counter2, parentColumn: parentColumn2 } = blocks[i];
2894
3051
  const nodeFrom = node.name === "CodeBlock" ? node.from - 4 : node.from;
2895
- let padding = nodeFrom > 0 && !/\s/.test(state2.doc.sliceString(nodeFrom - 1, nodeFrom)) ? 1 : 0;
3052
+ let padding = nodeFrom > 0 && !/\s/.test(state.doc.sliceString(nodeFrom - 1, nodeFrom)) ? 1 : 0;
2896
3053
  if (type === 0) {
2897
3054
  padding += String(counter2).length;
2898
3055
  }
2899
- let line = state2.doc.lineAt(nodeFrom);
3056
+ let line = state.doc.lineAt(nodeFrom);
2900
3057
  const column = nodeFrom - line.from;
2901
3058
  if (parentColumn2 !== null && parentColumn2 > column) {
2902
3059
  padding = Math.max(padding, parentColumn2 - column);
@@ -2921,7 +3078,7 @@ var addList = (type) => {
2921
3078
  insert: mark
2922
3079
  });
2923
3080
  while (line.to < node.to) {
2924
- line = state2.doc.lineAt(line.to + 1);
3081
+ line = state.doc.lineAt(line.to + 1);
2925
3082
  const open = /^[\s>]*/.exec(line.text)[0].length;
2926
3083
  changes.push({
2927
3084
  from: line.from + Math.min(open, column),
@@ -2936,13 +3093,13 @@ var addList = (type) => {
2936
3093
  next = next.nextSibling;
2937
3094
  }
2938
3095
  if (next?.name === "OrderedList") {
2939
- renumberListItems(next.firstChild, last.counter + 1, changes, state2.doc);
3096
+ renumberListItems(next.firstChild, last.counter + 1, changes, state.doc);
2940
3097
  }
2941
3098
  }
2942
- const changeSet = state2.changes(changes);
2943
- dispatch(state2.update({
3099
+ const changeSet = state.changes(changes);
3100
+ dispatch(state.update({
2944
3101
  changes: changeSet,
2945
- selection: state2.selection.map(changeSet, 1),
3102
+ selection: state.selection.map(changeSet, 1),
2946
3103
  userEvent: "format.list.add",
2947
3104
  scrollIntoView: true
2948
3105
  }));
@@ -2950,13 +3107,13 @@ var addList = (type) => {
2950
3107
  };
2951
3108
  };
2952
3109
  var removeList = (type) => {
2953
- return ({ state: state2, dispatch }) => {
3110
+ return ({ state, dispatch }) => {
2954
3111
  let lastBlock = -1;
2955
3112
  const changes = [];
2956
3113
  const stack = [];
2957
3114
  const targetNodeType = type === 0 ? "OrderedList" : type === 1 ? "BulletList" : "TaskList";
2958
- for (const { from, to } of state2.selection.ranges) {
2959
- syntaxTree2(state2).iterate({
3115
+ for (const { from, to } of state.selection.ranges) {
3116
+ syntaxTree2(state).iterate({
2960
3117
  from,
2961
3118
  to,
2962
3119
  enter: (node) => {
@@ -2973,7 +3130,7 @@ var removeList = (type) => {
2973
3130
  stack.pop();
2974
3131
  } else if (name === "ListItem" && stack[stack.length - 1] === targetNodeType && node.from !== lastBlock) {
2975
3132
  lastBlock = node.from;
2976
- let line = state2.doc.lineAt(node.from);
3133
+ let line = state.doc.lineAt(node.from);
2977
3134
  const mark = /^\s*(\d+[.)] |[-*+] (\[[ x]\] )?)/.exec(line.text.slice(node.from - line.from));
2978
3135
  if (!mark) {
2979
3136
  return false;
@@ -2984,7 +3141,7 @@ var removeList = (type) => {
2984
3141
  to: node.from + mark[0].length
2985
3142
  });
2986
3143
  while (line.to < node.to) {
2987
- line = state2.doc.lineAt(line.to + 1);
3144
+ line = state.doc.lineAt(line.to + 1);
2988
3145
  const open = /^[\s>]*/.exec(line.text)[0].length;
2989
3146
  if (open > column) {
2990
3147
  changes.push({
@@ -2994,7 +3151,7 @@ var removeList = (type) => {
2994
3151
  }
2995
3152
  }
2996
3153
  if (node.to >= to) {
2997
- renumberListItems(node.node.nextSibling, 1, changes, state2.doc);
3154
+ renumberListItems(node.node.nextSibling, 1, changes, state.doc);
2998
3155
  }
2999
3156
  return false;
3000
3157
  }
@@ -3004,7 +3161,7 @@ var removeList = (type) => {
3004
3161
  if (!changes.length) {
3005
3162
  return false;
3006
3163
  }
3007
- dispatch(state2.update({
3164
+ dispatch(state.update({
3008
3165
  changes,
3009
3166
  userEvent: "format.list.remove",
3010
3167
  scrollIntoView: true
@@ -3038,12 +3195,12 @@ var renumberListItems = (item, counter, changes, doc) => {
3038
3195
  }
3039
3196
  };
3040
3197
  var setBlockquote = (enable) => {
3041
- return ({ state: state2, dispatch }) => {
3198
+ return ({ state, dispatch }) => {
3042
3199
  const lines = [];
3043
3200
  let lastBlock = -1;
3044
- for (const { from, to } of state2.selection.ranges) {
3201
+ for (const { from, to } of state.selection.ranges) {
3045
3202
  const sawBlock = false;
3046
- syntaxTree2(state2).iterate({
3203
+ syntaxTree2(state).iterate({
3047
3204
  from,
3048
3205
  to,
3049
3206
  enter: (node) => {
@@ -3052,9 +3209,9 @@ var setBlockquote = (enable) => {
3052
3209
  return false;
3053
3210
  }
3054
3211
  lastBlock = node.from;
3055
- let line2 = state2.doc.lineAt(node.from);
3212
+ let line2 = state.doc.lineAt(node.from);
3056
3213
  if (line2.number > 1) {
3057
- const prevLine = state2.doc.line(line2.number - 1);
3214
+ const prevLine = state.doc.line(line2.number - 1);
3058
3215
  if (/^[>\s]*$/.test(prevLine.text)) {
3059
3216
  if (!enable || lines.length && lines[lines.length - 1].number === prevLine.number - 1) {
3060
3217
  lines.push(prevLine);
@@ -3066,10 +3223,10 @@ var setBlockquote = (enable) => {
3066
3223
  if (line2.to >= node.to) {
3067
3224
  break;
3068
3225
  }
3069
- line2 = state2.doc.line(line2.number + 1);
3226
+ line2 = state.doc.line(line2.number + 1);
3070
3227
  }
3071
- if (!enable && line2.number < state2.doc.lines) {
3072
- const nextLine = state2.doc.line(line2.number + 1);
3228
+ if (!enable && line2.number < state.doc.lines) {
3229
+ const nextLine = state.doc.line(line2.number + 1);
3073
3230
  if (/^[>\s]*$/.test(nextLine.text)) {
3074
3231
  lines.push(nextLine);
3075
3232
  }
@@ -3079,7 +3236,7 @@ var setBlockquote = (enable) => {
3079
3236
  }
3080
3237
  });
3081
3238
  let line;
3082
- if (!sawBlock && enable && from === to && !/\S/.test((line = state2.doc.lineAt(from)).text)) {
3239
+ if (!sawBlock && enable && from === to && !/\S/.test((line = state.doc.lineAt(from)).text)) {
3083
3240
  lines.push(line);
3084
3241
  }
3085
3242
  }
@@ -3103,10 +3260,10 @@ var setBlockquote = (enable) => {
3103
3260
  if (!changes.length) {
3104
3261
  return false;
3105
3262
  }
3106
- const changeSet = state2.changes(changes);
3107
- dispatch(state2.update({
3263
+ const changeSet = state.changes(changes);
3264
+ dispatch(state.update({
3108
3265
  changes: changeSet,
3109
- selection: state2.selection.map(changeSet, 1),
3266
+ selection: state.selection.map(changeSet, 1),
3110
3267
  userEvent: enable ? "format.blockquote.add" : "format.blockquote.remove",
3111
3268
  scrollIntoView: true
3112
3269
  }));
@@ -3119,11 +3276,11 @@ var toggleBlockquote = (target) => {
3119
3276
  return (getFormatting(target.state).blockQuote ? removeBlockquote : addBlockquote)(target);
3120
3277
  };
3121
3278
  var addCodeblock = (target) => {
3122
- const { state: state2, dispatch } = target;
3123
- const { selection } = state2;
3279
+ const { state, dispatch } = target;
3280
+ const { selection } = state;
3124
3281
  if (selection.ranges.length === 1 && selection.main.empty) {
3125
3282
  const { head } = selection.main;
3126
- const line = state2.doc.lineAt(head);
3283
+ const line = state.doc.lineAt(head);
3127
3284
  if (!/\S/.test(line.text) && head === line.from) {
3128
3285
  snippets.codeblock(target, null, line.from, line.to);
3129
3286
  return true;
@@ -3133,7 +3290,7 @@ var addCodeblock = (target) => {
3133
3290
  for (const { from, to } of selection.ranges) {
3134
3291
  let blockFrom = from;
3135
3292
  let blockTo = to;
3136
- syntaxTree2(state2).iterate({
3293
+ syntaxTree2(state).iterate({
3137
3294
  from,
3138
3295
  to,
3139
3296
  enter: (node) => {
@@ -3142,8 +3299,8 @@ var addCodeblock = (target) => {
3142
3299
  blockFrom = node.from;
3143
3300
  blockTo = node.to;
3144
3301
  } else {
3145
- blockFrom = Math.min(blockFrom, state2.doc.lineAt(node.from).from);
3146
- blockTo = Math.max(blockTo, state2.doc.lineAt(node.to).to);
3302
+ blockFrom = Math.min(blockFrom, state.doc.lineAt(node.from).from);
3303
+ blockTo = Math.max(blockTo, state.doc.lineAt(node.to).to);
3147
3304
  }
3148
3305
  }
3149
3306
  }
@@ -3161,7 +3318,7 @@ var addCodeblock = (target) => {
3161
3318
  return false;
3162
3319
  }
3163
3320
  const changes = ranges.map(({ from, to }) => {
3164
- const column = from - state2.doc.lineAt(from).from;
3321
+ const column = from - state.doc.lineAt(from).from;
3165
3322
  return [
3166
3323
  {
3167
3324
  from,
@@ -3173,30 +3330,30 @@ var addCodeblock = (target) => {
3173
3330
  }
3174
3331
  ];
3175
3332
  });
3176
- dispatch(state2.update({
3333
+ dispatch(state.update({
3177
3334
  changes,
3178
3335
  userEvent: "format.codeblock.add",
3179
3336
  scrollIntoView: true
3180
3337
  }));
3181
3338
  return true;
3182
3339
  };
3183
- var removeCodeblock = ({ state: state2, dispatch }) => {
3340
+ var removeCodeblock = ({ state, dispatch }) => {
3184
3341
  let lastBlock = -1;
3185
3342
  const changes = [];
3186
- for (const { from, to } of state2.selection.ranges) {
3187
- syntaxTree2(state2).iterate({
3343
+ for (const { from, to } of state.selection.ranges) {
3344
+ syntaxTree2(state).iterate({
3188
3345
  from,
3189
3346
  to,
3190
3347
  enter: (node) => {
3191
3348
  if (Textblocks[node.name] === "codeblock" && lastBlock !== node.from) {
3192
3349
  lastBlock = node.from;
3193
- const firstLine = state2.doc.lineAt(node.from);
3350
+ const firstLine = state.doc.lineAt(node.from);
3194
3351
  if (node.name === "FencedCode") {
3195
3352
  changes.push({
3196
3353
  from: node.from,
3197
3354
  to: firstLine.to + 1 + node.from - firstLine.from
3198
3355
  });
3199
- const lastLine = state2.doc.lineAt(node.to);
3356
+ const lastLine = state.doc.lineAt(node.to);
3200
3357
  if (/^([\s>]|[-*+] |\d+[).])*`+$/.test(lastLine.text)) {
3201
3358
  changes.push({
3202
3359
  from: lastLine.from - (lastLine.number === firstLine.number + 1 ? 0 : 1),
@@ -3205,7 +3362,7 @@ var removeCodeblock = ({ state: state2, dispatch }) => {
3205
3362
  }
3206
3363
  } else {
3207
3364
  const column = node.from - firstLine.from;
3208
- for (let line = firstLine; ; line = state2.doc.line(line.number + 1)) {
3365
+ for (let line = firstLine; ; line = state.doc.line(line.number + 1)) {
3209
3366
  changes.push({
3210
3367
  from: line.from + column - 4,
3211
3368
  to: line.from + column
@@ -3222,7 +3379,7 @@ var removeCodeblock = ({ state: state2, dispatch }) => {
3222
3379
  if (!changes.length) {
3223
3380
  return false;
3224
3381
  }
3225
- dispatch(state2.update({
3382
+ dispatch(state.update({
3226
3383
  changes,
3227
3384
  userEvent: "format.codeblock.remove",
3228
3385
  scrollIntoView: true
@@ -3234,7 +3391,7 @@ var toggleCodeblock = (target) => {
3234
3391
  };
3235
3392
  var formattingKeymap = (_options = {}) => {
3236
3393
  return [
3237
- keymap6.of([
3394
+ keymap7.of([
3238
3395
  {
3239
3396
  key: "meta-b",
3240
3397
  run: toggleStrong
@@ -3285,7 +3442,7 @@ var Textblocks = {
3285
3442
  TableCell: "tablecell",
3286
3443
  Task: "paragraph"
3287
3444
  };
3288
- var getFormatting = (state2) => {
3445
+ var getFormatting = (state) => {
3289
3446
  let blockType = null;
3290
3447
  const inline = [
3291
3448
  null,
@@ -3311,7 +3468,7 @@ var getFormatting = (state2) => {
3311
3468
  continue;
3312
3469
  } else if (currentBlock.active[i]) {
3313
3470
  inline[i] = true;
3314
- } else if (/\S/.test(state2.doc.sliceString(currentBlock.pos, upto))) {
3471
+ } else if (/\S/.test(state.doc.sliceString(currentBlock.pos, upto))) {
3315
3472
  inline[i] = false;
3316
3473
  }
3317
3474
  }
@@ -3322,12 +3479,12 @@ var getFormatting = (state2) => {
3322
3479
  currentBlock.pos = Math.min(upto, currentBlock.end);
3323
3480
  }
3324
3481
  };
3325
- const { selection } = state2;
3482
+ const { selection } = state;
3326
3483
  for (const range of selection.ranges) {
3327
3484
  if (range.empty && inline.some((v) => v === null)) {
3328
3485
  const contextSize = Math.min(range.head, 6);
3329
- const contextBefore = state2.doc.sliceString(range.head - contextSize, range.head);
3330
- let contextAfter = state2.doc.sliceString(range.head, range.head + contextSize);
3486
+ const contextBefore = state.doc.sliceString(range.head - contextSize, range.head);
3487
+ let contextAfter = state.doc.sliceString(range.head, range.head + contextSize);
3331
3488
  for (let i = 0; i < contextSize; i++) {
3332
3489
  const ch = contextAfter[i];
3333
3490
  if (ch !== contextBefore[contextBefore.length - 1 - i] || !/[~`*]/.test(ch)) {
@@ -3346,7 +3503,7 @@ var getFormatting = (state2) => {
3346
3503
  }
3347
3504
  }
3348
3505
  }
3349
- syntaxTree2(state2).iterate({
3506
+ syntaxTree2(state).iterate({
3350
3507
  from: range.from,
3351
3508
  to: range.to,
3352
3509
  enter: (node) => {
@@ -3420,7 +3577,7 @@ var getFormatting = (state2) => {
3420
3577
  }
3421
3578
  });
3422
3579
  }
3423
- const { from, to } = state2.doc.lineAt(selection.main.anchor);
3580
+ const { from, to } = state.doc.lineAt(selection.main.anchor);
3424
3581
  const blankLine = from === to;
3425
3582
  return {
3426
3583
  blankLine,
@@ -3435,8 +3592,8 @@ var getFormatting = (state2) => {
3435
3592
  };
3436
3593
  };
3437
3594
  var useFormattingState = () => {
3438
- const [state2, setState] = useState2();
3439
- const observer = useMemo2(() => EditorView12.updateListener.of((update2) => {
3595
+ const [state, setState] = useState2();
3596
+ const observer = useMemo2(() => EditorView14.updateListener.of((update2) => {
3440
3597
  if (update2.docChanged || update2.selectionSet) {
3441
3598
  setState((prevState) => {
3442
3599
  const newState = getFormatting(update2.state);
@@ -3448,7 +3605,7 @@ var useFormattingState = () => {
3448
3605
  }
3449
3606
  }), []);
3450
3607
  return [
3451
- state2,
3608
+ state,
3452
3609
  observer
3453
3610
  ];
3454
3611
  };
@@ -3509,7 +3666,7 @@ import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lan
3509
3666
  import { syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
3510
3667
  import { languages } from "@codemirror/language-data";
3511
3668
  import { lintKeymap } from "@codemirror/lint";
3512
- import { keymap as keymap7 } from "@codemirror/view";
3669
+ import { keymap as keymap8 } from "@codemirror/view";
3513
3670
 
3514
3671
  // packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
3515
3672
  import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
@@ -3715,7 +3872,7 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
3715
3872
  }),
3716
3873
  // Custom styles.
3717
3874
  syntaxHighlighting2(markdownHighlightStyle()),
3718
- keymap7.of([
3875
+ keymap8.of([
3719
3876
  // https://codemirror.net/docs/ref/#commands.indentWithTab
3720
3877
  indentWithTab2,
3721
3878
  // https://codemirror.net/docs/ref/#commands.defaultKeymap
@@ -3728,18 +3885,18 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
3728
3885
 
3729
3886
  // packages/ui/react-ui-editor/src/extensions/markdown/debug.ts
3730
3887
  import { syntaxTree as syntaxTree3 } from "@codemirror/language";
3731
- import { StateField as StateField6 } from "@codemirror/state";
3732
- var debugTree = (cb) => StateField6.define({
3733
- create: (state2) => cb(convertTreeToJson(state2)),
3888
+ import { StateField as StateField7 } from "@codemirror/state";
3889
+ var debugTree = (cb) => StateField7.define({
3890
+ create: (state) => cb(convertTreeToJson(state)),
3734
3891
  update: (value, tr) => cb(convertTreeToJson(tr.state))
3735
3892
  });
3736
- var convertTreeToJson = (state2) => {
3893
+ var convertTreeToJson = (state) => {
3737
3894
  const treeToJson = (cursor) => {
3738
3895
  const node = {
3739
3896
  type: cursor.type.name,
3740
3897
  from: cursor.from,
3741
3898
  to: cursor.to,
3742
- text: state2.doc.slice(cursor.from, cursor.to).toString(),
3899
+ text: state.doc.slice(cursor.from, cursor.to).toString(),
3743
3900
  children: []
3744
3901
  };
3745
3902
  if (cursor.firstChild()) {
@@ -3750,19 +3907,19 @@ var convertTreeToJson = (state2) => {
3750
3907
  }
3751
3908
  return node;
3752
3909
  };
3753
- return treeToJson(syntaxTree3(state2).cursor());
3910
+ return treeToJson(syntaxTree3(state).cursor());
3754
3911
  };
3755
3912
 
3756
3913
  // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
3757
3914
  import { syntaxTree as syntaxTree7 } from "@codemirror/language";
3758
- import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect4 } from "@codemirror/state";
3759
- import { EditorView as EditorView16, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
3760
- import { invariant as invariant3 } from "@dxos/invariant";
3915
+ import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect5 } from "@codemirror/state";
3916
+ import { EditorView as EditorView18, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
3917
+ import { invariant as invariant4 } from "@dxos/invariant";
3761
3918
  import { mx as mx2 } from "@dxos/react-ui-theme";
3762
3919
 
3763
3920
  // packages/ui/react-ui-editor/src/extensions/markdown/changes.ts
3764
3921
  import { syntaxTree as syntaxTree4 } from "@codemirror/language";
3765
- import { Transaction } from "@codemirror/state";
3922
+ import { Transaction as Transaction2 } from "@codemirror/state";
3766
3923
  import { ViewPlugin as ViewPlugin5 } from "@codemirror/view";
3767
3924
  var adjustChanges = () => {
3768
3925
  return ViewPlugin5.fromClass(class {
@@ -3770,7 +3927,7 @@ var adjustChanges = () => {
3770
3927
  const tree = syntaxTree4(update2.state);
3771
3928
  const adjustments = [];
3772
3929
  for (const tr of update2.transactions) {
3773
- const event = tr.annotation(Transaction.userEvent);
3930
+ const event = tr.annotation(Transaction2.userEvent);
3774
3931
  switch (event) {
3775
3932
  //
3776
3933
  // Enter
@@ -3906,36 +4063,38 @@ var getValidUrl = (str) => {
3906
4063
 
3907
4064
  // packages/ui/react-ui-editor/src/extensions/markdown/image.ts
3908
4065
  import { syntaxTree as syntaxTree5 } from "@codemirror/language";
3909
- import { StateField as StateField7 } from "@codemirror/state";
3910
- import { Decoration as Decoration5, EditorView as EditorView13, WidgetType as WidgetType3 } from "@codemirror/view";
4066
+ import { StateField as StateField8 } from "@codemirror/state";
4067
+ import { Decoration as Decoration5, EditorView as EditorView15, WidgetType as WidgetType3 } from "@codemirror/view";
3911
4068
  var image = (_options = {}) => {
3912
- return StateField7.define({
3913
- create: (state2) => {
3914
- return Decoration5.set(buildDecorations(0, state2.doc.length, state2));
3915
- },
3916
- update: (value, tr) => {
3917
- if (!tr.docChanged && !tr.selection) {
3918
- return value;
3919
- }
3920
- const cursor = tr.state.selection.main.head;
3921
- const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
3922
- let from = Math.min(cursor, oldCursor);
3923
- let to = Math.max(cursor, oldCursor);
3924
- tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
3925
- from = Math.min(from, fromB);
3926
- to = Math.max(to, toB);
3927
- });
3928
- from = tr.state.doc.lineAt(from).from;
3929
- to = tr.state.doc.lineAt(to).to;
3930
- return value.map(tr.changes).update({
3931
- filterFrom: from,
3932
- filterTo: to,
3933
- filter: () => false,
3934
- add: buildDecorations(from, to, tr.state)
3935
- });
3936
- },
3937
- provide: (field) => EditorView13.decorations.from(field)
3938
- });
4069
+ return [
4070
+ StateField8.define({
4071
+ create: (state) => {
4072
+ return Decoration5.set(buildDecorations(0, state.doc.length, state));
4073
+ },
4074
+ update: (value, tr) => {
4075
+ if (!tr.docChanged && !tr.selection) {
4076
+ return value;
4077
+ }
4078
+ const cursor = tr.state.selection.main.head;
4079
+ const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
4080
+ let from = Math.min(cursor, oldCursor);
4081
+ let to = Math.max(cursor, oldCursor);
4082
+ tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
4083
+ from = Math.min(from, fromB);
4084
+ to = Math.max(to, toB);
4085
+ });
4086
+ from = tr.state.doc.lineAt(from).from;
4087
+ to = tr.state.doc.lineAt(to).to;
4088
+ return value.map(tr.changes).update({
4089
+ filterFrom: from,
4090
+ filterTo: to,
4091
+ filter: () => false,
4092
+ add: buildDecorations(from, to, tr.state)
4093
+ });
4094
+ },
4095
+ provide: (field) => EditorView15.decorations.from(field)
4096
+ })
4097
+ ];
3939
4098
  };
3940
4099
  var preloaded = /* @__PURE__ */ new Set();
3941
4100
  var preloadImage = (url) => {
@@ -3945,16 +4104,19 @@ var preloadImage = (url) => {
3945
4104
  preloaded.add(url);
3946
4105
  }
3947
4106
  };
3948
- var buildDecorations = (from, to, state2) => {
4107
+ var buildDecorations = (from, to, state) => {
3949
4108
  const decorations = [];
3950
- const cursor = state2.selection.main.head;
3951
- syntaxTree5(state2).iterate({
4109
+ const cursor = state.selection.main.head;
4110
+ syntaxTree5(state).iterate({
3952
4111
  enter: (node) => {
3953
4112
  if (node.name === "Image") {
3954
4113
  const urlNode = node.node.getChild("URL");
3955
4114
  if (urlNode) {
3956
- const hide2 = state2.readOnly || cursor < node.from || cursor > node.to;
3957
- const url = state2.sliceDoc(urlNode.from, urlNode.to);
4115
+ const hide2 = state.readOnly || cursor < node.from || cursor > node.to || !state.field(focusField);
4116
+ const url = state.sliceDoc(urlNode.from, urlNode.to);
4117
+ if (url.match(/^https?:\/\//) === null && url.match(/^file?:\/\//) === null) {
4118
+ return;
4119
+ }
3958
4120
  preloadImage(url);
3959
4121
  decorations.push(Decoration5.replace({
3960
4122
  block: true,
@@ -3980,18 +4142,20 @@ var ImageWidget = class extends WidgetType3 {
3980
4142
  const img = document.createElement("img");
3981
4143
  img.setAttribute("src", this._url);
3982
4144
  img.setAttribute("class", "cm-image");
3983
- img.onload = () => img.classList.add("cm-loaded-image");
4145
+ if (view.state.field(focusField)) {
4146
+ img.onload = () => img.classList.add("cm-loaded-image");
4147
+ } else {
4148
+ img.classList.add("cm-loaded-image");
4149
+ }
3984
4150
  return img;
3985
4151
  }
3986
4152
  };
3987
- var imageUpload = (options = {}) => {
3988
- };
3989
4153
 
3990
4154
  // packages/ui/react-ui-editor/src/extensions/markdown/styles.ts
3991
- import { EditorView as EditorView14 } from "@codemirror/view";
4155
+ import { EditorView as EditorView16 } from "@codemirror/view";
3992
4156
  var bulletListIndentationWidth = 24;
3993
4157
  var orderedListIndentationWidth = 36;
3994
- var formattingStyles = EditorView14.theme({
4158
+ var formattingStyles = EditorView16.theme({
3995
4159
  /**
3996
4160
  * Horizontal rule.
3997
4161
  */
@@ -4090,25 +4254,25 @@ var formattingStyles = EditorView14.theme({
4090
4254
 
4091
4255
  // packages/ui/react-ui-editor/src/extensions/markdown/table.ts
4092
4256
  import { syntaxTree as syntaxTree6 } from "@codemirror/language";
4093
- import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField8 } from "@codemirror/state";
4094
- import { Decoration as Decoration6, EditorView as EditorView15, WidgetType as WidgetType4 } from "@codemirror/view";
4257
+ import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField9 } from "@codemirror/state";
4258
+ import { Decoration as Decoration6, EditorView as EditorView17, WidgetType as WidgetType4 } from "@codemirror/view";
4095
4259
  var table = (options = {}) => {
4096
- return StateField8.define({
4097
- create: (state2) => update(state2, options),
4260
+ return StateField9.define({
4261
+ create: (state) => update(state, options),
4098
4262
  update: (_, tr) => update(tr.state, options),
4099
- provide: (field) => EditorView15.decorations.from(field)
4263
+ provide: (field) => EditorView17.decorations.from(field)
4100
4264
  });
4101
4265
  };
4102
- var update = (state2, _options) => {
4266
+ var update = (state, _options) => {
4103
4267
  const builder = new RangeSetBuilder2();
4104
- const cursor = state2.selection.main.head;
4268
+ const cursor = state.selection.main.head;
4105
4269
  const tables = [];
4106
4270
  const getTable = () => tables[tables.length - 1];
4107
4271
  const getRow = () => {
4108
4272
  const table2 = getTable();
4109
4273
  return table2.rows?.[table2.rows.length - 1];
4110
4274
  };
4111
- syntaxTree6(state2).iterate({
4275
+ syntaxTree6(state).iterate({
4112
4276
  enter: (node) => {
4113
4277
  switch (node.name) {
4114
4278
  case "Table": {
@@ -4129,9 +4293,9 @@ var update = (state2, _options) => {
4129
4293
  case "TableCell": {
4130
4294
  const row = getRow();
4131
4295
  if (row) {
4132
- row.push(state2.sliceDoc(node.from, node.to));
4296
+ row.push(state.sliceDoc(node.from, node.to));
4133
4297
  } else {
4134
- getTable().header?.push(state2.sliceDoc(node.from, node.to));
4298
+ getTable().header?.push(state.sliceDoc(node.from, node.to));
4135
4299
  }
4136
4300
  break;
4137
4301
  }
@@ -4139,7 +4303,7 @@ var update = (state2, _options) => {
4139
4303
  }
4140
4304
  });
4141
4305
  tables.forEach((table2) => {
4142
- const replace = state2.readOnly || cursor < table2.from || cursor > table2.to;
4306
+ const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
4143
4307
  if (replace) {
4144
4308
  builder.add(table2.from, table2.to, Decoration6.replace({
4145
4309
  block: true,
@@ -4303,9 +4467,9 @@ var checkedTask = Decoration7.replace({
4303
4467
  var uncheckedTask = Decoration7.replace({
4304
4468
  widget: new CheckboxWidget(false)
4305
4469
  });
4306
- var editingRange = (state2, range, focus) => {
4307
- const { readOnly, selection: { main: { head } } } = state2;
4308
- return focus && !readOnly && head >= range.from && head <= range.to;
4470
+ var editingRange = (state, range, focus2) => {
4471
+ const { readOnly, selection: { main: { head } } } = state;
4472
+ return focus2 && !readOnly && head >= range.from && head <= range.to;
4309
4473
  };
4310
4474
  var autoHideTags = /* @__PURE__ */ new Set([
4311
4475
  "CodeMark",
@@ -4315,13 +4479,13 @@ var autoHideTags = /* @__PURE__ */ new Set([
4315
4479
  "SubscriptMark",
4316
4480
  "SuperscriptMark"
4317
4481
  ]);
4318
- var buildDecorations2 = (view, options, focus) => {
4482
+ var buildDecorations2 = (view, options, focus2) => {
4319
4483
  const deco = new RangeSetBuilder3();
4320
4484
  const atomicDeco = new RangeSetBuilder3();
4321
- const { state: state2 } = view;
4485
+ const { state } = view;
4322
4486
  const headerLevels = [];
4323
4487
  const getHeaderLevels = (node, level) => {
4324
- invariant3(level > 0, void 0, {
4488
+ invariant4(level > 0, void 0, {
4325
4489
  F: __dxlog_file9,
4326
4490
  L: 178,
4327
4491
  S: void 0,
@@ -4360,7 +4524,7 @@ var buildDecorations2 = (view, options, focus) => {
4360
4524
  listLevels.pop();
4361
4525
  };
4362
4526
  const getCurrentListLevel = () => {
4363
- invariant3(listLevels.length, void 0, {
4527
+ invariant4(listLevels.length, void 0, {
4364
4528
  F: __dxlog_file9,
4365
4529
  L: 200,
4366
4530
  S: void 0,
@@ -4387,7 +4551,7 @@ var buildDecorations2 = (view, options, focus) => {
4387
4551
  if (options.numberedHeadings?.from !== void 0) {
4388
4552
  headers[level - 1].number++;
4389
4553
  }
4390
- const editing = editingRange(state2, node, focus);
4554
+ const editing = editingRange(state, node, focus2);
4391
4555
  if (editing) {
4392
4556
  break;
4393
4557
  }
@@ -4419,7 +4583,7 @@ var buildDecorations2 = (view, options, focus) => {
4419
4583
  break;
4420
4584
  }
4421
4585
  case "ListItem": {
4422
- const line = state2.doc.lineAt(node.from);
4586
+ const line = state.doc.lineAt(node.from);
4423
4587
  const list = getCurrentListLevel();
4424
4588
  const width = list.type === "OrderedList" ? orderedListIndentationWidth : bulletListIndentationWidth;
4425
4589
  const offset = ((list.level ?? 0) + 1) * width;
@@ -4441,17 +4605,17 @@ var buildDecorations2 = (view, options, focus) => {
4441
4605
  break;
4442
4606
  }
4443
4607
  const label = list.type === "OrderedList" ? `${++list.number}.` : Unicode.bulletSmall;
4444
- const line = state2.doc.lineAt(node.from);
4445
- const to = state2.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
4608
+ const line = state.doc.lineAt(node.from);
4609
+ const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
4446
4610
  atomicDeco.add(line.from, to, Decoration7.replace({
4447
4611
  widget: new TextWidget(label, list.type === "OrderedList" ? "cm-list-mark cm-list-mark-ordered" : "cm-list-mark cm-list-mark-bullet")
4448
4612
  }));
4449
4613
  break;
4450
4614
  }
4451
4615
  case "TaskMarker": {
4452
- const checked = state2.doc.sliceString(node.from + 1, node.to - 1) === "x";
4453
- const line = state2.doc.lineAt(node.from);
4454
- const to = state2.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
4616
+ const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
4617
+ const line = state.doc.lineAt(node.from);
4618
+ const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
4455
4619
  atomicDeco.add(line.from, to, checked ? checkedTask : uncheckedTask);
4456
4620
  break;
4457
4621
  }
@@ -4459,7 +4623,7 @@ var buildDecorations2 = (view, options, focus) => {
4459
4623
  // Blockquote > QuoteMark > Paragraph
4460
4624
  //
4461
4625
  case "Blockquote": {
4462
- const editing = editingRange(state2, node, focus);
4626
+ const editing = editingRange(state, node, focus2);
4463
4627
  const quoteMark = node.node.getChild("QuoteMark");
4464
4628
  const paragraph = node.node.getChild("Paragraph");
4465
4629
  if (!editing && quoteMark && paragraph) {
@@ -4480,7 +4644,7 @@ var buildDecorations2 = (view, options, focus) => {
4480
4644
  // CommentBlock
4481
4645
  //
4482
4646
  case "CommentBlock": {
4483
- const editing = editingRange(state2, node, focus);
4647
+ const editing = editingRange(state, node, focus2);
4484
4648
  for (const block of view.viewportLineBlocks) {
4485
4649
  if (block.to < node.from) {
4486
4650
  continue;
@@ -4489,7 +4653,7 @@ var buildDecorations2 = (view, options, focus) => {
4489
4653
  break;
4490
4654
  }
4491
4655
  const isFirst = block.from <= node.from;
4492
- const isLast = block.to >= node.to && /^(\s>)*-->$/.test(state2.doc.sliceString(block.from, block.to));
4656
+ const isLast = block.to >= node.to && /^(\s>)*-->$/.test(state.doc.sliceString(block.from, block.to));
4493
4657
  deco.add(block.from, block.from, isFirst ? commentBlockLineFirst : isLast ? commentBlockLineLast : commentBlockLine);
4494
4658
  if (!editing && (isFirst || isLast)) {
4495
4659
  atomicDeco.add(block.from, block.to, hide);
@@ -4509,9 +4673,9 @@ var buildDecorations2 = (view, options, focus) => {
4509
4673
  break;
4510
4674
  }
4511
4675
  const first = block.from <= node.from;
4512
- const last = block.to >= node.to && /^(\s>)*```$/.test(state2.doc.sliceString(block.from, block.to));
4676
+ const last = block.to >= node.to && /^(\s>)*```$/.test(state.doc.sliceString(block.from, block.to));
4513
4677
  deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
4514
- const editing = editingRange(state2, node, focus);
4678
+ const editing = editingRange(state, node, focus2);
4515
4679
  if (!editing && (first || last)) {
4516
4680
  atomicDeco.add(block.from, block.to, hide);
4517
4681
  }
@@ -4524,9 +4688,9 @@ var buildDecorations2 = (view, options, focus) => {
4524
4688
  case "Link": {
4525
4689
  const marks = node.node.getChildren("LinkMark");
4526
4690
  const urlNode = node.node.getChild("URL");
4527
- const editing = editingRange(state2, node, focus);
4691
+ const editing = editingRange(state, node, focus2);
4528
4692
  if (urlNode && marks.length >= 2) {
4529
- const url = state2.sliceDoc(urlNode.from, urlNode.to);
4693
+ const url = state.sliceDoc(urlNode.from, urlNode.to);
4530
4694
  if (!editing) {
4531
4695
  atomicDeco.add(node.from, marks[0].to, hide);
4532
4696
  }
@@ -4551,14 +4715,14 @@ var buildDecorations2 = (view, options, focus) => {
4551
4715
  // HR
4552
4716
  //
4553
4717
  case "HorizontalRule": {
4554
- if (!editingRange(state2, node, focus)) {
4718
+ if (!editingRange(state, node, focus2)) {
4555
4719
  deco.add(node.from, node.to, horizontalRule);
4556
4720
  }
4557
4721
  break;
4558
4722
  }
4559
4723
  default: {
4560
4724
  if (autoHideTags.has(node.name)) {
4561
- if (!editingRange(state2, node.node.parent, focus)) {
4725
+ if (!editingRange(state, node.node.parent, focus2)) {
4562
4726
  atomicDeco.add(node.from, node.to, hide);
4563
4727
  }
4564
4728
  }
@@ -4574,7 +4738,7 @@ var buildDecorations2 = (view, options, focus) => {
4574
4738
  }
4575
4739
  }
4576
4740
  };
4577
- const tree = syntaxTree7(state2);
4741
+ const tree = syntaxTree7(state);
4578
4742
  if (options.numberedHeadings?.from === void 0) {
4579
4743
  for (const { from, to } of view.visibleRanges) {
4580
4744
  tree.iterate({
@@ -4595,7 +4759,7 @@ var buildDecorations2 = (view, options, focus) => {
4595
4759
  atomicDeco: atomicDeco.finish()
4596
4760
  };
4597
4761
  };
4598
- var forceUpdate = StateEffect4.define();
4762
+ var forceUpdate = StateEffect5.define();
4599
4763
  var decorateMarkdown = (options = {}) => {
4600
4764
  return [
4601
4765
  ViewPlugin6.fromClass(class {
@@ -4630,9 +4794,9 @@ var decorateMarkdown = (options = {}) => {
4630
4794
  }
4631
4795
  }, {
4632
4796
  provide: (plugin) => [
4633
- EditorView16.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4634
- EditorView16.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4635
- EditorView16.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
4797
+ EditorView18.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4798
+ EditorView18.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4799
+ EditorView18.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
4636
4800
  ]
4637
4801
  }),
4638
4802
  image(),
@@ -4680,7 +4844,7 @@ var linkTooltip = (render) => {
4680
4844
 
4681
4845
  // packages/ui/react-ui-editor/src/extensions/mention.ts
4682
4846
  import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
4683
- import { log as log7 } from "@dxos/log";
4847
+ import { log as log6 } from "@dxos/log";
4684
4848
  var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/mention.ts";
4685
4849
  var mention = ({ onSearch }) => {
4686
4850
  return autocompletion2({
@@ -4693,7 +4857,7 @@ var mention = ({ onSearch }) => {
4693
4857
  icons: false,
4694
4858
  override: [
4695
4859
  (context) => {
4696
- log7.info("completion context", {
4860
+ log6.info("completion context", {
4697
4861
  context
4698
4862
  }, {
4699
4863
  F: __dxlog_file10,
@@ -4717,7 +4881,7 @@ var mention = ({ onSearch }) => {
4717
4881
  };
4718
4882
 
4719
4883
  // packages/ui/react-ui-editor/src/extensions/modes.ts
4720
- import { keymap as keymap8 } from "@codemirror/view";
4884
+ import { keymap as keymap9 } from "@codemirror/view";
4721
4885
  import { vim } from "@replit/codemirror-vim";
4722
4886
  import { vscodeKeymap } from "@replit/codemirror-vscode-keymap";
4723
4887
  var focusEvent = "focus.container";
@@ -4739,7 +4903,7 @@ var InputModeExtensions = {
4739
4903
  editorInputMode.of({
4740
4904
  type: "vscode"
4741
4905
  }),
4742
- keymap8.of(vscodeKeymap)
4906
+ keymap9.of(vscodeKeymap)
4743
4907
  ],
4744
4908
  vim: [
4745
4909
  // https://github.com/replit/codemirror-vim
@@ -4748,7 +4912,7 @@ var InputModeExtensions = {
4748
4912
  type: "vim",
4749
4913
  noTabster: true
4750
4914
  }),
4751
- keymap8.of([
4915
+ keymap9.of([
4752
4916
  {
4753
4917
  key: "Alt-Escape",
4754
4918
  run: (view) => {
@@ -4763,7 +4927,7 @@ var InputModeExtensions = {
4763
4927
  };
4764
4928
 
4765
4929
  // packages/ui/react-ui-editor/src/extensions/typewriter.ts
4766
- import { keymap as keymap9 } from "@codemirror/view";
4930
+ import { keymap as keymap10 } from "@codemirror/view";
4767
4931
  var defaultItems = [
4768
4932
  "hello world!",
4769
4933
  "this is a test.",
@@ -4773,7 +4937,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
4773
4937
  let t;
4774
4938
  let idx = 0;
4775
4939
  return [
4776
- keymap9.of([
4940
+ keymap10.of([
4777
4941
  {
4778
4942
  // Reset.
4779
4943
  key: "alt-meta-'",
@@ -4831,10 +4995,10 @@ var ToolbarSeparator = () => /* @__PURE__ */ React3.createElement("div", {
4831
4995
  className: "grow"
4832
4996
  });
4833
4997
  var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
4834
- var ToolbarRoot = ({ children, onAction, classNames, state: state2 }) => {
4998
+ var ToolbarRoot = ({ children, onAction, classNames, state }) => {
4835
4999
  return /* @__PURE__ */ React3.createElement(ToolbarContextProvider, {
4836
5000
  onAction,
4837
- state: state2
5001
+ state
4838
5002
  }, /* @__PURE__ */ React3.createElement(ElevationProvider, {
4839
5003
  elevation: "chrome"
4840
5004
  }, /* @__PURE__ */ React3.createElement(NaturalToolbar.Root, {
@@ -4884,8 +5048,8 @@ var HeadingIcons = {
4884
5048
  };
4885
5049
  var MarkdownHeading = () => {
4886
5050
  const { t } = useTranslation(translationKey);
4887
- const { onAction, state: state2 } = useToolbarContext("MarkdownFormatting");
4888
- const blockType = state2 ? state2.blockType : "paragraph";
5051
+ const { onAction, state } = useToolbarContext("MarkdownFormatting");
5052
+ const blockType = state ? state.blockType : "paragraph";
4889
5053
  const header = blockType && /heading(\d)/.exec(blockType);
4890
5054
  const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
4891
5055
  const HeadingIcon = HeadingIcons[value ?? "0"];
@@ -4949,43 +5113,43 @@ var markdownStyles = [
4949
5113
  {
4950
5114
  type: "strong",
4951
5115
  Icon: TextB,
4952
- getState: (state2) => !!state2?.strong
5116
+ getState: (state) => !!state?.strong
4953
5117
  },
4954
5118
  {
4955
5119
  type: "emphasis",
4956
5120
  Icon: TextItalic,
4957
- getState: (state2) => !!state2?.emphasis
5121
+ getState: (state) => !!state?.emphasis
4958
5122
  },
4959
5123
  {
4960
5124
  type: "strikethrough",
4961
5125
  Icon: TextStrikethrough,
4962
- getState: (state2) => !!state2?.strikethrough
5126
+ getState: (state) => !!state?.strikethrough
4963
5127
  },
4964
5128
  {
4965
5129
  type: "code",
4966
5130
  Icon: Code,
4967
- getState: (state2) => !!state2?.code
5131
+ getState: (state) => !!state?.code
4968
5132
  },
4969
5133
  {
4970
5134
  type: "link",
4971
5135
  Icon: Link,
4972
- getState: (state2) => !!state2?.link
5136
+ getState: (state) => !!state?.link
4973
5137
  }
4974
5138
  ];
4975
5139
  var MarkdownStyles = () => {
4976
- const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
5140
+ const { onAction, state } = useToolbarContext("MarkdownStyles");
4977
5141
  const { t } = useTranslation(translationKey);
4978
5142
  return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
4979
5143
  type: "multiple",
4980
- value: markdownStyles.filter(({ getState }) => state2 && getState(state2)).map(({ type }) => type)
5144
+ value: markdownStyles.filter(({ getState }) => state && getState(state)).map(({ type }) => type)
4981
5145
  }, markdownStyles.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
4982
5146
  key: type,
4983
5147
  value: type,
4984
5148
  Icon: Icon2,
4985
- disabled: state2?.blockType === "codeblock",
4986
- onClick: state2 ? () => onAction?.({
5149
+ disabled: state?.blockType === "codeblock",
5150
+ onClick: state ? () => onAction?.({
4987
5151
  type,
4988
- data: !getState(state2)
5152
+ data: !getState(state)
4989
5153
  }) : void 0
4990
5154
  }, t(`${type} label`))));
4991
5155
  };
@@ -4993,32 +5157,32 @@ var markdownLists = [
4993
5157
  {
4994
5158
  type: "list-bullet",
4995
5159
  Icon: ListBullets,
4996
- getState: (state2) => state2.listStyle === "bullet"
5160
+ getState: (state) => state.listStyle === "bullet"
4997
5161
  },
4998
5162
  {
4999
5163
  type: "list-ordered",
5000
5164
  Icon: ListNumbers,
5001
- getState: (state2) => state2.listStyle === "ordered"
5165
+ getState: (state) => state.listStyle === "ordered"
5002
5166
  },
5003
5167
  {
5004
5168
  type: "list-task",
5005
5169
  Icon: ListChecks,
5006
- getState: (state2) => state2.listStyle === "task"
5170
+ getState: (state) => state.listStyle === "task"
5007
5171
  }
5008
5172
  ];
5009
5173
  var MarkdownLists = () => {
5010
- const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
5174
+ const { onAction, state } = useToolbarContext("MarkdownStyles");
5011
5175
  const { t } = useTranslation(translationKey);
5012
5176
  return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
5013
5177
  type: "single",
5014
- value: state2?.listStyle ? `list-${state2.listStyle}` : ""
5178
+ value: state?.listStyle ? `list-${state.listStyle}` : ""
5015
5179
  }, markdownLists.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
5016
5180
  key: type,
5017
5181
  value: type,
5018
5182
  Icon: Icon2,
5019
- onClick: state2 ? () => onAction?.({
5183
+ onClick: state ? () => onAction?.({
5020
5184
  type,
5021
- data: !getState(state2)
5185
+ data: !getState(state)
5022
5186
  }) : void 0
5023
5187
  }, t(`${type} label`))));
5024
5188
  };
@@ -5026,24 +5190,24 @@ var markdownBlocks = [
5026
5190
  {
5027
5191
  type: "blockquote",
5028
5192
  Icon: Quotes,
5029
- getState: (state2) => !!state2?.blockQuote
5193
+ getState: (state) => !!state?.blockQuote
5030
5194
  },
5031
5195
  {
5032
5196
  type: "codeblock",
5033
5197
  Icon: CodeBlock,
5034
- getState: (state2) => state2.blockType === "codeblock"
5198
+ getState: (state) => state.blockType === "codeblock"
5035
5199
  },
5036
5200
  {
5037
5201
  type: "table",
5038
5202
  Icon: Table2,
5039
- getState: (state2) => state2.blockType === "tablecell",
5040
- disabled: (state2) => !state2.blankLine
5203
+ getState: (state) => state.blockType === "tablecell",
5204
+ disabled: (state) => !state.blankLine
5041
5205
  }
5042
5206
  ];
5043
5207
  var MarkdownBlocks = () => {
5044
- const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
5208
+ const { onAction, state } = useToolbarContext("MarkdownStyles");
5045
5209
  const { t } = useTranslation(translationKey);
5046
- const value = markdownBlocks.find(({ getState }) => state2 && getState(state2));
5210
+ const value = markdownBlocks.find(({ getState }) => state && getState(state));
5047
5211
  return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
5048
5212
  type: "single",
5049
5213
  value: value?.type ?? ""
@@ -5051,10 +5215,10 @@ var MarkdownBlocks = () => {
5051
5215
  key: type,
5052
5216
  value: type,
5053
5217
  Icon: Icon2,
5054
- disabled: !state2 || disabled?.(state2),
5055
- onClick: state2 ? () => onAction?.({
5218
+ disabled: !state || disabled?.(state),
5219
+ onClick: state ? () => onAction?.({
5056
5220
  type,
5057
- data: !getState(state2)
5221
+ data: !getState(state)
5058
5222
  }) : void 0
5059
5223
  }, t(`${type} label`))));
5060
5224
  };
@@ -5167,12 +5331,12 @@ var MarkdownView = ({ mode }) => {
5167
5331
  })), /* @__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))));
5168
5332
  };
5169
5333
  var MarkdownActions = () => {
5170
- const { onAction, state: state2 } = useToolbarContext("MarkdownActions");
5334
+ const { onAction, state } = useToolbarContext("MarkdownActions");
5171
5335
  const { t } = useTranslation(translationKey);
5172
5336
  let commentToolTipKey = "comment label";
5173
- if (state2?.comment) {
5337
+ if (state?.comment) {
5174
5338
  commentToolTipKey = "selection overlaps existing comment label";
5175
- } else if (state2?.selection === false) {
5339
+ } else if (state?.selection === false) {
5176
5340
  commentToolTipKey = "select text to comment label";
5177
5341
  }
5178
5342
  return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(ToolbarButton, {
@@ -5188,7 +5352,7 @@ var MarkdownActions = () => {
5188
5352
  onClick: () => onAction?.({
5189
5353
  type: "comment"
5190
5354
  }),
5191
- disabled: !state2 || state2.comment || !state2.selection
5355
+ disabled: !state || state.comment || !state.selection
5192
5356
  }, t(commentToolTipKey)));
5193
5357
  };
5194
5358
  var Toolbar = {
@@ -5202,20 +5366,20 @@ var Toolbar = {
5202
5366
  };
5203
5367
 
5204
5368
  // packages/ui/react-ui-editor/src/defaults.ts
5205
- import { EditorView as EditorView17 } from "@codemirror/view";
5369
+ import { EditorView as EditorView19 } from "@codemirror/view";
5206
5370
  import { mx as mx3 } from "@dxos/react-ui-theme";
5207
5371
  var margin = "!mt-[1rem]";
5208
5372
  var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
5209
5373
  var editorFullWidth = mx3(margin);
5210
5374
  var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
5211
- var editorGutter = EditorView17.theme({
5375
+ var editorGutter = EditorView19.theme({
5212
5376
  // Match margin from content.
5213
5377
  ".cm-gutters": {
5214
5378
  marginTop: "16px",
5215
5379
  paddingRight: "1rem"
5216
5380
  }
5217
5381
  });
5218
- var editorMonospace = EditorView17.theme({
5382
+ var editorMonospace = EditorView19.theme({
5219
5383
  ".cm-content": {
5220
5384
  fontFamily: fontMono
5221
5385
  }
@@ -5228,11 +5392,11 @@ var useActionHandler = (view) => {
5228
5392
 
5229
5393
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
5230
5394
  import { EditorState as EditorState2 } from "@codemirror/state";
5231
- import { EditorView as EditorView18 } from "@codemirror/view";
5395
+ import { EditorView as EditorView20 } from "@codemirror/view";
5232
5396
  import { useFocusableGroup } from "@fluentui/react-tabster";
5233
5397
  import { useCallback, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2, useState as useState4 } from "react";
5234
- import { log as log8 } from "@dxos/log";
5235
- import { getProviderValue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
5398
+ import { log as log7 } from "@dxos/log";
5399
+ import { getProviderValue, isNotFalsy as isNotFalsy4 } from "@dxos/util";
5236
5400
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
5237
5401
  var instanceCount = 0;
5238
5402
  var useTextEditor = (props = {}, deps = []) => {
@@ -5243,13 +5407,13 @@ var useTextEditor = (props = {}, deps = []) => {
5243
5407
  useEffect3(() => {
5244
5408
  let view2;
5245
5409
  if (parentRef.current) {
5246
- log8("create", {
5410
+ log7("create", {
5247
5411
  id,
5248
5412
  instanceId,
5249
5413
  doc: initialValue?.length ?? 0
5250
5414
  }, {
5251
5415
  F: __dxlog_file11,
5252
- L: 76,
5416
+ L: 75,
5253
5417
  S: void 0,
5254
5418
  C: (f, a) => f(...a)
5255
5419
  });
@@ -5265,27 +5429,27 @@ var useTextEditor = (props = {}, deps = []) => {
5265
5429
  anchor
5266
5430
  };
5267
5431
  }
5268
- const state2 = EditorState2.create({
5432
+ const state = EditorState2.create({
5269
5433
  doc: initialValue,
5270
5434
  // selection: initialSelection,
5271
5435
  extensions: [
5272
5436
  id && documentId.of(id),
5273
5437
  extensions,
5274
5438
  // NOTE: This doesn't catch errors in keymap functions.
5275
- EditorView18.exceptionSink.of((err) => {
5276
- log8.catch(err, void 0, {
5439
+ EditorView20.exceptionSink.of((err) => {
5440
+ log7.catch(err, void 0, {
5277
5441
  F: __dxlog_file11,
5278
- L: 98,
5442
+ L: 97,
5279
5443
  S: void 0,
5280
5444
  C: (f, a) => f(...a)
5281
5445
  });
5282
5446
  })
5283
- ].filter(isNotFalsy3)
5447
+ ].filter(isNotFalsy4)
5284
5448
  });
5285
- view2 = new EditorView18({
5449
+ view2 = new EditorView20({
5286
5450
  parent: parentRef.current,
5287
- state: state2,
5288
- scrollTo: scrollTo ? EditorView18.scrollIntoView(scrollTo, {
5451
+ state,
5452
+ scrollTo: scrollTo ? EditorView20.scrollIntoView(scrollTo, {
5289
5453
  yMargin: 96
5290
5454
  }) : void 0,
5291
5455
  dispatchTransactions: debug ? debugDispatcher : void 0
@@ -5303,11 +5467,11 @@ var useTextEditor = (props = {}, deps = []) => {
5303
5467
  setView(view2);
5304
5468
  }
5305
5469
  return () => {
5306
- log8("destroy", {
5470
+ log7("destroy", {
5307
5471
  id
5308
5472
  }, {
5309
5473
  F: __dxlog_file11,
5310
- L: 135,
5474
+ L: 134,
5311
5475
  S: void 0,
5312
5476
  C: (f, a) => f(...a)
5313
5477
  });
@@ -5321,19 +5485,19 @@ var useTextEditor = (props = {}, deps = []) => {
5321
5485
  }
5322
5486
  if (scrollTo || selection) {
5323
5487
  if (selection && selection.anchor > view.state.doc.length) {
5324
- log8.warn("invalid selection", {
5488
+ log7.warn("invalid selection", {
5325
5489
  length: view.state.doc.length,
5326
5490
  scrollTo,
5327
5491
  selection
5328
5492
  }, {
5329
5493
  F: __dxlog_file11,
5330
- L: 149,
5494
+ L: 148,
5331
5495
  S: void 0,
5332
5496
  C: (f, a) => f(...a)
5333
5497
  });
5334
5498
  return;
5335
5499
  }
5336
- view.dispatch(createEditorStateTransaction(view.state, {
5500
+ view.dispatch(createEditorStateTransaction({
5337
5501
  scrollTo,
5338
5502
  selection
5339
5503
  }));
@@ -5402,6 +5566,7 @@ export {
5402
5566
  awarenessProvider,
5403
5567
  blast,
5404
5568
  callbackWrapper,
5569
+ clientRectsFor,
5405
5570
  command,
5406
5571
  comments,
5407
5572
  commentsState,
@@ -5409,7 +5574,9 @@ export {
5409
5574
  createBasicExtensions,
5410
5575
  createComment,
5411
5576
  createDataExtensions,
5577
+ createEditorStateStore,
5412
5578
  createEditorStateTransaction,
5579
+ createElement,
5413
5580
  createExternalCommentSync,
5414
5581
  createMarkdownExtensions,
5415
5582
  createThemeExtensions,
@@ -5426,23 +5593,25 @@ export {
5426
5593
  editorInputMode,
5427
5594
  editorMonospace,
5428
5595
  editorWithToolbarLayout,
5596
+ flattenRect,
5597
+ focus,
5429
5598
  focusEvent,
5599
+ focusField,
5430
5600
  folding,
5431
5601
  formattingEquals,
5432
5602
  formattingKeymap,
5433
5603
  getFormatting,
5434
5604
  image,
5435
- imageUpload,
5436
5605
  insertTable,
5437
- keymap10 as keymap,
5606
+ keymap11 as keymap,
5438
5607
  linkTooltip,
5439
5608
  listener,
5440
- localStorageStateStoreAdapter,
5441
5609
  logChanges,
5442
5610
  markdownHighlightStyle,
5443
5611
  markdownTags,
5444
5612
  markdownTagsExtensions,
5445
5613
  mention,
5614
+ overlap,
5446
5615
  preventNewline,
5447
5616
  processAction,
5448
5617
  removeBlockquote,
@@ -5450,17 +5619,19 @@ export {
5450
5619
  removeLink,
5451
5620
  removeList,
5452
5621
  removeStyle,
5622
+ renderRoot,
5453
5623
  scrollThreadIntoView,
5454
5624
  selectionOverlapsComment,
5625
+ selectionState,
5455
5626
  setBlockquote,
5456
5627
  setComments,
5457
5628
  setHeading,
5458
5629
  setSelection,
5459
5630
  setStyle,
5460
5631
  singleValueFacet,
5461
- state,
5462
5632
  table,
5463
5633
  tags2 as tags,
5634
+ textRange,
5464
5635
  toggleBlockquote,
5465
5636
  toggleCodeblock,
5466
5637
  toggleEmphasis,
@@ -5477,6 +5648,7 @@ export {
5477
5648
  useComments,
5478
5649
  useFormattingState,
5479
5650
  useTextEditor,
5480
- useToolbarContext
5651
+ useToolbarContext,
5652
+ wrapWithCatch
5481
5653
  };
5482
5654
  //# sourceMappingURL=index.mjs.map