@dxos/react-ui-editor 0.8.2-staging.7ac8446 → 0.8.3-main.672df60
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 +4505 -3151
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +6 -0
- package/dist/lib/browser/testing/index.mjs.map +7 -0
- package/dist/lib/node/index.cjs +3360 -1998
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +29 -0
- package/dist/lib/node/testing/index.cjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +4505 -3151
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +8 -0
- package/dist/lib/node-esm/testing/index.mjs.map +7 -0
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +1 -1
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/blocks.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/formatting.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/headings.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/{comment.d.ts → image.d.ts} +4 -5
- package/dist/types/src/components/EditorToolbar/image.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/index.d.ts +1 -1
- package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/lists.d.ts +4 -3
- package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/search.d.ts +17 -0
- package/dist/types/src/components/EditorToolbar/search.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/util.d.ts +17 -25
- package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/{viewMode.d.ts → view-mode.d.ts} +5 -4
- package/dist/types/src/components/EditorToolbar/view-mode.d.ts.map +1 -0
- package/dist/types/src/components/Popover/RefDropdownMenu.d.ts +21 -0
- package/dist/types/src/components/Popover/RefDropdownMenu.d.ts.map +1 -0
- package/dist/types/src/components/Popover/RefPopover.d.ts +21 -0
- package/dist/types/src/components/Popover/RefPopover.d.ts.map +1 -0
- package/dist/types/src/components/Popover/index.d.ts +3 -0
- package/dist/types/src/components/Popover/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/defaults.d.ts +3 -5
- package/dist/types/src/defaults.d.ts.map +1 -1
- package/dist/types/src/extensions/annotations.d.ts +4 -1
- package/dist/types/src/extensions/annotations.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete.d.ts +1 -2
- package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/defs.d.ts +1 -1
- package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts +1 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts +1 -1
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -1
- package/dist/types/src/extensions/blast.d.ts.map +1 -1
- package/dist/types/src/extensions/command/action.d.ts +17 -0
- package/dist/types/src/extensions/command/action.d.ts.map +1 -0
- package/dist/types/src/extensions/command/command.d.ts +4 -10
- package/dist/types/src/extensions/command/command.d.ts.map +1 -1
- package/dist/types/src/extensions/command/hint.d.ts +18 -4
- package/dist/types/src/extensions/command/hint.d.ts.map +1 -1
- package/dist/types/src/extensions/command/index.d.ts +3 -0
- package/dist/types/src/extensions/command/index.d.ts.map +1 -1
- package/dist/types/src/extensions/command/menu.d.ts +6 -11
- package/dist/types/src/extensions/command/menu.d.ts.map +1 -1
- package/dist/types/src/extensions/command/state.d.ts +9 -11
- package/dist/types/src/extensions/command/state.d.ts.map +1 -1
- package/dist/types/src/extensions/command/typeahead.d.ts +17 -0
- package/dist/types/src/extensions/command/typeahead.d.ts.map +1 -0
- package/dist/types/src/extensions/comments.d.ts +9 -17
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/dnd.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts +4 -0
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/folding.d.ts.map +1 -1
- package/dist/types/src/extensions/hashtag.d.ts +3 -0
- package/dist/types/src/extensions/hashtag.d.ts.map +1 -0
- package/dist/types/src/extensions/index.d.ts +4 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/json.d.ts +7 -0
- package/dist/types/src/extensions/json.d.ts.map +1 -0
- package/dist/types/src/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/{editorAction.d.ts → action.d.ts} +1 -1
- package/dist/types/src/extensions/markdown/action.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/bundle.d.ts +2 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/debug.d.ts +2 -2
- package/dist/types/src/extensions/markdown/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts +5 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts +3 -3
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/index.d.ts +1 -1
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts +4 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
- package/dist/types/src/extensions/mention.d.ts.map +1 -1
- package/dist/types/src/extensions/modes.d.ts +5 -5
- package/dist/types/src/extensions/modes.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/commands.d.ts +10 -0
- package/dist/types/src/extensions/outliner/commands.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/editor.d.ts +5 -0
- package/dist/types/src/extensions/outliner/editor.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/editor.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/editor.test.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/index.d.ts +4 -0
- package/dist/types/src/extensions/outliner/index.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/outliner.d.ts +11 -0
- package/dist/types/src/extensions/outliner/outliner.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/outliner.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/outliner.test.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/selection.d.ts +12 -0
- package/dist/types/src/extensions/outliner/selection.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/tree.d.ts +79 -0
- package/dist/types/src/extensions/outliner/tree.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/tree.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/tree.test.d.ts.map +1 -0
- package/dist/types/src/extensions/preview/index.d.ts +2 -0
- package/dist/types/src/extensions/preview/index.d.ts.map +1 -0
- package/dist/types/src/extensions/preview/preview.d.ts +39 -0
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -0
- package/dist/types/src/extensions/selection.d.ts.map +1 -1
- package/dist/types/src/extensions/typewriter.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +0 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts +2 -1
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/stories/Command.stories.d.ts +7 -0
- package/dist/types/src/stories/Command.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Comments.stories.d.ts +13 -0
- package/dist/types/src/stories/Comments.stories.d.ts.map +1 -0
- package/dist/types/src/stories/EditorToolbar.stories.d.ts +12 -0
- package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Experimental.stories.d.ts +16 -0
- package/dist/types/src/stories/Experimental.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Markdown.stories.d.ts +46 -0
- package/dist/types/src/stories/Markdown.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Outliner.stories.d.ts +26 -0
- package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Preview.stories.d.ts +10 -0
- package/dist/types/src/stories/Preview.stories.d.ts.map +1 -0
- package/dist/types/src/stories/TextEditor.stories.d.ts +55 -0
- package/dist/types/src/stories/TextEditor.stories.d.ts.map +1 -0
- package/dist/types/src/stories/components/EditorStory.d.ts +43 -0
- package/dist/types/src/stories/components/EditorStory.d.ts.map +1 -0
- package/dist/types/src/stories/components/index.d.ts +3 -0
- package/dist/types/src/stories/components/index.d.ts.map +1 -0
- package/dist/types/src/stories/components/util.d.ts +38 -0
- package/dist/types/src/stories/components/util.d.ts.map +1 -0
- package/dist/types/src/styles/theme.d.ts.map +1 -1
- package/dist/types/src/styles/tokens.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +2 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/testing/util.d.ts +2 -0
- package/dist/types/src/testing/util.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +5 -0
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/util/cursor.d.ts.map +1 -1
- package/dist/types/src/util/debug.d.ts.map +1 -1
- package/dist/types/src/util/dom.d.ts.map +1 -1
- package/dist/types/src/util/facet.d.ts.map +1 -1
- package/dist/types/src/util/react.d.ts +6 -1
- package/dist/types/src/util/react.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +47 -30
- package/src/components/EditorToolbar/EditorToolbar.tsx +95 -72
- package/src/components/EditorToolbar/blocks.ts +27 -6
- package/src/components/EditorToolbar/formatting.ts +34 -7
- package/src/components/EditorToolbar/headings.ts +9 -8
- package/src/components/EditorToolbar/image.ts +16 -0
- package/src/components/EditorToolbar/index.ts +7 -1
- package/src/components/EditorToolbar/lists.ts +26 -7
- package/src/components/EditorToolbar/search.ts +19 -0
- package/src/components/EditorToolbar/util.ts +19 -20
- package/src/components/EditorToolbar/{viewMode.ts → view-mode.ts} +9 -8
- package/src/components/Popover/RefDropdownMenu.tsx +77 -0
- package/src/components/Popover/RefPopover.tsx +75 -0
- package/src/components/Popover/index.ts +6 -0
- package/src/components/index.ts +1 -0
- package/src/defaults.ts +12 -13
- package/src/extensions/annotations.ts +41 -64
- package/src/extensions/autocomplete.ts +5 -6
- package/src/extensions/automerge/automerge.stories.tsx +13 -24
- package/src/extensions/automerge/automerge.test.tsx +6 -5
- package/src/extensions/automerge/automerge.ts +2 -2
- package/src/extensions/automerge/defs.ts +1 -2
- package/src/extensions/automerge/sync.ts +7 -7
- package/src/extensions/automerge/update-automerge.ts +1 -1
- package/src/extensions/automerge/update-codemirror.ts +3 -4
- package/src/extensions/awareness/awareness-provider.ts +4 -4
- package/src/extensions/awareness/awareness.ts +7 -7
- package/src/extensions/blast.ts +9 -9
- package/src/extensions/command/action.ts +49 -0
- package/src/extensions/command/command.ts +7 -27
- package/src/extensions/command/hint.ts +36 -33
- package/src/extensions/command/index.ts +3 -0
- package/src/extensions/command/menu.ts +91 -54
- package/src/extensions/command/state.ts +41 -61
- package/src/extensions/command/typeahead.ts +116 -0
- package/src/extensions/comments.ts +11 -76
- package/src/extensions/factories.ts +13 -0
- package/src/extensions/folding.tsx +1 -1
- package/src/extensions/hashtag.tsx +68 -0
- package/src/extensions/index.ts +4 -0
- package/src/extensions/json.ts +57 -0
- package/src/extensions/markdown/bundle.ts +13 -9
- package/src/extensions/markdown/changes.ts +3 -2
- package/src/extensions/markdown/debug.ts +2 -2
- package/src/extensions/markdown/decorate.ts +19 -17
- package/src/extensions/markdown/formatting.ts +6 -6
- package/src/extensions/markdown/image.ts +14 -13
- package/src/extensions/markdown/index.ts +1 -1
- package/src/extensions/markdown/link.ts +33 -24
- package/src/extensions/markdown/styles.ts +4 -3
- package/src/extensions/markdown/table.ts +3 -3
- package/src/extensions/modes.ts +5 -6
- package/src/extensions/outliner/commands.ts +270 -0
- package/src/extensions/outliner/editor.test.ts +33 -0
- package/src/extensions/outliner/editor.ts +184 -0
- package/src/extensions/outliner/index.ts +7 -0
- package/src/extensions/outliner/outliner.test.ts +99 -0
- package/src/extensions/outliner/outliner.ts +169 -0
- package/src/extensions/outliner/selection.ts +50 -0
- package/src/extensions/outliner/tree.test.ts +164 -0
- package/src/extensions/outliner/tree.ts +315 -0
- package/src/extensions/preview/index.ts +5 -0
- package/src/extensions/preview/preview.ts +271 -0
- package/src/hooks/index.ts +0 -1
- package/src/hooks/useTextEditor.ts +4 -3
- package/src/stories/Command.stories.tsx +97 -0
- package/src/stories/Comments.stories.tsx +98 -0
- package/src/stories/EditorToolbar.stories.tsx +96 -0
- package/src/stories/Experimental.stories.tsx +86 -0
- package/src/stories/Markdown.stories.tsx +121 -0
- package/src/stories/Outliner.stories.tsx +120 -0
- package/src/stories/Preview.stories.tsx +149 -0
- package/src/stories/TextEditor.stories.tsx +256 -0
- package/src/stories/components/EditorStory.tsx +135 -0
- package/src/stories/components/index.ts +6 -0
- package/src/stories/components/util.tsx +231 -0
- package/src/styles/theme.ts +15 -5
- package/src/styles/tokens.ts +1 -2
- package/src/testing/index.ts +5 -0
- package/src/testing/util.ts +5 -0
- package/src/types.ts +7 -0
- package/src/util/react.tsx +20 -2
- package/dist/types/src/InputMode.stories.d.ts +0 -57
- package/dist/types/src/InputMode.stories.d.ts.map +0 -1
- package/dist/types/src/TextEditor.stories.d.ts +0 -115
- package/dist/types/src/TextEditor.stories.d.ts.map +0 -1
- package/dist/types/src/components/EditorToolbar/comment.d.ts.map +0 -1
- package/dist/types/src/components/EditorToolbar/viewMode.d.ts.map +0 -1
- package/dist/types/src/extensions/command/preview.d.ts +0 -12
- package/dist/types/src/extensions/command/preview.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/editorAction.d.ts.map +0 -1
- package/dist/types/src/fragments.d.ts +0 -3
- package/dist/types/src/fragments.d.ts.map +0 -1
- package/dist/types/src/hooks/useActionHandler.d.ts +0 -4
- package/dist/types/src/hooks/useActionHandler.d.ts.map +0 -1
- package/src/InputMode.stories.tsx +0 -124
- package/src/TextEditor.stories.tsx +0 -856
- package/src/components/EditorToolbar/comment.ts +0 -23
- package/src/extensions/command/preview.ts +0 -79
- package/src/fragments.ts +0 -19
- package/src/hooks/useActionHandler.ts +0 -12
- /package/src/extensions/markdown/{editorAction.ts → action.ts} +0 -0
@@ -2,28 +2,30 @@
|
|
2
2
|
// Copyright 2025 DXOS.org
|
3
3
|
//
|
4
4
|
|
5
|
+
import { type EditorView } from '@codemirror/view';
|
6
|
+
import { type Rx } from '@effect-rx/rx-react';
|
5
7
|
import { useMemo } from 'react';
|
6
8
|
|
7
|
-
import {
|
8
|
-
import {
|
9
|
+
import { type Action } from '@dxos/app-graph';
|
10
|
+
import { live, type Live } from '@dxos/live-object';
|
11
|
+
import { type ThemedClassName } from '@dxos/react-ui';
|
9
12
|
import {
|
10
13
|
type MenuSeparator,
|
11
14
|
type MenuItemGroup,
|
12
15
|
type ToolbarMenuActionGroupProperties,
|
13
|
-
type MenuActionProperties,
|
14
16
|
createMenuAction,
|
15
17
|
createMenuItemGroup,
|
16
18
|
type ActionGraphProps,
|
19
|
+
type MenuActionProperties,
|
17
20
|
} from '@dxos/react-ui-menu';
|
18
21
|
|
19
|
-
import type { EditorAction,
|
22
|
+
import type { EditorAction, EditorViewMode, Formatting } from '../../extensions';
|
20
23
|
import { translationKey } from '../../translations';
|
21
24
|
|
22
|
-
export type EditorToolbarState = Formatting &
|
23
|
-
Partial<{ comment: boolean; viewMode: EditorViewMode; selection: boolean }>;
|
25
|
+
export type EditorToolbarState = Formatting & Partial<{ viewMode: EditorViewMode }>;
|
24
26
|
|
25
27
|
export const useEditorToolbarState = (initialState: Partial<EditorToolbarState> = {}) => {
|
26
|
-
return useMemo(() =>
|
28
|
+
return useMemo(() => live<EditorToolbarState>(initialState), []);
|
27
29
|
};
|
28
30
|
|
29
31
|
export type EditorToolbarFeatureFlags = Partial<{
|
@@ -31,16 +33,17 @@ export type EditorToolbarFeatureFlags = Partial<{
|
|
31
33
|
formatting: boolean;
|
32
34
|
lists: boolean;
|
33
35
|
blocks: boolean;
|
34
|
-
comment: boolean;
|
35
36
|
search: boolean;
|
36
|
-
|
37
|
+
// TODO(wittjosiah): Factor out. Depend on plugin-level capabilities.
|
38
|
+
image: () => void;
|
39
|
+
viewMode: (mode: EditorViewMode) => void;
|
37
40
|
}>;
|
38
41
|
|
39
42
|
export type EditorToolbarActionGraphProps = {
|
40
|
-
state:
|
43
|
+
state: Live<EditorToolbarState>;
|
44
|
+
getView: () => EditorView;
|
41
45
|
// TODO(wittjosiah): Control positioning.
|
42
|
-
customActions?:
|
43
|
-
onAction: (action: EditorAction) => void;
|
46
|
+
customActions?: Rx.Rx<ActionGraphProps>;
|
44
47
|
};
|
45
48
|
|
46
49
|
export type EditorToolbarProps = ThemedClassName<
|
@@ -49,17 +52,13 @@ export type EditorToolbarProps = ThemedClassName<
|
|
49
52
|
|
50
53
|
export type EditorToolbarItem = EditorAction | MenuItemGroup | MenuSeparator;
|
51
54
|
|
52
|
-
export const createEditorAction = (
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
id: string = payload.type,
|
57
|
-
) => createMenuAction(id, { icon, label, ...payload }) as EditorAction;
|
55
|
+
export const createEditorAction = (id: string, invoke: () => void, properties: Partial<MenuActionProperties>) => {
|
56
|
+
const { label = [`${id} label`, { ns: translationKey }], ...rest } = properties;
|
57
|
+
return createMenuAction(id, invoke, { label, ...rest }) as Action<MenuActionProperties>;
|
58
|
+
};
|
58
59
|
|
59
60
|
export const createEditorActionGroup = (
|
60
61
|
id: string,
|
61
62
|
props: Omit<ToolbarMenuActionGroupProperties, 'icon'>,
|
62
63
|
icon?: string,
|
63
64
|
) => createMenuItemGroup(id, { icon, iconOnly: true, ...props });
|
64
|
-
|
65
|
-
export const editorToolbarSearch = createEditorAction({ type: 'search' }, 'ph--magnifying-glass--regular');
|
@@ -6,6 +6,7 @@ import { type NodeArg } from '@dxos/app-graph';
|
|
6
6
|
import { type ToolbarMenuActionGroupProperties } from '@dxos/react-ui-menu';
|
7
7
|
|
8
8
|
import { createEditorAction, createEditorActionGroup, type EditorToolbarState } from './util';
|
9
|
+
import { type EditorViewMode } from '../../extensions';
|
9
10
|
import { translationKey } from '../../translations';
|
10
11
|
|
11
12
|
const createViewModeGroupAction = (value: string) =>
|
@@ -20,24 +21,24 @@ const createViewModeGroupAction = (value: string) =>
|
|
20
21
|
'ph--eye--regular',
|
21
22
|
);
|
22
23
|
|
23
|
-
const createViewModeActions = (value: string) =>
|
24
|
+
const createViewModeActions = (value: string, onViewModeChange: (mode: EditorViewMode) => void) =>
|
24
25
|
Object.entries({
|
25
26
|
preview: 'ph--eye--regular',
|
26
27
|
source: 'ph--pencil-simple--regular',
|
27
28
|
readonly: 'ph--pencil-slash--regular',
|
28
29
|
}).map(([viewMode, icon]) => {
|
29
|
-
|
30
|
-
|
30
|
+
const checked = viewMode === value;
|
31
|
+
return createEditorAction(`view-mode--${viewMode}`, () => onViewModeChange(viewMode as EditorViewMode), {
|
32
|
+
label: [`${viewMode} mode label`, { ns: translationKey }],
|
33
|
+
checked,
|
31
34
|
icon,
|
32
|
-
|
33
|
-
`view-mode--${viewMode}`,
|
34
|
-
);
|
35
|
+
});
|
35
36
|
});
|
36
37
|
|
37
|
-
export const createViewMode = (state: EditorToolbarState) => {
|
38
|
+
export const createViewMode = (state: EditorToolbarState, onViewModeChange: (mode: EditorViewMode) => void) => {
|
38
39
|
const value = state.viewMode ?? 'source';
|
39
40
|
const viewModeGroupAction = createViewModeGroupAction(value);
|
40
|
-
const viewModeActions = createViewModeActions(value);
|
41
|
+
const viewModeActions = createViewModeActions(value, onViewModeChange);
|
41
42
|
return {
|
42
43
|
nodes: [viewModeGroupAction as NodeArg<any>, ...viewModeActions],
|
43
44
|
edges: [
|
@@ -0,0 +1,77 @@
|
|
1
|
+
//
|
2
|
+
// Copyright 2025 DXOS.org
|
3
|
+
//
|
4
|
+
|
5
|
+
import { createContext } from '@radix-ui/react-context';
|
6
|
+
import React, { type PropsWithChildren, useRef, useState, useEffect, useCallback, type RefObject } from 'react';
|
7
|
+
|
8
|
+
import { addEventListener } from '@dxos/async';
|
9
|
+
import { type DxRefTag, type DxRefTagActivate } from '@dxos/lit-ui';
|
10
|
+
import { DropdownMenu } from '@dxos/react-ui';
|
11
|
+
|
12
|
+
import { type PreviewLinkRef, type PreviewLinkTarget, type PreviewLookup } from '../../extensions';
|
13
|
+
|
14
|
+
// TODO(burdon): Reconcile with RefPopover?
|
15
|
+
|
16
|
+
const customEventOptions = { capture: true, passive: false };
|
17
|
+
|
18
|
+
// Create a context for the dxn value.
|
19
|
+
type RefDropdownMenuValue = Partial<{ link: PreviewLinkRef; target: PreviewLinkTarget; pending: boolean }>;
|
20
|
+
|
21
|
+
const REF_DROPDOWN_MENU = 'RefDropdownMenu';
|
22
|
+
const [RefDropdownMenuContextProvider, useRefDropdownMenu] = createContext<RefDropdownMenuValue>(REF_DROPDOWN_MENU, {});
|
23
|
+
|
24
|
+
type RefDropdownMenuProviderProps = PropsWithChildren<{ onLookup?: PreviewLookup }>;
|
25
|
+
|
26
|
+
const RefDropdownMenuProvider = ({ children, onLookup }: RefDropdownMenuProviderProps) => {
|
27
|
+
const trigger = useRef<DxRefTag | null>(null);
|
28
|
+
const [value, setValue] = useState<RefDropdownMenuValue>({});
|
29
|
+
const [rootRef, setRootRef] = useState<HTMLDivElement | null>(null);
|
30
|
+
const [open, setOpen] = useState(false);
|
31
|
+
|
32
|
+
const handleDxRefTagActivate = useCallback(
|
33
|
+
(event: DxRefTagActivate) => {
|
34
|
+
const { refId, label, trigger: dxTrigger } = event;
|
35
|
+
setValue((value) => ({
|
36
|
+
...value,
|
37
|
+
link: { label, ref: refId },
|
38
|
+
pending: true,
|
39
|
+
}));
|
40
|
+
trigger.current = dxTrigger;
|
41
|
+
queueMicrotask(() => setOpen(true));
|
42
|
+
void onLookup?.({ label, ref: refId }).then((target) =>
|
43
|
+
setValue((value) => ({
|
44
|
+
...value,
|
45
|
+
target: target ?? undefined,
|
46
|
+
pending: false,
|
47
|
+
})),
|
48
|
+
);
|
49
|
+
},
|
50
|
+
[onLookup],
|
51
|
+
);
|
52
|
+
|
53
|
+
useEffect(() => {
|
54
|
+
return rootRef
|
55
|
+
? addEventListener(rootRef, 'dx-ref-tag-activate', handleDxRefTagActivate, customEventOptions)
|
56
|
+
: undefined;
|
57
|
+
}, [rootRef]);
|
58
|
+
|
59
|
+
return (
|
60
|
+
<RefDropdownMenuContextProvider pending={value.pending} link={value.link} target={value.target}>
|
61
|
+
<DropdownMenu.Root open={open} onOpenChange={setOpen}>
|
62
|
+
<DropdownMenu.VirtualTrigger virtualRef={trigger as unknown as RefObject<HTMLButtonElement>} />
|
63
|
+
<div role='none' className='contents' ref={setRootRef}>
|
64
|
+
{children}
|
65
|
+
</div>
|
66
|
+
</DropdownMenu.Root>
|
67
|
+
</RefDropdownMenuContextProvider>
|
68
|
+
);
|
69
|
+
};
|
70
|
+
|
71
|
+
export const RefDropdownMenu = {
|
72
|
+
Provider: RefDropdownMenuProvider,
|
73
|
+
};
|
74
|
+
|
75
|
+
export { useRefDropdownMenu };
|
76
|
+
|
77
|
+
export type { RefDropdownMenuProviderProps, RefDropdownMenuValue };
|
@@ -0,0 +1,75 @@
|
|
1
|
+
//
|
2
|
+
// Copyright 2025 DXOS.org
|
3
|
+
//
|
4
|
+
|
5
|
+
import { createContext } from '@radix-ui/react-context';
|
6
|
+
import React, { type PropsWithChildren, useRef, useState, useEffect, useCallback, type RefObject } from 'react';
|
7
|
+
|
8
|
+
import { addEventListener } from '@dxos/async';
|
9
|
+
import { type DxRefTag, type DxRefTagActivate } from '@dxos/lit-ui';
|
10
|
+
import { Popover } from '@dxos/react-ui';
|
11
|
+
|
12
|
+
import { type PreviewLinkRef, type PreviewLinkTarget, type PreviewLookup } from '../../extensions';
|
13
|
+
|
14
|
+
const customEventOptions = { capture: true, passive: false };
|
15
|
+
|
16
|
+
// Create a context for the dxn value.
|
17
|
+
type RefPopoverValue = Partial<{ link: PreviewLinkRef; target: PreviewLinkTarget; pending: boolean }>;
|
18
|
+
|
19
|
+
const REF_POPOVER = 'RefPopover';
|
20
|
+
const [RefPopoverContextProvider, useRefPopover] = createContext<RefPopoverValue>(REF_POPOVER, {});
|
21
|
+
|
22
|
+
type RefPopoverProviderProps = PropsWithChildren<{ onLookup?: PreviewLookup }>;
|
23
|
+
|
24
|
+
const RefPopoverProvider = ({ children, onLookup }: RefPopoverProviderProps) => {
|
25
|
+
const trigger = useRef<DxRefTag | null>(null);
|
26
|
+
const [value, setValue] = useState<RefPopoverValue>({});
|
27
|
+
const [rootRef, setRootRef] = useState<HTMLDivElement | null>(null);
|
28
|
+
const [open, setOpen] = useState(false);
|
29
|
+
|
30
|
+
const handleDxRefTagActivate = useCallback(
|
31
|
+
(event: DxRefTagActivate) => {
|
32
|
+
const { refId, label, trigger: dxTrigger } = event;
|
33
|
+
setValue((value) => ({
|
34
|
+
...value,
|
35
|
+
link: { label, ref: refId },
|
36
|
+
pending: true,
|
37
|
+
}));
|
38
|
+
trigger.current = dxTrigger;
|
39
|
+
queueMicrotask(() => setOpen(true));
|
40
|
+
void onLookup?.({ label, ref: refId }).then((target) =>
|
41
|
+
setValue((value) => ({
|
42
|
+
...value,
|
43
|
+
target: target ?? undefined,
|
44
|
+
pending: false,
|
45
|
+
})),
|
46
|
+
);
|
47
|
+
},
|
48
|
+
[onLookup],
|
49
|
+
);
|
50
|
+
|
51
|
+
useEffect(() => {
|
52
|
+
return rootRef
|
53
|
+
? addEventListener(rootRef, 'dx-ref-tag-activate', handleDxRefTagActivate, customEventOptions)
|
54
|
+
: undefined;
|
55
|
+
}, [rootRef]);
|
56
|
+
|
57
|
+
return (
|
58
|
+
<RefPopoverContextProvider pending={value.pending} link={value.link} target={value.target}>
|
59
|
+
<Popover.Root open={open} onOpenChange={setOpen}>
|
60
|
+
<Popover.VirtualTrigger virtualRef={trigger as unknown as RefObject<HTMLButtonElement>} />
|
61
|
+
<div role='none' className='contents' ref={setRootRef}>
|
62
|
+
{children}
|
63
|
+
</div>
|
64
|
+
</Popover.Root>
|
65
|
+
</RefPopoverContextProvider>
|
66
|
+
);
|
67
|
+
};
|
68
|
+
|
69
|
+
export const RefPopover = {
|
70
|
+
Provider: RefPopoverProvider,
|
71
|
+
};
|
72
|
+
|
73
|
+
export { useRefPopover };
|
74
|
+
|
75
|
+
export type { RefPopoverProviderProps, RefPopoverValue };
|
package/src/components/index.ts
CHANGED
package/src/defaults.ts
CHANGED
@@ -6,29 +6,28 @@ import { EditorView } from '@codemirror/view';
|
|
6
6
|
|
7
7
|
import { mx } from '@dxos/react-ui-theme';
|
8
8
|
|
9
|
+
import { type ThemeExtensionsOptions } from './extensions';
|
9
10
|
import { fontMono } from './styles';
|
10
11
|
|
11
|
-
const margin = '!mt-[1rem]';
|
12
|
-
|
13
12
|
/**
|
14
13
|
* CodeMirror content width.
|
15
14
|
* 40rem = 640px. Corresponds to initial plank width (Google docs, Stashpad, etc.)
|
16
15
|
* 50rem = 800px. Maximum content width for solo mode.
|
17
16
|
* NOTE: Max width - 4rem = 2rem left/right margin (or 2rem gutter plus 1rem left/right margin).
|
18
17
|
*/
|
19
|
-
|
20
|
-
export const editorContent = mx(margin, '!mli-auto w-full max-w-[min(50rem,100%-4rem)]');
|
18
|
+
export const editorWidth = '!mli-auto is-full max-is-[min(50rem,100%-4rem)]';
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
export const editorSlots: ThemeExtensionsOptions['slots'] = {
|
21
|
+
scroll: {
|
22
|
+
className: 'pbs-2',
|
23
|
+
},
|
24
|
+
content: {
|
25
|
+
className: editorWidth,
|
26
|
+
},
|
27
|
+
};
|
26
28
|
|
27
29
|
export const editorGutter = EditorView.theme({
|
28
|
-
// Match margin from content.
|
29
|
-
// Gutter = 2rem + 1rem margin.
|
30
30
|
'.cm-gutters': {
|
31
|
-
marginTop: '1rem',
|
32
31
|
paddingRight: '1rem',
|
33
32
|
},
|
34
33
|
});
|
@@ -50,6 +49,6 @@ export const stackItemContentEditorClassNames = (role?: string) =>
|
|
50
49
|
|
51
50
|
export const stackItemContentToolbarClassNames = (role?: string) =>
|
52
51
|
mx(
|
53
|
-
'
|
54
|
-
role === 'section' && 'sticky block-start-0
|
52
|
+
'relative z-[1] flex is-full bg-toolbarSurface border-be border-subduedSeparator',
|
53
|
+
role === 'section' && 'sticky block-start-0 -mbe-px min-is-0',
|
55
54
|
);
|
@@ -2,77 +2,54 @@
|
|
2
2
|
// Copyright 2024 DXOS.org
|
3
3
|
//
|
4
4
|
|
5
|
-
import { type
|
6
|
-
import { Decoration, EditorView } from '@codemirror/view';
|
5
|
+
import { type Extension, RangeSetBuilder } from '@codemirror/state';
|
6
|
+
import { Decoration, type DecorationSet, EditorView, ViewPlugin, type ViewUpdate } from '@codemirror/view';
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
import { Cursor } from '../util';
|
11
|
-
|
12
|
-
type Annotation = {
|
13
|
-
cursor: string;
|
14
|
-
};
|
8
|
+
const annotationMark = Decoration.mark({ class: 'cm-annotation' });
|
15
9
|
|
16
10
|
export type AnnotationOptions = {
|
17
11
|
match?: RegExp; // TODO(burdon): Update via hook (e.g., for search).
|
18
12
|
};
|
19
13
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
// Define annotation action in prompt. E.g., extract company names. Find links, etc.
|
25
|
-
// Show popover card. A16Z chain demo. Identify, extract, research, link. Multi-agent.
|
26
|
-
const match = (state: EditorState) => {
|
27
|
-
const annotations: Annotation[] = [];
|
28
|
-
const text = state.doc.toString();
|
29
|
-
if (options.match) {
|
30
|
-
const matches = text.matchAll(options.match);
|
31
|
-
for (const match of matches) {
|
32
|
-
const from = match.index!;
|
33
|
-
const to = from + match[0].length;
|
34
|
-
const cursor = Cursor.getCursorFromRange(state, { from, to });
|
35
|
-
annotations.push({ cursor });
|
36
|
-
}
|
37
|
-
}
|
38
|
-
|
39
|
-
return annotations;
|
40
|
-
};
|
41
|
-
|
42
|
-
const annotationsState = StateField.define<Annotation[]>({
|
43
|
-
create: (state) => {
|
44
|
-
return match(state);
|
45
|
-
},
|
46
|
-
update: (value, tr) => {
|
47
|
-
if (!tr.changes.empty) {
|
48
|
-
return match(tr.state);
|
49
|
-
}
|
50
|
-
|
51
|
-
return value;
|
52
|
-
},
|
53
|
-
});
|
54
|
-
|
14
|
+
/**
|
15
|
+
*
|
16
|
+
*/
|
17
|
+
export const annotations = ({ match }: AnnotationOptions = {}): Extension => {
|
55
18
|
return [
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
19
|
+
ViewPlugin.fromClass(
|
20
|
+
class {
|
21
|
+
decorations: DecorationSet = Decoration.none;
|
22
|
+
update(update: ViewUpdate) {
|
23
|
+
const builder = new RangeSetBuilder<Decoration>();
|
24
|
+
if (match) {
|
25
|
+
// Only process visible lines.
|
26
|
+
const { from, to } = update.view.viewport;
|
27
|
+
const text = update.state.doc.sliceString(from, to);
|
28
|
+
const matches = text.matchAll(match);
|
29
|
+
for (const m of matches) {
|
30
|
+
if (m.index !== undefined) {
|
31
|
+
// Adjust match position relative to viewport.
|
32
|
+
const start = from + m.index;
|
33
|
+
const end = start + m[0].length;
|
34
|
+
builder.add(start, end, annotationMark);
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
this.decorations = builder.finish();
|
40
|
+
}
|
41
|
+
},
|
42
|
+
{
|
43
|
+
decorations: (v) => v.decorations,
|
44
|
+
},
|
45
|
+
),
|
46
|
+
|
47
|
+
EditorView.theme({
|
48
|
+
'.cm-annotation': {
|
49
|
+
textDecoration: 'underline',
|
50
|
+
textDecorationStyle: 'wavy',
|
51
|
+
textDecorationColor: 'var(--dx-errorText)',
|
52
|
+
},
|
67
53
|
}),
|
68
|
-
styles,
|
69
54
|
];
|
70
55
|
};
|
71
|
-
|
72
|
-
const styles = EditorView.theme({
|
73
|
-
'.cm-annotation': {
|
74
|
-
textDecoration: 'underline',
|
75
|
-
textDecorationStyle: 'wavy',
|
76
|
-
textDecorationColor: 'var(--dx-error)',
|
77
|
-
},
|
78
|
-
});
|
@@ -17,7 +17,6 @@ import { keymap } from '@codemirror/view';
|
|
17
17
|
export type AutocompleteResult = Completion;
|
18
18
|
|
19
19
|
export type AutocompleteOptions = {
|
20
|
-
debug?: boolean;
|
21
20
|
activateOnTyping?: boolean;
|
22
21
|
override?: CompletionSource[];
|
23
22
|
onSearch?: (text: string) => Completion[];
|
@@ -30,7 +29,7 @@ export type AutocompleteOptions = {
|
|
30
29
|
/**
|
31
30
|
* Autocomplete extension.
|
32
31
|
*/
|
33
|
-
export const autocomplete = ({
|
32
|
+
export const autocomplete = ({ activateOnTyping, override, onSearch }: AutocompleteOptions = {}): Extension => {
|
34
33
|
const extensions: Extension[] = [
|
35
34
|
// https://codemirror.net/docs/ref/#view.keymap
|
36
35
|
// https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
|
@@ -40,16 +39,16 @@ export const autocomplete = ({ debug, activateOnTyping, override, onSearch }: Au
|
|
40
39
|
// https://codemirror.net/examples/autocompletion
|
41
40
|
// https://codemirror.net/docs/ref/#autocomplete.autocompletion
|
42
41
|
autocompletion({
|
43
|
-
activateOnTyping,
|
44
42
|
override,
|
45
|
-
|
46
|
-
|
43
|
+
activateOnTyping,
|
44
|
+
// closeOnBlur: false,
|
45
|
+
// tooltipClass: () => 'rounded-be pbe-1 border-separator',
|
47
46
|
}),
|
48
47
|
];
|
49
48
|
|
50
49
|
if (onSearch) {
|
51
50
|
extensions.push(
|
52
|
-
// TODO(burdon): Optional decoration via addToOptions
|
51
|
+
// TODO(burdon): Optional decoration via addToOptions.
|
53
52
|
markdownLanguage.data.of({
|
54
53
|
autocomplete: (context: CompletionContext): CompletionResult | null => {
|
55
54
|
const match = context.matchBefore(/\w*/);
|
@@ -5,26 +5,19 @@
|
|
5
5
|
import '@dxos-theme';
|
6
6
|
|
7
7
|
import '@preact/signals-react';
|
8
|
+
|
9
|
+
import { Repo } from '@automerge/automerge-repo';
|
10
|
+
import { BroadcastChannelNetworkAdapter } from '@automerge/automerge-repo-network-broadcastchannel';
|
8
11
|
import React, { useEffect, useState } from 'react';
|
9
12
|
|
10
|
-
import { Repo } from '@dxos/automerge/automerge-repo';
|
11
|
-
import { BroadcastChannelNetworkAdapter } from '@dxos/automerge/automerge-repo-network-broadcastchannel';
|
12
13
|
import { Expando } from '@dxos/echo-schema';
|
13
|
-
import {
|
14
|
-
DocAccessor,
|
15
|
-
Filter,
|
16
|
-
create,
|
17
|
-
createDocAccessor,
|
18
|
-
useQuery,
|
19
|
-
useSpace,
|
20
|
-
type Space,
|
21
|
-
} from '@dxos/react-client/echo';
|
14
|
+
import { DocAccessor, live, createDocAccessor, useQuery, useSpace, type Space, Query } from '@dxos/react-client/echo';
|
22
15
|
import { useIdentity, type Identity } from '@dxos/react-client/halo';
|
23
16
|
import { ClientRepeater, type ClientRepeatedComponentProps } from '@dxos/react-client/testing';
|
24
17
|
import { useThemeContext } from '@dxos/react-ui';
|
25
18
|
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
26
19
|
|
27
|
-
import {
|
20
|
+
import { editorSlots } from '../../defaults';
|
28
21
|
import { useTextEditor } from '../../hooks';
|
29
22
|
import translations from '../../translations';
|
30
23
|
import { createBasicExtensions, createDataExtensions, createThemeExtensions } from '../factories';
|
@@ -49,12 +42,7 @@ const Editor = ({ source, autoFocus, space, identity }: EditorProps) => {
|
|
49
42
|
initialValue: DocAccessor.getValue(source),
|
50
43
|
extensions: [
|
51
44
|
createBasicExtensions({ placeholder: 'Type here...' }),
|
52
|
-
createThemeExtensions({
|
53
|
-
themeMode,
|
54
|
-
slots: {
|
55
|
-
editor: { className: editorContent },
|
56
|
-
},
|
57
|
-
}),
|
45
|
+
createThemeExtensions({ themeMode, slots: editorSlots }),
|
58
46
|
createDataExtensions({ id: 'test', text: source, space, identity }),
|
59
47
|
],
|
60
48
|
autoFocus,
|
@@ -79,11 +67,12 @@ const Story = () => {
|
|
79
67
|
doc.text = initialContent;
|
80
68
|
});
|
81
69
|
|
82
|
-
const object2 = repo2.find<TestObject>(object1.url);
|
70
|
+
const object2 = await repo2.find<TestObject>(object1.url);
|
83
71
|
await object2.whenReady();
|
84
72
|
|
85
|
-
|
86
|
-
|
73
|
+
// TODO(mykola): Fix types.
|
74
|
+
setObject1({ handle: object1 as any, path: ['text'] });
|
75
|
+
setObject2({ handle: object2 as any, path: ['text'] });
|
87
76
|
});
|
88
77
|
}, []);
|
89
78
|
|
@@ -111,7 +100,7 @@ const EchoStory = ({ spaceKey }: ClientRepeatedComponentProps) => {
|
|
111
100
|
const identity = useIdentity();
|
112
101
|
const space = useSpace(spaceKey);
|
113
102
|
const [source, setSource] = useState<DocAccessor>();
|
114
|
-
const objects = useQuery
|
103
|
+
const objects = useQuery(space, Query.type(Expando, { type: 'test' }));
|
115
104
|
|
116
105
|
useEffect(() => {
|
117
106
|
if (!source && objects.length) {
|
@@ -139,9 +128,9 @@ export const WithEcho = {
|
|
139
128
|
createSpace
|
140
129
|
onSpaceCreated={async ({ space }) => {
|
141
130
|
space.db.add(
|
142
|
-
|
131
|
+
live({
|
143
132
|
type: 'test',
|
144
|
-
content:
|
133
|
+
content: live(Expando, { content: initialContent }),
|
145
134
|
}),
|
146
135
|
);
|
147
136
|
}}
|
@@ -2,17 +2,17 @@
|
|
2
2
|
// Copyright 2024 DXOS.org
|
3
3
|
//
|
4
4
|
|
5
|
+
import { type DocHandle, Repo } from '@automerge/automerge-repo';
|
5
6
|
import { EditorState } from '@codemirror/state';
|
6
7
|
import { EditorView } from '@codemirror/view';
|
7
8
|
import { render, screen } from '@testing-library/react';
|
8
9
|
// TODO(wittjosiah): Move to vitest expect (and remove from package.json).
|
9
10
|
import chai, { expect } from 'chai';
|
10
11
|
import chaiDom from 'chai-dom';
|
11
|
-
import get from 'lodash.get';
|
12
12
|
import React, { type FC, useEffect, useRef, useState } from 'react';
|
13
13
|
import { describe, test } from 'vitest';
|
14
14
|
|
15
|
-
import {
|
15
|
+
import { get } from '@dxos/util';
|
16
16
|
|
17
17
|
import { automerge } from './automerge';
|
18
18
|
|
@@ -24,7 +24,7 @@ const path = ['text'];
|
|
24
24
|
|
25
25
|
class Generator {
|
26
26
|
constructor(private readonly _handle: DocHandle<TestObject>) {}
|
27
|
-
update(text: string) {
|
27
|
+
update(text: string): void {
|
28
28
|
this._handle.change((doc: TestObject) => {
|
29
29
|
doc.text = text;
|
30
30
|
});
|
@@ -36,7 +36,8 @@ const Test: FC<{ handle: DocHandle<TestObject>; generator: Generator }> = ({ han
|
|
36
36
|
const [view, setView] = useState<EditorView>();
|
37
37
|
useEffect(() => {
|
38
38
|
const extensions = [
|
39
|
-
|
39
|
+
// TODO(mykola): Fix types.
|
40
|
+
automerge({ handle: handle as any, path }),
|
40
41
|
EditorView.updateListener.of((update) => {
|
41
42
|
if (view.state.doc.toString() === 'hello!') {
|
42
43
|
// Update editor.
|
@@ -46,7 +47,7 @@ const Test: FC<{ handle: DocHandle<TestObject>; generator: Generator }> = ({ han
|
|
46
47
|
];
|
47
48
|
|
48
49
|
const view = new EditorView({
|
49
|
-
state: EditorState.create({ doc: get(handle.
|
50
|
+
state: EditorState.create({ doc: get(handle.doc()!, path), extensions }),
|
50
51
|
parent: ref.current!,
|
51
52
|
});
|
52
53
|
|
@@ -4,10 +4,10 @@
|
|
4
4
|
// Ref: https://github.com/automerge/automerge-codemirror
|
5
5
|
//
|
6
6
|
|
7
|
+
import { next as A } from '@automerge/automerge';
|
7
8
|
import { StateField, type Extension } from '@codemirror/state';
|
8
9
|
import { EditorView, ViewPlugin } from '@codemirror/view';
|
9
10
|
|
10
|
-
import { next as A } from '@dxos/automerge/automerge';
|
11
11
|
import { type DocAccessor } from '@dxos/react-client/echo';
|
12
12
|
|
13
13
|
import { cursorConverter } from './cursor';
|
@@ -19,7 +19,7 @@ export const automerge = (accessor: DocAccessor): Extension => {
|
|
19
19
|
const syncState = StateField.define<State>({
|
20
20
|
create: () => ({
|
21
21
|
path: accessor.path.slice(),
|
22
|
-
lastHeads: A.getHeads(accessor.handle.
|
22
|
+
lastHeads: A.getHeads(accessor.handle.doc()!),
|
23
23
|
unreconciledTransactions: [],
|
24
24
|
}),
|
25
25
|
|
@@ -4,10 +4,9 @@
|
|
4
4
|
// Ref: https://github.com/automerge/automerge-codemirror
|
5
5
|
//
|
6
6
|
|
7
|
+
import { type Heads, type Prop } from '@automerge/automerge';
|
7
8
|
import { Annotation, StateEffect, type StateField, type EditorState, type Transaction } from '@codemirror/state';
|
8
9
|
|
9
|
-
import { type Heads, type Prop } from '@dxos/automerge/automerge';
|
10
|
-
|
11
10
|
export type State = {
|
12
11
|
path: Prop[];
|
13
12
|
lastHeads: Heads;
|