@dxos/react-ui-editor 0.8.4-main.3eb6e50203 → 0.8.4-main.3fbcb4aa9b

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 (147) hide show
  1. package/dist/lib/browser/index.mjs +793 -752
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/browser/translations.mjs +39 -0
  5. package/dist/lib/browser/translations.mjs.map +7 -0
  6. package/dist/lib/node-esm/index.mjs +793 -752
  7. package/dist/lib/node-esm/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/meta.json +1 -1
  9. package/dist/lib/node-esm/translations.mjs +41 -0
  10. package/dist/lib/node-esm/translations.mjs.map +7 -0
  11. package/dist/types/src/components/Editor/Editor.d.ts +36 -25
  12. package/dist/types/src/components/Editor/Editor.d.ts.map +1 -1
  13. package/dist/types/src/components/Editor/Editor.stories.d.ts +4 -4
  14. package/dist/types/src/components/Editor/Editor.stories.d.ts.map +1 -1
  15. package/dist/types/src/components/{EditorContent/EditorContent.d.ts → Editor/EditorView.d.ts} +5 -5
  16. package/dist/types/src/components/Editor/EditorView.d.ts.map +1 -0
  17. package/dist/types/src/components/Editor/controller.d.ts.map +1 -0
  18. package/dist/types/src/components/EditorMenuProvider/EditorMenuProvider.d.ts +1 -3
  19. package/dist/types/src/components/EditorMenuProvider/EditorMenuProvider.d.ts.map +1 -1
  20. package/dist/types/src/components/EditorMenuProvider/menu-presets.d.ts.map +1 -1
  21. package/dist/types/src/components/EditorMenuProvider/menu.d.ts.map +1 -1
  22. package/dist/types/src/components/EditorMenuProvider/popover.d.ts +2 -1
  23. package/dist/types/src/components/EditorMenuProvider/popover.d.ts.map +1 -1
  24. package/dist/types/src/components/EditorMenuProvider/useEditorMenu.d.ts.map +1 -1
  25. package/dist/types/src/components/EditorPreviewProvider/EditorPreviewProvider.d.ts.map +1 -1
  26. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +2 -2
  27. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
  28. package/dist/types/src/components/EditorToolbar/blocks.d.ts +4 -18
  29. package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
  30. package/dist/types/src/components/EditorToolbar/formatting.d.ts +4 -18
  31. package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
  32. package/dist/types/src/components/EditorToolbar/headings.d.ts +4 -18
  33. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
  34. package/dist/types/src/components/EditorToolbar/image.d.ts +3 -8
  35. package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -1
  36. package/dist/types/src/components/EditorToolbar/index.d.ts +1 -2
  37. package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -1
  38. package/dist/types/src/components/EditorToolbar/lists.d.ts +6 -0
  39. package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -0
  40. package/dist/types/src/components/EditorToolbar/search.d.ts +3 -8
  41. package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -1
  42. package/dist/types/src/components/EditorToolbar/types.d.ts +6 -0
  43. package/dist/types/src/components/EditorToolbar/types.d.ts.map +1 -0
  44. package/dist/types/src/components/EditorToolbar/view-mode.d.ts +5 -19
  45. package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -1
  46. package/dist/types/src/components/index.d.ts +0 -2
  47. package/dist/types/src/components/index.d.ts.map +1 -1
  48. package/dist/types/src/extensions/Assistant.stories.d.ts +10 -0
  49. package/dist/types/src/extensions/Assistant.stories.d.ts.map +1 -0
  50. package/dist/types/src/extensions/assistant-extension.d.ts +24 -0
  51. package/dist/types/src/extensions/assistant-extension.d.ts.map +1 -0
  52. package/dist/types/src/extensions/index.d.ts +2 -0
  53. package/dist/types/src/extensions/index.d.ts.map +1 -0
  54. package/dist/types/src/hooks/index.d.ts +1 -0
  55. package/dist/types/src/hooks/index.d.ts.map +1 -1
  56. package/dist/types/src/hooks/useBasicMarkdownExtensions.d.ts +25 -0
  57. package/dist/types/src/hooks/useBasicMarkdownExtensions.d.ts.map +1 -0
  58. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  59. package/dist/types/src/index.d.ts +1 -2
  60. package/dist/types/src/index.d.ts.map +1 -1
  61. package/dist/types/src/stories/Automerge.stories.d.ts +25 -24
  62. package/dist/types/src/stories/Automerge.stories.d.ts.map +1 -1
  63. package/dist/types/src/stories/Comments.stories.d.ts +2 -2
  64. package/dist/types/src/stories/Comments.stories.d.ts.map +1 -1
  65. package/dist/types/src/stories/EditorToolbar.stories.d.ts +28 -26
  66. package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -1
  67. package/dist/types/src/stories/Experimental.stories.d.ts +3 -3
  68. package/dist/types/src/stories/Experimental.stories.d.ts.map +1 -1
  69. package/dist/types/src/stories/Markdown.stories.d.ts +2 -2
  70. package/dist/types/src/stories/Markdown.stories.d.ts.map +1 -1
  71. package/dist/types/src/stories/Outliner.stories.d.ts +2 -2
  72. package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -1
  73. package/dist/types/src/stories/Popover.stories.d.ts +2 -2
  74. package/dist/types/src/stories/Popover.stories.d.ts.map +1 -1
  75. package/dist/types/src/stories/Preview.stories.d.ts +2 -2
  76. package/dist/types/src/stories/Preview.stories.d.ts.map +1 -1
  77. package/dist/types/src/stories/Tags.stories.d.ts.map +1 -1
  78. package/dist/types/src/stories/TextEditor.stories.d.ts +2 -2
  79. package/dist/types/src/stories/TextEditor.stories.d.ts.map +1 -1
  80. package/dist/types/src/stories/Theme.stories.d.ts.map +1 -1
  81. package/dist/types/src/stories/components/EditorStory.d.ts +4 -4
  82. package/dist/types/src/stories/components/EditorStory.d.ts.map +1 -1
  83. package/dist/types/src/stories/components/util.d.ts +3 -2
  84. package/dist/types/src/stories/components/util.d.ts.map +1 -1
  85. package/dist/types/src/translations.d.ts +24 -24
  86. package/dist/types/src/translations.d.ts.map +1 -1
  87. package/dist/types/src/util/react.d.ts +2 -5
  88. package/dist/types/src/util/react.d.ts.map +1 -1
  89. package/dist/types/tsconfig.tsbuildinfo +1 -1
  90. package/package.json +59 -50
  91. package/src/components/Editor/Editor.stories.tsx +15 -21
  92. package/src/components/Editor/Editor.tsx +54 -53
  93. package/src/components/Editor/EditorView.tsx +102 -0
  94. package/src/components/EditorMenuProvider/EditorMenuProvider.tsx +17 -18
  95. package/src/components/EditorMenuProvider/menu-presets.ts +1 -0
  96. package/src/components/EditorMenuProvider/popover.ts +3 -1
  97. package/src/components/EditorMenuProvider/useEditorMenu.ts +8 -1
  98. package/src/components/EditorPreviewProvider/EditorPreviewProvider.tsx +1 -1
  99. package/src/components/EditorToolbar/EditorToolbar.tsx +31 -65
  100. package/src/components/EditorToolbar/blocks.ts +54 -46
  101. package/src/components/EditorToolbar/formatting.ts +44 -45
  102. package/src/components/EditorToolbar/headings.ts +44 -50
  103. package/src/components/EditorToolbar/image.ts +16 -21
  104. package/src/components/EditorToolbar/index.ts +2 -3
  105. package/src/components/EditorToolbar/lists.ts +58 -0
  106. package/src/components/EditorToolbar/search.ts +16 -21
  107. package/src/components/EditorToolbar/types.ts +8 -0
  108. package/src/components/EditorToolbar/view-mode.ts +37 -43
  109. package/src/components/index.ts +0 -3
  110. package/src/extensions/Assistant.stories.tsx +112 -0
  111. package/src/extensions/assistant-extension.tsx +223 -0
  112. package/src/extensions/index.ts +5 -0
  113. package/src/hooks/index.ts +1 -0
  114. package/src/hooks/useBasicMarkdownExtensions.ts +55 -0
  115. package/src/index.ts +1 -4
  116. package/src/stories/Automerge.stories.tsx +12 -13
  117. package/src/stories/Comments.stories.tsx +6 -6
  118. package/src/stories/EditorToolbar.stories.tsx +37 -65
  119. package/src/stories/Experimental.stories.tsx +12 -12
  120. package/src/stories/Markdown.stories.tsx +2 -2
  121. package/src/stories/Outliner.stories.tsx +4 -5
  122. package/src/stories/Popover.stories.tsx +9 -10
  123. package/src/stories/Preview.stories.tsx +49 -41
  124. package/src/stories/Tags.stories.tsx +5 -5
  125. package/src/stories/TextEditor.stories.tsx +2 -2
  126. package/src/stories/Theme.stories.tsx +4 -4
  127. package/src/stories/components/EditorStory.tsx +19 -12
  128. package/src/stories/components/util.tsx +49 -50
  129. package/src/translations.ts +29 -24
  130. package/src/util/react.tsx +3 -12
  131. package/dist/types/src/components/EditorContent/EditorContent.d.ts.map +0 -1
  132. package/dist/types/src/components/EditorContent/controller.d.ts.map +0 -1
  133. package/dist/types/src/components/EditorContent/index.d.ts +0 -3
  134. package/dist/types/src/components/EditorContent/index.d.ts.map +0 -1
  135. package/dist/types/src/components/EditorToolbar/actions.d.ts +0 -24
  136. package/dist/types/src/components/EditorToolbar/actions.d.ts.map +0 -1
  137. package/dist/types/src/components/EditorToolbar/useEditorToolbar.d.ts +0 -11
  138. package/dist/types/src/components/EditorToolbar/useEditorToolbar.d.ts.map +0 -1
  139. package/dist/types/src/stories/CommandDialog.stories.d.ts +0 -14
  140. package/dist/types/src/stories/CommandDialog.stories.d.ts.map +0 -1
  141. package/src/components/EditorContent/EditorContent.tsx +0 -83
  142. package/src/components/EditorContent/index.ts +0 -6
  143. package/src/components/EditorToolbar/actions.ts +0 -87
  144. package/src/components/EditorToolbar/useEditorToolbar.ts +0 -20
  145. package/src/stories/CommandDialog.stories.tsx +0 -81
  146. /package/dist/types/src/components/{EditorContent → Editor}/controller.d.ts +0 -0
  147. /package/src/components/{EditorContent → Editor}/controller.ts +0 -0
@@ -12,7 +12,7 @@ import { PublicKey } from '@dxos/keys';
12
12
  import { log } from '@dxos/log';
13
13
  import { useMergeRefs, useThemeContext } from '@dxos/react-ui';
14
14
  import { useAttentionAttributes } from '@dxos/react-ui-attention';
15
- import { JsonFilter } from '@dxos/react-ui-syntax-highlighter';
15
+ import { Syntax } from '@dxos/react-ui-syntax-highlighter';
16
16
  import {
17
17
  type DebugNode,
18
18
  type ThemeExtensionsOptions,
@@ -20,8 +20,7 @@ import {
20
20
  createMarkdownExtensions,
21
21
  createThemeExtensions,
22
22
  debugTree,
23
- decorateMarkdown,
24
- editorSlots,
23
+ documentSlots,
25
24
  } from '@dxos/ui-editor';
26
25
  import { mx } from '@dxos/ui-theme';
27
26
  import { isNonNullable } from '@dxos/util';
@@ -34,12 +33,12 @@ export type DebugMode = 'raw' | 'tree' | 'raw+tree';
34
33
 
35
34
  const defaultId = 'editor-' + PublicKey.random().toHex().slice(0, 8);
36
35
 
37
- export type StoryProps = Pick<UseTextEditorProps, 'id' | 'scrollTo' | 'selection' | 'extensions'> &
36
+ export type EditorStoryProps = Pick<UseTextEditorProps, 'id' | 'scrollTo' | 'selection' | 'extensions'> &
38
37
  Pick<ThemeExtensionsOptions, 'slots'> & {
39
38
  debug?: DebugMode;
40
39
  debugCustom?: (view: EditorView) => ReactNode;
41
40
  text?: string;
42
- object?: Obj.Obj<TestSchema.Expando>;
41
+ object?: Obj.OfShape<TestSchema.Expando>;
43
42
  readOnly?: boolean;
44
43
  placeholder?: string;
45
44
  lineNumbers?: boolean;
@@ -47,7 +46,7 @@ export type StoryProps = Pick<UseTextEditorProps, 'id' | 'scrollTo' | 'selection
47
46
  onReady?: (view: EditorView) => void;
48
47
  };
49
48
 
50
- export const EditorStory = forwardRef<EditorController, StoryProps>(
49
+ export const EditorStory = forwardRef<EditorController, EditorStoryProps>(
51
50
  ({ debug, debugCustom, text, extensions: extensionsProp, ...props }, forwardedRef) => {
52
51
  const controllerRef = useRef<EditorController>(null);
53
52
  const mergedRef = useMergeRefs([controllerRef, forwardedRef]);
@@ -63,12 +62,12 @@ export const EditorStory = forwardRef<EditorController, StoryProps>(
63
62
 
64
63
  const view = controllerRef.current?.view;
65
64
  return (
66
- <div className={mx('is-full bs-full grid overflow-hidden', debug && 'grid-cols-2 lg:grid-cols-[1fr_600px]')}>
65
+ <div className={mx('dx-container grid', debug && 'grid-cols-2 lg:grid-cols-[1fr_600px]')}>
67
66
  <EditorComponent ref={mergedRef} object={object} text={text} extensions={extensions} {...props} />
68
67
 
69
68
  {debug && (
70
69
  <div
71
- className='grid bs-full auto-rows-fr border-l border-separator divide-y divide-separator overflow-hidden'
70
+ className='grid h-full auto-rows-fr border-l border-separator divide-y divide-separator overflow-hidden'
72
71
  {...attentionAttrs}
73
72
  >
74
73
  {view && debugCustom?.(view)}
@@ -77,7 +76,16 @@ export const EditorStory = forwardRef<EditorController, StoryProps>(
77
76
  {view?.state.doc.toString()}
78
77
  </pre>
79
78
  )}
80
- {(debug === 'tree' || debug === 'raw+tree') && <JsonFilter data={tree} classNames='p-1 text-xs' />}
79
+ {(debug === 'tree' || debug === 'raw+tree') && (
80
+ <Syntax.Root data={tree}>
81
+ <Syntax.Content>
82
+ <Syntax.Filter />
83
+ <Syntax.Viewport>
84
+ <Syntax.Code classNames='p-1 text-xs' />
85
+ </Syntax.Viewport>
86
+ </Syntax.Content>
87
+ </Syntax.Root>
88
+ )}
81
89
  </div>
82
90
  )}
83
91
  </div>
@@ -88,7 +96,7 @@ export const EditorStory = forwardRef<EditorController, StoryProps>(
88
96
  /**
89
97
  * Default story component.
90
98
  */
91
- const EditorComponent = forwardRef<EditorController, StoryProps>(
99
+ const EditorComponent = forwardRef<EditorController, EditorStoryProps>(
92
100
  (
93
101
  {
94
102
  id = defaultId,
@@ -101,7 +109,7 @@ const EditorComponent = forwardRef<EditorController, StoryProps>(
101
109
  scrollTo,
102
110
  selection,
103
111
  extensions,
104
- slots = editorSlots,
112
+ slots = documentSlots,
105
113
  onReady,
106
114
  },
107
115
  forwardedRef,
@@ -119,7 +127,6 @@ const EditorComponent = forwardRef<EditorController, StoryProps>(
119
127
  createBasicExtensions({ readOnly, placeholder, lineNumbers, scrollPastEnd: true, search: true }),
120
128
  createThemeExtensions({ monospace, themeMode, syntaxHighlighting: true, slots }),
121
129
  createMarkdownExtensions(),
122
- decorateMarkdown(),
123
130
  extensions || [],
124
131
  ],
125
132
  }),
@@ -4,10 +4,9 @@
4
4
 
5
5
  import { type Completion } from '@codemirror/autocomplete';
6
6
  import { type Extension } from '@codemirror/state';
7
- import React, { type FC } from 'react';
8
7
 
9
- import { faker } from '@dxos/random';
10
- import { Icon } from '@dxos/react-ui';
8
+ import { random } from '@dxos/random';
9
+ import { Domino } from '@dxos/ui';
11
10
  import {
12
11
  type EditorSelectionState,
13
12
  decorateMarkdown,
@@ -17,11 +16,12 @@ import {
17
16
  linkTooltip,
18
17
  table,
19
18
  } from '@dxos/ui-editor';
20
- import { mx } from '@dxos/ui-theme';
19
+ import { type RenderCallback } from '@dxos/ui-editor/types';
20
+ import { safeUrl } from '@dxos/util';
21
21
 
22
- import { createRenderer, str } from '../../util';
22
+ import { str } from '../../util';
23
23
 
24
- export const num = () => faker.number.int({ min: 0, max: 9999 }).toLocaleString();
24
+ export const num = () => random.number.int({ min: 0, max: 9999 }).toLocaleString();
25
25
 
26
26
  export const img = '![dxos](https://dxos.network/dxos-logotype-blue.png)';
27
27
 
@@ -41,11 +41,11 @@ export const content = {
41
41
  // prettier-ignore
42
42
  '### TaskList',
43
43
  '',
44
- `- [x] ${faker.lorem.sentences()}`,
45
- `- [ ] ${faker.lorem.sentences()}`,
46
- ` - [ ] ${faker.lorem.sentences()}`,
47
- ` - [ ] ${faker.lorem.sentences()}`,
48
- ` - [x] ${faker.lorem.sentences()}`,
44
+ `- [x] ${random.lorem.sentences()}`,
45
+ `- [ ] ${random.lorem.sentences()}`,
46
+ ` - [ ] ${random.lorem.sentences()}`,
47
+ ` - [ ] ${random.lorem.sentences()}`,
48
+ ` - [x] ${random.lorem.sentences()}`,
49
49
  '',
50
50
  ),
51
51
 
@@ -53,11 +53,11 @@ export const content = {
53
53
  // prettier-ignore
54
54
  '### BulletList',
55
55
  '',
56
- `- ${faker.lorem.sentences()}`,
57
- `- ${faker.lorem.sentences()}`,
58
- ` - ${faker.lorem.sentences()}`,
59
- ` - ${faker.lorem.sentences()}`,
60
- `- ${faker.lorem.sentences()}`,
56
+ `- ${random.lorem.sentences()}`,
57
+ `- ${random.lorem.sentences()}`,
58
+ ` - ${random.lorem.sentences()}`,
59
+ ` - ${random.lorem.sentences()}`,
60
+ `- ${random.lorem.sentences()}`,
61
61
  '',
62
62
  ),
63
63
 
@@ -65,17 +65,17 @@ export const content = {
65
65
  // prettier-ignore
66
66
  '### OrderedList (part 1)',
67
67
  '',
68
- `1. ${faker.lorem.sentences()}`,
69
- `1. ${faker.lorem.sentences()}`,
70
- `1. ${faker.lorem.sentences()}`,
71
- ` 1. ${faker.lorem.sentences()}`,
72
- ` 1. ${faker.lorem.sentences()}`,
73
- ` 1. ${faker.lorem.sentences()}`,
74
- `1. ${faker.lorem.sentences()}`,
68
+ `1. ${random.lorem.sentences()}`,
69
+ `1. ${random.lorem.sentences()}`,
70
+ `1. ${random.lorem.sentences()}`,
71
+ ` 1. ${random.lorem.sentences()}`,
72
+ ` 1. ${random.lorem.sentences()}`,
73
+ ` 1. ${random.lorem.sentences()}`,
74
+ `1. ${random.lorem.sentences()}`,
75
75
  '',
76
76
  '### OrderedList (part 2)',
77
77
  '',
78
- `1. ${faker.lorem.sentences()}`,
78
+ `1. ${random.lorem.sentences()}`,
79
79
  '',
80
80
  ),
81
81
 
@@ -123,7 +123,7 @@ export const content = {
123
123
  // prettier-ignore
124
124
  '### Tables',
125
125
  '',
126
- `| ${faker.lorem.word().padStart(12)} | ${faker.lorem.word().padStart(12)} | ${faker.lorem.word().padStart(12)} |`,
126
+ `| ${random.lorem.word().padStart(12)} | ${random.lorem.word().padStart(12)} | ${random.lorem.word().padStart(12)} |`,
127
127
  `|-${''.padStart(12, '-')}-|-${''.padStart(12, '-')}-|-${''.padStart(12, '-')}-|`,
128
128
  `| ${num().padStart(12)} | ${num().padStart(12)} | ${num().padStart(12)} |`,
129
129
  `| ${num().padStart(12)} | ${num().padStart(12)} | ${num().padStart(12)} |`,
@@ -134,7 +134,9 @@ export const content = {
134
134
  image: str('### Image', '', img),
135
135
 
136
136
  headings: str(
137
- ...[1, 2, 3, 4, 5, 6].map((level) => ['#'.repeat(level) + ` Heading ${level}`, faker.lorem.sentences(), '']).flat(),
137
+ ...[1, 2, 3, 4, 5, 6]
138
+ .map((level) => ['#'.repeat(level) + ` Heading ${level}`, random.lorem.sentences(), ''])
139
+ .flat(),
138
140
  ),
139
141
 
140
142
  formatting: str(
@@ -159,7 +161,7 @@ export const content = {
159
161
  '',
160
162
  ),
161
163
 
162
- paragraphs: str(...faker.helpers.multiple(() => [faker.lorem.paragraph(), ''], { count: 3 }).flat()),
164
+ paragraphs: str(...random.helpers.multiple(() => [random.lorem.paragraph(), ''], { count: 3 }).flat()),
163
165
 
164
166
  footer: str('', '', '', '', ''),
165
167
  };
@@ -204,30 +206,27 @@ export const links: Completion[] = [
204
206
  export const names = ['adam', 'alice', 'alison', 'bob', 'carol', 'charlie', 'sayuri', 'shoko'];
205
207
 
206
208
  const hover =
207
- 'rounded-sm text-baseText text-primary-600 hover:text-primary-500 dark:text-primary-300 hover:dark:text-primary-200';
208
-
209
- const LinkTooltip: FC<{ url: string }> = ({ url }) => {
210
- const web = new URL(url);
211
- return (
212
- <a href={url} target='_blank' rel='noreferrer' className={mx(hover, 'flex items-center gap-2')}>
213
- {web.origin}
214
- <Icon icon='ph--arrow-square-out--regular' size={4} />
215
- </a>
209
+ 'rounded-xs text-base-surface-text text-primary-600 hover:text-primary-500 dark:text-primary-300 hover:dark:text-primary-200';
210
+
211
+ export const renderLinkTooltip: RenderCallback<{ url: string }> = (el, { url }) => {
212
+ el.appendChild(
213
+ Domino.of('a')
214
+ .attributes({ href: url, target: '_blank', rel: 'noreferrer', 'aria-label': 'Open link' })
215
+ .classNames(hover, 'flex items-center gap-2')
216
+ .text(safeUrl(url)?.toString() ?? url)
217
+ .append(Domino.svg('ph--arrow-square-out--regular')).root,
216
218
  );
217
219
  };
218
220
 
219
- export const renderLinkTooltip = createRenderer(LinkTooltip);
220
-
221
- const LinkButton: FC<{ url: string }> = ({ url }) => {
222
- return (
223
- <a href={url} target='_blank' rel='noreferrer' className={mx(hover)}>
224
- <Icon icon='ph--arrow-square-out--regular' size={4} classNames='inline-block mis-1 mb-[3px]' />
225
- </a>
221
+ export const renderLinkButton: RenderCallback<{ url: string }> = (el, { url }) => {
222
+ el.appendChild(
223
+ Domino.of('span')
224
+ .attributes({ 'aria-hidden': 'true' })
225
+ .classNames(hover, 'ms-1 inline-block align-[-0.125em]')
226
+ .append(Domino.svg('ph--arrow-square-out--regular')).root,
226
227
  );
227
228
  };
228
229
 
229
- export const renderLinkButton = createRenderer(LinkButton);
230
-
231
230
  // Shared extensions.
232
231
  export const defaultExtensions: Extension[] = [
233
232
  decorateMarkdown({ renderLinkButton, selectionChangeDelay: 100 }),
@@ -245,18 +244,18 @@ export const allExtensions: Extension[] = [
245
244
  ];
246
245
 
247
246
  // Long text for scrolling stories.
248
- export const longText = faker.helpers
249
- .multiple(() => faker.lorem.paragraph({ min: 8, max: 16 }), { count: 20 })
247
+ export const longText = random.helpers
248
+ .multiple(() => random.lorem.paragraph({ min: 8, max: 16 }), { count: 20 })
250
249
  .join('\n\n');
251
250
 
252
- export const largeWithImages = faker.helpers
253
- .multiple(() => [faker.lorem.paragraph({ min: 12, max: 16 }), img], { count: 20 })
251
+ export const largeWithImages = random.helpers
252
+ .multiple(() => [random.lorem.paragraph({ min: 12, max: 16 }), img], { count: 20 })
254
253
  .flatMap((x) => x)
255
254
  .join('\n\n');
256
255
 
257
256
  export const headings = str(
258
257
  ...[1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 2, 3, 3, 2, 2, 6, 1]
259
- .map((level) => ['#'.repeat(level) + ' ' + faker.lorem.sentence(3), faker.lorem.sentences(), ''])
258
+ .map((level) => ['#'.repeat(level) + ' ' + random.lorem.sentence(3), random.lorem.sentences(), ''])
260
259
  .flat(),
261
260
  );
262
261
 
@@ -10,30 +10,35 @@ export const translations = [
10
10
  {
11
11
  'en-US': {
12
12
  [translationKey]: {
13
- 'strong label': 'Bold',
14
- 'emphasis label': 'Italics',
15
- 'strikethrough label': 'Strikethrough',
16
- 'code label': 'Code',
17
- 'link label': 'Link',
18
- 'list-bullet label': 'Bullet list',
19
- 'list-ordered label': 'Numbered list',
20
- 'list-task label': 'Task list',
21
- 'blockquote label': 'Block quote',
22
- 'codeblock label': 'Code block',
23
- 'comment label': 'Create comment',
24
- 'selection overlaps existing comment label': 'Selection overlaps existing comment',
25
- 'select text to comment label': 'Select text to comment',
26
- 'image label': 'Insert image',
27
- 'table label': 'Create table',
28
- 'heading label': 'Heading level',
29
- 'heading level label_zero': 'Paragraph',
30
- 'heading level label_one': 'Heading level {{count}}',
31
- 'heading level label_other': 'Heading level {{count}}',
32
- 'search label': 'Search',
33
- 'view mode label': 'Editor view',
34
- 'preview mode label': 'Markdown',
35
- 'readonly mode label': 'Read only',
36
- 'source mode label': 'Plain text',
13
+ 'comment.label': 'Create comment',
14
+ 'image.label': 'Insert image',
15
+ 'search.label': 'Search',
16
+
17
+ 'block.label': 'Block',
18
+ 'block.blockquote.label': 'Block quote',
19
+ 'block.codeblock.label': 'Code block',
20
+ 'block.table.label': 'Create table',
21
+
22
+ 'formatting.label': 'Formatting',
23
+ 'formatting.strong.label': 'Bold',
24
+ 'formatting.emphasis.label': 'Italics',
25
+ 'formatting.strikethrough.label': 'Strikethrough',
26
+ 'formatting.code.label': 'Code',
27
+ 'formatting.link.label': 'Link',
28
+
29
+ 'list.bullet.label': 'Bullet list',
30
+ 'list.ordered.label': 'Numbered list',
31
+ 'list.task.label': 'Task list',
32
+
33
+ 'heading.label': 'Heading level',
34
+ 'heading-level.label_zero': 'Paragraph',
35
+ 'heading-level.label_one': 'Heading level {{count}}',
36
+ 'heading-level.label_other': 'Heading level {{count}}',
37
+
38
+ 'view-mode.label': 'Editor view',
39
+ 'view-mode.preview.label': 'Markdown',
40
+ 'view-mode.source.label': 'Plain text',
41
+ 'view-mode.readonly.label': 'Read only',
37
42
  },
38
43
  },
39
44
  },
@@ -2,11 +2,11 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import React, { type FC, type ReactNode } from 'react';
5
+ import React, { type FC } from 'react';
6
6
  import { createRoot } from 'react-dom/client';
7
7
 
8
8
  import { ThemeProvider, Tooltip } from '@dxos/react-ui';
9
- import { type RenderCallback } from '@dxos/ui-editor';
9
+ import { type RenderCallback } from '@dxos/ui-editor/types';
10
10
  import { defaultTx } from '@dxos/ui-theme';
11
11
 
12
12
  /**
@@ -14,22 +14,13 @@ import { defaultTx } from '@dxos/ui-theme';
14
14
  */
15
15
  export const str = (...lines: string[]) => lines.join('\n');
16
16
 
17
- /** @deprecated */
18
- // TODO(wittjosiah): Replace with portals which are lighter weight and inherit context from the main react tree.
19
- export const renderRoot = <T extends Element>(root: T, node: ReactNode): T => {
20
- createRoot(root).render(<ThemeProvider tx={defaultTx}>{node}</ThemeProvider>);
21
- return root;
22
- };
23
-
24
17
  /**
25
- * Utility to create a renderer for a React component.
26
18
  * @deprecated
27
19
  */
28
20
  export const createRenderer =
29
21
  <TProps extends object>(Component: FC<TProps>): RenderCallback<TProps> =>
30
22
  (el, props) => {
31
- renderRoot(
32
- el,
23
+ createRoot(el).render(
33
24
  <ThemeProvider tx={defaultTx}>
34
25
  <Tooltip.Provider>
35
26
  <Component {...props} />
@@ -1 +0,0 @@
1
- {"version":3,"file":"EditorContent.d.ts","sourceRoot":"","sources":["../../../../../src/components/EditorContent/EditorContent.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAqD,MAAM,OAAO,CAAC;AAE1E,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAItD,OAAO,EAAE,KAAK,kBAAkB,EAAiB,MAAM,aAAa,CAAC;AAErE,OAAO,EAAE,KAAK,gBAAgB,EAA0B,MAAM,cAAc,CAAC;AAE7E,MAAM,MAAM,kBAAkB,GAAG,eAAe,CAC9C;IACE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC,GAAG,kBAAkB,CACvB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa;gBAXV,OAAO;YACX,MAAM;eACH,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;;;;;;;;;;;;0CA8DrC,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../../src/components/EditorContent/controller.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,IAAI,IAAI,UAAU,GAAG,IAAI,CAAC;IAC9B,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,eAAO,MAAM,cAAc,EAAE,gBAO5B,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,MAAM,UAAU,GAAG,IAAI,KAAG,gBA2BhE,CAAC"}
@@ -1,3 +0,0 @@
1
- export * from './controller';
2
- export * from './EditorContent';
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/EditorContent/index.ts"],"names":[],"mappings":"AAIA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC"}
@@ -1,24 +0,0 @@
1
- import { type EditorView } from '@codemirror/view';
2
- import { type Node } from '@dxos/app-graph';
3
- import { type MenuItemGroup, type ToolbarMenuActionGroupProperties } from '@dxos/react-ui-menu';
4
- import { type MenuActionProperties } from '@dxos/ui-types';
5
- import { type EditorToolbarState } from './useEditorToolbar';
6
- export declare const createLists: (state: EditorToolbarState, getView: () => EditorView) => {
7
- nodes: (Node.NodeArg<any, Record<string, any>> | Readonly<Omit<Readonly<{
8
- id: string;
9
- type: string;
10
- cacheable?: string[];
11
- properties: Readonly<MenuActionProperties>;
12
- data: Node.ActionData<never>;
13
- }>, "properties"> & {
14
- properties: Readonly<MenuActionProperties>;
15
- _actionContext?: Node.ActionContext;
16
- }>)[];
17
- edges: {
18
- source: string;
19
- target: string;
20
- }[];
21
- };
22
- export declare const createEditorAction: (id: string, props: Partial<MenuActionProperties>, invoke: () => void) => Node.Action<MenuActionProperties>;
23
- export declare const createEditorActionGroup: (id: string, props: Omit<ToolbarMenuActionGroupProperties, "icon">, icon?: string) => MenuItemGroup<ToolbarMenuActionGroupProperties>;
24
- //# sourceMappingURL=actions.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../../../src/components/EditorToolbar/actions.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,gCAAgC,EAGtC,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAI3D,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAQ7D,eAAO,MAAM,WAAW,GAAI,OAAO,kBAAkB,EAAE,SAAS,MAAM,UAAU;;;;;;;;;;;;;;;CAW/E,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,IAAI,MAAM,EAAE,OAAO,OAAO,CAAC,oBAAoB,CAAC,EAAE,QAAQ,MAAM,IAAI,KAM/F,IAAI,CAAC,MAAM,CAAC,oBAAoB,CACvC,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,IAAI,MAAM,EACV,OAAO,IAAI,CAAC,gCAAgC,EAAE,MAAM,CAAC,EACrD,OAAO,MAAM,KACZ,aAAa,CAAC,gCAAgC,CAShD,CAAC"}
@@ -1,11 +0,0 @@
1
- import { Atom } from '@effect-atom/atom-react';
2
- import { type EditorViewMode, type Formatting } from '@dxos/ui-editor';
3
- export type EditorToolbarState = {
4
- viewMode?: EditorViewMode;
5
- } & Formatting;
6
- /**
7
- * Creates an atom for editor toolbar state.
8
- * @deprecated Use Editor.Root
9
- */
10
- export declare const useEditorToolbar: (initialState?: EditorToolbarState) => Atom.Writable<EditorToolbarState>;
11
- //# sourceMappingURL=useEditorToolbar.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useEditorToolbar.d.ts","sourceRoot":"","sources":["../../../../../src/components/EditorToolbar/useEditorToolbar.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAG/C,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGvE,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,CAAC,EAAE,cAAc,CAAA;CAAE,GAAG,UAAU,CAAC;AAE5E;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,eAAc,kBAAuB,KAAG,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAGxG,CAAC"}
@@ -1,14 +0,0 @@
1
- import { type StoryObj } from '@storybook/react-vite';
2
- import React from 'react';
3
- declare const meta: {
4
- title: string;
5
- render: () => React.JSX.Element;
6
- decorators: import("@storybook/react").Decorator[];
7
- parameters: {
8
- layout: string;
9
- };
10
- };
11
- export default meta;
12
- type Story = StoryObj<typeof meta>;
13
- export declare const Default: Story;
14
- //# sourceMappingURL=CommandDialog.stories.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CommandDialog.stories.d.ts","sourceRoot":"","sources":["../../../../src/stories/CommandDialog.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAuC,MAAM,OAAO,CAAC;AA8D5D,QAAA,MAAM,IAAI;;;;;;;CAOqB,CAAC;AAEhC,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC"}
@@ -1,83 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { Transaction } from '@codemirror/state';
6
- import { EditorView } from '@codemirror/view';
7
- import React, { forwardRef, useEffect, useImperativeHandle } from 'react';
8
-
9
- import { type ThemedClassName } from '@dxos/react-ui';
10
- import { initialSync } from '@dxos/ui-editor';
11
- import { mx } from '@dxos/ui-theme';
12
-
13
- import { type UseTextEditorProps, useTextEditor } from '../../hooks';
14
-
15
- import { type EditorController, createEditorController } from './controller';
16
-
17
- export type EditorContentProps = ThemedClassName<
18
- {
19
- focusable?: boolean;
20
- value?: string;
21
- onChange?: (value: string) => void;
22
- } & UseTextEditorProps
23
- >;
24
-
25
- /**
26
- * Minimal text editor.
27
- * NOTE: This shouold not be used with the automerge extension.
28
- * @deprecated Use Editor.Content
29
- */
30
- export const EditorContent = forwardRef<EditorController, EditorContentProps>(
31
- ({ classNames, id, extensions, selectionEnd, focusable = true, value, onChange, ...props }, forwardedRef) => {
32
- const { parentRef, focusAttributes, view } = useTextEditor(
33
- () => ({
34
- id,
35
- initialValue: value,
36
- selectionEnd,
37
- extensions: [
38
- extensions ?? [],
39
- EditorView.updateListener.of(({ view, docChanged, transactions }) => {
40
- const isInitialSync = transactions.some((tr) => tr.annotation(Transaction.userEvent) === initialSync.value);
41
- if (!isInitialSync && docChanged) {
42
- onChange?.(view.state.doc.toString());
43
- }
44
- }),
45
- ],
46
- ...props,
47
- }),
48
- [id, extensions, selectionEnd, onChange],
49
- );
50
-
51
- // External controller.
52
- useImperativeHandle(forwardedRef, () => {
53
- return createEditorController(view);
54
- }, [id, view]);
55
-
56
- // Set initial value and cursor position.
57
- useEffect(() => {
58
- requestAnimationFrame(() => {
59
- view?.dispatch({
60
- annotations: initialSync,
61
- changes: value ? [{ from: 0, to: view?.state.doc.length ?? 0, insert: value ?? '' }] : [],
62
- selection: selectionEnd ? { anchor: view?.state.doc.length ?? 0 } : undefined,
63
- });
64
-
65
- if (selectionEnd) {
66
- view?.focus();
67
- }
68
- });
69
- }, [view, value, selectionEnd]);
70
-
71
- return (
72
- <div
73
- role='none'
74
- className={mx(
75
- 'is-full outline-none focus:border-accentSurface focus-within:border-neutralFocusIndicator',
76
- classNames,
77
- )}
78
- ref={parentRef}
79
- {...(focusable ? focusAttributes : {})}
80
- />
81
- );
82
- },
83
- );
@@ -1,6 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- export * from './controller';
6
- export * from './EditorContent';
@@ -1,87 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { type EditorView } from '@codemirror/view';
6
-
7
- import { type Node } from '@dxos/app-graph';
8
- import {
9
- type MenuItemGroup,
10
- type ToolbarMenuActionGroupProperties,
11
- createMenuAction,
12
- createMenuItemGroup,
13
- } from '@dxos/react-ui-menu';
14
- import { List, addList, removeList } from '@dxos/ui-editor';
15
- import { type MenuActionProperties } from '@dxos/ui-types';
16
-
17
- import { translationKey } from '../../translations';
18
-
19
- import { type EditorToolbarState } from './useEditorToolbar';
20
-
21
- const listStyles = {
22
- bullet: 'ph--list-bullets--regular',
23
- ordered: 'ph--list-numbers--regular',
24
- task: 'ph--list-checks--regular',
25
- };
26
-
27
- export const createLists = (state: EditorToolbarState, getView: () => EditorView) => {
28
- const value = state.listStyle ?? '';
29
- const listGroupAction = createListGroupAction(value);
30
- const listActionsMap = createListActions(value, getView);
31
- return {
32
- nodes: [listGroupAction as Node.NodeArg<any>, ...listActionsMap],
33
- edges: [
34
- { source: 'root', target: 'list' },
35
- ...listActionsMap.map(({ id }) => ({ source: listGroupAction.id, target: id })),
36
- ],
37
- };
38
- };
39
-
40
- export const createEditorAction = (id: string, props: Partial<MenuActionProperties>, invoke: () => void) => {
41
- const { label = [`${id} label`, { ns: translationKey }], ...rest } = props;
42
-
43
- return createMenuAction(id, invoke, {
44
- label,
45
- ...rest,
46
- }) as Node.Action<MenuActionProperties>;
47
- };
48
-
49
- export const createEditorActionGroup = (
50
- id: string,
51
- props: Omit<ToolbarMenuActionGroupProperties, 'icon'>,
52
- icon?: string,
53
- ): MenuItemGroup<ToolbarMenuActionGroupProperties> => {
54
- const { label = [`${id} label`, { ns: translationKey }], ...rest } = props;
55
-
56
- return createMenuItemGroup(id, {
57
- label,
58
- icon,
59
- iconOnly: true,
60
- ...rest,
61
- }) as MenuItemGroup<ToolbarMenuActionGroupProperties>;
62
- };
63
-
64
- const createListGroupAction = (value: string) =>
65
- createEditorActionGroup('list', {
66
- variant: 'toggleGroup',
67
- selectCardinality: 'single',
68
- value,
69
- } as ToolbarMenuActionGroupProperties);
70
-
71
- const createListActions = (value: string, getView: () => EditorView) =>
72
- Object.entries(listStyles).map(([listStyle, icon]) => {
73
- const checked = value === listStyle;
74
- return createEditorAction(`list-${listStyle}`, { checked, icon }, () => {
75
- const view = getView();
76
- if (!view) {
77
- return;
78
- }
79
-
80
- const listType = listStyle === 'ordered' ? List.Ordered : listStyle === 'bullet' ? List.Bullet : List.Task;
81
- if (checked) {
82
- removeList(listType)(view);
83
- } else {
84
- addList(listType)(view);
85
- }
86
- });
87
- });