@dxos/react-ui-editor 0.8.4-main.8360d9e660 → 0.8.4-main.8baae0fced

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 (146) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/browser/index.mjs +753 -729
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/translations.mjs +39 -0
  7. package/dist/lib/browser/translations.mjs.map +7 -0
  8. package/dist/lib/node-esm/index.mjs +753 -729
  9. package/dist/lib/node-esm/index.mjs.map +4 -4
  10. package/dist/lib/node-esm/meta.json +1 -1
  11. package/dist/lib/node-esm/translations.mjs +41 -0
  12. package/dist/lib/node-esm/translations.mjs.map +7 -0
  13. package/dist/types/src/components/Editor/Editor.d.ts +36 -25
  14. package/dist/types/src/components/Editor/Editor.d.ts.map +1 -1
  15. package/dist/types/src/components/Editor/Editor.stories.d.ts +4 -4
  16. package/dist/types/src/components/Editor/Editor.stories.d.ts.map +1 -1
  17. package/dist/types/src/components/{EditorContent/EditorContent.d.ts → Editor/EditorView.d.ts} +5 -5
  18. package/dist/types/src/components/Editor/EditorView.d.ts.map +1 -0
  19. package/dist/types/src/components/Editor/controller.d.ts.map +1 -0
  20. package/dist/types/src/components/EditorMenuProvider/EditorMenuProvider.d.ts +1 -3
  21. package/dist/types/src/components/EditorMenuProvider/EditorMenuProvider.d.ts.map +1 -1
  22. package/dist/types/src/components/EditorMenuProvider/menu-presets.d.ts.map +1 -1
  23. package/dist/types/src/components/EditorMenuProvider/menu.d.ts.map +1 -1
  24. package/dist/types/src/components/EditorMenuProvider/popover.d.ts +2 -1
  25. package/dist/types/src/components/EditorMenuProvider/popover.d.ts.map +1 -1
  26. package/dist/types/src/components/EditorMenuProvider/useEditorMenu.d.ts.map +1 -1
  27. package/dist/types/src/components/EditorPreviewProvider/EditorPreviewProvider.d.ts.map +1 -1
  28. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +2 -2
  29. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
  30. package/dist/types/src/components/EditorToolbar/blocks.d.ts +4 -19
  31. package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
  32. package/dist/types/src/components/EditorToolbar/formatting.d.ts +4 -19
  33. package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
  34. package/dist/types/src/components/EditorToolbar/headings.d.ts +4 -19
  35. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
  36. package/dist/types/src/components/EditorToolbar/image.d.ts +3 -9
  37. package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -1
  38. package/dist/types/src/components/EditorToolbar/index.d.ts +1 -2
  39. package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -1
  40. package/dist/types/src/components/EditorToolbar/lists.d.ts +6 -0
  41. package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -0
  42. package/dist/types/src/components/EditorToolbar/search.d.ts +3 -9
  43. package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -1
  44. package/dist/types/src/components/EditorToolbar/types.d.ts +6 -0
  45. package/dist/types/src/components/EditorToolbar/types.d.ts.map +1 -0
  46. package/dist/types/src/components/EditorToolbar/view-mode.d.ts +5 -20
  47. package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -1
  48. package/dist/types/src/components/index.d.ts +0 -2
  49. package/dist/types/src/components/index.d.ts.map +1 -1
  50. package/dist/types/src/extensions/Assistant.stories.d.ts +10 -0
  51. package/dist/types/src/extensions/Assistant.stories.d.ts.map +1 -0
  52. package/dist/types/src/extensions/assistant-extension.d.ts +24 -0
  53. package/dist/types/src/extensions/assistant-extension.d.ts.map +1 -0
  54. package/dist/types/src/extensions/index.d.ts +2 -0
  55. package/dist/types/src/extensions/index.d.ts.map +1 -0
  56. package/dist/types/src/hooks/index.d.ts +1 -0
  57. package/dist/types/src/hooks/index.d.ts.map +1 -1
  58. package/dist/types/src/hooks/useBasicMarkdownExtensions.d.ts +25 -0
  59. package/dist/types/src/hooks/useBasicMarkdownExtensions.d.ts.map +1 -0
  60. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  61. package/dist/types/src/index.d.ts +1 -2
  62. package/dist/types/src/index.d.ts.map +1 -1
  63. package/dist/types/src/stories/Automerge.stories.d.ts +24 -24
  64. package/dist/types/src/stories/Automerge.stories.d.ts.map +1 -1
  65. package/dist/types/src/stories/Comments.stories.d.ts +1 -1
  66. package/dist/types/src/stories/Comments.stories.d.ts.map +1 -1
  67. package/dist/types/src/stories/EditorToolbar.stories.d.ts +28 -26
  68. package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -1
  69. package/dist/types/src/stories/Experimental.stories.d.ts +2 -2
  70. package/dist/types/src/stories/Experimental.stories.d.ts.map +1 -1
  71. package/dist/types/src/stories/Markdown.stories.d.ts +1 -1
  72. package/dist/types/src/stories/Markdown.stories.d.ts.map +1 -1
  73. package/dist/types/src/stories/Outliner.stories.d.ts +2 -2
  74. package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -1
  75. package/dist/types/src/stories/Popover.stories.d.ts +2 -2
  76. package/dist/types/src/stories/Popover.stories.d.ts.map +1 -1
  77. package/dist/types/src/stories/Preview.stories.d.ts +1 -1
  78. package/dist/types/src/stories/Preview.stories.d.ts.map +1 -1
  79. package/dist/types/src/stories/Tags.stories.d.ts.map +1 -1
  80. package/dist/types/src/stories/TextEditor.stories.d.ts +1 -1
  81. package/dist/types/src/stories/TextEditor.stories.d.ts.map +1 -1
  82. package/dist/types/src/stories/Theme.stories.d.ts.map +1 -1
  83. package/dist/types/src/stories/components/EditorStory.d.ts +2 -2
  84. package/dist/types/src/stories/components/EditorStory.d.ts.map +1 -1
  85. package/dist/types/src/stories/components/util.d.ts +2 -1
  86. package/dist/types/src/stories/components/util.d.ts.map +1 -1
  87. package/dist/types/src/translations.d.ts +24 -24
  88. package/dist/types/src/translations.d.ts.map +1 -1
  89. package/dist/types/src/util/react.d.ts +1 -1
  90. package/dist/types/src/util/react.d.ts.map +1 -1
  91. package/dist/types/tsconfig.tsbuildinfo +1 -1
  92. package/package.json +58 -49
  93. package/src/components/Editor/Editor.stories.tsx +15 -21
  94. package/src/components/Editor/Editor.tsx +54 -53
  95. package/src/components/Editor/EditorView.tsx +102 -0
  96. package/src/components/EditorMenuProvider/EditorMenuProvider.tsx +3 -5
  97. package/src/components/EditorMenuProvider/menu-presets.ts +1 -0
  98. package/src/components/EditorMenuProvider/popover.ts +3 -1
  99. package/src/components/EditorMenuProvider/useEditorMenu.ts +2 -1
  100. package/src/components/EditorPreviewProvider/EditorPreviewProvider.tsx +1 -1
  101. package/src/components/EditorToolbar/EditorToolbar.tsx +28 -47
  102. package/src/components/EditorToolbar/blocks.ts +54 -46
  103. package/src/components/EditorToolbar/formatting.ts +44 -45
  104. package/src/components/EditorToolbar/headings.ts +44 -50
  105. package/src/components/EditorToolbar/image.ts +16 -21
  106. package/src/components/EditorToolbar/index.ts +2 -3
  107. package/src/components/EditorToolbar/lists.ts +58 -0
  108. package/src/components/EditorToolbar/search.ts +16 -21
  109. package/src/components/EditorToolbar/types.ts +8 -0
  110. package/src/components/EditorToolbar/view-mode.ts +37 -43
  111. package/src/components/index.ts +0 -3
  112. package/src/extensions/Assistant.stories.tsx +112 -0
  113. package/src/extensions/assistant-extension.tsx +223 -0
  114. package/src/extensions/index.ts +5 -0
  115. package/src/hooks/index.ts +1 -0
  116. package/src/hooks/useBasicMarkdownExtensions.ts +55 -0
  117. package/src/index.ts +1 -4
  118. package/src/stories/Automerge.stories.tsx +10 -6
  119. package/src/stories/Comments.stories.tsx +2 -2
  120. package/src/stories/EditorToolbar.stories.tsx +36 -64
  121. package/src/stories/Experimental.stories.tsx +10 -10
  122. package/src/stories/Outliner.stories.tsx +3 -4
  123. package/src/stories/Popover.stories.tsx +6 -7
  124. package/src/stories/Preview.stories.tsx +4 -5
  125. package/src/stories/Theme.stories.tsx +2 -2
  126. package/src/stories/components/EditorStory.tsx +17 -8
  127. package/src/stories/components/util.tsx +38 -36
  128. package/src/translations.ts +29 -24
  129. package/src/util/react.tsx +1 -1
  130. package/dist/types/src/components/EditorContent/EditorContent.d.ts.map +0 -1
  131. package/dist/types/src/components/EditorContent/controller.d.ts.map +0 -1
  132. package/dist/types/src/components/EditorContent/index.d.ts +0 -3
  133. package/dist/types/src/components/EditorContent/index.d.ts.map +0 -1
  134. package/dist/types/src/components/EditorToolbar/actions.d.ts +0 -25
  135. package/dist/types/src/components/EditorToolbar/actions.d.ts.map +0 -1
  136. package/dist/types/src/components/EditorToolbar/useEditorToolbar.d.ts +0 -11
  137. package/dist/types/src/components/EditorToolbar/useEditorToolbar.d.ts.map +0 -1
  138. package/dist/types/src/stories/CommandDialog.stories.d.ts +0 -14
  139. package/dist/types/src/stories/CommandDialog.stories.d.ts.map +0 -1
  140. package/src/components/EditorContent/EditorContent.tsx +0 -83
  141. package/src/components/EditorContent/index.ts +0 -6
  142. package/src/components/EditorToolbar/actions.ts +0 -87
  143. package/src/components/EditorToolbar/useEditorToolbar.ts +0 -20
  144. package/src/stories/CommandDialog.stories.tsx +0 -81
  145. /package/dist/types/src/components/{EditorContent → Editor}/controller.d.ts +0 -0
  146. /package/src/components/{EditorContent → Editor}/controller.ts +0 -0
@@ -2,96 +2,68 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { RegistryContext, useAtomValue } from '@effect-atom/atom-react';
6
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
7
- import React, { useCallback, useContext, useState } from 'react';
6
+ import React, { useMemo } from 'react';
8
7
 
9
- import { invariant } from '@dxos/invariant';
10
8
  import { useThemeContext } from '@dxos/react-ui';
11
9
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
12
10
  import { withRegistry } from '@dxos/storybook-utils';
13
11
  import {
14
- type EditorInputMode,
15
- type EditorViewMode,
16
- InputModeExtensions,
17
12
  createBasicExtensions,
18
13
  createMarkdownExtensions,
19
14
  createThemeExtensions,
20
15
  decorateMarkdown,
21
- editorWidth,
16
+ documentSlots,
22
17
  formattingKeymap,
23
- formattingListener,
24
18
  } from '@dxos/ui-editor';
25
- import { mx } from '@dxos/ui-theme';
19
+ import { type EditorViewMode } from '@dxos/ui-editor/types';
26
20
 
27
- import { EditorToolbar, type EditorToolbarState, useEditorToolbar } from '../components';
28
- import { type UseTextEditorProps, useTextEditor } from '../hooks';
29
- import { translations } from '../translations';
21
+ import { translations } from '#translations';
30
22
 
31
- type StoryProps = { placeholder?: string } & UseTextEditorProps;
23
+ import { Editor } from '../components';
24
+ import { type UseTextEditorProps } from '../hooks';
32
25
 
33
- const DefaultStory = ({ autoFocus, initialValue, placeholder }: StoryProps) => {
34
- const { themeMode } = useThemeContext();
35
- const registry = useContext(RegistryContext);
36
-
37
- const toolbarState = useEditorToolbar({ viewMode: 'source' });
38
- const { viewMode } = useAtomValue(toolbarState);
39
-
40
- const updateToolbarState = useCallback(
41
- (formatting: EditorToolbarState) => {
42
- registry.update(toolbarState, (state) => ({ ...state, ...formatting }));
43
- },
44
- [registry, toolbarState],
45
- );
26
+ type DefaultStoryProps = { placeholder?: string; viewMode?: EditorViewMode } & UseTextEditorProps;
46
27
 
47
- // TODO(wittjosiah): Provide way to change the input mode.
48
- const [editorInputMode, _setEditorInputMode] = useState<EditorInputMode>('default');
49
- const { parentRef, view } = useTextEditor(
50
- () => ({
51
- autoFocus,
52
- initialValue,
53
- selectionEnd: true,
54
- extensions: [
55
- editorInputMode ? InputModeExtensions[editorInputMode] : [],
56
- createBasicExtensions({ placeholder, lineWrapping: true, readOnly: viewMode === 'readonly', search: true }),
57
- createMarkdownExtensions(),
58
- createThemeExtensions({ themeMode, syntaxHighlighting: true }),
59
- viewMode === 'source' ? [] : decorateMarkdown(),
60
- formattingKeymap(),
61
- formattingListener(updateToolbarState),
62
- ],
63
- }),
64
- [editorInputMode, viewMode, themeMode, placeholder],
65
- );
66
-
67
- const getView = useCallback(() => {
68
- invariant(view);
69
- return view;
70
- }, [view]);
28
+ const DefaultStory = ({ autoFocus, initialValue, placeholder, viewMode = 'source' }: DefaultStoryProps) => {
29
+ const { themeMode } = useThemeContext();
71
30
 
72
- const handleViewModeChange = useCallback(
73
- (mode: EditorViewMode) => {
74
- registry.update(toolbarState, (state) => ({ ...state, viewMode: mode }));
75
- },
76
- [registry, toolbarState],
31
+ const extensions = useMemo(
32
+ () => [
33
+ createBasicExtensions({
34
+ placeholder,
35
+ lineWrapping: true,
36
+ readOnly: viewMode === 'readonly',
37
+ search: true,
38
+ }),
39
+ createThemeExtensions({
40
+ themeMode,
41
+ syntaxHighlighting: true,
42
+ slots: documentSlots,
43
+ }),
44
+ createMarkdownExtensions(),
45
+ viewMode === 'source' ? [] : decorateMarkdown(),
46
+ formattingKeymap(),
47
+ ],
48
+ [viewMode, themeMode, placeholder],
77
49
  );
78
50
 
79
- // TODO(marijn): This doesn't update the state on view changes.
80
- // Also not sure if view is even guaranteed to exist at this point.
81
51
  return (
82
- <div role='none' className={mx('fixed inset-0 flex flex-col')}>
83
- {toolbarState && <EditorToolbar state={toolbarState} getView={getView} onViewModeChange={handleViewModeChange} />}
84
- <div role='none' className='grow overflow-hidden'>
85
- <div className={mx(editorWidth)} ref={parentRef} />
86
- </div>
87
- </div>
52
+ <Editor.Root extensions={extensions} viewMode={viewMode}>
53
+ <Editor.Content>
54
+ <Editor.Toolbar classNames='dx-document' />
55
+ <div className='dx-container dx-document bg-base-surface'>
56
+ <Editor.View autoFocus={autoFocus} initialValue={initialValue} selectionEnd />
57
+ </div>
58
+ </Editor.Content>
59
+ </Editor.Root>
88
60
  );
89
61
  };
90
62
 
91
63
  const meta = {
92
64
  title: 'ui/react-ui-editor/EditorToolbar',
93
65
  render: DefaultStory,
94
- decorators: [withRegistry, withTheme(), withLayout({ layout: 'fullscreen' })],
66
+ decorators: [withRegistry, withTheme(), withLayout({ layout: 'fullscreen', classNames: 'bg-sidebar-surface' })],
95
67
  parameters: {
96
68
  layout: 'fullscreen',
97
69
  translations,
@@ -7,9 +7,9 @@ import defaultsDeep from 'lodash.defaultsdeep';
7
7
  import React from 'react';
8
8
 
9
9
  import { log } from '@dxos/log';
10
- import { faker } from '@dxos/random';
10
+ import { random } from '@dxos/random';
11
11
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
12
- import { blast, defaultOptions, dropFile, join, typewriter } from '@dxos/ui-editor';
12
+ import { blast, defaultOptions, dropFile, join, snippets } from '@dxos/ui-editor';
13
13
 
14
14
  import { EditorStory, content } from './components';
15
15
 
@@ -27,16 +27,16 @@ export default meta;
27
27
  type Story = StoryObj<typeof meta>;
28
28
 
29
29
  //
30
- // Typewriter
30
+ // Snippets
31
31
  //
32
32
 
33
- const typewriterItems = localStorage.getItem('org.dxos.testing.typewriter')?.split(',');
33
+ const snippetItems = localStorage.getItem('org.dxos.testing.snippets')?.split(',');
34
34
 
35
- export const Typewriter: Story = {
35
+ export const Snippets: Story = {
36
36
  render: () => (
37
37
  <EditorStory
38
- text={join('# Typewriter', '', content.paragraphs, content.footer)}
39
- extensions={[typewriter({ items: typewriterItems })]}
38
+ text={join('# Snippets', '', content.paragraphs, content.footer)}
39
+ extensions={[snippets({ items: snippetItems })]}
40
40
  />
41
41
  ),
42
42
  };
@@ -50,15 +50,15 @@ export const Blast: Story = {
50
50
  <EditorStory
51
51
  text={join('# Blast', '', content.paragraphs, content.codeblocks, content.paragraphs)}
52
52
  extensions={[
53
- typewriter({ items: typewriterItems }),
53
+ snippets({ items: snippetItems }),
54
54
  blast(
55
55
  defaultsDeep(
56
56
  {
57
57
  effect: 2,
58
58
  particleGravity: 0.2,
59
59
  particleShrinkRate: 0.995,
60
- color: () => [faker.number.int({ min: 100, max: 200 }), 0, 0],
61
- // color: () => [faker.number.int(256), faker.number.int(256), faker.number.int(256)],
60
+ color: () => [random.number.int({ min: 100, max: 200 }), 0, 0],
61
+ // color: () => [random.number.int(256), random.number.int(256), random.number.int(256)],
62
62
  },
63
63
  defaultOptions,
64
64
  ),
@@ -5,19 +5,18 @@
5
5
  import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import React, { useMemo, useState } from 'react';
7
7
 
8
- import { withLayout, withTheme } from '@dxos/react-ui/testing';
9
8
  import { withAttention } from '@dxos/react-ui-attention/testing';
9
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
10
10
  import { deleteItem, hashtag, join, listItemToString, outliner, treeFacet } from '@dxos/ui-editor';
11
11
 
12
12
  import { type EditorController, type EditorMenuGroup, EditorMenuProvider } from '../components';
13
-
14
13
  import { EditorStory } from './components';
15
14
 
16
- type StoryProps = {
15
+ type DefaultStoryProps = {
17
16
  text?: string;
18
17
  };
19
18
 
20
- const DefaultStory = ({ text }: StoryProps) => {
19
+ const DefaultStory = ({ text }: DefaultStoryProps) => {
21
20
  const [controller, setController] = useState<EditorController | null>(null);
22
21
 
23
22
  const extensions = useMemo(() => [outliner(), hashtag()], []);
@@ -6,7 +6,7 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import React, { useCallback, useState } from 'react';
7
7
 
8
8
  import { Obj, Query } from '@dxos/echo';
9
- import { faker } from '@dxos/random';
9
+ import { random } from '@dxos/random';
10
10
  import { useClientStory, withClientProvider } from '@dxos/react-client/testing';
11
11
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
12
12
  import { TestSchema, type ValueGenerator, createObjectFactory } from '@dxos/schema/testing';
@@ -25,10 +25,9 @@ import {
25
25
  linkSlashCommands,
26
26
  useEditorMenu,
27
27
  } from '../components';
28
-
29
28
  import { EditorStory } from './components';
30
29
 
31
- const generator: ValueGenerator = faker as any;
30
+ const generator: ValueGenerator = random as any;
32
31
 
33
32
  const customCompletions: EditorMenuGroup = createMenuGroup({
34
33
  id: 'test',
@@ -41,12 +40,12 @@ const placeholder = (trigger: string[]) => {
41
40
  Domino.of('span').classNames(mx('border border-separator rounded-xs mx-1 px-1 py-[2px] pb-[3px]')).text(trigger),
42
41
  );
43
42
  const forCommandsEl = Domino.of('span').text('for commands');
44
- return Domino.of('div').children(pressEl, ...triggerEls, forCommandsEl).root;
43
+ return Domino.of('div').append(pressEl, ...triggerEls, forCommandsEl).root;
45
44
  };
46
45
 
47
- type StoryProps = Omit<UseEditorMenuProps, 'viewRef'> & { text: string };
46
+ type DefaultStoryProps = Omit<UseEditorMenuProps, 'viewRef'> & { text: string };
48
47
 
49
- const DefaultStory = ({ text, ...props }: StoryProps) => {
48
+ const DefaultStory = ({ text, ...props }: DefaultStoryProps) => {
50
49
  const [controller, setController] = useState<EditorController | null>(null);
51
50
  const { groupsRef, extension, ...menuProps } = useEditorMenu(props);
52
51
 
@@ -57,7 +56,7 @@ const DefaultStory = ({ text, ...props }: StoryProps) => {
57
56
  );
58
57
  };
59
58
 
60
- const LinkStory = (args: StoryProps) => {
59
+ const LinkStory = (args: DefaultStoryProps) => {
61
60
  const { space } = useClientStory();
62
61
 
63
62
  const getMenu = useCallback<NonNullable<UseEditorMenuProps['getMenu']>>(
@@ -9,10 +9,10 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
9
9
  import { createPortal } from 'react-dom';
10
10
 
11
11
  import { invariant } from '@dxos/invariant';
12
- import { faker } from '@dxos/random';
12
+ import { random } from '@dxos/random';
13
13
  import { Card, Popover, Toolbar } from '@dxos/react-ui';
14
- import { withLayout, withTheme } from '@dxos/react-ui/testing';
15
14
  import { Menu, createMenuAction } from '@dxos/react-ui-menu';
15
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
16
16
  import {
17
17
  type PreviewBlock,
18
18
  type PreviewLinkRef,
@@ -25,13 +25,12 @@ import { hoverableControls } from '@dxos/ui-theme';
25
25
  import { trim } from '@dxos/util';
26
26
 
27
27
  import { type EditorController, EditorPreviewProvider, useEditorPreview } from '../components';
28
-
29
28
  import { EditorStory } from './components';
30
29
 
31
30
  const handlePreviewLookup = async ({ dxn, label }: PreviewLinkRef): Promise<PreviewLinkTarget> => {
32
31
  // Random text.
33
- faker.seed(dxn.split('').reduce((acc: number, char: string) => acc + char.charCodeAt(0), 1));
34
- const text = Array.from({ length: 2 }, () => faker.lorem.paragraphs()).join('\n\n');
32
+ random.seed(dxn.split('').reduce((acc: number, char: string) => acc + char.charCodeAt(0), 1));
33
+ const text = Array.from({ length: 2 }, () => random.lorem.paragraphs()).join('\n\n');
35
34
  return {
36
35
  label,
37
36
  text,
@@ -34,10 +34,10 @@ const DefaultStory = () => {
34
34
  return (
35
35
  <div className='w-full grid grid-cols-2 gap-2'>
36
36
  <Editor.Root>
37
- <Editor.Content classNames='p-2' extensions={ext1} initialValue={createText(false)} />
37
+ <Editor.View classNames='p-2' extensions={ext1} initialValue={createText(false)} />
38
38
  </Editor.Root>
39
39
  <Editor.Root>
40
- <Editor.Content classNames='p-2' extensions={ext2} initialValue={createText(true)} />
40
+ <Editor.View classNames='p-2' extensions={ext2} initialValue={createText(true)} />
41
41
  </Editor.Root>
42
42
  </div>
43
43
  );
@@ -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,7 +20,7 @@ import {
20
20
  createMarkdownExtensions,
21
21
  createThemeExtensions,
22
22
  debugTree,
23
- editorSlots,
23
+ documentSlots,
24
24
  } from '@dxos/ui-editor';
25
25
  import { mx } from '@dxos/ui-theme';
26
26
  import { isNonNullable } from '@dxos/util';
@@ -33,7 +33,7 @@ export type DebugMode = 'raw' | 'tree' | 'raw+tree';
33
33
 
34
34
  const defaultId = 'editor-' + PublicKey.random().toHex().slice(0, 8);
35
35
 
36
- export type StoryProps = Pick<UseTextEditorProps, 'id' | 'scrollTo' | 'selection' | 'extensions'> &
36
+ export type EditorStoryProps = Pick<UseTextEditorProps, 'id' | 'scrollTo' | 'selection' | 'extensions'> &
37
37
  Pick<ThemeExtensionsOptions, 'slots'> & {
38
38
  debug?: DebugMode;
39
39
  debugCustom?: (view: EditorView) => ReactNode;
@@ -46,7 +46,7 @@ export type StoryProps = Pick<UseTextEditorProps, 'id' | 'scrollTo' | 'selection
46
46
  onReady?: (view: EditorView) => void;
47
47
  };
48
48
 
49
- export const EditorStory = forwardRef<EditorController, StoryProps>(
49
+ export const EditorStory = forwardRef<EditorController, EditorStoryProps>(
50
50
  ({ debug, debugCustom, text, extensions: extensionsProp, ...props }, forwardedRef) => {
51
51
  const controllerRef = useRef<EditorController>(null);
52
52
  const mergedRef = useMergeRefs([controllerRef, forwardedRef]);
@@ -62,7 +62,7 @@ export const EditorStory = forwardRef<EditorController, StoryProps>(
62
62
 
63
63
  const view = controllerRef.current?.view;
64
64
  return (
65
- <div className={mx('w-full h-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]')}>
66
66
  <EditorComponent ref={mergedRef} object={object} text={text} extensions={extensions} {...props} />
67
67
 
68
68
  {debug && (
@@ -76,7 +76,16 @@ export const EditorStory = forwardRef<EditorController, StoryProps>(
76
76
  {view?.state.doc.toString()}
77
77
  </pre>
78
78
  )}
79
- {(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
+ )}
80
89
  </div>
81
90
  )}
82
91
  </div>
@@ -87,7 +96,7 @@ export const EditorStory = forwardRef<EditorController, StoryProps>(
87
96
  /**
88
97
  * Default story component.
89
98
  */
90
- const EditorComponent = forwardRef<EditorController, StoryProps>(
99
+ const EditorComponent = forwardRef<EditorController, EditorStoryProps>(
91
100
  (
92
101
  {
93
102
  id = defaultId,
@@ -100,7 +109,7 @@ const EditorComponent = forwardRef<EditorController, StoryProps>(
100
109
  scrollTo,
101
110
  selection,
102
111
  extensions,
103
- slots = editorSlots,
112
+ slots = documentSlots,
104
113
  onReady,
105
114
  },
106
115
  forwardedRef,
@@ -5,11 +5,10 @@
5
5
  import { type Completion } from '@codemirror/autocomplete';
6
6
  import { type Extension } from '@codemirror/state';
7
7
 
8
- import { faker } from '@dxos/random';
8
+ import { random } from '@dxos/random';
9
9
  import { Domino } from '@dxos/ui';
10
10
  import {
11
11
  type EditorSelectionState,
12
- type RenderCallback,
13
12
  decorateMarkdown,
14
13
  folding,
15
14
  formattingKeymap,
@@ -17,11 +16,12 @@ import {
17
16
  linkTooltip,
18
17
  table,
19
18
  } from '@dxos/ui-editor';
19
+ import { type RenderCallback } from '@dxos/ui-editor/types';
20
20
  import { safeUrl } from '@dxos/util';
21
21
 
22
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,24 +206,24 @@ 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-xs text-base-surface-text text-primary-600 hover:text-primary-500 dark:text-primary-300 hover:dark:text-primary-200';
209
+ 'rounded-xs text-base-foreground text-primary-600 hover:text-primary-500 dark:text-primary-300 hover:dark:text-primary-200';
208
210
 
209
211
  export const renderLinkTooltip: RenderCallback<{ url: string }> = (el, { url }) => {
210
212
  el.appendChild(
211
213
  Domino.of('a')
212
214
  .attributes({ href: url, target: '_blank', rel: 'noreferrer', 'aria-label': 'Open link' })
213
215
  .classNames(hover, 'flex items-center gap-2')
214
- .text(safeUrl(url)?.origin ?? url)
215
- .children(Domino.svg('ph--arrow-square-out--regular')).root,
216
+ .text(safeUrl(url)?.toString() ?? url)
217
+ .append(Domino.svg('ph--arrow-square-out--regular')).root,
216
218
  );
217
219
  };
218
220
 
219
221
  export const renderLinkButton: RenderCallback<{ url: string }> = (el, { url }) => {
220
222
  el.appendChild(
221
- Domino.of('a')
222
- .attributes({ href: url, target: '_blank', rel: 'noreferrer', 'aria-label': 'Open link' })
223
- .classNames(hover, 'inline-block ms-1 align-[-0.125em]') // Center icon.
224
- .children(Domino.svg('ph--arrow-square-out--regular')).root,
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,
225
227
  );
226
228
  };
227
229
 
@@ -242,18 +244,18 @@ export const allExtensions: Extension[] = [
242
244
  ];
243
245
 
244
246
  // Long text for scrolling stories.
245
- export const longText = faker.helpers
246
- .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 })
247
249
  .join('\n\n');
248
250
 
249
- export const largeWithImages = faker.helpers
250
- .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 })
251
253
  .flatMap((x) => x)
252
254
  .join('\n\n');
253
255
 
254
256
  export const headings = str(
255
257
  ...[1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 2, 3, 3, 2, 2, 6, 1]
256
- .map((level) => ['#'.repeat(level) + ' ' + faker.lorem.sentence(3), faker.lorem.sentences(), ''])
258
+ .map((level) => ['#'.repeat(level) + ' ' + random.lorem.sentence(3), random.lorem.sentences(), ''])
257
259
  .flat(),
258
260
  );
259
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
  },
@@ -6,7 +6,7 @@ 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
  /**
@@ -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"}