@dxos/react-ui-editor 0.6.12-staging.e11e696 → 0.6.12

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 (116) hide show
  1. package/dist/lib/browser/index.mjs +270 -153
  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/markdown/decorate.d.ts.map +1 -1
  30. package/dist/types/src/extensions/markdown/formatting.test.d.ts.map +1 -1
  31. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  32. package/dist/types/src/extensions/markdown/link.d.ts +1 -1
  33. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  34. package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
  35. package/dist/types/src/extensions/modes.d.ts +3 -3
  36. package/dist/types/src/extensions/modes.d.ts.map +1 -1
  37. package/dist/types/src/extensions/state.d.ts.map +1 -0
  38. package/dist/types/src/extensions/types.d.ts.map +1 -0
  39. package/dist/types/src/extensions/util/overlap.d.ts +1 -1
  40. package/dist/types/src/extensions/util/overlap.d.ts.map +1 -1
  41. package/dist/types/src/extensions/util/react.d.ts +1 -1
  42. package/dist/types/src/extensions/util/react.d.ts.map +1 -1
  43. package/dist/types/src/hooks/useTextEditor.d.ts +1 -1
  44. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  45. package/dist/types/src/index.d.ts +0 -1
  46. package/dist/types/src/index.d.ts.map +1 -1
  47. package/dist/types/src/styles/markdown.d.ts +2 -1
  48. package/dist/types/src/styles/markdown.d.ts.map +1 -1
  49. package/dist/types/src/styles/theme.d.ts.map +1 -1
  50. package/package.json +37 -54
  51. package/src/TextEditor.stories.tsx +17 -22
  52. package/src/defaults.ts +2 -0
  53. package/src/extensions/annotations.ts +1 -1
  54. package/src/extensions/autocomplete.ts +8 -9
  55. package/src/extensions/automerge/{automerge.test.tsx → automerge.spec.tsx} +0 -1
  56. package/src/extensions/automerge/automerge.stories.tsx +1 -1
  57. package/src/extensions/automerge/automerge.test.ts +13 -0
  58. package/src/extensions/automerge/automerge.ts +2 -2
  59. package/src/extensions/automerge/cursor.ts +1 -1
  60. package/src/extensions/awareness/awareness.ts +5 -3
  61. package/src/extensions/command/state.ts +4 -3
  62. package/src/extensions/comments.ts +43 -37
  63. package/src/{state → extensions}/cursor.ts +6 -3
  64. package/src/extensions/debug.ts +2 -2
  65. package/src/extensions/doc.ts +17 -0
  66. package/src/extensions/folding.tsx +2 -4
  67. package/src/extensions/index.ts +4 -0
  68. package/src/extensions/markdown/changes.test.ts +3 -1
  69. package/src/extensions/markdown/decorate.ts +6 -49
  70. package/src/extensions/markdown/formatting.test.ts +3 -1
  71. package/src/extensions/markdown/highlight.ts +5 -0
  72. package/src/extensions/markdown/link.ts +2 -3
  73. package/src/extensions/markdown/parser.test.ts +2 -1
  74. package/src/extensions/markdown/styles.ts +0 -10
  75. package/src/extensions/markdown/table.ts +3 -3
  76. package/src/extensions/modes.ts +5 -6
  77. package/src/{state → extensions}/state.ts +0 -1
  78. package/src/extensions/util/overlap.ts +1 -1
  79. package/src/extensions/util/react.tsx +1 -5
  80. package/src/hooks/useTextEditor.ts +2 -3
  81. package/src/index.ts +0 -1
  82. package/src/styles/markdown.ts +3 -1
  83. package/src/styles/theme.ts +1 -3
  84. package/dist/lib/browser/chunk-AZWYO7TE.mjs +0 -148
  85. package/dist/lib/browser/chunk-AZWYO7TE.mjs.map +0 -7
  86. package/dist/lib/browser/state/index.mjs +0 -17
  87. package/dist/lib/browser/state/index.mjs.map +0 -7
  88. package/dist/lib/node/chunk-5RSKGJRI.cjs +0 -169
  89. package/dist/lib/node/chunk-5RSKGJRI.cjs.map +0 -7
  90. package/dist/lib/node/index.cjs +0 -5480
  91. package/dist/lib/node/index.cjs.map +0 -7
  92. package/dist/lib/node/meta.json +0 -1
  93. package/dist/lib/node/state/index.cjs +0 -39
  94. package/dist/lib/node/state/index.cjs.map +0 -7
  95. package/dist/lib/node-esm/chunk-RCIWLRIY.mjs +0 -150
  96. package/dist/lib/node-esm/chunk-RCIWLRIY.mjs.map +0 -7
  97. package/dist/lib/node-esm/index.mjs +0 -5472
  98. package/dist/lib/node-esm/index.mjs.map +0 -7
  99. package/dist/lib/node-esm/meta.json +0 -1
  100. package/dist/lib/node-esm/state/index.mjs +0 -18
  101. package/dist/lib/node-esm/state/index.mjs.map +0 -7
  102. package/dist/types/src/state/cursor.d.ts.map +0 -1
  103. package/dist/types/src/state/doc.d.ts +0 -5
  104. package/dist/types/src/state/doc.d.ts.map +0 -1
  105. package/dist/types/src/state/index.d.ts +0 -6
  106. package/dist/types/src/state/index.d.ts.map +0 -1
  107. package/dist/types/src/state/state.d.ts.map +0 -1
  108. package/dist/types/src/state/types.d.ts.map +0 -1
  109. package/dist/types/src/state/util.d.ts +0 -3
  110. package/dist/types/src/state/util.d.ts.map +0 -1
  111. package/src/state/doc.ts +0 -10
  112. package/src/state/index.ts +0 -11
  113. package/src/state/util.ts +0 -13
  114. /package/dist/types/src/{state → extensions}/state.d.ts +0 -0
  115. /package/dist/types/src/{state → extensions}/types.d.ts +0 -0
  116. /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-AZWYO7TE.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) => {
@@ -1319,7 +1355,7 @@ var command = (options) => {
1319
1355
 
1320
1356
  // packages/ui/react-ui-editor/src/extensions/comments.ts
1321
1357
  import { invertedEffects } from "@codemirror/commands";
1322
- import { StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
1358
+ import { Facet as Facet4, StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
1323
1359
  import { hoverTooltip, keymap as keymap4, Decoration as Decoration4, EditorView as EditorView7, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
1324
1360
  import sortBy from "lodash.sortby";
1325
1361
  import { useEffect, useMemo, useState } from "react";
@@ -1416,6 +1452,9 @@ var logChanges = (trs) => {
1416
1452
 
1417
1453
  // packages/ui/react-ui-editor/src/extensions/comments.ts
1418
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
+ });
1419
1458
  var setComments = StateEffect3.define();
1420
1459
  var setSelection = StateEffect3.define();
1421
1460
  var setCommentState = StateEffect3.define();
@@ -1486,7 +1525,7 @@ var commentsDecorations = EditorView7.decorations.compute([
1486
1525
  if (!range) {
1487
1526
  log5.warn("Invalid range:", range, {
1488
1527
  F: __dxlog_file7,
1489
- L: 143,
1528
+ L: 147,
1490
1529
  S: void 0,
1491
1530
  C: (f, a) => f(...a)
1492
1531
  });
@@ -1648,13 +1687,15 @@ var createComment = (view) => {
1648
1687
  }
1649
1688
  return false;
1650
1689
  };
1651
- var optionsFacet = singleValueFacet();
1690
+ var optionsFacet = Facet4.define({
1691
+ combine: (providers) => providers[0]
1692
+ });
1652
1693
  var comments = (options = {}) => {
1653
1694
  const { key: shortcut = "meta-'" } = options;
1654
1695
  const handleSelect = debounce((state2) => options.onSelect?.(state2), 200);
1655
1696
  return [
1656
1697
  optionsFacet.of(options),
1657
- options.id ? documentId.of(options.id) : void 0,
1698
+ documentId.of(options.id),
1658
1699
  commentsState,
1659
1700
  commentsDecorations,
1660
1701
  handleCommentClick,
@@ -1662,17 +1703,17 @@ var comments = (options = {}) => {
1662
1703
  //
1663
1704
  // Keymap.
1664
1705
  //
1665
- options.onCreate && keymap4.of([
1706
+ options.onCreate ? keymap4.of([
1666
1707
  {
1667
1708
  key: shortcut,
1668
1709
  run: callbackWrapper(createComment)
1669
1710
  }
1670
- ]),
1711
+ ]) : [],
1671
1712
  //
1672
1713
  // Hover tooltip (for key shortcut hints, etc.)
1673
1714
  // TODO(burdon): Factor out to generic hints extension for current selection/line.
1674
1715
  //
1675
- options.onHover && hoverTooltip((view, pos) => {
1716
+ options.onHover ? hoverTooltip((view, pos) => {
1676
1717
  const selection = view.state.selection.main;
1677
1718
  if (selection && pos >= selection.from && pos <= selection.to) {
1678
1719
  return {
@@ -1697,7 +1738,7 @@ var comments = (options = {}) => {
1697
1738
  // TODO(burdon): Hide on change triggered immediately?
1698
1739
  // hideOnChange: true,
1699
1740
  hoverTime: 1e3
1700
- }),
1741
+ }) : [],
1701
1742
  //
1702
1743
  // Track deleted ranges and update ranges for decorations.
1703
1744
  //
@@ -1766,8 +1807,8 @@ var comments = (options = {}) => {
1766
1807
  });
1767
1808
  }
1768
1809
  }),
1769
- options.onUpdate && trackPastedComments(options.onUpdate)
1770
- ].filter(nonNullable);
1810
+ options.onUpdate ? trackPastedComments(options.onUpdate) : []
1811
+ ];
1771
1812
  };
1772
1813
  var scrollThreadIntoView = (view, id, center = true) => {
1773
1814
  const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
@@ -1894,6 +1935,25 @@ var debugNodeLogger = (log9 = console.log) => {
1894
1935
  });
1895
1936
  };
1896
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
+
1897
1957
  // packages/ui/react-ui-editor/src/extensions/dnd.ts
1898
1958
  import { dropCursor, EditorView as EditorView8 } from "@codemirror/view";
1899
1959
  var styles4 = EditorView8.theme({
@@ -1956,9 +2016,11 @@ var headings = {
1956
2016
  6: "text-md"
1957
2017
  };
1958
2018
  var theme = {
2019
+ mark: "opacity-50",
1959
2020
  code: "font-mono !no-underline text-neutral-700 dark:text-neutral-300",
1960
2021
  codeMark: "font-mono text-primary-500",
1961
- 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",
1962
2024
  heading: (level) => {
1963
2025
  return mx(headings[level], "dark:text-primary-400");
1964
2026
  }
@@ -2001,11 +2063,9 @@ var defaultTheme = {
2001
2063
  /**
2002
2064
  * Gutters
2003
2065
  * NOTE: Gutters should have the same top margin as the content.
2004
- * NOTE: They can't be transparent since the content needs to scroll below.
2005
2066
  */
2006
2067
  ".cm-gutters": {
2007
- background: "var(--surface-bg)",
2008
- borderRight: "none"
2068
+ background: "var(--surface-bg)"
2009
2069
  },
2010
2070
  ".cm-gutter": {},
2011
2071
  ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
@@ -2026,7 +2086,7 @@ var defaultTheme = {
2026
2086
  paddingInline: 0
2027
2087
  },
2028
2088
  ".cm-activeLine": {
2029
- background: "var(--dx-cmActiveLine)"
2089
+ background: "var(--dx-hoverSurface)"
2030
2090
  },
2031
2091
  /**
2032
2092
  * Cursor (layer).
@@ -2174,7 +2234,7 @@ var defaultTheme = {
2174
2234
  };
2175
2235
 
2176
2236
  // packages/ui/react-ui-editor/src/extensions/factories.ts
2177
- 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";
2178
2238
  var preventNewline = EditorState.transactionFilter.of((tr) => tr.newDoc.lines > 1 ? [] : tr);
2179
2239
  var defaultBasicOptions = {
2180
2240
  allowMultipleSelections: true,
@@ -2199,7 +2259,7 @@ var createBasicExtensions = (_props) => {
2199
2259
  // NOTE: Doesn't catch errors in keymap functions.
2200
2260
  EditorView9.exceptionSink.of((err) => {
2201
2261
  log6.catch(err, void 0, {
2202
- F: __dxlog_file8,
2262
+ F: __dxlog_file9,
2203
2263
  L: 93,
2204
2264
  S: void 0,
2205
2265
  C: (f, a) => f(...a)
@@ -2296,10 +2356,9 @@ var folding = (_props = {}) => [
2296
2356
  }),
2297
2357
  foldGutter({
2298
2358
  markerDOM: (open) => {
2299
- const el = createElement("div", {
2359
+ return renderRoot(createElement("div", {
2300
2360
  className: "flex h-full items-center"
2301
- });
2302
- return renderRoot(el, /* @__PURE__ */ React2.createElement(Icon, {
2361
+ }), /* @__PURE__ */ React2.createElement(Icon, {
2303
2362
  icon: "ph--caret-right--regular",
2304
2363
  classNames: [
2305
2364
  getSize(3),
@@ -3286,7 +3345,7 @@ var getFormatting = (state2) => {
3286
3345
  null
3287
3346
  ];
3288
3347
  let link = false;
3289
- let blockQuote2 = null;
3348
+ let blockQuote = null;
3290
3349
  let listStyle = null;
3291
3350
  const stack = [];
3292
3351
  let currentBlock = null;
@@ -3395,10 +3454,10 @@ var getFormatting = (state2) => {
3395
3454
  hasList = stack[i] === "TaskList" ? "task" : stack[i] === "BulletList" ? "bullet" : "ordered";
3396
3455
  }
3397
3456
  }
3398
- if (blockQuote2 === null) {
3399
- blockQuote2 = hasQuote;
3400
- } else if (!hasQuote && blockQuote2) {
3401
- blockQuote2 = false;
3457
+ if (blockQuote === null) {
3458
+ blockQuote = hasQuote;
3459
+ } else if (!hasQuote && blockQuote) {
3460
+ blockQuote = false;
3402
3461
  }
3403
3462
  if (listStyle === null) {
3404
3463
  listStyle = hasList;
@@ -3417,7 +3476,7 @@ var getFormatting = (state2) => {
3417
3476
  return {
3418
3477
  blankLine,
3419
3478
  blockType: blockType || null,
3420
- blockQuote: blockQuote2 ?? false,
3479
+ blockQuote: blockQuote ?? false,
3421
3480
  code: inline[3] ?? false,
3422
3481
  emphasis: inline[1] ?? false,
3423
3482
  strong: inline[0] ?? false,
@@ -3668,6 +3727,12 @@ var markdownHighlightStyle = (_options = {}) => {
3668
3727
  ],
3669
3728
  class: theme.code
3670
3729
  },
3730
+ {
3731
+ tag: [
3732
+ markdownTags.QuoteMark
3733
+ ],
3734
+ class: theme.blockquote
3735
+ },
3671
3736
  {
3672
3737
  tag: [
3673
3738
  markdownTags.TableCell
@@ -3749,7 +3814,7 @@ var convertTreeToJson = (state2) => {
3749
3814
  import { syntaxTree as syntaxTree7 } from "@codemirror/language";
3750
3815
  import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect4 } from "@codemirror/state";
3751
3816
  import { EditorView as EditorView16, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
3752
- import { invariant as invariant3 } from "@dxos/invariant";
3817
+ import { invariant as invariant4 } from "@dxos/invariant";
3753
3818
  import { mx as mx2 } from "@dxos/react-ui-theme";
3754
3819
 
3755
3820
  // packages/ui/react-ui-editor/src/extensions/markdown/changes.ts
@@ -4012,15 +4077,6 @@ var formattingStyles = EditorView14.theme({
4012
4077
  width: `${orderedListIndentationWidth}px`
4013
4078
  },
4014
4079
  /**
4015
- * Blockquote.
4016
- */
4017
- "& .cm-blockquote": {
4018
- background: "var(--dx-cmCodeblock)",
4019
- borderLeft: "2px solid var(--dx-cmSeparator)",
4020
- paddingLeft: "1rem",
4021
- margin: "0"
4022
- },
4023
- /**
4024
4080
  * Code and codeblocks.
4025
4081
  */
4026
4082
  "& .cm-code": {
@@ -4180,7 +4236,7 @@ var TableWidget = class extends WidgetType4 {
4180
4236
  };
4181
4237
 
4182
4238
  // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
4183
- 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";
4184
4240
  var Unicode = {
4185
4241
  emDash: "\u2014",
4186
4242
  bullet: "\u2022",
@@ -4203,7 +4259,6 @@ var LinkButton = class extends WidgetType5 {
4203
4259
  eq(other) {
4204
4260
  return this.url === other.url;
4205
4261
  }
4206
- // TODO(burdon): Create icon and link directly without react?
4207
4262
  toDOM(view) {
4208
4263
  const el = document.createElement("span");
4209
4264
  this.render(el, this.url);
@@ -4271,9 +4326,6 @@ var TextWidget = class extends WidgetType5 {
4271
4326
  }
4272
4327
  };
4273
4328
  var hide = Decoration7.replace({});
4274
- var blockQuote = Decoration7.line({
4275
- class: mx2("cm-blockquote")
4276
- });
4277
4329
  var fencedCodeLine = Decoration7.line({
4278
4330
  class: mx2("cm-code cm-codeblock-line")
4279
4331
  });
@@ -4313,9 +4365,9 @@ var buildDecorations2 = (view, options, focus) => {
4313
4365
  const { state: state2 } = view;
4314
4366
  const headerLevels = [];
4315
4367
  const getHeaderLevels = (node, level) => {
4316
- invariant3(level > 0, void 0, {
4317
- F: __dxlog_file9,
4318
- L: 178,
4368
+ invariant4(level > 0, void 0, {
4369
+ F: __dxlog_file10,
4370
+ L: 176,
4319
4371
  S: void 0,
4320
4372
  A: [
4321
4373
  "level > 0",
@@ -4352,9 +4404,9 @@ var buildDecorations2 = (view, options, focus) => {
4352
4404
  listLevels.pop();
4353
4405
  };
4354
4406
  const getCurrentListLevel = () => {
4355
- invariant3(listLevels.length, void 0, {
4356
- F: __dxlog_file9,
4357
- L: 200,
4407
+ invariant4(listLevels.length, void 0, {
4408
+ F: __dxlog_file10,
4409
+ L: 198,
4358
4410
  S: void 0,
4359
4411
  A: [
4360
4412
  "listLevels.length",
@@ -4447,30 +4499,7 @@ var buildDecorations2 = (view, options, focus) => {
4447
4499
  atomicDeco.add(line.from, to, checked ? checkedTask : uncheckedTask);
4448
4500
  break;
4449
4501
  }
4450
- //
4451
- // Blockquote > QuoteMark > Paragraph
4452
- //
4453
- case "Blockquote": {
4454
- const editing = editingRange(state2, node, focus);
4455
- const quoteMark = node.node.getChild("QuoteMark");
4456
- const paragraph = node.node.getChild("Paragraph");
4457
- if (!editing && quoteMark && paragraph) {
4458
- atomicDeco.add(quoteMark.from, paragraph.from, hide);
4459
- }
4460
- for (const block of view.viewportLineBlocks) {
4461
- if (block.to < node.from) {
4462
- continue;
4463
- }
4464
- if (block.from > node.to) {
4465
- break;
4466
- }
4467
- deco.add(block.from, block.from, blockQuote);
4468
- }
4469
- break;
4470
- }
4471
- //
4472
4502
  // CommentBlock
4473
- //
4474
4503
  case "CommentBlock": {
4475
4504
  const editing = editingRange(state2, node, focus);
4476
4505
  for (const block of view.viewportLineBlocks) {
@@ -4480,18 +4509,16 @@ var buildDecorations2 = (view, options, focus) => {
4480
4509
  if (block.from > node.to) {
4481
4510
  break;
4482
4511
  }
4483
- const isFirst = block.from <= node.from;
4484
- const isLast = block.to >= node.to && /^(\s>)*-->$/.test(state2.doc.sliceString(block.from, block.to));
4485
- deco.add(block.from, block.from, isFirst ? commentBlockLineFirst : isLast ? commentBlockLineLast : commentBlockLine);
4486
- 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)) {
4487
4516
  atomicDeco.add(block.from, block.to, hide);
4488
4517
  }
4489
4518
  }
4490
4519
  break;
4491
4520
  }
4492
- //
4493
4521
  // FencedCode > CodeMark > [CodeInfo] > CodeText > CodeMark
4494
- //
4495
4522
  case "FencedCode": {
4496
4523
  for (const block of view.viewportLineBlocks) {
4497
4524
  if (block.to < node.from) {
@@ -4510,9 +4537,7 @@ var buildDecorations2 = (view, options, focus) => {
4510
4537
  }
4511
4538
  return false;
4512
4539
  }
4513
- //
4514
4540
  // Link > [LinkMark, URL]
4515
- //
4516
4541
  case "Link": {
4517
4542
  const marks = node.node.getChildren("LinkMark");
4518
4543
  const urlNode = node.node.getChild("URL");
@@ -4539,9 +4564,7 @@ var buildDecorations2 = (view, options, focus) => {
4539
4564
  }
4540
4565
  break;
4541
4566
  }
4542
- //
4543
4567
  // HR
4544
- //
4545
4568
  case "HorizontalRule": {
4546
4569
  if (!editingRange(state2, node, focus)) {
4547
4570
  deco.add(node.from, node.to, horizontalRule);
@@ -4638,42 +4661,40 @@ var decorateMarkdown = (options = {}) => {
4638
4661
  import { syntaxTree as syntaxTree8 } from "@codemirror/language";
4639
4662
  import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
4640
4663
  import { tooltipContent } from "@dxos/react-ui-theme";
4641
- var linkTooltip = (render) => {
4642
- return hoverTooltip2((view, pos, side) => {
4643
- const syntax = syntaxTree8(view.state).resolveInner(pos, side);
4644
- let link = null;
4645
- for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
4646
- link = node.name === "Link" ? node : null;
4647
- }
4648
- const url = link && link.getChild("URL");
4649
- if (!url || !link) {
4650
- 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
+ };
4651
4690
  }
4652
- const urlText = view.state.sliceDoc(url.from, url.to);
4653
- return {
4654
- pos: link.from,
4655
- end: link.to,
4656
- above: true,
4657
- create: () => {
4658
- const el = document.createElement("div");
4659
- el.className = tooltipContent({}, "pli-2 plb-1");
4660
- render(el, urlText);
4661
- return {
4662
- dom: el,
4663
- offset: {
4664
- x: 0,
4665
- y: 4
4666
- }
4667
- };
4668
- }
4669
- };
4670
- });
4671
- };
4691
+ };
4692
+ });
4672
4693
 
4673
4694
  // packages/ui/react-ui-editor/src/extensions/mention.ts
4674
4695
  import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
4675
4696
  import { log as log7 } from "@dxos/log";
4676
- 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";
4677
4698
  var mention = ({ onSearch }) => {
4678
4699
  return autocompletion2({
4679
4700
  // TODO(burdon): Not working.
@@ -4688,7 +4709,7 @@ var mention = ({ onSearch }) => {
4688
4709
  log7.info("completion context", {
4689
4710
  context
4690
4711
  }, {
4691
- F: __dxlog_file10,
4712
+ F: __dxlog_file11,
4692
4713
  L: 26,
4693
4714
  S: void 0,
4694
4715
  C: (f, a) => f(...a)
@@ -4709,6 +4730,7 @@ var mention = ({ onSearch }) => {
4709
4730
  };
4710
4731
 
4711
4732
  // packages/ui/react-ui-editor/src/extensions/modes.ts
4733
+ import { Facet as Facet6 } from "@codemirror/state";
4712
4734
  import { keymap as keymap8 } from "@codemirror/view";
4713
4735
  import { vim } from "@replit/codemirror-vim";
4714
4736
  import { vscodeKeymap } from "@replit/codemirror-vscode-keymap";
@@ -4723,7 +4745,9 @@ var EditorInputModes = [
4723
4745
  "vim",
4724
4746
  "vscode"
4725
4747
  ];
4726
- var editorInputMode = singleValueFacet({});
4748
+ var editorInputMode = Facet6.define({
4749
+ combine: (modes) => modes[0] ?? {}
4750
+ });
4727
4751
  var InputModeExtensions = {
4728
4752
  default: [],
4729
4753
  vscode: [
@@ -4754,8 +4778,101 @@ var InputModeExtensions = {
4754
4778
  ]
4755
4779
  };
4756
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
+
4757
4874
  // packages/ui/react-ui-editor/src/extensions/typewriter.ts
4758
- import { keymap as keymap9 } from "@codemirror/view";
4875
+ import { keymap as keymap10 } from "@codemirror/view";
4759
4876
  var defaultItems = [
4760
4877
  "hello world!",
4761
4878
  "this is a test.",
@@ -4765,7 +4882,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
4765
4882
  let t;
4766
4883
  let idx = 0;
4767
4884
  return [
4768
- keymap9.of([
4885
+ keymap10.of([
4769
4886
  {
4770
4887
  // Reset.
4771
4888
  key: "alt-meta-'",
@@ -5196,20 +5313,20 @@ var Toolbar = {
5196
5313
  };
5197
5314
 
5198
5315
  // packages/ui/react-ui-editor/src/defaults.ts
5199
- import { EditorView as EditorView17 } from "@codemirror/view";
5316
+ import { EditorView as EditorView18 } from "@codemirror/view";
5200
5317
  import { mx as mx3 } from "@dxos/react-ui-theme";
5201
5318
  var margin = "!mt-[1rem]";
5202
5319
  var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
5203
5320
  var editorFullWidth = mx3(margin);
5204
5321
  var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
5205
- var editorGutter = EditorView17.theme({
5322
+ var editorGutter = EditorView18.theme({
5206
5323
  // Match margin from content.
5207
5324
  ".cm-gutters": {
5208
5325
  marginTop: "16px",
5209
5326
  paddingRight: "1rem"
5210
5327
  }
5211
5328
  });
5212
- var editorMonospace = EditorView17.theme({
5329
+ var editorMonospace = EditorView18.theme({
5213
5330
  ".cm-content": {
5214
5331
  fontFamily: fontMono
5215
5332
  }
@@ -5222,12 +5339,12 @@ var useActionHandler = (view) => {
5222
5339
 
5223
5340
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
5224
5341
  import { EditorState as EditorState2 } from "@codemirror/state";
5225
- import { EditorView as EditorView18 } from "@codemirror/view";
5342
+ import { EditorView as EditorView19 } from "@codemirror/view";
5226
5343
  import { useFocusableGroup } from "@fluentui/react-tabster";
5227
5344
  import { useCallback, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2, useState as useState4 } from "react";
5228
5345
  import { log as log8 } from "@dxos/log";
5229
- import { getProviderValue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
5230
- 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";
5231
5348
  var instanceCount = 0;
5232
5349
  var useTextEditor = (props = {}, deps = []) => {
5233
5350
  const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo3(() => getProviderValue(props), deps ?? []);
@@ -5243,8 +5360,8 @@ var useTextEditor = (props = {}, deps = []) => {
5243
5360
  instanceId,
5244
5361
  doc: initialValue?.length ?? 0
5245
5362
  }, {
5246
- F: __dxlog_file11,
5247
- L: 78,
5363
+ F: __dxlog_file13,
5364
+ L: 76,
5248
5365
  S: void 0,
5249
5366
  C: (f, a) => f(...a)
5250
5367
  });
@@ -5264,26 +5381,27 @@ var useTextEditor = (props = {}, deps = []) => {
5264
5381
  doc: initialValue,
5265
5382
  selection: initialSelection,
5266
5383
  extensions: [
5267
- id && documentId.of(id),
5384
+ id && documentId2.of(id),
5268
5385
  // NOTE: Doesn't catch errors in keymap functions.
5269
- EditorView18.exceptionSink.of((err) => {
5386
+ EditorView19.exceptionSink.of((err) => {
5270
5387
  log8.catch(err, void 0, {
5271
- F: __dxlog_file11,
5272
- L: 100,
5388
+ F: __dxlog_file13,
5389
+ L: 98,
5273
5390
  S: void 0,
5274
5391
  C: (f, a) => f(...a)
5275
5392
  });
5276
5393
  }),
5277
5394
  extensions,
5278
- EditorView18.updateListener.of(() => {
5395
+ EditorView19.updateListener.of(() => {
5279
5396
  setTimeout(() => {
5280
5397
  onUpdate.current?.();
5281
5398
  });
5282
5399
  })
5283
- ].filter(isNotFalsy3)
5400
+ ].filter(isNotFalsy4)
5284
5401
  });
5285
- view2 = new EditorView18({
5402
+ view2 = new EditorView19({
5286
5403
  parent: parentRef.current,
5404
+ selection: initialSelection,
5287
5405
  state: state2,
5288
5406
  // NOTE: Uncomment to debug/monitor all transactions.
5289
5407
  // https://codemirror.net/docs/ref/#view.EditorView.dispatch
@@ -5308,8 +5426,8 @@ var useTextEditor = (props = {}, deps = []) => {
5308
5426
  log8("destroy", {
5309
5427
  id
5310
5428
  }, {
5311
- F: __dxlog_file11,
5312
- L: 135,
5429
+ F: __dxlog_file13,
5430
+ L: 134,
5313
5431
  S: void 0,
5314
5432
  C: (f, a) => f(...a)
5315
5433
  });
@@ -5407,7 +5525,7 @@ export {
5407
5525
  debugTree,
5408
5526
  decorateMarkdown,
5409
5527
  defaultOptions,
5410
- documentId,
5528
+ documentId2 as documentId,
5411
5529
  dropFile,
5412
5530
  editorContent,
5413
5531
  editorFullWidth,
@@ -5423,7 +5541,7 @@ export {
5423
5541
  image,
5424
5542
  imageUpload,
5425
5543
  insertTable,
5426
- keymap10 as keymap,
5544
+ keymap11 as keymap,
5427
5545
  linkTooltip,
5428
5546
  listener,
5429
5547
  localStorageStateStoreAdapter,
@@ -5446,7 +5564,6 @@ export {
5446
5564
  setHeading,
5447
5565
  setSelection,
5448
5566
  setStyle,
5449
- singleValueFacet,
5450
5567
  state,
5451
5568
  table,
5452
5569
  tags2 as tags,