@dxos/react-ui-editor 0.8.4-main.5ad4a44 → 0.8.4-main.66e292d

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 (280) hide show
  1. package/dist/lib/browser/index.mjs +2979 -2478
  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 +2979 -2478
  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 +37 -21
  8. package/dist/types/src/components/Editor/Editor.d.ts.map +1 -1
  9. package/dist/types/src/components/Editor/Editor.stories.d.ts +20 -0
  10. package/dist/types/src/components/Editor/Editor.stories.d.ts.map +1 -0
  11. package/dist/types/src/components/EditorContent/EditorContent.d.ts +29 -0
  12. package/dist/types/src/components/EditorContent/EditorContent.d.ts.map +1 -0
  13. package/dist/types/src/components/EditorContent/EditorContent.stories.d.ts +26 -0
  14. package/dist/types/src/components/EditorContent/EditorContent.stories.d.ts.map +1 -0
  15. package/dist/types/src/components/EditorContent/controller.d.ts +10 -0
  16. package/dist/types/src/components/EditorContent/controller.d.ts.map +1 -0
  17. package/dist/types/src/components/EditorContent/index.d.ts +3 -0
  18. package/dist/types/src/components/EditorContent/index.d.ts.map +1 -0
  19. package/dist/types/src/components/EditorMenuProvider/EditorMenuProvider.d.ts +36 -0
  20. package/dist/types/src/components/EditorMenuProvider/EditorMenuProvider.d.ts.map +1 -0
  21. package/dist/types/src/components/EditorMenuProvider/index.d.ts +7 -0
  22. package/dist/types/src/components/EditorMenuProvider/index.d.ts.map +1 -0
  23. package/dist/types/src/components/EditorMenuProvider/menu-presets.d.ts +4 -0
  24. package/dist/types/src/components/EditorMenuProvider/menu-presets.d.ts.map +1 -0
  25. package/dist/types/src/components/EditorMenuProvider/menu.d.ts +28 -0
  26. package/dist/types/src/components/EditorMenuProvider/menu.d.ts.map +1 -0
  27. package/dist/types/src/components/EditorMenuProvider/popover.d.ts +47 -0
  28. package/dist/types/src/components/EditorMenuProvider/popover.d.ts.map +1 -0
  29. package/dist/types/src/components/EditorMenuProvider/useEditorMenu.d.ts +34 -0
  30. package/dist/types/src/components/EditorMenuProvider/useEditorMenu.d.ts.map +1 -0
  31. package/dist/types/src/components/EditorMenuProvider/util.d.ts +8 -0
  32. package/dist/types/src/components/EditorMenuProvider/util.d.ts.map +1 -0
  33. package/dist/types/src/components/EditorPreviewProvider/EditorPreviewProvider.d.ts +16 -0
  34. package/dist/types/src/components/EditorPreviewProvider/EditorPreviewProvider.d.ts.map +1 -0
  35. package/dist/types/src/components/EditorPreviewProvider/index.d.ts +2 -0
  36. package/dist/types/src/components/EditorPreviewProvider/index.d.ts.map +1 -0
  37. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +26 -2
  38. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
  39. package/dist/types/src/components/EditorToolbar/actions.d.ts +39 -0
  40. package/dist/types/src/components/EditorToolbar/actions.d.ts.map +1 -0
  41. package/dist/types/src/components/EditorToolbar/blocks.d.ts +3 -3
  42. package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
  43. package/dist/types/src/components/EditorToolbar/formatting.d.ts +3 -3
  44. package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
  45. package/dist/types/src/components/EditorToolbar/headings.d.ts +3 -3
  46. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
  47. package/dist/types/src/components/EditorToolbar/index.d.ts +2 -1
  48. package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -1
  49. package/dist/types/src/components/EditorToolbar/useEditorToolbar.d.ts +11 -0
  50. package/dist/types/src/components/EditorToolbar/useEditorToolbar.d.ts.map +1 -0
  51. package/dist/types/src/components/EditorToolbar/view-mode.d.ts +3 -3
  52. package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -1
  53. package/dist/types/src/components/index.d.ts +4 -2
  54. package/dist/types/src/components/index.d.ts.map +1 -1
  55. package/dist/types/src/extensions/autocomplete/autocomplete.d.ts +17 -0
  56. package/dist/types/src/extensions/autocomplete/autocomplete.d.ts.map +1 -0
  57. package/dist/types/src/extensions/autocomplete/index.d.ts +5 -0
  58. package/dist/types/src/extensions/autocomplete/index.d.ts.map +1 -0
  59. package/dist/types/src/extensions/autocomplete/match.d.ts +13 -0
  60. package/dist/types/src/extensions/autocomplete/match.d.ts.map +1 -0
  61. package/dist/types/src/extensions/autocomplete/placeholder.d.ts +20 -0
  62. package/dist/types/src/extensions/autocomplete/placeholder.d.ts.map +1 -0
  63. package/dist/types/src/extensions/autocomplete/typeahead.d.ts +10 -0
  64. package/dist/types/src/extensions/autocomplete/typeahead.d.ts.map +1 -0
  65. package/dist/types/src/extensions/automerge/automerge.d.ts +1 -1
  66. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  67. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  68. package/dist/types/src/extensions/automerge/cursor.d.ts +1 -1
  69. package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
  70. package/dist/types/src/extensions/automerge/sync.d.ts +3 -3
  71. package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
  72. package/dist/types/src/extensions/automerge/update-automerge.d.ts +1 -1
  73. package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
  74. package/dist/types/src/extensions/autoscroll.d.ts +14 -4
  75. package/dist/types/src/extensions/autoscroll.d.ts.map +1 -1
  76. package/dist/types/src/extensions/awareness/awareness-provider.d.ts +4 -4
  77. package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -1
  78. package/dist/types/src/extensions/blocks.d.ts +2 -0
  79. package/dist/types/src/extensions/blocks.d.ts.map +1 -0
  80. package/dist/types/src/extensions/bookmarks.d.ts +12 -0
  81. package/dist/types/src/extensions/bookmarks.d.ts.map +1 -0
  82. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  83. package/dist/types/src/extensions/factories.d.ts +7 -6
  84. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  85. package/dist/types/src/extensions/folding.d.ts.map +1 -1
  86. package/dist/types/src/extensions/index.d.ts +8 -3
  87. package/dist/types/src/extensions/index.d.ts.map +1 -1
  88. package/dist/types/src/extensions/listener.d.ts +8 -6
  89. package/dist/types/src/extensions/listener.d.ts.map +1 -1
  90. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
  91. package/dist/types/src/extensions/markdown/formatting.d.ts +1 -3
  92. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  93. package/dist/types/src/extensions/modal.d.ts +7 -0
  94. package/dist/types/src/extensions/modal.d.ts.map +1 -0
  95. package/dist/types/src/extensions/modes.d.ts +1 -1
  96. package/dist/types/src/extensions/modes.d.ts.map +1 -1
  97. package/dist/types/src/extensions/outliner/menu.d.ts +8 -0
  98. package/dist/types/src/extensions/outliner/menu.d.ts.map +1 -0
  99. package/dist/types/src/extensions/preview/preview.d.ts +6 -3
  100. package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
  101. package/dist/types/src/extensions/replacer.d.ts +21 -0
  102. package/dist/types/src/extensions/replacer.d.ts.map +1 -0
  103. package/dist/types/src/extensions/replacer.test.d.ts +2 -0
  104. package/dist/types/src/extensions/replacer.test.d.ts.map +1 -0
  105. package/dist/types/src/extensions/scrolling.d.ts +78 -0
  106. package/dist/types/src/extensions/scrolling.d.ts.map +1 -0
  107. package/dist/types/src/extensions/state.d.ts +2 -0
  108. package/dist/types/src/extensions/state.d.ts.map +1 -0
  109. package/dist/types/src/extensions/submit.d.ts +10 -0
  110. package/dist/types/src/extensions/submit.d.ts.map +1 -0
  111. package/dist/types/src/extensions/tab.d.ts +4 -0
  112. package/dist/types/src/extensions/tab.d.ts.map +1 -0
  113. package/dist/types/src/extensions/tags/xml-tags.d.ts +41 -16
  114. package/dist/types/src/extensions/tags/xml-tags.d.ts.map +1 -1
  115. package/dist/types/src/hooks/useTextEditor.d.ts +3 -7
  116. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  117. package/dist/types/src/stories/CommandDialog.stories.d.ts.map +1 -1
  118. package/dist/types/src/stories/Comments.stories.d.ts +3 -3
  119. package/dist/types/src/stories/Comments.stories.d.ts.map +1 -1
  120. package/dist/types/src/stories/Experimental.stories.d.ts +3 -3
  121. package/dist/types/src/stories/Markdown.stories.d.ts +3 -3
  122. package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -1
  123. package/dist/types/src/stories/{CommandMenu.stories.d.ts → Popover.stories.d.ts} +6 -5
  124. package/dist/types/src/stories/Popover.stories.d.ts.map +1 -0
  125. package/dist/types/src/stories/Preview.stories.d.ts +4 -3
  126. package/dist/types/src/stories/Preview.stories.d.ts.map +1 -1
  127. package/dist/types/src/stories/Tags.stories.d.ts.map +1 -1
  128. package/dist/types/src/stories/TextEditor.stories.d.ts +3 -4
  129. package/dist/types/src/stories/TextEditor.stories.d.ts.map +1 -1
  130. package/dist/types/src/stories/components/EditorStory.d.ts +11 -8
  131. package/dist/types/src/stories/components/EditorStory.d.ts.map +1 -1
  132. package/dist/types/src/stories/components/util.d.ts.map +1 -1
  133. package/dist/types/src/styles/theme.d.ts.map +1 -1
  134. package/dist/types/src/util/debug.d.ts +4 -0
  135. package/dist/types/src/util/debug.d.ts.map +1 -1
  136. package/dist/types/tsconfig.tsbuildinfo +1 -1
  137. package/package.json +44 -46
  138. package/src/components/Editor/Editor.stories.tsx +89 -0
  139. package/src/components/Editor/Editor.tsx +157 -57
  140. package/src/components/EditorContent/EditorContent.stories.tsx +70 -0
  141. package/src/components/EditorContent/EditorContent.tsx +70 -0
  142. package/src/components/EditorContent/controller.ts +50 -0
  143. package/src/components/EditorContent/index.ts +6 -0
  144. package/src/components/EditorMenuProvider/EditorMenuProvider.tsx +233 -0
  145. package/src/components/EditorMenuProvider/index.ts +11 -0
  146. package/src/components/EditorMenuProvider/menu-presets.ts +123 -0
  147. package/src/components/EditorMenuProvider/menu.ts +71 -0
  148. package/src/components/EditorMenuProvider/popover.ts +287 -0
  149. package/src/components/EditorMenuProvider/useEditorMenu.ts +175 -0
  150. package/src/components/EditorMenuProvider/util.ts +31 -0
  151. package/src/components/EditorPreviewProvider/EditorPreviewProvider.tsx +82 -0
  152. package/src/components/EditorPreviewProvider/index.ts +5 -0
  153. package/src/components/EditorToolbar/EditorToolbar.tsx +101 -92
  154. package/src/components/EditorToolbar/{lists.ts → actions.ts} +46 -16
  155. package/src/components/EditorToolbar/blocks.ts +2 -1
  156. package/src/components/EditorToolbar/formatting.ts +2 -1
  157. package/src/components/EditorToolbar/headings.ts +8 -5
  158. package/src/components/EditorToolbar/image.ts +1 -1
  159. package/src/components/EditorToolbar/index.ts +3 -7
  160. package/src/components/EditorToolbar/search.ts +1 -1
  161. package/src/components/EditorToolbar/useEditorToolbar.ts +20 -0
  162. package/src/components/EditorToolbar/view-mode.ts +2 -1
  163. package/src/components/index.ts +8 -2
  164. package/src/extensions/{autocomplete.ts → autocomplete/autocomplete.ts} +8 -76
  165. package/src/extensions/autocomplete/index.ts +8 -0
  166. package/src/extensions/autocomplete/match.ts +46 -0
  167. package/src/extensions/{command-menu → autocomplete}/placeholder.ts +21 -17
  168. package/src/extensions/{command-dialog → autocomplete}/typeahead.ts +6 -48
  169. package/src/extensions/automerge/automerge.stories.tsx +4 -3
  170. package/src/extensions/automerge/automerge.ts +28 -9
  171. package/src/extensions/automerge/cursor.ts +1 -1
  172. package/src/extensions/automerge/sync.ts +8 -4
  173. package/src/extensions/automerge/update-automerge.ts +1 -1
  174. package/src/extensions/autoscroll.ts +75 -69
  175. package/src/extensions/awareness/awareness-provider.ts +12 -12
  176. package/src/extensions/blocks.ts +131 -0
  177. package/src/extensions/bookmarks.ts +75 -0
  178. package/src/extensions/comments.ts +2 -1
  179. package/src/extensions/factories.ts +22 -24
  180. package/src/extensions/folding.tsx +1 -2
  181. package/src/extensions/index.ts +8 -3
  182. package/src/extensions/listener.ts +14 -20
  183. package/src/extensions/markdown/bundle.ts +14 -2
  184. package/src/extensions/markdown/decorate.ts +8 -8
  185. package/src/extensions/markdown/formatting.ts +8 -10
  186. package/src/extensions/markdown/highlight.ts +1 -1
  187. package/src/extensions/markdown/image.ts +2 -2
  188. package/src/extensions/markdown/table.ts +6 -6
  189. package/src/extensions/modal.ts +24 -0
  190. package/src/extensions/modes.ts +2 -2
  191. package/src/extensions/{floating-menu.ts → outliner/menu.ts} +7 -5
  192. package/src/extensions/outliner/outliner.test.ts +1 -1
  193. package/src/extensions/outliner/outliner.ts +3 -3
  194. package/src/extensions/outliner/tree.test.ts +1 -1
  195. package/src/extensions/preview/index.ts +1 -1
  196. package/src/extensions/preview/preview.ts +14 -11
  197. package/src/extensions/replacer.test.ts +75 -0
  198. package/src/extensions/replacer.ts +93 -0
  199. package/src/extensions/scrolling.ts +189 -0
  200. package/src/extensions/selection.ts +1 -1
  201. package/src/extensions/state.ts +7 -0
  202. package/src/extensions/submit.ts +62 -0
  203. package/src/extensions/tab.ts +29 -0
  204. package/src/extensions/tags/extended-markdown.test.ts +2 -1
  205. package/src/extensions/tags/xml-tags.ts +310 -203
  206. package/src/extensions/typewriter.ts +1 -1
  207. package/src/hooks/useTextEditor.ts +25 -25
  208. package/src/stories/CommandDialog.stories.tsx +13 -19
  209. package/src/stories/Comments.stories.tsx +3 -4
  210. package/src/stories/EditorToolbar.stories.tsx +8 -8
  211. package/src/stories/Experimental.stories.tsx +1 -1
  212. package/src/stories/Markdown.stories.tsx +1 -1
  213. package/src/stories/Outliner.stories.tsx +15 -15
  214. package/src/stories/Popover.stories.tsx +162 -0
  215. package/src/stories/Preview.stories.tsx +41 -37
  216. package/src/stories/Tags.stories.tsx +19 -5
  217. package/src/stories/TextEditor.stories.tsx +4 -30
  218. package/src/stories/components/EditorStory.tsx +31 -20
  219. package/src/stories/components/util.tsx +40 -8
  220. package/src/styles/markdown.ts +1 -1
  221. package/src/styles/theme.ts +2 -1
  222. package/src/util/debug.ts +5 -0
  223. package/dist/lib/browser/testing/index.mjs +0 -76
  224. package/dist/lib/browser/testing/index.mjs.map +0 -7
  225. package/dist/lib/node-esm/testing/index.mjs +0 -78
  226. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  227. package/dist/types/src/components/CommandMenu/CommandMenu.d.ts +0 -38
  228. package/dist/types/src/components/CommandMenu/CommandMenu.d.ts.map +0 -1
  229. package/dist/types/src/components/CommandMenu/index.d.ts +0 -2
  230. package/dist/types/src/components/CommandMenu/index.d.ts.map +0 -1
  231. package/dist/types/src/components/EditorToolbar/lists.d.ts +0 -19
  232. package/dist/types/src/components/EditorToolbar/lists.d.ts.map +0 -1
  233. package/dist/types/src/components/EditorToolbar/util.d.ts +0 -51
  234. package/dist/types/src/components/EditorToolbar/util.d.ts.map +0 -1
  235. package/dist/types/src/extensions/autocomplete.d.ts +0 -26
  236. package/dist/types/src/extensions/autocomplete.d.ts.map +0 -1
  237. package/dist/types/src/extensions/command-dialog/action.d.ts +0 -17
  238. package/dist/types/src/extensions/command-dialog/action.d.ts.map +0 -1
  239. package/dist/types/src/extensions/command-dialog/command-dialog.d.ts +0 -6
  240. package/dist/types/src/extensions/command-dialog/command-dialog.d.ts.map +0 -1
  241. package/dist/types/src/extensions/command-dialog/hint.d.ts +0 -19
  242. package/dist/types/src/extensions/command-dialog/hint.d.ts.map +0 -1
  243. package/dist/types/src/extensions/command-dialog/index.d.ts +0 -4
  244. package/dist/types/src/extensions/command-dialog/index.d.ts.map +0 -1
  245. package/dist/types/src/extensions/command-dialog/state.d.ts +0 -16
  246. package/dist/types/src/extensions/command-dialog/state.d.ts.map +0 -1
  247. package/dist/types/src/extensions/command-dialog/typeahead.d.ts +0 -22
  248. package/dist/types/src/extensions/command-dialog/typeahead.d.ts.map +0 -1
  249. package/dist/types/src/extensions/command-menu/command-menu.d.ts +0 -20
  250. package/dist/types/src/extensions/command-menu/command-menu.d.ts.map +0 -1
  251. package/dist/types/src/extensions/command-menu/index.d.ts +0 -3
  252. package/dist/types/src/extensions/command-menu/index.d.ts.map +0 -1
  253. package/dist/types/src/extensions/command-menu/placeholder.d.ts +0 -10
  254. package/dist/types/src/extensions/command-menu/placeholder.d.ts.map +0 -1
  255. package/dist/types/src/extensions/command-menu/useCommandMenu.d.ts +0 -24
  256. package/dist/types/src/extensions/command-menu/useCommandMenu.d.ts.map +0 -1
  257. package/dist/types/src/extensions/floating-menu.d.ts +0 -7
  258. package/dist/types/src/extensions/floating-menu.d.ts.map +0 -1
  259. package/dist/types/src/stories/CommandMenu.stories.d.ts.map +0 -1
  260. package/dist/types/src/testing/PreviewPopover.d.ts +0 -20
  261. package/dist/types/src/testing/PreviewPopover.d.ts.map +0 -1
  262. package/dist/types/src/testing/index.d.ts +0 -3
  263. package/dist/types/src/testing/index.d.ts.map +0 -1
  264. package/dist/types/src/testing/util.d.ts +0 -3
  265. package/dist/types/src/testing/util.d.ts.map +0 -1
  266. package/src/components/CommandMenu/CommandMenu.tsx +0 -348
  267. package/src/components/CommandMenu/index.ts +0 -5
  268. package/src/components/EditorToolbar/util.ts +0 -76
  269. package/src/extensions/command-dialog/action.ts +0 -55
  270. package/src/extensions/command-dialog/command-dialog.ts +0 -34
  271. package/src/extensions/command-dialog/hint.ts +0 -103
  272. package/src/extensions/command-dialog/index.ts +0 -7
  273. package/src/extensions/command-dialog/state.ts +0 -90
  274. package/src/extensions/command-menu/command-menu.ts +0 -210
  275. package/src/extensions/command-menu/index.ts +0 -6
  276. package/src/extensions/command-menu/useCommandMenu.ts +0 -134
  277. package/src/stories/CommandMenu.stories.tsx +0 -158
  278. package/src/testing/PreviewPopover.tsx +0 -78
  279. package/src/testing/index.ts +0 -6
  280. package/src/testing/util.ts +0 -7
@@ -4,8 +4,8 @@
4
4
 
5
5
  import { EditorState, type EditorStateConfig, type Text } from '@codemirror/state';
6
6
  import { EditorView } from '@codemirror/view';
7
- import { type TabsterTypes, useFocusableGroup } from '@fluentui/react-tabster';
8
7
  import {
8
+ type ComponentPropsWithoutRef,
9
9
  type DependencyList,
10
10
  type KeyboardEventHandler,
11
11
  type RefObject,
@@ -19,7 +19,7 @@ import {
19
19
  import { log } from '@dxos/log';
20
20
  import { type MaybeProvider, getProviderValue, isTruthy } from '@dxos/util';
21
21
 
22
- import { type EditorSelection, createEditorStateTransaction, documentId, editorInputMode } from '../extensions';
22
+ import { type EditorSelection, createEditorStateTransaction, documentId, modalStateField } from '../extensions';
23
23
  import { debugDispatcher } from '../util';
24
24
 
25
25
  let instanceCount = 0;
@@ -34,13 +34,9 @@ export type CursorInfo = {
34
34
  };
35
35
 
36
36
  export type UseTextEditor = {
37
- // TODO(burdon): Rename.
38
37
  parentRef: RefObject<HTMLDivElement | null>;
39
38
  view: EditorView | null;
40
- focusAttributes?: TabsterTypes.TabsterDOMAttribute & {
41
- tabIndex: 0;
42
- onKeyUp: KeyboardEventHandler<HTMLDivElement>;
43
- };
39
+ focusAttributes?: ComponentPropsWithoutRef<'div'>;
44
40
  };
45
41
 
46
42
  export type UseTextEditorProps = Pick<EditorStateConfig, 'extensions'> & {
@@ -50,7 +46,7 @@ export type UseTextEditorProps = Pick<EditorStateConfig, 'extensions'> & {
50
46
  autoFocus?: boolean;
51
47
  scrollTo?: number;
52
48
  selection?: EditorSelection;
53
- moveToEndOfLine?: boolean;
49
+ selectionEnd?: boolean;
54
50
  debug?: boolean;
55
51
  };
56
52
 
@@ -61,7 +57,7 @@ export const useTextEditor = (
61
57
  props: MaybeProvider<UseTextEditorProps> = {},
62
58
  deps: DependencyList = [],
63
59
  ): UseTextEditor => {
64
- const { id, doc, initialValue, extensions, autoFocus, scrollTo, selection, moveToEndOfLine, debug } =
60
+ const { id, doc, initialValue, extensions, autoFocus, scrollTo, selection, selectionEnd, debug } =
65
61
  useMemo<UseTextEditorProps>(() => getProviderValue(props), deps ?? []);
66
62
 
67
63
  // NOTE: Increments by 2 in strict mode.
@@ -79,7 +75,7 @@ export const useTextEditor = (
79
75
  if (selection.anchor <= initialValue.length && (selection?.head ?? 0) <= initialValue.length) {
80
76
  initialSelection = selection;
81
77
  }
82
- } else if (moveToEndOfLine && selection === undefined) {
78
+ } else if (selectionEnd && selection === undefined) {
83
79
  const index = initialValue?.indexOf('\n');
84
80
  const anchor = !index || index === -1 ? 0 : index;
85
81
  initialSelection = { anchor };
@@ -108,7 +104,7 @@ export const useTextEditor = (
108
104
  });
109
105
 
110
106
  // Move to end of line after document loaded (unless selection is specified).
111
- if (moveToEndOfLine && !initialSelection) {
107
+ if (selectionEnd && !initialSelection) {
112
108
  const { to } = view.state.doc.lineAt(0);
113
109
  if (to) {
114
110
  view.dispatch({ selection: { anchor: to } });
@@ -143,23 +139,28 @@ export const useTextEditor = (
143
139
  }
144
140
  }, [autoFocus, view]);
145
141
 
146
- const focusableGroupAttrs = useFocusableGroup({
147
- tabBehavior: 'limited',
148
- ignoreDefaultKeydown: {
149
- Escape: view?.state.facet(editorInputMode).noTabster,
150
- },
151
- });
152
-
153
142
  // Focus editor on Enter (e.g., when tabbing to this component).
154
- const handleKeyUp = useCallback<KeyboardEventHandler<HTMLDivElement>>(
143
+ const handleKeyDown = useCallback<KeyboardEventHandler<HTMLDivElement>>(
155
144
  (event) => {
156
145
  const { key, target, currentTarget } = event;
157
- if (target === currentTarget) {
158
- switch (key) {
159
- case 'Enter': {
146
+ switch (key) {
147
+ case 'Escape': {
148
+ // Check if popover is open.
149
+ const modal = view?.state.field(modalStateField, false);
150
+ if (modal) {
151
+ return;
152
+ }
153
+
154
+ // Focus the closest focusable parent.
155
+ const element = view?.contentDOM.closest('[tabindex="0"]') as HTMLDivElement | null;
156
+ element?.focus();
157
+ break;
158
+ }
159
+ case 'Enter': {
160
+ if (target === currentTarget) {
160
161
  view?.focus();
161
- break;
162
162
  }
163
+ break;
163
164
  }
164
165
  }
165
166
  },
@@ -171,8 +172,7 @@ export const useTextEditor = (
171
172
  view,
172
173
  focusAttributes: {
173
174
  tabIndex: 0 as const,
174
- ...focusableGroupAttrs,
175
- onKeyUp: handleKeyUp,
175
+ onKeyDown: handleKeyDown,
176
176
  },
177
177
  };
178
178
  };
@@ -5,18 +5,17 @@
5
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import React, { type KeyboardEvent, useState } from 'react';
7
7
 
8
- import { Button, Icon, Input } from '@dxos/react-ui';
8
+ import { type Button, IconButton, Input } from '@dxos/react-ui';
9
9
  import { withTheme } from '@dxos/react-ui/testing';
10
10
  import { mx } from '@dxos/react-ui-theme';
11
11
 
12
12
  import { editorWidth } from '../defaults';
13
- import { type Action, commandDialog } from '../extensions';
14
- import { str } from '../testing';
15
- import { createRenderer } from '../util';
13
+ import { str } from '../util';
16
14
 
17
15
  import { EditorStory } from './components';
18
16
 
19
- const CommandDialog = ({ onAction }: { onAction: (action?: Action) => void }) => {
17
+ // TODO(burdon): Reimplement with Popover.
18
+ const CommandDialog = ({ onAction }: { onAction: (action?: any) => void }) => {
20
19
  const [text, setText] = useState('');
21
20
 
22
21
  const handleInsert = () => {
@@ -55,9 +54,14 @@ const CommandDialog = ({ onAction }: { onAction: (action?: Action) => void }) =>
55
54
  onKeyDown={handleKeyDown}
56
55
  />
57
56
  </Input.Root>
58
- <Button variant='ghost' classNames='pli-0' onClick={() => onAction({ type: 'cancel' })}>
59
- <Icon icon='ph--x--regular' size={5} />
60
- </Button>
57
+ <IconButton
58
+ icon='ph--x--regular'
59
+ label='Cancel'
60
+ iconOnly
61
+ variant='ghost'
62
+ classNames='pli-0'
63
+ onClick={() => onAction({ type: 'cancel' })}
64
+ />
61
65
  </div>
62
66
  </div>
63
67
  );
@@ -65,17 +69,7 @@ const CommandDialog = ({ onAction }: { onAction: (action?: Action) => void }) =>
65
69
 
66
70
  const meta = {
67
71
  title: 'ui/react-ui-editor/CommandDialog',
68
- render: () => (
69
- <EditorStory
70
- text={str('# Command', '', '', '')}
71
- extensions={[
72
- commandDialog({
73
- renderDialog: createRenderer(CommandDialog),
74
- onHint: () => "Press '?' to ask a question",
75
- }),
76
- ]}
77
- />
78
- ),
72
+ render: () => <EditorStory text={str('# Command', '', '')} extensions={[]} />,
79
73
  decorators: [withTheme],
80
74
  parameters: {
81
75
  layout: 'fullscreen',
@@ -12,9 +12,8 @@ import { log } from '@dxos/log';
12
12
  import { withTheme } from '@dxos/react-ui/testing';
13
13
 
14
14
  import { annotations, comments, createExternalCommentSync } from '../extensions';
15
- import { str } from '../testing';
16
15
  import { type Comment } from '../types';
17
- import { createRenderer } from '../util';
16
+ import { createRenderer, str } from '../util';
18
17
 
19
18
  import { EditorStory, content, longText } from './components';
20
19
 
@@ -73,14 +72,14 @@ export const Comments: Story = {
73
72
  };
74
73
 
75
74
  const Key: FC<{ char: string }> = ({ char }) => (
76
- <span className='flex justify-center items-center w-[24px] h-[24px] rounded text-xs bg-neutral-200 text-black'>
75
+ <span className='flex justify-center items-center is-[24px] bs-[24px] rounded text-xs bg-neutral-200 text-black'>
77
76
  {char}
78
77
  </span>
79
78
  );
80
79
 
81
80
  const CommentTooltip: FC<{ shortcut: string }> = ({ shortcut }) => {
82
81
  return (
83
- <div className='flex items-center gap-2 px-2 py-2 bg-neutral-700 text-white text-xs rounded'>
82
+ <div className='flex items-center gap-2 pli-2 plb-2 bg-neutral-700 text-white text-xs rounded'>
84
83
  <div>Create comment</div>
85
84
  <div className='flex gap-1'>
86
85
  {keySymbols(parseShortcut(shortcut)).map((char) => (
@@ -10,7 +10,7 @@ import { useThemeContext } from '@dxos/react-ui';
10
10
  import { withTheme } from '@dxos/react-ui/testing';
11
11
  import { attentionSurface, mx } from '@dxos/react-ui-theme';
12
12
 
13
- import { EditorToolbar, useEditorToolbarState } from '../components';
13
+ import { EditorToolbar, useEditorToolbar } from '../components';
14
14
  import { editorWidth } from '../defaults';
15
15
  import {
16
16
  InputModeExtensions,
@@ -19,7 +19,7 @@ import {
19
19
  createThemeExtensions,
20
20
  decorateMarkdown,
21
21
  formattingKeymap,
22
- useFormattingState,
22
+ formattingListener,
23
23
  } from '../extensions';
24
24
  import { type UseTextEditorProps, useTextEditor } from '../hooks';
25
25
  import { translations } from '../translations';
@@ -29,16 +29,16 @@ type StoryProps = { placeholder?: string } & UseTextEditorProps;
29
29
 
30
30
  const DefaultStory = ({ autoFocus, initialValue, placeholder }: StoryProps) => {
31
31
  const { themeMode } = useThemeContext();
32
- const toolbarState = useEditorToolbarState({ viewMode: 'source' });
32
+
33
+ const toolbarState = useEditorToolbar({ viewMode: 'source' });
33
34
  const viewMode = toolbarState.viewMode;
34
- const trackFormatting = useFormattingState(toolbarState);
35
35
  // TODO(wittjosiah): Provide way to change the input mode.
36
36
  const [editorInputMode, _setEditorInputMode] = useState<EditorInputMode>('default');
37
37
  const { parentRef, view } = useTextEditor(
38
38
  () => ({
39
39
  autoFocus,
40
40
  initialValue,
41
- moveToEndOfLine: true,
41
+ selectionEnd: true,
42
42
  extensions: [
43
43
  editorInputMode ? InputModeExtensions[editorInputMode] : [],
44
44
  createBasicExtensions({ placeholder, lineWrapping: true, readOnly: viewMode === 'readonly', search: true }),
@@ -46,7 +46,7 @@ const DefaultStory = ({ autoFocus, initialValue, placeholder }: StoryProps) => {
46
46
  createThemeExtensions({ themeMode, syntaxHighlighting: true }),
47
47
  viewMode === 'source' ? [] : decorateMarkdown(),
48
48
  formattingKeymap(),
49
- trackFormatting,
49
+ formattingListener(() => toolbarState),
50
50
  ],
51
51
  }),
52
52
  [editorInputMode, viewMode, themeMode, placeholder],
@@ -65,7 +65,7 @@ const DefaultStory = ({ autoFocus, initialValue, placeholder }: StoryProps) => {
65
65
  // Also not sure if view is even guaranteed to exist at this point.
66
66
  return (
67
67
  <div role='none' className={mx('fixed inset-0 flex flex-col')}>
68
- {toolbarState && <EditorToolbar state={toolbarState} getView={getView} viewMode={handleViewModeChange} />}
68
+ {toolbarState && <EditorToolbar state={toolbarState} getView={getView} onViewModeChange={handleViewModeChange} />}
69
69
  <div role='none' className={mx('grow overflow-hidden', attentionSurface)}>
70
70
  <div className={mx(editorWidth)} ref={parentRef} />
71
71
  </div>
@@ -91,6 +91,6 @@ export const Default: Story = {
91
91
  args: {
92
92
  autoFocus: true,
93
93
  placeholder: 'Text...',
94
- initialValue: '# Demo\n\nThis is a document.\n\n',
94
+ initialValue: '# Demo\n\nThis is a **document**.\n\n',
95
95
  },
96
96
  };
@@ -11,7 +11,7 @@ import { faker } from '@dxos/random';
11
11
  import { withTheme } from '@dxos/react-ui/testing';
12
12
 
13
13
  import { blast, defaultOptions, dropFile, typewriter } from '../extensions';
14
- import { str } from '../testing';
14
+ import { str } from '../util';
15
15
 
16
16
  import { EditorStory, content } from './components';
17
17
 
@@ -9,7 +9,7 @@ import React from 'react';
9
9
  import { withTheme } from '@dxos/react-ui/testing';
10
10
 
11
11
  import { decorateMarkdown, image, linkTooltip, table } from '../extensions';
12
- import { str } from '../testing';
12
+ import { str } from '../util';
13
13
 
14
14
  import { EditorStory, content, defaultExtensions, headings, renderLinkTooltip, text } from './components';
15
15
 
@@ -2,16 +2,15 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { type EditorView } from '@codemirror/view';
6
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
7
- import React, { useMemo, useRef } from 'react';
6
+ import React, { useMemo, useState } from 'react';
8
7
 
9
8
  import { withTheme } from '@dxos/react-ui/testing';
10
9
  import { withAttention } from '@dxos/react-ui-attention/testing';
11
10
 
12
- import { type CommandMenuGroup, type CommandMenuItem, CommandMenuProvider } from '../components';
11
+ import { type EditorController, type EditorMenuGroup, EditorMenuProvider } from '../components';
13
12
  import { deleteItem, hashtag, listItemToString, outliner, treeFacet } from '../extensions';
14
- import { str } from '../testing';
13
+ import { str } from '../util';
15
14
 
16
15
  import { EditorStory } from './components';
17
16
 
@@ -20,9 +19,10 @@ type StoryProps = {
20
19
  };
21
20
 
22
21
  const DefaultStory = ({ text }: StoryProps) => {
23
- const viewRef = useRef<EditorView>(null);
22
+ const [controller, setController] = useState<EditorController | null>(null);
24
23
 
25
- const commandGroups: CommandMenuGroup[] = useMemo(
24
+ const extensions = useMemo(() => [outliner(), hashtag()], []);
25
+ const commandGroups: EditorMenuGroup[] = useMemo(
26
26
  () => [
27
27
  {
28
28
  id: 'outliner-actions',
@@ -30,7 +30,7 @@ const DefaultStory = ({ text }: StoryProps) => {
30
30
  {
31
31
  id: 'delete-row',
32
32
  label: 'Delete',
33
- onSelect: (view: EditorView) => {
33
+ onSelect: ({ view }) => {
34
34
  deleteItem(view);
35
35
  },
36
36
  },
@@ -41,19 +41,19 @@ const DefaultStory = ({ text }: StoryProps) => {
41
41
  );
42
42
 
43
43
  return (
44
- <CommandMenuProvider
44
+ <EditorMenuProvider
45
+ view={controller?.view}
45
46
  groups={commandGroups}
46
- onSelect={(item: CommandMenuItem) => {
47
- if (viewRef.current && item.onSelect) {
48
- return item.onSelect(viewRef.current, viewRef.current.state.selection.main.head);
47
+ onSelect={({ view, item }) => {
48
+ if (item.onSelect) {
49
+ return item.onSelect({ view, head: view.state.selection.main.head });
49
50
  }
50
51
  }}
51
52
  >
52
53
  <EditorStory
53
- ref={viewRef}
54
+ ref={setController}
54
55
  text={text}
55
- extensions={[outliner(), hashtag()]}
56
- placeholder=''
56
+ extensions={extensions}
57
57
  debug='raw+tree'
58
58
  debugCustom={(view) => {
59
59
  const tree = view.state.facet(treeFacet);
@@ -62,7 +62,7 @@ const DefaultStory = ({ text }: StoryProps) => {
62
62
  return <pre className='p-1 overflow-auto text-xs text-green-800 dark:text-green-200'>{lines.join('\n')}</pre>;
63
63
  }}
64
64
  />
65
- </CommandMenuProvider>
65
+ </EditorMenuProvider>
66
66
  );
67
67
  };
68
68
 
@@ -0,0 +1,162 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React, { useCallback, useState } from 'react';
7
+
8
+ import { Obj, Query } from '@dxos/echo';
9
+ import { faker } from '@dxos/random';
10
+ import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
11
+ import { Domino } from '@dxos/react-ui';
12
+ import { withTheme } from '@dxos/react-ui/testing';
13
+ import { TestSchema, type ValueGenerator, createObjectFactory } from '@dxos/schema/testing';
14
+
15
+ import {
16
+ type EditorController,
17
+ type EditorMenuGroup,
18
+ type EditorMenuItem,
19
+ EditorMenuProvider,
20
+ type UseEditorMenuProps,
21
+ createMenuGroup,
22
+ filterMenuGroups,
23
+ formattingCommands,
24
+ insertAtCursor,
25
+ insertAtLineStart,
26
+ linkSlashCommands,
27
+ useEditorMenu,
28
+ } from '../components';
29
+ import { str } from '../util';
30
+
31
+ import { EditorStory } from './components';
32
+
33
+ const generator: ValueGenerator = faker as any;
34
+
35
+ const customCompletions: EditorMenuGroup = createMenuGroup({
36
+ id: 'test',
37
+ items: ['Hello world!', 'Hello DXOS', 'Hello Composer', 'https://dxos.org'],
38
+ });
39
+
40
+ const placeholder = (trigger: string[]) =>
41
+ Domino.of('div')
42
+ .children(
43
+ Domino.of('span').text('Press'),
44
+ ...trigger.map((trigger) =>
45
+ Domino.of('span').text(trigger).classNames('border border-separator rounded-sm mx-1 pli-1 pbs-[2px] pbe-[3px]'),
46
+ ),
47
+ Domino.of('span').text('for commands'),
48
+ )
49
+ .build();
50
+
51
+ type StoryProps = Omit<UseEditorMenuProps, 'viewRef'> & { text: string };
52
+
53
+ const DefaultStory = ({ text, ...props }: StoryProps) => {
54
+ const [controller, setController] = useState<EditorController | null>(null);
55
+ const { groupsRef, extension, ...menuProps } = useEditorMenu(props);
56
+
57
+ return (
58
+ <EditorMenuProvider view={controller?.view} groups={groupsRef.current} {...menuProps}>
59
+ <EditorStory ref={setController} text={text} extensions={extension} />
60
+ </EditorMenuProvider>
61
+ );
62
+ };
63
+
64
+ const LinkStory = (args: StoryProps) => {
65
+ const { space } = useClientProvider();
66
+
67
+ const getMenu = useCallback<NonNullable<UseEditorMenuProps['getMenu']>>(
68
+ async ({ text, trigger }): Promise<EditorMenuGroup[]> => {
69
+ if (trigger === '/') {
70
+ return filterMenuGroups([linkSlashCommands], (item) =>
71
+ text ? (item.label as string).toLowerCase().includes(text.toLowerCase()) : true,
72
+ );
73
+ }
74
+
75
+ if (!space) {
76
+ return [];
77
+ }
78
+
79
+ const name = text?.startsWith('@') ? text.slice(1).toLowerCase() : (text?.toLowerCase() ?? '');
80
+ const result = await space?.db.query(Query.type(TestSchema.Person)).run();
81
+ const items = result.objects
82
+ .filter((object) => object.name.toLowerCase().includes(name))
83
+ .map(
84
+ (object): EditorMenuItem => ({
85
+ id: object.id,
86
+ label: object.name,
87
+ icon: 'ph--user--regular',
88
+ onSelect: ({ view, head }) => {
89
+ const link = `[${object.name}](${Obj.getDXN(object)})`;
90
+ if (text?.startsWith('@')) {
91
+ insertAtLineStart(view, head, `!${link}\n`);
92
+ } else {
93
+ insertAtCursor(view, head, `${link} `);
94
+ }
95
+ },
96
+ }),
97
+ );
98
+
99
+ return [{ id: 'test', items }];
100
+ },
101
+ [space],
102
+ );
103
+
104
+ return <DefaultStory {...args} getMenu={getMenu} />;
105
+ };
106
+
107
+ const meta = {
108
+ title: 'ui/react-ui-editor/Popover',
109
+ render: DefaultStory,
110
+ decorators: [withTheme],
111
+ parameters: {
112
+ layout: 'fullscreen',
113
+ },
114
+ } satisfies Meta<typeof DefaultStory>;
115
+
116
+ export default meta;
117
+
118
+ type Story = StoryObj<typeof meta>;
119
+
120
+ export const Default: Story = {
121
+ args: {
122
+ text: str('# Autocomplete', '', ''),
123
+ triggerKey: 'Ctrl-Space',
124
+ filter: true,
125
+ getMenu: () => [customCompletions],
126
+ },
127
+ };
128
+
129
+ export const Formatting: Story = {
130
+ args: {
131
+ text: str('# Slash command', '', ''),
132
+ trigger: '/',
133
+ placeholder: {
134
+ content: () => placeholder(['/']),
135
+ },
136
+ getMenu: () => [formattingCommands],
137
+ },
138
+ };
139
+
140
+ export const Link: Story = {
141
+ render: LinkStory,
142
+ decorators: [
143
+ withClientProvider({
144
+ createSpace: true,
145
+ onInitialized: async (client) => {
146
+ client.addTypes([TestSchema.Person]);
147
+ },
148
+ onCreateSpace: async ({ space }) => {
149
+ const createObjects = createObjectFactory(space.db, generator);
150
+ await createObjects([{ type: TestSchema.Person, count: 10 }]);
151
+ await space.db.flush({ indexes: true });
152
+ },
153
+ }),
154
+ ],
155
+ args: {
156
+ text: str('# Links', '', ''),
157
+ trigger: ['/', '@'],
158
+ placeholder: {
159
+ content: () => placeholder(['/', '@']),
160
+ },
161
+ },
162
+ };
@@ -16,8 +16,15 @@ import { Card } from '@dxos/react-ui-stack';
16
16
  import { hoverableControlItem, hoverableControlItemTransition, hoverableControls } from '@dxos/react-ui-theme';
17
17
  import { trim } from '@dxos/util';
18
18
 
19
- import { type PreviewLinkRef, type PreviewLinkTarget, getLinkRef, image, preview } from '../extensions';
20
- import { PreviewPopoverProvider, usePreviewPopover } from '../testing';
19
+ import { type EditorController, EditorPreviewProvider, useEditorPreview } from '../components';
20
+ import {
21
+ type PreviewBlock,
22
+ type PreviewLinkRef,
23
+ type PreviewLinkTarget,
24
+ getLinkRef,
25
+ image,
26
+ preview,
27
+ } from '../extensions';
21
28
 
22
29
  import { EditorStory } from './components';
23
30
 
@@ -43,7 +50,7 @@ const useRefTarget = (link: PreviewLinkRef): PreviewLinkTarget | undefined => {
43
50
  };
44
51
 
45
52
  const PreviewCard = () => {
46
- const { target } = usePreviewPopover('PreviewCard');
53
+ const { target } = useEditorPreview('PreviewCard');
47
54
  return (
48
55
  <Popover.Portal>
49
56
  <Popover.Content onOpenAutoFocus={(event) => event.preventDefault()}>
@@ -70,7 +77,7 @@ type PreviewAction =
70
77
  link: PreviewLinkRef;
71
78
  };
72
79
 
73
- const PreviewBlock = ({ link, el, view }: { link: PreviewLinkRef; el: HTMLElement; view?: EditorView }) => {
80
+ const PreviewBlockComponent = ({ link, el, view }: { link: PreviewLinkRef; el: HTMLElement; view?: EditorView }) => {
74
81
  const target = useRefTarget(link);
75
82
 
76
83
  const handleAction = useCallback(
@@ -177,53 +184,50 @@ export default meta;
177
184
 
178
185
  type Story = StoryObj<typeof meta>;
179
186
 
187
+ const text = trim`
188
+ # Preview
189
+
190
+ This project is part of the [DXOS](dxn:queue:data:123) SDK.
191
+
192
+ ![DXOS](dxn:queue:data:123)
193
+
194
+ It consists of [ECHO](dxn:queue:data:echo), [HALO](dxn:queue:data:halo), and [MESH](dxn:queue:data:mesh).
195
+
196
+ ## Deep dive
197
+
198
+ ![ECHO](dxn:queue:data:echo)
199
+
200
+ `;
201
+
180
202
  export const Default: Story = {
181
203
  render: () => {
182
- const [view, setView] = useState<EditorView>();
183
- const [previewBlocks, setPreviewBlocks] = useState<{ link: PreviewLinkRef; el: HTMLElement }[]>([]);
204
+ const [controller, setController] = useState<EditorController | null>(null);
205
+ const [previewBlocks, setPreviewBlocks] = useState<PreviewBlock[]>([]);
184
206
  const extensions = useMemo(() => {
185
207
  return [
186
208
  image(),
187
209
  preview({
188
- addBlockContainer: (link, el) => {
189
- setPreviewBlocks((prev) => [...prev, { link, el }]);
210
+ addBlockContainer: (block) => {
211
+ setPreviewBlocks((prev) => [...prev, block]);
190
212
  },
191
- removeBlockContainer: (link) => {
192
- setPreviewBlocks((prev) => prev.filter(({ link: prevLink }) => prevLink.ref !== link.ref));
213
+ removeBlockContainer: (block) => {
214
+ setPreviewBlocks((prev) => prev.filter(({ link: prevLink }) => prevLink.ref !== block.link.ref));
193
215
  },
194
216
  }),
195
217
  ];
196
218
  }, []);
197
219
 
198
- const handleViewRef = useCallback((instance?: EditorView | null) => {
199
- setView(instance ?? undefined);
200
- }, []);
201
-
220
+ // TODO(burdon): Migrate to Editor.Root.
221
+ // TODO(burdon): Ranges must be sorted error (decorate.enter).
202
222
  return (
203
- <PreviewPopoverProvider onLookup={handlePreviewLookup}>
204
- <EditorStory
205
- ref={handleViewRef}
206
- text={trim`
207
- # Preview
208
-
209
- This project is part of the [DXOS](dxn:queue:data:123) SDK.
210
-
211
- ![DXOS](dxn:queue:data:123)
212
-
213
- It consists of [ECHO](dxn:queue:data:echo), [HALO](dxn:queue:data:halo), and [MESH](dxn:queue:data:mesh).
214
-
215
- ## Deep dive
216
-
217
- ![ECHO](dxn:queue:data:echo)
218
-
219
- `}
220
- extensions={extensions}
221
- />
223
+ <EditorPreviewProvider onLookup={handlePreviewLookup}>
224
+ <EditorStory ref={setController} text={text} extensions={extensions} />
222
225
  <PreviewCard />
223
- {previewBlocks.map(({ link, el }) => (
224
- <PreviewBlock key={link.ref} link={link} el={el} view={view} />
225
- ))}
226
- </PreviewPopoverProvider>
226
+ {controller?.view &&
227
+ previewBlocks.map(({ link, el }) => (
228
+ <PreviewBlockComponent key={link.ref} link={link} el={el} view={controller.view!} />
229
+ ))}
230
+ </EditorPreviewProvider>
227
231
  );
228
232
  },
229
233
  };