@dxos/react-ui-editor 0.8.1-main.ae460ac → 0.8.1-staging.31c3ee1

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 (56) hide show
  1. package/dist/lib/browser/index.mjs +283 -147
  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 +317 -185
  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 +283 -147
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/InputMode.stories.d.ts +4 -3
  11. package/dist/types/src/InputMode.stories.d.ts.map +1 -1
  12. package/dist/types/src/TextEditor.stories.d.ts +38 -72
  13. package/dist/types/src/TextEditor.stories.d.ts.map +1 -1
  14. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +2 -1
  15. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
  16. package/dist/types/src/defaults.d.ts +2 -0
  17. package/dist/types/src/defaults.d.ts.map +1 -1
  18. package/dist/types/src/extensions/automerge/automerge.stories.d.ts +4 -3
  19. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  20. package/dist/types/src/extensions/command/command.d.ts +4 -2
  21. package/dist/types/src/extensions/command/command.d.ts.map +1 -1
  22. package/dist/types/src/extensions/command/hint.d.ts.map +1 -1
  23. package/dist/types/src/extensions/command/menu.d.ts +12 -0
  24. package/dist/types/src/extensions/command/menu.d.ts.map +1 -0
  25. package/dist/types/src/extensions/command/preview.d.ts +12 -0
  26. package/dist/types/src/extensions/command/preview.d.ts.map +1 -0
  27. package/dist/types/src/extensions/command/state.d.ts.map +1 -1
  28. package/dist/types/src/extensions/comments.d.ts +3 -3
  29. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  30. package/dist/types/src/extensions/factories.d.ts +2 -1
  31. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  32. package/dist/types/src/{styles/stack-item-content-class-names.d.ts → fragments.d.ts} +1 -1
  33. package/dist/types/src/fragments.d.ts.map +1 -0
  34. package/dist/types/src/hooks/useTextEditor.d.ts +3 -3
  35. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  36. package/dist/types/src/index.d.ts +0 -1
  37. package/dist/types/src/index.d.ts.map +1 -1
  38. package/dist/types/src/styles/theme.d.ts.map +1 -1
  39. package/package.json +28 -28
  40. package/src/InputMode.stories.tsx +4 -4
  41. package/src/TextEditor.stories.tsx +173 -59
  42. package/src/components/EditorToolbar/EditorToolbar.tsx +4 -5
  43. package/src/defaults.ts +12 -0
  44. package/src/extensions/command/command.ts +21 -2
  45. package/src/extensions/command/hint.ts +3 -0
  46. package/src/extensions/command/menu.ts +100 -0
  47. package/src/extensions/command/preview.ts +79 -0
  48. package/src/extensions/command/state.ts +9 -4
  49. package/src/extensions/comments.ts +6 -10
  50. package/src/extensions/factories.ts +4 -3
  51. package/src/{styles/stack-item-content-class-names.ts → fragments.ts} +4 -2
  52. package/src/hooks/useTextEditor.ts +17 -8
  53. package/src/index.ts +0 -4
  54. package/src/styles/theme.ts +6 -1
  55. package/src/util/debug.ts +1 -1
  56. package/dist/types/src/styles/stack-item-content-class-names.d.ts.map +0 -1
@@ -35,14 +35,14 @@ var translations_default = [
35
35
 
36
36
  // packages/ui/react-ui-editor/src/index.ts
37
37
  import { EditorState as EditorState3 } from "@codemirror/state";
38
- import { EditorView as EditorView21, keymap as keymap11 } from "@codemirror/view";
38
+ import { EditorView as EditorView22, keymap as keymap11 } from "@codemirror/view";
39
39
  import { tags as tags2 } from "@lezer/highlight";
40
40
  import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
41
41
 
42
42
  // packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
43
43
  import React, { useCallback } from "react";
44
44
  import { ElevationProvider } from "@dxos/react-ui";
45
- import { ToolbarMenu, MenuProvider, useMenuActions, createGapSeparator } from "@dxos/react-ui-menu";
45
+ import { MenuProvider, ToolbarMenu, createGapSeparator, useMenuActions } from "@dxos/react-ui-menu";
46
46
  import { textBlockWidth } from "@dxos/react-ui-theme";
47
47
 
48
48
  // packages/ui/react-ui-editor/src/components/EditorToolbar/util.ts
@@ -311,9 +311,8 @@ var createViewMode = (state) => {
311
311
  };
312
312
  };
313
313
 
314
- // packages/ui/react-ui-editor/src/styles/stack-item-content-class-names.ts
314
+ // packages/ui/react-ui-editor/src/fragments.ts
315
315
  import { mx } from "@dxos/react-ui-theme";
316
- var stackItemContentEditorClassNames = (role) => mx("dx-focus-ring-inset data-[toolbar=disabled]:pbs-2 attention-surface", role === "article" ? "min-bs-0" : "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24");
317
316
  var stackItemContentToolbarClassNames = (role) => mx("attention-surface is-full border-be !border-separator", role === "section" && "sticky block-start-0 z-[1] -mbe-px min-is-0");
318
317
 
319
318
  // packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
@@ -465,6 +464,10 @@ var defaultTheme = {
465
464
  background: "transparent"
466
465
  },
467
466
  ".cm-gutter": {},
467
+ ".cm-gutter.cm-lineNumbers": {
468
+ paddingRight: "4px",
469
+ borderRight: "1px solid var(--dx-separator)"
470
+ },
468
471
  ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
469
472
  minWidth: "40px",
470
473
  alignContent: "center"
@@ -474,7 +477,7 @@ var defaultTheme = {
474
477
  */
475
478
  ".cm-gutterElement": {
476
479
  alignItems: "center",
477
- fontSize: "16px"
480
+ fontSize: "12px"
478
481
  },
479
482
  /**
480
483
  * Line.
@@ -520,6 +523,7 @@ var defaultTheme = {
520
523
  ".cm-link": {
521
524
  textDecorationLine: "underline",
522
525
  textDecorationThickness: "1px",
526
+ textDecorationColor: "var(--dx-separator)",
523
527
  textUnderlineOffset: "2px",
524
528
  borderRadius: ".125rem"
525
529
  },
@@ -648,6 +652,8 @@ var editorMonospace = EditorView.theme({
648
652
  }
649
653
  });
650
654
  var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
655
+ var stackItemContentEditorClassNames = (role) => mx3("attention-surface dx-focus-ring-inset data-[toolbar=disabled]:pbs-2", role === "section" ? "[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-bs-24" : "min-bs-0");
656
+ var stackItemContentToolbarClassNames2 = (role) => mx3("attention-surface is-full border-be !border-separator", role === "section" && "sticky block-start-0 z-[1] -mbe-px min-is-0");
651
657
 
652
658
  // packages/ui/react-ui-editor/src/extensions/annotations.ts
653
659
  import { StateField } from "@codemirror/state";
@@ -747,7 +753,7 @@ var logChanges = (trs) => {
747
753
  return changes2;
748
754
  }).filter(Boolean);
749
755
  if (changes.length) {
750
- log.info("changes", {
756
+ log("changes", {
751
757
  changes
752
758
  }, {
753
759
  F: __dxlog_file,
@@ -1852,7 +1858,7 @@ var random = (min, max) => {
1852
1858
  };
1853
1859
 
1854
1860
  // packages/ui/react-ui-editor/src/extensions/command/command.ts
1855
- import { EditorView as EditorView7, keymap as keymap3 } from "@codemirror/view";
1861
+ import { EditorView as EditorView8, keymap as keymap3 } from "@codemirror/view";
1856
1862
 
1857
1863
  // packages/ui/react-ui-editor/src/extensions/command/hint.ts
1858
1864
  import { RangeSetBuilder } from "@codemirror/state";
@@ -1888,18 +1894,19 @@ var commandState = StateField3.define({
1888
1894
  const widthWithoutPadding = parent.clientWidth - parseFloat(paddingLeft) - parseFloat(paddingRight);
1889
1895
  dom.style.width = `${widthWithoutPadding}px`;
1890
1896
  }
1891
- options.onRender(dom, (action) => {
1897
+ options.onRenderDialog(dom, (action) => {
1892
1898
  view2.dispatch({
1893
1899
  effects: closeEffect.of(null)
1894
1900
  });
1895
1901
  if (action?.insert?.length) {
1902
+ const text = action.insert + "\n";
1896
1903
  view2.dispatch({
1897
1904
  changes: {
1898
1905
  from: pos,
1899
- insert: action.insert
1906
+ insert: text
1900
1907
  },
1901
1908
  selection: {
1902
- anchor: pos + action.insert.length
1909
+ anchor: pos + text.length
1903
1910
  }
1904
1911
  });
1905
1912
  }
@@ -2026,23 +2033,156 @@ var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
2026
2033
  ]
2027
2034
  });
2028
2035
 
2036
+ // packages/ui/react-ui-editor/src/extensions/command/menu.ts
2037
+ import { ViewPlugin as ViewPlugin4 } from "@codemirror/view";
2038
+ var floatingMenu = (options) => ViewPlugin4.fromClass(class {
2039
+ constructor(view) {
2040
+ this.rafId = null;
2041
+ this.view = view;
2042
+ const container = view.scrollDOM;
2043
+ if (getComputedStyle(container).position === "static") {
2044
+ container.style.position = "relative";
2045
+ }
2046
+ this.button = document.createElement("div");
2047
+ this.button.style.position = "absolute";
2048
+ this.button.style.zIndex = "10";
2049
+ this.button.style.display = "none";
2050
+ options.onRenderMenu(this.button, () => {
2051
+ openCommand(view);
2052
+ });
2053
+ container.appendChild(this.button);
2054
+ container.addEventListener("scroll", this.scheduleUpdate);
2055
+ this.scheduleUpdate();
2056
+ }
2057
+ update(update2) {
2058
+ if (update2.transactions.some((tr) => tr.effects.some((effect) => effect.is(openEffect)))) {
2059
+ this.button.style.display = "none";
2060
+ } else if (update2.transactions.some((tr) => tr.effects.some((effect) => effect.is(closeEffect)))) {
2061
+ this.button.style.display = "block";
2062
+ } else if (update2.selectionSet || update2.viewportChanged || update2.docChanged || update2.geometryChanged) {
2063
+ this.scheduleUpdate();
2064
+ }
2065
+ }
2066
+ scheduleUpdate() {
2067
+ if (this.rafId != null) {
2068
+ cancelAnimationFrame(this.rafId);
2069
+ }
2070
+ this.rafId = requestAnimationFrame(() => this.updateButtonPosition());
2071
+ }
2072
+ updateButtonPosition() {
2073
+ const pos = this.view.state.selection.main.head;
2074
+ const lineBlock = this.view.lineBlockAt(pos);
2075
+ const domInfo = this.view.domAtPos(lineBlock.from);
2076
+ let node = domInfo.node;
2077
+ while (node && !(node instanceof HTMLElement)) {
2078
+ node = node.parentNode;
2079
+ }
2080
+ if (!node) {
2081
+ this.button.style.display = "none";
2082
+ return;
2083
+ }
2084
+ const lineRect = node.getBoundingClientRect();
2085
+ const containerRect = this.view.scrollDOM.getBoundingClientRect();
2086
+ const offsetTop = lineRect.top - containerRect.top + this.view.scrollDOM.scrollTop;
2087
+ const offsetLeft = this.view.scrollDOM.clientWidth + this.view.scrollDOM.scrollLeft - lineRect.x;
2088
+ this.button.style.top = `${offsetTop}px`;
2089
+ this.button.style.left = `${offsetLeft}px`;
2090
+ this.button.style.display = "block";
2091
+ }
2092
+ destroy() {
2093
+ this.button.remove();
2094
+ if (this.rafId != null) {
2095
+ cancelAnimationFrame(this.rafId);
2096
+ }
2097
+ }
2098
+ });
2099
+
2100
+ // packages/ui/react-ui-editor/src/extensions/command/preview.ts
2101
+ import { syntaxTree } from "@codemirror/language";
2102
+ import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField4 } from "@codemirror/state";
2103
+ import { Decoration as Decoration4, EditorView as EditorView7, WidgetType as WidgetType3 } from "@codemirror/view";
2104
+ var preview = (options) => {
2105
+ return [
2106
+ StateField4.define({
2107
+ create: (state) => buildDecorations(state, options),
2108
+ update: (_, tr) => buildDecorations(tr.state, options),
2109
+ // TODO(burdon): Make atomic.
2110
+ provide: (field) => EditorView7.decorations.from(field)
2111
+ })
2112
+ ];
2113
+ };
2114
+ var buildDecorations = (state, options) => {
2115
+ const builder = new RangeSetBuilder2();
2116
+ syntaxTree(state).iterate({
2117
+ enter: (node) => {
2118
+ if (node.name === "Link") {
2119
+ const urlNode = node.node.getChild("URL");
2120
+ if (urlNode) {
2121
+ const text = state.sliceDoc(node.from + 1, urlNode.from - 2);
2122
+ const url = state.sliceDoc(urlNode.from, urlNode.to);
2123
+ builder.add(node.from, node.to, Decoration4.replace({
2124
+ block: true,
2125
+ widget: new PreviewWidget(options.onRenderPreview, url, text)
2126
+ }));
2127
+ }
2128
+ }
2129
+ }
2130
+ });
2131
+ return builder.finish();
2132
+ };
2133
+ var PreviewWidget = class extends WidgetType3 {
2134
+ constructor(_onRenderPreview, _url, _text) {
2135
+ super();
2136
+ this._onRenderPreview = _onRenderPreview;
2137
+ this._url = _url;
2138
+ this._text = _text;
2139
+ }
2140
+ eq(other) {
2141
+ return this._url === other._url;
2142
+ }
2143
+ toDOM(view) {
2144
+ const root = document.createElement("div");
2145
+ root.classList.add("cm-preview");
2146
+ this._onRenderPreview(root, {
2147
+ url: this._url,
2148
+ text: this._text
2149
+ });
2150
+ return root;
2151
+ }
2152
+ };
2153
+
2029
2154
  // packages/ui/react-ui-editor/src/extensions/command/command.ts
2030
2155
  var command = (options) => {
2031
2156
  return [
2032
2157
  commandConfig.of(options),
2033
2158
  commandState,
2034
2159
  keymap3.of(commandKeyBindings),
2160
+ preview(options),
2161
+ floatingMenu(options),
2035
2162
  hintViewPlugin(options),
2036
- EditorView7.focusChangeEffect.of((_, focusing) => {
2163
+ EditorView8.focusChangeEffect.of((_, focusing) => {
2037
2164
  return focusing ? closeEffect.of(null) : null;
2165
+ }),
2166
+ EditorView8.theme({
2167
+ ".cm-tooltip": {
2168
+ background: "transparent"
2169
+ },
2170
+ ".cm-preview": {
2171
+ marginLeft: "-1rem",
2172
+ marginRight: "-1rem",
2173
+ padding: "1rem",
2174
+ borderRadius: "1rem",
2175
+ background: "var(--dx-modalSurface)",
2176
+ border: "1px solid var(--dx-separator)"
2177
+ }
2038
2178
  })
2039
2179
  ];
2040
2180
  };
2041
2181
 
2042
2182
  // packages/ui/react-ui-editor/src/extensions/comments.ts
2043
2183
  import { invertedEffects } from "@codemirror/commands";
2044
- import { StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
2045
- import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as EditorView9, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
2184
+ import { StateEffect as StateEffect3, StateField as StateField5 } from "@codemirror/state";
2185
+ import { hoverTooltip, keymap as keymap5, Decoration as Decoration5, EditorView as EditorView10, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
2046
2186
  import sortBy from "lodash.sortby";
2047
2187
  import { useEffect, useMemo as useMemo2 } from "react";
2048
2188
  import { debounce as debounce2 } from "@dxos/async";
@@ -2051,7 +2191,7 @@ import { isNonNullable } from "@dxos/util";
2051
2191
 
2052
2192
  // packages/ui/react-ui-editor/src/extensions/selection.ts
2053
2193
  import { Transaction } from "@codemirror/state";
2054
- import { EditorView as EditorView8, keymap as keymap4 } from "@codemirror/view";
2194
+ import { EditorView as EditorView9, keymap as keymap4 } from "@codemirror/view";
2055
2195
  import { debounce } from "@dxos/async";
2056
2196
  import { invariant as invariant3 } from "@dxos/invariant";
2057
2197
  import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
@@ -2062,7 +2202,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
2062
2202
  return {
2063
2203
  selection,
2064
2204
  scrollIntoView: !scrollTo,
2065
- effects: scrollTo ? EditorView8.scrollIntoView(scrollTo, {
2205
+ effects: scrollTo ? EditorView9.scrollIntoView(scrollTo, {
2066
2206
  yMargin: 96
2067
2207
  }) : void 0,
2068
2208
  annotations: Transaction.userEvent.of(stateRestoreAnnotation)
@@ -2104,7 +2244,7 @@ var selectionState = ({ getState, setState } = {}) => {
2104
2244
  // setStateDebounced(id, {});
2105
2245
  // },
2106
2246
  // }),
2107
- EditorView8.updateListener.of(({ view, transactions }) => {
2247
+ EditorView9.updateListener.of(({ view, transactions }) => {
2108
2248
  const id = view.state.facet(documentId);
2109
2249
  if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
2110
2250
  return;
@@ -2147,7 +2287,7 @@ var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src
2147
2287
  var setComments = StateEffect3.define();
2148
2288
  var setSelection = StateEffect3.define();
2149
2289
  var setCommentState = StateEffect3.define();
2150
- var commentsState = StateField4.define({
2290
+ var commentsState = StateField5.define({
2151
2291
  create: (state) => ({
2152
2292
  id: state.facet(documentId),
2153
2293
  comments: [],
@@ -2185,7 +2325,7 @@ var commentsState = StateField4.define({
2185
2325
  return value;
2186
2326
  }
2187
2327
  });
2188
- var styles3 = EditorView9.theme({
2328
+ var styles3 = EditorView10.theme({
2189
2329
  ".cm-comment, .cm-comment-current": {
2190
2330
  margin: "0 -3px",
2191
2331
  padding: "3px",
@@ -2198,14 +2338,14 @@ var styles3 = EditorView9.theme({
2198
2338
  textDecoration: "underline"
2199
2339
  }
2200
2340
  });
2201
- var createCommentMark = (id, isCurrent) => Decoration4.mark({
2341
+ var createCommentMark = (id, isCurrent) => Decoration5.mark({
2202
2342
  class: isCurrent ? "cm-comment-current" : "cm-comment",
2203
2343
  attributes: {
2204
2344
  "data-testid": "cm-comment",
2205
2345
  "data-comment-id": id
2206
2346
  }
2207
2347
  });
2208
- var commentsDecorations = EditorView9.decorations.compute([
2348
+ var commentsDecorations = EditorView10.decorations.compute([
2209
2349
  commentsState
2210
2350
  ], (state) => {
2211
2351
  const { selection: { current }, comments: comments2 } = state.field(commentsState);
@@ -2225,10 +2365,10 @@ var commentsDecorations = EditorView9.decorations.compute([
2225
2365
  const mark = createCommentMark(comment.comment.id, comment.comment.id === current);
2226
2366
  return mark.range(range.from, range.to);
2227
2367
  }).filter(isNonNullable);
2228
- return Decoration4.set(decorations);
2368
+ return Decoration5.set(decorations);
2229
2369
  });
2230
2370
  var commentClickedEffect = StateEffect3.define();
2231
- var handleCommentClick = EditorView9.domEventHandlers({
2371
+ var handleCommentClick = EditorView10.domEventHandlers({
2232
2372
  click: (event, view) => {
2233
2373
  let target = event.target;
2234
2374
  const editorRoot = view.dom;
@@ -2267,7 +2407,7 @@ var trackPastedComments = (onUpdate) => {
2267
2407
  }
2268
2408
  };
2269
2409
  return [
2270
- EditorView9.domEventHandlers({
2410
+ EditorView10.domEventHandlers({
2271
2411
  cut: handleTrack,
2272
2412
  copy: handleTrack
2273
2413
  }),
@@ -2289,7 +2429,7 @@ var trackPastedComments = (onUpdate) => {
2289
2429
  return effects;
2290
2430
  }),
2291
2431
  // Handle paste or the undo of comment deletion.
2292
- EditorView9.updateListener.of((update2) => {
2432
+ EditorView10.updateListener.of((update2) => {
2293
2433
  const restore = [];
2294
2434
  for (let i = 0; i < update2.transactions.length; i++) {
2295
2435
  const tr = update2.transactions[i];
@@ -2429,7 +2569,7 @@ var comments = (options = {}) => {
2429
2569
  //
2430
2570
  // Track deleted ranges and update ranges for decorations.
2431
2571
  //
2432
- EditorView9.updateListener.of(({ view, state, changes }) => {
2572
+ EditorView10.updateListener.of(({ view, state, changes }) => {
2433
2573
  let mod = false;
2434
2574
  const { comments: comments2, ...value } = state.field(commentsState);
2435
2575
  changes.iterChanges((from, to, from2, to2) => {
@@ -2461,7 +2601,7 @@ var comments = (options = {}) => {
2461
2601
  //
2462
2602
  // Track selection/proximity.
2463
2603
  //
2464
- EditorView9.updateListener.of(({ view, state }) => {
2604
+ EditorView10.updateListener.of(({ view, state }) => {
2465
2605
  let min = Infinity;
2466
2606
  const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
2467
2607
  const { head } = state.selection.main;
@@ -2515,7 +2655,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
2515
2655
  anchor: range.from
2516
2656
  } : void 0,
2517
2657
  effects: [
2518
- needsScroll ? EditorView9.scrollIntoView(range.from, center ? {
2658
+ needsScroll ? EditorView10.scrollIntoView(range.from, center ? {
2519
2659
  y: "center"
2520
2660
  } : void 0) : [],
2521
2661
  needsSelectionUpdate ? setSelection.of({
@@ -2561,13 +2701,13 @@ var ExternalCommentSync = class {
2561
2701
  this.unsubscribe = subscribe(updateComments);
2562
2702
  }
2563
2703
  };
2564
- var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin4.fromClass(class {
2704
+ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin5.fromClass(class {
2565
2705
  constructor(view) {
2566
2706
  return new ExternalCommentSync(view, id, subscribe, getComments);
2567
2707
  }
2568
2708
  });
2569
2709
  var useCommentState = (state) => {
2570
- return useMemo2(() => EditorView9.updateListener.of((update2) => {
2710
+ return useMemo2(() => EditorView10.updateListener.of((update2) => {
2571
2711
  if (update2.docChanged || update2.selectionSet) {
2572
2712
  state.comment = selectionOverlapsComment(update2.state);
2573
2713
  state.selection = hasActiveSelection(update2.state);
@@ -2591,7 +2731,7 @@ var useComments = (view, id, comments2) => {
2591
2731
  });
2592
2732
  };
2593
2733
  var useCommentClickListener = (onCommentClick) => {
2594
- return useMemo2(() => EditorView9.updateListener.of((update2) => {
2734
+ return useMemo2(() => EditorView10.updateListener.of((update2) => {
2595
2735
  update2.transactions.forEach((transaction) => {
2596
2736
  transaction.effects.forEach((effect) => {
2597
2737
  if (effect.is(commentClickedEffect)) {
@@ -2605,21 +2745,21 @@ var useCommentClickListener = (onCommentClick) => {
2605
2745
  };
2606
2746
 
2607
2747
  // packages/ui/react-ui-editor/src/extensions/debug.ts
2608
- import { syntaxTree } from "@codemirror/language";
2609
- import { StateField as StateField5 } from "@codemirror/state";
2748
+ import { syntaxTree as syntaxTree2 } from "@codemirror/language";
2749
+ import { StateField as StateField6 } from "@codemirror/state";
2610
2750
  var debugNodeLogger = (log8 = console.log) => {
2611
- const logTokens = (state) => syntaxTree(state).iterate({
2751
+ const logTokens = (state) => syntaxTree2(state).iterate({
2612
2752
  enter: (node) => log8(node.type)
2613
2753
  });
2614
- return StateField5.define({
2754
+ return StateField6.define({
2615
2755
  create: (state) => logTokens(state),
2616
2756
  update: (_, tr) => logTokens(tr.state)
2617
2757
  });
2618
2758
  };
2619
2759
 
2620
2760
  // packages/ui/react-ui-editor/src/extensions/dnd.ts
2621
- import { dropCursor, EditorView as EditorView10 } from "@codemirror/view";
2622
- var styles4 = EditorView10.theme({
2761
+ import { dropCursor, EditorView as EditorView11 } from "@codemirror/view";
2762
+ var styles4 = EditorView11.theme({
2623
2763
  ".cm-dropCursor": {
2624
2764
  borderLeft: "2px solid var(--dx-accentText)",
2625
2765
  color: "var(--dx-accentText)",
@@ -2633,7 +2773,7 @@ var dropFile = (options = {}) => {
2633
2773
  return [
2634
2774
  styles4,
2635
2775
  dropCursor(),
2636
- EditorView10.domEventHandlers({
2776
+ EditorView11.domEventHandlers({
2637
2777
  drop: (event, view) => {
2638
2778
  event.preventDefault();
2639
2779
  const files = event.dataTransfer?.files;
@@ -2660,7 +2800,7 @@ import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@cod
2660
2800
  import { searchKeymap } from "@codemirror/search";
2661
2801
  import { EditorState } from "@codemirror/state";
2662
2802
  import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
2663
- import { EditorView as EditorView12, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
2803
+ import { EditorView as EditorView13, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
2664
2804
  import defaultsDeep2 from "lodash.defaultsdeep";
2665
2805
  import merge from "lodash.merge";
2666
2806
  import { generateName } from "@dxos/display-name";
@@ -2668,10 +2808,10 @@ import { log as log5 } from "@dxos/log";
2668
2808
  import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
2669
2809
 
2670
2810
  // packages/ui/react-ui-editor/src/extensions/focus.ts
2671
- import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
2672
- import { EditorView as EditorView11 } from "@codemirror/view";
2811
+ import { StateEffect as StateEffect4, StateField as StateField7 } from "@codemirror/state";
2812
+ import { EditorView as EditorView12 } from "@codemirror/view";
2673
2813
  var focusEffect = StateEffect4.define();
2674
- var focusField = StateField6.define({
2814
+ var focusField = StateField7.define({
2675
2815
  create: () => false,
2676
2816
  update: (value, tr) => {
2677
2817
  for (const effect of tr.effects) {
@@ -2684,7 +2824,7 @@ var focusField = StateField6.define({
2684
2824
  });
2685
2825
  var focus = [
2686
2826
  focusField,
2687
- EditorView11.domEventHandlers({
2827
+ EditorView12.domEventHandlers({
2688
2828
  focus: (event, view) => {
2689
2829
  setTimeout(() => view.dispatch({
2690
2830
  effects: focusEffect.of(true)
@@ -2706,7 +2846,6 @@ var defaultBasicOptions = {
2706
2846
  bracketMatching: true,
2707
2847
  closeBrackets: true,
2708
2848
  drawSelection: true,
2709
- editable: true,
2710
2849
  focus: true,
2711
2850
  history: true,
2712
2851
  keymap: "standard",
@@ -2723,7 +2862,7 @@ var createBasicExtensions = (_props) => {
2723
2862
  const props = defaultsDeep2({}, _props, defaultBasicOptions);
2724
2863
  return [
2725
2864
  // NOTE: Doesn't catch errors in keymap functions.
2726
- EditorView12.exceptionSink.of((err) => {
2865
+ EditorView13.exceptionSink.of((err) => {
2727
2866
  log5.catch(err, void 0, {
2728
2867
  F: __dxlog_file8,
2729
2868
  L: 96,
@@ -2738,16 +2877,14 @@ var createBasicExtensions = (_props) => {
2738
2877
  props.drawSelection && drawSelection({
2739
2878
  cursorBlinkRate: 1200
2740
2879
  }),
2880
+ props.editable !== void 0 && EditorView13.editable.of(props.editable),
2741
2881
  props.focus && focus,
2742
2882
  props.highlightActiveLine && highlightActiveLine(),
2743
2883
  props.history && history(),
2744
2884
  props.lineNumbers && lineNumbers(),
2745
- props.lineWrapping && EditorView12.lineWrapping,
2885
+ props.lineWrapping && EditorView13.lineWrapping,
2746
2886
  props.placeholder && placeholder(props.placeholder),
2747
- props.readonly && [
2748
- EditorState.readOnly.of(true),
2749
- EditorView12.editable.of(false)
2750
- ],
2887
+ props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
2751
2888
  props.scrollPastEnd && scrollPastEnd(),
2752
2889
  props.tabSize && EditorState.tabSize.of(props.tabSize),
2753
2890
  // https://codemirror.net/docs/ref/#view.KeyBinding
@@ -2782,14 +2919,14 @@ var defaultThemeSlots = {
2782
2919
  var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
2783
2920
  const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
2784
2921
  return [
2785
- EditorView12.darkTheme.of(themeMode === "dark"),
2786
- EditorView12.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2922
+ EditorView13.darkTheme.of(themeMode === "dark"),
2923
+ EditorView13.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2787
2924
  // https://github.com/codemirror/theme-one-dark
2788
2925
  _syntaxHighlighting && (themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)),
2789
- slots.editor?.className && EditorView12.editorAttributes.of({
2926
+ slots.editor?.className && EditorView13.editorAttributes.of({
2790
2927
  class: slots.editor.className
2791
2928
  }),
2792
- slots.content?.className && EditorView12.contentAttributes.of({
2929
+ slots.content?.className && EditorView13.contentAttributes.of({
2793
2930
  class: slots.content.className
2794
2931
  })
2795
2932
  ].filter(isNotFalsy3);
@@ -2818,7 +2955,7 @@ var createDataExtensions = ({ id, text, space, identity }) => {
2818
2955
 
2819
2956
  // packages/ui/react-ui-editor/src/extensions/folding.tsx
2820
2957
  import { codeFolding, foldGutter } from "@codemirror/language";
2821
- import { EditorView as EditorView13 } from "@codemirror/view";
2958
+ import { EditorView as EditorView14 } from "@codemirror/view";
2822
2959
  import React3 from "react";
2823
2960
  import { Icon } from "@dxos/react-ui";
2824
2961
  var folding = (_props = {}) => [
@@ -2842,7 +2979,7 @@ var folding = (_props = {}) => [
2842
2979
  }));
2843
2980
  }
2844
2981
  }),
2845
- EditorView13.theme({
2982
+ EditorView14.theme({
2846
2983
  ".cm-foldGutter": {
2847
2984
  opacity: 0.3,
2848
2985
  transition: "opacity 0.3s",
@@ -2855,14 +2992,14 @@ var folding = (_props = {}) => [
2855
2992
  ];
2856
2993
 
2857
2994
  // packages/ui/react-ui-editor/src/extensions/listener.ts
2858
- import { EditorView as EditorView14 } from "@codemirror/view";
2995
+ import { EditorView as EditorView15 } from "@codemirror/view";
2859
2996
  var listener = ({ onFocus, onChange }) => {
2860
2997
  const extensions = [];
2861
- onFocus && extensions.push(EditorView14.focusChangeEffect.of((_, focusing) => {
2998
+ onFocus && extensions.push(EditorView15.focusChangeEffect.of((_, focusing) => {
2862
2999
  onFocus(focusing);
2863
3000
  return null;
2864
3001
  }));
2865
- onChange && extensions.push(EditorView14.updateListener.of((update2) => {
3002
+ onChange && extensions.push(EditorView15.updateListener.of((update2) => {
2866
3003
  onChange(update2.state.doc.toString(), update2.state.facet(documentId));
2867
3004
  }));
2868
3005
  return extensions;
@@ -2870,9 +3007,9 @@ var listener = ({ onFocus, onChange }) => {
2870
3007
 
2871
3008
  // packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
2872
3009
  import { snippet } from "@codemirror/autocomplete";
2873
- import { syntaxTree as syntaxTree2 } from "@codemirror/language";
3010
+ import { syntaxTree as syntaxTree3 } from "@codemirror/language";
2874
3011
  import { EditorSelection } from "@codemirror/state";
2875
- import { EditorView as EditorView15, keymap as keymap7 } from "@codemirror/view";
3012
+ import { EditorView as EditorView16, keymap as keymap7 } from "@codemirror/view";
2876
3013
  import { useMemo as useMemo3 } from "react";
2877
3014
  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;
2878
3015
  var Inline;
@@ -2895,7 +3032,7 @@ var setHeading = (level) => {
2895
3032
  let prevBlock = -1;
2896
3033
  for (const range of ranges) {
2897
3034
  let sawBlock = false;
2898
- syntaxTree2(state).iterate({
3035
+ syntaxTree3(state).iterate({
2899
3036
  from: range.from,
2900
3037
  to: range.to,
2901
3038
  enter: (node) => {
@@ -3004,7 +3141,7 @@ var setStyle = (type, enable) => {
3004
3141
  let startCovered = false;
3005
3142
  let endCovered = false;
3006
3143
  let { from, to } = range;
3007
- syntaxTree2(state).iterate({
3144
+ syntaxTree3(state).iterate({
3008
3145
  from,
3009
3146
  to,
3010
3147
  enter: (node) => {
@@ -3207,7 +3344,7 @@ var insertTable = (view) => {
3207
3344
  snippets.table(view, null, from, from);
3208
3345
  };
3209
3346
  var removeLinkInner = (from, to, changes, state) => {
3210
- syntaxTree2(state).iterate({
3347
+ syntaxTree3(state).iterate({
3211
3348
  from,
3212
3349
  to,
3213
3350
  enter: (node) => {
@@ -3252,7 +3389,7 @@ var addLink = ({ url, image: image2 } = {}) => {
3252
3389
  let { from, to } = range;
3253
3390
  const cutStyles = [];
3254
3391
  let okay = null;
3255
- syntaxTree2(state).iterate({
3392
+ syntaxTree3(state).iterate({
3256
3393
  from,
3257
3394
  to,
3258
3395
  enter: (node) => {
@@ -3347,7 +3484,7 @@ var addList = (type) => {
3347
3484
  let parentColumn = null;
3348
3485
  const blocks = [];
3349
3486
  for (const { from, to } of state.selection.ranges) {
3350
- syntaxTree2(state).iterate({
3487
+ syntaxTree3(state).iterate({
3351
3488
  from,
3352
3489
  to,
3353
3490
  enter: (node) => {
@@ -3482,7 +3619,7 @@ var removeList = (type) => {
3482
3619
  const stack = [];
3483
3620
  const targetNodeType = type === 0 ? "OrderedList" : type === 1 ? "BulletList" : "TaskList";
3484
3621
  for (const { from, to } of state.selection.ranges) {
3485
- syntaxTree2(state).iterate({
3622
+ syntaxTree3(state).iterate({
3486
3623
  from,
3487
3624
  to,
3488
3625
  enter: (node) => {
@@ -3569,7 +3706,7 @@ var setBlockquote = (enable) => {
3569
3706
  let lastBlock = -1;
3570
3707
  for (const { from, to } of state.selection.ranges) {
3571
3708
  const sawBlock = false;
3572
- syntaxTree2(state).iterate({
3709
+ syntaxTree3(state).iterate({
3573
3710
  from,
3574
3711
  to,
3575
3712
  enter: (node) => {
@@ -3659,7 +3796,7 @@ var addCodeblock = (target) => {
3659
3796
  for (const { from, to } of selection.ranges) {
3660
3797
  let blockFrom = from;
3661
3798
  let blockTo = to;
3662
- syntaxTree2(state).iterate({
3799
+ syntaxTree3(state).iterate({
3663
3800
  from,
3664
3801
  to,
3665
3802
  enter: (node) => {
@@ -3710,7 +3847,7 @@ var removeCodeblock = ({ state, dispatch }) => {
3710
3847
  let lastBlock = -1;
3711
3848
  const changes = [];
3712
3849
  for (const { from, to } of state.selection.ranges) {
3713
- syntaxTree2(state).iterate({
3850
+ syntaxTree3(state).iterate({
3714
3851
  from,
3715
3852
  to,
3716
3853
  enter: (node) => {
@@ -3872,7 +4009,7 @@ var getFormatting = (state) => {
3872
4009
  }
3873
4010
  }
3874
4011
  }
3875
- syntaxTree2(state).iterate({
4012
+ syntaxTree3(state).iterate({
3876
4013
  from: range.from,
3877
4014
  to: range.to,
3878
4015
  enter: (node) => {
@@ -3961,7 +4098,7 @@ var getFormatting = (state) => {
3961
4098
  };
3962
4099
  };
3963
4100
  var useFormattingState = (state) => {
3964
- return useMemo3(() => EditorView15.updateListener.of((update2) => {
4101
+ return useMemo3(() => EditorView16.updateListener.of((update2) => {
3965
4102
  if (update2.docChanged || update2.selectionSet) {
3966
4103
  Object.entries(getFormatting(update2.state)).forEach(([key, active]) => {
3967
4104
  state[key] = active;
@@ -4244,9 +4381,9 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
4244
4381
  };
4245
4382
 
4246
4383
  // packages/ui/react-ui-editor/src/extensions/markdown/debug.ts
4247
- import { syntaxTree as syntaxTree3 } from "@codemirror/language";
4248
- import { StateField as StateField7 } from "@codemirror/state";
4249
- var debugTree = (cb) => StateField7.define({
4384
+ import { syntaxTree as syntaxTree4 } from "@codemirror/language";
4385
+ import { StateField as StateField8 } from "@codemirror/state";
4386
+ var debugTree = (cb) => StateField8.define({
4250
4387
  create: (state) => cb(convertTreeToJson(state)),
4251
4388
  update: (value, tr) => cb(convertTreeToJson(tr.state))
4252
4389
  });
@@ -4267,24 +4404,24 @@ var convertTreeToJson = (state) => {
4267
4404
  }
4268
4405
  return node;
4269
4406
  };
4270
- return treeToJson(syntaxTree3(state).cursor());
4407
+ return treeToJson(syntaxTree4(state).cursor());
4271
4408
  };
4272
4409
 
4273
4410
  // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
4274
- import { syntaxTree as syntaxTree7 } from "@codemirror/language";
4275
- import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect5 } from "@codemirror/state";
4276
- import { EditorView as EditorView19, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
4411
+ import { syntaxTree as syntaxTree8 } from "@codemirror/language";
4412
+ import { RangeSetBuilder as RangeSetBuilder4, StateEffect as StateEffect5 } from "@codemirror/state";
4413
+ import { EditorView as EditorView20, Decoration as Decoration8, WidgetType as WidgetType6, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
4277
4414
  import { invariant as invariant4 } from "@dxos/invariant";
4278
4415
  import { mx as mx4 } from "@dxos/react-ui-theme";
4279
4416
 
4280
4417
  // packages/ui/react-ui-editor/src/extensions/markdown/changes.ts
4281
- import { syntaxTree as syntaxTree4 } from "@codemirror/language";
4418
+ import { syntaxTree as syntaxTree5 } from "@codemirror/language";
4282
4419
  import { Transaction as Transaction2 } from "@codemirror/state";
4283
- import { ViewPlugin as ViewPlugin5 } from "@codemirror/view";
4420
+ import { ViewPlugin as ViewPlugin6 } from "@codemirror/view";
4284
4421
  var adjustChanges = () => {
4285
- return ViewPlugin5.fromClass(class {
4422
+ return ViewPlugin6.fromClass(class {
4286
4423
  update(update2) {
4287
- const tree = syntaxTree4(update2.state);
4424
+ const tree = syntaxTree5(update2.state);
4288
4425
  const adjustments = [];
4289
4426
  for (const tr of update2.transactions) {
4290
4427
  const event = tr.annotation(Transaction2.userEvent);
@@ -4422,14 +4559,14 @@ var getValidUrl = (str) => {
4422
4559
  };
4423
4560
 
4424
4561
  // packages/ui/react-ui-editor/src/extensions/markdown/image.ts
4425
- import { syntaxTree as syntaxTree5 } from "@codemirror/language";
4426
- import { StateField as StateField8 } from "@codemirror/state";
4427
- import { Decoration as Decoration5, EditorView as EditorView16, WidgetType as WidgetType3 } from "@codemirror/view";
4562
+ import { syntaxTree as syntaxTree6 } from "@codemirror/language";
4563
+ import { StateField as StateField9 } from "@codemirror/state";
4564
+ import { Decoration as Decoration6, EditorView as EditorView17, WidgetType as WidgetType4 } from "@codemirror/view";
4428
4565
  var image = (_options = {}) => {
4429
4566
  return [
4430
- StateField8.define({
4567
+ StateField9.define({
4431
4568
  create: (state) => {
4432
- return Decoration5.set(buildDecorations(0, state.doc.length, state));
4569
+ return Decoration6.set(buildDecorations2(0, state.doc.length, state));
4433
4570
  },
4434
4571
  update: (value, tr) => {
4435
4572
  if (!tr.docChanged && !tr.selection) {
@@ -4449,10 +4586,10 @@ var image = (_options = {}) => {
4449
4586
  filterFrom: from,
4450
4587
  filterTo: to,
4451
4588
  filter: () => false,
4452
- add: buildDecorations(from, to, tr.state)
4589
+ add: buildDecorations2(from, to, tr.state)
4453
4590
  });
4454
4591
  },
4455
- provide: (field) => EditorView16.decorations.from(field)
4592
+ provide: (field) => EditorView17.decorations.from(field)
4456
4593
  })
4457
4594
  ];
4458
4595
  };
@@ -4464,10 +4601,10 @@ var preloadImage = (url) => {
4464
4601
  preloaded.add(url);
4465
4602
  }
4466
4603
  };
4467
- var buildDecorations = (from, to, state) => {
4604
+ var buildDecorations2 = (from, to, state) => {
4468
4605
  const decorations = [];
4469
4606
  const cursor = state.selection.main.head;
4470
- syntaxTree5(state).iterate({
4607
+ syntaxTree6(state).iterate({
4471
4608
  enter: (node) => {
4472
4609
  if (node.name === "Image") {
4473
4610
  const urlNode = node.node.getChild("URL");
@@ -4478,7 +4615,7 @@ var buildDecorations = (from, to, state) => {
4478
4615
  return;
4479
4616
  }
4480
4617
  preloadImage(url);
4481
- decorations.push(Decoration5.replace({
4618
+ decorations.push(Decoration6.replace({
4482
4619
  block: true,
4483
4620
  widget: new ImageWidget(url)
4484
4621
  }).range(hide2 ? node.from : node.to, node.to));
@@ -4490,7 +4627,7 @@ var buildDecorations = (from, to, state) => {
4490
4627
  });
4491
4628
  return decorations;
4492
4629
  };
4493
- var ImageWidget = class extends WidgetType3 {
4630
+ var ImageWidget = class extends WidgetType4 {
4494
4631
  constructor(_url) {
4495
4632
  super();
4496
4633
  this._url = _url;
@@ -4512,10 +4649,10 @@ var ImageWidget = class extends WidgetType3 {
4512
4649
  };
4513
4650
 
4514
4651
  // packages/ui/react-ui-editor/src/extensions/markdown/styles.ts
4515
- import { EditorView as EditorView17 } from "@codemirror/view";
4652
+ import { EditorView as EditorView18 } from "@codemirror/view";
4516
4653
  var bulletListIndentationWidth = 24;
4517
4654
  var orderedListIndentationWidth = 36;
4518
- var formattingStyles = EditorView17.theme({
4655
+ var formattingStyles = EditorView18.theme({
4519
4656
  /**
4520
4657
  * Horizontal rule.
4521
4658
  */
@@ -4634,18 +4771,18 @@ var formattingStyles = EditorView17.theme({
4634
4771
  });
4635
4772
 
4636
4773
  // packages/ui/react-ui-editor/src/extensions/markdown/table.ts
4637
- import { syntaxTree as syntaxTree6 } from "@codemirror/language";
4638
- import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField9 } from "@codemirror/state";
4639
- import { Decoration as Decoration6, EditorView as EditorView18, WidgetType as WidgetType4 } from "@codemirror/view";
4774
+ import { syntaxTree as syntaxTree7 } from "@codemirror/language";
4775
+ import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField10 } from "@codemirror/state";
4776
+ import { Decoration as Decoration7, EditorView as EditorView19, WidgetType as WidgetType5 } from "@codemirror/view";
4640
4777
  var table = (options = {}) => {
4641
- return StateField9.define({
4778
+ return StateField10.define({
4642
4779
  create: (state) => update(state, options),
4643
4780
  update: (_, tr) => update(tr.state, options),
4644
- provide: (field) => EditorView18.decorations.from(field)
4781
+ provide: (field) => EditorView19.decorations.from(field)
4645
4782
  });
4646
4783
  };
4647
4784
  var update = (state, _options) => {
4648
- const builder = new RangeSetBuilder2();
4785
+ const builder = new RangeSetBuilder3();
4649
4786
  const cursor = state.selection.main.head;
4650
4787
  const tables = [];
4651
4788
  const getTable = () => tables[tables.length - 1];
@@ -4653,7 +4790,7 @@ var update = (state, _options) => {
4653
4790
  const table2 = getTable();
4654
4791
  return table2.rows?.[table2.rows.length - 1];
4655
4792
  };
4656
- syntaxTree6(state).iterate({
4793
+ syntaxTree7(state).iterate({
4657
4794
  enter: (node) => {
4658
4795
  switch (node.name) {
4659
4796
  case "Table": {
@@ -4686,19 +4823,19 @@ var update = (state, _options) => {
4686
4823
  tables.forEach((table2) => {
4687
4824
  const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
4688
4825
  if (replace) {
4689
- builder.add(table2.from, table2.to, Decoration6.replace({
4826
+ builder.add(table2.from, table2.to, Decoration7.replace({
4690
4827
  block: true,
4691
4828
  widget: new TableWidget(table2)
4692
4829
  }));
4693
4830
  } else {
4694
- builder.add(table2.from, table2.to, Decoration6.mark({
4831
+ builder.add(table2.from, table2.to, Decoration7.mark({
4695
4832
  class: "cm-table"
4696
4833
  }));
4697
4834
  }
4698
4835
  });
4699
4836
  return builder.finish();
4700
4837
  };
4701
- var TableWidget = class extends WidgetType4 {
4838
+ var TableWidget = class extends WidgetType5 {
4702
4839
  constructor(_table) {
4703
4840
  super();
4704
4841
  this._table = _table;
@@ -4740,14 +4877,14 @@ var Unicode = {
4740
4877
  bulletSmall: "\u2219",
4741
4878
  bulletSquare: "\u2B1D"
4742
4879
  };
4743
- var HorizontalRuleWidget = class extends WidgetType5 {
4880
+ var HorizontalRuleWidget = class extends WidgetType6 {
4744
4881
  toDOM() {
4745
4882
  const el = document.createElement("span");
4746
4883
  el.className = "cm-hr";
4747
4884
  return el;
4748
4885
  }
4749
4886
  };
4750
- var LinkButton = class extends WidgetType5 {
4887
+ var LinkButton = class extends WidgetType6 {
4751
4888
  constructor(url, render) {
4752
4889
  super();
4753
4890
  this.url = url;
@@ -4763,7 +4900,7 @@ var LinkButton = class extends WidgetType5 {
4763
4900
  return el;
4764
4901
  }
4765
4902
  };
4766
- var CheckboxWidget = class extends WidgetType5 {
4903
+ var CheckboxWidget = class extends WidgetType6 {
4767
4904
  constructor(_checked) {
4768
4905
  super();
4769
4906
  this._checked = _checked;
@@ -4808,7 +4945,7 @@ var CheckboxWidget = class extends WidgetType5 {
4808
4945
  return false;
4809
4946
  }
4810
4947
  };
4811
- var TextWidget = class extends WidgetType5 {
4948
+ var TextWidget = class extends WidgetType6 {
4812
4949
  constructor(text, className) {
4813
4950
  super();
4814
4951
  this.text = text;
@@ -4823,29 +4960,29 @@ var TextWidget = class extends WidgetType5 {
4823
4960
  return el;
4824
4961
  }
4825
4962
  };
4826
- var hide = Decoration7.replace({});
4827
- var blockQuote = Decoration7.line({
4963
+ var hide = Decoration8.replace({});
4964
+ var blockQuote = Decoration8.line({
4828
4965
  class: mx4("cm-blockquote")
4829
4966
  });
4830
- var fencedCodeLine = Decoration7.line({
4967
+ var fencedCodeLine = Decoration8.line({
4831
4968
  class: mx4("cm-code cm-codeblock-line")
4832
4969
  });
4833
- var fencedCodeLineFirst = Decoration7.line({
4970
+ var fencedCodeLineFirst = Decoration8.line({
4834
4971
  class: mx4("cm-code cm-codeblock-line", "cm-codeblock-first")
4835
4972
  });
4836
- var fencedCodeLineLast = Decoration7.line({
4973
+ var fencedCodeLineLast = Decoration8.line({
4837
4974
  class: mx4("cm-code cm-codeblock-line", "cm-codeblock-last")
4838
4975
  });
4839
4976
  var commentBlockLine = fencedCodeLine;
4840
4977
  var commentBlockLineFirst = fencedCodeLineFirst;
4841
4978
  var commentBlockLineLast = fencedCodeLineLast;
4842
- var horizontalRule = Decoration7.replace({
4979
+ var horizontalRule = Decoration8.replace({
4843
4980
  widget: new HorizontalRuleWidget()
4844
4981
  });
4845
- var checkedTask = Decoration7.replace({
4982
+ var checkedTask = Decoration8.replace({
4846
4983
  widget: new CheckboxWidget(true)
4847
4984
  });
4848
- var uncheckedTask = Decoration7.replace({
4985
+ var uncheckedTask = Decoration8.replace({
4849
4986
  widget: new CheckboxWidget(false)
4850
4987
  });
4851
4988
  var editingRange = (state, range, focus2) => {
@@ -4860,9 +4997,9 @@ var autoHideTags = /* @__PURE__ */ new Set([
4860
4997
  "SubscriptMark",
4861
4998
  "SuperscriptMark"
4862
4999
  ]);
4863
- var buildDecorations2 = (view, options, focus2) => {
4864
- const deco = new RangeSetBuilder3();
4865
- const atomicDeco = new RangeSetBuilder3();
5000
+ var buildDecorations3 = (view, options, focus2) => {
5001
+ const deco = new RangeSetBuilder4();
5002
+ const atomicDeco = new RangeSetBuilder4();
4866
5003
  const { state } = view;
4867
5004
  const headerLevels = [];
4868
5005
  const getHeaderLevels = (node, level) => {
@@ -4949,7 +5086,7 @@ var buildDecorations2 = (view, options, focus2) => {
4949
5086
  } else {
4950
5087
  const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
4951
5088
  if (num.length) {
4952
- atomicDeco.add(mark.from, mark.from + len, Decoration7.replace({
5089
+ atomicDeco.add(mark.from, mark.from + len, Decoration8.replace({
4953
5090
  widget: new TextWidget(num, theme.heading(level))
4954
5091
  }));
4955
5092
  }
@@ -4974,7 +5111,7 @@ var buildDecorations2 = (view, options, focus2) => {
4974
5111
  if (node.from === line.to - 1) {
4975
5112
  return false;
4976
5113
  }
4977
- deco.add(line.from, line.from, Decoration7.line({
5114
+ deco.add(line.from, line.from, Decoration8.line({
4978
5115
  class: "cm-list-item",
4979
5116
  attributes: {
4980
5117
  style: `padding-left: ${offset}px; text-indent: -${width}px;`
@@ -4991,7 +5128,7 @@ var buildDecorations2 = (view, options, focus2) => {
4991
5128
  const label = list.type === "OrderedList" ? `${++list.number}.` : Unicode.bulletSmall;
4992
5129
  const line = state.doc.lineAt(node.from);
4993
5130
  const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
4994
- atomicDeco.add(line.from, to, Decoration7.replace({
5131
+ atomicDeco.add(line.from, to, Decoration8.replace({
4995
5132
  widget: new TextWidget(label, list.type === "OrderedList" ? "cm-list-mark cm-list-mark-ordered" : "cm-list-mark cm-list-mark-bullet")
4996
5133
  }));
4997
5134
  break;
@@ -5078,7 +5215,7 @@ var buildDecorations2 = (view, options, focus2) => {
5078
5215
  if (!editing) {
5079
5216
  atomicDeco.add(node.from, marks[0].to, hide);
5080
5217
  }
5081
- deco.add(marks[0].to, marks[1].from, Decoration7.mark({
5218
+ deco.add(marks[0].to, marks[1].from, Decoration8.mark({
5082
5219
  tagName: "a",
5083
5220
  attributes: {
5084
5221
  class: "cm-link",
@@ -5088,7 +5225,7 @@ var buildDecorations2 = (view, options, focus2) => {
5088
5225
  }
5089
5226
  }));
5090
5227
  if (!editing) {
5091
- atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration7.replace({
5228
+ atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration8.replace({
5092
5229
  widget: new LinkButton(url, options.renderLinkButton)
5093
5230
  }) : hide);
5094
5231
  }
@@ -5122,7 +5259,7 @@ var buildDecorations2 = (view, options, focus2) => {
5122
5259
  }
5123
5260
  }
5124
5261
  };
5125
- const tree = syntaxTree7(state);
5262
+ const tree = syntaxTree8(state);
5126
5263
  if (options.numberedHeadings?.from === void 0) {
5127
5264
  for (const { from, to } of view.visibleRanges) {
5128
5265
  tree.iterate({
@@ -5146,13 +5283,13 @@ var buildDecorations2 = (view, options, focus2) => {
5146
5283
  var forceUpdate = StateEffect5.define();
5147
5284
  var decorateMarkdown = (options = {}) => {
5148
5285
  return [
5149
- ViewPlugin6.fromClass(class {
5286
+ ViewPlugin7.fromClass(class {
5150
5287
  constructor(view) {
5151
- ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(view, options, view.hasFocus));
5288
+ ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations3(view, options, view.hasFocus));
5152
5289
  }
5153
5290
  update(update2) {
5154
5291
  if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((effect) => effect.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
5155
- ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(update2.view, options, update2.view.hasFocus));
5292
+ ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations3(update2.view, options, update2.view.hasFocus));
5156
5293
  this.clearUpdate();
5157
5294
  } else if (update2.selectionSet) {
5158
5295
  this.scheduleUpdate(update2.view);
@@ -5178,9 +5315,9 @@ var decorateMarkdown = (options = {}) => {
5178
5315
  }
5179
5316
  }, {
5180
5317
  provide: (plugin) => [
5181
- EditorView19.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
5182
- EditorView19.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
5183
- EditorView19.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
5318
+ EditorView20.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration8.none),
5319
+ EditorView20.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration8.none),
5320
+ EditorView20.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration8.none)
5184
5321
  ]
5185
5322
  }),
5186
5323
  image(),
@@ -5191,12 +5328,12 @@ var decorateMarkdown = (options = {}) => {
5191
5328
  };
5192
5329
 
5193
5330
  // packages/ui/react-ui-editor/src/extensions/markdown/link.ts
5194
- import { syntaxTree as syntaxTree8 } from "@codemirror/language";
5331
+ import { syntaxTree as syntaxTree9 } from "@codemirror/language";
5195
5332
  import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
5196
5333
  import { tooltipContent } from "@dxos/react-ui-theme";
5197
5334
  var linkTooltip = (render) => {
5198
5335
  return hoverTooltip2((view, pos, side) => {
5199
- const syntax = syntaxTree8(view.state).resolveInner(pos, side);
5336
+ const syntax = syntaxTree9(view.state).resolveInner(pos, side);
5200
5337
  let link = null;
5201
5338
  for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
5202
5339
  link = node.name === "Link" ? node : null;
@@ -5377,7 +5514,7 @@ var useActionHandler = (view) => {
5377
5514
 
5378
5515
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
5379
5516
  import { EditorState as EditorState2 } from "@codemirror/state";
5380
- import { EditorView as EditorView20 } from "@codemirror/view";
5517
+ import { EditorView as EditorView21 } from "@codemirror/view";
5381
5518
  import { useFocusableGroup } from "@fluentui/react-tabster";
5382
5519
  import { useCallback as useCallback3, useEffect as useEffect2, useMemo as useMemo4, useRef, useState } from "react";
5383
5520
  import { log as log7 } from "@dxos/log";
@@ -5421,7 +5558,7 @@ var useTextEditor = (props = {}, deps = []) => {
5421
5558
  id && documentId.of(id),
5422
5559
  extensions,
5423
5560
  // NOTE: This doesn't catch errors in keymap functions.
5424
- EditorView20.exceptionSink.of((err) => {
5561
+ EditorView21.exceptionSink.of((err) => {
5425
5562
  log7.catch(err, void 0, {
5426
5563
  F: __dxlog_file11,
5427
5564
  L: 97,
@@ -5431,10 +5568,10 @@ var useTextEditor = (props = {}, deps = []) => {
5431
5568
  })
5432
5569
  ].filter(isNotFalsy4)
5433
5570
  });
5434
- view2 = new EditorView20({
5571
+ view2 = new EditorView21({
5435
5572
  parent: parentRef.current,
5436
5573
  state,
5437
- scrollTo: scrollTo ? EditorView20.scrollIntoView(scrollTo, {
5574
+ scrollTo: scrollTo ? EditorView21.scrollIntoView(scrollTo, {
5438
5575
  yMargin: 96
5439
5576
  }) : void 0,
5440
5577
  dispatchTransactions: debug ? debugDispatcher : void 0
@@ -5498,7 +5635,7 @@ var useTextEditor = (props = {}, deps = []) => {
5498
5635
  autoFocus,
5499
5636
  view
5500
5637
  ]);
5501
- const focusableGroup = useFocusableGroup({
5638
+ const focusableGroupAttrs = useFocusableGroup({
5502
5639
  tabBehavior: "limited",
5503
5640
  ignoreDefaultKeydown: {
5504
5641
  Escape: view?.state.facet(editorInputMode).noTabster
@@ -5517,15 +5654,14 @@ var useTextEditor = (props = {}, deps = []) => {
5517
5654
  }, [
5518
5655
  view
5519
5656
  ]);
5520
- const focusAttributes = {
5521
- tabIndex: 0,
5522
- ...focusableGroup,
5523
- onKeyUp: handleKeyUp
5524
- };
5525
5657
  return {
5526
5658
  parentRef,
5527
5659
  view,
5528
- focusAttributes
5660
+ focusAttributes: {
5661
+ tabIndex: 0,
5662
+ ...focusableGroupAttrs,
5663
+ onKeyUp: handleKeyUp
5664
+ }
5529
5665
  };
5530
5666
  };
5531
5667
  export {
@@ -5534,7 +5670,7 @@ export {
5534
5670
  EditorInputModes,
5535
5671
  EditorState3 as EditorState,
5536
5672
  EditorToolbar,
5537
- EditorView21 as EditorView,
5673
+ EditorView22 as EditorView,
5538
5674
  EditorViewMode,
5539
5675
  EditorViewModes,
5540
5676
  Inline,
@@ -5620,7 +5756,7 @@ export {
5620
5756
  setStyle,
5621
5757
  singleValueFacet,
5622
5758
  stackItemContentEditorClassNames,
5623
- stackItemContentToolbarClassNames,
5759
+ stackItemContentToolbarClassNames2 as stackItemContentToolbarClassNames,
5624
5760
  table,
5625
5761
  tags2 as tags,
5626
5762
  textRange,