@dxos/react-ui-editor 0.8.4-main.bc674ce → 0.8.4-main.bcb3aa67d6

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 (90) hide show
  1. package/dist/lib/browser/index.mjs +298 -377
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +298 -377
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/components/Editor/Editor.d.ts.map +1 -1
  8. package/dist/types/src/components/EditorMenuProvider/EditorMenuProvider.d.ts +1 -3
  9. package/dist/types/src/components/EditorMenuProvider/EditorMenuProvider.d.ts.map +1 -1
  10. package/dist/types/src/components/EditorMenuProvider/menu-presets.d.ts.map +1 -1
  11. package/dist/types/src/components/EditorMenuProvider/useEditorMenu.d.ts.map +1 -1
  12. package/dist/types/src/components/EditorPreviewProvider/EditorPreviewProvider.d.ts.map +1 -1
  13. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
  14. package/dist/types/src/components/EditorToolbar/blocks.d.ts +3 -17
  15. package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
  16. package/dist/types/src/components/EditorToolbar/formatting.d.ts +3 -17
  17. package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
  18. package/dist/types/src/components/EditorToolbar/headings.d.ts +3 -17
  19. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
  20. package/dist/types/src/components/EditorToolbar/image.d.ts +3 -8
  21. package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -1
  22. package/dist/types/src/components/EditorToolbar/index.d.ts +0 -1
  23. package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -1
  24. package/dist/types/src/components/EditorToolbar/lists.d.ts +6 -0
  25. package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -0
  26. package/dist/types/src/components/EditorToolbar/search.d.ts +3 -8
  27. package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -1
  28. package/dist/types/src/components/EditorToolbar/view-mode.d.ts +3 -17
  29. package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -1
  30. package/dist/types/src/stories/Automerge.stories.d.ts +25 -24
  31. package/dist/types/src/stories/Automerge.stories.d.ts.map +1 -1
  32. package/dist/types/src/stories/Comments.stories.d.ts +1 -1
  33. package/dist/types/src/stories/EditorToolbar.stories.d.ts +26 -26
  34. package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -1
  35. package/dist/types/src/stories/Experimental.stories.d.ts +1 -1
  36. package/dist/types/src/stories/Markdown.stories.d.ts +1 -1
  37. package/dist/types/src/stories/Outliner.stories.d.ts +2 -2
  38. package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -1
  39. package/dist/types/src/stories/Popover.stories.d.ts +2 -2
  40. package/dist/types/src/stories/Popover.stories.d.ts.map +1 -1
  41. package/dist/types/src/stories/Preview.stories.d.ts +1 -1
  42. package/dist/types/src/stories/Preview.stories.d.ts.map +1 -1
  43. package/dist/types/src/stories/TextEditor.stories.d.ts +1 -1
  44. package/dist/types/src/stories/components/EditorStory.d.ts +3 -3
  45. package/dist/types/src/stories/components/EditorStory.d.ts.map +1 -1
  46. package/dist/types/src/stories/components/util.d.ts +3 -3
  47. package/dist/types/src/stories/components/util.d.ts.map +1 -1
  48. package/dist/types/src/translations.d.ts +24 -24
  49. package/dist/types/src/translations.d.ts.map +1 -1
  50. package/dist/types/src/util/react.d.ts +1 -4
  51. package/dist/types/src/util/react.d.ts.map +1 -1
  52. package/dist/types/tsconfig.tsbuildinfo +1 -1
  53. package/package.json +45 -45
  54. package/src/components/Editor/Editor.stories.tsx +2 -2
  55. package/src/components/Editor/Editor.tsx +12 -6
  56. package/src/components/EditorContent/EditorContent.tsx +1 -1
  57. package/src/components/EditorMenuProvider/EditorMenuProvider.tsx +21 -28
  58. package/src/components/EditorMenuProvider/menu-presets.ts +1 -0
  59. package/src/components/EditorMenuProvider/useEditorMenu.ts +8 -1
  60. package/src/components/EditorPreviewProvider/EditorPreviewProvider.tsx +5 -7
  61. package/src/components/EditorToolbar/EditorToolbar.tsx +24 -61
  62. package/src/components/EditorToolbar/blocks.ts +54 -46
  63. package/src/components/EditorToolbar/formatting.ts +43 -44
  64. package/src/components/EditorToolbar/headings.ts +42 -48
  65. package/src/components/EditorToolbar/image.ts +16 -21
  66. package/src/components/EditorToolbar/index.ts +0 -1
  67. package/src/components/EditorToolbar/lists.ts +57 -0
  68. package/src/components/EditorToolbar/search.ts +16 -21
  69. package/src/components/EditorToolbar/view-mode.ts +34 -40
  70. package/src/stories/Automerge.stories.tsx +8 -10
  71. package/src/stories/Comments.stories.tsx +4 -4
  72. package/src/stories/EditorToolbar.stories.tsx +32 -17
  73. package/src/stories/Experimental.stories.tsx +3 -3
  74. package/src/stories/Markdown.stories.tsx +2 -2
  75. package/src/stories/Outliner.stories.tsx +4 -4
  76. package/src/stories/Popover.stories.tsx +6 -6
  77. package/src/stories/Preview.stories.tsx +58 -48
  78. package/src/stories/Tags.stories.tsx +5 -5
  79. package/src/stories/TextEditor.stories.tsx +2 -2
  80. package/src/stories/Theme.stories.tsx +2 -2
  81. package/src/stories/components/EditorStory.tsx +17 -12
  82. package/src/stories/components/util.tsx +19 -22
  83. package/src/translations.ts +29 -24
  84. package/src/util/react.tsx +2 -11
  85. package/dist/types/src/components/EditorToolbar/actions.d.ts +0 -24
  86. package/dist/types/src/components/EditorToolbar/actions.d.ts.map +0 -1
  87. package/dist/types/src/stories/CommandDialog.stories.d.ts +0 -14
  88. package/dist/types/src/stories/CommandDialog.stories.d.ts.map +0 -1
  89. package/src/components/EditorToolbar/actions.ts +0 -87
  90. package/src/stories/CommandDialog.stories.tsx +0 -81
@@ -6,30 +6,30 @@ var translations = [
6
6
  {
7
7
  "en-US": {
8
8
  [translationKey]: {
9
- "strong label": "Bold",
10
- "emphasis label": "Italics",
11
- "strikethrough label": "Strikethrough",
12
- "code label": "Code",
13
- "link label": "Link",
14
- "list-bullet label": "Bullet list",
15
- "list-ordered label": "Numbered list",
16
- "list-task label": "Task list",
17
- "blockquote label": "Block quote",
18
- "codeblock label": "Code block",
19
- "comment label": "Create comment",
20
- "selection overlaps existing comment label": "Selection overlaps existing comment",
21
- "select text to comment label": "Select text to comment",
22
- "image label": "Insert image",
23
- "table label": "Create table",
24
- "heading label": "Heading level",
25
- "heading level label_zero": "Paragraph",
26
- "heading level label_one": "Heading level {{count}}",
27
- "heading level label_other": "Heading level {{count}}",
28
- "search label": "Search",
29
- "view mode label": "Editor view",
30
- "preview mode label": "Markdown",
31
- "readonly mode label": "Read only",
32
- "source mode label": "Plain text"
9
+ "comment.label": "Create comment",
10
+ "image.label": "Insert image",
11
+ "search.label": "Search",
12
+ "block.label": "Block",
13
+ "block.blockquote.label": "Block quote",
14
+ "block.codeblock.label": "Code block",
15
+ "block.table.label": "Create table",
16
+ "formatting.label": "Formatting",
17
+ "formatting.strong.label": "Bold",
18
+ "formatting.emphasis.label": "Italics",
19
+ "formatting.strikethrough.label": "Strikethrough",
20
+ "formatting.code.label": "Code",
21
+ "formatting.link.label": "Link",
22
+ "list.bullet.label": "Bullet list",
23
+ "list.ordered.label": "Numbered list",
24
+ "list.task.label": "Task list",
25
+ "heading.label": "Heading level",
26
+ "heading-level.label_zero": "Paragraph",
27
+ "heading-level.label_one": "Heading level {{count}}",
28
+ "heading-level.label_other": "Heading level {{count}}",
29
+ "view-mode.label": "Editor view",
30
+ "view-mode.preview.label": "Markdown",
31
+ "view-mode.source.label": "Plain text",
32
+ "view-mode.readonly.label": "Read only"
33
33
  }
34
34
  }
35
35
  }
@@ -298,7 +298,7 @@ var EditorContent = /* @__PURE__ */ forwardRef(({ classNames, id, extensions, se
298
298
  ]);
299
299
  return /* @__PURE__ */ React.createElement("div", {
300
300
  role: "none",
301
- className: mx("is-full outline-none focus:border-accentSurface focus-within:border-neutralFocusIndicator", classNames),
301
+ className: mx("w-full outline-hidden focus:border-accent-surface focus-within:border-neutral-focus-indicator", classNames),
302
302
  ref: parentRef,
303
303
  ...focusable ? focusAttributes : {}
304
304
  });
@@ -704,7 +704,7 @@ import { useControllableState } from "@radix-ui/react-use-controllable-state";
704
704
  import React2, { Fragment, useCallback as useCallback2, useEffect as useEffect3, useRef as useRef2, useState as useState2 } from "react";
705
705
  import { addEventListener } from "@dxos/async";
706
706
  import { invariant } from "@dxos/invariant";
707
- import { DX_ANCHOR_ACTIVATE, Icon, Popover, toLocalizedString, useDynamicRef, useThemeContext, useTranslation } from "@dxos/react-ui";
707
+ import { DX_ANCHOR_ACTIVATE, Icon, Popover, ScrollArea, toLocalizedString, useDynamicRef, useThemeContext, useTranslation } from "@dxos/react-ui";
708
708
  var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-editor/src/components/EditorMenuProvider/EditorMenuProvider.tsx";
709
709
  var EditorMenuProvider = ({ children, view, groups, currentItem, open: openProp, defaultOpen, numItems = 8, onOpenChange, onActivate, onSelect, onCancel }) => {
710
710
  const { tx } = useThemeContext();
@@ -716,7 +716,7 @@ var EditorMenuProvider = ({ children, view, groups, currentItem, open: openProp,
716
716
  onChange: (open2) => {
717
717
  invariant(viewRef.current, void 0, {
718
718
  F: __dxlog_file2,
719
- L: 65,
719
+ L: 64,
720
720
  S: void 0,
721
721
  A: [
722
722
  "viewRef.current",
@@ -735,8 +735,8 @@ var EditorMenuProvider = ({ children, view, groups, currentItem, open: openProp,
735
735
  return;
736
736
  }
737
737
  return addEventListener(root, DX_ANCHOR_ACTIVATE, (event) => {
738
- const { trigger, refId } = event;
739
- if (!refId) {
738
+ const { trigger, dxn } = event;
739
+ if (!dxn) {
740
740
  triggerRef.current = trigger;
741
741
  if (onActivate) {
742
742
  onActivate({
@@ -758,7 +758,7 @@ var EditorMenuProvider = ({ children, view, groups, currentItem, open: openProp,
758
758
  const handleSelect = useCallback2((item) => {
759
759
  invariant(viewRef.current, void 0, {
760
760
  F: __dxlog_file2,
761
- L: 102,
761
+ L: 99,
762
762
  S: void 0,
763
763
  A: [
764
764
  "viewRef.current",
@@ -782,34 +782,36 @@ var EditorMenuProvider = ({ children, view, groups, currentItem, open: openProp,
782
782
  virtualRef: triggerRef
783
783
  }), /* @__PURE__ */ React2.createElement(Popover.Portal, null, /* @__PURE__ */ React2.createElement(Popover.Content, {
784
784
  align: "start",
785
- classNames: tx("menu.content", "menu--exotic-unfocusable", {
786
- elevation: "positioned"
787
- }, [
788
- "overflow-y-auto",
785
+ classNames: [
786
+ "flex flex-col",
789
787
  !menuGroups.length && "hidden"
790
- ]),
788
+ ],
791
789
  style: {
792
790
  maxBlockSize: 36 * numItems + 10
793
791
  },
794
- /**
795
- * NOTE: We keep the focus in the editor, but Radix routes escape key.
796
- */
792
+ // NOTE: We keep the focus in the editor, but Radix routes escape key.
797
793
  onEscapeKeyDown: () => {
798
- onCancel?.({
799
- view
800
- });
794
+ const currentView = viewRef.current;
795
+ if (currentView) {
796
+ onCancel?.({
797
+ view: currentView
798
+ });
799
+ }
801
800
  },
802
801
  onOpenAutoFocus: (event) => event.preventDefault()
803
802
  }, /* @__PURE__ */ React2.createElement(Popover.Viewport, {
804
- classNames: tx("menu.viewport", "menu__viewport--exotic-unfocusable", {})
805
- }, /* @__PURE__ */ React2.createElement(Menu, {
803
+ asChild: true,
804
+ classNames: "dx-container"
805
+ }, /* @__PURE__ */ React2.createElement(ScrollArea.Root, {
806
+ thin: true
807
+ }, /* @__PURE__ */ React2.createElement(ScrollArea.Viewport, null, /* @__PURE__ */ React2.createElement(Menu, {
806
808
  groups: menuGroups,
807
809
  currentItem,
808
810
  onSelect: handleSelect
809
- })), /* @__PURE__ */ React2.createElement(Popover.Arrow, null))), /* @__PURE__ */ React2.createElement("div", {
810
- ref: setRoot,
811
+ })))), /* @__PURE__ */ React2.createElement(Popover.Arrow, null))), /* @__PURE__ */ React2.createElement("div", {
811
812
  role: "none",
812
- className: "contents"
813
+ className: "contents",
814
+ ref: setRoot
813
815
  }, children));
814
816
  };
815
817
  var Menu = ({ groups, currentItem, onSelect }) => {
@@ -821,14 +823,14 @@ var Menu = ({ groups, currentItem, onSelect }) => {
821
823
  currentItem,
822
824
  onSelect
823
825
  }), index < groups.length - 1 && /* @__PURE__ */ React2.createElement("div", {
824
- className: tx("menu.separator", "menu__item", {})
826
+ className: tx("menu.separator", {})
825
827
  }))));
826
828
  };
827
829
  var MenuGroup = ({ group, currentItem, onSelect }) => {
828
830
  const { tx } = useThemeContext();
829
831
  const { t } = useTranslation();
830
832
  return /* @__PURE__ */ React2.createElement(React2.Fragment, null, group.label && /* @__PURE__ */ React2.createElement("div", {
831
- className: tx("menu.groupLabel", "menu__group__label", {})
833
+ className: tx("menu.groupLabel", {})
832
834
  }, /* @__PURE__ */ React2.createElement("span", null, toLocalizedString(group.label, t))), group.items.map((item) => /* @__PURE__ */ React2.createElement(MenuItem, {
833
835
  key: item.id,
834
836
  item,
@@ -856,13 +858,12 @@ var MenuItem = ({ item, current, onSelect }) => {
856
858
  ]);
857
859
  return /* @__PURE__ */ React2.createElement("li", {
858
860
  ref: listRef,
859
- className: tx("menu.item", "menu__item--exotic-unfocusable", {}, [
860
- current && "bg-hoverSurface"
861
+ className: tx("menu.item", {}, [
862
+ current && "bg-hover-surface"
861
863
  ]),
862
864
  onClick: handleSelect
863
865
  }, item.icon && /* @__PURE__ */ React2.createElement(Icon, {
864
- icon: item.icon,
865
- size: 5
866
+ icon: item.icon
866
867
  }), /* @__PURE__ */ React2.createElement("span", {
867
868
  className: "grow truncate"
868
869
  }, toLocalizedString(item.label, t)));
@@ -885,7 +886,7 @@ var useEditorMenu = ({ trigger, triggerKey, placeholder: placeholder2, filter =
885
886
  trigger: trigger2,
886
887
  ...props
887
888
  }) ?? [];
888
- return filter ? filterMenuGroups(groups, (item) => text ? item.label.toLowerCase().startsWith(text.toLowerCase()) : true) : groups;
889
+ return filter && trigger2 !== "@" ? filterMenuGroups(groups, (item) => text ? item.label.toLowerCase().startsWith(text.toLowerCase()) : true) : groups;
889
890
  }, [
890
891
  getMenu,
891
892
  filter
@@ -893,7 +894,7 @@ var useEditorMenu = ({ trigger, triggerKey, placeholder: placeholder2, filter =
893
894
  const handleOpenChange = useCallback3(async ({ view, open: open2 }) => {
894
895
  invariant2(view, void 0, {
895
896
  F: __dxlog_file3,
896
- L: 76,
897
+ L: 77,
897
898
  S: void 0,
898
899
  A: [
899
900
  "view",
@@ -936,10 +937,21 @@ var useEditorMenu = ({ trigger, triggerKey, placeholder: placeholder2, filter =
936
937
  handleOpenChange
937
938
  ]);
938
939
  const handleSelect = useCallback3(({ view, item }) => {
940
+ const { range } = view.state.field(popoverStateField) ?? {};
941
+ if (range) {
942
+ view.dispatch({
943
+ changes: {
944
+ from: range.from,
945
+ to: range.to,
946
+ insert: ""
947
+ }
948
+ });
949
+ }
939
950
  void item.onSelect?.({
940
951
  view,
941
952
  head: view.state.selection.main.head
942
953
  });
954
+ view.focus();
943
955
  }, []);
944
956
  const handleCancel = useCallback3(({ view }) => {
945
957
  const { range, trigger: trigger2 } = view.state.field(popoverStateField) ?? {};
@@ -1021,144 +1033,110 @@ var useEditorMenu = ({ trigger, triggerKey, placeholder: placeholder2, filter =
1021
1033
  import { Atom } from "@effect-atom/atom-react";
1022
1034
  import React3, { memo, useMemo as useMemo3 } from "react";
1023
1035
  import { ElevationProvider } from "@dxos/react-ui";
1024
- import { MenuProvider, ToolbarMenu, createGapSeparator, useMenuActions } from "@dxos/react-ui-menu";
1036
+ import { Menu as Menu2, MenuBuilder, useMenuActions } from "@dxos/react-ui-menu";
1025
1037
 
1026
- // src/components/EditorToolbar/actions.ts
1027
- import { createMenuAction, createMenuItemGroup } from "@dxos/react-ui-menu";
1038
+ // src/components/EditorToolbar/lists.ts
1028
1039
  import { List, addList, removeList } from "@dxos/ui-editor";
1029
1040
  var listStyles = {
1030
1041
  bullet: "ph--list-bullets--regular",
1031
1042
  ordered: "ph--list-numbers--regular",
1032
1043
  task: "ph--list-checks--regular"
1033
1044
  };
1034
- var createLists = (state, getView) => {
1045
+ var addLists = (state, getView) => (builder) => {
1035
1046
  const value = state.listStyle ?? "";
1036
- const listGroupAction = createListGroupAction(value);
1037
- const listActionsMap = createListActions(value, getView);
1038
- return {
1039
- nodes: [
1040
- listGroupAction,
1041
- ...listActionsMap
1042
- ],
1043
- edges: [
1047
+ builder.group("list", {
1048
+ label: [
1049
+ "list.label",
1044
1050
  {
1045
- source: "root",
1046
- target: "list"
1047
- },
1048
- ...listActionsMap.map(({ id }) => ({
1049
- source: listGroupAction.id,
1050
- target: id
1051
- }))
1052
- ]
1053
- };
1054
- };
1055
- var createEditorAction = (id, props, invoke) => {
1056
- const { label = [
1057
- `${id} label`,
1058
- {
1059
- ns: translationKey
1060
- }
1061
- ], ...rest } = props;
1062
- return createMenuAction(id, invoke, {
1063
- label,
1064
- ...rest
1065
- });
1066
- };
1067
- var createEditorActionGroup = (id, props, icon) => {
1068
- const { label = [
1069
- `${id} label`,
1070
- {
1071
- ns: translationKey
1072
- }
1073
- ], ...rest } = props;
1074
- return createMenuItemGroup(id, {
1075
- label,
1076
- icon,
1051
+ ns: translationKey
1052
+ }
1053
+ ],
1077
1054
  iconOnly: true,
1078
- ...rest
1079
- });
1080
- };
1081
- var createListGroupAction = (value) => createEditorActionGroup("list", {
1082
- variant: "toggleGroup",
1083
- selectCardinality: "single",
1084
- value
1085
- });
1086
- var createListActions = (value, getView) => Object.entries(listStyles).map(([listStyle, icon]) => {
1087
- const checked = value === listStyle;
1088
- return createEditorAction(`list-${listStyle}`, {
1089
- checked,
1090
- icon
1091
- }, () => {
1092
- const view = getView();
1093
- if (!view) {
1094
- return;
1095
- }
1096
- const listType = listStyle === "ordered" ? List.Ordered : listStyle === "bullet" ? List.Bullet : List.Task;
1097
- if (checked) {
1098
- removeList(listType)(view);
1099
- } else {
1100
- addList(listType)(view);
1055
+ variant: "toggleGroup",
1056
+ selectCardinality: "single",
1057
+ value
1058
+ }, (group) => {
1059
+ for (const [listStyle, icon] of Object.entries(listStyles)) {
1060
+ const checked = value === listStyle;
1061
+ group.action(`list-${listStyle}`, {
1062
+ label: [
1063
+ `list.${listStyle}.label`,
1064
+ {
1065
+ ns: translationKey
1066
+ }
1067
+ ],
1068
+ checked,
1069
+ icon
1070
+ }, () => {
1071
+ const view = getView();
1072
+ if (!view) {
1073
+ return;
1074
+ }
1075
+ const listType = listStyle === "ordered" ? List.Ordered : listStyle === "bullet" ? List.Bullet : List.Task;
1076
+ if (checked) {
1077
+ removeList(listType)(view);
1078
+ } else {
1079
+ addList(listType)(view);
1080
+ }
1081
+ });
1101
1082
  }
1102
1083
  });
1103
- });
1084
+ };
1104
1085
 
1105
1086
  // src/components/EditorToolbar/blocks.ts
1106
1087
  import { addBlockquote, addCodeblock, insertTable, removeBlockquote, removeCodeblock } from "@dxos/ui-editor";
1107
- var createBlockGroupAction = (value) => createEditorActionGroup("block", {
1108
- variant: "toggleGroup",
1109
- selectCardinality: "single",
1110
- value
1111
- });
1112
- var createBlockActions = (value, getView, blankLine) => Object.entries({
1088
+ var blockTypes = {
1113
1089
  blockquote: "ph--quotes--regular",
1114
1090
  codeblock: "ph--code-block--regular",
1115
1091
  table: "ph--table--regular"
1116
- }).map(([type, icon]) => {
1117
- const checked = type === value;
1118
- return createEditorAction(type, {
1119
- checked,
1120
- ...type === "table" && {
1121
- disabled: !!blankLine
1122
- },
1123
- icon
1124
- }, () => {
1125
- const view = getView();
1126
- if (!view) {
1127
- return;
1128
- }
1129
- switch (type) {
1130
- case "blockquote":
1131
- checked ? removeBlockquote(view) : addBlockquote(view);
1132
- break;
1133
- case "codeblock":
1134
- checked ? removeCodeblock(view) : addCodeblock(view);
1135
- break;
1136
- case "table":
1137
- insertTable(view);
1138
- break;
1139
- }
1140
- });
1141
- });
1142
- var createBlocks = (state, getView) => {
1092
+ };
1093
+ var addBlocks = (state, getView) => (builder) => {
1143
1094
  const value = state?.blockQuote ? "blockquote" : state.blockType ?? "";
1144
- const blockGroupAction = createBlockGroupAction(value);
1145
- const blockActions = createBlockActions(value, getView, state.blankLine);
1146
- return {
1147
- nodes: [
1148
- blockGroupAction,
1149
- ...blockActions
1150
- ],
1151
- edges: [
1095
+ builder.group("block", {
1096
+ label: [
1097
+ "block.label",
1152
1098
  {
1153
- source: "root",
1154
- target: "block"
1155
- },
1156
- ...blockActions.map(({ id }) => ({
1157
- source: blockGroupAction.id,
1158
- target: id
1159
- }))
1160
- ]
1161
- };
1099
+ ns: translationKey
1100
+ }
1101
+ ],
1102
+ iconOnly: true,
1103
+ variant: "toggleGroup",
1104
+ selectCardinality: "single",
1105
+ value
1106
+ }, (group) => {
1107
+ for (const [type, icon] of Object.entries(blockTypes)) {
1108
+ const checked = type === value;
1109
+ group.action(type, {
1110
+ label: [
1111
+ `block.${type}.label`,
1112
+ {
1113
+ ns: translationKey
1114
+ }
1115
+ ],
1116
+ checked,
1117
+ ...type === "table" && {
1118
+ disabled: !!state.blankLine
1119
+ },
1120
+ icon
1121
+ }, () => {
1122
+ const view = getView();
1123
+ if (!view) {
1124
+ return;
1125
+ }
1126
+ switch (type) {
1127
+ case "blockquote":
1128
+ checked ? removeBlockquote(view) : addBlockquote(view);
1129
+ break;
1130
+ case "codeblock":
1131
+ checked ? removeCodeblock(view) : addCodeblock(view);
1132
+ break;
1133
+ case "table":
1134
+ insertTable(view);
1135
+ break;
1136
+ }
1137
+ });
1138
+ }
1139
+ });
1162
1140
  };
1163
1141
 
1164
1142
  // src/components/EditorToolbar/formatting.ts
@@ -1170,201 +1148,174 @@ var formats = {
1170
1148
  code: "ph--code--regular",
1171
1149
  link: "ph--link--regular"
1172
1150
  };
1173
- var createFormattingGroup = (formatting) => createEditorActionGroup("formatting", {
1174
- variant: "toggleGroup",
1175
- selectCardinality: "multiple",
1176
- value: Object.keys(formats).filter((key) => !!formatting[key])
1177
- });
1178
- var createFormattingActions = (formatting, getView) => Object.entries(formats).map(([type, icon]) => {
1179
- const checked = !!formatting[type];
1180
- return createEditorAction(type, {
1181
- checked,
1182
- icon
1183
- }, () => {
1184
- const view = getView();
1185
- if (!view) {
1186
- return;
1187
- }
1188
- if (type === "link") {
1189
- checked ? removeLink(view) : addLink()(view);
1190
- return;
1151
+ var addFormatting = (state, getView) => (builder) => {
1152
+ const formatting = state;
1153
+ builder.group("formatting", {
1154
+ label: [
1155
+ "formatting.label",
1156
+ {
1157
+ ns: translationKey
1158
+ }
1159
+ ],
1160
+ iconOnly: true,
1161
+ variant: "toggleGroup",
1162
+ selectCardinality: "multiple",
1163
+ value: Object.keys(formats).filter((key) => !!formatting[key])
1164
+ }, (group) => {
1165
+ for (const [type, icon] of Object.entries(formats)) {
1166
+ const checked = !!formatting[type];
1167
+ group.action(type, {
1168
+ label: [
1169
+ `formatting.${type}.label`,
1170
+ {
1171
+ ns: translationKey
1172
+ }
1173
+ ],
1174
+ checked,
1175
+ icon
1176
+ }, () => {
1177
+ const view = getView();
1178
+ if (!view) {
1179
+ return;
1180
+ }
1181
+ if (type === "link") {
1182
+ checked ? removeLink(view) : addLink()(view);
1183
+ return;
1184
+ }
1185
+ setStyle(type === "strong" ? Inline.Strong : type === "emphasis" ? Inline.Emphasis : type === "strikethrough" ? Inline.Strikethrough : Inline.Code, !checked)(view);
1186
+ });
1191
1187
  }
1192
- const inlineType = type === "strong" ? Inline.Strong : type === "emphasis" ? Inline.Emphasis : type === "strikethrough" ? Inline.Strikethrough : Inline.Code;
1193
- setStyle(inlineType, !checked)(view);
1194
1188
  });
1195
- });
1196
- var createFormatting = (state, getView) => {
1197
- const formattingGroupAction = createFormattingGroup(state);
1198
- const formattingActions = createFormattingActions(state, getView);
1199
- return {
1200
- nodes: [
1201
- formattingGroupAction,
1202
- ...formattingActions
1203
- ],
1204
- edges: [
1205
- {
1206
- source: "root",
1207
- target: "formatting"
1208
- },
1209
- ...formattingActions.map(({ id }) => ({
1210
- source: formattingGroupAction.id,
1211
- target: id
1212
- }))
1213
- ]
1214
- };
1215
1189
  };
1216
1190
 
1217
1191
  // src/components/EditorToolbar/headings.ts
1218
1192
  import { setHeading } from "@dxos/ui-editor";
1219
- var createHeadingGroupAction = (value) => createEditorActionGroup("heading", {
1220
- variant: "dropdownMenu",
1221
- applyActive: true,
1222
- selectCardinality: "single",
1223
- // TODO(wittjosiah): Remove? Not sure this does anything.
1224
- value
1225
- }, "ph--text-h--regular");
1226
- var createHeadingActions = (currentLevel, getView) => Object.entries({
1227
- "0": "ph--paragraph--regular",
1228
- "1": "ph--text-h-one--regular",
1229
- "2": "ph--text-h-two--regular",
1230
- "3": "ph--text-h-three--regular",
1231
- "4": "ph--text-h-four--regular",
1232
- "5": "ph--text-h-five--regular",
1233
- "6": "ph--text-h-six--regular"
1234
- }).map(([levelStr, icon]) => {
1235
- const level = parseInt(levelStr);
1236
- return createEditorAction(`heading--${levelStr}`, {
1237
- label: [
1238
- "heading level label",
1239
- {
1240
- count: level,
1241
- ns: translationKey
1242
- }
1243
- ],
1244
- icon,
1245
- checked: levelStr === currentLevel
1246
- }, () => setHeading(level)(getView()));
1247
- });
1193
+ var headingIcons = {
1194
+ 0: "ph--paragraph--regular",
1195
+ 1: "ph--text-h-one--regular",
1196
+ 2: "ph--text-h-two--regular",
1197
+ 3: "ph--text-h-three--regular",
1198
+ 4: "ph--text-h-four--regular",
1199
+ 5: "ph--text-h-five--regular",
1200
+ 6: "ph--text-h-six--regular"
1201
+ };
1248
1202
  var computeHeadingValue = (state) => {
1249
1203
  const blockType = state ? state.blockType : "paragraph";
1250
1204
  const heading = blockType && /heading(\d)/.exec(blockType);
1251
1205
  return heading ? heading[1] : blockType === "paragraph" || !blockType ? "0" : "";
1252
1206
  };
1253
- var createHeadings = (state, getView) => {
1207
+ var addHeadings = (state, getView) => (builder) => {
1254
1208
  const headingValue = computeHeadingValue(state);
1255
- const headingGroupAction = createHeadingGroupAction(headingValue);
1256
- const headingActions = createHeadingActions(headingValue, getView);
1257
- return {
1258
- nodes: [
1259
- headingGroupAction,
1260
- ...headingActions
1261
- ],
1262
- edges: [
1209
+ builder.group("heading", {
1210
+ label: [
1211
+ "heading.label",
1263
1212
  {
1264
- source: "root",
1265
- target: "heading"
1266
- },
1267
- ...headingActions.map(({ id }) => ({
1268
- source: headingGroupAction.id,
1269
- target: id
1270
- }))
1271
- ]
1272
- };
1213
+ ns: translationKey
1214
+ }
1215
+ ],
1216
+ icon: "ph--text-h--regular",
1217
+ iconOnly: true,
1218
+ variant: "dropdownMenu",
1219
+ applyActive: true,
1220
+ selectCardinality: "single",
1221
+ // TODO(wittjosiah): Remove? Not sure this does anything.
1222
+ value: headingValue
1223
+ }, (group) => {
1224
+ for (const [levelStr, icon] of Object.entries(headingIcons)) {
1225
+ const level = parseInt(levelStr);
1226
+ group.action(`heading--${levelStr}`, {
1227
+ label: [
1228
+ "heading-level.label",
1229
+ {
1230
+ count: level,
1231
+ ns: translationKey
1232
+ }
1233
+ ],
1234
+ icon,
1235
+ checked: levelStr === headingValue
1236
+ }, () => setHeading(level)(getView()));
1237
+ }
1238
+ });
1273
1239
  };
1274
1240
 
1275
1241
  // src/components/EditorToolbar/image.ts
1276
- var createImageUploadAction = (onImageUpload) => createEditorAction("image", {
1277
- testId: "editor.toolbar.image",
1278
- icon: "ph--image-square--regular"
1279
- }, onImageUpload);
1280
- var createImageUpload = (onImageUpload) => ({
1281
- nodes: [
1282
- createImageUploadAction(onImageUpload)
1283
- ],
1284
- edges: [
1285
- {
1286
- source: "root",
1287
- target: "image"
1288
- }
1289
- ]
1290
- });
1242
+ var addImageUpload = (onImageUpload) => (builder) => {
1243
+ builder.action("image", {
1244
+ label: [
1245
+ "image.label",
1246
+ {
1247
+ ns: translationKey
1248
+ }
1249
+ ],
1250
+ testId: "editor.toolbar.image",
1251
+ icon: "ph--image-square--regular"
1252
+ }, onImageUpload);
1253
+ };
1291
1254
 
1292
1255
  // src/components/EditorToolbar/search.ts
1293
1256
  import { openSearchPanel } from "@codemirror/search";
1294
- var createSearchAction = (getView) => createEditorAction("search", {
1295
- testId: "editor.toolbar.search",
1296
- icon: "ph--magnifying-glass--regular"
1297
- }, () => openSearchPanel(getView()));
1298
- var createSearch = (getView) => ({
1299
- nodes: [
1300
- createSearchAction(getView)
1301
- ],
1302
- edges: [
1303
- {
1304
- source: "root",
1305
- target: "search"
1306
- }
1307
- ]
1308
- });
1257
+ var addSearch = (getView) => (builder) => {
1258
+ builder.action("search", {
1259
+ label: [
1260
+ "search.label",
1261
+ {
1262
+ ns: translationKey
1263
+ }
1264
+ ],
1265
+ testId: "editor.toolbar.search",
1266
+ icon: "ph--magnifying-glass--regular"
1267
+ }, () => openSearchPanel(getView()));
1268
+ };
1309
1269
 
1310
1270
  // src/components/EditorToolbar/view-mode.ts
1311
- var createViewModeGroupAction = (value) => createEditorActionGroup("viewMode", {
1312
- variant: "dropdownMenu",
1313
- applyActive: true,
1314
- selectCardinality: "single",
1315
- value
1316
- }, "ph--eye--regular");
1317
- var createViewModeActions = (value, onViewModeChange) => Object.entries({
1271
+ var viewModes = {
1318
1272
  preview: "ph--eye--regular",
1319
1273
  source: "ph--pencil-simple--regular",
1320
1274
  readonly: "ph--pencil-slash--regular"
1321
- }).map(([viewMode, icon]) => {
1322
- const checked = viewMode === value;
1323
- return createEditorAction(`view-mode--${viewMode}`, {
1275
+ };
1276
+ var addViewMode = (state, onViewModeChange) => (builder) => {
1277
+ const value = state.viewMode ?? "source";
1278
+ builder.group("viewMode", {
1324
1279
  label: [
1325
- `${viewMode} mode label`,
1280
+ "view-mode.label",
1326
1281
  {
1327
1282
  ns: translationKey
1328
1283
  }
1329
1284
  ],
1330
- checked,
1331
- icon
1332
- }, () => onViewModeChange(viewMode));
1333
- });
1334
- var createViewMode = (state, onViewModeChange) => {
1335
- const value = state.viewMode ?? "source";
1336
- const viewModeGroupAction = createViewModeGroupAction(value);
1337
- const viewModeActions = createViewModeActions(value, onViewModeChange);
1338
- return {
1339
- nodes: [
1340
- viewModeGroupAction,
1341
- ...viewModeActions
1342
- ],
1343
- edges: [
1344
- {
1345
- source: "root",
1346
- target: "viewMode"
1347
- },
1348
- ...viewModeActions.map(({ id }) => ({
1349
- source: viewModeGroupAction.id,
1350
- target: id
1351
- }))
1352
- ]
1353
- };
1285
+ icon: "ph--eye--regular",
1286
+ iconOnly: true,
1287
+ variant: "dropdownMenu",
1288
+ applyActive: true,
1289
+ selectCardinality: "single",
1290
+ value
1291
+ }, (group) => {
1292
+ for (const [viewMode, icon] of Object.entries(viewModes)) {
1293
+ const checked = viewMode === value;
1294
+ group.action(`view-mode--${viewMode}`, {
1295
+ label: [
1296
+ `view-mode.${viewMode}.label`,
1297
+ {
1298
+ ns: translationKey
1299
+ }
1300
+ ],
1301
+ checked,
1302
+ icon
1303
+ }, () => onViewModeChange(viewMode));
1304
+ }
1305
+ });
1354
1306
  };
1355
1307
 
1356
1308
  // src/components/EditorToolbar/EditorToolbar.tsx
1357
1309
  var EditorToolbar = /* @__PURE__ */ memo(({ classNames, role, attendableId, onAction, ...props }) => {
1358
- const menuProps = useEditorToolbarActionGraph(props);
1310
+ const menuActions = useEditorToolbarActionGraph(props);
1359
1311
  return /* @__PURE__ */ React3.createElement(ElevationProvider, {
1360
1312
  elevation: role === "section" ? "positioned" : "base"
1361
- }, /* @__PURE__ */ React3.createElement(MenuProvider, {
1362
- ...menuProps,
1313
+ }, /* @__PURE__ */ React3.createElement(Menu2.Root, {
1314
+ ...menuActions,
1363
1315
  attendableId,
1364
1316
  onAction
1365
- }, /* @__PURE__ */ React3.createElement(ToolbarMenu, {
1366
- classNames,
1367
- textBlockWidth: true
1317
+ }, /* @__PURE__ */ React3.createElement(Menu2.Toolbar, {
1318
+ classNames
1368
1319
  })));
1369
1320
  });
1370
1321
  var useEditorToolbarActionGraph = ({ state, getView, customActions, ...features }) => {
@@ -1389,41 +1340,8 @@ var useEditorToolbarActionGraph = ({ state, getView, customActions, ...features
1389
1340
  };
1390
1341
  var createToolbarActions = ({ state, getView, customActions, ...features }) => {
1391
1342
  return Atom.make((get) => {
1392
- const graph = {
1393
- nodes: [],
1394
- edges: []
1395
- };
1396
- const addSubGraph = (graph2, subGraph) => {
1397
- graph2.nodes.push(...subGraph.nodes);
1398
- graph2.edges.push(...subGraph.edges);
1399
- };
1400
1343
  const stateSnapshot = get(state);
1401
- if (features?.showHeadings ?? true) {
1402
- addSubGraph(graph, createHeadings(stateSnapshot, getView));
1403
- }
1404
- if (features?.showFormatting ?? true) {
1405
- addSubGraph(graph, createFormatting(stateSnapshot, getView));
1406
- }
1407
- if (features?.showLists ?? true) {
1408
- addSubGraph(graph, createLists(stateSnapshot, getView));
1409
- }
1410
- if (features?.showBlocks ?? true) {
1411
- addSubGraph(graph, createBlocks(stateSnapshot, getView));
1412
- }
1413
- if (features?.onImageUpload) {
1414
- addSubGraph(graph, createImageUpload(features.onImageUpload));
1415
- }
1416
- addSubGraph(graph, createGapSeparator());
1417
- if (customActions) {
1418
- addSubGraph(graph, get(customActions));
1419
- }
1420
- if (features?.showSearch ?? true) {
1421
- addSubGraph(graph, createSearch(getView));
1422
- }
1423
- if (features?.onViewModeChange) {
1424
- addSubGraph(graph, createViewMode(stateSnapshot, features.onViewModeChange));
1425
- }
1426
- return graph;
1344
+ return MenuBuilder.make().subgraph(features?.showHeadings !== false && addHeadings(stateSnapshot, getView)).subgraph(features?.showFormatting !== false && addFormatting(stateSnapshot, getView)).subgraph(features?.showLists !== false && addLists(stateSnapshot, getView)).subgraph(features?.showBlocks !== false && addBlocks(stateSnapshot, getView)).subgraph(features?.onImageUpload && addImageUpload(features.onImageUpload)).separator("gap").subgraph(customActions && get(customActions)).subgraph(features?.showSearch !== false && addSearch(getView)).subgraph(features?.onViewModeChange && addViewMode(stateSnapshot, features.onViewModeChange)).build();
1427
1345
  });
1428
1346
  };
1429
1347
 
@@ -1465,15 +1383,17 @@ var EditorRoot = /* @__PURE__ */ forwardRef2(({ children, extensions: extensions
1465
1383
  }, children));
1466
1384
  });
1467
1385
  EditorRoot.displayName = "Editor.Root";
1386
+ var EDITOR_VIEWPORT_NAME = "Editor.Viewport";
1468
1387
  var EditorViewport = ({ classNames, children }) => {
1469
1388
  return /* @__PURE__ */ React4.createElement("div", {
1470
1389
  role: "none",
1471
- className: mx2("grid grid-rows-[min-content_1fr] bs-full overflow-hidden", classNames)
1390
+ className: mx2("grid grid-rows-[min-content_1fr] h-full overflow-hidden", classNames)
1472
1391
  }, children);
1473
1392
  };
1474
- EditorViewport.displayName = "Editor.Viewport";
1393
+ EditorViewport.displayName = EDITOR_VIEWPORT_NAME;
1394
+ var EDITOR_CONTENT_NAME = "Editor.Content";
1475
1395
  var EditorContent2 = ({ extensions: providedExtensions, ...props }) => {
1476
- const { extensions: additionalExtensions = [], setController } = useEditorContext(EditorContent2.displayName);
1396
+ const { extensions: additionalExtensions = [], setController } = useEditorContext(EDITOR_CONTENT_NAME);
1477
1397
  const extensions = useMemo5(() => [
1478
1398
  additionalExtensions,
1479
1399
  providedExtensions
@@ -1487,13 +1407,14 @@ var EditorContent2 = ({ extensions: providedExtensions, ...props }) => {
1487
1407
  ref: setController
1488
1408
  });
1489
1409
  };
1490
- EditorContent2.displayName = "Editor.Content";
1410
+ EditorContent2.displayName = EDITOR_CONTENT_NAME;
1411
+ var EDITOR_TOOLBAR_NAME = "Editor.Toolbar";
1491
1412
  var EditorToolbar2 = (props) => {
1492
- const { controller, state } = useEditorContext(EditorToolbar2.displayName);
1413
+ const { controller, state } = useEditorContext(EDITOR_TOOLBAR_NAME);
1493
1414
  const getView = useCallback4(() => {
1494
1415
  invariant3(controller?.view, void 0, {
1495
1416
  F: __dxlog_file4,
1496
- L: 140,
1417
+ L: 146,
1497
1418
  S: void 0,
1498
1419
  A: [
1499
1420
  "controller?.view",
@@ -1510,7 +1431,7 @@ var EditorToolbar2 = (props) => {
1510
1431
  state
1511
1432
  });
1512
1433
  };
1513
- EditorToolbar2.displayName = "Editor.Toolbar";
1434
+ EditorToolbar2.displayName = EDITOR_TOOLBAR_NAME;
1514
1435
  var Editor = {
1515
1436
  Root: EditorRoot,
1516
1437
  Viewport: EditorViewport,
@@ -1529,20 +1450,20 @@ var EditorPreviewProvider = ({ children, onLookup }) => {
1529
1450
  const [value, setValue] = useState5({});
1530
1451
  const [open, setOpen] = useState5(false);
1531
1452
  const handleActivate = useCallback5((event) => {
1532
- const { refId, label, trigger: dxTrigger } = event;
1453
+ const { dxn, label, trigger } = event;
1533
1454
  setValue((value2) => ({
1534
1455
  ...value2,
1535
1456
  link: {
1536
1457
  label,
1537
- ref: refId
1458
+ dxn
1538
1459
  },
1539
1460
  pending: true
1540
1461
  }));
1541
- triggerRef.current = dxTrigger;
1462
+ triggerRef.current = trigger;
1542
1463
  queueMicrotask(() => setOpen(true));
1543
1464
  void onLookup?.({
1544
1465
  label,
1545
- ref: refId
1466
+ dxn
1546
1467
  }).then((target) => setValue((value2) => ({
1547
1468
  ...value2,
1548
1469
  target: target ?? void 0,
@@ -1574,9 +1495,9 @@ var EditorPreviewProvider = ({ children, onLookup }) => {
1574
1495
  }, /* @__PURE__ */ React5.createElement(Popover2.VirtualTrigger, {
1575
1496
  virtualRef: triggerRef
1576
1497
  }), /* @__PURE__ */ React5.createElement("div", {
1577
- ref: setRoot,
1578
1498
  role: "none",
1579
- className: "contents"
1499
+ className: "contents",
1500
+ ref: setRoot
1580
1501
  }, children)));
1581
1502
  };
1582
1503
  export {