@dxos/react-ui-editor 0.8.4-main.b97322e → 0.8.4-main.c4373fc

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 (275) hide show
  1. package/dist/lib/browser/{chunk-22UMM3QJ.mjs → chunk-HL3YF6WC.mjs} +2 -2
  2. package/dist/lib/browser/chunk-HL3YF6WC.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +3082 -1957
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +71 -1
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/browser/types/index.mjs +1 -1
  9. package/dist/lib/node-esm/{chunk-YXYQPV6R.mjs → chunk-YJZGD3LY.mjs} +2 -2
  10. package/dist/lib/node-esm/chunk-YJZGD3LY.mjs.map +7 -0
  11. package/dist/lib/node-esm/index.mjs +3082 -1957
  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 +71 -1
  15. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  16. package/dist/lib/node-esm/types/index.mjs +1 -1
  17. package/dist/types/src/components/{Popover → CommandMenu}/CommandMenu.d.ts +10 -6
  18. package/dist/types/src/components/CommandMenu/CommandMenu.d.ts.map +1 -0
  19. package/dist/types/src/components/CommandMenu/index.d.ts +2 -0
  20. package/dist/types/src/components/CommandMenu/index.d.ts.map +1 -0
  21. package/dist/types/src/components/Editor/Editor.d.ts +15 -9
  22. package/dist/types/src/components/Editor/Editor.d.ts.map +1 -1
  23. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
  24. package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
  25. package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
  26. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
  27. package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -1
  28. package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -1
  29. package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -1
  30. package/dist/types/src/components/EditorToolbar/util.d.ts +5 -5
  31. package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -1
  32. package/dist/types/src/components/EditorToolbar/view-mode.d.ts +1 -1
  33. package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -1
  34. package/dist/types/src/components/index.d.ts +1 -1
  35. package/dist/types/src/components/index.d.ts.map +1 -1
  36. package/dist/types/src/defaults.d.ts.map +1 -1
  37. package/dist/types/src/extensions/autocomplete.d.ts +20 -7
  38. package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
  39. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  40. package/dist/types/src/extensions/automerge/automerge.stories.d.ts +10 -19
  41. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  42. package/dist/types/src/extensions/automerge/defs.d.ts +1 -1
  43. package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
  44. package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
  45. package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
  46. package/dist/types/src/extensions/autoscroll.d.ts +10 -0
  47. package/dist/types/src/extensions/autoscroll.d.ts.map +1 -0
  48. package/dist/types/src/extensions/{command → command-dialog}/action.d.ts +1 -1
  49. package/dist/types/src/extensions/command-dialog/action.d.ts.map +1 -0
  50. package/dist/types/src/extensions/{command/command.d.ts → command-dialog/command-dialog.d.ts} +2 -2
  51. package/dist/types/src/extensions/command-dialog/command-dialog.d.ts.map +1 -0
  52. package/dist/types/src/extensions/{command → command-dialog}/hint.d.ts +2 -7
  53. package/dist/types/src/extensions/command-dialog/hint.d.ts.map +1 -0
  54. package/dist/types/src/extensions/command-dialog/index.d.ts +4 -0
  55. package/dist/types/src/extensions/command-dialog/index.d.ts.map +1 -0
  56. package/dist/types/src/extensions/{command → command-dialog}/state.d.ts +1 -1
  57. package/dist/types/src/extensions/command-dialog/state.d.ts.map +1 -0
  58. package/dist/types/src/extensions/command-dialog/typeahead.d.ts.map +1 -0
  59. package/dist/types/src/extensions/{command → command-menu}/command-menu.d.ts +3 -3
  60. package/dist/types/src/extensions/command-menu/command-menu.d.ts.map +1 -0
  61. package/dist/types/src/extensions/command-menu/index.d.ts +3 -0
  62. package/dist/types/src/extensions/command-menu/index.d.ts.map +1 -0
  63. package/dist/types/src/extensions/command-menu/placeholder.d.ts.map +1 -0
  64. package/dist/types/src/extensions/command-menu/useCommandMenu.d.ts +24 -0
  65. package/dist/types/src/extensions/command-menu/useCommandMenu.d.ts.map +1 -0
  66. package/dist/types/src/extensions/comments.d.ts +1 -1
  67. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  68. package/dist/types/src/extensions/dnd.d.ts.map +1 -1
  69. package/dist/types/src/extensions/factories.d.ts +8 -8
  70. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  71. package/dist/types/src/extensions/floating-menu.d.ts.map +1 -0
  72. package/dist/types/src/extensions/focus.d.ts.map +1 -1
  73. package/dist/types/src/extensions/folding.d.ts.map +1 -1
  74. package/dist/types/src/extensions/index.d.ts +5 -1
  75. package/dist/types/src/extensions/index.d.ts.map +1 -1
  76. package/dist/types/src/extensions/json.d.ts +1 -1
  77. package/dist/types/src/extensions/json.d.ts.map +1 -1
  78. package/dist/types/src/extensions/markdown/action.d.ts.map +1 -1
  79. package/dist/types/src/extensions/markdown/bundle.d.ts +8 -2
  80. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
  81. package/dist/types/src/extensions/markdown/changes.d.ts +1 -1
  82. package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -1
  83. package/dist/types/src/extensions/markdown/decorate.d.ts +9 -1
  84. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  85. package/dist/types/src/extensions/markdown/formatting.d.ts +1 -1
  86. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  87. package/dist/types/src/extensions/markdown/formatting.test.d.ts.map +1 -1
  88. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  89. package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
  90. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  91. package/dist/types/src/extensions/outliner/outliner.d.ts +1 -1
  92. package/dist/types/src/extensions/outliner/outliner.d.ts.map +1 -1
  93. package/dist/types/src/extensions/outliner/selection.d.ts.map +1 -1
  94. package/dist/types/src/extensions/outliner/tree.d.ts +2 -2
  95. package/dist/types/src/extensions/outliner/tree.d.ts.map +1 -1
  96. package/dist/types/src/extensions/preview/preview.d.ts +3 -6
  97. package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
  98. package/dist/types/src/extensions/tags/extended-markdown.d.ts +10 -0
  99. package/dist/types/src/extensions/tags/extended-markdown.d.ts.map +1 -0
  100. package/dist/types/src/extensions/tags/extended-markdown.test.d.ts +2 -0
  101. package/dist/types/src/extensions/tags/extended-markdown.test.d.ts.map +1 -0
  102. package/dist/types/src/extensions/tags/index.d.ts +4 -0
  103. package/dist/types/src/extensions/tags/index.d.ts.map +1 -0
  104. package/dist/types/src/extensions/tags/streamer.d.ts +12 -0
  105. package/dist/types/src/extensions/tags/streamer.d.ts.map +1 -0
  106. package/dist/types/src/extensions/tags/xml-tags.d.ts +72 -0
  107. package/dist/types/src/extensions/tags/xml-tags.d.ts.map +1 -0
  108. package/dist/types/src/extensions/tags/xml-util.d.ts +10 -0
  109. package/dist/types/src/extensions/tags/xml-util.d.ts.map +1 -0
  110. package/dist/types/src/hooks/useTextEditor.d.ts +2 -2
  111. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  112. package/dist/types/src/stories/CommandDialog.stories.d.ts +14 -0
  113. package/dist/types/src/stories/CommandDialog.stories.d.ts.map +1 -0
  114. package/dist/types/src/stories/CommandMenu.stories.d.ts +10 -4
  115. package/dist/types/src/stories/CommandMenu.stories.d.ts.map +1 -1
  116. package/dist/types/src/stories/Comments.stories.d.ts +21 -10
  117. package/dist/types/src/stories/Comments.stories.d.ts.map +1 -1
  118. package/dist/types/src/stories/EditorToolbar.stories.d.ts +39 -3
  119. package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -1
  120. package/dist/types/src/stories/Experimental.stories.d.ts +22 -13
  121. package/dist/types/src/stories/Experimental.stories.d.ts.map +1 -1
  122. package/dist/types/src/stories/Markdown.stories.d.ts +32 -43
  123. package/dist/types/src/stories/Markdown.stories.d.ts.map +1 -1
  124. package/dist/types/src/stories/Outliner.stories.d.ts +15 -21
  125. package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -1
  126. package/dist/types/src/stories/Preview.stories.d.ts +21 -7
  127. package/dist/types/src/stories/Preview.stories.d.ts.map +1 -1
  128. package/dist/types/src/stories/Tags.stories.d.ts +16 -0
  129. package/dist/types/src/stories/Tags.stories.d.ts.map +1 -0
  130. package/dist/types/src/stories/TextEditor.stories.d.ts +38 -52
  131. package/dist/types/src/stories/TextEditor.stories.d.ts.map +1 -1
  132. package/dist/types/src/stories/components/EditorStory.d.ts +6 -9
  133. package/dist/types/src/stories/components/EditorStory.d.ts.map +1 -1
  134. package/dist/types/src/styles/theme.d.ts.map +1 -1
  135. package/dist/types/src/testing/PreviewPopover.d.ts +20 -0
  136. package/dist/types/src/testing/PreviewPopover.d.ts.map +1 -0
  137. package/dist/types/src/testing/index.d.ts +1 -0
  138. package/dist/types/src/testing/index.d.ts.map +1 -1
  139. package/dist/types/src/testing/util.d.ts +1 -0
  140. package/dist/types/src/testing/util.d.ts.map +1 -1
  141. package/dist/types/src/translations.d.ts +1 -1
  142. package/dist/types/src/types/types.d.ts +2 -2
  143. package/dist/types/src/types/types.d.ts.map +1 -1
  144. package/dist/types/src/util/cursor.d.ts.map +1 -1
  145. package/dist/types/src/util/debug.d.ts +1 -1
  146. package/dist/types/src/util/debug.d.ts.map +1 -1
  147. package/dist/types/src/util/decorations.d.ts +4 -0
  148. package/dist/types/src/util/decorations.d.ts.map +1 -0
  149. package/dist/types/src/util/dom.d.ts +2 -12
  150. package/dist/types/src/util/dom.d.ts.map +1 -1
  151. package/dist/types/src/util/index.d.ts +1 -0
  152. package/dist/types/src/util/index.d.ts.map +1 -1
  153. package/dist/types/src/util/react.d.ts +1 -1
  154. package/dist/types/src/util/react.d.ts.map +1 -1
  155. package/dist/types/tsconfig.tsbuildinfo +1 -1
  156. package/package.json +68 -60
  157. package/src/components/{Popover → CommandMenu}/CommandMenu.tsx +95 -26
  158. package/src/components/{Popover → CommandMenu}/index.ts +0 -2
  159. package/src/components/Editor/Editor.tsx +50 -15
  160. package/src/components/EditorToolbar/EditorToolbar.tsx +41 -30
  161. package/src/components/EditorToolbar/blocks.ts +21 -24
  162. package/src/components/EditorToolbar/formatting.ts +22 -25
  163. package/src/components/EditorToolbar/headings.ts +10 -5
  164. package/src/components/EditorToolbar/image.ts +8 -4
  165. package/src/components/EditorToolbar/lists.ts +16 -19
  166. package/src/components/EditorToolbar/search.ts +8 -4
  167. package/src/components/EditorToolbar/util.ts +16 -5
  168. package/src/components/EditorToolbar/view-mode.ts +11 -6
  169. package/src/components/index.ts +1 -1
  170. package/src/defaults.ts +5 -2
  171. package/src/extensions/autocomplete.ts +204 -54
  172. package/src/extensions/automerge/automerge.stories.tsx +31 -24
  173. package/src/extensions/automerge/automerge.ts +4 -3
  174. package/src/extensions/automerge/defs.ts +1 -1
  175. package/src/extensions/automerge/sync.ts +1 -1
  176. package/src/extensions/automerge/update-automerge.ts +1 -1
  177. package/src/extensions/autoscroll.ts +157 -0
  178. package/src/extensions/awareness/awareness.ts +2 -2
  179. package/src/extensions/{command → command-dialog}/action.ts +2 -3
  180. package/src/extensions/{command/command.ts → command-dialog/command-dialog.ts} +4 -4
  181. package/src/extensions/{command → command-dialog}/hint.ts +2 -1
  182. package/src/extensions/command-dialog/index.ts +7 -0
  183. package/src/extensions/{command → command-dialog}/state.ts +4 -3
  184. package/src/extensions/{command → command-dialog}/typeahead.ts +2 -2
  185. package/src/extensions/{command → command-menu}/command-menu.ts +9 -9
  186. package/src/extensions/command-menu/index.ts +6 -0
  187. package/src/extensions/{command → command-menu}/placeholder.ts +1 -1
  188. package/src/extensions/{command → command-menu}/useCommandMenu.ts +35 -19
  189. package/src/extensions/comments.ts +18 -13
  190. package/src/extensions/dnd.ts +1 -1
  191. package/src/extensions/factories.ts +56 -31
  192. package/src/extensions/{command/floating-menu.ts → floating-menu.ts} +12 -19
  193. package/src/extensions/focus.ts +5 -4
  194. package/src/extensions/folding.tsx +4 -6
  195. package/src/extensions/hashtag.tsx +2 -2
  196. package/src/extensions/index.ts +5 -1
  197. package/src/extensions/json.ts +1 -1
  198. package/src/extensions/markdown/action.ts +2 -1
  199. package/src/extensions/markdown/bundle.ts +27 -5
  200. package/src/extensions/markdown/changes.ts +1 -1
  201. package/src/extensions/markdown/decorate.ts +24 -14
  202. package/src/extensions/markdown/formatting.test.ts +6 -6
  203. package/src/extensions/markdown/formatting.ts +3 -3
  204. package/src/extensions/markdown/highlight.ts +1 -1
  205. package/src/extensions/markdown/image.ts +3 -4
  206. package/src/extensions/markdown/link.ts +3 -0
  207. package/src/extensions/markdown/table.ts +7 -1
  208. package/src/extensions/mention.ts +1 -1
  209. package/src/extensions/outliner/outliner.test.ts +3 -2
  210. package/src/extensions/outliner/outliner.ts +6 -5
  211. package/src/extensions/outliner/selection.ts +1 -1
  212. package/src/extensions/outliner/tree.test.ts +2 -1
  213. package/src/extensions/outliner/tree.ts +2 -2
  214. package/src/extensions/preview/preview.ts +59 -62
  215. package/src/extensions/selection.ts +2 -2
  216. package/src/extensions/tags/extended-markdown.test.ts +261 -0
  217. package/src/extensions/tags/extended-markdown.ts +78 -0
  218. package/src/extensions/tags/index.ts +7 -0
  219. package/src/extensions/tags/streamer.ts +243 -0
  220. package/src/extensions/tags/xml-tags.ts +393 -0
  221. package/src/extensions/tags/xml-util.ts +94 -0
  222. package/src/hooks/useTextEditor.ts +8 -20
  223. package/src/stories/CommandDialog.stories.tsx +89 -0
  224. package/src/stories/CommandMenu.stories.tsx +33 -34
  225. package/src/stories/Comments.stories.tsx +14 -10
  226. package/src/stories/EditorToolbar.stories.tsx +13 -12
  227. package/src/stories/Experimental.stories.tsx +17 -13
  228. package/src/stories/Markdown.stories.tsx +25 -21
  229. package/src/stories/Outliner.stories.tsx +46 -34
  230. package/src/stories/Preview.stories.tsx +34 -33
  231. package/src/stories/Tags.stories.tsx +81 -0
  232. package/src/stories/TextEditor.stories.tsx +45 -38
  233. package/src/stories/components/EditorStory.tsx +14 -15
  234. package/src/styles/theme.ts +15 -12
  235. package/src/testing/PreviewPopover.tsx +78 -0
  236. package/src/testing/index.ts +1 -0
  237. package/src/testing/util.ts +2 -0
  238. package/src/translations.ts +1 -1
  239. package/src/types/types.ts +1 -1
  240. package/src/util/cursor.ts +2 -1
  241. package/src/util/debug.ts +2 -2
  242. package/src/util/decorations.ts +21 -0
  243. package/src/util/dom.ts +5 -27
  244. package/src/util/index.ts +1 -0
  245. package/src/util/react.tsx +1 -1
  246. package/dist/lib/browser/chunk-22UMM3QJ.mjs.map +0 -7
  247. package/dist/lib/node-esm/chunk-YXYQPV6R.mjs.map +0 -7
  248. package/dist/types/src/components/Popover/CommandMenu.d.ts.map +0 -1
  249. package/dist/types/src/components/Popover/RefDropdownMenu.d.ts +0 -21
  250. package/dist/types/src/components/Popover/RefDropdownMenu.d.ts.map +0 -1
  251. package/dist/types/src/components/Popover/RefPopover.d.ts +0 -34
  252. package/dist/types/src/components/Popover/RefPopover.d.ts.map +0 -1
  253. package/dist/types/src/components/Popover/index.d.ts +0 -4
  254. package/dist/types/src/components/Popover/index.d.ts.map +0 -1
  255. package/dist/types/src/extensions/command/action.d.ts.map +0 -1
  256. package/dist/types/src/extensions/command/command-menu.d.ts.map +0 -1
  257. package/dist/types/src/extensions/command/command.d.ts.map +0 -1
  258. package/dist/types/src/extensions/command/floating-menu.d.ts.map +0 -1
  259. package/dist/types/src/extensions/command/hint.d.ts.map +0 -1
  260. package/dist/types/src/extensions/command/index.d.ts +0 -7
  261. package/dist/types/src/extensions/command/index.d.ts.map +0 -1
  262. package/dist/types/src/extensions/command/placeholder.d.ts.map +0 -1
  263. package/dist/types/src/extensions/command/state.d.ts.map +0 -1
  264. package/dist/types/src/extensions/command/typeahead.d.ts.map +0 -1
  265. package/dist/types/src/extensions/command/useCommandMenu.d.ts +0 -26
  266. package/dist/types/src/extensions/command/useCommandMenu.d.ts.map +0 -1
  267. package/dist/types/src/stories/Command.stories.d.ts +0 -7
  268. package/dist/types/src/stories/Command.stories.d.ts.map +0 -1
  269. package/src/components/Popover/RefDropdownMenu.tsx +0 -85
  270. package/src/components/Popover/RefPopover.tsx +0 -99
  271. package/src/extensions/command/index.ts +0 -10
  272. package/src/stories/Command.stories.tsx +0 -97
  273. /package/dist/types/src/extensions/{command → command-dialog}/typeahead.d.ts +0 -0
  274. /package/dist/types/src/extensions/{command → command-menu}/placeholder.d.ts +0 -0
  275. /package/dist/types/src/extensions/{command/floating-menu.d.ts → floating-menu.d.ts} +0 -0
@@ -2,35 +2,39 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { markdown } from '@codemirror/lang-markdown';
6
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
7
  import React from 'react';
9
8
 
10
- import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
9
+ import { withTheme } from '@dxos/react-ui/testing';
11
10
 
12
- import { EditorStory, content, defaultExtensions, headings, renderLinkTooltip, text } from './components';
13
11
  import { decorateMarkdown, image, linkTooltip, table } from '../extensions';
14
12
  import { str } from '../testing';
15
13
 
16
- const meta: Meta<typeof EditorStory> = {
14
+ import { EditorStory, content, defaultExtensions, headings, renderLinkTooltip, text } from './components';
15
+
16
+ const meta = {
17
17
  title: 'ui/react-ui-editor/Markdown',
18
18
  component: EditorStory,
19
- decorators: [withTheme, withLayout({ fullscreen: true })],
20
- parameters: { layout: 'fullscreen' },
21
- };
19
+ decorators: [withTheme],
20
+ parameters: {
21
+ layout: 'fullscreen',
22
+ },
23
+ } satisfies Meta<typeof EditorStory>;
22
24
 
23
25
  export default meta;
24
26
 
27
+ type Story = StoryObj<typeof meta>;
28
+
25
29
  //
26
30
  // Default
27
31
  //
28
32
 
29
- export const Default = {
33
+ export const Default: Story = {
30
34
  render: () => <EditorStory text={text} extensions={defaultExtensions} />,
31
35
  };
32
36
 
33
- export const Blockquote = {
37
+ export const Blockquote: Story = {
34
38
  render: () => (
35
39
  <EditorStory
36
40
  text={str('> Blockquote', 'continuation', content.footer)}
@@ -40,23 +44,23 @@ export const Blockquote = {
40
44
  ),
41
45
  };
42
46
 
43
- export const Headings = {
47
+ export const Headings: Story = {
44
48
  render: () => <EditorStory text={headings} extensions={decorateMarkdown({ numberedHeadings: { from: 2, to: 4 } })} />,
45
49
  };
46
50
 
47
- export const Links = {
51
+ export const Links: Story = {
48
52
  render: () => <EditorStory text={str(content.links, content.footer)} extensions={[linkTooltip(renderLinkTooltip)]} />,
49
53
  };
50
54
 
51
- export const Image = {
55
+ export const Image: Story = {
52
56
  render: () => <EditorStory text={str(content.image, content.footer)} extensions={[image()]} />,
53
57
  };
54
58
 
55
- export const Code = {
59
+ export const Code: Story = {
56
60
  render: () => <EditorStory text={str(content.codeblocks, content.footer)} extensions={[decorateMarkdown()]} />,
57
61
  };
58
62
 
59
- export const Lists = {
63
+ export const Lists: Story = {
60
64
  render: () => (
61
65
  <EditorStory
62
66
  text={str(content.tasks, '', content.bullets, '', content.numbered, content.footer)}
@@ -69,7 +73,7 @@ export const Lists = {
69
73
  // Bullet List
70
74
  //
71
75
 
72
- export const BulletList = {
76
+ export const BulletList: Story = {
73
77
  render: () => <EditorStory text={str(content.bullets, content.footer)} extensions={[decorateMarkdown()]} />,
74
78
  };
75
79
 
@@ -77,7 +81,7 @@ export const BulletList = {
77
81
  // Ordered List
78
82
  //
79
83
 
80
- export const OrderedList = {
84
+ export const OrderedList: Story = {
81
85
  render: () => <EditorStory text={str(content.numbered, content.footer)} extensions={[decorateMarkdown()]} />,
82
86
  };
83
87
 
@@ -85,13 +89,13 @@ export const OrderedList = {
85
89
  // Task List
86
90
  //
87
91
 
88
- export const TaskList = {
92
+ export const TaskList: Story = {
89
93
  render: () => (
90
94
  <EditorStory text={str(content.tasks, content.footer)} extensions={[decorateMarkdown()]} debug='raw+tree' />
91
95
  ),
92
96
  };
93
97
 
94
- export const TaskListEmpty = {
98
+ export const TaskListEmpty: Story = {
95
99
  render: () => <EditorStory text={str('- [ ] ')} extensions={[decorateMarkdown()]} debug='raw+tree' />,
96
100
  };
97
101
 
@@ -99,7 +103,7 @@ export const TaskListEmpty = {
99
103
  // Table
100
104
  //
101
105
 
102
- export const Table = {
106
+ export const Table: Story = {
103
107
  render: () => <EditorStory text={str(content.table, content.footer)} extensions={[decorateMarkdown(), table()]} />,
104
108
  };
105
109
 
@@ -107,7 +111,7 @@ export const Table = {
107
111
  // Commented out
108
112
  //
109
113
 
110
- export const CommentedOut = {
114
+ export const CommentedOut: Story = {
111
115
  render: () => (
112
116
  <EditorStory
113
117
  text={str('# Commented out', '', content.comment, content.footer)}
@@ -2,41 +2,58 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { type EditorView } from '@codemirror/view';
8
- import React, { useRef } from 'react';
6
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
7
+ import React, { useMemo, useRef } from 'react';
9
8
 
10
- import { DropdownMenu } from '@dxos/react-ui';
9
+ import { withTheme } from '@dxos/react-ui/testing';
11
10
  import { withAttention } from '@dxos/react-ui-attention/testing';
12
- import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
13
11
 
14
- import { EditorStory } from './components';
15
- import { RefDropdownMenu } from '../components';
16
- import { outliner, listItemToString, treeFacet, deleteItem, hashtag } from '../extensions';
12
+ import { type CommandMenuGroup, type CommandMenuItem, CommandMenuProvider } from '../components';
13
+ import { deleteItem, hashtag, listItemToString, outliner, treeFacet } from '../extensions';
17
14
  import { str } from '../testing';
18
15
 
16
+ import { EditorStory } from './components';
17
+
19
18
  type StoryProps = {
20
- text: string;
19
+ text?: string;
21
20
  };
22
21
 
23
22
  const DefaultStory = ({ text }: StoryProps) => {
24
23
  const viewRef = useRef<EditorView>(null);
25
24
 
26
- const handleDelete = () => {
27
- if (viewRef.current) {
28
- deleteItem(viewRef.current);
29
- }
30
- };
25
+ const commandGroups: CommandMenuGroup[] = useMemo(
26
+ () => [
27
+ {
28
+ id: 'outliner-actions',
29
+ items: [
30
+ {
31
+ id: 'delete-row',
32
+ label: 'Delete',
33
+ onSelect: (view: EditorView) => {
34
+ deleteItem(view);
35
+ },
36
+ },
37
+ ],
38
+ },
39
+ ],
40
+ [],
41
+ );
31
42
 
32
43
  return (
33
- <RefDropdownMenu.Provider>
44
+ <CommandMenuProvider
45
+ groups={commandGroups}
46
+ onSelect={(item: CommandMenuItem) => {
47
+ if (viewRef.current && item.onSelect) {
48
+ return item.onSelect(viewRef.current, viewRef.current.state.selection.main.head);
49
+ }
50
+ }}
51
+ >
34
52
  <EditorStory
35
53
  ref={viewRef}
36
54
  text={text}
37
55
  extensions={[outliner(), hashtag()]}
38
56
  placeholder=''
39
- slots={{}}
40
57
  debug='raw+tree'
41
58
  debugCustom={(view) => {
42
59
  const tree = view.state.facet(treeFacet);
@@ -45,33 +62,28 @@ const DefaultStory = ({ text }: StoryProps) => {
45
62
  return <pre className='p-1 overflow-auto text-xs text-green-800 dark:text-green-200'>{lines.join('\n')}</pre>;
46
63
  }}
47
64
  />
48
-
49
- <DropdownMenu.Portal>
50
- <DropdownMenu.Content>
51
- <DropdownMenu.Viewport>
52
- <DropdownMenu.Item onClick={handleDelete}>Delete</DropdownMenu.Item>
53
- </DropdownMenu.Viewport>
54
- <DropdownMenu.Arrow />
55
- </DropdownMenu.Content>
56
- </DropdownMenu.Portal>
57
- </RefDropdownMenu.Provider>
65
+ </CommandMenuProvider>
58
66
  );
59
67
  };
60
68
 
61
- const meta: Meta<StoryProps> = {
69
+ const meta = {
62
70
  title: 'ui/react-ui-editor/Outliner',
63
71
  render: DefaultStory,
64
- decorators: [withAttention, withTheme, withLayout({ fullscreen: true })],
65
- parameters: { layout: 'fullscreen' },
66
- };
72
+ decorators: [withTheme, withAttention],
73
+ parameters: {
74
+ layout: 'fullscreen',
75
+ },
76
+ } satisfies Meta<typeof DefaultStory>;
67
77
 
68
78
  export default meta;
69
79
 
70
- export const Empty = {
80
+ type Story = StoryObj<typeof meta>;
81
+
82
+ export const Empty: Story = {
71
83
  args: {},
72
84
  };
73
85
 
74
- export const Basic = {
86
+ export const Basic: Story = {
75
87
  args: {
76
88
  text: str(
77
89
  //
@@ -86,7 +98,7 @@ export const Basic = {
86
98
  },
87
99
  };
88
100
 
89
- export const Nested = {
101
+ export const Nested: Story = {
90
102
  args: {
91
103
  text: str(
92
104
  //
@@ -101,7 +113,7 @@ export const Nested = {
101
113
  },
102
114
  };
103
115
 
104
- export const Continuation = {
116
+ export const Continuation: Story = {
105
117
  args: {
106
118
  text: str(
107
119
  //
@@ -2,24 +2,24 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { syntaxTree } from '@codemirror/language';
8
6
  import { type EditorView } from '@codemirror/view';
9
- import React, { useState, useEffect, useMemo, useCallback } from 'react';
7
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
10
9
  import { createPortal } from 'react-dom';
11
10
 
12
11
  import { invariant } from '@dxos/invariant';
13
12
  import { faker } from '@dxos/random';
14
13
  import { Popover } from '@dxos/react-ui';
14
+ import { withTheme } from '@dxos/react-ui/testing';
15
15
  import { Card } from '@dxos/react-ui-stack';
16
16
  import { hoverableControlItem, hoverableControlItemTransition, hoverableControls } from '@dxos/react-ui-theme';
17
- import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
17
+ import { trim } from '@dxos/util';
18
+
19
+ import { type PreviewLinkRef, type PreviewLinkTarget, getLinkRef, image, preview } from '../extensions';
20
+ import { PreviewPopoverProvider, usePreviewPopover } from '../testing';
18
21
 
19
22
  import { EditorStory } from './components';
20
- import { PreviewProvider, useRefPopover } from '../components';
21
- import { preview, image, type PreviewLinkRef, type PreviewLinkTarget, getLinkRef } from '../extensions';
22
- import { str } from '../testing';
23
23
 
24
24
  const handlePreviewLookup = async ({ label, ref }: PreviewLinkRef): Promise<PreviewLinkTarget> => {
25
25
  // Random text.
@@ -43,7 +43,7 @@ const useRefTarget = (link: PreviewLinkRef): PreviewLinkTarget | undefined => {
43
43
  };
44
44
 
45
45
  const PreviewCard = () => {
46
- const { target } = useRefPopover('PreviewCard');
46
+ const { target } = usePreviewPopover('PreviewCard');
47
47
  return (
48
48
  <Popover.Portal>
49
49
  <Popover.Content onOpenAutoFocus={(event) => event.preventDefault()}>
@@ -132,7 +132,7 @@ const PreviewBlock = ({ link, el, view }: { link: PreviewLinkRef; el: HTMLElemen
132
132
  <Card.Toolbar classNames='is-min p-[--dx-cardSpacingInline]'>
133
133
  {(link.suggest && (
134
134
  <>
135
- <Card.ToolbarIconButton label='Discard' icon={'ph--x--regular'} onClick={handleDelete} />
135
+ <Card.ToolbarIconButton label='Discard' icon='ph--x--regular' onClick={handleDelete} />
136
136
  {target && (
137
137
  <Card.ToolbarIconButton
138
138
  classNames='bg-successSurface text-successSurfaceText'
@@ -164,20 +164,23 @@ const PreviewBlock = ({ link, el, view }: { link: PreviewLinkRef; el: HTMLElemen
164
164
  );
165
165
  };
166
166
 
167
- const meta: Meta<typeof EditorStory> = {
167
+ const meta = {
168
168
  title: 'ui/react-ui-editor/Preview',
169
169
  component: EditorStory,
170
- decorators: [withTheme, withLayout({ fullscreen: true })],
171
- parameters: { layout: 'fullscreen' },
172
- };
170
+ decorators: [withTheme],
171
+ parameters: {
172
+ layout: 'fullscreen',
173
+ },
174
+ } satisfies Meta<typeof EditorStory>;
173
175
 
174
176
  export default meta;
175
177
 
176
- export const Default = {
178
+ type Story = StoryObj<typeof meta>;
179
+
180
+ export const Default: Story = {
177
181
  render: () => {
178
182
  const [view, setView] = useState<EditorView>();
179
183
  const [previewBlocks, setPreviewBlocks] = useState<{ link: PreviewLinkRef; el: HTMLElement }[]>([]);
180
-
181
184
  const extensions = useMemo(() => {
182
185
  return [
183
186
  image(),
@@ -197,32 +200,30 @@ export const Default = {
197
200
  }, []);
198
201
 
199
202
  return (
200
- <PreviewProvider onLookup={handlePreviewLookup}>
203
+ <PreviewPopoverProvider onLookup={handlePreviewLookup}>
201
204
  <EditorStory
202
205
  ref={handleViewRef}
203
- text={str(
204
- '# Preview',
205
- '',
206
- 'This project is part of the [DXOS][dxn:queue:data:123] SDK.',
207
- '',
208
- '![DXOS][?dxn:queue:data:123]',
209
- '',
210
- 'It consists of [ECHO][dxn:queue:data:echo], [HALO][dxn:queue:data:halo], and [MESH][dxn:queue:data:mesh].',
211
- '',
212
- '## Deep dive',
213
- '',
214
- '![ECHO][dxn:queue:data:echo]',
215
- '',
216
- '',
217
- '',
218
- )}
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
+ `}
219
220
  extensions={extensions}
220
221
  />
221
222
  <PreviewCard />
222
223
  {previewBlocks.map(({ link, el }) => (
223
224
  <PreviewBlock key={link.ref} link={link} el={el} view={view} />
224
225
  ))}
225
- </PreviewProvider>
226
+ </PreviewPopoverProvider>
226
227
  );
227
228
  },
228
229
  };
@@ -0,0 +1,81 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import React, { useState } from 'react';
7
+ import { createPortal } from 'react-dom';
8
+
9
+ import { useThemeContext } from '@dxos/react-ui';
10
+ import { withTheme } from '@dxos/react-ui/testing';
11
+ import { trim } from '@dxos/util';
12
+
13
+ import {
14
+ type XmlWidgetRegistry,
15
+ type XmlWidgetState,
16
+ createBasicExtensions,
17
+ createThemeExtensions,
18
+ decorateMarkdown,
19
+ extendedMarkdown,
20
+ xmlTags,
21
+ } from '../extensions';
22
+ import { useTextEditor } from '../hooks';
23
+
24
+ const registry = {
25
+ // <test/>
26
+ ['test' as const]: {
27
+ block: true,
28
+ Component: () => <div className='p-2 border border-separator rounded'>Test</div>,
29
+ },
30
+ } satisfies XmlWidgetRegistry;
31
+
32
+ const DefaultStory = ({ text }: { text?: string }) => {
33
+ const { themeMode } = useThemeContext();
34
+ const [widgets, setWidgets] = useState<XmlWidgetState[]>([]);
35
+ const { parentRef } = useTextEditor({
36
+ initialValue: text,
37
+ extensions: [
38
+ createThemeExtensions({ themeMode }),
39
+ createBasicExtensions({ lineWrapping: true, readOnly: true }),
40
+ decorateMarkdown(),
41
+ extendedMarkdown({ registry }),
42
+ xmlTags({ registry, setWidgets }),
43
+ ],
44
+ });
45
+
46
+ return (
47
+ <>
48
+ <div ref={parentRef} className='is-full p-4' />
49
+ {widgets.map(({ Component, root, id, ...props }) => (
50
+ <div key={id}>{createPortal(<Component {...props} />, root)}</div>
51
+ ))}
52
+ </>
53
+ );
54
+ };
55
+
56
+ const text = trim`
57
+ # Tags
58
+
59
+ <test id="123" />
60
+
61
+ React widget above.
62
+ `;
63
+
64
+ const meta = {
65
+ title: 'ui/react-ui-editor/Tags',
66
+ render: DefaultStory,
67
+ decorators: [withTheme],
68
+ parameters: {
69
+ layout: 'fullscreen',
70
+ },
71
+ } satisfies Meta<typeof DefaultStory>;
72
+
73
+ export default meta;
74
+
75
+ type Story = StoryObj<typeof meta>;
76
+
77
+ export const Default: Story = {
78
+ args: {
79
+ text,
80
+ },
81
+ };
@@ -2,28 +2,14 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
5
  import { javascript } from '@codemirror/lang-javascript';
8
6
  import { openSearchPanel } from '@codemirror/search';
7
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
9
8
  import React from 'react';
10
9
 
11
10
  import { log } from '@dxos/log';
12
- import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
11
+ import { withTheme } from '@dxos/react-ui/testing';
13
12
 
14
- import {
15
- EditorStory,
16
- allExtensions,
17
- content,
18
- defaultExtensions,
19
- global,
20
- largeWithImages,
21
- links,
22
- longText,
23
- names,
24
- renderLinkButton,
25
- text,
26
- } from './components';
27
13
  import { editorMonospace } from '../defaults';
28
14
  import {
29
15
  InputModeExtensions,
@@ -39,12 +25,29 @@ import {
39
25
  } from '../extensions';
40
26
  import { str } from '../testing';
41
27
 
42
- const meta: Meta<typeof EditorStory> = {
28
+ import {
29
+ EditorStory,
30
+ allExtensions,
31
+ content,
32
+ defaultExtensions,
33
+ global,
34
+ largeWithImages,
35
+ links,
36
+ longText,
37
+ names,
38
+ renderLinkButton,
39
+ text,
40
+ } from './components';
41
+
42
+ const meta = {
43
43
  title: 'ui/react-ui-editor/TextEditor',
44
44
  component: EditorStory,
45
- decorators: [withTheme, withLayout({ fullscreen: true })],
46
- parameters: { layout: 'fullscreen', controls: { disable: true } },
47
- };
45
+ decorators: [withTheme],
46
+ parameters: {
47
+ layout: 'fullscreen',
48
+ controls: { disable: true },
49
+ },
50
+ } satisfies Meta<typeof EditorStory>;
48
51
 
49
52
  export default meta;
50
53
 
@@ -52,7 +55,9 @@ export default meta;
52
55
  // Default
53
56
  //
54
57
 
55
- export const Default = {
58
+ type Story = StoryObj<typeof meta>;
59
+
60
+ export const Default: Story = {
56
61
  render: () => <EditorStory text={text} extensions={defaultExtensions} />,
57
62
  };
58
63
 
@@ -60,7 +65,7 @@ export const Default = {
60
65
  // Everything
61
66
  //
62
67
 
63
- export const Everything = {
68
+ export const Everything: Story = {
64
69
  render: () => <EditorStory text={text} extensions={allExtensions} selection={{ anchor: 99, head: 110 }} />,
65
70
  };
66
71
 
@@ -68,7 +73,7 @@ export const Everything = {
68
73
  // Empty
69
74
  //
70
75
 
71
- export const Empty = {
76
+ export const Empty: Story = {
72
77
  render: () => <EditorStory extensions={defaultExtensions} />,
73
78
  };
74
79
 
@@ -76,7 +81,7 @@ export const Empty = {
76
81
  // Readonly
77
82
  //
78
83
 
79
- export const Readonly = {
84
+ export const Readonly: Story = {
80
85
  render: () => <EditorStory text={text} extensions={defaultExtensions} readOnly />,
81
86
  };
82
87
 
@@ -84,7 +89,7 @@ export const Readonly = {
84
89
  // No Extensions
85
90
  //
86
91
 
87
- export const NoExtensions = {
92
+ export const NoExtensions: Story = {
88
93
  render: () => <EditorStory text={text} />,
89
94
  };
90
95
 
@@ -92,7 +97,7 @@ export const NoExtensions = {
92
97
  // Vim
93
98
  //
94
99
 
95
- export const Vim = {
100
+ export const Vim: Story = {
96
101
  render: () => (
97
102
  <EditorStory
98
103
  text={str('# Vim Mode', '', 'The distant future. The year 2000.', '', content.paragraphs)}
@@ -105,7 +110,7 @@ export const Vim = {
105
110
  // Listener
106
111
  //
107
112
 
108
- export const Listener = {
113
+ export const Listener: Story = {
109
114
  render: () => (
110
115
  <EditorStory
111
116
  text={str('# Listener', '', content.footer)}
@@ -127,7 +132,7 @@ export const Listener = {
127
132
  // Folding
128
133
  //
129
134
 
130
- export const Folding = {
135
+ export const Folding: Story = {
131
136
  render: () => <EditorStory text={text} extensions={[folding()]} />,
132
137
  };
133
138
 
@@ -135,7 +140,7 @@ export const Folding = {
135
140
  // Scrolling
136
141
  //
137
142
 
138
- export const Scrolling = {
143
+ export const Scrolling: Story = {
139
144
  render: () => (
140
145
  <EditorStory
141
146
  text={str('# Large Document', '', longText)}
@@ -147,13 +152,13 @@ export const Scrolling = {
147
152
  ),
148
153
  };
149
154
 
150
- export const ScrollingWithImages = {
155
+ export const ScrollingWithImages: Story = {
151
156
  render: () => (
152
157
  <EditorStory text={str('# Large Document', '', largeWithImages)} extensions={[decorateMarkdown(), image()]} />
153
158
  ),
154
159
  };
155
160
 
156
- export const ScrollTo = {
161
+ export const ScrollTo: Story = {
157
162
  render: () => {
158
163
  // NOTE: Selection won't appear if text is reformatted.
159
164
  const word = 'Scroll to here...';
@@ -174,7 +179,7 @@ export const ScrollTo = {
174
179
  // Typescript
175
180
  //
176
181
 
177
- export const Typescript = {
182
+ export const Typescript: Story = {
178
183
  render: () => (
179
184
  <EditorStory
180
185
  text={content.typescript}
@@ -188,15 +193,17 @@ export const Typescript = {
188
193
  // Autocomplete
189
194
  //
190
195
 
191
- export const Autocomplete = {
196
+ export const Autocomplete: Story = {
192
197
  render: () => (
193
198
  <EditorStory
194
199
  text={str('# Autocomplete', '', 'Press Ctrl-Space...', content.footer)}
195
200
  extensions={[
196
201
  decorateMarkdown({ renderLinkButton }),
197
202
  autocomplete({
198
- onSearch: (text) => {
199
- return links.filter(({ label }) => label.toLowerCase().includes(text.toLowerCase()));
203
+ onSuggest: (text) => {
204
+ return links
205
+ .filter(({ label }) => label.toLowerCase().includes(text.toLowerCase()))
206
+ .map(({ label }) => label);
200
207
  },
201
208
  }),
202
209
  ]}
@@ -210,7 +217,7 @@ export const Autocomplete = {
210
217
 
211
218
  const completions = ['type', 'AND', 'OR', 'NOT', 'dxos.org'];
212
219
 
213
- export const Typeahead = {
220
+ export const Typeahead: Story = {
214
221
  render: () => (
215
222
  <EditorStory
216
223
  text={str('# Typeahead', '')}
@@ -228,7 +235,7 @@ export const Typeahead = {
228
235
  // Mention
229
236
  //
230
237
 
231
- export const Mention = {
238
+ export const Mention: Story = {
232
239
  render: () => (
233
240
  <EditorStory
234
241
  text={str('# Mention', '', 'Type @...', content.footer)}
@@ -245,7 +252,7 @@ export const Mention = {
245
252
  // Search
246
253
  //
247
254
 
248
- export const Search = {
255
+ export const Search: Story = {
249
256
  render: () => (
250
257
  <EditorStory
251
258
  text={str('# Search', text)}