@dxos/react-ui-editor 0.8.1 → 0.8.2-main.f081794

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 (112) hide show
  1. package/dist/lib/browser/index.mjs +499 -371
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/browser/testing/index.mjs +67 -0
  5. package/dist/lib/browser/testing/index.mjs.map +7 -0
  6. package/dist/lib/node/index.cjs +515 -379
  7. package/dist/lib/node/index.cjs.map +4 -4
  8. package/dist/lib/node/meta.json +1 -1
  9. package/dist/lib/node/testing/index.cjs +101 -0
  10. package/dist/lib/node/testing/index.cjs.map +7 -0
  11. package/dist/lib/node-esm/index.mjs +499 -371
  12. package/dist/lib/node-esm/index.mjs.map +4 -4
  13. package/dist/lib/node-esm/meta.json +1 -1
  14. package/dist/lib/node-esm/testing/index.mjs +69 -0
  15. package/dist/lib/node-esm/testing/index.mjs.map +7 -0
  16. package/dist/types/src/components/EditorToolbar/util.d.ts +3 -3
  17. package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -1
  18. package/dist/types/src/components/EditorToolbar/{viewMode.d.ts → view-mode.d.ts} +1 -1
  19. package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -0
  20. package/dist/types/src/defaults.d.ts +1 -0
  21. package/dist/types/src/defaults.d.ts.map +1 -1
  22. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  23. package/dist/types/src/extensions/command/action.d.ts +17 -0
  24. package/dist/types/src/extensions/command/action.d.ts.map +1 -0
  25. package/dist/types/src/extensions/command/command.d.ts +5 -10
  26. package/dist/types/src/extensions/command/command.d.ts.map +1 -1
  27. package/dist/types/src/extensions/command/hint.d.ts +4 -2
  28. package/dist/types/src/extensions/command/hint.d.ts.map +1 -1
  29. package/dist/types/src/extensions/command/index.d.ts +1 -0
  30. package/dist/types/src/extensions/command/index.d.ts.map +1 -1
  31. package/dist/types/src/extensions/command/menu.d.ts +7 -2
  32. package/dist/types/src/extensions/command/menu.d.ts.map +1 -1
  33. package/dist/types/src/extensions/command/state.d.ts +9 -11
  34. package/dist/types/src/extensions/command/state.d.ts.map +1 -1
  35. package/dist/types/src/extensions/comments.d.ts +9 -7
  36. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  37. package/dist/types/src/extensions/index.d.ts +1 -0
  38. package/dist/types/src/extensions/index.d.ts.map +1 -1
  39. package/dist/types/src/extensions/markdown/decorate.d.ts +4 -1
  40. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  41. package/dist/types/src/extensions/markdown/formatting.d.ts +2 -2
  42. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  43. package/dist/types/src/extensions/markdown/link.d.ts +4 -1
  44. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  45. package/dist/types/src/extensions/preview/index.d.ts +2 -0
  46. package/dist/types/src/extensions/preview/index.d.ts.map +1 -0
  47. package/dist/types/src/extensions/preview/preview.d.ts +39 -0
  48. package/dist/types/src/extensions/preview/preview.d.ts.map +1 -0
  49. package/dist/types/src/hooks/useTextEditor.d.ts +2 -1
  50. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  51. package/dist/types/src/{InputMode.stories.d.ts → stories/InputMode.stories.d.ts} +1 -1
  52. package/dist/types/src/stories/InputMode.stories.d.ts.map +1 -0
  53. package/dist/types/src/{TextEditor.stories.d.ts → stories/TextEditorBasic.stories.d.ts} +2 -35
  54. package/dist/types/src/stories/TextEditorBasic.stories.d.ts.map +1 -0
  55. package/dist/types/src/stories/TextEditorComments.stories.d.ts +13 -0
  56. package/dist/types/src/stories/TextEditorComments.stories.d.ts.map +1 -0
  57. package/dist/types/src/stories/TextEditorPreview.stories.d.ts +13 -0
  58. package/dist/types/src/stories/TextEditorPreview.stories.d.ts.map +1 -0
  59. package/dist/types/src/stories/TextEditorSpecial.stories.d.ts +19 -0
  60. package/dist/types/src/stories/TextEditorSpecial.stories.d.ts.map +1 -0
  61. package/dist/types/src/stories/story-utils.d.ts +53 -0
  62. package/dist/types/src/stories/story-utils.d.ts.map +1 -0
  63. package/dist/types/src/testing/RefPopover.d.ts +21 -0
  64. package/dist/types/src/testing/RefPopover.d.ts.map +1 -0
  65. package/dist/types/src/testing/index.d.ts +2 -0
  66. package/dist/types/src/testing/index.d.ts.map +1 -0
  67. package/dist/types/src/types.d.ts +5 -0
  68. package/dist/types/src/types.d.ts.map +1 -1
  69. package/dist/types/src/util/react.d.ts +6 -1
  70. package/dist/types/src/util/react.d.ts.map +1 -1
  71. package/package.json +33 -27
  72. package/src/components/EditorToolbar/EditorToolbar.tsx +2 -2
  73. package/src/components/EditorToolbar/util.ts +3 -3
  74. package/src/defaults.ts +5 -3
  75. package/src/extensions/automerge/automerge.stories.tsx +3 -11
  76. package/src/extensions/command/action.ts +49 -0
  77. package/src/extensions/command/command.ts +9 -27
  78. package/src/extensions/command/hint.ts +33 -30
  79. package/src/extensions/command/index.ts +1 -0
  80. package/src/extensions/command/menu.ts +11 -8
  81. package/src/extensions/command/state.ts +41 -61
  82. package/src/extensions/comments.ts +9 -9
  83. package/src/extensions/folding.tsx +1 -1
  84. package/src/extensions/index.ts +1 -0
  85. package/src/extensions/markdown/decorate.ts +4 -3
  86. package/src/extensions/markdown/formatting.ts +2 -2
  87. package/src/extensions/markdown/image.ts +12 -11
  88. package/src/extensions/markdown/link.ts +33 -24
  89. package/src/extensions/preview/index.ts +5 -0
  90. package/src/extensions/preview/preview.ts +271 -0
  91. package/src/hooks/useTextEditor.ts +4 -3
  92. package/src/{InputMode.stories.tsx → stories/InputMode.stories.tsx} +4 -4
  93. package/src/stories/TextEditorBasic.stories.tsx +289 -0
  94. package/src/stories/TextEditorComments.stories.tsx +99 -0
  95. package/src/stories/TextEditorPreview.stories.tsx +239 -0
  96. package/src/stories/TextEditorSpecial.stories.tsx +107 -0
  97. package/src/stories/story-utils.tsx +329 -0
  98. package/src/testing/RefPopover.tsx +74 -0
  99. package/src/testing/index.ts +5 -0
  100. package/src/types.ts +7 -0
  101. package/src/util/react.tsx +20 -2
  102. package/dist/types/src/InputMode.stories.d.ts.map +0 -1
  103. package/dist/types/src/TextEditor.stories.d.ts.map +0 -1
  104. package/dist/types/src/components/EditorToolbar/viewMode.d.ts.map +0 -1
  105. package/dist/types/src/extensions/command/preview.d.ts +0 -12
  106. package/dist/types/src/extensions/command/preview.d.ts.map +0 -1
  107. package/dist/types/src/fragments.d.ts +0 -3
  108. package/dist/types/src/fragments.d.ts.map +0 -1
  109. package/src/TextEditor.stories.tsx +0 -856
  110. package/src/extensions/command/preview.ts +0 -79
  111. package/src/fragments.ts +0 -19
  112. /package/src/components/EditorToolbar/{viewMode.ts → view-mode.ts} +0 -0
@@ -49,10 +49,10 @@ import { textBlockWidth } from "@dxos/react-ui-theme";
49
49
 
50
50
  // packages/ui/react-ui-editor/src/components/EditorToolbar/util.ts
51
51
  import { useMemo } from "react";
52
- import { create } from "@dxos/live-object";
52
+ import { live } from "@dxos/live-object";
53
53
  import { createMenuAction, createMenuItemGroup } from "@dxos/react-ui-menu";
54
54
  var useEditorToolbarState = (initialState = {}) => {
55
- return useMemo(() => create(initialState), []);
55
+ return useMemo(() => live(initialState), []);
56
56
  };
57
57
  var createEditorAction = (payload, icon, label = [
58
58
  `${payload.type} label`,
@@ -268,7 +268,7 @@ var createLists = (state) => {
268
268
  };
269
269
  };
270
270
 
271
- // packages/ui/react-ui-editor/src/components/EditorToolbar/viewMode.ts
271
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/view-mode.ts
272
272
  var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
273
273
  variant: "dropdownMenu",
274
274
  applyActive: true,
@@ -313,99 +313,12 @@ var createViewMode = (state) => {
313
313
  };
314
314
  };
315
315
 
316
- // packages/ui/react-ui-editor/src/fragments.ts
317
- import { mx } from "@dxos/react-ui-theme";
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");
319
-
320
- // packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
321
- var createToolbar = ({ state, customActions, ...features }) => {
322
- const nodes = [];
323
- const edges = [];
324
- if (features.headings ?? true) {
325
- const headings2 = createHeadings(state);
326
- nodes.push(...headings2.nodes);
327
- edges.push(...headings2.edges);
328
- }
329
- if (features.formatting ?? true) {
330
- const formatting = createFormatting(state);
331
- nodes.push(...formatting.nodes);
332
- edges.push(...formatting.edges);
333
- }
334
- if (features.lists ?? true) {
335
- const lists = createLists(state);
336
- nodes.push(...lists.nodes);
337
- edges.push(...lists.edges);
338
- }
339
- if (features.blocks ?? true) {
340
- const blocks = createBlocks(state);
341
- nodes.push(...blocks.nodes);
342
- edges.push(...blocks.edges);
343
- }
344
- if (customActions) {
345
- const custom = customActions();
346
- nodes.push(...custom.nodes);
347
- edges.push(...custom.edges);
348
- }
349
- const editorToolbarGap = createGapSeparator();
350
- nodes.push(...editorToolbarGap.nodes);
351
- edges.push(...editorToolbarGap.edges);
352
- if (features.comment ?? true) {
353
- const comment = createComment(state);
354
- nodes.push(...comment.nodes);
355
- edges.push(...comment.edges);
356
- }
357
- if (features.search ?? true) {
358
- nodes.push(editorToolbarSearch);
359
- edges.push({
360
- source: "root",
361
- target: editorToolbarSearch.id
362
- });
363
- }
364
- if (features.viewMode ?? true) {
365
- const viewMode = createViewMode(state);
366
- nodes.push(...viewMode.nodes);
367
- edges.push(...viewMode.edges);
368
- }
369
- return {
370
- nodes,
371
- edges
372
- };
373
- };
374
- var useEditorToolbarActionGraph = ({ onAction, ...props }) => {
375
- const menuCreator = useCallback(() => createToolbar(props), [
376
- props
377
- ]);
378
- const { resolveGroupItems } = useMenuActions(menuCreator);
379
- return {
380
- resolveGroupItems,
381
- onAction
382
- };
383
- };
384
- var EditorToolbar = ({ classNames, attendableId, role, ...props }) => {
385
- const menuProps = useEditorToolbarActionGraph(props);
386
- return /* @__PURE__ */ React.createElement("div", {
387
- role: "none",
388
- className: stackItemContentToolbarClassNames(role)
389
- }, /* @__PURE__ */ React.createElement(ElevationProvider, {
390
- elevation: role === "section" ? "positioned" : "base"
391
- }, /* @__PURE__ */ React.createElement(MenuProvider, {
392
- ...menuProps,
393
- attendableId
394
- }, /* @__PURE__ */ React.createElement(ToolbarMenu, {
395
- classNames: [
396
- textBlockWidth,
397
- "!bg-transparent",
398
- classNames
399
- ]
400
- }))));
401
- };
402
-
403
316
  // packages/ui/react-ui-editor/src/defaults.ts
404
317
  import { EditorView } from "@codemirror/view";
405
- import { mx as mx3 } from "@dxos/react-ui-theme";
318
+ import { mx as mx2 } from "@dxos/react-ui-theme";
406
319
 
407
320
  // packages/ui/react-ui-editor/src/styles/markdown.ts
408
- import { mx as mx2 } from "@dxos/react-ui-theme";
321
+ import { mx } from "@dxos/react-ui-theme";
409
322
  var headings = {
410
323
  1: "text-4xl",
411
324
  2: "text-3xl",
@@ -419,7 +332,7 @@ var theme = {
419
332
  codeMark: "font-mono text-primary-500",
420
333
  mark: "opacity-50",
421
334
  heading: (level) => {
422
- return mx2(headings[level], "dark:text-primary-400");
335
+ return mx(headings[level], "dark:text-primary-400");
423
336
  }
424
337
  };
425
338
 
@@ -638,8 +551,9 @@ var defaultTheme = {
638
551
 
639
552
  // packages/ui/react-ui-editor/src/defaults.ts
640
553
  var margin = "!mt-[1rem]";
641
- var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-4rem)]");
642
- var editorFullWidth = mx3(margin);
554
+ var editorWidth = "!mli-auto is-full max-is-[min(50rem,100%-4rem)]";
555
+ var editorContent = mx2(margin, editorWidth);
556
+ var editorFullWidth = mx2(margin);
643
557
  var editorGutter = EditorView.theme({
644
558
  // Match margin from content.
645
559
  // Gutter = 2rem + 1rem margin.
@@ -654,8 +568,91 @@ var editorMonospace = EditorView.theme({
654
568
  }
655
569
  });
656
570
  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");
571
+ var stackItemContentEditorClassNames = (role) => mx2("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");
572
+ var stackItemContentToolbarClassNames = (role) => mx2("attention-surface is-full border-be !border-separator relative z-[1]", role === "section" && "sticky block-start-0 -mbe-px min-is-0");
573
+
574
+ // packages/ui/react-ui-editor/src/components/EditorToolbar/EditorToolbar.tsx
575
+ var createToolbar = ({ state, customActions, ...features }) => {
576
+ const nodes = [];
577
+ const edges = [];
578
+ if (features.headings ?? true) {
579
+ const headings2 = createHeadings(state);
580
+ nodes.push(...headings2.nodes);
581
+ edges.push(...headings2.edges);
582
+ }
583
+ if (features.formatting ?? true) {
584
+ const formatting = createFormatting(state);
585
+ nodes.push(...formatting.nodes);
586
+ edges.push(...formatting.edges);
587
+ }
588
+ if (features.lists ?? true) {
589
+ const lists = createLists(state);
590
+ nodes.push(...lists.nodes);
591
+ edges.push(...lists.edges);
592
+ }
593
+ if (features.blocks ?? true) {
594
+ const blocks = createBlocks(state);
595
+ nodes.push(...blocks.nodes);
596
+ edges.push(...blocks.edges);
597
+ }
598
+ if (customActions) {
599
+ const custom = customActions();
600
+ nodes.push(...custom.nodes);
601
+ edges.push(...custom.edges);
602
+ }
603
+ const editorToolbarGap = createGapSeparator();
604
+ nodes.push(...editorToolbarGap.nodes);
605
+ edges.push(...editorToolbarGap.edges);
606
+ if (features.comment ?? true) {
607
+ const comment = createComment(state);
608
+ nodes.push(...comment.nodes);
609
+ edges.push(...comment.edges);
610
+ }
611
+ if (features.search ?? true) {
612
+ nodes.push(editorToolbarSearch);
613
+ edges.push({
614
+ source: "root",
615
+ target: editorToolbarSearch.id
616
+ });
617
+ }
618
+ if (features.viewMode ?? true) {
619
+ const viewMode = createViewMode(state);
620
+ nodes.push(...viewMode.nodes);
621
+ edges.push(...viewMode.edges);
622
+ }
623
+ return {
624
+ nodes,
625
+ edges
626
+ };
627
+ };
628
+ var useEditorToolbarActionGraph = ({ onAction, ...props }) => {
629
+ const menuCreator = useCallback(() => createToolbar(props), [
630
+ props
631
+ ]);
632
+ const { resolveGroupItems } = useMenuActions(menuCreator);
633
+ return {
634
+ resolveGroupItems,
635
+ onAction
636
+ };
637
+ };
638
+ var EditorToolbar = ({ classNames, attendableId, role, ...props }) => {
639
+ const menuProps = useEditorToolbarActionGraph(props);
640
+ return /* @__PURE__ */ React.createElement("div", {
641
+ role: "none",
642
+ className: stackItemContentToolbarClassNames(role)
643
+ }, /* @__PURE__ */ React.createElement(ElevationProvider, {
644
+ elevation: role === "section" ? "positioned" : "base"
645
+ }, /* @__PURE__ */ React.createElement(MenuProvider, {
646
+ ...menuProps,
647
+ attendableId
648
+ }, /* @__PURE__ */ React.createElement(ToolbarMenu, {
649
+ classNames: [
650
+ textBlockWidth,
651
+ "!bg-transparent",
652
+ classNames
653
+ ]
654
+ }))));
655
+ };
659
656
 
660
657
  // packages/ui/react-ui-editor/src/extensions/annotations.ts
661
658
  import { StateField } from "@codemirror/state";
@@ -796,7 +793,7 @@ var clientRectsFor = (dom) => {
796
793
  // packages/ui/react-ui-editor/src/util/react.tsx
797
794
  import React2 from "react";
798
795
  import { createRoot } from "react-dom/client";
799
- import { ThemeProvider } from "@dxos/react-ui";
796
+ import { ThemeProvider, Tooltip } from "@dxos/react-ui";
800
797
  import { defaultTx } from "@dxos/react-ui-theme";
801
798
  var createElement = (tag, options, children) => {
802
799
  const el = document.createElement(tag);
@@ -816,6 +813,11 @@ var renderRoot = (root, node) => {
816
813
  }, node));
817
814
  return root;
818
815
  };
816
+ var createRenderer = (Component) => (el, props) => {
817
+ renderRoot(el, /* @__PURE__ */ React2.createElement(ThemeProvider, {
818
+ tx: defaultTx
819
+ }, /* @__PURE__ */ React2.createElement(Tooltip.Provider, null, /* @__PURE__ */ React2.createElement(Component, props))));
820
+ };
819
821
 
820
822
  // packages/ui/react-ui-editor/src/extensions/annotations.ts
821
823
  var annotationMark = Decoration.mark({
@@ -1859,15 +1861,11 @@ var random = (min, max) => {
1859
1861
  return min + ~~(Math.random() * (max - min + 1));
1860
1862
  };
1861
1863
 
1862
- // packages/ui/react-ui-editor/src/extensions/command/command.ts
1863
- import { EditorView as EditorView8, keymap as keymap3 } from "@codemirror/view";
1864
-
1865
- // packages/ui/react-ui-editor/src/extensions/command/hint.ts
1866
- import { RangeSetBuilder } from "@codemirror/state";
1867
- import { Decoration as Decoration3, EditorView as EditorView6, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
1864
+ // packages/ui/react-ui-editor/src/extensions/command/action.ts
1865
+ import { StateEffect as StateEffect2 } from "@codemirror/state";
1868
1866
 
1869
1867
  // packages/ui/react-ui-editor/src/extensions/command/state.ts
1870
- import { StateEffect as StateEffect2, StateField as StateField3 } from "@codemirror/state";
1868
+ import { StateField as StateField3 } from "@codemirror/state";
1871
1869
  import { showTooltip } from "@codemirror/view";
1872
1870
  var commandConfig = singleValueFacet();
1873
1871
  var commandState = StateField3.define({
@@ -1877,8 +1875,8 @@ var commandState = StateField3.define({
1877
1875
  if (effect.is(closeEffect)) {
1878
1876
  return {};
1879
1877
  }
1880
- if (effect.is(openEffect)) {
1881
- const options = tr.state.facet(commandConfig);
1878
+ const { renderDialog } = tr.state.facet(commandConfig);
1879
+ if (effect.is(openEffect) && renderDialog) {
1882
1880
  const { pos, fullWidth } = effect.value;
1883
1881
  const tooltip = {
1884
1882
  pos,
@@ -1886,34 +1884,39 @@ var commandState = StateField3.define({
1886
1884
  arrow: false,
1887
1885
  strictSide: true,
1888
1886
  create: (view) => {
1889
- const dom = document.createElement("div");
1887
+ const root = document.createElement("div");
1890
1888
  const tooltipView = {
1891
- dom,
1889
+ dom: root,
1892
1890
  mount: (view2) => {
1893
1891
  if (fullWidth) {
1894
- const parent = dom.parentElement;
1892
+ const parent = root.parentElement;
1895
1893
  const { paddingLeft, paddingRight } = window.getComputedStyle(parent);
1896
1894
  const widthWithoutPadding = parent.clientWidth - parseFloat(paddingLeft) - parseFloat(paddingRight);
1897
- dom.style.width = `${widthWithoutPadding}px`;
1895
+ root.style.width = `${widthWithoutPadding}px`;
1898
1896
  }
1899
- options.onRenderDialog(dom, (action) => {
1900
- view2.dispatch({
1901
- effects: closeEffect.of(null)
1902
- });
1903
- if (action?.insert?.length) {
1904
- const text = action.insert + "\n";
1897
+ renderDialog(root, {
1898
+ onAction: (action) => {
1905
1899
  view2.dispatch({
1906
- changes: {
1907
- from: pos,
1908
- insert: text
1909
- },
1910
- selection: {
1911
- anchor: pos + text.length
1912
- }
1900
+ effects: closeEffect.of(null)
1913
1901
  });
1902
+ switch (action?.type) {
1903
+ case "insert": {
1904
+ const text = action.text + "\n";
1905
+ view2.dispatch({
1906
+ changes: {
1907
+ from: pos,
1908
+ insert: text
1909
+ },
1910
+ selection: {
1911
+ anchor: pos + text.length
1912
+ }
1913
+ });
1914
+ break;
1915
+ }
1916
+ }
1917
+ requestAnimationFrame(() => view2.focus());
1914
1918
  }
1915
- requestAnimationFrame(() => view2.focus());
1916
- });
1919
+ }, view2);
1917
1920
  }
1918
1921
  };
1919
1922
  return tooltipView;
@@ -1930,6 +1933,8 @@ var commandState = StateField3.define({
1930
1933
  showTooltip.from(field, (value) => value.tooltip ?? null)
1931
1934
  ]
1932
1935
  });
1936
+
1937
+ // packages/ui/react-ui-editor/src/extensions/command/action.ts
1933
1938
  var openEffect = StateEffect2.define();
1934
1939
  var closeEffect = StateEffect2.define();
1935
1940
  var openCommand = (view) => {
@@ -1968,7 +1973,38 @@ var commandKeyBindings = [
1968
1973
  }
1969
1974
  ];
1970
1975
 
1976
+ // packages/ui/react-ui-editor/src/extensions/command/command.ts
1977
+ import { EditorView as EditorView7, keymap as keymap3 } from "@codemirror/view";
1978
+
1971
1979
  // packages/ui/react-ui-editor/src/extensions/command/hint.ts
1980
+ import { RangeSetBuilder } from "@codemirror/state";
1981
+ import { Decoration as Decoration3, EditorView as EditorView6, ViewPlugin as ViewPlugin3, WidgetType as WidgetType2 } from "@codemirror/view";
1982
+ var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
1983
+ constructor() {
1984
+ this.deco = Decoration3.none;
1985
+ }
1986
+ update(update2) {
1987
+ const builder = new RangeSetBuilder();
1988
+ const cState = update2.view.state.field(commandState, false);
1989
+ if (!cState?.tooltip) {
1990
+ const selection = update2.view.state.selection.main;
1991
+ const line = update2.view.state.doc.lineAt(selection.from);
1992
+ if (selection.from === selection.to && line.from === line.to) {
1993
+ const hint = onHint();
1994
+ if (hint) {
1995
+ builder.add(selection.from, selection.to, Decoration3.widget({
1996
+ widget: new CommandHint(hint)
1997
+ }));
1998
+ }
1999
+ }
2000
+ }
2001
+ this.deco = builder.finish();
2002
+ }
2003
+ }, {
2004
+ provide: (plugin) => [
2005
+ EditorView6.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
2006
+ ]
2007
+ });
1972
2008
  var CommandHint = class extends WidgetType2 {
1973
2009
  constructor(content) {
1974
2010
  super();
@@ -2008,32 +2044,6 @@ var CommandHint = class extends WidgetType2 {
2008
2044
  return false;
2009
2045
  }
2010
2046
  };
2011
- var hintViewPlugin = ({ onHint }) => ViewPlugin3.fromClass(class {
2012
- constructor() {
2013
- this.deco = Decoration3.none;
2014
- }
2015
- update(update2) {
2016
- const builder = new RangeSetBuilder();
2017
- const cState = update2.view.state.field(commandState, false);
2018
- if (!cState?.tooltip) {
2019
- const selection = update2.view.state.selection.main;
2020
- const line = update2.view.state.doc.lineAt(selection.from);
2021
- if (selection.from === selection.to && line.from === line.to) {
2022
- const hint = onHint();
2023
- if (hint) {
2024
- builder.add(selection.from, selection.to, Decoration3.widget({
2025
- widget: new CommandHint(hint)
2026
- }));
2027
- }
2028
- }
2029
- }
2030
- this.deco = builder.finish();
2031
- }
2032
- }, {
2033
- provide: (plugin) => [
2034
- EditorView6.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration3.none)
2035
- ]
2036
- });
2037
2047
 
2038
2048
  // packages/ui/react-ui-editor/src/extensions/command/menu.ts
2039
2049
  import { ViewPlugin as ViewPlugin4 } from "@codemirror/view";
@@ -2049,11 +2059,11 @@ var floatingMenu = (options) => ViewPlugin4.fromClass(class {
2049
2059
  this.button.style.position = "absolute";
2050
2060
  this.button.style.zIndex = "10";
2051
2061
  this.button.style.display = "none";
2052
- options.onRenderMenu(this.button, () => {
2053
- openCommand(view);
2054
- });
2062
+ options.renderMenu(this.button, {
2063
+ onAction: () => openCommand(view)
2064
+ }, view);
2055
2065
  container.appendChild(this.button);
2056
- container.addEventListener("scroll", this.scheduleUpdate);
2066
+ container.addEventListener("scroll", this.scheduleUpdate.bind(this));
2057
2067
  this.scheduleUpdate();
2058
2068
  }
2059
2069
  update(update2) {
@@ -2069,7 +2079,7 @@ var floatingMenu = (options) => ViewPlugin4.fromClass(class {
2069
2079
  if (this.rafId != null) {
2070
2080
  cancelAnimationFrame(this.rafId);
2071
2081
  }
2072
- this.rafId = requestAnimationFrame(() => this.updateButtonPosition());
2082
+ this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));
2073
2083
  }
2074
2084
  updateButtonPosition() {
2075
2085
  const pos = this.view.state.selection.main.head;
@@ -2099,83 +2109,24 @@ var floatingMenu = (options) => ViewPlugin4.fromClass(class {
2099
2109
  }
2100
2110
  });
2101
2111
 
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
-
2156
2112
  // packages/ui/react-ui-editor/src/extensions/command/command.ts
2157
- var command = (options) => {
2113
+ var command = (options = {}) => {
2158
2114
  return [
2115
+ keymap3.of(commandKeyBindings),
2159
2116
  commandConfig.of(options),
2160
2117
  commandState,
2161
- keymap3.of(commandKeyBindings),
2162
- preview(options),
2163
- floatingMenu(options),
2164
- hintViewPlugin(options),
2165
- EditorView8.focusChangeEffect.of((_, focusing) => {
2118
+ options.renderMenu ? floatingMenu({
2119
+ renderMenu: options.renderMenu
2120
+ }) : [],
2121
+ options.onHint ? hintViewPlugin({
2122
+ onHint: options.onHint
2123
+ }) : [],
2124
+ EditorView7.focusChangeEffect.of((_, focusing) => {
2166
2125
  return focusing ? closeEffect.of(null) : null;
2167
2126
  }),
2168
- EditorView8.theme({
2127
+ EditorView7.theme({
2169
2128
  ".cm-tooltip": {
2170
2129
  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
2130
  }
2180
2131
  })
2181
2132
  ];
@@ -2183,8 +2134,8 @@ var command = (options) => {
2183
2134
 
2184
2135
  // packages/ui/react-ui-editor/src/extensions/comments.ts
2185
2136
  import { invertedEffects } from "@codemirror/commands";
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";
2137
+ import { StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
2138
+ import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as EditorView9, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
2188
2139
  import sortBy from "lodash.sortby";
2189
2140
  import { useEffect, useMemo as useMemo2 } from "react";
2190
2141
  import { debounce as debounce2 } from "@dxos/async";
@@ -2193,7 +2144,7 @@ import { isNonNullable } from "@dxos/util";
2193
2144
 
2194
2145
  // packages/ui/react-ui-editor/src/extensions/selection.ts
2195
2146
  import { Transaction } from "@codemirror/state";
2196
- import { EditorView as EditorView9, keymap as keymap4 } from "@codemirror/view";
2147
+ import { EditorView as EditorView8, keymap as keymap4 } from "@codemirror/view";
2197
2148
  import { debounce } from "@dxos/async";
2198
2149
  import { invariant as invariant3 } from "@dxos/invariant";
2199
2150
  import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
@@ -2204,7 +2155,7 @@ var createEditorStateTransaction = ({ scrollTo, selection }) => {
2204
2155
  return {
2205
2156
  selection,
2206
2157
  scrollIntoView: !scrollTo,
2207
- effects: scrollTo ? EditorView9.scrollIntoView(scrollTo, {
2158
+ effects: scrollTo ? EditorView8.scrollIntoView(scrollTo, {
2208
2159
  yMargin: 96
2209
2160
  }) : void 0,
2210
2161
  annotations: Transaction.userEvent.of(stateRestoreAnnotation)
@@ -2246,7 +2197,7 @@ var selectionState = ({ getState, setState } = {}) => {
2246
2197
  // setStateDebounced(id, {});
2247
2198
  // },
2248
2199
  // }),
2249
- EditorView9.updateListener.of(({ view, transactions }) => {
2200
+ EditorView8.updateListener.of(({ view, transactions }) => {
2250
2201
  const id = view.state.facet(documentId);
2251
2202
  if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
2252
2203
  return;
@@ -2289,7 +2240,7 @@ var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src
2289
2240
  var setComments = StateEffect3.define();
2290
2241
  var setSelection = StateEffect3.define();
2291
2242
  var setCommentState = StateEffect3.define();
2292
- var commentsState = StateField5.define({
2243
+ var commentsState = StateField4.define({
2293
2244
  create: (state) => ({
2294
2245
  id: state.facet(documentId),
2295
2246
  comments: [],
@@ -2327,7 +2278,7 @@ var commentsState = StateField5.define({
2327
2278
  return value;
2328
2279
  }
2329
2280
  });
2330
- var styles3 = EditorView10.theme({
2281
+ var styles3 = EditorView9.theme({
2331
2282
  ".cm-comment, .cm-comment-current": {
2332
2283
  margin: "0 -3px",
2333
2284
  padding: "3px",
@@ -2340,14 +2291,14 @@ var styles3 = EditorView10.theme({
2340
2291
  textDecoration: "underline"
2341
2292
  }
2342
2293
  });
2343
- var createCommentMark = (id, isCurrent) => Decoration5.mark({
2294
+ var createCommentMark = (id, isCurrent) => Decoration4.mark({
2344
2295
  class: isCurrent ? "cm-comment-current" : "cm-comment",
2345
2296
  attributes: {
2346
2297
  "data-testid": "cm-comment",
2347
2298
  "data-comment-id": id
2348
2299
  }
2349
2300
  });
2350
- var commentsDecorations = EditorView10.decorations.compute([
2301
+ var commentsDecorations = EditorView9.decorations.compute([
2351
2302
  commentsState
2352
2303
  ], (state) => {
2353
2304
  const { selection: { current }, comments: comments2 } = state.field(commentsState);
@@ -2367,10 +2318,10 @@ var commentsDecorations = EditorView10.decorations.compute([
2367
2318
  const mark = createCommentMark(comment.comment.id, comment.comment.id === current);
2368
2319
  return mark.range(range.from, range.to);
2369
2320
  }).filter(isNonNullable);
2370
- return Decoration5.set(decorations);
2321
+ return Decoration4.set(decorations);
2371
2322
  });
2372
2323
  var commentClickedEffect = StateEffect3.define();
2373
- var handleCommentClick = EditorView10.domEventHandlers({
2324
+ var handleCommentClick = EditorView9.domEventHandlers({
2374
2325
  click: (event, view) => {
2375
2326
  let target = event.target;
2376
2327
  const editorRoot = view.dom;
@@ -2409,7 +2360,7 @@ var trackPastedComments = (onUpdate) => {
2409
2360
  }
2410
2361
  };
2411
2362
  return [
2412
- EditorView10.domEventHandlers({
2363
+ EditorView9.domEventHandlers({
2413
2364
  cut: handleTrack,
2414
2365
  copy: handleTrack
2415
2366
  }),
@@ -2431,7 +2382,7 @@ var trackPastedComments = (onUpdate) => {
2431
2382
  return effects;
2432
2383
  }),
2433
2384
  // Handle paste or the undo of comment deletion.
2434
- EditorView10.updateListener.of((update2) => {
2385
+ EditorView9.updateListener.of((update2) => {
2435
2386
  const restore = [];
2436
2387
  for (let i = 0; i < update2.transactions.length; i++) {
2437
2388
  const tr = update2.transactions[i];
@@ -2542,7 +2493,7 @@ var comments = (options = {}) => {
2542
2493
  // Hover tooltip (for key shortcut hints, etc.)
2543
2494
  // TODO(burdon): Factor out to generic hints extension for current selection/line.
2544
2495
  //
2545
- options.onHover && hoverTooltip((view, pos) => {
2496
+ options.renderTooltip && hoverTooltip((view, pos) => {
2546
2497
  const selection = view.state.selection.main;
2547
2498
  if (selection && pos >= selection.from && pos <= selection.to) {
2548
2499
  return {
@@ -2551,7 +2502,9 @@ var comments = (options = {}) => {
2551
2502
  above: true,
2552
2503
  create: () => {
2553
2504
  const el = document.createElement("div");
2554
- options.onHover(el, shortcut);
2505
+ options.renderTooltip(el, {
2506
+ shortcut
2507
+ }, view);
2555
2508
  return {
2556
2509
  dom: el,
2557
2510
  offset: {
@@ -2571,7 +2524,7 @@ var comments = (options = {}) => {
2571
2524
  //
2572
2525
  // Track deleted ranges and update ranges for decorations.
2573
2526
  //
2574
- EditorView10.updateListener.of(({ view, state, changes }) => {
2527
+ EditorView9.updateListener.of(({ view, state, changes }) => {
2575
2528
  let mod = false;
2576
2529
  const { comments: comments2, ...value } = state.field(commentsState);
2577
2530
  changes.iterChanges((from, to, from2, to2) => {
@@ -2603,7 +2556,7 @@ var comments = (options = {}) => {
2603
2556
  //
2604
2557
  // Track selection/proximity.
2605
2558
  //
2606
- EditorView10.updateListener.of(({ view, state }) => {
2559
+ EditorView9.updateListener.of(({ view, state }) => {
2607
2560
  let min = Infinity;
2608
2561
  const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
2609
2562
  const { head } = state.selection.main;
@@ -2657,7 +2610,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
2657
2610
  anchor: range.from
2658
2611
  } : void 0,
2659
2612
  effects: [
2660
- needsScroll ? EditorView10.scrollIntoView(range.from, center ? {
2613
+ needsScroll ? EditorView9.scrollIntoView(range.from, center ? {
2661
2614
  y: "center"
2662
2615
  } : void 0) : [],
2663
2616
  needsSelectionUpdate ? setSelection.of({
@@ -2709,7 +2662,7 @@ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin5.from
2709
2662
  }
2710
2663
  });
2711
2664
  var useCommentState = (state) => {
2712
- return useMemo2(() => EditorView10.updateListener.of((update2) => {
2665
+ return useMemo2(() => EditorView9.updateListener.of((update2) => {
2713
2666
  if (update2.docChanged || update2.selectionSet) {
2714
2667
  state.comment = selectionOverlapsComment(update2.state);
2715
2668
  state.selection = hasActiveSelection(update2.state);
@@ -2733,7 +2686,7 @@ var useComments = (view, id, comments2) => {
2733
2686
  });
2734
2687
  };
2735
2688
  var useCommentClickListener = (onCommentClick) => {
2736
- return useMemo2(() => EditorView10.updateListener.of((update2) => {
2689
+ return useMemo2(() => EditorView9.updateListener.of((update2) => {
2737
2690
  update2.transactions.forEach((transaction) => {
2738
2691
  transaction.effects.forEach((effect) => {
2739
2692
  if (effect.is(commentClickedEffect)) {
@@ -2747,21 +2700,21 @@ var useCommentClickListener = (onCommentClick) => {
2747
2700
  };
2748
2701
 
2749
2702
  // packages/ui/react-ui-editor/src/extensions/debug.ts
2750
- import { syntaxTree as syntaxTree2 } from "@codemirror/language";
2751
- import { StateField as StateField6 } from "@codemirror/state";
2703
+ import { syntaxTree } from "@codemirror/language";
2704
+ import { StateField as StateField5 } from "@codemirror/state";
2752
2705
  var debugNodeLogger = (log8 = console.log) => {
2753
- const logTokens = (state) => syntaxTree2(state).iterate({
2706
+ const logTokens = (state) => syntaxTree(state).iterate({
2754
2707
  enter: (node) => log8(node.type)
2755
2708
  });
2756
- return StateField6.define({
2709
+ return StateField5.define({
2757
2710
  create: (state) => logTokens(state),
2758
2711
  update: (_, tr) => logTokens(tr.state)
2759
2712
  });
2760
2713
  };
2761
2714
 
2762
2715
  // packages/ui/react-ui-editor/src/extensions/dnd.ts
2763
- import { dropCursor, EditorView as EditorView11 } from "@codemirror/view";
2764
- var styles4 = EditorView11.theme({
2716
+ import { dropCursor, EditorView as EditorView10 } from "@codemirror/view";
2717
+ var styles4 = EditorView10.theme({
2765
2718
  ".cm-dropCursor": {
2766
2719
  borderLeft: "2px solid var(--dx-accentText)",
2767
2720
  color: "var(--dx-accentText)",
@@ -2775,7 +2728,7 @@ var dropFile = (options = {}) => {
2775
2728
  return [
2776
2729
  styles4,
2777
2730
  dropCursor(),
2778
- EditorView11.domEventHandlers({
2731
+ EditorView10.domEventHandlers({
2779
2732
  drop: (event, view) => {
2780
2733
  event.preventDefault();
2781
2734
  const files = event.dataTransfer?.files;
@@ -2802,7 +2755,7 @@ import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@cod
2802
2755
  import { searchKeymap } from "@codemirror/search";
2803
2756
  import { EditorState } from "@codemirror/state";
2804
2757
  import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
2805
- import { EditorView as EditorView13, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
2758
+ import { EditorView as EditorView12, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
2806
2759
  import defaultsDeep2 from "lodash.defaultsdeep";
2807
2760
  import merge from "lodash.merge";
2808
2761
  import { generateName } from "@dxos/display-name";
@@ -2810,10 +2763,10 @@ import { log as log5 } from "@dxos/log";
2810
2763
  import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
2811
2764
 
2812
2765
  // packages/ui/react-ui-editor/src/extensions/focus.ts
2813
- import { StateEffect as StateEffect4, StateField as StateField7 } from "@codemirror/state";
2814
- import { EditorView as EditorView12 } from "@codemirror/view";
2766
+ import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
2767
+ import { EditorView as EditorView11 } from "@codemirror/view";
2815
2768
  var focusEffect = StateEffect4.define();
2816
- var focusField = StateField7.define({
2769
+ var focusField = StateField6.define({
2817
2770
  create: () => false,
2818
2771
  update: (value, tr) => {
2819
2772
  for (const effect of tr.effects) {
@@ -2826,7 +2779,7 @@ var focusField = StateField7.define({
2826
2779
  });
2827
2780
  var focus = [
2828
2781
  focusField,
2829
- EditorView12.domEventHandlers({
2782
+ EditorView11.domEventHandlers({
2830
2783
  focus: (event, view) => {
2831
2784
  setTimeout(() => view.dispatch({
2832
2785
  effects: focusEffect.of(true)
@@ -2864,7 +2817,7 @@ var createBasicExtensions = (_props) => {
2864
2817
  const props = defaultsDeep2({}, _props, defaultBasicOptions);
2865
2818
  return [
2866
2819
  // NOTE: Doesn't catch errors in keymap functions.
2867
- EditorView13.exceptionSink.of((err) => {
2820
+ EditorView12.exceptionSink.of((err) => {
2868
2821
  log5.catch(err, void 0, {
2869
2822
  F: __dxlog_file8,
2870
2823
  L: 96,
@@ -2879,12 +2832,12 @@ var createBasicExtensions = (_props) => {
2879
2832
  props.drawSelection && drawSelection({
2880
2833
  cursorBlinkRate: 1200
2881
2834
  }),
2882
- props.editable !== void 0 && EditorView13.editable.of(props.editable),
2835
+ props.editable !== void 0 && EditorView12.editable.of(props.editable),
2883
2836
  props.focus && focus,
2884
2837
  props.highlightActiveLine && highlightActiveLine(),
2885
2838
  props.history && history(),
2886
2839
  props.lineNumbers && lineNumbers(),
2887
- props.lineWrapping && EditorView13.lineWrapping,
2840
+ props.lineWrapping && EditorView12.lineWrapping,
2888
2841
  props.placeholder && placeholder(props.placeholder),
2889
2842
  props.readOnly !== void 0 && EditorState.readOnly.of(props.readOnly),
2890
2843
  props.scrollPastEnd && scrollPastEnd(),
@@ -2921,14 +2874,14 @@ var defaultThemeSlots = {
2921
2874
  var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
2922
2875
  const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
2923
2876
  return [
2924
- EditorView13.darkTheme.of(themeMode === "dark"),
2925
- EditorView13.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2877
+ EditorView12.darkTheme.of(themeMode === "dark"),
2878
+ EditorView12.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2926
2879
  // https://github.com/codemirror/theme-one-dark
2927
2880
  _syntaxHighlighting && (themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)),
2928
- slots.editor?.className && EditorView13.editorAttributes.of({
2881
+ slots.editor?.className && EditorView12.editorAttributes.of({
2929
2882
  class: slots.editor.className
2930
2883
  }),
2931
- slots.content?.className && EditorView13.contentAttributes.of({
2884
+ slots.content?.className && EditorView12.contentAttributes.of({
2932
2885
  class: slots.content.className
2933
2886
  })
2934
2887
  ].filter(isNotFalsy3);
@@ -2957,7 +2910,7 @@ var createDataExtensions = ({ id, text, space, identity }) => {
2957
2910
 
2958
2911
  // packages/ui/react-ui-editor/src/extensions/folding.tsx
2959
2912
  import { codeFolding, foldGutter } from "@codemirror/language";
2960
- import { EditorView as EditorView14 } from "@codemirror/view";
2913
+ import { EditorView as EditorView13 } from "@codemirror/view";
2961
2914
  import React3 from "react";
2962
2915
  import { Icon } from "@dxos/react-ui";
2963
2916
  var folding = (_props = {}) => [
@@ -2972,7 +2925,7 @@ var folding = (_props = {}) => [
2972
2925
  className: "flex h-full items-center"
2973
2926
  });
2974
2927
  return renderRoot(el, /* @__PURE__ */ React3.createElement(Icon, {
2975
- icon: "ph--caret-right--regular",
2928
+ icon: "ph--caret-right--bold",
2976
2929
  size: 3,
2977
2930
  classNames: [
2978
2931
  "mx-3 cursor-pointer",
@@ -2981,7 +2934,7 @@ var folding = (_props = {}) => [
2981
2934
  }));
2982
2935
  }
2983
2936
  }),
2984
- EditorView14.theme({
2937
+ EditorView13.theme({
2985
2938
  ".cm-foldGutter": {
2986
2939
  opacity: 0.3,
2987
2940
  transition: "opacity 0.3s",
@@ -2994,14 +2947,14 @@ var folding = (_props = {}) => [
2994
2947
  ];
2995
2948
 
2996
2949
  // packages/ui/react-ui-editor/src/extensions/listener.ts
2997
- import { EditorView as EditorView15 } from "@codemirror/view";
2950
+ import { EditorView as EditorView14 } from "@codemirror/view";
2998
2951
  var listener = ({ onFocus, onChange }) => {
2999
2952
  const extensions = [];
3000
- onFocus && extensions.push(EditorView15.focusChangeEffect.of((_, focusing) => {
2953
+ onFocus && extensions.push(EditorView14.focusChangeEffect.of((_, focusing) => {
3001
2954
  onFocus(focusing);
3002
2955
  return null;
3003
2956
  }));
3004
- onChange && extensions.push(EditorView15.updateListener.of((update2) => {
2957
+ onChange && extensions.push(EditorView14.updateListener.of((update2) => {
3005
2958
  onChange(update2.state.doc.toString(), update2.state.facet(documentId));
3006
2959
  }));
3007
2960
  return extensions;
@@ -3009,9 +2962,9 @@ var listener = ({ onFocus, onChange }) => {
3009
2962
 
3010
2963
  // packages/ui/react-ui-editor/src/extensions/markdown/formatting.ts
3011
2964
  import { snippet } from "@codemirror/autocomplete";
3012
- import { syntaxTree as syntaxTree3 } from "@codemirror/language";
2965
+ import { syntaxTree as syntaxTree2 } from "@codemirror/language";
3013
2966
  import { EditorSelection } from "@codemirror/state";
3014
- import { EditorView as EditorView16, keymap as keymap7 } from "@codemirror/view";
2967
+ import { EditorView as EditorView15, keymap as keymap7 } from "@codemirror/view";
3015
2968
  import { useMemo as useMemo3 } from "react";
3016
2969
  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;
3017
2970
  var Inline;
@@ -3034,7 +2987,7 @@ var setHeading = (level) => {
3034
2987
  let prevBlock = -1;
3035
2988
  for (const range of ranges) {
3036
2989
  let sawBlock = false;
3037
- syntaxTree3(state).iterate({
2990
+ syntaxTree2(state).iterate({
3038
2991
  from: range.from,
3039
2992
  to: range.to,
3040
2993
  enter: (node) => {
@@ -3143,7 +3096,7 @@ var setStyle = (type, enable) => {
3143
3096
  let startCovered = false;
3144
3097
  let endCovered = false;
3145
3098
  let { from, to } = range;
3146
- syntaxTree3(state).iterate({
3099
+ syntaxTree2(state).iterate({
3147
3100
  from,
3148
3101
  to,
3149
3102
  enter: (node) => {
@@ -3346,7 +3299,7 @@ var insertTable = (view) => {
3346
3299
  snippets.table(view, null, from, from);
3347
3300
  };
3348
3301
  var removeLinkInner = (from, to, changes, state) => {
3349
- syntaxTree3(state).iterate({
3302
+ syntaxTree2(state).iterate({
3350
3303
  from,
3351
3304
  to,
3352
3305
  enter: (node) => {
@@ -3391,7 +3344,7 @@ var addLink = ({ url, image: image2 } = {}) => {
3391
3344
  let { from, to } = range;
3392
3345
  const cutStyles = [];
3393
3346
  let okay = null;
3394
- syntaxTree3(state).iterate({
3347
+ syntaxTree2(state).iterate({
3395
3348
  from,
3396
3349
  to,
3397
3350
  enter: (node) => {
@@ -3486,7 +3439,7 @@ var addList = (type) => {
3486
3439
  let parentColumn = null;
3487
3440
  const blocks = [];
3488
3441
  for (const { from, to } of state.selection.ranges) {
3489
- syntaxTree3(state).iterate({
3442
+ syntaxTree2(state).iterate({
3490
3443
  from,
3491
3444
  to,
3492
3445
  enter: (node) => {
@@ -3621,7 +3574,7 @@ var removeList = (type) => {
3621
3574
  const stack = [];
3622
3575
  const targetNodeType = type === 0 ? "OrderedList" : type === 1 ? "BulletList" : "TaskList";
3623
3576
  for (const { from, to } of state.selection.ranges) {
3624
- syntaxTree3(state).iterate({
3577
+ syntaxTree2(state).iterate({
3625
3578
  from,
3626
3579
  to,
3627
3580
  enter: (node) => {
@@ -3708,7 +3661,7 @@ var setBlockquote = (enable) => {
3708
3661
  let lastBlock = -1;
3709
3662
  for (const { from, to } of state.selection.ranges) {
3710
3663
  const sawBlock = false;
3711
- syntaxTree3(state).iterate({
3664
+ syntaxTree2(state).iterate({
3712
3665
  from,
3713
3666
  to,
3714
3667
  enter: (node) => {
@@ -3798,7 +3751,7 @@ var addCodeblock = (target) => {
3798
3751
  for (const { from, to } of selection.ranges) {
3799
3752
  let blockFrom = from;
3800
3753
  let blockTo = to;
3801
- syntaxTree3(state).iterate({
3754
+ syntaxTree2(state).iterate({
3802
3755
  from,
3803
3756
  to,
3804
3757
  enter: (node) => {
@@ -3849,7 +3802,7 @@ var removeCodeblock = ({ state, dispatch }) => {
3849
3802
  let lastBlock = -1;
3850
3803
  const changes = [];
3851
3804
  for (const { from, to } of state.selection.ranges) {
3852
- syntaxTree3(state).iterate({
3805
+ syntaxTree2(state).iterate({
3853
3806
  from,
3854
3807
  to,
3855
3808
  enter: (node) => {
@@ -4011,7 +3964,7 @@ var getFormatting = (state) => {
4011
3964
  }
4012
3965
  }
4013
3966
  }
4014
- syntaxTree3(state).iterate({
3967
+ syntaxTree2(state).iterate({
4015
3968
  from: range.from,
4016
3969
  to: range.to,
4017
3970
  enter: (node) => {
@@ -4100,7 +4053,7 @@ var getFormatting = (state) => {
4100
4053
  };
4101
4054
  };
4102
4055
  var useFormattingState = (state) => {
4103
- return useMemo3(() => EditorView16.updateListener.of((update2) => {
4056
+ return useMemo3(() => EditorView15.updateListener.of((update2) => {
4104
4057
  if (update2.docChanged || update2.selectionSet) {
4105
4058
  Object.entries(getFormatting(update2.state)).forEach(([key, active]) => {
4106
4059
  state[key] = active;
@@ -4383,9 +4336,9 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
4383
4336
  };
4384
4337
 
4385
4338
  // packages/ui/react-ui-editor/src/extensions/markdown/debug.ts
4386
- import { syntaxTree as syntaxTree4 } from "@codemirror/language";
4387
- import { StateField as StateField8 } from "@codemirror/state";
4388
- var debugTree = (cb) => StateField8.define({
4339
+ import { syntaxTree as syntaxTree3 } from "@codemirror/language";
4340
+ import { StateField as StateField7 } from "@codemirror/state";
4341
+ var debugTree = (cb) => StateField7.define({
4389
4342
  create: (state) => cb(convertTreeToJson(state)),
4390
4343
  update: (value, tr) => cb(convertTreeToJson(tr.state))
4391
4344
  });
@@ -4406,24 +4359,24 @@ var convertTreeToJson = (state) => {
4406
4359
  }
4407
4360
  return node;
4408
4361
  };
4409
- return treeToJson(syntaxTree4(state).cursor());
4362
+ return treeToJson(syntaxTree3(state).cursor());
4410
4363
  };
4411
4364
 
4412
4365
  // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
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";
4366
+ import { syntaxTree as syntaxTree7 } from "@codemirror/language";
4367
+ import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect5 } from "@codemirror/state";
4368
+ import { EditorView as EditorView19, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin7 } from "@codemirror/view";
4416
4369
  import { invariant as invariant4 } from "@dxos/invariant";
4417
- import { mx as mx4 } from "@dxos/react-ui-theme";
4370
+ import { mx as mx3 } from "@dxos/react-ui-theme";
4418
4371
 
4419
4372
  // packages/ui/react-ui-editor/src/extensions/markdown/changes.ts
4420
- import { syntaxTree as syntaxTree5 } from "@codemirror/language";
4373
+ import { syntaxTree as syntaxTree4 } from "@codemirror/language";
4421
4374
  import { Transaction as Transaction2 } from "@codemirror/state";
4422
4375
  import { ViewPlugin as ViewPlugin6 } from "@codemirror/view";
4423
4376
  var adjustChanges = () => {
4424
4377
  return ViewPlugin6.fromClass(class {
4425
4378
  update(update2) {
4426
- const tree = syntaxTree5(update2.state);
4379
+ const tree = syntaxTree4(update2.state);
4427
4380
  const adjustments = [];
4428
4381
  for (const tr of update2.transactions) {
4429
4382
  const event = tr.annotation(Transaction2.userEvent);
@@ -4561,14 +4514,14 @@ var getValidUrl = (str) => {
4561
4514
  };
4562
4515
 
4563
4516
  // packages/ui/react-ui-editor/src/extensions/markdown/image.ts
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";
4517
+ import { syntaxTree as syntaxTree5 } from "@codemirror/language";
4518
+ import { StateField as StateField8 } from "@codemirror/state";
4519
+ import { Decoration as Decoration5, EditorView as EditorView16, WidgetType as WidgetType3 } from "@codemirror/view";
4567
4520
  var image = (_options = {}) => {
4568
4521
  return [
4569
- StateField9.define({
4522
+ StateField8.define({
4570
4523
  create: (state) => {
4571
- return Decoration6.set(buildDecorations2(0, state.doc.length, state));
4524
+ return Decoration5.set(buildDecorations(0, state.doc.length, state));
4572
4525
  },
4573
4526
  update: (value, tr) => {
4574
4527
  if (!tr.docChanged && !tr.selection) {
@@ -4588,25 +4541,17 @@ var image = (_options = {}) => {
4588
4541
  filterFrom: from,
4589
4542
  filterTo: to,
4590
4543
  filter: () => false,
4591
- add: buildDecorations2(from, to, tr.state)
4544
+ add: buildDecorations(from, to, tr.state)
4592
4545
  });
4593
4546
  },
4594
- provide: (field) => EditorView17.decorations.from(field)
4547
+ provide: (field) => EditorView16.decorations.from(field)
4595
4548
  })
4596
4549
  ];
4597
4550
  };
4598
- var preloaded = /* @__PURE__ */ new Set();
4599
- var preloadImage = (url) => {
4600
- if (!preloaded.has(url)) {
4601
- const img = document.createElement("img");
4602
- img.src = url;
4603
- preloaded.add(url);
4604
- }
4605
- };
4606
- var buildDecorations2 = (from, to, state) => {
4551
+ var buildDecorations = (from, to, state) => {
4607
4552
  const decorations = [];
4608
4553
  const cursor = state.selection.main.head;
4609
- syntaxTree6(state).iterate({
4554
+ syntaxTree5(state).iterate({
4610
4555
  enter: (node) => {
4611
4556
  if (node.name === "Image") {
4612
4557
  const urlNode = node.node.getChild("URL");
@@ -4617,7 +4562,7 @@ var buildDecorations2 = (from, to, state) => {
4617
4562
  return;
4618
4563
  }
4619
4564
  preloadImage(url);
4620
- decorations.push(Decoration6.replace({
4565
+ decorations.push(Decoration5.replace({
4621
4566
  block: true,
4622
4567
  widget: new ImageWidget(url)
4623
4568
  }).range(hide2 ? node.from : node.to, node.to));
@@ -4629,7 +4574,15 @@ var buildDecorations2 = (from, to, state) => {
4629
4574
  });
4630
4575
  return decorations;
4631
4576
  };
4632
- var ImageWidget = class extends WidgetType4 {
4577
+ var preloaded = /* @__PURE__ */ new Set();
4578
+ var preloadImage = (url) => {
4579
+ if (!preloaded.has(url)) {
4580
+ const img = document.createElement("img");
4581
+ img.src = url;
4582
+ preloaded.add(url);
4583
+ }
4584
+ };
4585
+ var ImageWidget = class extends WidgetType3 {
4633
4586
  constructor(_url) {
4634
4587
  super();
4635
4588
  this._url = _url;
@@ -4651,10 +4604,10 @@ var ImageWidget = class extends WidgetType4 {
4651
4604
  };
4652
4605
 
4653
4606
  // packages/ui/react-ui-editor/src/extensions/markdown/styles.ts
4654
- import { EditorView as EditorView18 } from "@codemirror/view";
4607
+ import { EditorView as EditorView17 } from "@codemirror/view";
4655
4608
  var bulletListIndentationWidth = 24;
4656
4609
  var orderedListIndentationWidth = 36;
4657
- var formattingStyles = EditorView18.theme({
4610
+ var formattingStyles = EditorView17.theme({
4658
4611
  /**
4659
4612
  * Horizontal rule.
4660
4613
  */
@@ -4773,18 +4726,18 @@ var formattingStyles = EditorView18.theme({
4773
4726
  });
4774
4727
 
4775
4728
  // packages/ui/react-ui-editor/src/extensions/markdown/table.ts
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";
4729
+ import { syntaxTree as syntaxTree6 } from "@codemirror/language";
4730
+ import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField9 } from "@codemirror/state";
4731
+ import { Decoration as Decoration6, EditorView as EditorView18, WidgetType as WidgetType4 } from "@codemirror/view";
4779
4732
  var table = (options = {}) => {
4780
- return StateField10.define({
4733
+ return StateField9.define({
4781
4734
  create: (state) => update(state, options),
4782
4735
  update: (_, tr) => update(tr.state, options),
4783
- provide: (field) => EditorView19.decorations.from(field)
4736
+ provide: (field) => EditorView18.decorations.from(field)
4784
4737
  });
4785
4738
  };
4786
4739
  var update = (state, _options) => {
4787
- const builder = new RangeSetBuilder3();
4740
+ const builder = new RangeSetBuilder2();
4788
4741
  const cursor = state.selection.main.head;
4789
4742
  const tables = [];
4790
4743
  const getTable = () => tables[tables.length - 1];
@@ -4792,7 +4745,7 @@ var update = (state, _options) => {
4792
4745
  const table2 = getTable();
4793
4746
  return table2.rows?.[table2.rows.length - 1];
4794
4747
  };
4795
- syntaxTree7(state).iterate({
4748
+ syntaxTree6(state).iterate({
4796
4749
  enter: (node) => {
4797
4750
  switch (node.name) {
4798
4751
  case "Table": {
@@ -4825,19 +4778,19 @@ var update = (state, _options) => {
4825
4778
  tables.forEach((table2) => {
4826
4779
  const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
4827
4780
  if (replace) {
4828
- builder.add(table2.from, table2.to, Decoration7.replace({
4781
+ builder.add(table2.from, table2.to, Decoration6.replace({
4829
4782
  block: true,
4830
4783
  widget: new TableWidget(table2)
4831
4784
  }));
4832
4785
  } else {
4833
- builder.add(table2.from, table2.to, Decoration7.mark({
4786
+ builder.add(table2.from, table2.to, Decoration6.mark({
4834
4787
  class: "cm-table"
4835
4788
  }));
4836
4789
  }
4837
4790
  });
4838
4791
  return builder.finish();
4839
4792
  };
4840
- var TableWidget = class extends WidgetType5 {
4793
+ var TableWidget = class extends WidgetType4 {
4841
4794
  constructor(_table) {
4842
4795
  super();
4843
4796
  this._table = _table;
@@ -4879,14 +4832,14 @@ var Unicode = {
4879
4832
  bulletSmall: "\u2219",
4880
4833
  bulletSquare: "\u2B1D"
4881
4834
  };
4882
- var HorizontalRuleWidget = class extends WidgetType6 {
4835
+ var HorizontalRuleWidget = class extends WidgetType5 {
4883
4836
  toDOM() {
4884
4837
  const el = document.createElement("span");
4885
4838
  el.className = "cm-hr";
4886
4839
  return el;
4887
4840
  }
4888
4841
  };
4889
- var LinkButton = class extends WidgetType6 {
4842
+ var LinkButton = class extends WidgetType5 {
4890
4843
  constructor(url, render) {
4891
4844
  super();
4892
4845
  this.url = url;
@@ -4898,11 +4851,13 @@ var LinkButton = class extends WidgetType6 {
4898
4851
  // TODO(burdon): Create icon and link directly without react?
4899
4852
  toDOM(view) {
4900
4853
  const el = document.createElement("span");
4901
- this.render(el, this.url);
4854
+ this.render(el, {
4855
+ url: this.url
4856
+ }, view);
4902
4857
  return el;
4903
4858
  }
4904
4859
  };
4905
- var CheckboxWidget = class extends WidgetType6 {
4860
+ var CheckboxWidget = class extends WidgetType5 {
4906
4861
  constructor(_checked) {
4907
4862
  super();
4908
4863
  this._checked = _checked;
@@ -4947,7 +4902,7 @@ var CheckboxWidget = class extends WidgetType6 {
4947
4902
  return false;
4948
4903
  }
4949
4904
  };
4950
- var TextWidget = class extends WidgetType6 {
4905
+ var TextWidget = class extends WidgetType5 {
4951
4906
  constructor(text, className) {
4952
4907
  super();
4953
4908
  this.text = text;
@@ -4962,29 +4917,29 @@ var TextWidget = class extends WidgetType6 {
4962
4917
  return el;
4963
4918
  }
4964
4919
  };
4965
- var hide = Decoration8.replace({});
4966
- var blockQuote = Decoration8.line({
4967
- class: mx4("cm-blockquote")
4920
+ var hide = Decoration7.replace({});
4921
+ var blockQuote = Decoration7.line({
4922
+ class: mx3("cm-blockquote")
4968
4923
  });
4969
- var fencedCodeLine = Decoration8.line({
4970
- class: mx4("cm-code cm-codeblock-line")
4924
+ var fencedCodeLine = Decoration7.line({
4925
+ class: mx3("cm-code cm-codeblock-line")
4971
4926
  });
4972
- var fencedCodeLineFirst = Decoration8.line({
4973
- class: mx4("cm-code cm-codeblock-line", "cm-codeblock-first")
4927
+ var fencedCodeLineFirst = Decoration7.line({
4928
+ class: mx3("cm-code cm-codeblock-line", "cm-codeblock-first")
4974
4929
  });
4975
- var fencedCodeLineLast = Decoration8.line({
4976
- class: mx4("cm-code cm-codeblock-line", "cm-codeblock-last")
4930
+ var fencedCodeLineLast = Decoration7.line({
4931
+ class: mx3("cm-code cm-codeblock-line", "cm-codeblock-last")
4977
4932
  });
4978
4933
  var commentBlockLine = fencedCodeLine;
4979
4934
  var commentBlockLineFirst = fencedCodeLineFirst;
4980
4935
  var commentBlockLineLast = fencedCodeLineLast;
4981
- var horizontalRule = Decoration8.replace({
4936
+ var horizontalRule = Decoration7.replace({
4982
4937
  widget: new HorizontalRuleWidget()
4983
4938
  });
4984
- var checkedTask = Decoration8.replace({
4939
+ var checkedTask = Decoration7.replace({
4985
4940
  widget: new CheckboxWidget(true)
4986
4941
  });
4987
- var uncheckedTask = Decoration8.replace({
4942
+ var uncheckedTask = Decoration7.replace({
4988
4943
  widget: new CheckboxWidget(false)
4989
4944
  });
4990
4945
  var editingRange = (state, range, focus2) => {
@@ -4999,15 +4954,15 @@ var autoHideTags = /* @__PURE__ */ new Set([
4999
4954
  "SubscriptMark",
5000
4955
  "SuperscriptMark"
5001
4956
  ]);
5002
- var buildDecorations3 = (view, options, focus2) => {
5003
- const deco = new RangeSetBuilder4();
5004
- const atomicDeco = new RangeSetBuilder4();
4957
+ var buildDecorations2 = (view, options, focus2) => {
4958
+ const deco = new RangeSetBuilder3();
4959
+ const atomicDeco = new RangeSetBuilder3();
5005
4960
  const { state } = view;
5006
4961
  const headerLevels = [];
5007
4962
  const getHeaderLevels = (node, level) => {
5008
4963
  invariant4(level > 0, void 0, {
5009
4964
  F: __dxlog_file9,
5010
- L: 178,
4965
+ L: 179,
5011
4966
  S: void 0,
5012
4967
  A: [
5013
4968
  "level > 0",
@@ -5046,7 +5001,7 @@ var buildDecorations3 = (view, options, focus2) => {
5046
5001
  const getCurrentListLevel = () => {
5047
5002
  invariant4(listLevels.length, void 0, {
5048
5003
  F: __dxlog_file9,
5049
- L: 200,
5004
+ L: 201,
5050
5005
  S: void 0,
5051
5006
  A: [
5052
5007
  "listLevels.length",
@@ -5088,7 +5043,7 @@ var buildDecorations3 = (view, options, focus2) => {
5088
5043
  } else {
5089
5044
  const num = headers.slice(from - 1).map((level2) => level2?.number ?? 0).join(".") + " ";
5090
5045
  if (num.length) {
5091
- atomicDeco.add(mark.from, mark.from + len, Decoration8.replace({
5046
+ atomicDeco.add(mark.from, mark.from + len, Decoration7.replace({
5092
5047
  widget: new TextWidget(num, theme.heading(level))
5093
5048
  }));
5094
5049
  }
@@ -5113,7 +5068,7 @@ var buildDecorations3 = (view, options, focus2) => {
5113
5068
  if (node.from === line.to - 1) {
5114
5069
  return false;
5115
5070
  }
5116
- deco.add(line.from, line.from, Decoration8.line({
5071
+ deco.add(line.from, line.from, Decoration7.line({
5117
5072
  class: "cm-list-item",
5118
5073
  attributes: {
5119
5074
  style: `padding-left: ${offset}px; text-indent: -${width}px;`
@@ -5130,7 +5085,7 @@ var buildDecorations3 = (view, options, focus2) => {
5130
5085
  const label = list.type === "OrderedList" ? `${++list.number}.` : Unicode.bulletSmall;
5131
5086
  const line = state.doc.lineAt(node.from);
5132
5087
  const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
5133
- atomicDeco.add(line.from, to, Decoration8.replace({
5088
+ atomicDeco.add(line.from, to, Decoration7.replace({
5134
5089
  widget: new TextWidget(label, list.type === "OrderedList" ? "cm-list-mark cm-list-mark-ordered" : "cm-list-mark cm-list-mark-bullet")
5135
5090
  }));
5136
5091
  break;
@@ -5217,7 +5172,7 @@ var buildDecorations3 = (view, options, focus2) => {
5217
5172
  if (!editing) {
5218
5173
  atomicDeco.add(node.from, marks[0].to, hide);
5219
5174
  }
5220
- deco.add(marks[0].to, marks[1].from, Decoration8.mark({
5175
+ deco.add(marks[0].to, marks[1].from, Decoration7.mark({
5221
5176
  tagName: "a",
5222
5177
  attributes: {
5223
5178
  class: "cm-link",
@@ -5227,7 +5182,7 @@ var buildDecorations3 = (view, options, focus2) => {
5227
5182
  }
5228
5183
  }));
5229
5184
  if (!editing) {
5230
- atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration8.replace({
5185
+ atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration7.replace({
5231
5186
  widget: new LinkButton(url, options.renderLinkButton)
5232
5187
  }) : hide);
5233
5188
  }
@@ -5261,7 +5216,7 @@ var buildDecorations3 = (view, options, focus2) => {
5261
5216
  }
5262
5217
  }
5263
5218
  };
5264
- const tree = syntaxTree8(state);
5219
+ const tree = syntaxTree7(state);
5265
5220
  if (options.numberedHeadings?.from === void 0) {
5266
5221
  for (const { from, to } of view.visibleRanges) {
5267
5222
  tree.iterate({
@@ -5287,11 +5242,11 @@ var decorateMarkdown = (options = {}) => {
5287
5242
  return [
5288
5243
  ViewPlugin7.fromClass(class {
5289
5244
  constructor(view) {
5290
- ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations3(view, options, view.hasFocus));
5245
+ ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(view, options, view.hasFocus));
5291
5246
  }
5292
5247
  update(update2) {
5293
5248
  if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((effect) => effect.is(forceUpdate))) || update2.selectionSet && !options.selectionChangeDelay) {
5294
- ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations3(update2.view, options, update2.view.hasFocus));
5249
+ ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations2(update2.view, options, update2.view.hasFocus));
5295
5250
  this.clearUpdate();
5296
5251
  } else if (update2.selectionSet) {
5297
5252
  this.scheduleUpdate(update2.view);
@@ -5317,9 +5272,9 @@ var decorateMarkdown = (options = {}) => {
5317
5272
  }
5318
5273
  }, {
5319
5274
  provide: (plugin) => [
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)
5275
+ EditorView19.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
5276
+ EditorView19.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
5277
+ EditorView19.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
5323
5278
  ]
5324
5279
  }),
5325
5280
  image(),
@@ -5330,12 +5285,12 @@ var decorateMarkdown = (options = {}) => {
5330
5285
  };
5331
5286
 
5332
5287
  // packages/ui/react-ui-editor/src/extensions/markdown/link.ts
5333
- import { syntaxTree as syntaxTree9 } from "@codemirror/language";
5288
+ import { syntaxTree as syntaxTree8 } from "@codemirror/language";
5334
5289
  import { hoverTooltip as hoverTooltip2 } from "@codemirror/view";
5335
5290
  import { tooltipContent } from "@dxos/react-ui-theme";
5336
- var linkTooltip = (render) => {
5291
+ var linkTooltip = (renderTooltip) => {
5337
5292
  return hoverTooltip2((view, pos, side) => {
5338
- const syntax = syntaxTree9(view.state).resolveInner(pos, side);
5293
+ const syntax = syntaxTree8(view.state).resolveInner(pos, side);
5339
5294
  let link = null;
5340
5295
  for (let i = 0, node = syntax; !link && node && i < 5; node = node.parent, i++) {
5341
5296
  link = node.name === "Link" ? node : null;
@@ -5348,11 +5303,14 @@ var linkTooltip = (render) => {
5348
5303
  return {
5349
5304
  pos: link.from,
5350
5305
  end: link.to,
5351
- above: true,
5306
+ // NOTE: Forcing above causes the tooltip to flicker.
5307
+ // above: true,
5352
5308
  create: () => {
5353
5309
  const el = document.createElement("div");
5354
- el.className = tooltipContent({}, "pli-2 plb-1");
5355
- render(el, urlText);
5310
+ el.className = tooltipContent({});
5311
+ renderTooltip(el, {
5312
+ url: urlText
5313
+ }, view);
5356
5314
  return {
5357
5315
  dom: el,
5358
5316
  offset: {
@@ -5362,6 +5320,9 @@ var linkTooltip = (render) => {
5362
5320
  };
5363
5321
  }
5364
5322
  };
5323
+ }, {
5324
+ // NOTE: 0 = default of 300ms.
5325
+ hoverTime: 1
5365
5326
  });
5366
5327
  };
5367
5328
 
@@ -5449,6 +5410,165 @@ var InputModeExtensions = {
5449
5410
  ]
5450
5411
  };
5451
5412
 
5413
+ // packages/ui/react-ui-editor/src/extensions/preview/preview.ts
5414
+ import "@dxos/lit-ui/dx-ref-tag.pcss";
5415
+ import { syntaxTree as syntaxTree9 } from "@codemirror/language";
5416
+ import { RangeSetBuilder as RangeSetBuilder4, StateField as StateField10 } from "@codemirror/state";
5417
+ import { Decoration as Decoration8, EditorView as EditorView20, WidgetType as WidgetType6 } from "@codemirror/view";
5418
+ var preview = (options = {}) => {
5419
+ return [
5420
+ // NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:
5421
+ // "Block decorations may not be specified via plugins"
5422
+ StateField10.define({
5423
+ create: (state) => buildDecorations3(state, options),
5424
+ update: (_, tr) => buildDecorations3(tr.state, options),
5425
+ provide: (field) => [
5426
+ EditorView20.decorations.from(field),
5427
+ EditorView20.atomicRanges.of((view) => view.state.field(field))
5428
+ ]
5429
+ }),
5430
+ EditorView20.theme({
5431
+ ".cm-preview-block": {
5432
+ marginLeft: "-1rem",
5433
+ marginRight: "-1rem",
5434
+ padding: "1rem",
5435
+ borderRadius: "0.5rem",
5436
+ background: "var(--dx-modalSurface)",
5437
+ border: "1px solid var(--dx-separator)"
5438
+ }
5439
+ })
5440
+ ];
5441
+ };
5442
+ var getLinkRef = (state, node) => {
5443
+ const mark = node.getChild("LinkMark");
5444
+ const label = node.getChild("LinkLabel");
5445
+ if (mark && label) {
5446
+ const ref = state.sliceDoc(label.from + 1, label.to - 1);
5447
+ return {
5448
+ suggest: ref.startsWith("?"),
5449
+ block: state.sliceDoc(mark.from, mark.from + 1) === "!",
5450
+ label: state.sliceDoc(mark.to, label.from - 1),
5451
+ ref: ref.startsWith("?") ? ref.slice(1) : ref
5452
+ };
5453
+ }
5454
+ };
5455
+ var buildDecorations3 = (state, options) => {
5456
+ const builder = new RangeSetBuilder4();
5457
+ syntaxTree9(state).iterate({
5458
+ enter: (node) => {
5459
+ switch (node.name) {
5460
+ //
5461
+ // Decoration.
5462
+ // [Label][dxn:echo:123]
5463
+ //
5464
+ case "Link": {
5465
+ const link = getLinkRef(state, node.node);
5466
+ if (link) {
5467
+ builder.add(node.from, node.to, Decoration8.replace({
5468
+ widget: new PreviewInlineWidget(options, link)
5469
+ }));
5470
+ }
5471
+ break;
5472
+ }
5473
+ //
5474
+ // Block widget.
5475
+ // ![Label][dxn:echo:123]
5476
+ //
5477
+ case "Image": {
5478
+ const link = getLinkRef(state, node.node);
5479
+ if (options.renderBlock && link) {
5480
+ builder.add(node.from, node.to, Decoration8.replace({
5481
+ block: true,
5482
+ // atomic: true,
5483
+ widget: new PreviewBlockWidget(options, link)
5484
+ }));
5485
+ }
5486
+ break;
5487
+ }
5488
+ }
5489
+ }
5490
+ });
5491
+ return builder.finish();
5492
+ };
5493
+ var PreviewInlineWidget = class extends WidgetType6 {
5494
+ constructor(_options, _link) {
5495
+ super();
5496
+ this._options = _options;
5497
+ this._link = _link;
5498
+ }
5499
+ // override ignoreEvent() {
5500
+ // return false;
5501
+ // }
5502
+ eq(other) {
5503
+ return this._link.ref === other._link.ref && this._link.label === other._link.label;
5504
+ }
5505
+ toDOM(view) {
5506
+ const root = document.createElement("dx-ref-tag");
5507
+ root.setAttribute("label", this._link.label);
5508
+ root.setAttribute("ref", this._link.ref);
5509
+ return root;
5510
+ }
5511
+ };
5512
+ var PreviewBlockWidget = class extends WidgetType6 {
5513
+ constructor(_options, _link) {
5514
+ super();
5515
+ this._options = _options;
5516
+ this._link = _link;
5517
+ }
5518
+ // override ignoreEvent() {
5519
+ // return true;
5520
+ // }
5521
+ eq(other) {
5522
+ return this._link.ref === other._link.ref;
5523
+ }
5524
+ toDOM(view) {
5525
+ const root = document.createElement("div");
5526
+ root.classList.add("cm-preview-block");
5527
+ const handleAction = (action) => {
5528
+ const pos = view.posAtDOM(root);
5529
+ const node = syntaxTree9(view.state).resolve(pos + 1).node.parent;
5530
+ if (!node) {
5531
+ return;
5532
+ }
5533
+ const link = getLinkRef(view.state, node);
5534
+ if (link?.ref !== action.link.ref) {
5535
+ return;
5536
+ }
5537
+ switch (action.type) {
5538
+ // TODO(burdon): Should we dispatch to the view or mutate the document? (i.e., handle externally?)
5539
+ // Insert ref text.
5540
+ case "insert": {
5541
+ view.dispatch({
5542
+ changes: {
5543
+ from: node.from,
5544
+ to: node.to,
5545
+ insert: action.target.text
5546
+ }
5547
+ });
5548
+ break;
5549
+ }
5550
+ // Remove ref.
5551
+ case "delete": {
5552
+ view.dispatch({
5553
+ changes: {
5554
+ from: node.from,
5555
+ to: node.to
5556
+ }
5557
+ });
5558
+ break;
5559
+ }
5560
+ }
5561
+ };
5562
+ this._options.renderBlock(root, {
5563
+ readonly: view.state.readOnly,
5564
+ link: this._link,
5565
+ onAction: handleAction,
5566
+ onLookup: this._options.onLookup
5567
+ }, view);
5568
+ return root;
5569
+ }
5570
+ };
5571
+
5452
5572
  // packages/ui/react-ui-editor/src/extensions/typewriter.ts
5453
5573
  import { keymap as keymap10 } from "@codemirror/view";
5454
5574
  var defaultItems = [
@@ -5524,7 +5644,7 @@ import { getProviderValue, isNotFalsy as isNotFalsy4 } from "@dxos/util";
5524
5644
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
5525
5645
  var instanceCount = 0;
5526
5646
  var useTextEditor = (props = {}, deps = []) => {
5527
- const { id, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo4(() => getProviderValue(props), deps ?? []);
5647
+ const { id, doc, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } = useMemo4(() => getProviderValue(props), deps ?? []);
5528
5648
  const [instanceId] = useState(() => `text-editor-${++instanceCount}`);
5529
5649
  const [view, setView] = useState();
5530
5650
  const parentRef = useRef(null);
@@ -5537,7 +5657,7 @@ var useTextEditor = (props = {}, deps = []) => {
5537
5657
  doc: initialValue?.length ?? 0
5538
5658
  }, {
5539
5659
  F: __dxlog_file11,
5540
- L: 75,
5660
+ L: 76,
5541
5661
  S: void 0,
5542
5662
  C: (f, a) => f(...a)
5543
5663
  });
@@ -5554,7 +5674,7 @@ var useTextEditor = (props = {}, deps = []) => {
5554
5674
  };
5555
5675
  }
5556
5676
  const state = EditorState2.create({
5557
- doc: initialValue,
5677
+ doc: doc ?? initialValue,
5558
5678
  // selection: initialSelection,
5559
5679
  extensions: [
5560
5680
  id && documentId.of(id),
@@ -5563,7 +5683,7 @@ var useTextEditor = (props = {}, deps = []) => {
5563
5683
  EditorView21.exceptionSink.of((err) => {
5564
5684
  log7.catch(err, void 0, {
5565
5685
  F: __dxlog_file11,
5566
- L: 97,
5686
+ L: 98,
5567
5687
  S: void 0,
5568
5688
  C: (f, a) => f(...a)
5569
5689
  });
@@ -5595,7 +5715,7 @@ var useTextEditor = (props = {}, deps = []) => {
5595
5715
  id
5596
5716
  }, {
5597
5717
  F: __dxlog_file11,
5598
- L: 134,
5718
+ L: 135,
5599
5719
  S: void 0,
5600
5720
  C: (f, a) => f(...a)
5601
5721
  });
@@ -5612,7 +5732,7 @@ var useTextEditor = (props = {}, deps = []) => {
5612
5732
  selection
5613
5733
  }, {
5614
5734
  F: __dxlog_file11,
5615
- L: 143,
5735
+ L: 144,
5616
5736
  S: void 0,
5617
5737
  C: (f, a) => f(...a)
5618
5738
  });
@@ -5694,7 +5814,10 @@ export {
5694
5814
  blast,
5695
5815
  callbackWrapper,
5696
5816
  clientRectsFor,
5817
+ closeCommand,
5818
+ closeEffect,
5697
5819
  command,
5820
+ commandKeyBindings,
5698
5821
  comments,
5699
5822
  commentsState,
5700
5823
  convertTreeToJson,
@@ -5708,6 +5831,7 @@ export {
5708
5831
  createElement,
5709
5832
  createExternalCommentSync,
5710
5833
  createMarkdownExtensions,
5834
+ createRenderer,
5711
5835
  createThemeExtensions,
5712
5836
  debugDispatcher,
5713
5837
  debugNodeLogger,
@@ -5721,6 +5845,7 @@ export {
5721
5845
  editorGutter,
5722
5846
  editorInputMode,
5723
5847
  editorMonospace,
5848
+ editorWidth,
5724
5849
  editorWithToolbarLayout,
5725
5850
  flattenRect,
5726
5851
  focus,
@@ -5739,8 +5864,11 @@ export {
5739
5864
  markdownTags,
5740
5865
  markdownTagsExtensions,
5741
5866
  mention,
5867
+ openCommand,
5868
+ openEffect,
5742
5869
  overlap,
5743
5870
  preventNewline,
5871
+ preview,
5744
5872
  processEditorPayload,
5745
5873
  removeBlockquote,
5746
5874
  removeCodeblock,
@@ -5758,7 +5886,7 @@ export {
5758
5886
  setStyle,
5759
5887
  singleValueFacet,
5760
5888
  stackItemContentEditorClassNames,
5761
- stackItemContentToolbarClassNames2 as stackItemContentToolbarClassNames,
5889
+ stackItemContentToolbarClassNames,
5762
5890
  table,
5763
5891
  tags2 as tags,
5764
5892
  textRange,