@dxos/react-ui-editor 0.4.4 → 0.4.5-main.181e1ed

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.
@@ -8,7 +8,7 @@ import { tags as tags2 } from "@lezer/highlight";
8
8
 
9
9
  // packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
10
10
  import { EditorState as EditorState2 } from "@codemirror/state";
11
- import { EditorView as EditorView15 } from "@codemirror/view";
11
+ import { EditorView as EditorView16 } from "@codemirror/view";
12
12
  import { useFocusableGroup } from "@fluentui/react-tabster";
13
13
  import defaultsDeep2 from "lodash.defaultsdeep";
14
14
  import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2, useMemo as useMemo2 } from "react";
@@ -102,8 +102,8 @@ var annotations = (options = {}) => {
102
102
  annotationsState
103
103
  ], (state) => {
104
104
  const annotations2 = state.field(annotationsState);
105
- const decorations = annotations2.map((annotation) => {
106
- const range = Cursor.getRangeFromCursor(state, annotation.cursor);
105
+ const decorations = annotations2.map((annotation2) => {
106
+ const range = Cursor.getRangeFromCursor(state, annotation2.cursor);
107
107
  return range && annotationMark.range(range.from, range.to);
108
108
  }).filter(isNotFalsy);
109
109
  return Decoration.set(decorations);
@@ -1116,8 +1116,8 @@ var getToken = (path, defaultValue = void 0) => get2(tokens, path, defaultValue)
1116
1116
 
1117
1117
  // packages/ui/react-ui-editor/src/styles/layout.ts
1118
1118
  var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
1119
- var editorFillLayoutRoot = "min-bs-full grid";
1120
- var editorFillLayoutEditor = "min-bs-full";
1119
+ var editorFillLayoutRoot = "bs-full overflow-hidden grid";
1120
+ var editorFillLayoutEditor = "bs-full overflow-hidden [&>.cm-scroller]:bs-full [&>.cm-scroller]:overflow-y-auto";
1121
1121
  var editorHalfViewportOverscrollContent = "after:block after:min-bs-[50dvh] after:pointer-events-none";
1122
1122
 
1123
1123
  // packages/ui/react-ui-editor/src/util.ts
@@ -1553,15 +1553,66 @@ var useComments = (view, id, comments2 = []) => {
1553
1553
  ]);
1554
1554
  };
1555
1555
 
1556
- // packages/ui/react-ui-editor/src/extensions/listener.ts
1556
+ // packages/ui/react-ui-editor/src/extensions/cursor-line-margin.ts
1557
+ import { Facet as Facet4, Transaction } from "@codemirror/state";
1557
1558
  import { EditorView as EditorView7 } from "@codemirror/view";
1559
+ var cursorLineMarginFacet = Facet4.define({
1560
+ combine: (input) => input[0] ?? 3
1561
+ });
1562
+ var annotation = "cursorLineMargin";
1563
+ var lineAtPos = (s, pos) => s.doc.lineAt(pos).number;
1564
+ var cursorLineMargin = EditorView7.updateListener.of(({ transactions, state, selectionSet, startState, view }) => {
1565
+ if (transactions.length < 1 || transactions.some((tr) => tr.isUserEvent(annotation))) {
1566
+ return;
1567
+ }
1568
+ const s = state;
1569
+ const { main } = s.selection;
1570
+ const cursorLineMargin2 = s.facet(cursorLineMarginFacet);
1571
+ const rect = view.dom.getBoundingClientRect();
1572
+ const viewportTop = rect.top - view.documentTop;
1573
+ const viewportBottom = rect.bottom - view.documentTop;
1574
+ const mainLine = lineAtPos(s, main.head);
1575
+ const _visTopLine = lineAtPos(s, view.lineBlockAtHeight(viewportTop).from);
1576
+ const botLineBlk = view.lineBlockAtHeight(viewportBottom);
1577
+ const visBotLineDoc = lineAtPos(s, Math.min(botLineBlk.to, s.doc.length));
1578
+ const visBotLine = botLineBlk.bottom >= viewportBottom ? visBotLineDoc : visBotLineDoc + Math.floor((viewportBottom - botLineBlk.bottom) / view.defaultLineHeight);
1579
+ const needsScrollTop = false;
1580
+ const needsScrollBot = mainLine >= visBotLine - cursorLineMargin2;
1581
+ if (needsScrollTop && needsScrollBot) {
1582
+ console.warn("is cursorScrollMargin too large for the editor size?");
1583
+ return;
1584
+ }
1585
+ if (!needsScrollTop && !needsScrollBot) {
1586
+ return;
1587
+ }
1588
+ if (selectionSet) {
1589
+ const { head } = startState.selection.main;
1590
+ const oldMainLine = lineAtPos(startState, head);
1591
+ if (needsScrollTop && oldMainLine < mainLine) {
1592
+ return;
1593
+ }
1594
+ if (needsScrollBot && oldMainLine > mainLine) {
1595
+ return;
1596
+ }
1597
+ }
1598
+ view.dispatch({
1599
+ annotations: Transaction.userEvent.of(annotation),
1600
+ effects: EditorView7.scrollIntoView(s.selection.main.head, {
1601
+ y: needsScrollTop ? "start" : "end",
1602
+ yMargin: view.defaultLineHeight * cursorLineMargin2
1603
+ })
1604
+ });
1605
+ });
1606
+
1607
+ // packages/ui/react-ui-editor/src/extensions/listener.ts
1608
+ import { EditorView as EditorView8 } from "@codemirror/view";
1558
1609
  var listener = ({ onFocus, onChange }) => {
1559
1610
  const extensions = [];
1560
- onFocus && extensions.push(EditorView7.focusChangeEffect.of((_, focused) => {
1611
+ onFocus && extensions.push(EditorView8.focusChangeEffect.of((_, focused) => {
1561
1612
  onFocus(focused);
1562
1613
  return null;
1563
1614
  }));
1564
- onChange && extensions.push(EditorView7.updateListener.of((update2) => {
1615
+ onChange && extensions.push(EditorView8.updateListener.of((update2) => {
1565
1616
  onChange(update2.state.doc.toString());
1566
1617
  }));
1567
1618
  return extensions;
@@ -1576,7 +1627,7 @@ import { languages } from "@codemirror/language-data";
1576
1627
  import { searchKeymap } from "@codemirror/search";
1577
1628
  import { EditorState } from "@codemirror/state";
1578
1629
  import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
1579
- import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView8, highlightActiveLine as highlightActiveLine2, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
1630
+ import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView9, highlightActiveLine as highlightActiveLine2, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
1580
1631
  import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
1581
1632
 
1582
1633
  // packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
@@ -1770,7 +1821,7 @@ var markdownHighlightStyle = (readonly) => {
1770
1821
  // packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
1771
1822
  var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => {
1772
1823
  return [
1773
- lineWrapping && EditorView8.lineWrapping,
1824
+ lineWrapping && EditorView9.lineWrapping,
1774
1825
  EditorState.allowMultipleSelections.of(true),
1775
1826
  EditorState.tabSize.of(2),
1776
1827
  // https://github.com/codemirror/basic-setup
@@ -1823,9 +1874,9 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
1823
1874
  // packages/ui/react-ui-editor/src/extensions/markdown/code.ts
1824
1875
  import { syntaxTree } from "@codemirror/language";
1825
1876
  import { RangeSetBuilder } from "@codemirror/state";
1826
- import { ViewPlugin as ViewPlugin3, EditorView as EditorView9, Decoration as Decoration4, WidgetType as WidgetType2 } from "@codemirror/view";
1877
+ import { ViewPlugin as ViewPlugin3, EditorView as EditorView10, Decoration as Decoration4, WidgetType as WidgetType2 } from "@codemirror/view";
1827
1878
  import { mx as mx2 } from "@dxos/react-ui-theme";
1828
- var styles4 = EditorView9.baseTheme({
1879
+ var styles4 = EditorView10.baseTheme({
1829
1880
  "& .cm-code": {
1830
1881
  fontFamily: getToken("fontFamily.mono", []).join(",")
1831
1882
  },
@@ -1948,7 +1999,7 @@ var code2 = () => {
1948
1999
  import { snippet } from "@codemirror/autocomplete";
1949
2000
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
1950
2001
  import { RangeSetBuilder as RangeSetBuilder2, EditorSelection } from "@codemirror/state";
1951
- import { Decoration as Decoration5, EditorView as EditorView10, keymap as keymap5, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
2002
+ import { Decoration as Decoration5, EditorView as EditorView11, keymap as keymap5, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
1952
2003
  import { useState, useMemo } from "react";
1953
2004
  var compareFormatting = (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;
1954
2005
  var Inline;
@@ -1969,6 +2020,7 @@ var setHeading = (level) => ({ state, dispatch }) => {
1969
2020
  const changes = [];
1970
2021
  let prevBlock = -1;
1971
2022
  for (const range of ranges) {
2023
+ let sawBlock = false;
1972
2024
  syntaxTree2(state).iterate({
1973
2025
  from: range.from,
1974
2026
  to: range.to,
@@ -1976,6 +2028,7 @@ var setHeading = (level) => ({ state, dispatch }) => {
1976
2028
  if (!Object.hasOwn(Textblocks, node.name) || prevBlock === node.from) {
1977
2029
  return;
1978
2030
  }
2031
+ sawBlock = true;
1979
2032
  prevBlock = node.from;
1980
2033
  const blockType = Textblocks[node.name];
1981
2034
  const isHeading = /heading(\d)/.exec(blockType);
@@ -2020,12 +2073,22 @@ var setHeading = (level) => ({ state, dispatch }) => {
2020
2073
  }
2021
2074
  }
2022
2075
  });
2076
+ let line;
2077
+ if (!sawBlock && range.empty && level > 0 && !/\S/.test((line = state.doc.lineAt(range.from)).text)) {
2078
+ changes.push({
2079
+ from: line.from,
2080
+ to: line.to,
2081
+ insert: "#".repeat(level) + " "
2082
+ });
2083
+ }
2023
2084
  }
2024
2085
  if (!changes.length) {
2025
2086
  return false;
2026
2087
  }
2088
+ const changeSet = state.changes(changes);
2027
2089
  dispatch(state.update({
2028
- changes,
2090
+ changes: changeSet,
2091
+ selection: state.selection.map(changeSet, 1),
2029
2092
  userEvent: "format.setHeading",
2030
2093
  scrollIntoView: true
2031
2094
  }));
@@ -2097,10 +2160,16 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
2097
2160
  const closeStart = node.to - size;
2098
2161
  if (markType === type) {
2099
2162
  if (openEnd <= from && closeStart >= from) {
2100
- startCovered = openEnd === from ? "adjacent" : true;
2163
+ startCovered = !enable && openEnd === skipMarkers(from, node.node, -1, openEnd) ? {
2164
+ from: node.from,
2165
+ to: openEnd
2166
+ } : true;
2101
2167
  }
2102
2168
  if (openEnd <= to && closeStart >= to) {
2103
- endCovered = closeStart === to ? "adjacent" : true;
2169
+ endCovered = !enable && closeStart === skipMarkers(to, node.node, 1, closeStart) ? {
2170
+ from: closeStart,
2171
+ to: node.to
2172
+ } : true;
2104
2173
  }
2105
2174
  }
2106
2175
  if (markType === type || type === 3 && enable) {
@@ -2149,22 +2218,16 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
2149
2218
  });
2150
2219
  }
2151
2220
  } else {
2152
- if (startCovered === "adjacent") {
2153
- changes2.push({
2154
- from: from - marker.length,
2155
- to: from
2156
- });
2221
+ if (typeof startCovered === "object") {
2222
+ changes2.push(startCovered);
2157
2223
  } else if (startCovered) {
2158
2224
  changes2.push({
2159
2225
  from: skipSpaces(rangeStart, state.doc, -1, blockStart),
2160
2226
  insert: marker
2161
2227
  });
2162
2228
  }
2163
- if (endCovered === "adjacent") {
2164
- changes2.push({
2165
- from: to,
2166
- to: to + marker.length
2167
- });
2229
+ if (typeof endCovered === "object") {
2230
+ changes2.push(endCovered);
2168
2231
  } else if (endCovered) {
2169
2232
  changes2.push({
2170
2233
  from: skipSpaces(rangeEnd, state.doc, 1, blockEnd),
@@ -2175,6 +2238,15 @@ var setStyle = (type, enable) => ({ state, dispatch }) => {
2175
2238
  }
2176
2239
  }
2177
2240
  });
2241
+ if (blockStart < 0 && range.empty && enable && !/\S/.test(state.doc.lineAt(range.from).text)) {
2242
+ return {
2243
+ changes: {
2244
+ from: range.head,
2245
+ insert: marker + marker
2246
+ },
2247
+ range: EditorSelection.cursor(range.head + marker.length)
2248
+ };
2249
+ }
2178
2250
  const changeSet = state.changes(changes2.concat(changesAtEnd));
2179
2251
  return {
2180
2252
  changes: changeSet,
@@ -2220,6 +2292,19 @@ var skipSpaces = (pos, doc, dir, limit) => {
2220
2292
  }
2221
2293
  return pos;
2222
2294
  };
2295
+ var skipMarkers = (pos, tree, dir, limit) => {
2296
+ for (; ; ) {
2297
+ const next = tree.resolve(pos, dir);
2298
+ if (!IgnoreInline.has(next.name)) {
2299
+ return pos;
2300
+ }
2301
+ const moveTo = dir < 0 ? next.from : next.to;
2302
+ if (limit != null && (dir < 0 ? moveTo < limit : moveTo > limit)) {
2303
+ return pos;
2304
+ }
2305
+ pos = moveTo;
2306
+ }
2307
+ };
2223
2308
  var snippets = {
2224
2309
  codeblock: snippet([
2225
2310
  //
@@ -2498,8 +2583,10 @@ var addList = (type) => ({ state, dispatch }) => {
2498
2583
  renumberListItems(next.firstChild, last.counter + 1, changes, state.doc);
2499
2584
  }
2500
2585
  }
2586
+ const changeSet = state.changes(changes);
2501
2587
  dispatch(state.update({
2502
- changes,
2588
+ changes: changeSet,
2589
+ selection: state.selection.map(changeSet, 1),
2503
2590
  userEvent: "format.list.add",
2504
2591
  scrollIntoView: true
2505
2592
  }));
@@ -2593,6 +2680,7 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
2593
2680
  const lines = [];
2594
2681
  let lastBlock = -1;
2595
2682
  for (const { from, to } of state.selection.ranges) {
2683
+ const sawBlock = false;
2596
2684
  syntaxTree2(state).iterate({
2597
2685
  from,
2598
2686
  to,
@@ -2602,9 +2690,9 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
2602
2690
  return false;
2603
2691
  }
2604
2692
  lastBlock = node.from;
2605
- let line = state.doc.lineAt(node.from);
2606
- if (line.number > 1) {
2607
- const prevLine = state.doc.line(line.number - 1);
2693
+ let line2 = state.doc.lineAt(node.from);
2694
+ if (line2.number > 1) {
2695
+ const prevLine = state.doc.line(line2.number - 1);
2608
2696
  if (/^[>\s]*$/.test(prevLine.text)) {
2609
2697
  if (!enable || lines.length && lines[lines.length - 1].number === prevLine.number - 1) {
2610
2698
  lines.push(prevLine);
@@ -2612,14 +2700,14 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
2612
2700
  }
2613
2701
  }
2614
2702
  for (; ; ) {
2615
- lines.push(line);
2616
- if (line.to >= node.to) {
2703
+ lines.push(line2);
2704
+ if (line2.to >= node.to) {
2617
2705
  break;
2618
2706
  }
2619
- line = state.doc.line(line.number + 1);
2707
+ line2 = state.doc.line(line2.number + 1);
2620
2708
  }
2621
- if (!enable && line.number < state.doc.lines) {
2622
- const nextLine = state.doc.line(line.number + 1);
2709
+ if (!enable && line2.number < state.doc.lines) {
2710
+ const nextLine = state.doc.line(line2.number + 1);
2623
2711
  if (/^[>\s]*$/.test(nextLine.text)) {
2624
2712
  lines.push(nextLine);
2625
2713
  }
@@ -2628,6 +2716,10 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
2628
2716
  }
2629
2717
  }
2630
2718
  });
2719
+ let line;
2720
+ if (!sawBlock && enable && from === to && !/\S/.test((line = state.doc.lineAt(from)).text)) {
2721
+ lines.push(line);
2722
+ }
2631
2723
  }
2632
2724
  const changes = [];
2633
2725
  for (const line of lines) {
@@ -2649,8 +2741,10 @@ var setBlockquote = (enable) => ({ state, dispatch }) => {
2649
2741
  if (!changes.length) {
2650
2742
  return false;
2651
2743
  }
2744
+ const changeSet = state.changes(changes);
2652
2745
  dispatch(state.update({
2653
- changes,
2746
+ changes: changeSet,
2747
+ selection: state.selection.map(changeSet, 1),
2654
2748
  userEvent: enable ? "format.blockquote.add" : "format.blockquote.remove",
2655
2749
  scrollIntoView: true
2656
2750
  }));
@@ -3024,7 +3118,7 @@ var getFormatting = (state) => {
3024
3118
  };
3025
3119
  var useFormattingState = () => {
3026
3120
  const [state, setState] = useState(null);
3027
- const observer = useMemo(() => EditorView10.updateListener.of((update2) => {
3121
+ const observer = useMemo(() => EditorView11.updateListener.of((update2) => {
3028
3122
  if (update2.docChanged || update2.selectionSet) {
3029
3123
  const newState = getFormatting(update2.state);
3030
3124
  if (!state || !compareFormatting(state, newState)) {
@@ -3089,8 +3183,8 @@ var heading2 = () => {
3089
3183
  // packages/ui/react-ui-editor/src/extensions/markdown/hr.ts
3090
3184
  import { syntaxTree as syntaxTree4 } from "@codemirror/language";
3091
3185
  import { RangeSetBuilder as RangeSetBuilder4 } from "@codemirror/state";
3092
- import { Decoration as Decoration7, EditorView as EditorView11, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
3093
- var styles5 = EditorView11.baseTheme({
3186
+ import { Decoration as Decoration7, EditorView as EditorView12, ViewPlugin as ViewPlugin6, WidgetType as WidgetType3 } from "@codemirror/view";
3187
+ var styles5 = EditorView12.baseTheme({
3094
3188
  "& .cm-hr": {
3095
3189
  // Note that block-level decorations should not have vertical margins,
3096
3190
  borderTop: `1px solid ${getToken("extend.colors.neutral.200")}`
@@ -3144,7 +3238,7 @@ var hr = () => {
3144
3238
  // packages/ui/react-ui-editor/src/extensions/markdown/image.ts
3145
3239
  import { syntaxTree as syntaxTree5 } from "@codemirror/language";
3146
3240
  import { StateField as StateField4 } from "@codemirror/state";
3147
- import { Decoration as Decoration8, EditorView as EditorView12, WidgetType as WidgetType4 } from "@codemirror/view";
3241
+ import { Decoration as Decoration8, EditorView as EditorView13, WidgetType as WidgetType4 } from "@codemirror/view";
3148
3242
  var image = (options = {}) => {
3149
3243
  return StateField4.define({
3150
3244
  create: (state) => {
@@ -3171,7 +3265,7 @@ var image = (options = {}) => {
3171
3265
  add: buildDecorations4(from, to, tr.state)
3172
3266
  });
3173
3267
  },
3174
- provide: (field) => EditorView12.decorations.from(field)
3268
+ provide: (field) => EditorView13.decorations.from(field)
3175
3269
  });
3176
3270
  };
3177
3271
  var buildDecorations4 = (from, to, state) => {
@@ -3353,12 +3447,12 @@ var buildDecorations5 = (view, options) => {
3353
3447
  // packages/ui/react-ui-editor/src/extensions/markdown/table.ts
3354
3448
  import { syntaxTree as syntaxTree7 } from "@codemirror/language";
3355
3449
  import { RangeSetBuilder as RangeSetBuilder6, StateField as StateField5 } from "@codemirror/state";
3356
- import { Decoration as Decoration10, EditorView as EditorView13, WidgetType as WidgetType6 } from "@codemirror/view";
3450
+ import { Decoration as Decoration10, EditorView as EditorView14, WidgetType as WidgetType6 } from "@codemirror/view";
3357
3451
  var table = (options = {}) => {
3358
3452
  return StateField5.define({
3359
3453
  create: (state) => update(state, options),
3360
3454
  update: (_, tr) => update(tr.state, options),
3361
- provide: (field) => EditorView13.decorations.from(field)
3455
+ provide: (field) => EditorView14.decorations.from(field)
3362
3456
  });
3363
3457
  };
3364
3458
  var update = (state, options) => {
@@ -3451,8 +3545,8 @@ var TableWidget = class extends WidgetType6 {
3451
3545
  // packages/ui/react-ui-editor/src/extensions/markdown/tasklist.ts
3452
3546
  import { syntaxTree as syntaxTree8 } from "@codemirror/language";
3453
3547
  import { RangeSetBuilder as RangeSetBuilder7 } from "@codemirror/state";
3454
- import { EditorView as EditorView14, Decoration as Decoration11, WidgetType as WidgetType7, ViewPlugin as ViewPlugin8 } from "@codemirror/view";
3455
- var styles6 = EditorView14.baseTheme({
3548
+ import { EditorView as EditorView15, Decoration as Decoration11, WidgetType as WidgetType7, ViewPlugin as ViewPlugin8 } from "@codemirror/view";
3549
+ var styles6 = EditorView15.baseTheme({
3456
3550
  "& .cm-task": {
3457
3551
  color: getToken("extend.colors.blue.500")
3458
3552
  },
@@ -3575,10 +3669,10 @@ var mention = ({ onSearch }) => {
3575
3669
  };
3576
3670
 
3577
3671
  // packages/ui/react-ui-editor/src/extensions/modes.ts
3578
- import { Facet as Facet4 } from "@codemirror/state";
3672
+ import { Facet as Facet5 } from "@codemirror/state";
3579
3673
  import { keymap as keymap6 } from "@codemirror/view";
3580
3674
  import { vim } from "@replit/codemirror-vim";
3581
- var editorMode = Facet4.define({
3675
+ var editorMode = Facet5.define({
3582
3676
  combine: (modes) => modes[0] ?? {}
3583
3677
  });
3584
3678
  var EditorModes = {
@@ -3942,7 +4036,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
3942
4036
  selection,
3943
4037
  extensions: [
3944
4038
  // TODO(burdon): Doesn't catch errors in keymap functions.
3945
- EditorView15.exceptionSink.of((err) => {
4039
+ EditorView16.exceptionSink.of((err) => {
3946
4040
  log3.catch(err, void 0, {
3947
4041
  F: __dxlog_file4,
3948
4042
  L: 113,
@@ -3952,17 +4046,17 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
3952
4046
  }),
3953
4047
  // Theme.
3954
4048
  // TODO(burdon): Make configurable.
3955
- EditorView15.baseTheme(defaultTheme),
3956
- EditorView15.theme(theme ?? {}),
3957
- EditorView15.darkTheme.of(themeMode === "dark"),
3958
- EditorView15.editorAttributes.of({
4049
+ EditorView16.baseTheme(defaultTheme),
4050
+ EditorView16.theme(theme ?? {}),
4051
+ EditorView16.darkTheme.of(themeMode === "dark"),
4052
+ EditorView16.editorAttributes.of({
3959
4053
  class: slots.editor?.className ?? ""
3960
4054
  }),
3961
- EditorView15.contentAttributes.of({
4055
+ EditorView16.contentAttributes.of({
3962
4056
  class: slots.content?.className ?? ""
3963
4057
  }),
3964
4058
  // Focus.
3965
- EditorView15.updateListener.of((update2) => {
4059
+ EditorView16.updateListener.of((update2) => {
3966
4060
  update2.transactions.forEach((transaction) => {
3967
4061
  if (transaction.isUserEvent("focus.container")) {
3968
4062
  rootRef.current?.focus();
@@ -3970,7 +4064,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
3970
4064
  });
3971
4065
  }),
3972
4066
  // State.
3973
- EditorView15.editable.of(!readonly),
4067
+ EditorView16.editable.of(!readonly),
3974
4068
  EditorState2.readOnly.of(!!readonly),
3975
4069
  // Storage and replication.
3976
4070
  // NOTE: This must come before user extensions.
@@ -3979,7 +4073,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
3979
4073
  ...extensions
3980
4074
  ].filter(isNotFalsy4)
3981
4075
  });
3982
- const newView = new EditorView15({
4076
+ const newView = new EditorView16({
3983
4077
  state,
3984
4078
  parent: rootRef.current,
3985
4079
  scrollTo,
@@ -4301,8 +4395,7 @@ var markdownBlocks = [
4301
4395
  {
4302
4396
  type: "codeblock",
4303
4397
  Icon: CodeBlock,
4304
- getState: (state) => state.blockType === "codeblock",
4305
- disabled: (state) => !state.blankLine
4398
+ getState: (state) => state.blockType === "codeblock"
4306
4399
  },
4307
4400
  {
4308
4401
  type: "table",
@@ -4535,7 +4628,7 @@ var useEditorView = (id) => {
4535
4628
 
4536
4629
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
4537
4630
  import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
4538
- import { EditorView as EditorView16 } from "@codemirror/view";
4631
+ import { EditorView as EditorView17 } from "@codemirror/view";
4539
4632
  import { useEffect as useEffect3, useRef as useRef3, useState as useState4 } from "react";
4540
4633
  import { log as log5 } from "@dxos/log";
4541
4634
  import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
@@ -4552,7 +4645,7 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
4552
4645
  selection,
4553
4646
  extensions: [
4554
4647
  // TODO(burdon): Doesn't catch errors in keymap functions.
4555
- EditorView16.exceptionSink.of((err) => {
4648
+ EditorView17.exceptionSink.of((err) => {
4556
4649
  log5.catch(err, void 0, {
4557
4650
  F: __dxlog_file6,
4558
4651
  L: 60,
@@ -4561,12 +4654,12 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
4561
4654
  });
4562
4655
  }),
4563
4656
  extensions,
4564
- EditorView16.updateListener.of(() => {
4657
+ EditorView17.updateListener.of(() => {
4565
4658
  onUpdate.current?.();
4566
4659
  })
4567
4660
  ].filter(isNotFalsy5)
4568
4661
  });
4569
- view2 = new EditorView16({
4662
+ view2 = new EditorView17({
4570
4663
  parent: parentRef.current,
4571
4664
  scrollTo,
4572
4665
  state,
@@ -4624,19 +4717,19 @@ var createDataExtensions = ({ readonly = false } = {}) => {
4624
4717
  return [
4625
4718
  //
4626
4719
  EditorState3.readOnly.of(readonly),
4627
- EditorView16.editable.of(!readonly)
4720
+ EditorView17.editable.of(!readonly)
4628
4721
  ];
4629
4722
  };
4630
4723
  var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
4631
4724
  return [
4632
4725
  //
4633
- EditorView16.baseTheme(defaultTheme),
4634
- theme && EditorView16.theme(theme),
4635
- EditorView16.darkTheme.of(themeMode === "dark"),
4636
- EditorView16.editorAttributes.of({
4726
+ EditorView17.baseTheme(defaultTheme),
4727
+ theme && EditorView17.theme(theme),
4728
+ EditorView17.darkTheme.of(themeMode === "dark"),
4729
+ EditorView17.editorAttributes.of({
4637
4730
  class: slots?.editor?.className ?? ""
4638
4731
  }),
4639
- EditorView16.contentAttributes.of({
4732
+ EditorView17.contentAttributes.of({
4640
4733
  class: slots?.content?.className ?? ""
4641
4734
  })
4642
4735
  ].filter(isNotFalsy5);
@@ -4745,6 +4838,8 @@ export {
4745
4838
  createDataExtensions,
4746
4839
  createMarkdownExtensions,
4747
4840
  createThemeExtensions,
4841
+ cursorLineMargin,
4842
+ cursorLineMarginFacet,
4748
4843
  defaultMarkdownSlots,
4749
4844
  defaultOptions,
4750
4845
  defaultSlots,