@dxos/react-ui-editor 0.8.2-staging.7ac8446 → 0.8.2

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 (268) hide show
  1. package/dist/lib/browser/index.mjs +4152 -2852
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/browser/testing/index.mjs +6 -0
  5. package/dist/lib/browser/testing/index.mjs.map +7 -0
  6. package/dist/lib/node/index.cjs +3318 -2009
  7. package/dist/lib/node/index.cjs.map +4 -4
  8. package/dist/lib/node/meta.json +1 -1
  9. package/dist/lib/node/testing/index.cjs +29 -0
  10. package/dist/lib/node/testing/index.cjs.map +7 -0
  11. package/dist/lib/node-esm/index.mjs +4152 -2852
  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 +8 -0
  15. package/dist/lib/node-esm/testing/index.mjs.map +7 -0
  16. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +1 -1
  17. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
  18. package/dist/types/src/components/EditorToolbar/blocks.d.ts +4 -3
  19. package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
  20. package/dist/types/src/components/EditorToolbar/formatting.d.ts +4 -3
  21. package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
  22. package/dist/types/src/components/EditorToolbar/headings.d.ts +4 -3
  23. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
  24. package/dist/types/src/components/EditorToolbar/{comment.d.ts → image.d.ts} +4 -5
  25. package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -0
  26. package/dist/types/src/components/EditorToolbar/index.d.ts +1 -1
  27. package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -1
  28. package/dist/types/src/components/EditorToolbar/lists.d.ts +4 -3
  29. package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -1
  30. package/dist/types/src/components/EditorToolbar/search.d.ts +17 -0
  31. package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -0
  32. package/dist/types/src/components/EditorToolbar/util.d.ts +17 -25
  33. package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -1
  34. package/dist/types/src/components/EditorToolbar/{viewMode.d.ts → view-mode.d.ts} +5 -4
  35. package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -0
  36. package/dist/types/src/components/Popover/RefDropdownMenu.d.ts +21 -0
  37. package/dist/types/src/components/Popover/RefDropdownMenu.d.ts.map +1 -0
  38. package/dist/types/src/components/Popover/RefPopover.d.ts +21 -0
  39. package/dist/types/src/components/Popover/RefPopover.d.ts.map +1 -0
  40. package/dist/types/src/components/Popover/index.d.ts +3 -0
  41. package/dist/types/src/components/Popover/index.d.ts.map +1 -0
  42. package/dist/types/src/components/index.d.ts +1 -0
  43. package/dist/types/src/components/index.d.ts.map +1 -1
  44. package/dist/types/src/defaults.d.ts +3 -5
  45. package/dist/types/src/defaults.d.ts.map +1 -1
  46. package/dist/types/src/extensions/annotations.d.ts +4 -1
  47. package/dist/types/src/extensions/annotations.d.ts.map +1 -1
  48. package/dist/types/src/extensions/autocomplete.d.ts +1 -2
  49. package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
  50. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  51. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  52. package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
  53. package/dist/types/src/extensions/automerge/defs.d.ts +1 -1
  54. package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
  55. package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
  56. package/dist/types/src/extensions/automerge/update-automerge.d.ts +1 -1
  57. package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
  58. package/dist/types/src/extensions/automerge/update-codemirror.d.ts +1 -1
  59. package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +1 -1
  60. package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -1
  61. package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -1
  62. package/dist/types/src/extensions/blast.d.ts.map +1 -1
  63. package/dist/types/src/extensions/command/action.d.ts +17 -0
  64. package/dist/types/src/extensions/command/action.d.ts.map +1 -0
  65. package/dist/types/src/extensions/command/command.d.ts +4 -10
  66. package/dist/types/src/extensions/command/command.d.ts.map +1 -1
  67. package/dist/types/src/extensions/command/hint.d.ts +18 -4
  68. package/dist/types/src/extensions/command/hint.d.ts.map +1 -1
  69. package/dist/types/src/extensions/command/index.d.ts +3 -0
  70. package/dist/types/src/extensions/command/index.d.ts.map +1 -1
  71. package/dist/types/src/extensions/command/menu.d.ts +6 -11
  72. package/dist/types/src/extensions/command/menu.d.ts.map +1 -1
  73. package/dist/types/src/extensions/command/state.d.ts +9 -11
  74. package/dist/types/src/extensions/command/state.d.ts.map +1 -1
  75. package/dist/types/src/extensions/command/typeahead.d.ts +17 -0
  76. package/dist/types/src/extensions/command/typeahead.d.ts.map +1 -0
  77. package/dist/types/src/extensions/comments.d.ts +9 -17
  78. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  79. package/dist/types/src/extensions/debug.d.ts.map +1 -1
  80. package/dist/types/src/extensions/dnd.d.ts.map +1 -1
  81. package/dist/types/src/extensions/factories.d.ts +4 -0
  82. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  83. package/dist/types/src/extensions/folding.d.ts.map +1 -1
  84. package/dist/types/src/extensions/index.d.ts +3 -0
  85. package/dist/types/src/extensions/index.d.ts.map +1 -1
  86. package/dist/types/src/extensions/json.d.ts +7 -0
  87. package/dist/types/src/extensions/json.d.ts.map +1 -0
  88. package/dist/types/src/extensions/listener.d.ts.map +1 -1
  89. package/dist/types/src/extensions/markdown/{editorAction.d.ts → action.d.ts} +1 -1
  90. package/dist/types/src/extensions/markdown/action.d.ts.map +1 -0
  91. package/dist/types/src/extensions/markdown/bundle.d.ts +2 -1
  92. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
  93. package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -1
  94. package/dist/types/src/extensions/markdown/debug.d.ts.map +1 -1
  95. package/dist/types/src/extensions/markdown/decorate.d.ts +5 -1
  96. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  97. package/dist/types/src/extensions/markdown/formatting.d.ts +3 -3
  98. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  99. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  100. package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
  101. package/dist/types/src/extensions/markdown/index.d.ts +1 -1
  102. package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
  103. package/dist/types/src/extensions/markdown/link.d.ts +4 -1
  104. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  105. package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
  106. package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
  107. package/dist/types/src/extensions/mention.d.ts.map +1 -1
  108. package/dist/types/src/extensions/modes.d.ts +5 -5
  109. package/dist/types/src/extensions/modes.d.ts.map +1 -1
  110. package/dist/types/src/extensions/outliner/commands.d.ts +10 -0
  111. package/dist/types/src/extensions/outliner/commands.d.ts.map +1 -0
  112. package/dist/types/src/extensions/outliner/editor.d.ts +5 -0
  113. package/dist/types/src/extensions/outliner/editor.d.ts.map +1 -0
  114. package/dist/types/src/extensions/outliner/editor.test.d.ts +2 -0
  115. package/dist/types/src/extensions/outliner/editor.test.d.ts.map +1 -0
  116. package/dist/types/src/extensions/outliner/index.d.ts +4 -0
  117. package/dist/types/src/extensions/outliner/index.d.ts.map +1 -0
  118. package/dist/types/src/extensions/outliner/outliner.d.ts +13 -0
  119. package/dist/types/src/extensions/outliner/outliner.d.ts.map +1 -0
  120. package/dist/types/src/extensions/outliner/outliner.test.d.ts +2 -0
  121. package/dist/types/src/extensions/outliner/outliner.test.d.ts.map +1 -0
  122. package/dist/types/src/extensions/outliner/selection.d.ts +12 -0
  123. package/dist/types/src/extensions/outliner/selection.d.ts.map +1 -0
  124. package/dist/types/src/extensions/outliner/tree.d.ts +79 -0
  125. package/dist/types/src/extensions/outliner/tree.d.ts.map +1 -0
  126. package/dist/types/src/extensions/outliner/tree.test.d.ts +2 -0
  127. package/dist/types/src/extensions/outliner/tree.test.d.ts.map +1 -0
  128. package/dist/types/src/extensions/preview/index.d.ts +2 -0
  129. package/dist/types/src/extensions/preview/index.d.ts.map +1 -0
  130. package/dist/types/src/extensions/preview/preview.d.ts +39 -0
  131. package/dist/types/src/extensions/preview/preview.d.ts.map +1 -0
  132. package/dist/types/src/extensions/selection.d.ts.map +1 -1
  133. package/dist/types/src/extensions/typewriter.d.ts.map +1 -1
  134. package/dist/types/src/hooks/index.d.ts +0 -1
  135. package/dist/types/src/hooks/index.d.ts.map +1 -1
  136. package/dist/types/src/hooks/useTextEditor.d.ts +2 -1
  137. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  138. package/dist/types/src/stories/Command.stories.d.ts +7 -0
  139. package/dist/types/src/stories/Command.stories.d.ts.map +1 -0
  140. package/dist/types/src/stories/Comments.stories.d.ts +13 -0
  141. package/dist/types/src/stories/Comments.stories.d.ts.map +1 -0
  142. package/dist/types/src/stories/EditorToolbar.stories.d.ts +12 -0
  143. package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -0
  144. package/dist/types/src/stories/Experimental.stories.d.ts +16 -0
  145. package/dist/types/src/stories/Experimental.stories.d.ts.map +1 -0
  146. package/dist/types/src/stories/Markdown.stories.d.ts +46 -0
  147. package/dist/types/src/stories/Markdown.stories.d.ts.map +1 -0
  148. package/dist/types/src/stories/Outliner.stories.d.ts +26 -0
  149. package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -0
  150. package/dist/types/src/stories/Preview.stories.d.ts +10 -0
  151. package/dist/types/src/stories/Preview.stories.d.ts.map +1 -0
  152. package/dist/types/src/stories/TextEditor.stories.d.ts +55 -0
  153. package/dist/types/src/stories/TextEditor.stories.d.ts.map +1 -0
  154. package/dist/types/src/stories/util.d.ts +53 -0
  155. package/dist/types/src/stories/util.d.ts.map +1 -0
  156. package/dist/types/src/styles/theme.d.ts.map +1 -1
  157. package/dist/types/src/styles/tokens.d.ts.map +1 -1
  158. package/dist/types/src/testing/index.d.ts +2 -0
  159. package/dist/types/src/testing/index.d.ts.map +1 -0
  160. package/dist/types/src/testing/util.d.ts +2 -0
  161. package/dist/types/src/testing/util.d.ts.map +1 -0
  162. package/dist/types/src/types.d.ts +5 -0
  163. package/dist/types/src/types.d.ts.map +1 -1
  164. package/dist/types/src/util/cursor.d.ts.map +1 -1
  165. package/dist/types/src/util/debug.d.ts.map +1 -1
  166. package/dist/types/src/util/dom.d.ts.map +1 -1
  167. package/dist/types/src/util/facet.d.ts.map +1 -1
  168. package/dist/types/src/util/react.d.ts +6 -1
  169. package/dist/types/src/util/react.d.ts.map +1 -1
  170. package/dist/types/tsconfig.tsbuildinfo +1 -1
  171. package/package.json +46 -30
  172. package/src/components/EditorToolbar/EditorToolbar.tsx +95 -72
  173. package/src/components/EditorToolbar/blocks.ts +27 -6
  174. package/src/components/EditorToolbar/formatting.ts +34 -7
  175. package/src/components/EditorToolbar/headings.ts +9 -8
  176. package/src/components/EditorToolbar/image.ts +16 -0
  177. package/src/components/EditorToolbar/index.ts +7 -1
  178. package/src/components/EditorToolbar/lists.ts +26 -7
  179. package/src/components/EditorToolbar/search.ts +19 -0
  180. package/src/components/EditorToolbar/util.ts +19 -20
  181. package/src/components/EditorToolbar/{viewMode.ts → view-mode.ts} +9 -8
  182. package/src/components/Popover/RefDropdownMenu.tsx +77 -0
  183. package/src/components/Popover/RefPopover.tsx +75 -0
  184. package/src/components/Popover/index.ts +6 -0
  185. package/src/components/index.ts +1 -0
  186. package/src/defaults.ts +12 -13
  187. package/src/extensions/annotations.ts +41 -64
  188. package/src/extensions/autocomplete.ts +5 -6
  189. package/src/extensions/automerge/automerge.stories.tsx +13 -24
  190. package/src/extensions/automerge/automerge.test.tsx +6 -5
  191. package/src/extensions/automerge/automerge.ts +2 -2
  192. package/src/extensions/automerge/defs.ts +1 -2
  193. package/src/extensions/automerge/sync.ts +7 -7
  194. package/src/extensions/automerge/update-automerge.ts +1 -1
  195. package/src/extensions/automerge/update-codemirror.ts +3 -4
  196. package/src/extensions/awareness/awareness-provider.ts +4 -4
  197. package/src/extensions/awareness/awareness.ts +7 -7
  198. package/src/extensions/blast.ts +9 -9
  199. package/src/extensions/command/action.ts +49 -0
  200. package/src/extensions/command/command.ts +7 -27
  201. package/src/extensions/command/hint.ts +36 -33
  202. package/src/extensions/command/index.ts +3 -0
  203. package/src/extensions/command/menu.ts +79 -51
  204. package/src/extensions/command/state.ts +41 -61
  205. package/src/extensions/command/typeahead.ts +116 -0
  206. package/src/extensions/comments.ts +11 -76
  207. package/src/extensions/factories.ts +13 -0
  208. package/src/extensions/folding.tsx +1 -1
  209. package/src/extensions/index.ts +3 -0
  210. package/src/extensions/json.ts +56 -0
  211. package/src/extensions/markdown/bundle.ts +13 -9
  212. package/src/extensions/markdown/changes.ts +3 -2
  213. package/src/extensions/markdown/decorate.ts +19 -17
  214. package/src/extensions/markdown/formatting.ts +6 -6
  215. package/src/extensions/markdown/image.ts +14 -13
  216. package/src/extensions/markdown/index.ts +1 -1
  217. package/src/extensions/markdown/link.ts +33 -24
  218. package/src/extensions/markdown/styles.ts +4 -3
  219. package/src/extensions/markdown/table.ts +3 -3
  220. package/src/extensions/modes.ts +5 -6
  221. package/src/extensions/outliner/commands.ts +270 -0
  222. package/src/extensions/outliner/editor.test.ts +33 -0
  223. package/src/extensions/outliner/editor.ts +184 -0
  224. package/src/extensions/outliner/index.ts +7 -0
  225. package/src/extensions/outliner/outliner.test.ts +99 -0
  226. package/src/extensions/outliner/outliner.ts +168 -0
  227. package/src/extensions/outliner/selection.ts +50 -0
  228. package/src/extensions/outliner/tree.test.ts +164 -0
  229. package/src/extensions/outliner/tree.ts +315 -0
  230. package/src/extensions/preview/index.ts +5 -0
  231. package/src/extensions/preview/preview.ts +271 -0
  232. package/src/hooks/index.ts +0 -1
  233. package/src/hooks/useTextEditor.ts +4 -3
  234. package/src/stories/Command.stories.tsx +97 -0
  235. package/src/stories/Comments.stories.tsx +98 -0
  236. package/src/stories/EditorToolbar.stories.tsx +96 -0
  237. package/src/stories/Experimental.stories.tsx +86 -0
  238. package/src/stories/Markdown.stories.tsx +121 -0
  239. package/src/stories/Outliner.stories.tsx +108 -0
  240. package/src/stories/Preview.stories.tsx +149 -0
  241. package/src/stories/TextEditor.stories.tsx +256 -0
  242. package/src/stories/util.tsx +326 -0
  243. package/src/styles/theme.ts +15 -5
  244. package/src/styles/tokens.ts +1 -2
  245. package/src/testing/index.ts +5 -0
  246. package/src/testing/util.ts +5 -0
  247. package/src/types.ts +7 -0
  248. package/src/util/react.tsx +20 -2
  249. package/dist/types/src/InputMode.stories.d.ts +0 -57
  250. package/dist/types/src/InputMode.stories.d.ts.map +0 -1
  251. package/dist/types/src/TextEditor.stories.d.ts +0 -115
  252. package/dist/types/src/TextEditor.stories.d.ts.map +0 -1
  253. package/dist/types/src/components/EditorToolbar/comment.d.ts.map +0 -1
  254. package/dist/types/src/components/EditorToolbar/viewMode.d.ts.map +0 -1
  255. package/dist/types/src/extensions/command/preview.d.ts +0 -12
  256. package/dist/types/src/extensions/command/preview.d.ts.map +0 -1
  257. package/dist/types/src/extensions/markdown/editorAction.d.ts.map +0 -1
  258. package/dist/types/src/fragments.d.ts +0 -3
  259. package/dist/types/src/fragments.d.ts.map +0 -1
  260. package/dist/types/src/hooks/useActionHandler.d.ts +0 -4
  261. package/dist/types/src/hooks/useActionHandler.d.ts.map +0 -1
  262. package/src/InputMode.stories.tsx +0 -124
  263. package/src/TextEditor.stories.tsx +0 -856
  264. package/src/components/EditorToolbar/comment.ts +0 -23
  265. package/src/extensions/command/preview.ts +0 -79
  266. package/src/fragments.ts +0 -19
  267. package/src/hooks/useActionHandler.ts +0 -12
  268. /package/src/extensions/markdown/{editorAction.ts → action.ts} +0 -0
@@ -0,0 +1,97 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import '@dxos-theme';
6
+
7
+ import React, { useState, type KeyboardEvent } from 'react';
8
+
9
+ import { Button, Icon, Input, DropdownMenu } from '@dxos/react-ui';
10
+ import { mx } from '@dxos/react-ui-theme';
11
+ import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
12
+
13
+ import { EditorStory } from './util';
14
+ import { RefDropdownMenu } from '../components';
15
+ import { editorWidth } from '../defaults';
16
+ import { command, type Action, floatingMenu } from '../extensions';
17
+ import { str } from '../testing';
18
+ import { createRenderer } from '../util';
19
+
20
+ const CommandDialog = ({ onAction }: { onAction: (action?: Action) => void }) => {
21
+ const [text, setText] = useState('');
22
+
23
+ const handleInsert = () => {
24
+ // TODO(burdon): Use queue ref.
25
+ const link = `[${text}](dxn:queue:data:123)`;
26
+ onAction(text.length ? { type: 'insert', text: link } : undefined);
27
+ };
28
+
29
+ const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
30
+ switch (event.key) {
31
+ case 'Enter': {
32
+ handleInsert();
33
+ break;
34
+ }
35
+ case 'Escape': {
36
+ onAction();
37
+ break;
38
+ }
39
+ }
40
+ };
41
+
42
+ return (
43
+ <div className='flex w-full justify-center'>
44
+ <div
45
+ className={mx(
46
+ 'flex w-full p-2 gap-2 items-center bg-modalSurface border border-separator rounded-md',
47
+ editorWidth,
48
+ )}
49
+ >
50
+ <Input.Root>
51
+ <Input.TextInput
52
+ autoFocus={true}
53
+ placeholder='Ask a question...'
54
+ value={text}
55
+ onChange={(ev) => setText(ev.target.value)}
56
+ onKeyDown={handleKeyDown}
57
+ />
58
+ </Input.Root>
59
+ <Button variant='ghost' classNames='pli-0' onClick={() => onAction({ type: 'cancel' })}>
60
+ <Icon icon='ph--x--regular' size={5} />
61
+ </Button>
62
+ </div>
63
+ </div>
64
+ );
65
+ };
66
+
67
+ const meta: Meta<typeof EditorStory> = {
68
+ title: 'ui/react-ui-editor/Command',
69
+ decorators: [withTheme, withLayout({ fullscreen: true })],
70
+ 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>
91
+ ),
92
+ parameters: { layout: 'fullscreen' },
93
+ };
94
+
95
+ export default meta;
96
+
97
+ export const Default = {};
@@ -0,0 +1,98 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import '@dxos-theme';
6
+
7
+ import { effect, useSignal } from '@preact/signals-react';
8
+ import React, { type FC } from 'react';
9
+
10
+ import { keySymbols, parseShortcut } from '@dxos/keyboard';
11
+ import { PublicKey } from '@dxos/keys';
12
+ import { log } from '@dxos/log';
13
+ import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
14
+
15
+ import { EditorStory, content, longText } from './util';
16
+ import { annotations, comments, createExternalCommentSync } from '../extensions';
17
+ import { str } from '../testing';
18
+ import { type Comment } from '../types';
19
+ import { createRenderer } from '../util';
20
+
21
+ const meta: Meta<typeof EditorStory> = {
22
+ title: 'ui/react-ui-editor/Comments',
23
+ decorators: [withTheme, withLayout({ fullscreen: true })],
24
+ render: EditorStory,
25
+ parameters: { layout: 'fullscreen' },
26
+ };
27
+
28
+ export default meta;
29
+
30
+ //
31
+ // Comments
32
+ //
33
+
34
+ export const Comments = {
35
+ render: () => {
36
+ const _comments = useSignal<Comment[]>([]);
37
+ return (
38
+ <EditorStory
39
+ text={str('# Comments', '', content.paragraphs, content.footer)}
40
+ extensions={[
41
+ createExternalCommentSync(
42
+ 'test',
43
+ (sink) => effect(() => sink()),
44
+ () => _comments.value,
45
+ ),
46
+ comments({
47
+ id: 'test',
48
+ renderTooltip: createRenderer(CommentTooltip),
49
+ onCreate: ({ cursor }) => {
50
+ const id = PublicKey.random().toHex();
51
+ _comments.value = [..._comments.value, { id, cursor }];
52
+ return id;
53
+ },
54
+ onSelect: (state) => {
55
+ const debug = false;
56
+ if (debug) {
57
+ log.info('update', {
58
+ comments: state.comments.length,
59
+ active: state.selection.current?.slice(0, 8),
60
+ closest: state.selection.closest?.slice(0, 8),
61
+ });
62
+ }
63
+ },
64
+ }),
65
+ ]}
66
+ />
67
+ );
68
+ },
69
+ };
70
+
71
+ const Key: FC<{ char: string }> = ({ char }) => (
72
+ <span className='flex justify-center items-center w-[24px] h-[24px] rounded text-xs bg-neutral-200 text-black'>
73
+ {char}
74
+ </span>
75
+ );
76
+
77
+ const CommentTooltip: FC<{ shortcut: string }> = ({ shortcut }) => {
78
+ return (
79
+ <div className='flex items-center gap-2 px-2 py-2 bg-neutral-700 text-white text-xs rounded'>
80
+ <div>Create comment</div>
81
+ <div className='flex gap-1'>
82
+ {keySymbols(parseShortcut(shortcut)).map((char) => (
83
+ <Key key={char} char={char} />
84
+ ))}
85
+ </div>
86
+ </div>
87
+ );
88
+ };
89
+
90
+ //
91
+ // Annotations
92
+ //
93
+
94
+ export const Annotations = {
95
+ render: () => (
96
+ <EditorStory text={str('# Annotations', '', longText)} extensions={[annotations({ match: /volup/gi })]} />
97
+ ),
98
+ };
@@ -0,0 +1,96 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import '@dxos-theme';
6
+
7
+ import { type StoryObj } from '@storybook/react';
8
+ import React, { useCallback, useState } from 'react';
9
+
10
+ import { invariant } from '@dxos/invariant';
11
+ import { useThemeContext } from '@dxos/react-ui';
12
+ import { attentionSurface, mx } from '@dxos/react-ui-theme';
13
+ import { type Meta, withLayout, withTheme } from '@dxos/storybook-utils';
14
+
15
+ import { EditorToolbar, useEditorToolbarState } from '../components';
16
+ import { editorWidth } from '../defaults';
17
+ import {
18
+ type EditorInputMode,
19
+ type EditorViewMode,
20
+ InputModeExtensions,
21
+ createMarkdownExtensions,
22
+ createBasicExtensions,
23
+ createThemeExtensions,
24
+ decorateMarkdown,
25
+ formattingKeymap,
26
+ useFormattingState,
27
+ } from '../extensions';
28
+ import { useTextEditor, type UseTextEditorProps } from '../hooks';
29
+ import translations from '../translations';
30
+
31
+ type StoryProps = { placeholder?: string } & UseTextEditorProps;
32
+
33
+ const DefaultStory = ({ autoFocus, initialValue, placeholder }: StoryProps) => {
34
+ const { themeMode } = useThemeContext();
35
+ const toolbarState = useEditorToolbarState({ viewMode: 'source' });
36
+ const viewMode = toolbarState.viewMode;
37
+ const trackFormatting = useFormattingState(toolbarState);
38
+ // TODO(wittjosiah): Provide way to change the input mode.
39
+ const [editorInputMode, _setEditorInputMode] = useState<EditorInputMode>('default');
40
+ const { parentRef, view } = useTextEditor(
41
+ () => ({
42
+ autoFocus,
43
+ initialValue,
44
+ moveToEndOfLine: true,
45
+ extensions: [
46
+ editorInputMode ? InputModeExtensions[editorInputMode] : [],
47
+ createBasicExtensions({ placeholder, lineWrapping: true, readOnly: viewMode === 'readonly' }),
48
+ createMarkdownExtensions({ themeMode }),
49
+ createThemeExtensions({ themeMode, syntaxHighlighting: true }),
50
+ viewMode === 'source' ? [] : decorateMarkdown(),
51
+ formattingKeymap(),
52
+ trackFormatting,
53
+ ],
54
+ }),
55
+ [editorInputMode, viewMode, themeMode, placeholder],
56
+ );
57
+
58
+ const getView = useCallback(() => {
59
+ invariant(view);
60
+ return view;
61
+ }, [view]);
62
+
63
+ const handleViewModeChange = useCallback((mode: EditorViewMode) => {
64
+ toolbarState.viewMode = mode;
65
+ }, []);
66
+
67
+ // TODO(marijn): This doesn't update the state on view changes.
68
+ // Also not sure if view is even guaranteed to exist at this point.
69
+ return (
70
+ <div role='none' className={mx('fixed inset-0 flex flex-col')}>
71
+ {toolbarState && <EditorToolbar state={toolbarState} getView={getView} viewMode={handleViewModeChange} />}
72
+ <div role='none' className={mx('grow overflow-hidden', attentionSurface)}>
73
+ <div className={mx(editorWidth)} ref={parentRef} />
74
+ </div>
75
+ </div>
76
+ );
77
+ };
78
+
79
+ const meta: Meta<StoryProps> = {
80
+ title: 'ui/react-ui-editor/EditorToolbar',
81
+ render: DefaultStory,
82
+ decorators: [withTheme, withLayout({ fullscreen: true })],
83
+ parameters: { translations, layout: 'fullscreen' },
84
+ };
85
+
86
+ export default meta;
87
+
88
+ type Story = StoryObj<typeof meta>;
89
+
90
+ export const Default: Story = {
91
+ args: {
92
+ autoFocus: true,
93
+ placeholder: 'Text...',
94
+ initialValue: '# Demo\n\nThis is a document.\n\n',
95
+ },
96
+ };
@@ -0,0 +1,86 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import '@dxos-theme';
6
+
7
+ import defaultsDeep from 'lodash.defaultsdeep';
8
+ import React from 'react';
9
+
10
+ import { log } from '@dxos/log';
11
+ import { faker } from '@dxos/random';
12
+ import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
13
+
14
+ import { EditorStory, content } from './util';
15
+ import { typewriter, blast, defaultOptions, dropFile } from '../extensions';
16
+ import { str } from '../testing';
17
+
18
+ const meta: Meta<typeof EditorStory> = {
19
+ title: 'ui/react-ui-editor/Experimental',
20
+ decorators: [withTheme, withLayout({ fullscreen: true })],
21
+ render: EditorStory,
22
+ parameters: { layout: 'fullscreen' },
23
+ };
24
+
25
+ export default meta;
26
+
27
+ //
28
+ // Typewriter
29
+ //
30
+
31
+ const typewriterItems = localStorage.getItem('dxos.org/plugin/markdown/typewriter')?.split(',');
32
+
33
+ export const Typewriter = {
34
+ render: () => (
35
+ <EditorStory
36
+ text={str('# Typewriter', '', content.paragraphs, content.footer)}
37
+ extensions={[typewriter({ items: typewriterItems })]}
38
+ />
39
+ ),
40
+ };
41
+
42
+ //
43
+ // Blast
44
+ //
45
+
46
+ export const Blast = {
47
+ render: () => (
48
+ <EditorStory
49
+ text={str('# Blast', '', content.paragraphs, content.codeblocks, content.paragraphs)}
50
+ extensions={[
51
+ typewriter({ items: typewriterItems }),
52
+ blast(
53
+ defaultsDeep(
54
+ {
55
+ effect: 2,
56
+ particleGravity: 0.2,
57
+ particleShrinkRate: 0.995,
58
+ color: () => [faker.number.int({ min: 100, max: 200 }), 0, 0],
59
+ // color: () => [faker.number.int(256), faker.number.int(256), faker.number.int(256)],
60
+ },
61
+ defaultOptions,
62
+ ),
63
+ ),
64
+ ]}
65
+ />
66
+ ),
67
+ };
68
+
69
+ //
70
+ // DND
71
+ //
72
+
73
+ export const DND = {
74
+ render: () => (
75
+ <EditorStory
76
+ text={str('# DND', '')}
77
+ extensions={[
78
+ dropFile({
79
+ onDrop: (view, event) => {
80
+ log.info('drop', event);
81
+ },
82
+ }),
83
+ ]}
84
+ />
85
+ ),
86
+ };
@@ -0,0 +1,121 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import '@dxos-theme';
6
+
7
+ import { markdown } from '@codemirror/lang-markdown';
8
+ import React from 'react';
9
+
10
+ import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
11
+
12
+ import { EditorStory, content, defaultExtensions, headings, renderLinkTooltip, text } from './util';
13
+ import { decorateMarkdown, image, linkTooltip, table } from '../extensions';
14
+ import { str } from '../testing';
15
+
16
+ const meta: Meta<typeof EditorStory> = {
17
+ title: 'ui/react-ui-editor/Markdown',
18
+ decorators: [withTheme, withLayout({ fullscreen: true })],
19
+ render: EditorStory,
20
+ parameters: { layout: 'fullscreen' },
21
+ };
22
+
23
+ export default meta;
24
+
25
+ //
26
+ // Default
27
+ //
28
+
29
+ export const Default = {
30
+ render: () => <EditorStory text={text} extensions={defaultExtensions} />,
31
+ };
32
+
33
+ export const Blockquote = {
34
+ render: () => (
35
+ <EditorStory
36
+ text={str('> Blockquote', 'continuation', content.footer)}
37
+ extensions={decorateMarkdown()}
38
+ debug='raw'
39
+ />
40
+ ),
41
+ };
42
+
43
+ export const Headings = {
44
+ render: () => <EditorStory text={headings} extensions={decorateMarkdown({ numberedHeadings: { from: 2, to: 4 } })} />,
45
+ };
46
+
47
+ export const Links = {
48
+ render: () => <EditorStory text={str(content.links, content.footer)} extensions={[linkTooltip(renderLinkTooltip)]} />,
49
+ };
50
+
51
+ export const Image = {
52
+ render: () => <EditorStory text={str(content.image, content.footer)} extensions={[image()]} />,
53
+ };
54
+
55
+ export const Code = {
56
+ render: () => <EditorStory text={str(content.codeblocks, content.footer)} extensions={[decorateMarkdown()]} />,
57
+ };
58
+
59
+ export const Lists = {
60
+ render: () => (
61
+ <EditorStory
62
+ text={str(content.tasks, '', content.bullets, '', content.numbered, content.footer)}
63
+ extensions={[decorateMarkdown()]}
64
+ />
65
+ ),
66
+ };
67
+
68
+ //
69
+ // Bullet List
70
+ //
71
+
72
+ export const BulletList = {
73
+ render: () => <EditorStory text={str(content.bullets, content.footer)} extensions={[decorateMarkdown()]} />,
74
+ };
75
+
76
+ //
77
+ // Ordered List
78
+ //
79
+
80
+ export const OrderedList = {
81
+ render: () => <EditorStory text={str(content.numbered, content.footer)} extensions={[decorateMarkdown()]} />,
82
+ };
83
+
84
+ //
85
+ // Task List
86
+ //
87
+
88
+ export const TaskList = {
89
+ render: () => (
90
+ <EditorStory text={str(content.tasks, content.footer)} extensions={[decorateMarkdown()]} debug='raw+tree' />
91
+ ),
92
+ };
93
+
94
+ export const TaskListEmpty = {
95
+ render: () => <EditorStory text={str('- [ ] ')} extensions={[decorateMarkdown()]} debug='raw+tree' />,
96
+ };
97
+
98
+ //
99
+ // Table
100
+ //
101
+
102
+ export const Table = {
103
+ render: () => <EditorStory text={str(content.table, content.footer)} extensions={[decorateMarkdown(), table()]} />,
104
+ };
105
+
106
+ //
107
+ // Commented out
108
+ //
109
+
110
+ export const CommentedOut = {
111
+ render: () => (
112
+ <EditorStory
113
+ text={str('# Commented out', '', content.comment, content.footer)}
114
+ extensions={[
115
+ decorateMarkdown(),
116
+ markdown(),
117
+ // commentBlock()
118
+ ]}
119
+ />
120
+ ),
121
+ };
@@ -0,0 +1,108 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import '@dxos-theme';
6
+
7
+ import React from 'react';
8
+
9
+ import { DropdownMenu } from '@dxos/react-ui';
10
+ import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
11
+
12
+ import { EditorStory } from './util';
13
+ import { RefDropdownMenu } from '../components';
14
+ import { outliner, listItemToString, treeFacet } from '../extensions';
15
+ import { str } from '../testing';
16
+
17
+ type StoryProps = {
18
+ text: string;
19
+ };
20
+
21
+ const DefaultStory = ({ text }: StoryProps) => {
22
+ return (
23
+ <RefDropdownMenu.Provider>
24
+ <EditorStory
25
+ text={text}
26
+ extensions={[outliner()]}
27
+ placeholder=''
28
+ slots={{}}
29
+ debug='raw+tree'
30
+ debugCustom={(view) => {
31
+ const tree = view.state.facet(treeFacet);
32
+ const lines: string[] = [];
33
+ tree.traverse((item) => lines.push(listItemToString(item)));
34
+ return <pre className='p-1 text-xs text-green-800 dark:text-green-200 overflow-auto'>{lines.join('\n')}</pre>;
35
+ }}
36
+ />
37
+ <DropdownMenu.Portal>
38
+ <DropdownMenu.Content>
39
+ <DropdownMenu.Viewport>
40
+ <DropdownMenu.Item onClick={() => console.log('test')}>Test</DropdownMenu.Item>
41
+ </DropdownMenu.Viewport>
42
+ <DropdownMenu.Arrow />
43
+ </DropdownMenu.Content>
44
+ </DropdownMenu.Portal>
45
+ </RefDropdownMenu.Provider>
46
+ );
47
+ };
48
+
49
+ const meta: Meta<StoryProps> = {
50
+ title: 'ui/react-ui-editor/Outliner',
51
+ decorators: [withTheme, withLayout({ fullscreen: true })],
52
+ render: DefaultStory,
53
+ parameters: { layout: 'fullscreen' },
54
+ };
55
+
56
+ export default meta;
57
+
58
+ export const Empty = {
59
+ args: {},
60
+ };
61
+
62
+ export const Basic = {
63
+ args: {
64
+ text: str(
65
+ //
66
+ '- [ ] A',
67
+ '- [ ] B',
68
+ '- [ ] C',
69
+ '- [ ] D',
70
+ '- [ ] E',
71
+ '- [ ] F',
72
+ '- [ ] G',
73
+ ),
74
+ },
75
+ };
76
+
77
+ export const Nested = {
78
+ args: {
79
+ text: str(
80
+ //
81
+ '- [ ] A',
82
+ ' - [ ] B',
83
+ '- [ ] C',
84
+ ' - [ ] D',
85
+ ' - [ ] E',
86
+ ' - [ ] F',
87
+ '- [ ] G',
88
+ ),
89
+ },
90
+ };
91
+
92
+ export const Continuation = {
93
+ args: {
94
+ text: str(
95
+ //
96
+ '- [ ] A',
97
+ '- [ ] B',
98
+ 'Continuation line.',
99
+ '- [ ] C',
100
+ '',
101
+ '- [ ] D',
102
+ '- [ ] E',
103
+ '- [ ] F',
104
+ '- [ ] G',
105
+ '',
106
+ ),
107
+ },
108
+ };