@dxos/react-ui-editor 0.6.13-main.ed424a1 → 0.6.13

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 (123) hide show
  1. package/dist/lib/browser/index.mjs +346 -241
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/TextEditor.stories.d.ts +1 -4
  5. package/dist/types/src/TextEditor.stories.d.ts.map +1 -1
  6. package/dist/types/src/defaults.d.ts.map +1 -1
  7. package/dist/types/src/extensions/autocomplete.d.ts +1 -2
  8. package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
  9. package/dist/types/src/extensions/automerge/automerge.spec.d.ts +2 -0
  10. package/dist/types/src/extensions/automerge/automerge.spec.d.ts.map +1 -0
  11. package/dist/types/src/extensions/automerge/automerge.test.d.ts.map +1 -1
  12. package/dist/types/src/extensions/automerge/cursor.d.ts +1 -1
  13. package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
  14. package/dist/types/src/extensions/awareness/awareness.d.ts +2 -2
  15. package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -1
  16. package/dist/types/src/extensions/command/state.d.ts +2 -2
  17. package/dist/types/src/extensions/command/state.d.ts.map +1 -1
  18. package/dist/types/src/extensions/comments.d.ts +1 -1
  19. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  20. package/dist/types/src/{state → extensions}/cursor.d.ts +2 -2
  21. package/dist/types/src/extensions/cursor.d.ts.map +1 -0
  22. package/dist/types/src/extensions/debug.d.ts +2 -2
  23. package/dist/types/src/extensions/debug.d.ts.map +1 -1
  24. package/dist/types/src/extensions/doc.d.ts +6 -0
  25. package/dist/types/src/extensions/doc.d.ts.map +1 -0
  26. package/dist/types/src/extensions/folding.d.ts.map +1 -1
  27. package/dist/types/src/extensions/index.d.ts +4 -0
  28. package/dist/types/src/extensions/index.d.ts.map +1 -1
  29. package/dist/types/src/extensions/listener.d.ts +0 -1
  30. package/dist/types/src/extensions/listener.d.ts.map +1 -1
  31. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  32. package/dist/types/src/extensions/markdown/formatting.test.d.ts.map +1 -1
  33. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  34. package/dist/types/src/extensions/markdown/link.d.ts +1 -1
  35. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  36. package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
  37. package/dist/types/src/extensions/modes.d.ts +3 -3
  38. package/dist/types/src/extensions/modes.d.ts.map +1 -1
  39. package/dist/types/src/{state → extensions}/state.d.ts +2 -2
  40. package/dist/types/src/extensions/state.d.ts.map +1 -0
  41. package/dist/types/src/extensions/types.d.ts.map +1 -0
  42. package/dist/types/src/extensions/util/overlap.d.ts +1 -1
  43. package/dist/types/src/extensions/util/overlap.d.ts.map +1 -1
  44. package/dist/types/src/extensions/util/react.d.ts +1 -1
  45. package/dist/types/src/extensions/util/react.d.ts.map +1 -1
  46. package/dist/types/src/hooks/useTextEditor.d.ts +1 -1
  47. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  48. package/dist/types/src/index.d.ts +0 -1
  49. package/dist/types/src/index.d.ts.map +1 -1
  50. package/dist/types/src/styles/markdown.d.ts +2 -1
  51. package/dist/types/src/styles/markdown.d.ts.map +1 -1
  52. package/dist/types/src/styles/theme.d.ts.map +1 -1
  53. package/dist/types/src/util.d.ts +0 -6
  54. package/dist/types/src/util.d.ts.map +1 -1
  55. package/package.json +38 -59
  56. package/src/TextEditor.stories.tsx +20 -25
  57. package/src/defaults.ts +2 -0
  58. package/src/extensions/annotations.ts +1 -1
  59. package/src/extensions/autocomplete.ts +8 -9
  60. package/src/extensions/automerge/{automerge.test.tsx → automerge.spec.tsx} +0 -1
  61. package/src/extensions/automerge/automerge.stories.tsx +1 -1
  62. package/src/extensions/automerge/automerge.test.ts +13 -0
  63. package/src/extensions/automerge/automerge.ts +2 -2
  64. package/src/extensions/automerge/cursor.ts +1 -1
  65. package/src/extensions/awareness/awareness.ts +5 -3
  66. package/src/extensions/command/hint.ts +1 -1
  67. package/src/extensions/command/state.ts +4 -3
  68. package/src/extensions/comments.ts +45 -44
  69. package/src/{state → extensions}/cursor.ts +6 -3
  70. package/src/extensions/debug.ts +2 -2
  71. package/src/extensions/doc.ts +17 -0
  72. package/src/extensions/folding.tsx +2 -4
  73. package/src/extensions/index.ts +4 -0
  74. package/src/extensions/listener.ts +0 -1
  75. package/src/extensions/markdown/changes.test.ts +3 -1
  76. package/src/extensions/markdown/decorate.ts +6 -49
  77. package/src/extensions/markdown/formatting.test.ts +3 -1
  78. package/src/extensions/markdown/highlight.ts +5 -0
  79. package/src/extensions/markdown/link.ts +2 -3
  80. package/src/extensions/markdown/parser.test.ts +2 -1
  81. package/src/extensions/markdown/styles.ts +0 -10
  82. package/src/extensions/markdown/table.ts +3 -3
  83. package/src/extensions/modes.ts +5 -6
  84. package/src/{state → extensions}/state.ts +3 -7
  85. package/src/extensions/util/overlap.ts +1 -1
  86. package/src/extensions/util/react.tsx +1 -5
  87. package/src/hooks/useTextEditor.ts +32 -36
  88. package/src/index.ts +0 -1
  89. package/src/styles/markdown.ts +3 -1
  90. package/src/styles/theme.ts +1 -3
  91. package/src/util.ts +0 -10
  92. package/dist/lib/browser/chunk-CIQSMP7K.mjs +0 -148
  93. package/dist/lib/browser/chunk-CIQSMP7K.mjs.map +0 -7
  94. package/dist/lib/browser/state/index.mjs +0 -17
  95. package/dist/lib/browser/state/index.mjs.map +0 -7
  96. package/dist/lib/node/chunk-GZWIENFM.cjs +0 -169
  97. package/dist/lib/node/chunk-GZWIENFM.cjs.map +0 -7
  98. package/dist/lib/node/index.cjs +0 -5493
  99. package/dist/lib/node/index.cjs.map +0 -7
  100. package/dist/lib/node/meta.json +0 -1
  101. package/dist/lib/node/state/index.cjs +0 -39
  102. package/dist/lib/node/state/index.cjs.map +0 -7
  103. package/dist/lib/node-esm/chunk-GP5RCZ3X.mjs +0 -150
  104. package/dist/lib/node-esm/chunk-GP5RCZ3X.mjs.map +0 -7
  105. package/dist/lib/node-esm/index.mjs +0 -5484
  106. package/dist/lib/node-esm/index.mjs.map +0 -7
  107. package/dist/lib/node-esm/meta.json +0 -1
  108. package/dist/lib/node-esm/state/index.mjs +0 -18
  109. package/dist/lib/node-esm/state/index.mjs.map +0 -7
  110. package/dist/types/src/state/cursor.d.ts.map +0 -1
  111. package/dist/types/src/state/doc.d.ts +0 -5
  112. package/dist/types/src/state/doc.d.ts.map +0 -1
  113. package/dist/types/src/state/index.d.ts +0 -6
  114. package/dist/types/src/state/index.d.ts.map +0 -1
  115. package/dist/types/src/state/state.d.ts.map +0 -1
  116. package/dist/types/src/state/types.d.ts.map +0 -1
  117. package/dist/types/src/state/util.d.ts +0 -3
  118. package/dist/types/src/state/util.d.ts.map +0 -1
  119. package/src/state/doc.ts +0 -10
  120. package/src/state/index.ts +0 -11
  121. package/src/state/util.ts +0 -13
  122. /package/dist/types/src/{state → extensions}/types.d.ts +0 -0
  123. /package/src/{state → extensions}/types.ts +0 -0
@@ -1,12 +1,3 @@
1
- import {
2
- Cursor,
3
- createEditorStateTransaction,
4
- documentId,
5
- localStorageStateStoreAdapter,
6
- singleValueFacet,
7
- state
8
- } from "./chunk-CIQSMP7K.mjs";
9
-
10
1
  // packages/ui/react-ui-editor/src/translations.ts
11
2
  var translationKey = "react-ui-editor";
12
3
  var translations_default = [
@@ -43,7 +34,7 @@ var translations_default = [
43
34
  ];
44
35
 
45
36
  // packages/ui/react-ui-editor/src/index.ts
46
- import { keymap as keymap10 } from "@codemirror/view";
37
+ import { keymap as keymap11 } from "@codemirror/view";
47
38
  import { tags as tags2 } from "@lezer/highlight";
48
39
  import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
49
40
 
@@ -59,6 +50,47 @@ import { getSize as getSize2 } from "@dxos/react-ui-theme";
59
50
  import { StateField } from "@codemirror/state";
60
51
  import { Decoration, EditorView } from "@codemirror/view";
61
52
  import { isNotFalsy } from "@dxos/util";
53
+
54
+ // packages/ui/react-ui-editor/src/extensions/cursor.ts
55
+ import { Facet } from "@codemirror/state";
56
+ var defaultCursorConverter = {
57
+ toCursor: (position) => position.toString(),
58
+ fromCursor: (cursor) => parseInt(cursor)
59
+ };
60
+ var Cursor = class _Cursor {
61
+ static {
62
+ this.converter = Facet.define({
63
+ combine: (providers) => {
64
+ return providers[0] ?? defaultCursorConverter;
65
+ }
66
+ });
67
+ }
68
+ static {
69
+ this.getCursorFromRange = (state2, range) => {
70
+ const cursorConverter2 = state2.facet(_Cursor.converter);
71
+ const from = cursorConverter2.toCursor(range.from);
72
+ const to = cursorConverter2.toCursor(range.to, -1);
73
+ return [
74
+ from,
75
+ to
76
+ ].join(":");
77
+ };
78
+ }
79
+ static {
80
+ this.getRangeFromCursor = (state2, cursor) => {
81
+ const cursorConverter2 = state2.facet(_Cursor.converter);
82
+ const parts = cursor.split(":");
83
+ const from = cursorConverter2.fromCursor(parts[0]);
84
+ const to = cursorConverter2.fromCursor(parts[1]);
85
+ return from !== void 0 && to !== void 0 ? {
86
+ from,
87
+ to
88
+ } : void 0;
89
+ };
90
+ }
91
+ };
92
+
93
+ // packages/ui/react-ui-editor/src/extensions/annotations.ts
62
94
  var annotationMark = Decoration.mark({
63
95
  class: "cm-annotation"
64
96
  });
@@ -121,7 +153,7 @@ import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
121
153
  import { markdownLanguage } from "@codemirror/lang-markdown";
122
154
  import { keymap } from "@codemirror/view";
123
155
  var autocomplete = ({ activateOnTyping, override, onSearch } = {}) => {
124
- const extensions = [
156
+ const extentions = [
125
157
  // https://codemirror.net/docs/ref/#view.keymap
126
158
  // https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
127
159
  // TODO(burdon): Set custom keymap.
@@ -138,7 +170,7 @@ var autocomplete = ({ activateOnTyping, override, onSearch } = {}) => {
138
170
  })
139
171
  ];
140
172
  if (onSearch) {
141
- extensions.push(
173
+ extentions.push(
142
174
  // TODO(burdon): Optional decoration via addToOptions
143
175
  markdownLanguage.data.of({
144
176
  autocomplete: (context) => {
@@ -154,7 +186,7 @@ var autocomplete = ({ activateOnTyping, override, onSearch } = {}) => {
154
186
  })
155
187
  );
156
188
  }
157
- return extensions;
189
+ return extentions;
158
190
  };
159
191
 
160
192
  // packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
@@ -452,7 +484,7 @@ var automerge = (accessor) => {
452
484
  };
453
485
 
454
486
  // packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts
455
- import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
487
+ import { Annotation as Annotation2, Facet as Facet2, RangeSet } from "@codemirror/state";
456
488
  import { Decoration as Decoration2, EditorView as EditorView3, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
457
489
  import { Event } from "@dxos/async";
458
490
  import { Context } from "@dxos/context";
@@ -467,7 +499,9 @@ var dummyProvider = {
467
499
  update: () => {
468
500
  }
469
501
  };
470
- var awarenessProvider = singleValueFacet(dummyProvider);
502
+ var awarenessProvider = Facet2.define({
503
+ combine: (providers) => providers[0] ?? dummyProvider
504
+ });
471
505
  var RemoteSelectionChangedAnnotation = Annotation2.define();
472
506
  var awareness = (provider = dummyProvider) => {
473
507
  return [
@@ -482,7 +516,7 @@ var RemoteSelectionsDecorator = class {
482
516
  constructor(view) {
483
517
  this._ctx = new Context(void 0, {
484
518
  F: __dxlog_file2,
485
- L: 80
519
+ L: 82
486
520
  });
487
521
  this.decorations = RangeSet.of([]);
488
522
  this._cursorConverter = view.state.facet(Cursor.converter);
@@ -1110,9 +1144,11 @@ import { RangeSetBuilder } from "@codemirror/state";
1110
1144
  import { Decoration as Decoration3, EditorView as EditorView5, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
1111
1145
 
1112
1146
  // packages/ui/react-ui-editor/src/extensions/command/state.ts
1113
- import { StateEffect as StateEffect2, StateField as StateField3 } from "@codemirror/state";
1147
+ import { Facet as Facet3, StateEffect as StateEffect2, StateField as StateField3 } from "@codemirror/state";
1114
1148
  import { showTooltip } from "@codemirror/view";
1115
- var commandConfig = singleValueFacet();
1149
+ var commandConfig = Facet3.define({
1150
+ combine: (providers) => providers[0]
1151
+ });
1116
1152
  var commandState = StateField3.define({
1117
1153
  create: () => ({}),
1118
1154
  update: (state2, tr) => {
@@ -1237,51 +1273,6 @@ var clientRectsFor = (dom) => {
1237
1273
  }
1238
1274
  };
1239
1275
 
1240
- // packages/ui/react-ui-editor/src/extensions/util/error.ts
1241
- import { log as log3 } from "@dxos/log";
1242
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/util/error.ts";
1243
- var wrapWithCatch = (fn) => {
1244
- return (...args) => {
1245
- try {
1246
- return fn(...args);
1247
- } catch (err) {
1248
- log3.catch(err, void 0, {
1249
- F: __dxlog_file5,
1250
- L: 12,
1251
- S: void 0,
1252
- C: (f, a) => f(...a)
1253
- });
1254
- }
1255
- };
1256
- };
1257
-
1258
- // packages/ui/react-ui-editor/src/extensions/util/overlap.ts
1259
- var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
1260
-
1261
- // packages/ui/react-ui-editor/src/extensions/util/react.tsx
1262
- import React from "react";
1263
- import { createRoot } from "react-dom/client";
1264
- import { ThemeProvider } from "@dxos/react-ui";
1265
- import { defaultTx } from "@dxos/react-ui-theme";
1266
- var createElement = (tag, options, children) => {
1267
- const el = document.createElement(tag);
1268
- if (options?.className) {
1269
- el.className = options.className;
1270
- }
1271
- if (children) {
1272
- el.append(...Array.isArray(children) ? children : [
1273
- children
1274
- ]);
1275
- }
1276
- return el;
1277
- };
1278
- var renderRoot = (root, node) => {
1279
- createRoot(root).render(/* @__PURE__ */ React.createElement(ThemeProvider, {
1280
- tx: defaultTx
1281
- }, node));
1282
- return root;
1283
- };
1284
-
1285
1276
  // packages/ui/react-ui-editor/src/extensions/command/hint.ts
1286
1277
  var CommandHint = class extends WidgetType2 {
1287
1278
  constructor(content) {
@@ -1364,7 +1355,7 @@ var command = (options) => {
1364
1355
 
1365
1356
  // packages/ui/react-ui-editor/src/extensions/comments.ts
1366
1357
  import { invertedEffects } from "@codemirror/commands";
1367
- import { StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
1358
+ import { Facet as Facet4, StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
1368
1359
  import { hoverTooltip, keymap as keymap4, Decoration as Decoration4, EditorView as EditorView7, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
1369
1360
  import sortBy from "lodash.sortby";
1370
1361
  import { useEffect, useMemo, useState } from "react";
@@ -1372,6 +1363,51 @@ import { debounce } from "@dxos/async";
1372
1363
  import { log as log5 } from "@dxos/log";
1373
1364
  import { nonNullable } from "@dxos/util";
1374
1365
 
1366
+ // packages/ui/react-ui-editor/src/extensions/util/error.ts
1367
+ import { log as log3 } from "@dxos/log";
1368
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/util/error.ts";
1369
+ var wrapWithCatch = (fn) => {
1370
+ return (...args) => {
1371
+ try {
1372
+ return fn(...args);
1373
+ } catch (err) {
1374
+ log3.catch(err, void 0, {
1375
+ F: __dxlog_file5,
1376
+ L: 12,
1377
+ S: void 0,
1378
+ C: (f, a) => f(...a)
1379
+ });
1380
+ }
1381
+ };
1382
+ };
1383
+
1384
+ // packages/ui/react-ui-editor/src/extensions/util/overlap.ts
1385
+ var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
1386
+
1387
+ // packages/ui/react-ui-editor/src/extensions/util/react.tsx
1388
+ import React from "react";
1389
+ import { createRoot } from "react-dom/client";
1390
+ import { ThemeProvider } from "@dxos/react-ui";
1391
+ import { defaultTx } from "@dxos/react-ui-theme";
1392
+ var createElement = (tag, options, children) => {
1393
+ const el = document.createElement(tag);
1394
+ if (options?.className) {
1395
+ el.className = options.className;
1396
+ }
1397
+ if (children) {
1398
+ el.append(...Array.isArray(children) ? children : [
1399
+ children
1400
+ ]);
1401
+ }
1402
+ return el;
1403
+ };
1404
+ var renderRoot = (root, node) => {
1405
+ createRoot(root).render(/* @__PURE__ */ React.createElement(ThemeProvider, {
1406
+ tx: defaultTx
1407
+ }, node));
1408
+ return root;
1409
+ };
1410
+
1375
1411
  // packages/ui/react-ui-editor/src/util.ts
1376
1412
  import { log as log4 } from "@dxos/log";
1377
1413
  var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
@@ -1381,16 +1417,12 @@ var callbackWrapper = (fn) => (...args) => {
1381
1417
  } catch (err) {
1382
1418
  log4.catch(err, void 0, {
1383
1419
  F: __dxlog_file6,
1384
- L: 19,
1420
+ L: 18,
1385
1421
  S: void 0,
1386
1422
  C: (f, a) => f(...a)
1387
1423
  });
1388
1424
  }
1389
1425
  };
1390
- var debugDispatcher = (trs, view) => {
1391
- logChanges(trs);
1392
- view.update(trs);
1393
- };
1394
1426
  var logChanges = (trs) => {
1395
1427
  const changes = trs.flatMap((tr) => {
1396
1428
  if (tr.changes.empty) {
@@ -1411,7 +1443,7 @@ var logChanges = (trs) => {
1411
1443
  changes
1412
1444
  }, {
1413
1445
  F: __dxlog_file6,
1414
- L: 49,
1446
+ L: 39,
1415
1447
  S: void 0,
1416
1448
  C: (f, a) => f(...a)
1417
1449
  });
@@ -1420,6 +1452,9 @@ var logChanges = (trs) => {
1420
1452
 
1421
1453
  // packages/ui/react-ui-editor/src/extensions/comments.ts
1422
1454
  var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/comments.ts";
1455
+ var documentId = Facet4.define({
1456
+ combine: (values) => values[0]
1457
+ });
1423
1458
  var setComments = StateEffect3.define();
1424
1459
  var setSelection = StateEffect3.define();
1425
1460
  var setCommentState = StateEffect3.define();
@@ -1490,7 +1525,7 @@ var commentsDecorations = EditorView7.decorations.compute([
1490
1525
  if (!range) {
1491
1526
  log5.warn("Invalid range:", range, {
1492
1527
  F: __dxlog_file7,
1493
- L: 143,
1528
+ L: 147,
1494
1529
  S: void 0,
1495
1530
  C: (f, a) => f(...a)
1496
1531
  });
@@ -1652,13 +1687,15 @@ var createComment = (view) => {
1652
1687
  }
1653
1688
  return false;
1654
1689
  };
1655
- var optionsFacet = singleValueFacet();
1690
+ var optionsFacet = Facet4.define({
1691
+ combine: (providers) => providers[0]
1692
+ });
1656
1693
  var comments = (options = {}) => {
1657
1694
  const { key: shortcut = "meta-'" } = options;
1658
1695
  const handleSelect = debounce((state2) => options.onSelect?.(state2), 200);
1659
1696
  return [
1660
1697
  optionsFacet.of(options),
1661
- options.id ? documentId.of(options.id) : void 0,
1698
+ documentId.of(options.id),
1662
1699
  commentsState,
1663
1700
  commentsDecorations,
1664
1701
  handleCommentClick,
@@ -1666,17 +1703,17 @@ var comments = (options = {}) => {
1666
1703
  //
1667
1704
  // Keymap.
1668
1705
  //
1669
- options.onCreate && keymap4.of([
1706
+ options.onCreate ? keymap4.of([
1670
1707
  {
1671
1708
  key: shortcut,
1672
1709
  run: callbackWrapper(createComment)
1673
1710
  }
1674
- ]),
1711
+ ]) : [],
1675
1712
  //
1676
1713
  // Hover tooltip (for key shortcut hints, etc.)
1677
1714
  // TODO(burdon): Factor out to generic hints extension for current selection/line.
1678
1715
  //
1679
- options.onHover && hoverTooltip((view, pos) => {
1716
+ options.onHover ? hoverTooltip((view, pos) => {
1680
1717
  const selection = view.state.selection.main;
1681
1718
  if (selection && pos >= selection.from && pos <= selection.to) {
1682
1719
  return {
@@ -1701,7 +1738,7 @@ var comments = (options = {}) => {
1701
1738
  // TODO(burdon): Hide on change triggered immediately?
1702
1739
  // hideOnChange: true,
1703
1740
  hoverTime: 1e3
1704
- }),
1741
+ }) : [],
1705
1742
  //
1706
1743
  // Track deleted ranges and update ranges for decorations.
1707
1744
  //
@@ -1770,8 +1807,8 @@ var comments = (options = {}) => {
1770
1807
  });
1771
1808
  }
1772
1809
  }),
1773
- options.onUpdate && trackPastedComments(options.onUpdate)
1774
- ].filter(nonNullable);
1810
+ options.onUpdate ? trackPastedComments(options.onUpdate) : []
1811
+ ];
1775
1812
  };
1776
1813
  var scrollThreadIntoView = (view, id, center = true) => {
1777
1814
  const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
@@ -1803,11 +1840,8 @@ var scrollThreadIntoView = (view, id, center = true) => {
1803
1840
  }
1804
1841
  };
1805
1842
  var selectionOverlapsComment = (state2) => {
1806
- const commentState = state2.field(commentsState, false);
1807
- if (commentState === void 0) {
1808
- return false;
1809
- }
1810
1843
  const { selection } = state2;
1844
+ const commentState = state2.field(commentsState);
1811
1845
  for (const range of selection.ranges) {
1812
1846
  if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
1813
1847
  return true;
@@ -1901,6 +1935,25 @@ var debugNodeLogger = (log9 = console.log) => {
1901
1935
  });
1902
1936
  };
1903
1937
 
1938
+ // packages/ui/react-ui-editor/src/extensions/doc.ts
1939
+ import { Facet as Facet5 } from "@codemirror/state";
1940
+ import { invariant as invariant3 } from "@dxos/invariant";
1941
+ var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/doc.ts";
1942
+ var documentId2 = Facet5.define({
1943
+ combine: (providers) => {
1944
+ invariant3(providers.length <= 1, void 0, {
1945
+ F: __dxlog_file8,
1946
+ L: 14,
1947
+ S: void 0,
1948
+ A: [
1949
+ "providers.length <= 1",
1950
+ ""
1951
+ ]
1952
+ });
1953
+ return providers[0];
1954
+ }
1955
+ });
1956
+
1904
1957
  // packages/ui/react-ui-editor/src/extensions/dnd.ts
1905
1958
  import { dropCursor, EditorView as EditorView8 } from "@codemirror/view";
1906
1959
  var styles4 = EditorView8.theme({
@@ -1963,9 +2016,11 @@ var headings = {
1963
2016
  6: "text-md"
1964
2017
  };
1965
2018
  var theme = {
2019
+ mark: "opacity-50",
1966
2020
  code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
1967
2021
  codeMark: "font-mono text-primary-500",
1968
- mark: "opacity-50",
2022
+ // TODO(burdon): Replace with widget.
2023
+ blockquote: "pl-1 mr-1 border-is-4 border-orange-500 dark:border-orange-500 dark:text-neutral-500",
1969
2024
  heading: (level) => {
1970
2025
  return mx(headings[level], "dark:text-primary-400");
1971
2026
  }
@@ -2008,11 +2063,9 @@ var defaultTheme = {
2008
2063
  /**
2009
2064
  * Gutters
2010
2065
  * NOTE: Gutters should have the same top margin as the content.
2011
- * NOTE: They can't be transparent since the content needs to scroll below.
2012
2066
  */
2013
2067
  ".cm-gutters": {
2014
- background: "var(--surface-bg)",
2015
- borderRight: "none"
2068
+ background: "var(--surface-bg)"
2016
2069
  },
2017
2070
  ".cm-gutter": {},
2018
2071
  ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
@@ -2033,7 +2086,7 @@ var defaultTheme = {
2033
2086
  paddingInline: 0
2034
2087
  },
2035
2088
  ".cm-activeLine": {
2036
- background: "var(--dx-cmActiveLine)"
2089
+ background: "var(--dx-hoverSurface)"
2037
2090
  },
2038
2091
  /**
2039
2092
  * Cursor (layer).
@@ -2181,7 +2234,7 @@ var defaultTheme = {
2181
2234
  };
2182
2235
 
2183
2236
  // packages/ui/react-ui-editor/src/extensions/factories.ts
2184
- var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
2237
+ var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
2185
2238
  var preventNewline = EditorState.transactionFilter.of((tr) => tr.newDoc.lines > 1 ? [] : tr);
2186
2239
  var defaultBasicOptions = {
2187
2240
  allowMultipleSelections: true,
@@ -2206,7 +2259,7 @@ var createBasicExtensions = (_props) => {
2206
2259
  // NOTE: Doesn't catch errors in keymap functions.
2207
2260
  EditorView9.exceptionSink.of((err) => {
2208
2261
  log6.catch(err, void 0, {
2209
- F: __dxlog_file8,
2262
+ F: __dxlog_file9,
2210
2263
  L: 93,
2211
2264
  S: void 0,
2212
2265
  C: (f, a) => f(...a)
@@ -2303,10 +2356,9 @@ var folding = (_props = {}) => [
2303
2356
  }),
2304
2357
  foldGutter({
2305
2358
  markerDOM: (open) => {
2306
- const el = createElement("div", {
2359
+ return renderRoot(createElement("div", {
2307
2360
  className: "flex h-full items-center"
2308
- });
2309
- return renderRoot(el, /* @__PURE__ */ React2.createElement(Icon, {
2361
+ }), /* @__PURE__ */ React2.createElement(Icon, {
2310
2362
  icon: "ph--caret-right--regular",
2311
2363
  classNames: [
2312
2364
  getSize(3),
@@ -3293,7 +3345,7 @@ var getFormatting = (state2) => {
3293
3345
  null
3294
3346
  ];
3295
3347
  let link = false;
3296
- let blockQuote2 = null;
3348
+ let blockQuote = null;
3297
3349
  let listStyle = null;
3298
3350
  const stack = [];
3299
3351
  let currentBlock = null;
@@ -3402,10 +3454,10 @@ var getFormatting = (state2) => {
3402
3454
  hasList = stack[i] === "TaskList" ? "task" : stack[i] === "BulletList" ? "bullet" : "ordered";
3403
3455
  }
3404
3456
  }
3405
- if (blockQuote2 === null) {
3406
- blockQuote2 = hasQuote;
3407
- } else if (!hasQuote && blockQuote2) {
3408
- blockQuote2 = false;
3457
+ if (blockQuote === null) {
3458
+ blockQuote = hasQuote;
3459
+ } else if (!hasQuote && blockQuote) {
3460
+ blockQuote = false;
3409
3461
  }
3410
3462
  if (listStyle === null) {
3411
3463
  listStyle = hasList;
@@ -3424,7 +3476,7 @@ var getFormatting = (state2) => {
3424
3476
  return {
3425
3477
  blankLine,
3426
3478
  blockType: blockType || null,
3427
- blockQuote: blockQuote2 ?? false,
3479
+ blockQuote: blockQuote ?? false,
3428
3480
  code: inline[3] ?? false,
3429
3481
  emphasis: inline[1] ?? false,
3430
3482
  strong: inline[0] ?? false,
@@ -3675,6 +3727,12 @@ var markdownHighlightStyle = (_options = {}) => {
3675
3727
  ],
3676
3728
  class: theme.code
3677
3729
  },
3730
+ {
3731
+ tag: [
3732
+ markdownTags.QuoteMark
3733
+ ],
3734
+ class: theme.blockquote
3735
+ },
3678
3736
  {
3679
3737
  tag: [
3680
3738
  markdownTags.TableCell
@@ -3756,7 +3814,7 @@ var convertTreeToJson = (state2) => {
3756
3814
  import { syntaxTree as syntaxTree7 } from "@codemirror/language";
3757
3815
  import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect4 } from "@codemirror/state";
3758
3816
  import { EditorView as EditorView16, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
3759
- import { invariant as invariant3 } from "@dxos/invariant";
3817
+ import { invariant as invariant4 } from "@dxos/invariant";
3760
3818
  import { mx as mx2 } from "@dxos/react-ui-theme";
3761
3819
 
3762
3820
  // packages/ui/react-ui-editor/src/extensions/markdown/changes.ts
@@ -4019,15 +4077,6 @@ var formattingStyles = EditorView14.theme({
4019
4077
  width: `${orderedListIndentationWidth}px`
4020
4078
  },
4021
4079
  /**
4022
- * Blockquote.
4023
- */
4024
- "& .cm-blockquote": {
4025
- background: "var(--dx-cmCodeblock)",
4026
- borderLeft: "2px solid var(--dx-cmSeparator)",
4027
- paddingLeft: "1rem",
4028
- margin: "0"
4029
- },
4030
- /**
4031
4080
  * Code and codeblocks.
4032
4081
  */
4033
4082
  "& .cm-code": {
@@ -4187,7 +4236,7 @@ var TableWidget = class extends WidgetType4 {
4187
4236
  };
4188
4237
 
4189
4238
  // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
4190
- var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts";
4239
+ var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts";
4191
4240
  var Unicode = {
4192
4241
  emDash: "\u2014",
4193
4242
  bullet: "\u2022",
@@ -4210,7 +4259,6 @@ var LinkButton = class extends WidgetType5 {
4210
4259
  eq(other) {
4211
4260
  return this.url === other.url;
4212
4261
  }
4213
- // TODO(burdon): Create icon and link directly without react?
4214
4262
  toDOM(view) {
4215
4263
  const el = document.createElement("span");
4216
4264
  this.render(el, this.url);
@@ -4278,9 +4326,6 @@ var TextWidget = class extends WidgetType5 {
4278
4326
  }
4279
4327
  };
4280
4328
  var hide = Decoration7.replace({});
4281
- var blockQuote = Decoration7.line({
4282
- class: mx2("cm-blockquote")
4283
- });
4284
4329
  var fencedCodeLine = Decoration7.line({
4285
4330
  class: mx2("cm-code cm-codeblock-line")
4286
4331
  });
@@ -4320,9 +4365,9 @@ var buildDecorations2 = (view, options, focus) => {
4320
4365
  const { state: state2 } = view;
4321
4366
  const headerLevels = [];
4322
4367
  const getHeaderLevels = (node, level) => {
4323
- invariant3(level > 0, void 0, {
4324
- F: __dxlog_file9,
4325
- L: 178,
4368
+ invariant4(level > 0, void 0, {
4369
+ F: __dxlog_file10,
4370
+ L: 176,
4326
4371
  S: void 0,
4327
4372
  A: [
4328
4373
  "level > 0",
@@ -4359,9 +4404,9 @@ var buildDecorations2 = (view, options, focus) => {
4359
4404
  listLevels.pop();
4360
4405
  };
4361
4406
  const getCurrentListLevel = () => {
4362
- invariant3(listLevels.length, void 0, {
4363
- F: __dxlog_file9,
4364
- L: 200,
4407
+ invariant4(listLevels.length, void 0, {
4408
+ F: __dxlog_file10,
4409
+ L: 198,
4365
4410
  S: void 0,
4366
4411
  A: [
4367
4412
  "listLevels.length",
@@ -4454,30 +4499,7 @@ var buildDecorations2 = (view, options, focus) => {
4454
4499
  atomicDeco.add(line.from, to, checked ? checkedTask : uncheckedTask);
4455
4500
  break;
4456
4501
  }
4457
- //
4458
- // Blockquote > QuoteMark > Paragraph
4459
- //
4460
- case "Blockquote": {
4461
- const editing = editingRange(state2, node, focus);
4462
- const quoteMark = node.node.getChild("QuoteMark");
4463
- const paragraph = node.node.getChild("Paragraph");
4464
- if (!editing && quoteMark && paragraph) {
4465
- atomicDeco.add(quoteMark.from, paragraph.from, hide);
4466
- }
4467
- for (const block of view.viewportLineBlocks) {
4468
- if (block.to < node.from) {
4469
- continue;
4470
- }
4471
- if (block.from > node.to) {
4472
- break;
4473
- }
4474
- deco.add(block.from, block.from, blockQuote);
4475
- }
4476
- break;
4477
- }
4478
- //
4479
4502
  // CommentBlock
4480
- //
4481
4503
  case "CommentBlock": {
4482
4504
  const editing = editingRange(state2, node, focus);
4483
4505
  for (const block of view.viewportLineBlocks) {
@@ -4487,18 +4509,16 @@ var buildDecorations2 = (view, options, focus) => {
4487
4509
  if (block.from > node.to) {
4488
4510
  break;
4489
4511
  }
4490
- const isFirst = block.from <= node.from;
4491
- const isLast = block.to >= node.to && /^(\s>)*-->$/.test(state2.doc.sliceString(block.from, block.to));
4492
- deco.add(block.from, block.from, isFirst ? commentBlockLineFirst : isLast ? commentBlockLineLast : commentBlockLine);
4493
- if (!editing && (isFirst || isLast)) {
4512
+ const first = block.from <= node.from;
4513
+ const last = block.to >= node.to && /^(\s>)*-->$/.test(state2.doc.sliceString(block.from, block.to));
4514
+ deco.add(block.from, block.from, first ? commentBlockLineFirst : last ? commentBlockLineLast : commentBlockLine);
4515
+ if (!editing && (first || last)) {
4494
4516
  atomicDeco.add(block.from, block.to, hide);
4495
4517
  }
4496
4518
  }
4497
4519
  break;
4498
4520
  }
4499
- //
4500
4521
  // FencedCode > CodeMark > [CodeInfo] > CodeText > CodeMark
4501
- //
4502
4522
  case "FencedCode": {
4503
4523
  for (const block of view.viewportLineBlocks) {
4504
4524
  if (block.to < node.from) {
@@ -4517,9 +4537,7 @@ var buildDecorations2 = (view, options, focus) => {
4517
4537
  }
4518
4538
  return false;
4519
4539
  }
4520
- //
4521
4540
  // Link > [LinkMark, URL]
4522
- //
4523
4541
  case "Link": {
4524
4542
  const marks = node.node.getChildren("LinkMark");
4525
4543
  const urlNode = node.node.getChild("URL");
@@ -4546,9 +4564,7 @@ var buildDecorations2 = (view, options, focus) => {
4546
4564
  }
4547
4565
  break;
4548
4566
  }
4549
- //
4550
4567
  // HR
4551
- //
4552
4568
  case "HorizontalRule": {
4553
4569
  if (!editingRange(state2, node, focus)) {
4554
4570
  deco.add(node.from, node.to, horizontalRule);
@@ -4645,42 +4661,40 @@ var decorateMarkdown = (options = {}) => {
4645
4661
  import { syntaxTree as syntaxTree8 } from "@codemirror/language";
4646
4662
  import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
4647
4663
  import { tooltipContent } from "@dxos/react-ui-theme";
4648
- var linkTooltip = (render) => {
4649
- return hoverTooltip2((view, pos, side) => {
4650
- const syntax = syntaxTree8(view.state).resolveInner(pos, side);
4651
- let link = null;
4652
- for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
4653
- link = node.name === "Link" ? node : null;
4654
- }
4655
- const url = link && link.getChild("URL");
4656
- if (!url || !link) {
4657
- return null;
4664
+ var linkTooltip = (render) => hoverTooltip2((view, pos, side) => {
4665
+ const syntax = syntaxTree8(view.state).resolveInner(pos, side);
4666
+ let link = null;
4667
+ for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
4668
+ link = node.name === "Link" ? node : null;
4669
+ }
4670
+ const url = link && link.getChild("URL");
4671
+ if (!url || !link) {
4672
+ return null;
4673
+ }
4674
+ const urlText = view.state.sliceDoc(url.from, url.to);
4675
+ return {
4676
+ pos: link.from,
4677
+ end: link.to,
4678
+ above: true,
4679
+ create: () => {
4680
+ const el = document.createElement("div");
4681
+ el.className = tooltipContent({}, "pli-2 plb-1");
4682
+ render(el, urlText);
4683
+ return {
4684
+ dom: el,
4685
+ offset: {
4686
+ x: 0,
4687
+ y: 4
4688
+ }
4689
+ };
4658
4690
  }
4659
- const urlText = view.state.sliceDoc(url.from, url.to);
4660
- return {
4661
- pos: link.from,
4662
- end: link.to,
4663
- above: true,
4664
- create: () => {
4665
- const el = document.createElement("div");
4666
- el.className = tooltipContent({}, "pli-2 plb-1");
4667
- render(el, urlText);
4668
- return {
4669
- dom: el,
4670
- offset: {
4671
- x: 0,
4672
- y: 4
4673
- }
4674
- };
4675
- }
4676
- };
4677
- });
4678
- };
4691
+ };
4692
+ });
4679
4693
 
4680
4694
  // packages/ui/react-ui-editor/src/extensions/mention.ts
4681
4695
  import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
4682
4696
  import { log as log7 } from "@dxos/log";
4683
- var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/mention.ts";
4697
+ var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/mention.ts";
4684
4698
  var mention = ({ onSearch }) => {
4685
4699
  return autocompletion2({
4686
4700
  // TODO(burdon): Not working.
@@ -4695,7 +4709,7 @@ var mention = ({ onSearch }) => {
4695
4709
  log7.info("completion context", {
4696
4710
  context
4697
4711
  }, {
4698
- F: __dxlog_file10,
4712
+ F: __dxlog_file11,
4699
4713
  L: 26,
4700
4714
  S: void 0,
4701
4715
  C: (f, a) => f(...a)
@@ -4716,6 +4730,7 @@ var mention = ({ onSearch }) => {
4716
4730
  };
4717
4731
 
4718
4732
  // packages/ui/react-ui-editor/src/extensions/modes.ts
4733
+ import { Facet as Facet6 } from "@codemirror/state";
4719
4734
  import { keymap as keymap8 } from "@codemirror/view";
4720
4735
  import { vim } from "@replit/codemirror-vim";
4721
4736
  import { vscodeKeymap } from "@replit/codemirror-vscode-keymap";
@@ -4730,7 +4745,9 @@ var EditorInputModes = [
4730
4745
  "vim",
4731
4746
  "vscode"
4732
4747
  ];
4733
- var editorInputMode = singleValueFacet({});
4748
+ var editorInputMode = Facet6.define({
4749
+ combine: (modes) => modes[0] ?? {}
4750
+ });
4734
4751
  var InputModeExtensions = {
4735
4752
  default: [],
4736
4753
  vscode: [
@@ -4761,8 +4778,101 @@ var InputModeExtensions = {
4761
4778
  ]
4762
4779
  };
4763
4780
 
4781
+ // packages/ui/react-ui-editor/src/extensions/state.ts
4782
+ import { Transaction as Transaction2 } from "@codemirror/state";
4783
+ import { EditorView as EditorView17, keymap as keymap9 } from "@codemirror/view";
4784
+ import { debounce as debounce2 } from "@dxos/async";
4785
+ import { invariant as invariant5 } from "@dxos/invariant";
4786
+ import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
4787
+ var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/state.ts";
4788
+ var stateRestoreAnnotation = "dxos.org/cm/state-restore";
4789
+ var keyPrefix = "dxos.org/react-ui-editor/state";
4790
+ var localStorageStateStoreAdapter = {
4791
+ getState: (id) => {
4792
+ invariant5(id, void 0, {
4793
+ F: __dxlog_file12,
4794
+ L: 34,
4795
+ S: void 0,
4796
+ A: [
4797
+ "id",
4798
+ ""
4799
+ ]
4800
+ });
4801
+ const state2 = localStorage.getItem(`${keyPrefix}/${id}`);
4802
+ return state2 ? JSON.parse(state2) : void 0;
4803
+ },
4804
+ setState: (id, state2) => {
4805
+ invariant5(id, void 0, {
4806
+ F: __dxlog_file12,
4807
+ L: 40,
4808
+ S: void 0,
4809
+ A: [
4810
+ "id",
4811
+ ""
4812
+ ]
4813
+ });
4814
+ localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state2));
4815
+ }
4816
+ };
4817
+ var createEditorStateTransaction = ({ scrollTo, selection }) => {
4818
+ return {
4819
+ selection,
4820
+ scrollIntoView: !scrollTo,
4821
+ effects: scrollTo ? EditorView17.scrollIntoView(scrollTo, {
4822
+ yMargin: 96
4823
+ }) : void 0,
4824
+ annotations: Transaction2.userEvent.of(stateRestoreAnnotation)
4825
+ };
4826
+ };
4827
+ var state = ({ getState, setState } = {}) => {
4828
+ const setStateDebounced = debounce2(setState, 1e3);
4829
+ return [
4830
+ // TODO(burdon): Track scrolling (currently only updates when cursor moves).
4831
+ // EditorView.domEventHandlers({
4832
+ // scroll: (event) => {
4833
+ // setStateDebounced(id, {});
4834
+ // },
4835
+ // }),
4836
+ EditorView17.updateListener.of(({ view, transactions }) => {
4837
+ const id = view.state.facet(documentId2);
4838
+ if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
4839
+ return;
4840
+ }
4841
+ if (setState) {
4842
+ const { scrollTop } = view.scrollDOM;
4843
+ const pos = view.posAtCoords({
4844
+ x: 0,
4845
+ y: scrollTop
4846
+ });
4847
+ if (pos !== null) {
4848
+ const { anchor, head } = view.state.selection.main;
4849
+ setStateDebounced(id, {
4850
+ scrollTo: pos,
4851
+ selection: {
4852
+ anchor,
4853
+ head
4854
+ }
4855
+ });
4856
+ }
4857
+ }
4858
+ }),
4859
+ getState && keymap9.of([
4860
+ {
4861
+ key: "ctrl-r",
4862
+ run: (view) => {
4863
+ const state2 = getState(view.state.facet(documentId2));
4864
+ if (state2) {
4865
+ view.dispatch(createEditorStateTransaction(state2));
4866
+ }
4867
+ return true;
4868
+ }
4869
+ }
4870
+ ])
4871
+ ].filter(isNotFalsy3);
4872
+ };
4873
+
4764
4874
  // packages/ui/react-ui-editor/src/extensions/typewriter.ts
4765
- import { keymap as keymap9 } from "@codemirror/view";
4875
+ import { keymap as keymap10 } from "@codemirror/view";
4766
4876
  var defaultItems = [
4767
4877
  "hello world!",
4768
4878
  "this is a test.",
@@ -4772,7 +4882,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
4772
4882
  let t;
4773
4883
  let idx = 0;
4774
4884
  return [
4775
- keymap9.of([
4885
+ keymap10.of([
4776
4886
  {
4777
4887
  // Reset.
4778
4888
  key: "alt-meta-'",
@@ -5203,20 +5313,20 @@ var Toolbar = {
5203
5313
  };
5204
5314
 
5205
5315
  // packages/ui/react-ui-editor/src/defaults.ts
5206
- import { EditorView as EditorView17 } from "@codemirror/view";
5316
+ import { EditorView as EditorView18 } from "@codemirror/view";
5207
5317
  import { mx as mx3 } from "@dxos/react-ui-theme";
5208
5318
  var margin = "!mt-[1rem]";
5209
5319
  var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
5210
5320
  var editorFullWidth = mx3(margin);
5211
5321
  var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
5212
- var editorGutter = EditorView17.theme({
5322
+ var editorGutter = EditorView18.theme({
5213
5323
  // Match margin from content.
5214
5324
  ".cm-gutters": {
5215
5325
  marginTop: "16px",
5216
5326
  paddingRight: "1rem"
5217
5327
  }
5218
5328
  });
5219
- var editorMonospace = EditorView17.theme({
5329
+ var editorMonospace = EditorView18.theme({
5220
5330
  ".cm-content": {
5221
5331
  fontFamily: fontMono
5222
5332
  }
@@ -5229,16 +5339,17 @@ var useActionHandler = (view) => {
5229
5339
 
5230
5340
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
5231
5341
  import { EditorState as EditorState2 } from "@codemirror/state";
5232
- import { EditorView as EditorView18 } from "@codemirror/view";
5342
+ import { EditorView as EditorView19 } from "@codemirror/view";
5233
5343
  import { useFocusableGroup } from "@fluentui/react-tabster";
5234
5344
  import { useCallback, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2, useState as useState4 } from "react";
5235
5345
  import { log as log8 } from "@dxos/log";
5236
- import { getProviderValue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
5237
- var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
5346
+ import { getProviderValue, isNotFalsy as isNotFalsy4 } from "@dxos/util";
5347
+ var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
5238
5348
  var instanceCount = 0;
5239
5349
  var useTextEditor = (props = {}, deps = []) => {
5240
5350
  const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo3(() => getProviderValue(props), deps ?? []);
5241
5351
  const [instanceId] = useState4(() => `text-editor-${++instanceCount}`);
5352
+ const onUpdate = useRef2();
5242
5353
  const [view, setView] = useState4();
5243
5354
  const parentRef = useRef2(null);
5244
5355
  useEffect3(() => {
@@ -5249,7 +5360,7 @@ var useTextEditor = (props = {}, deps = []) => {
5249
5360
  instanceId,
5250
5361
  doc: initialValue?.length ?? 0
5251
5362
  }, {
5252
- F: __dxlog_file11,
5363
+ F: __dxlog_file13,
5253
5364
  L: 76,
5254
5365
  S: void 0,
5255
5366
  C: (f, a) => f(...a)
@@ -5268,38 +5379,46 @@ var useTextEditor = (props = {}, deps = []) => {
5268
5379
  }
5269
5380
  const state2 = EditorState2.create({
5270
5381
  doc: initialValue,
5271
- // selection: initialSelection,
5382
+ selection: initialSelection,
5272
5383
  extensions: [
5273
- id && documentId.of(id),
5274
- extensions,
5275
- // NOTE: This doesn't catch errors in keymap functions.
5276
- EditorView18.exceptionSink.of((err) => {
5384
+ id && documentId2.of(id),
5385
+ // NOTE: Doesn't catch errors in keymap functions.
5386
+ EditorView19.exceptionSink.of((err) => {
5277
5387
  log8.catch(err, void 0, {
5278
- F: __dxlog_file11,
5388
+ F: __dxlog_file13,
5279
5389
  L: 98,
5280
5390
  S: void 0,
5281
5391
  C: (f, a) => f(...a)
5282
5392
  });
5393
+ }),
5394
+ extensions,
5395
+ EditorView19.updateListener.of(() => {
5396
+ setTimeout(() => {
5397
+ onUpdate.current?.();
5398
+ });
5283
5399
  })
5284
- ].filter(isNotFalsy3)
5400
+ ].filter(isNotFalsy4)
5285
5401
  });
5286
- view2 = new EditorView18({
5402
+ view2 = new EditorView19({
5287
5403
  parent: parentRef.current,
5404
+ selection: initialSelection,
5288
5405
  state: state2,
5289
- scrollTo: scrollTo ? EditorView18.scrollIntoView(scrollTo, {
5290
- yMargin: 96
5291
- }) : void 0,
5292
- dispatchTransactions: debug ? debugDispatcher : void 0
5406
+ // NOTE: Uncomment to debug/monitor all transactions.
5407
+ // https://codemirror.net/docs/ref/#view.EditorView.dispatch
5408
+ dispatchTransactions: (trs, view3) => {
5409
+ if (debug) {
5410
+ logChanges(trs);
5411
+ }
5412
+ view3.update(trs);
5413
+ }
5293
5414
  });
5294
- if (moveToEndOfLine && !initialSelection) {
5415
+ if (!initialValue && moveToEndOfLine) {
5295
5416
  const { to } = view2.state.doc.lineAt(0);
5296
- if (to) {
5297
- view2.dispatch({
5298
- selection: {
5299
- anchor: to
5300
- }
5301
- });
5302
- }
5417
+ view2.dispatch({
5418
+ selection: {
5419
+ anchor: to
5420
+ }
5421
+ });
5303
5422
  }
5304
5423
  setView(view2);
5305
5424
  }
@@ -5307,8 +5426,8 @@ var useTextEditor = (props = {}, deps = []) => {
5307
5426
  log8("destroy", {
5308
5427
  id
5309
5428
  }, {
5310
- F: __dxlog_file11,
5311
- L: 135,
5429
+ F: __dxlog_file13,
5430
+ L: 134,
5312
5431
  S: void 0,
5313
5432
  C: (f, a) => f(...a)
5314
5433
  });
@@ -5317,33 +5436,21 @@ var useTextEditor = (props = {}, deps = []) => {
5317
5436
  }, deps);
5318
5437
  useEffect3(() => {
5319
5438
  if (view) {
5320
- if (view.state.facet(editorInputMode).noTabster) {
5321
- parentRef.current?.removeAttribute("data-tabster");
5322
- }
5323
- if (scrollTo || selection) {
5324
- if (selection && selection.anchor > view.state.doc.length) {
5325
- log8.warn("invalid selection", {
5326
- length: view.state.doc.length,
5327
- scrollTo,
5328
- selection
5329
- }, {
5330
- F: __dxlog_file11,
5331
- L: 149,
5332
- S: void 0,
5333
- C: (f, a) => f(...a)
5334
- });
5335
- return;
5336
- }
5337
- view.dispatch(createEditorStateTransaction(view.state, {
5439
+ onUpdate.current = () => {
5440
+ onUpdate.current = void 0;
5441
+ view.dispatch(createEditorStateTransaction({
5338
5442
  scrollTo,
5339
5443
  selection
5340
5444
  }));
5445
+ };
5446
+ if (view.state.facet(editorInputMode).noTabster) {
5447
+ parentRef.current?.removeAttribute("data-tabster");
5341
5448
  }
5342
5449
  }
5343
5450
  }, [
5344
5451
  view,
5345
- scrollTo,
5346
- selection
5452
+ selection,
5453
+ scrollTo
5347
5454
  ]);
5348
5455
  useEffect3(() => {
5349
5456
  if (view && autoFocus) {
@@ -5414,12 +5521,11 @@ export {
5414
5521
  createExternalCommentSync,
5415
5522
  createMarkdownExtensions,
5416
5523
  createThemeExtensions,
5417
- debugDispatcher,
5418
5524
  debugNodeLogger,
5419
5525
  debugTree,
5420
5526
  decorateMarkdown,
5421
5527
  defaultOptions,
5422
- documentId,
5528
+ documentId2 as documentId,
5423
5529
  dropFile,
5424
5530
  editorContent,
5425
5531
  editorFullWidth,
@@ -5435,7 +5541,7 @@ export {
5435
5541
  image,
5436
5542
  imageUpload,
5437
5543
  insertTable,
5438
- keymap10 as keymap,
5544
+ keymap11 as keymap,
5439
5545
  linkTooltip,
5440
5546
  listener,
5441
5547
  localStorageStateStoreAdapter,
@@ -5458,7 +5564,6 @@ export {
5458
5564
  setHeading,
5459
5565
  setSelection,
5460
5566
  setStyle,
5461
- singleValueFacet,
5462
5567
  state,
5463
5568
  table,
5464
5569
  tags2 as tags,