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