@dxos/react-ui-editor 0.8.3 → 0.8.4-main.1da679c

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 (269) hide show
  1. package/dist/lib/browser/chunk-22UMM3QJ.mjs +22 -0
  2. package/dist/lib/browser/chunk-22UMM3QJ.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +2502 -1384
  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 +72 -2
  7. package/dist/lib/browser/testing/index.mjs.map +4 -4
  8. package/dist/lib/browser/types/index.mjs +13 -0
  9. package/dist/lib/browser/types/index.mjs.map +7 -0
  10. package/dist/lib/node-esm/chunk-YXYQPV6R.mjs +24 -0
  11. package/dist/lib/node-esm/chunk-YXYQPV6R.mjs.map +7 -0
  12. package/dist/lib/node-esm/index.mjs +2504 -1387
  13. package/dist/lib/node-esm/index.mjs.map +4 -4
  14. package/dist/lib/node-esm/meta.json +1 -1
  15. package/dist/lib/node-esm/testing/index.mjs +72 -2
  16. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  17. package/dist/lib/node-esm/types/index.mjs +14 -0
  18. package/dist/lib/node-esm/types/index.mjs.map +7 -0
  19. package/dist/types/src/components/{Popover → CommandMenu}/CommandMenu.d.ts +10 -6
  20. package/dist/types/src/components/CommandMenu/CommandMenu.d.ts.map +1 -0
  21. package/dist/types/src/components/CommandMenu/index.d.ts +2 -0
  22. package/dist/types/src/components/CommandMenu/index.d.ts.map +1 -0
  23. package/dist/types/src/components/Editor/Editor.d.ts +19 -0
  24. package/dist/types/src/components/Editor/Editor.d.ts.map +1 -0
  25. package/dist/types/src/components/Editor/index.d.ts +2 -0
  26. package/dist/types/src/components/Editor/index.d.ts.map +1 -0
  27. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
  28. package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
  29. package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
  30. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
  31. package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -1
  32. package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -1
  33. package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -1
  34. package/dist/types/src/components/EditorToolbar/util.d.ts +6 -5
  35. package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -1
  36. package/dist/types/src/components/EditorToolbar/view-mode.d.ts +1 -1
  37. package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -1
  38. package/dist/types/src/components/index.d.ts +2 -1
  39. package/dist/types/src/components/index.d.ts.map +1 -1
  40. package/dist/types/src/defaults.d.ts.map +1 -1
  41. package/dist/types/src/extensions/autocomplete.d.ts +20 -7
  42. package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
  43. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  44. package/dist/types/src/extensions/automerge/automerge.stories.d.ts +36 -45
  45. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  46. package/dist/types/src/extensions/automerge/defs.d.ts +1 -1
  47. package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
  48. package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
  49. package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
  50. package/dist/types/src/extensions/autoscroll.d.ts +10 -0
  51. package/dist/types/src/extensions/autoscroll.d.ts.map +1 -0
  52. package/dist/types/src/extensions/blast.d.ts.map +1 -1
  53. package/dist/types/src/extensions/command/action.d.ts +1 -1
  54. package/dist/types/src/extensions/command/action.d.ts.map +1 -1
  55. package/dist/types/src/extensions/command/command-menu.d.ts +1 -1
  56. package/dist/types/src/extensions/command/command-menu.d.ts.map +1 -1
  57. package/dist/types/src/extensions/command/command.d.ts.map +1 -1
  58. package/dist/types/src/extensions/command/floating-menu.d.ts.map +1 -1
  59. package/dist/types/src/extensions/command/hint.d.ts +2 -7
  60. package/dist/types/src/extensions/command/hint.d.ts.map +1 -1
  61. package/dist/types/src/extensions/command/index.d.ts +1 -1
  62. package/dist/types/src/extensions/command/index.d.ts.map +1 -1
  63. package/dist/types/src/extensions/command/state.d.ts +1 -1
  64. package/dist/types/src/extensions/command/state.d.ts.map +1 -1
  65. package/dist/types/src/extensions/command/typeahead.d.ts +7 -2
  66. package/dist/types/src/extensions/command/typeahead.d.ts.map +1 -1
  67. package/dist/types/src/extensions/command/useCommandMenu.d.ts +3 -4
  68. package/dist/types/src/extensions/command/useCommandMenu.d.ts.map +1 -1
  69. package/dist/types/src/extensions/comments.d.ts +1 -1
  70. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  71. package/dist/types/src/extensions/dnd.d.ts.map +1 -1
  72. package/dist/types/src/extensions/factories.d.ts +15 -1
  73. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  74. package/dist/types/src/extensions/index.d.ts +2 -0
  75. package/dist/types/src/extensions/index.d.ts.map +1 -1
  76. package/dist/types/src/extensions/markdown/action.d.ts.map +1 -1
  77. package/dist/types/src/extensions/markdown/bundle.d.ts +8 -2
  78. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
  79. package/dist/types/src/extensions/markdown/changes.d.ts +1 -1
  80. package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -1
  81. package/dist/types/src/extensions/markdown/decorate.d.ts +9 -1
  82. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  83. package/dist/types/src/extensions/markdown/formatting.d.ts +1 -1
  84. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  85. package/dist/types/src/extensions/markdown/formatting.test.d.ts.map +1 -1
  86. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  87. package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
  88. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  89. package/dist/types/src/extensions/modes.d.ts +0 -7
  90. package/dist/types/src/extensions/modes.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 +71 -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.map +1 -1
  111. package/dist/types/src/index.d.ts +1 -1
  112. package/dist/types/src/index.d.ts.map +1 -1
  113. package/dist/types/src/stories/Command.stories.d.ts +12 -4
  114. package/dist/types/src/stories/Command.stories.d.ts.map +1 -1
  115. package/dist/types/src/stories/CommandMenu.stories.d.ts +11 -4
  116. package/dist/types/src/stories/CommandMenu.stories.d.ts.map +1 -1
  117. package/dist/types/src/stories/Comments.stories.d.ts +21 -9
  118. package/dist/types/src/stories/Comments.stories.d.ts.map +1 -1
  119. package/dist/types/src/stories/EditorToolbar.stories.d.ts +40 -3
  120. package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -1
  121. package/dist/types/src/stories/Experimental.stories.d.ts +22 -12
  122. package/dist/types/src/stories/Experimental.stories.d.ts.map +1 -1
  123. package/dist/types/src/stories/Markdown.stories.d.ts +32 -42
  124. package/dist/types/src/stories/Markdown.stories.d.ts.map +1 -1
  125. package/dist/types/src/stories/Outliner.stories.d.ts +15 -20
  126. package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -1
  127. package/dist/types/src/stories/Preview.stories.d.ts +21 -6
  128. package/dist/types/src/stories/Preview.stories.d.ts.map +1 -1
  129. package/dist/types/src/stories/Tags.stories.d.ts +17 -0
  130. package/dist/types/src/stories/Tags.stories.d.ts.map +1 -0
  131. package/dist/types/src/stories/TextEditor.stories.d.ts +38 -51
  132. package/dist/types/src/stories/TextEditor.stories.d.ts.map +1 -1
  133. package/dist/types/src/stories/components/EditorStory.d.ts +3 -6
  134. package/dist/types/src/stories/components/EditorStory.d.ts.map +1 -1
  135. package/dist/types/src/styles/theme.d.ts.map +1 -1
  136. package/dist/types/src/testing/PreviewPopover.d.ts +20 -0
  137. package/dist/types/src/testing/PreviewPopover.d.ts.map +1 -0
  138. package/dist/types/src/testing/index.d.ts +1 -0
  139. package/dist/types/src/testing/index.d.ts.map +1 -1
  140. package/dist/types/src/testing/util.d.ts +1 -0
  141. package/dist/types/src/testing/util.d.ts.map +1 -1
  142. package/dist/types/src/translations.d.ts +28 -29
  143. package/dist/types/src/translations.d.ts.map +1 -1
  144. package/dist/types/src/types/index.d.ts +2 -0
  145. package/dist/types/src/types/index.d.ts.map +1 -0
  146. package/dist/types/src/types/types.d.ts +21 -0
  147. package/dist/types/src/types/types.d.ts.map +1 -0
  148. package/dist/types/src/util/cursor.d.ts.map +1 -1
  149. package/dist/types/src/util/debug.d.ts +1 -1
  150. package/dist/types/src/util/debug.d.ts.map +1 -1
  151. package/dist/types/src/util/decorations.d.ts +4 -0
  152. package/dist/types/src/util/decorations.d.ts.map +1 -0
  153. package/dist/types/src/util/dom.d.ts +2 -12
  154. package/dist/types/src/util/dom.d.ts.map +1 -1
  155. package/dist/types/src/util/domino.d.ts +18 -0
  156. package/dist/types/src/util/domino.d.ts.map +1 -0
  157. package/dist/types/src/util/index.d.ts +2 -0
  158. package/dist/types/src/util/index.d.ts.map +1 -1
  159. package/dist/types/src/util/react.d.ts +1 -1
  160. package/dist/types/src/util/react.d.ts.map +1 -1
  161. package/dist/types/tsconfig.tsbuildinfo +1 -1
  162. package/package.json +65 -55
  163. package/src/components/{Popover → CommandMenu}/CommandMenu.tsx +93 -26
  164. package/src/components/{Popover → CommandMenu}/index.ts +0 -2
  165. package/src/components/Editor/Editor.tsx +39 -0
  166. package/src/components/Editor/index.ts +5 -0
  167. package/src/components/EditorToolbar/EditorToolbar.tsx +40 -30
  168. package/src/components/EditorToolbar/blocks.ts +22 -25
  169. package/src/components/EditorToolbar/formatting.ts +22 -25
  170. package/src/components/EditorToolbar/headings.ts +10 -5
  171. package/src/components/EditorToolbar/image.ts +8 -4
  172. package/src/components/EditorToolbar/lists.ts +16 -19
  173. package/src/components/EditorToolbar/search.ts +8 -4
  174. package/src/components/EditorToolbar/util.ts +21 -9
  175. package/src/components/EditorToolbar/view-mode.ts +12 -7
  176. package/src/components/index.ts +2 -1
  177. package/src/defaults.ts +5 -2
  178. package/src/extensions/autocomplete.ts +204 -54
  179. package/src/extensions/automerge/automerge.stories.tsx +26 -17
  180. package/src/extensions/automerge/automerge.ts +4 -3
  181. package/src/extensions/automerge/defs.ts +1 -1
  182. package/src/extensions/automerge/sync.ts +1 -1
  183. package/src/extensions/automerge/update-automerge.ts +1 -1
  184. package/src/extensions/autoscroll.ts +157 -0
  185. package/src/extensions/awareness/awareness.ts +2 -2
  186. package/src/extensions/blast.ts +3 -16
  187. package/src/extensions/command/action.ts +1 -2
  188. package/src/extensions/command/command-menu.ts +7 -6
  189. package/src/extensions/command/command.ts +3 -3
  190. package/src/extensions/command/floating-menu.ts +10 -15
  191. package/src/extensions/command/hint.ts +2 -1
  192. package/src/extensions/command/index.ts +1 -1
  193. package/src/extensions/command/placeholder.ts +1 -1
  194. package/src/extensions/command/state.ts +4 -3
  195. package/src/extensions/command/typeahead.ts +28 -15
  196. package/src/extensions/command/useCommandMenu.ts +6 -9
  197. package/src/extensions/comments.ts +18 -13
  198. package/src/extensions/dnd.ts +1 -1
  199. package/src/extensions/factories.ts +22 -15
  200. package/src/extensions/folding.tsx +2 -2
  201. package/src/extensions/index.ts +2 -0
  202. package/src/extensions/markdown/action.ts +2 -1
  203. package/src/extensions/markdown/bundle.ts +25 -3
  204. package/src/extensions/markdown/changes.ts +1 -1
  205. package/src/extensions/markdown/decorate.ts +23 -14
  206. package/src/extensions/markdown/formatting.test.ts +7 -7
  207. package/src/extensions/markdown/formatting.ts +16 -14
  208. package/src/extensions/markdown/highlight.ts +1 -1
  209. package/src/extensions/markdown/image.ts +3 -4
  210. package/src/extensions/markdown/link.ts +3 -0
  211. package/src/extensions/markdown/table.ts +7 -1
  212. package/src/extensions/mention.ts +1 -1
  213. package/src/extensions/modes.ts +0 -9
  214. package/src/extensions/outliner/outliner.test.ts +3 -2
  215. package/src/extensions/outliner/outliner.ts +6 -5
  216. package/src/extensions/outliner/selection.ts +1 -1
  217. package/src/extensions/outliner/tree.test.ts +2 -1
  218. package/src/extensions/outliner/tree.ts +2 -2
  219. package/src/extensions/preview/preview.ts +59 -62
  220. package/src/extensions/tags/extended-markdown.test.ts +261 -0
  221. package/src/extensions/tags/extended-markdown.ts +78 -0
  222. package/src/extensions/tags/index.ts +7 -0
  223. package/src/extensions/tags/streamer.ts +244 -0
  224. package/src/extensions/tags/xml-tags.ts +335 -0
  225. package/src/extensions/tags/xml-util.ts +94 -0
  226. package/src/hooks/useTextEditor.ts +3 -15
  227. package/src/index.ts +1 -1
  228. package/src/stories/Command.stories.tsx +24 -31
  229. package/src/stories/CommandMenu.stories.tsx +29 -30
  230. package/src/stories/Comments.stories.tsx +10 -6
  231. package/src/stories/EditorToolbar.stories.tsx +10 -11
  232. package/src/stories/Experimental.stories.tsx +12 -8
  233. package/src/stories/Markdown.stories.tsx +21 -17
  234. package/src/stories/Outliner.stories.tsx +42 -30
  235. package/src/stories/Preview.stories.tsx +34 -33
  236. package/src/stories/Tags.stories.tsx +81 -0
  237. package/src/stories/TextEditor.stories.tsx +41 -35
  238. package/src/stories/components/EditorStory.tsx +9 -10
  239. package/src/styles/theme.ts +11 -10
  240. package/src/testing/PreviewPopover.tsx +78 -0
  241. package/src/testing/index.ts +1 -0
  242. package/src/testing/util.ts +2 -0
  243. package/src/translations.ts +5 -3
  244. package/src/types/index.ts +5 -0
  245. package/src/types/types.ts +32 -0
  246. package/src/util/cursor.ts +2 -1
  247. package/src/util/debug.ts +2 -2
  248. package/src/util/decorations.ts +21 -0
  249. package/src/util/dom.ts +5 -27
  250. package/src/util/domino.ts +51 -0
  251. package/src/util/index.ts +2 -0
  252. package/src/util/react.tsx +1 -1
  253. package/dist/lib/node/index.cjs +0 -7754
  254. package/dist/lib/node/index.cjs.map +0 -7
  255. package/dist/lib/node/meta.json +0 -1
  256. package/dist/lib/node/testing/index.cjs +0 -29
  257. package/dist/lib/node/testing/index.cjs.map +0 -7
  258. package/dist/types/src/components/Popover/CommandMenu.d.ts.map +0 -1
  259. package/dist/types/src/components/Popover/RefDropdownMenu.d.ts +0 -21
  260. package/dist/types/src/components/Popover/RefDropdownMenu.d.ts.map +0 -1
  261. package/dist/types/src/components/Popover/RefPopover.d.ts +0 -34
  262. package/dist/types/src/components/Popover/RefPopover.d.ts.map +0 -1
  263. package/dist/types/src/components/Popover/index.d.ts +0 -4
  264. package/dist/types/src/components/Popover/index.d.ts.map +0 -1
  265. package/dist/types/src/types.d.ts +0 -14
  266. package/dist/types/src/types.d.ts.map +0 -1
  267. package/src/components/Popover/RefDropdownMenu.tsx +0 -79
  268. package/src/components/Popover/RefPopover.tsx +0 -99
  269. package/src/types.ts +0 -23
package/src/index.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import translations from './translations';
5
+ import { translations } from './translations';
6
6
 
7
7
  export { type Extension, EditorState } from '@codemirror/state';
8
8
  export { EditorView, keymap } from '@codemirror/view';
@@ -4,19 +4,20 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
- import React, { useState, type KeyboardEvent } from 'react';
7
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
+ import React, { type KeyboardEvent, useState } from 'react';
8
9
 
9
- import { Button, Icon, Input, DropdownMenu } from '@dxos/react-ui';
10
+ import { Button, Icon, Input } from '@dxos/react-ui';
10
11
  import { mx } from '@dxos/react-ui-theme';
11
- import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
12
+ import { withLayout, withTheme } from '@dxos/storybook-utils';
12
13
 
13
- import { EditorStory } from './components';
14
- import { RefDropdownMenu } from '../components';
15
14
  import { editorWidth } from '../defaults';
16
- import { command, type Action, floatingMenu } from '../extensions';
15
+ import { type Action, command, floatingMenu } from '../extensions';
17
16
  import { str } from '../testing';
18
17
  import { createRenderer } from '../util';
19
18
 
19
+ import { EditorStory } from './components';
20
+
20
21
  const CommandDialog = ({ onAction }: { onAction: (action?: Action) => void }) => {
21
22
  const [text, setText] = useState('');
22
23
 
@@ -40,10 +41,10 @@ const CommandDialog = ({ onAction }: { onAction: (action?: Action) => void }) =>
40
41
  };
41
42
 
42
43
  return (
43
- <div className='flex w-full justify-center'>
44
+ <div className='flex is-full justify-center'>
44
45
  <div
45
46
  className={mx(
46
- 'flex w-full p-2 gap-2 items-center bg-modalSurface border border-separator rounded-md',
47
+ 'flex is-full p-2 gap-2 items-center bg-modalSurface border border-separator rounded-md',
47
48
  editorWidth,
48
49
  )}
49
50
  >
@@ -64,34 +65,26 @@ const CommandDialog = ({ onAction }: { onAction: (action?: Action) => void }) =>
64
65
  );
65
66
  };
66
67
 
67
- const meta: Meta<typeof EditorStory> = {
68
+ const meta = {
68
69
  title: 'ui/react-ui-editor/Command',
69
70
  decorators: [withTheme, withLayout({ fullscreen: true })],
70
71
  render: () => (
71
- <RefDropdownMenu.Provider>
72
- <EditorStory
73
- text={str('# Command', '', '', '')}
74
- extensions={[
75
- floatingMenu(),
76
- command({
77
- renderDialog: createRenderer(CommandDialog),
78
- onHint: () => "Press '/' for commands",
79
- }),
80
- ]}
81
- />
82
- <DropdownMenu.Portal>
83
- <DropdownMenu.Content>
84
- <DropdownMenu.Viewport>
85
- <DropdownMenu.Item onClick={() => console.log('!')}>Test</DropdownMenu.Item>
86
- </DropdownMenu.Viewport>
87
- <DropdownMenu.Arrow />
88
- </DropdownMenu.Content>
89
- </DropdownMenu.Portal>
90
- </RefDropdownMenu.Provider>
72
+ <EditorStory
73
+ text={str('# Command', '', '', '')}
74
+ extensions={[
75
+ floatingMenu(),
76
+ command({
77
+ renderDialog: createRenderer(CommandDialog),
78
+ onHint: () => "Press '/' for commands",
79
+ }),
80
+ ]}
81
+ />
91
82
  ),
92
83
  parameters: { layout: 'fullscreen' },
93
- };
84
+ } satisfies Meta<typeof Button>;
94
85
 
95
86
  export default meta;
96
87
 
97
- export const Default = {};
88
+ type Story = StoryObj<typeof meta>;
89
+
90
+ export const Default: Story = {};
@@ -5,30 +5,30 @@
5
5
  import '@dxos-theme';
6
6
 
7
7
  import { type EditorView } from '@codemirror/view';
8
- import { type StoryObj } from '@storybook/react';
8
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
9
9
  import React, { useCallback, useRef } from 'react';
10
10
 
11
11
  import { Obj, Query } from '@dxos/echo';
12
12
  import { faker } from '@dxos/random';
13
13
  import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
14
- import { createObjectFactory, Testing, type ValueGenerator } from '@dxos/schema/testing';
15
- import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
14
+ import { Testing, type ValueGenerator, createObjectFactory } from '@dxos/schema/testing';
15
+ import { withLayout, withTheme } from '@dxos/storybook-utils';
16
16
 
17
- import { EditorStory, names } from './components';
18
17
  import {
19
- CommandMenu,
20
18
  type CommandMenuGroup,
21
19
  type CommandMenuItem,
22
- RefPopover,
20
+ CommandMenuProvider,
23
21
  coreSlashCommands,
24
22
  filterItems,
25
23
  insertAtCursor,
26
24
  insertAtLineStart,
27
25
  linkSlashCommands,
28
26
  } from '../components';
29
- import { useCommandMenu, type UseCommandMenuOptions } from '../extensions';
27
+ import { type UseCommandMenuOptions, useCommandMenu } from '../extensions';
30
28
  import { str } from '../testing';
31
- import { createElement } from '../util';
29
+ import { Domino } from '../util';
30
+
31
+ import { EditorStory, names } from './components';
32
32
 
33
33
  const generator: ValueGenerator = faker as any;
34
34
 
@@ -36,13 +36,12 @@ type StoryProps = Omit<UseCommandMenuOptions, 'viewRef'> & { text: string };
36
36
 
37
37
  const DefaultStory = ({ text, ...options }: StoryProps) => {
38
38
  const viewRef = useRef<EditorView>();
39
- const { commandMenu, groupsRef, currentItem, onSelect, ...props } = useCommandMenu({ viewRef, ...options });
39
+ const { commandMenu, groupsRef, ...commandMenuProps } = useCommandMenu({ viewRef, ...options });
40
40
 
41
41
  return (
42
- <RefPopover modal={false} {...props}>
42
+ <CommandMenuProvider groups={groupsRef.current} {...commandMenuProps}>
43
43
  <EditorStory ref={viewRef} text={text} placeholder={''} extensions={commandMenu} />
44
- <CommandMenu groups={groupsRef.current} currentItem={currentItem} onSelect={onSelect} />
45
- </RefPopover>
44
+ </CommandMenuProvider>
46
45
  );
47
46
  };
48
47
 
@@ -63,18 +62,18 @@ const groups: CommandMenuGroup[] = [
63
62
  },
64
63
  ];
65
64
 
66
- const meta: Meta<StoryProps> = {
65
+ const meta = {
67
66
  title: 'ui/react-ui-editor/CommandMenu',
67
+ render: DefaultStory,
68
68
  decorators: [withTheme, withLayout({ fullscreen: true })],
69
- render: (args) => <DefaultStory {...args} />,
70
69
  parameters: {
71
70
  layout: 'fullscreen',
72
71
  },
73
- };
72
+ } satisfies Meta<typeof DefaultStory>;
74
73
 
75
74
  export default meta;
76
75
 
77
- type Story = StoryObj<StoryProps>;
76
+ type Story = StoryObj<typeof meta>;
78
77
 
79
78
  // TODO(burdon): Not working.
80
79
  export const Slash: Story = {
@@ -82,13 +81,12 @@ export const Slash: Story = {
82
81
  text: str('# Slash', '', names.join(' '), ''),
83
82
  trigger: '/',
84
83
  placeholder: {
85
- content: () => {
86
- return createElement('div', undefined, [
87
- createElement('span', { text: 'Press' }),
88
- createElement('span', { className: 'border border-separator rounded-sm mx-1 px-1', text: '/' }),
89
- createElement('span', { text: 'for commands' }),
90
- ]);
91
- },
84
+ content: () =>
85
+ Domino.of('div')
86
+ .child(Domino.of('span').text('Press'))
87
+ .child(Domino.of('span').text('/').classNames('border border-separator rounded-sm mx-1 px-1'))
88
+ .child(Domino.of('span').text('for commands'))
89
+ .build(),
92
90
  },
93
91
  getMenu: (text) => {
94
92
  return filterItems(groups, (item) =>
@@ -99,7 +97,7 @@ export const Slash: Story = {
99
97
  };
100
98
 
101
99
  export const Link: Story = {
102
- render: (args) => {
100
+ render: (args: StoryProps) => {
103
101
  const { space } = useClientProvider();
104
102
  const getMenu = useCallback(
105
103
  async (trigger: string, query?: string): Promise<CommandMenuGroup[]> => {
@@ -113,7 +111,7 @@ export const Link: Story = {
113
111
  return [];
114
112
  }
115
113
 
116
- const name = query?.startsWith('@') ? query.slice(1).toLowerCase() : query?.toLowerCase() ?? '';
114
+ const name = query?.startsWith('@') ? query.slice(1).toLowerCase() : (query?.toLowerCase() ?? '');
117
115
  const result = await space?.db.query(Query.type(Testing.Contact)).run();
118
116
  const items = result.objects
119
117
  .filter((object) => object.name.toLowerCase().includes(name))
@@ -123,7 +121,7 @@ export const Link: Story = {
123
121
  label: object.name,
124
122
  icon: 'ph--user--regular',
125
123
  onSelect: (view, head) => {
126
- const link = `[${object.name}][${Obj.getDXN(object)}]`;
124
+ const link = `[${object.name}](${Obj.getDXN(object)})`;
127
125
  if (query?.startsWith('@')) {
128
126
  insertAtLineStart(view, head, `!${link}\n`);
129
127
  } else {
@@ -139,10 +137,6 @@ export const Link: Story = {
139
137
 
140
138
  return <DefaultStory {...args} getMenu={getMenu} />;
141
139
  },
142
- args: {
143
- text: str('# Link', '', names.join(' '), ''),
144
- trigger: ['/', '@'],
145
- },
146
140
  decorators: [
147
141
  withClientProvider({
148
142
  createSpace: true,
@@ -156,4 +150,9 @@ export const Link: Story = {
156
150
  },
157
151
  }),
158
152
  ],
153
+ args: {
154
+ text: str('# Link', '', names.join(' '), ''),
155
+ trigger: ['/', '@'],
156
+ getMenu: () => [],
157
+ },
159
158
  };
@@ -5,33 +5,37 @@
5
5
  import '@dxos-theme';
6
6
 
7
7
  import { effect, useSignal } from '@preact/signals-react';
8
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
9
  import React, { type FC } from 'react';
9
10
 
10
11
  import { keySymbols, parseShortcut } from '@dxos/keyboard';
11
12
  import { PublicKey } from '@dxos/keys';
12
13
  import { log } from '@dxos/log';
13
- import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
14
+ import { withLayout, withTheme } from '@dxos/storybook-utils';
14
15
 
15
- import { EditorStory, content, longText } from './components';
16
16
  import { annotations, comments, createExternalCommentSync } from '../extensions';
17
17
  import { str } from '../testing';
18
18
  import { type Comment } from '../types';
19
19
  import { createRenderer } from '../util';
20
20
 
21
- const meta: Meta<typeof EditorStory> = {
21
+ import { EditorStory, content, longText } from './components';
22
+
23
+ const meta = {
22
24
  title: 'ui/react-ui-editor/Comments',
23
25
  component: EditorStory,
24
26
  decorators: [withTheme, withLayout({ fullscreen: true })],
25
27
  parameters: { layout: 'fullscreen' },
26
- };
28
+ } satisfies Meta<typeof EditorStory>;
27
29
 
28
30
  export default meta;
29
31
 
32
+ type Story = StoryObj<typeof meta>;
33
+
30
34
  //
31
35
  // Comments
32
36
  //
33
37
 
34
- export const Comments = {
38
+ export const Comments: Story = {
35
39
  render: () => {
36
40
  const _comments = useSignal<Comment[]>([]);
37
41
  return (
@@ -91,7 +95,7 @@ const CommentTooltip: FC<{ shortcut: string }> = ({ shortcut }) => {
91
95
  // Annotations
92
96
  //
93
97
 
94
- export const Annotations = {
98
+ export const Annotations: Story = {
95
99
  render: () => (
96
100
  <EditorStory text={str('# Annotations', '', longText)} extensions={[annotations({ match: /volup/gi })]} />
97
101
  ),
@@ -4,29 +4,28 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
- import { type StoryObj } from '@storybook/react';
7
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
8
  import React, { useCallback, useState } from 'react';
9
9
 
10
10
  import { invariant } from '@dxos/invariant';
11
11
  import { useThemeContext } from '@dxos/react-ui';
12
12
  import { attentionSurface, mx } from '@dxos/react-ui-theme';
13
- import { type Meta, withLayout, withTheme } from '@dxos/storybook-utils';
13
+ import { withLayout, withTheme } from '@dxos/storybook-utils';
14
14
 
15
15
  import { EditorToolbar, useEditorToolbarState } from '../components';
16
16
  import { editorWidth } from '../defaults';
17
17
  import {
18
- type EditorInputMode,
19
- type EditorViewMode,
20
18
  InputModeExtensions,
21
- createMarkdownExtensions,
22
19
  createBasicExtensions,
20
+ createMarkdownExtensions,
23
21
  createThemeExtensions,
24
22
  decorateMarkdown,
25
23
  formattingKeymap,
26
24
  useFormattingState,
27
25
  } from '../extensions';
28
- import { useTextEditor, type UseTextEditorProps } from '../hooks';
29
- import translations from '../translations';
26
+ import { type UseTextEditorProps, useTextEditor } from '../hooks';
27
+ import { translations } from '../translations';
28
+ import { type EditorInputMode, type EditorViewMode } from '../types';
30
29
 
31
30
  type StoryProps = { placeholder?: string } & UseTextEditorProps;
32
31
 
@@ -44,8 +43,8 @@ const DefaultStory = ({ autoFocus, initialValue, placeholder }: StoryProps) => {
44
43
  moveToEndOfLine: true,
45
44
  extensions: [
46
45
  editorInputMode ? InputModeExtensions[editorInputMode] : [],
47
- createBasicExtensions({ placeholder, lineWrapping: true, readOnly: viewMode === 'readonly' }),
48
- createMarkdownExtensions({ themeMode }),
46
+ createBasicExtensions({ placeholder, lineWrapping: true, readOnly: viewMode === 'readonly', search: true }),
47
+ createMarkdownExtensions(),
49
48
  createThemeExtensions({ themeMode, syntaxHighlighting: true }),
50
49
  viewMode === 'source' ? [] : decorateMarkdown(),
51
50
  formattingKeymap(),
@@ -76,12 +75,12 @@ const DefaultStory = ({ autoFocus, initialValue, placeholder }: StoryProps) => {
76
75
  );
77
76
  };
78
77
 
79
- const meta: Meta<StoryProps> = {
78
+ const meta = {
80
79
  title: 'ui/react-ui-editor/EditorToolbar',
81
80
  render: DefaultStory,
82
81
  decorators: [withTheme, withLayout({ fullscreen: true })],
83
82
  parameters: { translations, layout: 'fullscreen' },
84
- };
83
+ } satisfies Meta<typeof DefaultStory>;
85
84
 
86
85
  export default meta;
87
86
 
@@ -4,33 +4,37 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
7
8
  import defaultsDeep from 'lodash.defaultsdeep';
8
9
  import React from 'react';
9
10
 
10
11
  import { log } from '@dxos/log';
11
12
  import { faker } from '@dxos/random';
12
- import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
13
+ import { withLayout, withTheme } from '@dxos/storybook-utils';
13
14
 
14
- import { EditorStory, content } from './components';
15
- import { typewriter, blast, defaultOptions, dropFile } from '../extensions';
15
+ import { blast, defaultOptions, dropFile, typewriter } from '../extensions';
16
16
  import { str } from '../testing';
17
17
 
18
- const meta: Meta<typeof EditorStory> = {
18
+ import { EditorStory, content } from './components';
19
+
20
+ const meta = {
19
21
  title: 'ui/react-ui-editor/Experimental',
20
22
  component: EditorStory,
21
23
  decorators: [withTheme, withLayout({ fullscreen: true })],
22
24
  parameters: { layout: 'fullscreen' },
23
- };
25
+ } satisfies Meta<typeof EditorStory>;
24
26
 
25
27
  export default meta;
26
28
 
29
+ type Story = StoryObj<typeof meta>;
30
+
27
31
  //
28
32
  // Typewriter
29
33
  //
30
34
 
31
35
  const typewriterItems = localStorage.getItem('dxos.org/plugin/markdown/typewriter')?.split(',');
32
36
 
33
- export const Typewriter = {
37
+ export const Typewriter: Story = {
34
38
  render: () => (
35
39
  <EditorStory
36
40
  text={str('# Typewriter', '', content.paragraphs, content.footer)}
@@ -43,7 +47,7 @@ export const Typewriter = {
43
47
  // Blast
44
48
  //
45
49
 
46
- export const Blast = {
50
+ export const Blast: Story = {
47
51
  render: () => (
48
52
  <EditorStory
49
53
  text={str('# Blast', '', content.paragraphs, content.codeblocks, content.paragraphs)}
@@ -70,7 +74,7 @@ export const Blast = {
70
74
  // DND
71
75
  //
72
76
 
73
- export const DND = {
77
+ export const DND: Story = {
74
78
  render: () => (
75
79
  <EditorStory
76
80
  text={str('# DND', '')}
@@ -5,32 +5,36 @@
5
5
  import '@dxos-theme';
6
6
 
7
7
  import { markdown } from '@codemirror/lang-markdown';
8
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
9
  import React from 'react';
9
10
 
10
- import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
11
+ import { withLayout, withTheme } from '@dxos/storybook-utils';
11
12
 
12
- import { EditorStory, content, defaultExtensions, headings, renderLinkTooltip, text } from './components';
13
13
  import { decorateMarkdown, image, linkTooltip, table } from '../extensions';
14
14
  import { str } from '../testing';
15
15
 
16
- const meta: Meta<typeof EditorStory> = {
16
+ import { EditorStory, content, defaultExtensions, headings, renderLinkTooltip, text } from './components';
17
+
18
+ const meta = {
17
19
  title: 'ui/react-ui-editor/Markdown',
18
20
  component: EditorStory,
19
21
  decorators: [withTheme, withLayout({ fullscreen: true })],
20
22
  parameters: { layout: 'fullscreen' },
21
- };
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)}
@@ -5,38 +5,57 @@
5
5
  import '@dxos-theme';
6
6
 
7
7
  import { type EditorView } from '@codemirror/view';
8
- import React, { useRef } from 'react';
8
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
9
+ import React, { useMemo, useRef } from 'react';
9
10
 
10
- import { DropdownMenu } from '@dxos/react-ui';
11
11
  import { withAttention } from '@dxos/react-ui-attention/testing';
12
- import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
12
+ import { withLayout, withTheme } from '@dxos/storybook-utils';
13
13
 
14
- import { EditorStory } from './components';
15
- import { RefDropdownMenu } from '../components';
16
- import { outliner, listItemToString, treeFacet, deleteItem, hashtag } from '../extensions';
14
+ import { type CommandMenuGroup, type CommandMenuItem, CommandMenuProvider } from '../components';
15
+ import { deleteItem, hashtag, listItemToString, outliner, treeFacet } from '../extensions';
17
16
  import { str } from '../testing';
18
17
 
18
+ import { EditorStory } from './components';
19
+
19
20
  type StoryProps = {
20
- text: string;
21
+ text?: string;
21
22
  };
22
23
 
23
24
  const DefaultStory = ({ text }: StoryProps) => {
24
25
  const viewRef = useRef<EditorView>(null);
25
26
 
26
- const handleDelete = () => {
27
- if (viewRef.current) {
28
- deleteItem(viewRef.current);
29
- }
30
- };
27
+ const commandGroups: CommandMenuGroup[] = useMemo(
28
+ () => [
29
+ {
30
+ id: 'outliner-actions',
31
+ items: [
32
+ {
33
+ id: 'delete-row',
34
+ label: 'Delete',
35
+ onSelect: (view: EditorView) => {
36
+ deleteItem(view);
37
+ },
38
+ },
39
+ ],
40
+ },
41
+ ],
42
+ [],
43
+ );
31
44
 
32
45
  return (
33
- <RefDropdownMenu.Provider>
46
+ <CommandMenuProvider
47
+ groups={commandGroups}
48
+ onSelect={(item: CommandMenuItem) => {
49
+ if (viewRef.current && item.onSelect) {
50
+ return item.onSelect(viewRef.current, viewRef.current.state.selection.main.head);
51
+ }
52
+ }}
53
+ >
34
54
  <EditorStory
35
55
  ref={viewRef}
36
56
  text={text}
37
57
  extensions={[outliner(), hashtag()]}
38
58
  placeholder=''
39
- slots={{}}
40
59
  debug='raw+tree'
41
60
  debugCustom={(view) => {
42
61
  const tree = view.state.facet(treeFacet);
@@ -45,33 +64,26 @@ const DefaultStory = ({ text }: StoryProps) => {
45
64
  return <pre className='p-1 overflow-auto text-xs text-green-800 dark:text-green-200'>{lines.join('\n')}</pre>;
46
65
  }}
47
66
  />
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>
67
+ </CommandMenuProvider>
58
68
  );
59
69
  };
60
70
 
61
- const meta: Meta<StoryProps> = {
71
+ const meta = {
62
72
  title: 'ui/react-ui-editor/Outliner',
63
73
  render: DefaultStory,
64
74
  decorators: [withAttention, withTheme, withLayout({ fullscreen: true })],
65
75
  parameters: { layout: 'fullscreen' },
66
- };
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
  //