@dxos/react-ui-editor 0.8.4-main.e098934 → 0.8.4-main.ead640a
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/{chunk-22UMM3QJ.mjs → chunk-HL3YF6WC.mjs} +2 -2
- package/dist/lib/browser/chunk-HL3YF6WC.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +3555 -3484
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs.map +2 -2
- package/dist/lib/browser/types/index.mjs +1 -1
- package/dist/lib/node-esm/{chunk-YXYQPV6R.mjs → chunk-YJZGD3LY.mjs} +2 -2
- package/dist/lib/node-esm/chunk-YJZGD3LY.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +3555 -3484
- 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.map +2 -2
- package/dist/lib/node-esm/types/index.mjs +1 -1
- package/dist/types/src/components/Editor/Editor.d.ts +24 -9
- package/dist/types/src/components/Editor/Editor.d.ts.map +1 -1
- package/dist/types/src/components/Editor/Editor.stories.d.ts +27 -0
- package/dist/types/src/components/Editor/Editor.stories.d.ts.map +1 -0
- package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -1
- package/dist/types/src/components/EditorToolbar/util.d.ts +1 -1
- package/dist/types/src/components/index.d.ts +0 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/extensions/{autocomplete.d.ts → autocomplete/autocomplete.d.ts} +1 -1
- package/dist/types/src/extensions/autocomplete/autocomplete.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/index.d.ts +5 -0
- package/dist/types/src/extensions/autocomplete/index.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/match.d.ts +13 -0
- package/dist/types/src/extensions/autocomplete/match.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts +20 -0
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts +10 -0
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/automerge.d.ts +1 -1
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts +1 -1
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/sync.d.ts +2 -2
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
- package/dist/types/src/extensions/autoscroll.d.ts +2 -2
- package/dist/types/src/extensions/autoscroll.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts +7 -2
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/focus.d.ts.map +1 -1
- package/dist/types/src/extensions/folding.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +2 -1
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/json.d.ts +1 -1
- package/dist/types/src/extensions/json.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/modes.d.ts +1 -1
- package/dist/types/src/extensions/modes.d.ts.map +1 -1
- package/dist/types/src/extensions/outliner/menu.d.ts +8 -0
- package/dist/types/src/extensions/outliner/menu.d.ts.map +1 -0
- package/dist/types/src/extensions/popover/PopoverMenuProvider.d.ts +36 -0
- package/dist/types/src/extensions/popover/PopoverMenuProvider.d.ts.map +1 -0
- package/dist/types/src/extensions/popover/index.d.ts +8 -0
- package/dist/types/src/extensions/popover/index.d.ts.map +1 -0
- package/dist/types/src/extensions/popover/menu-presets.d.ts +4 -0
- package/dist/types/src/extensions/popover/menu-presets.d.ts.map +1 -0
- package/dist/types/src/extensions/popover/menu.d.ts +24 -0
- package/dist/types/src/extensions/popover/menu.d.ts.map +1 -0
- package/dist/types/src/extensions/popover/modal.d.ts +7 -0
- package/dist/types/src/extensions/popover/modal.d.ts.map +1 -0
- package/dist/types/src/extensions/popover/popover.d.ts +47 -0
- package/dist/types/src/extensions/popover/popover.d.ts.map +1 -0
- package/dist/types/src/extensions/popover/usePopoverMenu.d.ts +34 -0
- package/dist/types/src/extensions/popover/usePopoverMenu.d.ts.map +1 -0
- package/dist/types/src/extensions/popover/util.d.ts +8 -0
- package/dist/types/src/extensions/popover/util.d.ts.map +1 -0
- package/dist/types/src/extensions/preview/preview.d.ts +0 -1
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -1
- package/dist/types/src/extensions/state.d.ts +2 -0
- package/dist/types/src/extensions/state.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/streamer.d.ts.map +1 -1
- package/dist/types/src/extensions/tags/xml-tags.d.ts +1 -0
- package/dist/types/src/extensions/tags/xml-tags.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts +4 -8
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/stories/{Command.stories.d.ts → CommandDialog.stories.d.ts} +2 -3
- package/dist/types/src/stories/CommandDialog.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Comments.stories.d.ts +3 -4
- package/dist/types/src/stories/Comments.stories.d.ts.map +1 -1
- package/dist/types/src/stories/EditorToolbar.stories.d.ts +1 -2
- package/dist/types/src/stories/EditorToolbar.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Experimental.stories.d.ts +3 -4
- package/dist/types/src/stories/Experimental.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Markdown.stories.d.ts +3 -4
- package/dist/types/src/stories/Markdown.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Outliner.stories.d.ts +0 -1
- package/dist/types/src/stories/Outliner.stories.d.ts.map +1 -1
- package/dist/types/src/stories/{CommandMenu.stories.d.ts → Popover.stories.d.ts} +6 -6
- package/dist/types/src/stories/Popover.stories.d.ts.map +1 -0
- package/dist/types/src/stories/Preview.stories.d.ts +3 -4
- package/dist/types/src/stories/Preview.stories.d.ts.map +1 -1
- package/dist/types/src/stories/Tags.stories.d.ts +0 -1
- package/dist/types/src/stories/Tags.stories.d.ts.map +1 -1
- package/dist/types/src/stories/TextEditor.stories.d.ts +3 -5
- package/dist/types/src/stories/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/stories/components/EditorStory.d.ts +5 -5
- package/dist/types/src/stories/components/EditorStory.d.ts.map +1 -1
- package/dist/types/src/styles/theme.d.ts.map +1 -1
- package/dist/types/src/testing/PreviewPopover.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +1 -1
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +0 -1
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +54 -51
- package/src/components/Editor/Editor.stories.tsx +69 -0
- package/src/components/Editor/Editor.tsx +57 -14
- package/src/components/EditorToolbar/EditorToolbar.tsx +1 -0
- package/src/components/index.ts +0 -1
- package/src/extensions/{autocomplete.ts → autocomplete/autocomplete.ts} +2 -1
- package/src/extensions/autocomplete/index.ts +8 -0
- package/src/extensions/autocomplete/match.ts +46 -0
- package/src/extensions/{command → autocomplete}/placeholder.ts +21 -17
- package/src/extensions/{command → autocomplete}/typeahead.ts +6 -48
- package/src/extensions/automerge/automerge.stories.tsx +8 -8
- package/src/extensions/automerge/automerge.ts +28 -9
- package/src/extensions/automerge/sync.ts +7 -3
- package/src/extensions/autoscroll.ts +29 -29
- package/src/extensions/factories.ts +41 -12
- package/src/extensions/focus.ts +5 -4
- package/src/extensions/folding.tsx +4 -6
- package/src/extensions/hashtag.tsx +2 -2
- package/src/extensions/index.ts +2 -1
- package/src/extensions/json.ts +1 -1
- package/src/extensions/markdown/bundle.ts +16 -4
- package/src/extensions/markdown/decorate.ts +1 -0
- package/src/extensions/modes.ts +2 -2
- package/src/extensions/{command/floating-menu.ts → outliner/menu.ts} +9 -9
- package/src/extensions/outliner/outliner.ts +2 -2
- package/src/extensions/popover/PopoverMenuProvider.tsx +221 -0
- package/src/extensions/popover/index.ts +12 -0
- package/src/extensions/popover/menu-presets.ts +124 -0
- package/src/extensions/popover/menu.ts +67 -0
- package/src/extensions/popover/modal.ts +24 -0
- package/src/extensions/popover/popover.ts +291 -0
- package/src/extensions/popover/usePopoverMenu.ts +173 -0
- package/src/extensions/popover/util.ts +29 -0
- package/src/extensions/preview/index.ts +1 -1
- package/src/extensions/preview/preview.ts +0 -2
- package/src/extensions/selection.ts +2 -2
- package/src/extensions/state.ts +7 -0
- package/src/extensions/tags/streamer.ts +4 -5
- package/src/extensions/tags/xml-tags.ts +59 -1
- package/src/hooks/useTextEditor.ts +27 -27
- package/src/stories/{Command.stories.tsx → CommandDialog.stories.tsx} +10 -22
- package/src/stories/Comments.stories.tsx +5 -5
- package/src/stories/EditorToolbar.stories.tsx +6 -5
- package/src/stories/Experimental.stories.tsx +6 -6
- package/src/stories/Markdown.stories.tsx +5 -5
- package/src/stories/Outliner.stories.tsx +21 -14
- package/src/stories/Popover.stories.tsx +163 -0
- package/src/stories/Preview.stories.tsx +5 -5
- package/src/stories/Tags.stories.tsx +5 -5
- package/src/stories/TextEditor.stories.tsx +7 -32
- package/src/stories/components/EditorStory.tsx +7 -5
- package/src/styles/theme.ts +12 -10
- package/src/testing/PreviewPopover.tsx +2 -0
- package/src/types/types.ts +1 -1
- package/src/util/index.ts +0 -1
- package/dist/lib/browser/chunk-22UMM3QJ.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-YXYQPV6R.mjs.map +0 -7
- package/dist/types/src/components/CommandMenu/CommandMenu.d.ts +0 -38
- package/dist/types/src/components/CommandMenu/CommandMenu.d.ts.map +0 -1
- package/dist/types/src/components/CommandMenu/index.d.ts +0 -2
- package/dist/types/src/components/CommandMenu/index.d.ts.map +0 -1
- package/dist/types/src/extensions/autocomplete.d.ts.map +0 -1
- package/dist/types/src/extensions/command/action.d.ts +0 -17
- package/dist/types/src/extensions/command/action.d.ts.map +0 -1
- package/dist/types/src/extensions/command/command-menu.d.ts +0 -20
- package/dist/types/src/extensions/command/command-menu.d.ts.map +0 -1
- package/dist/types/src/extensions/command/command.d.ts +0 -6
- package/dist/types/src/extensions/command/command.d.ts.map +0 -1
- package/dist/types/src/extensions/command/floating-menu.d.ts +0 -7
- package/dist/types/src/extensions/command/floating-menu.d.ts.map +0 -1
- package/dist/types/src/extensions/command/hint.d.ts +0 -19
- package/dist/types/src/extensions/command/hint.d.ts.map +0 -1
- package/dist/types/src/extensions/command/index.d.ts +0 -7
- package/dist/types/src/extensions/command/index.d.ts.map +0 -1
- package/dist/types/src/extensions/command/placeholder.d.ts +0 -10
- package/dist/types/src/extensions/command/placeholder.d.ts.map +0 -1
- package/dist/types/src/extensions/command/state.d.ts +0 -16
- package/dist/types/src/extensions/command/state.d.ts.map +0 -1
- package/dist/types/src/extensions/command/typeahead.d.ts +0 -22
- package/dist/types/src/extensions/command/typeahead.d.ts.map +0 -1
- package/dist/types/src/extensions/command/useCommandMenu.d.ts +0 -25
- package/dist/types/src/extensions/command/useCommandMenu.d.ts.map +0 -1
- package/dist/types/src/stories/Command.stories.d.ts.map +0 -1
- package/dist/types/src/stories/CommandMenu.stories.d.ts.map +0 -1
- package/dist/types/src/util/domino.d.ts +0 -18
- package/dist/types/src/util/domino.d.ts.map +0 -1
- package/src/components/CommandMenu/CommandMenu.tsx +0 -346
- package/src/components/CommandMenu/index.ts +0 -5
- package/src/extensions/command/action.ts +0 -55
- package/src/extensions/command/command-menu.ts +0 -211
- package/src/extensions/command/command.ts +0 -34
- package/src/extensions/command/hint.ts +0 -103
- package/src/extensions/command/index.ts +0 -10
- package/src/extensions/command/state.ts +0 -90
- package/src/extensions/command/useCommandMenu.ts +0 -115
- package/src/stories/CommandMenu.stories.tsx +0 -158
- package/src/util/domino.ts +0 -51
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import { EditorState, type EditorStateConfig, type Text } from '@codemirror/state';
|
|
6
6
|
import { EditorView } from '@codemirror/view';
|
|
7
|
-
import { type TabsterTypes, useFocusableGroup } from '@fluentui/react-tabster';
|
|
8
7
|
import {
|
|
8
|
+
type ComponentPropsWithoutRef,
|
|
9
9
|
type DependencyList,
|
|
10
10
|
type KeyboardEventHandler,
|
|
11
11
|
type RefObject,
|
|
@@ -17,9 +17,9 @@ import {
|
|
|
17
17
|
} from 'react';
|
|
18
18
|
|
|
19
19
|
import { log } from '@dxos/log';
|
|
20
|
-
import { type MaybeProvider, getProviderValue,
|
|
20
|
+
import { type MaybeProvider, getProviderValue, isTruthy } from '@dxos/util';
|
|
21
21
|
|
|
22
|
-
import { type EditorSelection, createEditorStateTransaction, documentId,
|
|
22
|
+
import { type EditorSelection, createEditorStateTransaction, documentId, modalStateField } from '../extensions';
|
|
23
23
|
import { debugDispatcher } from '../util';
|
|
24
24
|
|
|
25
25
|
let instanceCount = 0;
|
|
@@ -34,13 +34,9 @@ export type CursorInfo = {
|
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
export type UseTextEditor = {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
focusAttributes?: TabsterTypes.TabsterDOMAttribute & {
|
|
41
|
-
tabIndex: 0;
|
|
42
|
-
onKeyUp: KeyboardEventHandler<HTMLDivElement>;
|
|
43
|
-
};
|
|
37
|
+
parentRef: RefObject<HTMLDivElement | null>;
|
|
38
|
+
view: EditorView | null;
|
|
39
|
+
focusAttributes?: ComponentPropsWithoutRef<'div'>;
|
|
44
40
|
};
|
|
45
41
|
|
|
46
42
|
export type UseTextEditorProps = Pick<EditorStateConfig, 'extensions'> & {
|
|
@@ -66,11 +62,11 @@ export const useTextEditor = (
|
|
|
66
62
|
|
|
67
63
|
// NOTE: Increments by 2 in strict mode.
|
|
68
64
|
const [instanceId] = useState(() => `text-editor-${++instanceCount}`);
|
|
69
|
-
const [view, setView] = useState<EditorView>();
|
|
65
|
+
const [view, setView] = useState<EditorView | null>(null);
|
|
70
66
|
const parentRef = useRef<HTMLDivElement>(null);
|
|
71
67
|
|
|
72
68
|
useEffect(() => {
|
|
73
|
-
let view: EditorView;
|
|
69
|
+
let view: EditorView | null = null;
|
|
74
70
|
if (parentRef.current) {
|
|
75
71
|
log('create', { id, instanceId, doc: initialValue?.length ?? 0 });
|
|
76
72
|
|
|
@@ -96,7 +92,7 @@ export const useTextEditor = (
|
|
|
96
92
|
EditorView.exceptionSink.of((err) => {
|
|
97
93
|
log.catch(err);
|
|
98
94
|
}),
|
|
99
|
-
].filter(
|
|
95
|
+
].filter(isTruthy),
|
|
100
96
|
});
|
|
101
97
|
|
|
102
98
|
// https://codemirror.net/docs/ref/#view.EditorViewConfig
|
|
@@ -143,23 +139,28 @@ export const useTextEditor = (
|
|
|
143
139
|
}
|
|
144
140
|
}, [autoFocus, view]);
|
|
145
141
|
|
|
146
|
-
const focusableGroupAttrs = useFocusableGroup({
|
|
147
|
-
tabBehavior: 'limited',
|
|
148
|
-
ignoreDefaultKeydown: {
|
|
149
|
-
Escape: view?.state.facet(editorInputMode).noTabster,
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
|
|
153
142
|
// Focus editor on Enter (e.g., when tabbing to this component).
|
|
154
|
-
const
|
|
143
|
+
const handleKeyDown = useCallback<KeyboardEventHandler<HTMLDivElement>>(
|
|
155
144
|
(event) => {
|
|
156
145
|
const { key, target, currentTarget } = event;
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
146
|
+
switch (key) {
|
|
147
|
+
case 'Escape': {
|
|
148
|
+
// Check if popover is open.
|
|
149
|
+
const modal = view?.state.field(modalStateField, false);
|
|
150
|
+
if (modal) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Focus the closest focusable parent.
|
|
155
|
+
const element = view?.contentDOM.closest('[tabindex="0"]') as HTMLDivElement | null;
|
|
156
|
+
element?.focus();
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
case 'Enter': {
|
|
160
|
+
if (target === currentTarget) {
|
|
160
161
|
view?.focus();
|
|
161
|
-
break;
|
|
162
162
|
}
|
|
163
|
+
break;
|
|
163
164
|
}
|
|
164
165
|
}
|
|
165
166
|
},
|
|
@@ -171,8 +172,7 @@ export const useTextEditor = (
|
|
|
171
172
|
view,
|
|
172
173
|
focusAttributes: {
|
|
173
174
|
tabIndex: 0 as const,
|
|
174
|
-
|
|
175
|
-
onKeyUp: handleKeyUp,
|
|
175
|
+
onKeyDown: handleKeyDown,
|
|
176
176
|
},
|
|
177
177
|
};
|
|
178
178
|
};
|
|
@@ -2,28 +2,25 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
import React, { type KeyboardEvent, useState } from 'react';
|
|
9
7
|
|
|
10
8
|
import { Button, Icon, Input } from '@dxos/react-ui';
|
|
9
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
11
10
|
import { mx } from '@dxos/react-ui-theme';
|
|
12
|
-
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
13
11
|
|
|
14
12
|
import { editorWidth } from '../defaults';
|
|
15
|
-
import { type Action, command, floatingMenu } from '../extensions';
|
|
16
13
|
import { str } from '../testing';
|
|
17
|
-
import { createRenderer } from '../util';
|
|
18
14
|
|
|
19
15
|
import { EditorStory } from './components';
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
// TODO(burdon): Reimplement with Popover.
|
|
18
|
+
const CommandDialog = ({ onAction }: { onAction: (action?: any) => void }) => {
|
|
22
19
|
const [text, setText] = useState('');
|
|
23
20
|
|
|
24
21
|
const handleInsert = () => {
|
|
25
22
|
// TODO(burdon): Use queue ref.
|
|
26
|
-
const link =
|
|
23
|
+
const link = ``;
|
|
27
24
|
onAction(text.length ? { type: 'insert', text: link } : undefined);
|
|
28
25
|
};
|
|
29
26
|
|
|
@@ -66,21 +63,12 @@ const CommandDialog = ({ onAction }: { onAction: (action?: Action) => void }) =>
|
|
|
66
63
|
};
|
|
67
64
|
|
|
68
65
|
const meta = {
|
|
69
|
-
title: 'ui/react-ui-editor/
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
floatingMenu(),
|
|
76
|
-
command({
|
|
77
|
-
renderDialog: createRenderer(CommandDialog),
|
|
78
|
-
onHint: () => "Press '/' for commands",
|
|
79
|
-
}),
|
|
80
|
-
]}
|
|
81
|
-
/>
|
|
82
|
-
),
|
|
83
|
-
parameters: { layout: 'fullscreen' },
|
|
66
|
+
title: 'ui/react-ui-editor/CommandDialog',
|
|
67
|
+
render: () => <EditorStory text={str('# Command', '', '')} extensions={[]} />,
|
|
68
|
+
decorators: [withTheme],
|
|
69
|
+
parameters: {
|
|
70
|
+
layout: 'fullscreen',
|
|
71
|
+
},
|
|
84
72
|
} satisfies Meta<typeof Button>;
|
|
85
73
|
|
|
86
74
|
export default meta;
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { effect, useSignal } from '@preact/signals-react';
|
|
8
6
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
9
7
|
import React, { type FC } from 'react';
|
|
@@ -11,7 +9,7 @@ import React, { type FC } from 'react';
|
|
|
11
9
|
import { keySymbols, parseShortcut } from '@dxos/keyboard';
|
|
12
10
|
import { PublicKey } from '@dxos/keys';
|
|
13
11
|
import { log } from '@dxos/log';
|
|
14
|
-
import {
|
|
12
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
15
13
|
|
|
16
14
|
import { annotations, comments, createExternalCommentSync } from '../extensions';
|
|
17
15
|
import { str } from '../testing';
|
|
@@ -23,8 +21,10 @@ import { EditorStory, content, longText } from './components';
|
|
|
23
21
|
const meta = {
|
|
24
22
|
title: 'ui/react-ui-editor/Comments',
|
|
25
23
|
component: EditorStory,
|
|
26
|
-
decorators: [withTheme
|
|
27
|
-
parameters: {
|
|
24
|
+
decorators: [withTheme],
|
|
25
|
+
parameters: {
|
|
26
|
+
layout: 'fullscreen',
|
|
27
|
+
},
|
|
28
28
|
} satisfies Meta<typeof EditorStory>;
|
|
29
29
|
|
|
30
30
|
export default meta;
|
|
@@ -2,15 +2,13 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
import React, { useCallback, useState } from 'react';
|
|
9
7
|
|
|
10
8
|
import { invariant } from '@dxos/invariant';
|
|
11
9
|
import { useThemeContext } from '@dxos/react-ui';
|
|
10
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
12
11
|
import { attentionSurface, mx } from '@dxos/react-ui-theme';
|
|
13
|
-
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
14
12
|
|
|
15
13
|
import { EditorToolbar, useEditorToolbarState } from '../components';
|
|
16
14
|
import { editorWidth } from '../defaults';
|
|
@@ -78,8 +76,11 @@ const DefaultStory = ({ autoFocus, initialValue, placeholder }: StoryProps) => {
|
|
|
78
76
|
const meta = {
|
|
79
77
|
title: 'ui/react-ui-editor/EditorToolbar',
|
|
80
78
|
render: DefaultStory,
|
|
81
|
-
decorators: [withTheme
|
|
82
|
-
parameters: {
|
|
79
|
+
decorators: [withTheme],
|
|
80
|
+
parameters: {
|
|
81
|
+
layout: 'fullscreen',
|
|
82
|
+
translations,
|
|
83
|
+
},
|
|
83
84
|
} satisfies Meta<typeof DefaultStory>;
|
|
84
85
|
|
|
85
86
|
export default meta;
|
|
@@ -2,15 +2,13 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
import defaultsDeep from 'lodash.defaultsdeep';
|
|
9
7
|
import React from 'react';
|
|
10
8
|
|
|
11
9
|
import { log } from '@dxos/log';
|
|
12
10
|
import { faker } from '@dxos/random';
|
|
13
|
-
import {
|
|
11
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
14
12
|
|
|
15
13
|
import { blast, defaultOptions, dropFile, typewriter } from '../extensions';
|
|
16
14
|
import { str } from '../testing';
|
|
@@ -20,8 +18,10 @@ import { EditorStory, content } from './components';
|
|
|
20
18
|
const meta = {
|
|
21
19
|
title: 'ui/react-ui-editor/Experimental',
|
|
22
20
|
component: EditorStory,
|
|
23
|
-
decorators: [withTheme
|
|
24
|
-
parameters: {
|
|
21
|
+
decorators: [withTheme],
|
|
22
|
+
parameters: {
|
|
23
|
+
layout: 'fullscreen',
|
|
24
|
+
},
|
|
25
25
|
} satisfies Meta<typeof EditorStory>;
|
|
26
26
|
|
|
27
27
|
export default meta;
|
|
@@ -32,7 +32,7 @@ type Story = StoryObj<typeof meta>;
|
|
|
32
32
|
// Typewriter
|
|
33
33
|
//
|
|
34
34
|
|
|
35
|
-
const typewriterItems = localStorage.getItem('dxos.org/
|
|
35
|
+
const typewriterItems = localStorage.getItem('dxos.org/testing/typewriter')?.split(',');
|
|
36
36
|
|
|
37
37
|
export const Typewriter: Story = {
|
|
38
38
|
render: () => (
|
|
@@ -2,13 +2,11 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { markdown } from '@codemirror/lang-markdown';
|
|
8
6
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
9
7
|
import React from 'react';
|
|
10
8
|
|
|
11
|
-
import {
|
|
9
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
12
10
|
|
|
13
11
|
import { decorateMarkdown, image, linkTooltip, table } from '../extensions';
|
|
14
12
|
import { str } from '../testing';
|
|
@@ -18,8 +16,10 @@ import { EditorStory, content, defaultExtensions, headings, renderLinkTooltip, t
|
|
|
18
16
|
const meta = {
|
|
19
17
|
title: 'ui/react-ui-editor/Markdown',
|
|
20
18
|
component: EditorStory,
|
|
21
|
-
decorators: [withTheme
|
|
22
|
-
parameters: {
|
|
19
|
+
decorators: [withTheme],
|
|
20
|
+
parameters: {
|
|
21
|
+
layout: 'fullscreen',
|
|
22
|
+
},
|
|
23
23
|
} satisfies Meta<typeof EditorStory>;
|
|
24
24
|
|
|
25
25
|
export default meta;
|
|
@@ -2,17 +2,22 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type EditorView } from '@codemirror/view';
|
|
8
6
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
9
7
|
import React, { useMemo, useRef } from 'react';
|
|
10
8
|
|
|
9
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
11
10
|
import { withAttention } from '@dxos/react-ui-attention/testing';
|
|
12
|
-
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
13
11
|
|
|
14
|
-
import {
|
|
15
|
-
|
|
12
|
+
import {
|
|
13
|
+
type PopoverMenuGroup,
|
|
14
|
+
PopoverMenuProvider,
|
|
15
|
+
deleteItem,
|
|
16
|
+
hashtag,
|
|
17
|
+
listItemToString,
|
|
18
|
+
outliner,
|
|
19
|
+
treeFacet,
|
|
20
|
+
} from '../extensions';
|
|
16
21
|
import { str } from '../testing';
|
|
17
22
|
|
|
18
23
|
import { EditorStory } from './components';
|
|
@@ -24,7 +29,7 @@ type StoryProps = {
|
|
|
24
29
|
const DefaultStory = ({ text }: StoryProps) => {
|
|
25
30
|
const viewRef = useRef<EditorView>(null);
|
|
26
31
|
|
|
27
|
-
const commandGroups:
|
|
32
|
+
const commandGroups: PopoverMenuGroup[] = useMemo(
|
|
28
33
|
() => [
|
|
29
34
|
{
|
|
30
35
|
id: 'outliner-actions',
|
|
@@ -43,11 +48,12 @@ const DefaultStory = ({ text }: StoryProps) => {
|
|
|
43
48
|
);
|
|
44
49
|
|
|
45
50
|
return (
|
|
46
|
-
<
|
|
51
|
+
<PopoverMenuProvider
|
|
52
|
+
view={viewRef.current}
|
|
47
53
|
groups={commandGroups}
|
|
48
|
-
onSelect={(item
|
|
49
|
-
if (
|
|
50
|
-
return item.onSelect(
|
|
54
|
+
onSelect={({ view, item }) => {
|
|
55
|
+
if (item.onSelect) {
|
|
56
|
+
return item.onSelect(view, view.state.selection.main.head);
|
|
51
57
|
}
|
|
52
58
|
}}
|
|
53
59
|
>
|
|
@@ -55,7 +61,6 @@ const DefaultStory = ({ text }: StoryProps) => {
|
|
|
55
61
|
ref={viewRef}
|
|
56
62
|
text={text}
|
|
57
63
|
extensions={[outliner(), hashtag()]}
|
|
58
|
-
placeholder=''
|
|
59
64
|
debug='raw+tree'
|
|
60
65
|
debugCustom={(view) => {
|
|
61
66
|
const tree = view.state.facet(treeFacet);
|
|
@@ -64,15 +69,17 @@ const DefaultStory = ({ text }: StoryProps) => {
|
|
|
64
69
|
return <pre className='p-1 overflow-auto text-xs text-green-800 dark:text-green-200'>{lines.join('\n')}</pre>;
|
|
65
70
|
}}
|
|
66
71
|
/>
|
|
67
|
-
</
|
|
72
|
+
</PopoverMenuProvider>
|
|
68
73
|
);
|
|
69
74
|
};
|
|
70
75
|
|
|
71
76
|
const meta = {
|
|
72
77
|
title: 'ui/react-ui-editor/Outliner',
|
|
73
78
|
render: DefaultStory,
|
|
74
|
-
decorators: [
|
|
75
|
-
parameters: {
|
|
79
|
+
decorators: [withTheme, withAttention],
|
|
80
|
+
parameters: {
|
|
81
|
+
layout: 'fullscreen',
|
|
82
|
+
},
|
|
76
83
|
} satisfies Meta<typeof DefaultStory>;
|
|
77
84
|
|
|
78
85
|
export default meta;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type EditorView } from '@codemirror/view';
|
|
6
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
7
|
+
import React, { useCallback, useState } from 'react';
|
|
8
|
+
|
|
9
|
+
import { Obj, Query } from '@dxos/echo';
|
|
10
|
+
import { faker } from '@dxos/random';
|
|
11
|
+
import { useClientProvider, withClientProvider } from '@dxos/react-client/testing';
|
|
12
|
+
import { Domino } from '@dxos/react-ui';
|
|
13
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
14
|
+
import { Testing, type ValueGenerator, createObjectFactory } from '@dxos/schema/testing';
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
type PopoverMenuGroup,
|
|
18
|
+
type PopoverMenuItem,
|
|
19
|
+
PopoverMenuProvider,
|
|
20
|
+
type UsePopoverMenuProps,
|
|
21
|
+
createMenuGroup,
|
|
22
|
+
filterMenuGroups,
|
|
23
|
+
formattingCommands,
|
|
24
|
+
insertAtCursor,
|
|
25
|
+
insertAtLineStart,
|
|
26
|
+
linkSlashCommands,
|
|
27
|
+
usePopoverMenu,
|
|
28
|
+
} from '../extensions';
|
|
29
|
+
import { str } from '../testing';
|
|
30
|
+
|
|
31
|
+
import { EditorStory } from './components';
|
|
32
|
+
|
|
33
|
+
const generator: ValueGenerator = faker as any;
|
|
34
|
+
|
|
35
|
+
const customCompletions: PopoverMenuGroup = createMenuGroup({
|
|
36
|
+
id: 'test',
|
|
37
|
+
items: ['Hello world!', 'Hello DXOS', 'Hello Composer', 'https://dxos.org'],
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const placeholder = (trigger: string[]) =>
|
|
41
|
+
Domino.of('div')
|
|
42
|
+
.children(
|
|
43
|
+
Domino.of('span').text('Press'),
|
|
44
|
+
...trigger.map((trigger) =>
|
|
45
|
+
Domino.of('span')
|
|
46
|
+
.text(trigger)
|
|
47
|
+
.classNames('border border-separator rounded-sm mx-1 pis-1 pie-1 pbs-[2px] pbe-[3px]'),
|
|
48
|
+
),
|
|
49
|
+
Domino.of('span').text('for commands'),
|
|
50
|
+
)
|
|
51
|
+
.build();
|
|
52
|
+
|
|
53
|
+
type StoryProps = Omit<UsePopoverMenuProps, 'viewRef'> & { text: string };
|
|
54
|
+
|
|
55
|
+
const DefaultStory = ({ text, ...props }: StoryProps) => {
|
|
56
|
+
const [view, setView] = useState<EditorView | null>(null);
|
|
57
|
+
const { groupsRef, extension, ...menuProps } = usePopoverMenu(props);
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<PopoverMenuProvider view={view} groups={groupsRef.current} {...menuProps}>
|
|
61
|
+
<EditorStory ref={setView} text={text} extensions={extension} />
|
|
62
|
+
</PopoverMenuProvider>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const LinkStory = (args: StoryProps) => {
|
|
67
|
+
const { space } = useClientProvider();
|
|
68
|
+
const getMenu = useCallback<NonNullable<UsePopoverMenuProps['getMenu']>>(
|
|
69
|
+
async ({ text, trigger }): Promise<PopoverMenuGroup[]> => {
|
|
70
|
+
if (trigger === '/') {
|
|
71
|
+
return filterMenuGroups([linkSlashCommands], (item) =>
|
|
72
|
+
text ? (item.label as string).toLowerCase().includes(text.toLowerCase()) : true,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!space) {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const name = text?.startsWith('@') ? text.slice(1).toLowerCase() : (text?.toLowerCase() ?? '');
|
|
81
|
+
const result = await space?.db.query(Query.type(Testing.Contact)).run();
|
|
82
|
+
const items = result.objects
|
|
83
|
+
.filter((object) => object.name.toLowerCase().includes(name))
|
|
84
|
+
.map(
|
|
85
|
+
(object): PopoverMenuItem => ({
|
|
86
|
+
id: object.id,
|
|
87
|
+
label: object.name,
|
|
88
|
+
icon: 'ph--user--regular',
|
|
89
|
+
onSelect: (view, head) => {
|
|
90
|
+
const link = `[${object.name}](${Obj.getDXN(object)})`;
|
|
91
|
+
if (text?.startsWith('@')) {
|
|
92
|
+
insertAtLineStart(view, head, `!${link}\n`);
|
|
93
|
+
} else {
|
|
94
|
+
insertAtCursor(view, head, `${link} `);
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
}),
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
return [{ id: 'test', items }];
|
|
101
|
+
},
|
|
102
|
+
[space],
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
return <DefaultStory {...args} getMenu={getMenu} />;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const meta = {
|
|
109
|
+
title: 'ui/react-ui-editor/Popover',
|
|
110
|
+
render: DefaultStory,
|
|
111
|
+
decorators: [withTheme],
|
|
112
|
+
parameters: {
|
|
113
|
+
layout: 'fullscreen',
|
|
114
|
+
},
|
|
115
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
116
|
+
|
|
117
|
+
export default meta;
|
|
118
|
+
|
|
119
|
+
type Story = StoryObj<typeof meta>;
|
|
120
|
+
|
|
121
|
+
export const Default: Story = {
|
|
122
|
+
args: {
|
|
123
|
+
text: str('# Autocomplete', '', ''),
|
|
124
|
+
triggerKey: 'Ctrl-Space',
|
|
125
|
+
filter: true,
|
|
126
|
+
getMenu: () => [customCompletions],
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export const Formatting: Story = {
|
|
131
|
+
args: {
|
|
132
|
+
text: str('# Slash command', '', ''),
|
|
133
|
+
trigger: '/',
|
|
134
|
+
placeholder: {
|
|
135
|
+
content: () => placeholder(['/']),
|
|
136
|
+
},
|
|
137
|
+
getMenu: () => [formattingCommands],
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export const Link: Story = {
|
|
142
|
+
render: LinkStory,
|
|
143
|
+
decorators: [
|
|
144
|
+
withClientProvider({
|
|
145
|
+
createSpace: true,
|
|
146
|
+
onInitialized: async (client) => {
|
|
147
|
+
client.addTypes([Testing.Contact]);
|
|
148
|
+
},
|
|
149
|
+
onCreateSpace: async ({ space }) => {
|
|
150
|
+
const createObjects = createObjectFactory(space.db, generator);
|
|
151
|
+
await createObjects([{ type: Testing.Contact, count: 10 }]);
|
|
152
|
+
await space.db.flush({ indexes: true });
|
|
153
|
+
},
|
|
154
|
+
}),
|
|
155
|
+
],
|
|
156
|
+
args: {
|
|
157
|
+
text: str('# Links', '', ''),
|
|
158
|
+
trigger: ['/', '@'],
|
|
159
|
+
placeholder: {
|
|
160
|
+
content: () => placeholder(['/', '@']),
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
};
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { syntaxTree } from '@codemirror/language';
|
|
8
6
|
import { type EditorView } from '@codemirror/view';
|
|
9
7
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
@@ -13,9 +11,9 @@ import { createPortal } from 'react-dom';
|
|
|
13
11
|
import { invariant } from '@dxos/invariant';
|
|
14
12
|
import { faker } from '@dxos/random';
|
|
15
13
|
import { Popover } from '@dxos/react-ui';
|
|
14
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
16
15
|
import { Card } from '@dxos/react-ui-stack';
|
|
17
16
|
import { hoverableControlItem, hoverableControlItemTransition, hoverableControls } from '@dxos/react-ui-theme';
|
|
18
|
-
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
19
17
|
import { trim } from '@dxos/util';
|
|
20
18
|
|
|
21
19
|
import { type PreviewLinkRef, type PreviewLinkTarget, getLinkRef, image, preview } from '../extensions';
|
|
@@ -169,8 +167,10 @@ const PreviewBlock = ({ link, el, view }: { link: PreviewLinkRef; el: HTMLElemen
|
|
|
169
167
|
const meta = {
|
|
170
168
|
title: 'ui/react-ui-editor/Preview',
|
|
171
169
|
component: EditorStory,
|
|
172
|
-
decorators: [withTheme
|
|
173
|
-
parameters: {
|
|
170
|
+
decorators: [withTheme],
|
|
171
|
+
parameters: {
|
|
172
|
+
layout: 'fullscreen',
|
|
173
|
+
},
|
|
174
174
|
} satisfies Meta<typeof EditorStory>;
|
|
175
175
|
|
|
176
176
|
export default meta;
|
|
@@ -2,14 +2,12 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
import React, { useState } from 'react';
|
|
9
7
|
import { createPortal } from 'react-dom';
|
|
10
8
|
|
|
11
9
|
import { useThemeContext } from '@dxos/react-ui';
|
|
12
|
-
import {
|
|
10
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
13
11
|
import { trim } from '@dxos/util';
|
|
14
12
|
|
|
15
13
|
import {
|
|
@@ -66,8 +64,10 @@ const text = trim`
|
|
|
66
64
|
const meta = {
|
|
67
65
|
title: 'ui/react-ui-editor/Tags',
|
|
68
66
|
render: DefaultStory,
|
|
69
|
-
decorators: [withTheme
|
|
70
|
-
parameters: {
|
|
67
|
+
decorators: [withTheme],
|
|
68
|
+
parameters: {
|
|
69
|
+
layout: 'fullscreen',
|
|
70
|
+
},
|
|
71
71
|
} satisfies Meta<typeof DefaultStory>;
|
|
72
72
|
|
|
73
73
|
export default meta;
|