@dxos/react-ui-editor 0.6.10 → 0.6.11-staging.32b42e4

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 (36) hide show
  1. package/dist/lib/browser/index.mjs +122 -83
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/InputMode.stories.d.ts.map +1 -1
  5. package/dist/types/src/TextEditor.stories.d.ts +10 -2
  6. package/dist/types/src/TextEditor.stories.d.ts.map +1 -1
  7. package/dist/types/src/defaults.d.ts.map +1 -1
  8. package/dist/types/src/extensions/automerge/automerge.stories.d.ts +0 -1
  9. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  10. package/dist/types/src/extensions/comments.d.ts +1 -1
  11. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  12. package/dist/types/src/extensions/factories.d.ts +5 -1
  13. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  14. package/dist/types/src/extensions/folding.d.ts.map +1 -1
  15. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
  16. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  17. package/dist/types/src/extensions/util/react.d.ts +4 -0
  18. package/dist/types/src/extensions/util/react.d.ts.map +1 -1
  19. package/dist/types/src/hooks/useTextEditor.d.ts +2 -2
  20. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  21. package/dist/types/src/styles/markdown.d.ts.map +1 -1
  22. package/dist/types/src/styles/theme.d.ts.map +1 -1
  23. package/package.json +24 -24
  24. package/src/InputMode.stories.tsx +8 -10
  25. package/src/TextEditor.stories.tsx +58 -32
  26. package/src/defaults.ts +5 -4
  27. package/src/extensions/automerge/automerge.stories.tsx +5 -6
  28. package/src/extensions/comments.ts +3 -11
  29. package/src/extensions/factories.ts +15 -4
  30. package/src/extensions/folding.tsx +17 -4
  31. package/src/extensions/markdown/bundle.ts +1 -5
  32. package/src/extensions/markdown/decorate.ts +31 -20
  33. package/src/extensions/util/react.tsx +15 -0
  34. package/src/hooks/useTextEditor.ts +3 -5
  35. package/src/styles/markdown.ts +0 -2
  36. package/src/styles/theme.ts +12 -8
@@ -1389,6 +1389,18 @@ import React from "react";
1389
1389
  import { createRoot } from "react-dom/client";
1390
1390
  import { ThemeProvider } from "@dxos/react-ui";
1391
1391
  import { defaultTx } from "@dxos/react-ui-theme";
1392
+ var createElement = (tag, options, children) => {
1393
+ const el = document.createElement(tag);
1394
+ if (options?.className) {
1395
+ el.className = options.className;
1396
+ }
1397
+ if (children) {
1398
+ el.append(...Array.isArray(children) ? children : [
1399
+ children
1400
+ ]);
1401
+ }
1402
+ return el;
1403
+ };
1392
1404
  var renderRoot = (root, node) => {
1393
1405
  createRoot(root).render(/* @__PURE__ */ React.createElement(ThemeProvider, {
1394
1406
  tx: defaultTx
@@ -1666,22 +1678,12 @@ var createComment = (view) => {
1666
1678
  to
1667
1679
  });
1668
1680
  if (cursor) {
1669
- const id = options.onCreate?.({
1681
+ options.onCreate?.({
1670
1682
  cursor,
1671
1683
  from,
1672
1684
  location: view.coordsAtPos(from)
1673
1685
  });
1674
- if (id) {
1675
- view.dispatch({
1676
- effects: setSelection.of({
1677
- current: id
1678
- }),
1679
- selection: {
1680
- anchor: to
1681
- }
1682
- });
1683
- return true;
1684
- }
1686
+ return true;
1685
1687
  }
1686
1688
  return false;
1687
1689
  };
@@ -1991,9 +1993,10 @@ var dropFile = (options = {}) => {
1991
1993
  // packages/ui/react-ui-editor/src/extensions/factories.ts
1992
1994
  import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
1993
1995
  import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
1994
- import { bracketMatching } from "@codemirror/language";
1996
+ import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
1995
1997
  import { searchKeymap } from "@codemirror/search";
1996
1998
  import { EditorState } from "@codemirror/state";
1999
+ import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
1997
2000
  import { EditorView as EditorView9, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap5, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
1998
2001
  import defaultsDeep2 from "lodash.defaultsdeep";
1999
2002
  import merge from "lodash.merge";
@@ -2062,15 +2065,19 @@ var defaultTheme = {
2062
2065
  * NOTE: Gutters should have the same top margin as the content.
2063
2066
  */
2064
2067
  ".cm-gutters": {
2065
- background: "unset"
2068
+ background: "var(--surface-bg)"
2066
2069
  },
2067
2070
  ".cm-gutter": {},
2068
- ".cm-gutterElement": {
2069
- fontSize: "16px",
2070
- lineHeight: 1.5
2071
+ ".cm-gutter.cm-lineNumbers .cm-gutterElement": {
2072
+ minWidth: "40px",
2073
+ alignContent: "center"
2071
2074
  },
2072
- ".cm-lineNumbers": {
2073
- minWidth: "36px"
2075
+ /**
2076
+ * Height is set to match the corresponding line.
2077
+ */
2078
+ ".cm-gutterElement": {
2079
+ alignItems: "center",
2080
+ fontSize: "16px"
2074
2081
  },
2075
2082
  /**
2076
2083
  * Line.
@@ -2178,13 +2185,14 @@ var defaultTheme = {
2178
2185
  * </div>
2179
2186
  * </div
2180
2187
  */
2181
- // TODO(burdon): Apply react-ui-theme or replace panel.
2188
+ // TODO(burdon): Implement custom panel (with icon buttons).
2182
2189
  ".cm-panels": {},
2183
2190
  ".cm-panel": {
2184
2191
  fontFamily: fontBody,
2185
- backgroundColor: "var(--dx-base)"
2192
+ backgroundColor: "var(--surface-bg)"
2186
2193
  },
2187
2194
  ".cm-panel input, .cm-panel button, .cm-panel label": {
2195
+ color: "var(--dx-subdued)",
2188
2196
  fontFamily: fontBody,
2189
2197
  fontSize: "14px",
2190
2198
  all: "unset",
@@ -2252,7 +2260,7 @@ var createBasicExtensions = (_props) => {
2252
2260
  EditorView9.exceptionSink.of((err) => {
2253
2261
  log6.catch(err, void 0, {
2254
2262
  F: __dxlog_file9,
2255
- L: 92,
2263
+ L: 93,
2256
2264
  S: void 0,
2257
2265
  C: (f, a) => f(...a)
2258
2266
  });
@@ -2297,11 +2305,13 @@ var defaultThemeSlots = {
2297
2305
  className: "w-full bs-full"
2298
2306
  }
2299
2307
  };
2300
- var createThemeExtensions = ({ themeMode, styles: styles5, slots: _slots } = {}) => {
2308
+ var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
2301
2309
  const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
2302
2310
  return [
2303
2311
  EditorView9.darkTheme.of(themeMode === "dark"),
2304
2312
  EditorView9.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2313
+ // https://github.com/codemirror/theme-one-dark
2314
+ _syntaxHighlighting && (themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)),
2305
2315
  slots.editor?.className && EditorView9.editorAttributes.of({
2306
2316
  class: slots.editor.className
2307
2317
  }),
@@ -2334,36 +2344,50 @@ var createDataExtensions = ({ id, text, space, identity }) => {
2334
2344
 
2335
2345
  // packages/ui/react-ui-editor/src/extensions/folding.tsx
2336
2346
  import { codeFolding, foldGutter } from "@codemirror/language";
2347
+ import { EditorView as EditorView10 } from "@codemirror/view";
2337
2348
  import React2 from "react";
2338
2349
  import { Icon } from "@dxos/react-ui";
2339
2350
  import { getSize } from "@dxos/react-ui-theme";
2340
2351
  var folding = (_props = {}) => [
2341
2352
  codeFolding({
2342
- placeholderDOM: () => document.createElement("div")
2353
+ placeholderDOM: () => {
2354
+ return document.createElement("span");
2355
+ }
2343
2356
  }),
2344
2357
  foldGutter({
2345
2358
  markerDOM: (open) => {
2346
- return renderRoot(document.createElement("div"), /* @__PURE__ */ React2.createElement(Icon, {
2359
+ return renderRoot(createElement("div", {
2360
+ className: "flex h-full items-center"
2361
+ }), /* @__PURE__ */ React2.createElement(Icon, {
2347
2362
  icon: "ph--caret-right--regular",
2348
2363
  classNames: [
2349
2364
  getSize(3),
2350
- "m-2 cursor-pointer",
2365
+ "mx-3 cursor-pointer",
2351
2366
  open && "rotate-90"
2352
2367
  ]
2353
2368
  }));
2354
2369
  }
2370
+ }),
2371
+ EditorView10.theme({
2372
+ ".cm-foldGutter": {
2373
+ opacity: 0.3,
2374
+ transition: "opacity 0.3s"
2375
+ },
2376
+ ".cm-foldGutter:hover": {
2377
+ opacity: 1
2378
+ }
2355
2379
  })
2356
2380
  ];
2357
2381
 
2358
2382
  // packages/ui/react-ui-editor/src/extensions/listener.ts
2359
- import { EditorView as EditorView10 } from "@codemirror/view";
2383
+ import { EditorView as EditorView11 } from "@codemirror/view";
2360
2384
  var listener = ({ onFocus, onChange }) => {
2361
2385
  const extensions = [];
2362
- onFocus && extensions.push(EditorView10.focusChangeEffect.of((_, focusing) => {
2386
+ onFocus && extensions.push(EditorView11.focusChangeEffect.of((_, focusing) => {
2363
2387
  onFocus(focusing);
2364
2388
  return null;
2365
2389
  }));
2366
- onChange && extensions.push(EditorView10.updateListener.of((update2) => {
2390
+ onChange && extensions.push(EditorView11.updateListener.of((update2) => {
2367
2391
  onChange(update2.state.doc.toString());
2368
2392
  }));
2369
2393
  return extensions;
@@ -2373,7 +2397,7 @@ var listener = ({ onFocus, onChange }) => {
2373
2397
  import { snippet } from "@codemirror/autocomplete";
2374
2398
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
2375
2399
  import { EditorSelection } from "@codemirror/state";
2376
- import { EditorView as EditorView11, keymap as keymap6 } from "@codemirror/view";
2400
+ import { EditorView as EditorView12, keymap as keymap6 } from "@codemirror/view";
2377
2401
  import { useMemo as useMemo2, useState as useState2 } from "react";
2378
2402
  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;
2379
2403
  var Inline;
@@ -3463,7 +3487,7 @@ var getFormatting = (state2) => {
3463
3487
  };
3464
3488
  var useFormattingState = () => {
3465
3489
  const [state2, setState] = useState2();
3466
- const observer = useMemo2(() => EditorView11.updateListener.of((update2) => {
3490
+ const observer = useMemo2(() => EditorView12.updateListener.of((update2) => {
3467
3491
  if (update2.docChanged || update2.selectionSet) {
3468
3492
  setState((prevState) => {
3469
3493
  const newState = getFormatting(update2.state);
@@ -3533,10 +3557,9 @@ var processAction = (view, action) => {
3533
3557
  import { completionKeymap as completionKeymap2 } from "@codemirror/autocomplete";
3534
3558
  import { defaultKeymap as defaultKeymap2, indentWithTab as indentWithTab2 } from "@codemirror/commands";
3535
3559
  import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
3536
- import { defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
3560
+ import { syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
3537
3561
  import { languages } from "@codemirror/language-data";
3538
3562
  import { lintKeymap } from "@codemirror/lint";
3539
- import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
3540
3563
  import { keymap as keymap7 } from "@codemirror/view";
3541
3564
 
3542
3565
  // packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
@@ -3747,10 +3770,8 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
3747
3770
  markdownTagsExtensions
3748
3771
  ]
3749
3772
  }),
3750
- // https://github.com/codemirror/theme-one-dark
3751
- themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle),
3752
3773
  // Custom styles.
3753
- syntaxHighlighting(markdownHighlightStyle()),
3774
+ syntaxHighlighting2(markdownHighlightStyle()),
3754
3775
  keymap7.of([
3755
3776
  // https://codemirror.net/docs/ref/#commands.indentWithTab
3756
3777
  indentWithTab2,
@@ -3792,7 +3813,7 @@ var convertTreeToJson = (state2) => {
3792
3813
  // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
3793
3814
  import { syntaxTree as syntaxTree7 } from "@codemirror/language";
3794
3815
  import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect4 } from "@codemirror/state";
3795
- import { EditorView as EditorView15, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
3816
+ import { EditorView as EditorView16, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
3796
3817
  import { invariant as invariant4 } from "@dxos/invariant";
3797
3818
  import { mx as mx2 } from "@dxos/react-ui-theme";
3798
3819
 
@@ -3808,6 +3829,9 @@ var adjustChanges = () => {
3808
3829
  for (const tr of update2.transactions) {
3809
3830
  const event = tr.annotation(Transaction.userEvent);
3810
3831
  switch (event) {
3832
+ //
3833
+ // Enter
3834
+ //
3811
3835
  case "input": {
3812
3836
  const changes = tr.changes;
3813
3837
  if (changes.empty) {
@@ -3828,6 +3852,9 @@ var adjustChanges = () => {
3828
3852
  });
3829
3853
  break;
3830
3854
  }
3855
+ //
3856
+ // Paste
3857
+ //
3831
3858
  case "input.paste": {
3832
3859
  const changes = tr.changes;
3833
3860
  if (changes.empty) {
@@ -3937,7 +3964,7 @@ var getValidUrl = (str) => {
3937
3964
  // packages/ui/react-ui-editor/src/extensions/markdown/image.ts
3938
3965
  import { syntaxTree as syntaxTree5 } from "@codemirror/language";
3939
3966
  import { StateField as StateField7 } from "@codemirror/state";
3940
- import { Decoration as Decoration5, EditorView as EditorView12, WidgetType as WidgetType3 } from "@codemirror/view";
3967
+ import { Decoration as Decoration5, EditorView as EditorView13, WidgetType as WidgetType3 } from "@codemirror/view";
3941
3968
  var image = (_options = {}) => {
3942
3969
  return StateField7.define({
3943
3970
  create: (state2) => {
@@ -3964,7 +3991,7 @@ var image = (_options = {}) => {
3964
3991
  add: buildDecorations(from, to, tr.state)
3965
3992
  });
3966
3993
  },
3967
- provide: (field) => EditorView12.decorations.from(field)
3994
+ provide: (field) => EditorView13.decorations.from(field)
3968
3995
  });
3969
3996
  };
3970
3997
  var preloaded = /* @__PURE__ */ new Set();
@@ -4018,10 +4045,10 @@ var imageUpload = (options = {}) => {
4018
4045
  };
4019
4046
 
4020
4047
  // packages/ui/react-ui-editor/src/extensions/markdown/styles.ts
4021
- import { EditorView as EditorView13 } from "@codemirror/view";
4048
+ import { EditorView as EditorView14 } from "@codemirror/view";
4022
4049
  var bulletListIndentationWidth = 24;
4023
4050
  var orderedListIndentationWidth = 36;
4024
- var formattingStyles = EditorView13.theme({
4051
+ var formattingStyles = EditorView14.theme({
4025
4052
  /**
4026
4053
  * Horizontal rule.
4027
4054
  */
@@ -4112,12 +4139,12 @@ var formattingStyles = EditorView13.theme({
4112
4139
  // packages/ui/react-ui-editor/src/extensions/markdown/table.ts
4113
4140
  import { syntaxTree as syntaxTree6 } from "@codemirror/language";
4114
4141
  import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField8 } from "@codemirror/state";
4115
- import { Decoration as Decoration6, EditorView as EditorView14, WidgetType as WidgetType4 } from "@codemirror/view";
4142
+ import { Decoration as Decoration6, EditorView as EditorView15, WidgetType as WidgetType4 } from "@codemirror/view";
4116
4143
  var table = (options = {}) => {
4117
4144
  return StateField8.define({
4118
4145
  create: (state2) => update(state2, options),
4119
4146
  update: (_, tr) => update(tr.state, options),
4120
- provide: (field) => EditorView14.decorations.from(field)
4147
+ provide: (field) => EditorView15.decorations.from(field)
4121
4148
  });
4122
4149
  };
4123
4150
  var update = (state2, _options) => {
@@ -4210,6 +4237,12 @@ var TableWidget = class extends WidgetType4 {
4210
4237
 
4211
4238
  // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
4212
4239
  var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts";
4240
+ var Unicode = {
4241
+ emDash: "\u2014",
4242
+ bullet: "\u2022",
4243
+ bulletSmall: "\u2219",
4244
+ bulletSquare: "\u2B1D"
4245
+ };
4213
4246
  var HorizontalRuleWidget = class extends WidgetType5 {
4214
4247
  toDOM() {
4215
4248
  const el = document.createElement("span");
@@ -4330,7 +4363,7 @@ var buildDecorations2 = (view, options, focus) => {
4330
4363
  const getHeaderLevels = (node, level) => {
4331
4364
  invariant4(level > 0, void 0, {
4332
4365
  F: __dxlog_file10,
4333
- L: 157,
4366
+ L: 170,
4334
4367
  S: void 0,
4335
4368
  A: [
4336
4369
  "level > 0",
@@ -4369,7 +4402,7 @@ var buildDecorations2 = (view, options, focus) => {
4369
4402
  const getCurrentListLevel = () => {
4370
4403
  invariant4(listLevels.length, void 0, {
4371
4404
  F: __dxlog_file10,
4372
- L: 179,
4405
+ L: 192,
4373
4406
  S: void 0,
4374
4407
  A: [
4375
4408
  "listLevels.length",
@@ -4380,6 +4413,9 @@ var buildDecorations2 = (view, options, focus) => {
4380
4413
  };
4381
4414
  const enterNode = (node) => {
4382
4415
  switch (node.name) {
4416
+ // ATXHeading > HeaderMark > Paragraph
4417
+ // NOTE: Numbering requires processing the entire document since otherwise only the visible range will be
4418
+ // processed and the numbering will be incorrect.
4383
4419
  case "ATXHeading1":
4384
4420
  case "ATXHeading2":
4385
4421
  case "ATXHeading3":
@@ -4413,16 +4449,20 @@ var buildDecorations2 = (view, options, focus) => {
4413
4449
  }
4414
4450
  return false;
4415
4451
  }
4452
+ //
4453
+ // Lists.
4454
+ // [BulletList | OrderedList] > (ListItem > ListMark) > (Task > TaskMarker)?
4455
+ //
4416
4456
  case "BulletList":
4417
4457
  case "OrderedList": {
4418
4458
  enterList(node);
4419
4459
  break;
4420
4460
  }
4421
4461
  case "ListItem": {
4462
+ const line = state2.doc.lineAt(node.from);
4422
4463
  const list = getCurrentListLevel();
4423
4464
  const width = list.type === "OrderedList" ? orderedListIndentationWidth : bulletListIndentationWidth;
4424
4465
  const offset = ((list.level ?? 0) + 1) * width;
4425
- const line = state2.doc.lineAt(node.from);
4426
4466
  if (node.from === line.to - 1) {
4427
4467
  return false;
4428
4468
  }
@@ -4432,33 +4472,30 @@ var buildDecorations2 = (view, options, focus) => {
4432
4472
  style: `padding-left: ${offset}px; text-indent: -${width}px;`
4433
4473
  }
4434
4474
  }));
4435
- const text = state2.doc.sliceString(line.from, node.to);
4436
- const whitespace = text.match(/^ */)?.[0].length ?? 0;
4437
- if (whitespace) {
4438
- atomicDeco.add(line.from, line.from + whitespace, hide);
4439
- }
4440
4475
  break;
4441
4476
  }
4442
4477
  case "ListMark": {
4478
+ const list = getCurrentListLevel();
4443
4479
  const next = tree.resolve(node.to + 1, 1);
4444
4480
  if (next?.name === "TaskMarker") {
4445
- atomicDeco.add(node.from, node.to + 1, hide);
4446
4481
  break;
4447
4482
  }
4448
- const list = getCurrentListLevel();
4449
- const label = list.type === "OrderedList" ? `${++list.number}.` : "\u2022";
4450
- atomicDeco.add(node.from, node.to + 1, Decoration7.replace({
4483
+ const label = list.type === "OrderedList" ? `${++list.number}.` : Unicode.bulletSmall;
4484
+ const line = state2.doc.lineAt(node.from);
4485
+ const to = state2.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
4486
+ atomicDeco.add(line.from, to, Decoration7.replace({
4451
4487
  widget: new TextWidget(label, list.type === "OrderedList" ? "cm-list-mark cm-list-mark-ordered" : "cm-list-mark cm-list-mark-bullet")
4452
4488
  }));
4453
4489
  break;
4454
4490
  }
4455
4491
  case "TaskMarker": {
4456
- if (!editingRange(state2, node, focus)) {
4457
- const checked = state2.doc.sliceString(node.from + 1, node.to - 1) === "x";
4458
- atomicDeco.add(node.from, node.to + 1, checked ? checkedTask : uncheckedTask);
4459
- }
4492
+ const checked = state2.doc.sliceString(node.from + 1, node.to - 1) === "x";
4493
+ const line = state2.doc.lineAt(node.from);
4494
+ const to = state2.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
4495
+ atomicDeco.add(line.from, to, checked ? checkedTask : uncheckedTask);
4460
4496
  break;
4461
4497
  }
4498
+ // CommentBlock
4462
4499
  case "CommentBlock": {
4463
4500
  const editing = editingRange(state2, node, focus);
4464
4501
  for (const block of view.viewportLineBlocks) {
@@ -4477,6 +4514,7 @@ var buildDecorations2 = (view, options, focus) => {
4477
4514
  }
4478
4515
  break;
4479
4516
  }
4517
+ // FencedCode > CodeMark > [CodeInfo] > CodeText > CodeMark
4480
4518
  case "FencedCode": {
4481
4519
  for (const block of view.viewportLineBlocks) {
4482
4520
  if (block.to < node.from) {
@@ -4495,6 +4533,7 @@ var buildDecorations2 = (view, options, focus) => {
4495
4533
  }
4496
4534
  return false;
4497
4535
  }
4536
+ // Link > [LinkMark, URL]
4498
4537
  case "Link": {
4499
4538
  const marks = node.node.getChildren("LinkMark");
4500
4539
  const urlNode = node.node.getChild("URL");
@@ -4521,6 +4560,7 @@ var buildDecorations2 = (view, options, focus) => {
4521
4560
  }
4522
4561
  break;
4523
4562
  }
4563
+ // HR
4524
4564
  case "HorizontalRule": {
4525
4565
  if (!editingRange(state2, node, focus)) {
4526
4566
  deco.add(node.from, node.to, horizontalRule);
@@ -4601,9 +4641,9 @@ var decorateMarkdown = (options = {}) => {
4601
4641
  }
4602
4642
  }, {
4603
4643
  provide: (plugin) => [
4604
- EditorView15.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4605
- EditorView15.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4606
- EditorView15.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
4644
+ EditorView16.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4645
+ EditorView16.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4646
+ EditorView16.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
4607
4647
  ]
4608
4648
  }),
4609
4649
  image(),
@@ -4736,7 +4776,7 @@ var InputModeExtensions = {
4736
4776
 
4737
4777
  // packages/ui/react-ui-editor/src/extensions/state.ts
4738
4778
  import { Transaction as Transaction2 } from "@codemirror/state";
4739
- import { EditorView as EditorView16, keymap as keymap9 } from "@codemirror/view";
4779
+ import { EditorView as EditorView17, keymap as keymap9 } from "@codemirror/view";
4740
4780
  import { debounce as debounce2 } from "@dxos/async";
4741
4781
  import { invariant as invariant5 } from "@dxos/invariant";
4742
4782
  import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
@@ -4774,7 +4814,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
4774
4814
  return {
4775
4815
  selection,
4776
4816
  scrollIntoView: !scrollTo,
4777
- effects: scrollTo ? EditorView16.scrollIntoView(scrollTo, {
4817
+ effects: scrollTo ? EditorView17.scrollIntoView(scrollTo, {
4778
4818
  yMargin: 96
4779
4819
  }) : void 0,
4780
4820
  annotations: Transaction2.userEvent.of(stateRestoreAnnotation)
@@ -4789,7 +4829,7 @@ var state = ({ getState, setState } = {}) => {
4789
4829
  // setStateDebounced(id, {});
4790
4830
  // },
4791
4831
  // }),
4792
- EditorView16.updateListener.of(({ view, transactions }) => {
4832
+ EditorView17.updateListener.of(({ view, transactions }) => {
4793
4833
  const id = view.state.facet(documentId2);
4794
4834
  if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
4795
4835
  return;
@@ -5269,19 +5309,20 @@ var Toolbar = {
5269
5309
  };
5270
5310
 
5271
5311
  // packages/ui/react-ui-editor/src/defaults.ts
5272
- import { EditorView as EditorView17 } from "@codemirror/view";
5312
+ import { EditorView as EditorView18 } from "@codemirror/view";
5273
5313
  import { mx as mx3 } from "@dxos/react-ui-theme";
5274
- var margin = "!mt-[16px]";
5275
- var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
5276
- var editorFullWidth = mx3(margin, "!ml-[3rem]");
5314
+ var margin = "!mt-[1rem]";
5315
+ var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-4rem)]");
5316
+ var editorFullWidth = mx3(margin);
5277
5317
  var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
5278
- var editorGutter = EditorView17.theme({
5318
+ var editorGutter = EditorView18.theme({
5279
5319
  // Match margin from content.
5280
5320
  ".cm-gutters": {
5281
- marginTop: "16px"
5321
+ marginTop: "16px",
5322
+ paddingRight: "2rem"
5282
5323
  }
5283
5324
  });
5284
- var editorMonospace = EditorView17.theme({
5325
+ var editorMonospace = EditorView18.theme({
5285
5326
  ".cm-content": {
5286
5327
  fontFamily: fontMono
5287
5328
  }
@@ -5294,17 +5335,15 @@ var useActionHandler = (view) => {
5294
5335
 
5295
5336
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
5296
5337
  import { EditorState as EditorState2 } from "@codemirror/state";
5297
- import { EditorView as EditorView18 } from "@codemirror/view";
5338
+ import { EditorView as EditorView19 } from "@codemirror/view";
5298
5339
  import { useFocusableGroup } from "@fluentui/react-tabster";
5299
5340
  import { useCallback, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2, useState as useState4 } from "react";
5300
5341
  import { log as log8 } from "@dxos/log";
5301
- import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
5342
+ import { getProviderValue, isNotFalsy as isNotFalsy4 } from "@dxos/util";
5302
5343
  var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
5303
5344
  var instanceCount = 0;
5304
5345
  var useTextEditor = (props = {}, deps = []) => {
5305
- const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo3(() => {
5306
- return typeof props === "function" ? props() : props;
5307
- }, deps ?? []);
5346
+ const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo3(() => getProviderValue(props), deps ?? []);
5308
5347
  const [instanceId] = useState4(() => `text-editor-${++instanceCount}`);
5309
5348
  const onUpdate = useRef2();
5310
5349
  const [view, setView] = useState4();
@@ -5318,7 +5357,7 @@ var useTextEditor = (props = {}, deps = []) => {
5318
5357
  doc: initialValue?.length ?? 0
5319
5358
  }, {
5320
5359
  F: __dxlog_file13,
5321
- L: 78,
5360
+ L: 76,
5322
5361
  S: void 0,
5323
5362
  C: (f, a) => f(...a)
5324
5363
  });
@@ -5340,23 +5379,23 @@ var useTextEditor = (props = {}, deps = []) => {
5340
5379
  extensions: [
5341
5380
  id && documentId2.of(id),
5342
5381
  // NOTE: Doesn't catch errors in keymap functions.
5343
- EditorView18.exceptionSink.of((err) => {
5382
+ EditorView19.exceptionSink.of((err) => {
5344
5383
  log8.catch(err, void 0, {
5345
5384
  F: __dxlog_file13,
5346
- L: 100,
5385
+ L: 98,
5347
5386
  S: void 0,
5348
5387
  C: (f, a) => f(...a)
5349
5388
  });
5350
5389
  }),
5351
5390
  extensions,
5352
- EditorView18.updateListener.of(() => {
5391
+ EditorView19.updateListener.of(() => {
5353
5392
  setTimeout(() => {
5354
5393
  onUpdate.current?.();
5355
5394
  });
5356
5395
  })
5357
5396
  ].filter(isNotFalsy4)
5358
5397
  });
5359
- view2 = new EditorView18({
5398
+ view2 = new EditorView19({
5360
5399
  parent: parentRef.current,
5361
5400
  selection: initialSelection,
5362
5401
  state: state2,
@@ -5384,7 +5423,7 @@ var useTextEditor = (props = {}, deps = []) => {
5384
5423
  id
5385
5424
  }, {
5386
5425
  F: __dxlog_file13,
5387
- L: 136,
5426
+ L: 134,
5388
5427
  S: void 0,
5389
5428
  C: (f, a) => f(...a)
5390
5429
  });