@dxos/react-ui-editor 0.8.2-main.fbd8ed0 → 0.8.2-staging.4d6ad0f

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 (180) hide show
  1. package/dist/lib/browser/index.mjs +1731 -926
  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 +3 -64
  5. package/dist/lib/browser/testing/index.mjs.map +4 -4
  6. package/dist/lib/node/index.cjs +1912 -1111
  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 +3 -75
  10. package/dist/lib/node/testing/index.cjs.map +4 -4
  11. package/dist/lib/node-esm/index.mjs +1731 -926
  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 +3 -64
  15. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  16. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
  17. package/dist/types/src/components/EditorToolbar/index.d.ts +1 -1
  18. package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -1
  19. package/dist/types/src/components/EditorToolbar/util.d.ts +4 -6
  20. package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -1
  21. package/dist/types/src/components/Popover/RefDropdownMenu.d.ts +21 -0
  22. package/dist/types/src/components/Popover/RefDropdownMenu.d.ts.map +1 -0
  23. package/dist/types/src/{testing → components/Popover}/RefPopover.d.ts +1 -1
  24. package/dist/types/src/components/Popover/RefPopover.d.ts.map +1 -0
  25. package/dist/types/src/components/Popover/index.d.ts +3 -0
  26. package/dist/types/src/components/Popover/index.d.ts.map +1 -0
  27. package/dist/types/src/components/index.d.ts +1 -0
  28. package/dist/types/src/components/index.d.ts.map +1 -1
  29. package/dist/types/src/defaults.d.ts +2 -5
  30. package/dist/types/src/defaults.d.ts.map +1 -1
  31. package/dist/types/src/extensions/annotations.d.ts +4 -1
  32. package/dist/types/src/extensions/annotations.d.ts.map +1 -1
  33. package/dist/types/src/extensions/autocomplete.d.ts +1 -2
  34. package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
  35. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  36. package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
  37. package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -1
  38. package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -1
  39. package/dist/types/src/extensions/command/command.d.ts +1 -2
  40. package/dist/types/src/extensions/command/command.d.ts.map +1 -1
  41. package/dist/types/src/extensions/command/hint.d.ts +14 -2
  42. package/dist/types/src/extensions/command/hint.d.ts.map +1 -1
  43. package/dist/types/src/extensions/command/index.d.ts +2 -0
  44. package/dist/types/src/extensions/command/index.d.ts.map +1 -1
  45. package/dist/types/src/extensions/command/menu.d.ts +7 -8
  46. package/dist/types/src/extensions/command/menu.d.ts.map +1 -1
  47. package/dist/types/src/extensions/command/state.d.ts +1 -1
  48. package/dist/types/src/extensions/command/state.d.ts.map +1 -1
  49. package/dist/types/src/extensions/command/typeahead.d.ts +17 -0
  50. package/dist/types/src/extensions/command/typeahead.d.ts.map +1 -0
  51. package/dist/types/src/extensions/comments.d.ts +2 -12
  52. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  53. package/dist/types/src/extensions/factories.d.ts +4 -0
  54. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  55. package/dist/types/src/extensions/index.d.ts +2 -0
  56. package/dist/types/src/extensions/index.d.ts.map +1 -1
  57. package/dist/types/src/extensions/json.d.ts +7 -0
  58. package/dist/types/src/extensions/json.d.ts.map +1 -0
  59. package/dist/types/src/extensions/markdown/{editorAction.d.ts → action.d.ts} +1 -1
  60. package/dist/types/src/extensions/markdown/action.d.ts.map +1 -0
  61. package/dist/types/src/extensions/markdown/bundle.d.ts +2 -1
  62. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
  63. package/dist/types/src/extensions/markdown/index.d.ts +1 -2
  64. package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
  65. package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
  66. package/dist/types/src/extensions/outliner/commands.d.ts +9 -0
  67. package/dist/types/src/extensions/outliner/commands.d.ts.map +1 -0
  68. package/dist/types/src/extensions/outliner/editor.d.ts +5 -0
  69. package/dist/types/src/extensions/outliner/editor.d.ts.map +1 -0
  70. package/dist/types/src/extensions/outliner/editor.test.d.ts +2 -0
  71. package/dist/types/src/extensions/outliner/editor.test.d.ts.map +1 -0
  72. package/dist/types/src/extensions/outliner/index.d.ts +3 -0
  73. package/dist/types/src/extensions/outliner/index.d.ts.map +1 -0
  74. package/dist/types/src/extensions/outliner/outliner.d.ts +10 -0
  75. package/dist/types/src/extensions/outliner/outliner.d.ts.map +1 -0
  76. package/dist/types/src/extensions/outliner/outliner.test.d.ts +2 -0
  77. package/dist/types/src/extensions/outliner/outliner.test.d.ts.map +1 -0
  78. package/dist/types/src/extensions/outliner/selection.d.ts +12 -0
  79. package/dist/types/src/extensions/outliner/selection.d.ts.map +1 -0
  80. package/dist/types/src/extensions/outliner/tree.d.ts +79 -0
  81. package/dist/types/src/extensions/outliner/tree.d.ts.map +1 -0
  82. package/dist/types/src/extensions/outliner/tree.test.d.ts +2 -0
  83. package/dist/types/src/extensions/outliner/tree.test.d.ts.map +1 -0
  84. package/dist/types/src/stories/Command.stories.d.ts +7 -0
  85. package/dist/types/src/stories/Command.stories.d.ts.map +1 -0
  86. package/dist/types/src/stories/{TextEditorComments.stories.d.ts → Comments.stories.d.ts} +3 -3
  87. package/dist/types/src/stories/Comments.stories.d.ts.map +1 -0
  88. package/dist/types/src/stories/EditorToolbar.stories.d.ts +12 -0
  89. package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -0
  90. package/dist/types/src/stories/{TextEditorSpecial.stories.d.ts → Experimental.stories.d.ts} +3 -6
  91. package/dist/types/src/stories/Experimental.stories.d.ts.map +1 -0
  92. package/dist/types/src/stories/Markdown.stories.d.ts +46 -0
  93. package/dist/types/src/stories/Markdown.stories.d.ts.map +1 -0
  94. package/dist/types/src/stories/Outliner.stories.d.ts +26 -0
  95. package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -0
  96. package/dist/types/src/stories/Preview.stories.d.ts +10 -0
  97. package/dist/types/src/stories/Preview.stories.d.ts.map +1 -0
  98. package/dist/types/src/stories/{TextEditorBasic.stories.d.ts → TextEditor.stories.d.ts} +9 -39
  99. package/dist/types/src/stories/TextEditor.stories.d.ts.map +1 -0
  100. package/dist/types/src/stories/{story-utils.d.ts → util.d.ts} +6 -6
  101. package/dist/types/src/stories/util.d.ts.map +1 -0
  102. package/dist/types/src/styles/theme.d.ts.map +1 -1
  103. package/dist/types/src/styles/tokens.d.ts.map +1 -1
  104. package/dist/types/src/testing/index.d.ts +1 -1
  105. package/dist/types/src/testing/index.d.ts.map +1 -1
  106. package/dist/types/src/testing/util.d.ts +2 -0
  107. package/dist/types/src/testing/util.d.ts.map +1 -0
  108. package/package.json +40 -34
  109. package/src/components/EditorToolbar/EditorToolbar.tsx +81 -57
  110. package/src/components/EditorToolbar/index.ts +7 -1
  111. package/src/components/EditorToolbar/util.ts +3 -4
  112. package/src/components/Popover/RefDropdownMenu.tsx +77 -0
  113. package/src/{testing → components/Popover}/RefPopover.tsx +5 -4
  114. package/src/components/Popover/index.ts +6 -0
  115. package/src/components/index.ts +1 -0
  116. package/src/defaults.ts +10 -13
  117. package/src/extensions/annotations.ts +41 -64
  118. package/src/extensions/autocomplete.ts +5 -6
  119. package/src/extensions/automerge/automerge.stories.tsx +2 -7
  120. package/src/extensions/automerge/automerge.test.tsx +3 -2
  121. package/src/extensions/automerge/sync.ts +3 -3
  122. package/src/extensions/awareness/awareness-provider.ts +4 -4
  123. package/src/extensions/awareness/awareness.ts +7 -7
  124. package/src/extensions/blast.ts +9 -9
  125. package/src/extensions/command/command.ts +1 -3
  126. package/src/extensions/command/hint.ts +7 -7
  127. package/src/extensions/command/index.ts +2 -0
  128. package/src/extensions/command/menu.ts +43 -49
  129. package/src/extensions/command/typeahead.ts +116 -0
  130. package/src/extensions/comments.ts +4 -69
  131. package/src/extensions/factories.ts +13 -0
  132. package/src/extensions/index.ts +2 -0
  133. package/src/extensions/json.ts +56 -0
  134. package/src/extensions/markdown/bundle.ts +13 -9
  135. package/src/extensions/markdown/decorate.ts +7 -7
  136. package/src/extensions/markdown/image.ts +2 -2
  137. package/src/extensions/markdown/index.ts +1 -2
  138. package/src/extensions/markdown/styles.ts +2 -1
  139. package/src/extensions/markdown/table.ts +3 -3
  140. package/src/extensions/outliner/commands.ts +242 -0
  141. package/src/extensions/outliner/editor.test.ts +33 -0
  142. package/src/extensions/outliner/editor.ts +180 -0
  143. package/src/extensions/outliner/index.ts +6 -0
  144. package/src/extensions/outliner/outliner.test.ts +99 -0
  145. package/src/extensions/outliner/outliner.ts +162 -0
  146. package/src/extensions/outliner/selection.ts +50 -0
  147. package/src/extensions/outliner/tree.test.ts +164 -0
  148. package/src/extensions/outliner/tree.ts +315 -0
  149. package/src/extensions/preview/preview.ts +5 -5
  150. package/src/stories/Command.stories.tsx +97 -0
  151. package/src/stories/{TextEditorComments.stories.tsx → Comments.stories.tsx} +13 -14
  152. package/src/{components/EditorToolbar → stories}/EditorToolbar.stories.tsx +26 -20
  153. package/src/stories/{TextEditorSpecial.stories.tsx → Experimental.stories.tsx} +9 -30
  154. package/src/stories/Markdown.stories.tsx +121 -0
  155. package/src/stories/Outliner.stories.tsx +108 -0
  156. package/src/stories/{TextEditorPreview.stories.tsx → Preview.stories.tsx} +46 -136
  157. package/src/stories/TextEditor.stories.tsx +256 -0
  158. package/src/stories/{story-utils.tsx → util.tsx} +21 -22
  159. package/src/styles/theme.ts +12 -5
  160. package/src/styles/tokens.ts +1 -2
  161. package/src/testing/index.ts +1 -1
  162. package/src/testing/util.ts +5 -0
  163. package/dist/types/src/components/EditorToolbar/EditorToolbar.stories.d.ts +0 -53
  164. package/dist/types/src/components/EditorToolbar/EditorToolbar.stories.d.ts.map +0 -1
  165. package/dist/types/src/components/EditorToolbar/comment.d.ts +0 -18
  166. package/dist/types/src/components/EditorToolbar/comment.d.ts.map +0 -1
  167. package/dist/types/src/extensions/markdown/editorAction.d.ts.map +0 -1
  168. package/dist/types/src/extensions/markdown/outliner.d.ts +0 -12
  169. package/dist/types/src/extensions/markdown/outliner.d.ts.map +0 -1
  170. package/dist/types/src/stories/TextEditorBasic.stories.d.ts.map +0 -1
  171. package/dist/types/src/stories/TextEditorComments.stories.d.ts.map +0 -1
  172. package/dist/types/src/stories/TextEditorPreview.stories.d.ts +0 -13
  173. package/dist/types/src/stories/TextEditorPreview.stories.d.ts.map +0 -1
  174. package/dist/types/src/stories/TextEditorSpecial.stories.d.ts.map +0 -1
  175. package/dist/types/src/stories/story-utils.d.ts.map +0 -1
  176. package/dist/types/src/testing/RefPopover.d.ts.map +0 -1
  177. package/src/components/EditorToolbar/comment.ts +0 -30
  178. package/src/extensions/markdown/outliner.ts +0 -235
  179. package/src/stories/TextEditorBasic.stories.tsx +0 -333
  180. /package/src/extensions/markdown/{editorAction.ts → action.ts} +0 -0
@@ -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
+ };
@@ -4,73 +4,26 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
- import React, { useState, useEffect, type FC, type KeyboardEvent } from 'react';
7
+ import React, { useState, useEffect, type FC } from 'react';
8
8
 
9
9
  import { faker } from '@dxos/random';
10
- import { Button, Icon, IconButton, Input, Popover } from '@dxos/react-ui';
11
- import { mx, hoverableHidden } from '@dxos/react-ui-theme';
10
+ import { IconButton, Popover } from '@dxos/react-ui';
11
+ import { hoverableHidden } from '@dxos/react-ui-theme';
12
12
  import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
13
13
 
14
- import { DefaultStory, str } from './story-utils';
15
- import { editorWidth } from '../defaults';
14
+ import { EditorStory } from './util';
15
+ import { RefPopover, useRefPopover } from '../components';
16
16
  import {
17
17
  preview,
18
- command,
19
18
  image,
20
19
  type PreviewOptions,
21
20
  type PreviewLinkRef,
22
21
  type PreviewLinkTarget,
23
22
  type PreviewRenderProps,
24
- type Action,
25
23
  } from '../extensions';
26
- import { RefPopover, useRefPopover } from '../testing';
24
+ import { str } from '../testing';
27
25
  import { createRenderer } from '../util';
28
26
 
29
- const meta: Meta<typeof DefaultStory> = {
30
- title: 'ui/react-ui-editor/TextEditor',
31
- decorators: [withTheme, withLayout({ fullscreen: true })],
32
- render: DefaultStory,
33
- parameters: { layout: 'fullscreen' },
34
- };
35
-
36
- export default meta;
37
-
38
- //
39
- // Preview
40
- //
41
-
42
- export const Preview = {
43
- render: () => (
44
- <RefPopover.Provider onLookup={handlePreviewLookup}>
45
- <DefaultStory
46
- text={str(
47
- '# Preview',
48
- '',
49
- 'This project is part of the [DXOS][dxn:queue:data:123] SDK.',
50
- '',
51
- '![DXOS][?dxn:queue:data:123]',
52
- '',
53
- 'It consists of [ECHO][dxn:queue:data:echo], [HALO][dxn:queue:data:halo], and [MESH][dxn:queue:data:mesh].',
54
- '',
55
- '## Deep dive',
56
- '',
57
- '![ECHO][dxn:queue:data:echo]',
58
- '',
59
- '',
60
- )}
61
- extensions={[
62
- image(),
63
- preview({
64
- renderBlock: createRenderer(PreviewBlock),
65
- onLookup: handlePreviewLookup,
66
- }),
67
- ]}
68
- />
69
- <PreviewCard />
70
- </RefPopover.Provider>
71
- ),
72
- };
73
-
74
27
  const handlePreviewLookup = async ({ label, ref }: PreviewLinkRef): Promise<PreviewLinkTarget> => {
75
28
  // Random text.
76
29
  faker.seed(ref.split('').reduce((acc: number, char: string) => acc + char.charCodeAt(0), 1));
@@ -82,7 +35,7 @@ const handlePreviewLookup = async ({ label, ref }: PreviewLinkRef): Promise<Prev
82
35
  };
83
36
 
84
37
  // Async lookup.
85
- // TODO(burdon): Handle error.s
38
+ // TODO(burdon): Handle errors.
86
39
  const useRefTarget = (link: PreviewLinkRef, onLookup: PreviewOptions['onLookup']): PreviewLinkTarget | undefined => {
87
40
  const [target, setTarget] = useState<PreviewLinkTarget | undefined>();
88
41
  useEffect(() => {
@@ -93,12 +46,12 @@ const useRefTarget = (link: PreviewLinkRef, onLookup: PreviewOptions['onLookup']
93
46
  };
94
47
 
95
48
  const PreviewCard = () => {
96
- const { link, target } = useRefPopover('PreviewCard');
49
+ const { target } = useRefPopover('PreviewCard');
97
50
  return (
98
51
  <Popover.Portal>
99
- <Popover.Content onOpenAutoFocus={(e) => e.preventDefault()}>
52
+ <Popover.Content classNames='popover-card-width p-2' onOpenAutoFocus={(event) => event.preventDefault()}>
100
53
  <Popover.Viewport>
101
- <div className='grow truncate'>{link?.label}</div>
54
+ <h2 className='grow truncate'>{target?.label}</h2>
102
55
  {target && <div className='line-clamp-3'>{target.text}</div>}
103
56
  </Popover.Viewport>
104
57
  <Popover.Arrow />
@@ -153,87 +106,44 @@ const PreviewBlock: FC<PreviewRenderProps> = ({ readonly, link, onAction, onLook
153
106
  );
154
107
  };
155
108
 
156
- //
157
- // Command
158
- //
159
-
160
- export const Command = {
161
- render: () => (
162
- <DefaultStory
163
- text={str(
164
- '# Preview',
165
- '',
166
- 'This project is part of the [DXOS][dxn:queue:data:123] SDK.',
167
- '',
168
- '![DXOS][dxn:queue:data:123]',
169
- '',
170
- )}
171
- extensions={[
172
- preview({
173
- renderBlock: createRenderer(PreviewBlock),
174
- onLookup: handlePreviewLookup,
175
- }),
176
- command({
177
- renderMenu: createRenderer(CommandMenu),
178
- renderDialog: createRenderer(CommandDialog),
179
- onHint: () => 'Press / for commands.',
180
- }),
181
- ]}
182
- />
183
- ),
184
- };
185
-
186
- const CommandMenu = ({ onAction }: { onAction: () => void }) => {
187
- return (
188
- <Button classNames='p-1 aspect-square' onClick={onAction}>
189
- <Icon icon='ph--sparkle--regular' size={5} />
190
- </Button>
191
- );
109
+ const meta: Meta<typeof EditorStory> = {
110
+ title: 'ui/react-ui-editor/Preview',
111
+ decorators: [withTheme, withLayout({ fullscreen: true })],
112
+ render: EditorStory,
113
+ parameters: { layout: 'fullscreen' },
192
114
  };
193
115
 
194
- const CommandDialog = ({ onAction }: { onAction: (action?: Action) => void }) => {
195
- const [text, setText] = useState('');
196
-
197
- const handleInsert = () => {
198
- // TODO(burdon): Use queue ref.
199
- const link = `[${text}](dxn:queue:data:123)`;
200
- onAction(text.length ? { type: 'insert', text: link } : undefined);
201
- };
202
-
203
- const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
204
- switch (event.key) {
205
- case 'Enter': {
206
- handleInsert();
207
- break;
208
- }
209
- case 'Escape': {
210
- onAction();
211
- break;
212
- }
213
- }
214
- };
116
+ export default meta;
215
117
 
216
- return (
217
- <div className='flex w-full justify-center'>
218
- <div
219
- className={mx(
220
- 'flex w-full p-2 gap-2 items-center bg-modalSurface border border-separator rounded-md',
221
- editorWidth,
118
+ export const Default = {
119
+ render: () => (
120
+ <RefPopover.Provider onLookup={handlePreviewLookup}>
121
+ <EditorStory
122
+ text={str(
123
+ '# Preview',
124
+ '',
125
+ 'This project is part of the [DXOS][dxn:queue:data:123] SDK.',
126
+ '',
127
+ '![DXOS][?dxn:queue:data:123]',
128
+ '',
129
+ 'It consists of [ECHO][dxn:queue:data:echo], [HALO][dxn:queue:data:halo], and [MESH][dxn:queue:data:mesh].',
130
+ '',
131
+ '## Deep dive',
132
+ '',
133
+ '![ECHO][dxn:queue:data:echo]',
134
+ '',
135
+ '',
136
+ '',
222
137
  )}
223
- >
224
- <Input.Root>
225
- <Input.TextInput
226
- autoFocus={true}
227
- placeholder='Ask a question...'
228
- value={text}
229
- onChange={(ev) => setText(ev.target.value)}
230
- onKeyDown={handleKeyDown}
231
- />
232
- </Input.Root>
233
- <Button variant='ghost' classNames='pli-0' onClick={() => onAction({ type: 'cancel' })}>
234
- <Icon icon='ph--x--regular' size={5} />
235
- </Button>
236
- </div>
237
- </div>
238
- );
138
+ extensions={[
139
+ image(),
140
+ preview({
141
+ renderBlock: createRenderer(PreviewBlock),
142
+ onLookup: handlePreviewLookup,
143
+ }),
144
+ ]}
145
+ />
146
+ <PreviewCard />
147
+ </RefPopover.Provider>
148
+ ),
239
149
  };
@@ -0,0 +1,256 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import '@dxos-theme';
6
+
7
+ import { javascript } from '@codemirror/lang-javascript';
8
+ import { openSearchPanel } from '@codemirror/search';
9
+ import React from 'react';
10
+
11
+ import { log } from '@dxos/log';
12
+ import { withLayout, withTheme, type Meta } from '@dxos/storybook-utils';
13
+
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 './util';
27
+ import { editorMonospace } from '../defaults';
28
+ import {
29
+ InputModeExtensions,
30
+ autocomplete,
31
+ decorateMarkdown,
32
+ folding,
33
+ image,
34
+ listener,
35
+ mention,
36
+ selectionState,
37
+ staticCompletion,
38
+ typeahead,
39
+ } from '../extensions';
40
+ import { str } from '../testing';
41
+
42
+ const meta: Meta<typeof EditorStory> = {
43
+ title: 'ui/react-ui-editor/TextEditor',
44
+ render: EditorStory,
45
+ decorators: [withTheme, withLayout({ fullscreen: true })],
46
+ parameters: { layout: 'fullscreen' },
47
+ };
48
+
49
+ export default meta;
50
+
51
+ //
52
+ // Default
53
+ //
54
+
55
+ export const Default = {
56
+ render: () => <EditorStory text={text} extensions={defaultExtensions} />,
57
+ };
58
+
59
+ //
60
+ // Everything
61
+ //
62
+
63
+ export const Everything = {
64
+ render: () => <EditorStory text={text} extensions={allExtensions} selection={{ anchor: 99, head: 110 }} />,
65
+ };
66
+
67
+ //
68
+ // Empty
69
+ //
70
+
71
+ export const Empty = {
72
+ render: () => <EditorStory extensions={defaultExtensions} />,
73
+ };
74
+
75
+ //
76
+ // Readonly
77
+ //
78
+
79
+ export const Readonly = {
80
+ render: () => <EditorStory text={text} extensions={defaultExtensions} readOnly />,
81
+ };
82
+
83
+ //
84
+ // No Extensions
85
+ //
86
+
87
+ export const NoExtensions = {
88
+ render: () => <EditorStory text={text} />,
89
+ };
90
+
91
+ //
92
+ // Vim
93
+ //
94
+
95
+ export const Vim = {
96
+ render: () => (
97
+ <EditorStory
98
+ text={str('# Vim Mode', '', 'The distant future. The year 2000.', '', content.paragraphs)}
99
+ extensions={[defaultExtensions, InputModeExtensions.vim]}
100
+ />
101
+ ),
102
+ };
103
+
104
+ //
105
+ // Listener
106
+ //
107
+
108
+ export const Listener = {
109
+ render: () => (
110
+ <EditorStory
111
+ text={str('# Listener', '', content.footer)}
112
+ extensions={[
113
+ listener({
114
+ onFocus: (focusing) => {
115
+ log.info('listener', { focusing });
116
+ },
117
+ onChange: (text) => {
118
+ log.info('listener', { text });
119
+ },
120
+ }),
121
+ ]}
122
+ />
123
+ ),
124
+ };
125
+
126
+ //
127
+ // Folding
128
+ //
129
+
130
+ export const Folding = {
131
+ render: () => <EditorStory text={text} extensions={[folding()]} />,
132
+ };
133
+
134
+ //
135
+ // Scrolling
136
+ //
137
+
138
+ export const Scrolling = {
139
+ render: () => (
140
+ <EditorStory
141
+ text={str('# Large Document', '', longText)}
142
+ extensions={selectionState({
143
+ setState: (id, state) => global.set(id, state),
144
+ getState: (id) => global.get(id),
145
+ })}
146
+ />
147
+ ),
148
+ };
149
+
150
+ export const ScrollingWithImages = {
151
+ render: () => (
152
+ <EditorStory text={str('# Large Document', '', largeWithImages)} extensions={[decorateMarkdown(), image()]} />
153
+ ),
154
+ };
155
+
156
+ export const ScrollTo = {
157
+ render: () => {
158
+ // NOTE: Selection won't appear if text is reformatted.
159
+ const word = 'Scroll to here...';
160
+ const text = str('# Scroll To', longText, '', word, '', longText);
161
+ const idx = text.indexOf(word);
162
+ return (
163
+ <EditorStory
164
+ text={text}
165
+ extensions={defaultExtensions}
166
+ scrollTo={idx}
167
+ selection={{ anchor: idx, head: idx + word.length }}
168
+ />
169
+ );
170
+ },
171
+ };
172
+
173
+ //
174
+ // Typescript
175
+ //
176
+
177
+ export const Typescript = {
178
+ render: () => (
179
+ <EditorStory
180
+ text={content.typescript}
181
+ lineNumbers
182
+ extensions={[editorMonospace, javascript({ typescript: true })]}
183
+ />
184
+ ),
185
+ };
186
+
187
+ //
188
+ // Autocomplete
189
+ //
190
+
191
+ export const Autocomplete = {
192
+ render: () => (
193
+ <EditorStory
194
+ text={str('# Autocomplete', '', 'Press Ctrl-Space...', content.footer)}
195
+ extensions={[
196
+ decorateMarkdown({ renderLinkButton }),
197
+ autocomplete({
198
+ onSearch: (text) => {
199
+ return links.filter(({ label }) => label.toLowerCase().includes(text.toLowerCase()));
200
+ },
201
+ }),
202
+ ]}
203
+ />
204
+ ),
205
+ };
206
+
207
+ //
208
+ // Typeahead
209
+ //
210
+
211
+ const completions = ['type', 'AND', 'OR', 'NOT', 'dxos.org'];
212
+
213
+ export const Typeahead = {
214
+ render: () => (
215
+ <EditorStory
216
+ text={str('# Typeahead', '')}
217
+ extensions={[
218
+ decorateMarkdown({ renderLinkButton }),
219
+ typeahead({
220
+ onComplete: staticCompletion(completions, completions[0]),
221
+ }),
222
+ ]}
223
+ />
224
+ ),
225
+ };
226
+
227
+ //
228
+ // Mention
229
+ //
230
+
231
+ export const Mention = {
232
+ render: () => (
233
+ <EditorStory
234
+ text={str('# Mention', '', 'Type @...', content.footer)}
235
+ extensions={[
236
+ mention({
237
+ onSearch: (text) => names.filter((name) => name.toLowerCase().startsWith(text.toLowerCase())),
238
+ }),
239
+ ]}
240
+ />
241
+ ),
242
+ };
243
+
244
+ //
245
+ // Search
246
+ //
247
+
248
+ export const Search = {
249
+ render: () => (
250
+ <EditorStory
251
+ text={str('# Search', text)}
252
+ extensions={defaultExtensions}
253
+ onReady={(view) => openSearchPanel(view)}
254
+ />
255
+ ),
256
+ };