@dxos/react-ui-editor 0.8.4-main.c85a9c8dae → 0.8.4-main.cb12b3f963
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.
- package/dist/lib/browser/index.mjs +754 -728
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/translations.mjs +39 -0
- package/dist/lib/browser/translations.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +754 -728
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/translations.mjs +41 -0
- package/dist/lib/node-esm/translations.mjs.map +7 -0
- package/dist/types/src/components/Editor/Editor.d.ts +36 -25
- package/dist/types/src/components/Editor/Editor.d.ts.map +1 -1
- package/dist/types/src/components/Editor/Editor.stories.d.ts +4 -4
- package/dist/types/src/components/Editor/Editor.stories.d.ts.map +1 -1
- package/dist/types/src/components/{EditorContent/EditorContent.d.ts → Editor/EditorView.d.ts} +5 -5
- package/dist/types/src/components/Editor/EditorView.d.ts.map +1 -0
- package/dist/types/src/components/Editor/controller.d.ts.map +1 -0
- package/dist/types/src/components/EditorMenuProvider/EditorMenuProvider.d.ts +1 -3
- package/dist/types/src/components/EditorMenuProvider/EditorMenuProvider.d.ts.map +1 -1
- package/dist/types/src/components/EditorMenuProvider/menu-presets.d.ts.map +1 -1
- package/dist/types/src/components/EditorMenuProvider/menu.d.ts.map +1 -1
- package/dist/types/src/components/EditorMenuProvider/popover.d.ts +2 -1
- package/dist/types/src/components/EditorMenuProvider/popover.d.ts.map +1 -1
- package/dist/types/src/components/EditorMenuProvider/useEditorMenu.d.ts.map +1 -1
- package/dist/types/src/components/EditorPreviewProvider/EditorPreviewProvider.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +2 -2
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/blocks.d.ts +4 -19
- package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/formatting.d.ts +4 -19
- package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/headings.d.ts +4 -19
- package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/image.d.ts +3 -9
- package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/index.d.ts +1 -2
- package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/lists.d.ts +6 -0
- package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/search.d.ts +3 -9
- package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/types.d.ts +6 -0
- package/dist/types/src/components/EditorToolbar/types.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/view-mode.d.ts +5 -20
- package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +0 -2
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/extensions/Assistant.stories.d.ts +10 -0
- package/dist/types/src/extensions/Assistant.stories.d.ts.map +1 -0
- package/dist/types/src/extensions/assistant-extension.d.ts +24 -0
- package/dist/types/src/extensions/assistant-extension.d.ts.map +1 -0
- package/dist/types/src/extensions/index.d.ts +2 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -0
- package/dist/types/src/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useBasicMarkdownExtensions.d.ts +25 -0
- package/dist/types/src/hooks/useBasicMarkdownExtensions.d.ts.map +1 -0
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/stories/Automerge.stories.d.ts +24 -24
- package/dist/types/src/stories/Automerge.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Comments.stories.d.ts +1 -1
- package/dist/types/src/stories/Comments.stories.d.ts.map +1 -1
- package/dist/types/src/stories/EditorToolbar.stories.d.ts +28 -26
- package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Experimental.stories.d.ts +2 -2
- package/dist/types/src/stories/Experimental.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Markdown.stories.d.ts +1 -1
- package/dist/types/src/stories/Markdown.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Outliner.stories.d.ts +2 -2
- package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Popover.stories.d.ts +2 -2
- package/dist/types/src/stories/Popover.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Preview.stories.d.ts +1 -1
- package/dist/types/src/stories/Preview.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Tags.stories.d.ts.map +1 -1
- package/dist/types/src/stories/TextEditor.stories.d.ts +1 -1
- package/dist/types/src/stories/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Theme.stories.d.ts.map +1 -1
- package/dist/types/src/stories/components/EditorStory.d.ts +2 -2
- package/dist/types/src/stories/components/EditorStory.d.ts.map +1 -1
- package/dist/types/src/stories/components/util.d.ts +2 -1
- package/dist/types/src/stories/components/util.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +24 -24
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/util/react.d.ts +1 -1
- package/dist/types/src/util/react.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +56 -47
- package/src/components/Editor/Editor.stories.tsx +15 -21
- package/src/components/Editor/Editor.tsx +53 -48
- package/src/components/Editor/EditorView.tsx +103 -0
- package/src/components/EditorMenuProvider/EditorMenuProvider.tsx +2 -4
- package/src/components/EditorMenuProvider/menu-presets.ts +1 -0
- package/src/components/EditorMenuProvider/popover.ts +2 -1
- package/src/components/EditorMenuProvider/useEditorMenu.ts +2 -1
- package/src/components/EditorToolbar/EditorToolbar.tsx +29 -48
- package/src/components/EditorToolbar/blocks.ts +54 -46
- package/src/components/EditorToolbar/formatting.ts +44 -45
- package/src/components/EditorToolbar/headings.ts +44 -50
- package/src/components/EditorToolbar/image.ts +16 -21
- package/src/components/EditorToolbar/index.ts +2 -3
- package/src/components/EditorToolbar/lists.ts +58 -0
- package/src/components/EditorToolbar/search.ts +16 -21
- package/src/components/EditorToolbar/types.ts +8 -0
- package/src/components/EditorToolbar/view-mode.ts +37 -43
- package/src/components/index.ts +0 -3
- package/src/extensions/Assistant.stories.tsx +112 -0
- package/src/extensions/assistant-extension.tsx +223 -0
- package/src/extensions/index.ts +5 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useBasicMarkdownExtensions.ts +55 -0
- package/src/index.ts +1 -4
- package/src/stories/Automerge.stories.tsx +8 -8
- package/src/stories/Comments.stories.tsx +2 -2
- package/src/stories/EditorToolbar.stories.tsx +36 -64
- package/src/stories/Experimental.stories.tsx +10 -10
- package/src/stories/Outliner.stories.tsx +3 -4
- package/src/stories/Popover.stories.tsx +6 -7
- package/src/stories/Preview.stories.tsx +6 -7
- package/src/stories/Theme.stories.tsx +2 -2
- package/src/stories/components/EditorStory.tsx +17 -8
- package/src/stories/components/util.tsx +37 -35
- package/src/translations.ts +29 -24
- package/src/util/react.tsx +1 -1
- package/dist/types/src/components/EditorContent/EditorContent.d.ts.map +0 -1
- package/dist/types/src/components/EditorContent/controller.d.ts.map +0 -1
- package/dist/types/src/components/EditorContent/index.d.ts +0 -3
- package/dist/types/src/components/EditorContent/index.d.ts.map +0 -1
- package/dist/types/src/components/EditorToolbar/actions.d.ts +0 -25
- package/dist/types/src/components/EditorToolbar/actions.d.ts.map +0 -1
- package/dist/types/src/components/EditorToolbar/useEditorToolbar.d.ts +0 -11
- package/dist/types/src/components/EditorToolbar/useEditorToolbar.d.ts.map +0 -1
- package/dist/types/src/stories/CommandDialog.stories.d.ts +0 -14
- package/dist/types/src/stories/CommandDialog.stories.d.ts.map +0 -1
- package/src/components/EditorContent/EditorContent.tsx +0 -83
- package/src/components/EditorContent/index.ts +0 -6
- package/src/components/EditorToolbar/actions.ts +0 -87
- package/src/components/EditorToolbar/useEditorToolbar.ts +0 -20
- package/src/stories/CommandDialog.stories.tsx +0 -81
- /package/dist/types/src/components/{EditorContent → Editor}/controller.d.ts +0 -0
- /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, {
|
|
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
|
-
|
|
16
|
+
documentSlots,
|
|
22
17
|
formattingKeymap,
|
|
23
|
-
formattingListener,
|
|
24
18
|
} from '@dxos/ui-editor';
|
|
25
|
-
import {
|
|
19
|
+
import { type EditorViewMode } from '@dxos/ui-editor/types';
|
|
26
20
|
|
|
27
|
-
import {
|
|
28
|
-
import { type UseTextEditorProps, useTextEditor } from '../hooks';
|
|
29
|
-
import { translations } from '../translations';
|
|
21
|
+
import { translations } from '#translations';
|
|
30
22
|
|
|
31
|
-
|
|
23
|
+
import { Editor } from '../components';
|
|
24
|
+
import { type UseTextEditorProps } from '../hooks';
|
|
32
25
|
|
|
33
|
-
|
|
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
|
-
|
|
48
|
-
const
|
|
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
|
|
73
|
-
(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
-
<
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<div
|
|
86
|
-
|
|
87
|
-
|
|
52
|
+
<Editor.Root extensions={extensions} viewMode={viewMode}>
|
|
53
|
+
<Editor.Content>
|
|
54
|
+
<Editor.Toolbar classNames='dx-document' />
|
|
55
|
+
<div role='none' 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 {
|
|
10
|
+
import { random } from '@dxos/random';
|
|
11
11
|
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
12
|
-
import { blast, defaultOptions, dropFile, join,
|
|
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
|
-
//
|
|
30
|
+
// Snippets
|
|
31
31
|
//
|
|
32
32
|
|
|
33
|
-
const
|
|
33
|
+
const snippetItems = localStorage.getItem('org.dxos.testing.snippets')?.split(',');
|
|
34
34
|
|
|
35
|
-
export const
|
|
35
|
+
export const Snippets: Story = {
|
|
36
36
|
render: () => (
|
|
37
37
|
<EditorStory
|
|
38
|
-
text={join('#
|
|
39
|
-
extensions={[
|
|
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
|
-
|
|
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: () => [
|
|
61
|
-
// color: () => [
|
|
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
|
|
15
|
+
type DefaultStoryProps = {
|
|
17
16
|
text?: string;
|
|
18
17
|
};
|
|
19
18
|
|
|
20
|
-
const DefaultStory = ({ text }:
|
|
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 {
|
|
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 =
|
|
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').
|
|
43
|
+
return Domino.of('div').append(pressEl, ...triggerEls, forCommandsEl).root;
|
|
45
44
|
};
|
|
46
45
|
|
|
47
|
-
type
|
|
46
|
+
type DefaultStoryProps = Omit<UseEditorMenuProps, 'viewRef'> & { text: string };
|
|
48
47
|
|
|
49
|
-
const DefaultStory = ({ text, ...props }:
|
|
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:
|
|
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 {
|
|
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
|
-
|
|
34
|
-
const text = Array.from({ length: 2 }, () =>
|
|
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,
|
|
@@ -61,7 +60,7 @@ const PreviewCard = () => {
|
|
|
61
60
|
<Popover.Viewport classNames='dx-card-popover-width'>
|
|
62
61
|
<Card.Root border={false}>
|
|
63
62
|
<Card.Toolbar>
|
|
64
|
-
<Card.Icon
|
|
63
|
+
<Card.Icon icon='ph--file-text--regular' />
|
|
65
64
|
<Card.Title>{target.label}</Card.Title>
|
|
66
65
|
<Popover.Close asChild>
|
|
67
66
|
<Card.CloseIconButton />
|
|
@@ -167,7 +166,7 @@ const PreviewBlockComponent = ({ link, el, view }: { link: PreviewLinkRef; el: H
|
|
|
167
166
|
<Card.Root classNames={hoverableControls}>
|
|
168
167
|
{!view?.state.readOnly && (
|
|
169
168
|
<Card.Toolbar>
|
|
170
|
-
<Card.Icon
|
|
169
|
+
<Card.Icon icon='ph--bookmark--regular' />
|
|
171
170
|
<Card.Title>{link.label}</Card.Title>
|
|
172
171
|
{/* TODO(wittjosiah): Reconcile with Card.Menu. */}
|
|
173
172
|
<Menu.Trigger asChild disabled={!menuItems?.length}>
|
|
@@ -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.
|
|
37
|
+
<Editor.View classNames='p-2' extensions={ext1} initialValue={createText(false)} />
|
|
38
38
|
</Editor.Root>
|
|
39
39
|
<Editor.Root>
|
|
40
|
-
<Editor.
|
|
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 {
|
|
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
|
-
|
|
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
|
|
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,
|
|
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('
|
|
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') &&
|
|
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,
|
|
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 =
|
|
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 {
|
|
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 = () =>
|
|
24
|
+
export const num = () => random.number.int({ min: 0, max: 9999 }).toLocaleString();
|
|
25
25
|
|
|
26
26
|
export const img = '';
|
|
27
27
|
|
|
@@ -41,11 +41,11 @@ export const content = {
|
|
|
41
41
|
// prettier-ignore
|
|
42
42
|
'### TaskList',
|
|
43
43
|
'',
|
|
44
|
-
`- [x] ${
|
|
45
|
-
`- [ ] ${
|
|
46
|
-
` - [ ] ${
|
|
47
|
-
` - [ ] ${
|
|
48
|
-
` - [x] ${
|
|
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
|
-
`- ${
|
|
57
|
-
`- ${
|
|
58
|
-
` - ${
|
|
59
|
-
` - ${
|
|
60
|
-
`- ${
|
|
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. ${
|
|
69
|
-
`1. ${
|
|
70
|
-
`1. ${
|
|
71
|
-
` 1. ${
|
|
72
|
-
` 1. ${
|
|
73
|
-
` 1. ${
|
|
74
|
-
`1. ${
|
|
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. ${
|
|
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
|
-
`| ${
|
|
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]
|
|
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(...
|
|
164
|
+
paragraphs: str(...random.helpers.multiple(() => [random.lorem.paragraph(), ''], { count: 3 }).flat()),
|
|
163
165
|
|
|
164
166
|
footer: str('', '', '', '', ''),
|
|
165
167
|
};
|
|
@@ -211,17 +213,17 @@ export const renderLinkTooltip: RenderCallback<{ url: string }> = (el, { url })
|
|
|
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)?.
|
|
215
|
-
.
|
|
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('
|
|
222
|
-
.attributes({
|
|
223
|
-
.classNames(hover, 'inline-block
|
|
224
|
-
.
|
|
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 =
|
|
246
|
-
.multiple(() =>
|
|
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 =
|
|
250
|
-
.multiple(() => [
|
|
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) + ' ' +
|
|
258
|
+
.map((level) => ['#'.repeat(level) + ' ' + random.lorem.sentence(3), random.lorem.sentences(), ''])
|
|
257
259
|
.flat(),
|
|
258
260
|
);
|
|
259
261
|
|
package/src/translations.ts
CHANGED
|
@@ -10,30 +10,35 @@ export const translations = [
|
|
|
10
10
|
{
|
|
11
11
|
'en-US': {
|
|
12
12
|
[translationKey]: {
|
|
13
|
-
'
|
|
14
|
-
'
|
|
15
|
-
'
|
|
16
|
-
|
|
17
|
-
'
|
|
18
|
-
'
|
|
19
|
-
'
|
|
20
|
-
'
|
|
21
|
-
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
'
|
|
25
|
-
'
|
|
26
|
-
'
|
|
27
|
-
'
|
|
28
|
-
|
|
29
|
-
'
|
|
30
|
-
'
|
|
31
|
-
'
|
|
32
|
-
|
|
33
|
-
'
|
|
34
|
-
'
|
|
35
|
-
'
|
|
36
|
-
'
|
|
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
|
},
|
package/src/util/react.tsx
CHANGED
|
@@ -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 +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"}
|