@dxos/plugin-markdown 0.8.2-main.fbd8ed0 → 0.8.2-staging.42af850
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/{MarkdownContainer-KKWICAKV.mjs → MarkdownContainer-5IEINNQB.mjs} +299 -262
- package/dist/lib/browser/MarkdownContainer-5IEINNQB.mjs.map +7 -0
- package/dist/lib/browser/MarkdownPreview-YW5CS3ID.mjs +87 -0
- package/dist/lib/{node-esm/MarkdownPreview-KYWRMBRM.mjs.map → browser/MarkdownPreview-YW5CS3ID.mjs.map} +1 -1
- package/dist/lib/browser/anchor-sort-VS4OZVPP.mjs +32 -0
- package/dist/lib/browser/anchor-sort-VS4OZVPP.mjs.map +7 -0
- package/dist/lib/browser/{app-graph-serializer-MPJQUYTQ.mjs → app-graph-serializer-V6RLEHVY.mjs} +3 -3
- package/dist/lib/browser/{artifact-definition-DAF3YCVL.mjs → artifact-definition-5NAODQLG.mjs} +61 -14
- package/dist/lib/browser/artifact-definition-5NAODQLG.mjs.map +7 -0
- package/dist/lib/browser/{chunk-S42YXFZ7.mjs → chunk-77NGW7EO.mjs} +5 -6
- package/dist/lib/browser/chunk-77NGW7EO.mjs.map +7 -0
- package/dist/lib/browser/chunk-ACAID3XF.mjs +20 -0
- package/dist/lib/browser/chunk-ACAID3XF.mjs.map +7 -0
- package/dist/lib/browser/{chunk-TUCSFCS5.mjs → chunk-C5RABVIX.mjs} +2 -2
- package/dist/lib/browser/{chunk-XP2ZPCLI.mjs → chunk-ECSM56YC.mjs} +15 -22
- package/dist/lib/browser/chunk-ECSM56YC.mjs.map +7 -0
- package/dist/lib/browser/{chunk-NAGMSX77.mjs → chunk-QVJETNGS.mjs} +2 -2
- package/dist/lib/{node-esm/chunk-ETXPC5VP.mjs.map → browser/chunk-QVJETNGS.mjs.map} +1 -1
- package/dist/lib/browser/index.mjs +29 -17
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/intent-resolver-4GDYST4Y.mjs +65 -0
- package/dist/lib/browser/intent-resolver-4GDYST4Y.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-EMQV3GVI.mjs → react-surface-QE4SKXBT.mjs} +75 -62
- package/dist/lib/browser/react-surface-QE4SKXBT.mjs.map +7 -0
- package/dist/lib/browser/{settings-GPB6WOIU.mjs → settings-W5CK4PXP.mjs} +2 -2
- package/dist/lib/browser/{state-XTP5IP3W.mjs → state-KI6PJ6DT.mjs} +2 -2
- package/dist/lib/browser/types/index.mjs +1 -1
- package/dist/lib/node/{MarkdownContainer-LBI6ZESS.cjs → MarkdownContainer-LSNNPNRB.cjs} +304 -267
- package/dist/lib/node/MarkdownContainer-LSNNPNRB.cjs.map +7 -0
- package/dist/lib/node/MarkdownPreview-G34HSQEB.cjs +110 -0
- package/dist/lib/node/{MarkdownPreview-O3BR4PZW.cjs.map → MarkdownPreview-G34HSQEB.cjs.map} +1 -1
- package/dist/lib/node/{thread-NWBGBGOR.cjs → anchor-sort-NHVF23EU.cjs} +15 -20
- package/dist/lib/node/anchor-sort-NHVF23EU.cjs.map +7 -0
- package/dist/lib/node/{app-graph-serializer-Z7UJYSSL.cjs → app-graph-serializer-CLALIYN3.cjs} +9 -9
- package/dist/lib/node/{artifact-definition-UIZSL2AL.cjs → artifact-definition-VEAHK7BX.cjs} +65 -19
- package/dist/lib/node/artifact-definition-VEAHK7BX.cjs.map +7 -0
- package/dist/lib/node/{chunk-AJHB57YQ.cjs → chunk-C4HR7UXE.cjs} +15 -15
- package/dist/lib/node/chunk-C4HR7UXE.cjs.map +7 -0
- package/dist/lib/node/{chunk-BWRBWEKN.cjs → chunk-G7RBJX22.cjs} +8 -9
- package/dist/lib/node/chunk-G7RBJX22.cjs.map +7 -0
- package/dist/lib/node/{chunk-DZXTXSXX.cjs → chunk-IFYSBQE5.cjs} +5 -5
- package/dist/lib/node/{chunk-DZXTXSXX.cjs.map → chunk-IFYSBQE5.cjs.map} +1 -1
- package/dist/lib/node/{chunk-EO5H4OZJ.cjs → chunk-RQS4KBMG.cjs} +13 -20
- package/dist/lib/node/chunk-RQS4KBMG.cjs.map +7 -0
- package/dist/lib/node/{chunk-4525YF72.cjs → chunk-ZDTL47I7.cjs} +6 -6
- package/dist/lib/node/index.cjs +41 -29
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/intent-resolver-AUZVK3NZ.cjs +78 -0
- package/dist/lib/node/intent-resolver-AUZVK3NZ.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/{react-surface-REHX3ABQ.cjs → react-surface-WJZTEBYO.cjs} +84 -71
- package/dist/lib/node/react-surface-WJZTEBYO.cjs.map +7 -0
- package/dist/lib/node/{settings-SF6JDJG6.cjs → settings-IRKU3WPM.cjs} +6 -6
- package/dist/lib/node/{state-K4IPZTRO.cjs → state-KKDRAG7X.cjs} +6 -6
- package/dist/lib/node/types/index.cjs +7 -7
- package/dist/lib/node/types/index.cjs.map +1 -1
- package/dist/lib/node-esm/{MarkdownContainer-62XZY5EP.mjs → MarkdownContainer-UZSLXMWO.mjs} +299 -262
- package/dist/lib/node-esm/MarkdownContainer-UZSLXMWO.mjs.map +7 -0
- package/dist/lib/node-esm/MarkdownPreview-TCV7BI32.mjs +88 -0
- package/dist/lib/{browser/MarkdownPreview-FVSYVJGN.mjs.map → node-esm/MarkdownPreview-TCV7BI32.mjs.map} +1 -1
- package/dist/lib/node-esm/anchor-sort-G2HLCYFK.mjs +33 -0
- package/dist/lib/node-esm/anchor-sort-G2HLCYFK.mjs.map +7 -0
- package/dist/lib/node-esm/{app-graph-serializer-DDMFMNYI.mjs → app-graph-serializer-C3RNTQGM.mjs} +3 -3
- package/dist/lib/node-esm/{artifact-definition-ER3446S7.mjs → artifact-definition-7TIJW2CO.mjs} +61 -14
- package/dist/lib/node-esm/artifact-definition-7TIJW2CO.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-PDD5B7EO.mjs → chunk-6RPARLIK.mjs} +5 -6
- package/dist/lib/node-esm/chunk-6RPARLIK.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-T5Z5BIOF.mjs → chunk-EIUTPXGL.mjs} +10 -10
- package/dist/lib/node-esm/chunk-EIUTPXGL.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-ETXPC5VP.mjs → chunk-JXXDCSMW.mjs} +2 -2
- package/dist/lib/{browser/chunk-NAGMSX77.mjs.map → node-esm/chunk-JXXDCSMW.mjs.map} +1 -1
- package/dist/lib/node-esm/{chunk-66XM3JMR.mjs → chunk-NCMPVEXO.mjs} +15 -22
- package/dist/lib/node-esm/chunk-NCMPVEXO.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-CXTVDT5U.mjs → chunk-TCFJNUAE.mjs} +2 -2
- package/dist/lib/node-esm/index.mjs +29 -17
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/intent-resolver-FTNXUNI2.mjs +66 -0
- package/dist/lib/node-esm/intent-resolver-FTNXUNI2.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-surface-FA7JYF2A.mjs → react-surface-XNM3YDFB.mjs} +75 -62
- package/dist/lib/node-esm/react-surface-XNM3YDFB.mjs.map +7 -0
- package/dist/lib/node-esm/{settings-2DT2C4RA.mjs → settings-MK7D7LHQ.mjs} +2 -2
- package/dist/lib/node-esm/{state-7VFYPF6Z.mjs → state-LLGVRYKL.mjs} +2 -2
- package/dist/lib/node-esm/types/index.mjs +1 -1
- package/dist/types/src/MarkdownPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/anchor-sort.d.ts +6 -0
- package/dist/types/src/capabilities/anchor-sort.d.ts.map +1 -0
- package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +4 -4
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/components/MarkdownContainer.d.ts +3 -1
- package/dist/types/src/components/MarkdownContainer.d.ts.map +1 -1
- package/dist/types/src/components/MarkdownEditor/MarkdownEditor.d.ts +3 -3
- package/dist/types/src/components/MarkdownEditor/MarkdownEditor.d.ts.map +1 -1
- package/dist/types/src/components/MarkdownPreview/MarkdownPreview.stories.d.ts +0 -104
- package/dist/types/src/components/MarkdownPreview/MarkdownPreview.stories.d.ts.map +1 -1
- package/dist/types/src/components/Suggestions.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/extensions.d.ts +4 -1
- package/dist/types/src/extensions.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +1 -314
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +7 -109
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/package.json +47 -40
- package/src/MarkdownPlugin.tsx +17 -7
- package/src/capabilities/anchor-sort.ts +30 -0
- package/src/capabilities/artifact-definition.ts +43 -7
- package/src/capabilities/index.ts +1 -1
- package/src/capabilities/intent-resolver.ts +23 -28
- package/src/capabilities/react-surface.tsx +7 -0
- package/src/components/MarkdownContainer.tsx +16 -3
- package/src/components/MarkdownEditor/MarkdownEditor.tsx +8 -29
- package/src/components/MarkdownPreview/MarkdownPreview.stories.tsx +0 -1
- package/src/components/Suggestions.stories.tsx +40 -15
- package/src/components/Toolbar.stories.tsx +2 -2
- package/src/extensions.tsx +40 -11
- package/src/types/schema.ts +7 -13
- package/src/util.tsx +2 -2
- package/dist/lib/browser/MarkdownContainer-KKWICAKV.mjs.map +0 -7
- package/dist/lib/browser/MarkdownPreview-FVSYVJGN.mjs +0 -81
- package/dist/lib/browser/artifact-definition-DAF3YCVL.mjs.map +0 -7
- package/dist/lib/browser/chunk-JJY5LKZS.mjs +0 -20
- package/dist/lib/browser/chunk-JJY5LKZS.mjs.map +0 -7
- package/dist/lib/browser/chunk-S42YXFZ7.mjs.map +0 -7
- package/dist/lib/browser/chunk-XP2ZPCLI.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-PVKVTAFF.mjs +0 -81
- package/dist/lib/browser/intent-resolver-PVKVTAFF.mjs.map +0 -7
- package/dist/lib/browser/react-surface-EMQV3GVI.mjs.map +0 -7
- package/dist/lib/browser/thread-KW43PJ53.mjs +0 -37
- package/dist/lib/browser/thread-KW43PJ53.mjs.map +0 -7
- package/dist/lib/node/MarkdownContainer-LBI6ZESS.cjs.map +0 -7
- package/dist/lib/node/MarkdownPreview-O3BR4PZW.cjs +0 -104
- package/dist/lib/node/artifact-definition-UIZSL2AL.cjs.map +0 -7
- package/dist/lib/node/chunk-AJHB57YQ.cjs.map +0 -7
- package/dist/lib/node/chunk-BWRBWEKN.cjs.map +0 -7
- package/dist/lib/node/chunk-EO5H4OZJ.cjs.map +0 -7
- package/dist/lib/node/intent-resolver-ND7PSRJX.cjs +0 -94
- package/dist/lib/node/intent-resolver-ND7PSRJX.cjs.map +0 -7
- package/dist/lib/node/react-surface-REHX3ABQ.cjs.map +0 -7
- package/dist/lib/node/thread-NWBGBGOR.cjs.map +0 -7
- package/dist/lib/node-esm/MarkdownContainer-62XZY5EP.mjs.map +0 -7
- package/dist/lib/node-esm/MarkdownPreview-KYWRMBRM.mjs +0 -82
- package/dist/lib/node-esm/artifact-definition-ER3446S7.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-66XM3JMR.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-PDD5B7EO.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-T5Z5BIOF.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-5BF5PLSN.mjs +0 -82
- package/dist/lib/node-esm/intent-resolver-5BF5PLSN.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-FA7JYF2A.mjs.map +0 -7
- package/dist/lib/node-esm/thread-D2E6W44K.mjs +0 -38
- package/dist/lib/node-esm/thread-D2E6W44K.mjs.map +0 -7
- package/dist/types/src/capabilities/thread.d.ts +0 -6
- package/dist/types/src/capabilities/thread.d.ts.map +0 -1
- package/src/capabilities/thread.ts +0 -35
- /package/dist/lib/browser/{app-graph-serializer-MPJQUYTQ.mjs.map → app-graph-serializer-V6RLEHVY.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-TUCSFCS5.mjs.map → chunk-C5RABVIX.mjs.map} +0 -0
- /package/dist/lib/browser/{settings-GPB6WOIU.mjs.map → settings-W5CK4PXP.mjs.map} +0 -0
- /package/dist/lib/browser/{state-XTP5IP3W.mjs.map → state-KI6PJ6DT.mjs.map} +0 -0
- /package/dist/lib/node/{app-graph-serializer-Z7UJYSSL.cjs.map → app-graph-serializer-CLALIYN3.cjs.map} +0 -0
- /package/dist/lib/node/{chunk-4525YF72.cjs.map → chunk-ZDTL47I7.cjs.map} +0 -0
- /package/dist/lib/node/{settings-SF6JDJG6.cjs.map → settings-IRKU3WPM.cjs.map} +0 -0
- /package/dist/lib/node/{state-K4IPZTRO.cjs.map → state-KKDRAG7X.cjs.map} +0 -0
- /package/dist/lib/node-esm/{app-graph-serializer-DDMFMNYI.mjs.map → app-graph-serializer-C3RNTQGM.mjs.map} +0 -0
- /package/dist/lib/node-esm/{chunk-CXTVDT5U.mjs.map → chunk-TCFJNUAE.mjs.map} +0 -0
- /package/dist/lib/node-esm/{settings-2DT2C4RA.mjs.map → settings-MK7D7LHQ.mjs.map} +0 -0
- /package/dist/lib/node-esm/{state-7VFYPF6Z.mjs.map → state-LLGVRYKL.mjs.map} +0 -0
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Rx } from '@effect-rx/rx-react';
|
|
5
6
|
import React, { useEffect, useMemo } from 'react';
|
|
6
7
|
|
|
7
|
-
import { Capabilities, useCapabilities } from '@dxos/app-framework';
|
|
8
|
+
import { Capabilities, useAppGraph, useCapabilities } from '@dxos/app-framework';
|
|
8
9
|
import { isInstanceOf } from '@dxos/echo-schema';
|
|
9
10
|
import { fullyQualifiedId, getSpace } from '@dxos/react-client/echo';
|
|
11
|
+
import { type SelectionManager } from '@dxos/react-ui-attention';
|
|
10
12
|
import { DataType } from '@dxos/schema';
|
|
11
13
|
|
|
12
14
|
import { MarkdownEditor, type MarkdownEditorProps } from './MarkdownEditor';
|
|
@@ -21,6 +23,7 @@ export type MarkdownContainerProps = Pick<
|
|
|
21
23
|
id: string;
|
|
22
24
|
object: DocumentType | DataType.Text | any;
|
|
23
25
|
settings: MarkdownSettingsProps;
|
|
26
|
+
selectionManager?: SelectionManager;
|
|
24
27
|
};
|
|
25
28
|
|
|
26
29
|
// TODO(burdon): Factor out difference for ECHO and non-ECHO objects; i.e., single component.
|
|
@@ -29,6 +32,7 @@ const MarkdownContainer = ({
|
|
|
29
32
|
role,
|
|
30
33
|
object,
|
|
31
34
|
settings,
|
|
35
|
+
selectionManager,
|
|
32
36
|
viewMode,
|
|
33
37
|
editorStateStore,
|
|
34
38
|
onViewModeChange,
|
|
@@ -36,7 +40,7 @@ const MarkdownContainer = ({
|
|
|
36
40
|
const scrollPastEnd = role === 'article';
|
|
37
41
|
const doc = isInstanceOf(DocumentType, object) ? object : undefined;
|
|
38
42
|
const text = isInstanceOf(DataType.Text, object) ? object : undefined;
|
|
39
|
-
const extensions = useExtensions({ document: doc, text, id, settings, viewMode, editorStateStore });
|
|
43
|
+
const extensions = useExtensions({ document: doc, text, id, settings, selectionManager, viewMode, editorStateStore });
|
|
40
44
|
|
|
41
45
|
if (doc) {
|
|
42
46
|
return (
|
|
@@ -60,7 +64,6 @@ const MarkdownContainer = ({
|
|
|
60
64
|
extensions={extensions}
|
|
61
65
|
viewMode={viewMode}
|
|
62
66
|
toolbar={settings.toolbar}
|
|
63
|
-
comment={false}
|
|
64
67
|
inputMode={settings.editorInputMode}
|
|
65
68
|
scrollPastEnd={scrollPastEnd}
|
|
66
69
|
onViewModeChange={onViewModeChange}
|
|
@@ -115,12 +118,22 @@ export const DocumentEditor = ({ id, document: doc, settings, viewMode, ...props
|
|
|
115
118
|
return async (file: File) => upload!(file, space);
|
|
116
119
|
}, [space, upload]);
|
|
117
120
|
|
|
121
|
+
const { graph } = useAppGraph();
|
|
122
|
+
const customActions = useMemo(() => {
|
|
123
|
+
return Rx.make((get) => {
|
|
124
|
+
const actions = get(graph.actions(id));
|
|
125
|
+
const nodes = actions.filter((action) => action.properties.disposition === 'toolbar');
|
|
126
|
+
return { nodes, edges: nodes.map((node) => ({ source: 'root', target: node.id })) };
|
|
127
|
+
});
|
|
128
|
+
}, [graph]);
|
|
129
|
+
|
|
118
130
|
return (
|
|
119
131
|
<MarkdownEditor
|
|
120
132
|
id={id}
|
|
121
133
|
initialValue={doc.content?.target?.content}
|
|
122
134
|
viewMode={viewMode}
|
|
123
135
|
toolbar={settings.toolbar}
|
|
136
|
+
customActions={customActions}
|
|
124
137
|
inputMode={settings.editorInputMode}
|
|
125
138
|
onFileUpload={handleFileUpload}
|
|
126
139
|
{...props}
|
|
@@ -6,9 +6,8 @@ import { type EditorView } from '@codemirror/view';
|
|
|
6
6
|
import React, { useMemo, useEffect, useCallback } from 'react';
|
|
7
7
|
import { useDropzone } from 'react-dropzone';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { type FileInfo } from '@dxos/app-framework';
|
|
10
10
|
import { invariant } from '@dxos/invariant';
|
|
11
|
-
import { ATTENDABLE_PATH_SEPARATOR, DeckAction } from '@dxos/plugin-deck/types';
|
|
12
11
|
import { useThemeContext, useTranslation } from '@dxos/react-ui';
|
|
13
12
|
import {
|
|
14
13
|
type DNDOptions,
|
|
@@ -22,16 +21,15 @@ import {
|
|
|
22
21
|
createMarkdownExtensions,
|
|
23
22
|
createThemeExtensions,
|
|
24
23
|
dropFile,
|
|
25
|
-
|
|
24
|
+
editorSlots,
|
|
26
25
|
editorGutter,
|
|
27
26
|
processEditorPayload,
|
|
28
27
|
stackItemContentEditorClassNames,
|
|
29
|
-
useCommentState,
|
|
30
|
-
useCommentClickListener,
|
|
31
28
|
useFormattingState,
|
|
32
29
|
useTextEditor,
|
|
33
30
|
useEditorToolbarState,
|
|
34
31
|
addLink,
|
|
32
|
+
type EditorToolbarActionGraphProps,
|
|
35
33
|
} from '@dxos/react-ui-editor';
|
|
36
34
|
import { StackItem } from '@dxos/react-ui-stack';
|
|
37
35
|
import { isNotFalsy, isNonNullable } from '@dxos/util';
|
|
@@ -46,8 +44,8 @@ export type MarkdownEditorProps = {
|
|
|
46
44
|
inputMode?: EditorInputMode;
|
|
47
45
|
scrollPastEnd?: boolean;
|
|
48
46
|
toolbar?: boolean;
|
|
47
|
+
customActions?: EditorToolbarActionGraphProps['customActions'];
|
|
49
48
|
// TODO(wittjosiah): Generalize custom toolbar actions (e.g. comment, upload, etc.)
|
|
50
|
-
comment?: boolean;
|
|
51
49
|
viewMode?: EditorViewMode;
|
|
52
50
|
editorStateStore?: EditorStateStore;
|
|
53
51
|
onViewModeChange?: (id: string, mode: EditorViewMode) => void;
|
|
@@ -69,7 +67,7 @@ export const MarkdownEditor = ({
|
|
|
69
67
|
extensionProviders,
|
|
70
68
|
scrollPastEnd,
|
|
71
69
|
toolbar,
|
|
72
|
-
|
|
70
|
+
customActions,
|
|
73
71
|
viewMode,
|
|
74
72
|
editorStateStore,
|
|
75
73
|
onFileUpload,
|
|
@@ -77,7 +75,6 @@ export const MarkdownEditor = ({
|
|
|
77
75
|
}: MarkdownEditorProps) => {
|
|
78
76
|
const { t } = useTranslation(MARKDOWN_PLUGIN);
|
|
79
77
|
const { themeMode } = useThemeContext();
|
|
80
|
-
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
81
78
|
const toolbarState = useEditorToolbarState({ viewMode });
|
|
82
79
|
const formattingObserver = useFormattingState(toolbarState);
|
|
83
80
|
|
|
@@ -91,18 +88,6 @@ export const MarkdownEditor = ({
|
|
|
91
88
|
[extensionProviders],
|
|
92
89
|
);
|
|
93
90
|
|
|
94
|
-
// TODO(Zan): Factor out to thread plugin.
|
|
95
|
-
const commentObserver = useCommentState(toolbarState);
|
|
96
|
-
const onCommentClick = useCallback(async () => {
|
|
97
|
-
await dispatch(
|
|
98
|
-
createIntent(DeckAction.ChangeCompanion, {
|
|
99
|
-
primary: id,
|
|
100
|
-
companion: `${id}${ATTENDABLE_PATH_SEPARATOR}comments`,
|
|
101
|
-
}),
|
|
102
|
-
);
|
|
103
|
-
}, [dispatch]);
|
|
104
|
-
const commentClickObserver = useCommentClickListener(onCommentClick);
|
|
105
|
-
|
|
106
91
|
// TODO(wittjosiah): Factor out to file uploader plugin.
|
|
107
92
|
// Drag files.
|
|
108
93
|
const handleDrop: DNDOptions['onDrop'] = async (view, { files }) => {
|
|
@@ -122,19 +107,13 @@ export const MarkdownEditor = ({
|
|
|
122
107
|
initialValue,
|
|
123
108
|
extensions: [
|
|
124
109
|
formattingObserver,
|
|
125
|
-
comment && commentObserver,
|
|
126
|
-
comment && commentClickObserver,
|
|
127
110
|
createBasicExtensions({
|
|
128
111
|
readOnly: viewMode === 'readonly',
|
|
129
112
|
placeholder: t('editor placeholder'),
|
|
130
113
|
scrollPastEnd: role === 'section' ? false : scrollPastEnd,
|
|
131
114
|
}),
|
|
132
115
|
createMarkdownExtensions({ themeMode }),
|
|
133
|
-
createThemeExtensions({
|
|
134
|
-
themeMode,
|
|
135
|
-
syntaxHighlighting: true,
|
|
136
|
-
slots: { content: { className: editorContent } },
|
|
137
|
-
}),
|
|
116
|
+
createThemeExtensions({ themeMode, syntaxHighlighting: true, slots: editorSlots }),
|
|
138
117
|
editorGutter,
|
|
139
118
|
role !== 'section' && onFileUpload && dropFile({ onDrop: handleDrop }),
|
|
140
119
|
providerExtensions,
|
|
@@ -149,7 +128,7 @@ export const MarkdownEditor = ({
|
|
|
149
128
|
moveToEndOfLine: true,
|
|
150
129
|
}),
|
|
151
130
|
}),
|
|
152
|
-
[id, formattingObserver,
|
|
131
|
+
[id, formattingObserver, viewMode, themeMode, extensions, providerExtensions],
|
|
153
132
|
);
|
|
154
133
|
|
|
155
134
|
useTest(editorView);
|
|
@@ -206,8 +185,8 @@ export const MarkdownEditor = ({
|
|
|
206
185
|
attendableId={id}
|
|
207
186
|
role={role}
|
|
208
187
|
state={toolbarState}
|
|
188
|
+
customActions={customActions}
|
|
209
189
|
getView={getView}
|
|
210
|
-
comment={comment}
|
|
211
190
|
image={handleImageUpload}
|
|
212
191
|
viewMode={handleViewModeChange}
|
|
213
192
|
/>
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
7
|
import { type Meta } from '@storybook/react';
|
|
8
|
-
import {
|
|
8
|
+
import { Match, Option, pipe, Schema } from 'effect';
|
|
9
9
|
import React, { type FC, useEffect, useMemo, useState } from 'react';
|
|
10
10
|
|
|
11
|
+
import { Message } from '@dxos/ai';
|
|
11
12
|
import {
|
|
12
13
|
Capabilities,
|
|
13
14
|
CollaborationActions,
|
|
@@ -19,7 +20,6 @@ import {
|
|
|
19
20
|
useIntentDispatcher,
|
|
20
21
|
} from '@dxos/app-framework';
|
|
21
22
|
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
22
|
-
import { Message } from '@dxos/artifact';
|
|
23
23
|
import { Type } from '@dxos/echo';
|
|
24
24
|
import { create, createQueueDxn, type Expando } from '@dxos/echo-schema';
|
|
25
25
|
import { invariant } from '@dxos/invariant';
|
|
@@ -31,9 +31,9 @@ import { SpacePlugin } from '@dxos/plugin-space';
|
|
|
31
31
|
import { StorybookLayoutPlugin } from '@dxos/plugin-storybook-layout';
|
|
32
32
|
import { ThemePlugin } from '@dxos/plugin-theme';
|
|
33
33
|
import { faker } from '@dxos/random';
|
|
34
|
-
import { useQueue, useSpace } from '@dxos/react-client/echo';
|
|
34
|
+
import { createDocAccessor, fullyQualifiedId, toCursorRange, useQueue, useSpace } from '@dxos/react-client/echo';
|
|
35
35
|
import { IconButton, Toolbar } from '@dxos/react-ui';
|
|
36
|
-
import { command, useTextEditor } from '@dxos/react-ui-editor';
|
|
36
|
+
import { command, type EditorSelection, type Range, useTextEditor } from '@dxos/react-ui-editor';
|
|
37
37
|
import { StackItem } from '@dxos/react-ui-stack';
|
|
38
38
|
import { defaultTx } from '@dxos/react-ui-theme';
|
|
39
39
|
import { withLayout } from '@dxos/storybook-utils';
|
|
@@ -49,15 +49,15 @@ faker.seed(1);
|
|
|
49
49
|
|
|
50
50
|
const TestItem = Schema.Struct({
|
|
51
51
|
title: Schema.String.annotations({
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
title: 'Title',
|
|
53
|
+
description: 'Product title',
|
|
54
54
|
}),
|
|
55
55
|
description: Schema.String.annotations({
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
title: 'Description',
|
|
57
|
+
description: 'Product description',
|
|
58
58
|
}),
|
|
59
59
|
}).pipe(
|
|
60
|
-
Type.
|
|
60
|
+
Type.Obj({
|
|
61
61
|
typename: 'dxos.org/type/Test',
|
|
62
62
|
version: '0.1.0',
|
|
63
63
|
}),
|
|
@@ -66,28 +66,39 @@ const TestItem = Schema.Struct({
|
|
|
66
66
|
const TestChat: FC<{ doc: DocumentType; content: string }> = ({ doc, content }) => {
|
|
67
67
|
const { dispatchPromise: dispatch } = useIntentDispatcher();
|
|
68
68
|
const { parentRef } = useTextEditor({ initialValue: content });
|
|
69
|
+
const { editorState } = useCapability(MarkdownCapabilities.State);
|
|
69
70
|
|
|
70
71
|
const space = useSpace();
|
|
71
72
|
const queueDxn = useMemo(() => space && createQueueDxn(space.id), [space]);
|
|
72
73
|
const queue = useQueue<Message>(queueDxn);
|
|
73
74
|
|
|
74
|
-
const handleInsert = () => {
|
|
75
|
+
const handleInsert = async () => {
|
|
75
76
|
invariant(space);
|
|
76
77
|
invariant(queue);
|
|
77
78
|
queue.append([create(Message, { role: 'assistant', content: [{ type: 'text', text: 'Hello' }] })]);
|
|
78
|
-
const message = queue.
|
|
79
|
+
const message = queue.objects.at(-1);
|
|
80
|
+
invariant(message);
|
|
81
|
+
|
|
82
|
+
const text = await doc.content.load();
|
|
83
|
+
const accessor = createDocAccessor(text, ['content']);
|
|
84
|
+
const cursor = pipe(
|
|
85
|
+
editorState.getState(fullyQualifiedId(doc))?.selection,
|
|
86
|
+
Option.fromNullable,
|
|
87
|
+
Option.map(selectionToRange),
|
|
88
|
+
Option.map((range) => toCursorRange(accessor, range.from, range.to)),
|
|
89
|
+
Option.getOrUndefined,
|
|
90
|
+
);
|
|
79
91
|
|
|
80
92
|
// {
|
|
81
93
|
// const ref = refFromDXN(new DXN(DXN.kind.QUEUE, [...queue.dxn.parts, message.id]));
|
|
82
|
-
|
|
83
94
|
// const message = deref(ref);
|
|
84
95
|
// }
|
|
85
96
|
|
|
86
97
|
void dispatch(
|
|
87
98
|
createIntent(CollaborationActions.InsertContent, {
|
|
88
|
-
|
|
89
|
-
target: makeRef(doc as any as Expando), // TODO(burdon): Comomon base type.
|
|
99
|
+
target: doc as any as Expando, // TODO(burdon): Common base type.
|
|
90
100
|
object: refFromDXN(new DXN(DXN.kind.QUEUE, [...queue.dxn.parts, message.id])),
|
|
101
|
+
at: cursor,
|
|
91
102
|
label: 'Proposal',
|
|
92
103
|
}),
|
|
93
104
|
);
|
|
@@ -107,6 +118,7 @@ const DefaultStory = ({ document, chat }: { document: string; chat: string }) =>
|
|
|
107
118
|
const space = useSpace();
|
|
108
119
|
const [doc, setDoc] = useState<DocumentType>();
|
|
109
120
|
const settings = useCapability(Capabilities.SettingsStore).getStore<MarkdownSettingsProps>(MARKDOWN_PLUGIN)!.value;
|
|
121
|
+
const { editorState } = useCapability(MarkdownCapabilities.State);
|
|
110
122
|
|
|
111
123
|
useEffect(() => {
|
|
112
124
|
if (!space) {
|
|
@@ -135,7 +147,7 @@ const DefaultStory = ({ document, chat }: { document: string; chat: string }) =>
|
|
|
135
147
|
|
|
136
148
|
return (
|
|
137
149
|
<>
|
|
138
|
-
<MarkdownContainer id={doc.id} object={doc} settings={settings} />
|
|
150
|
+
<MarkdownContainer id={doc.id} object={doc} settings={settings} editorStateStore={editorState} />
|
|
139
151
|
<TestChat doc={doc} content={chat} />
|
|
140
152
|
</>
|
|
141
153
|
);
|
|
@@ -189,3 +201,16 @@ export const Default: Story = {
|
|
|
189
201
|
].join('\n'),
|
|
190
202
|
},
|
|
191
203
|
};
|
|
204
|
+
|
|
205
|
+
// TODO(wittjosiah): Factor out.
|
|
206
|
+
const selectionToRange = Match.type<EditorSelection>().pipe(
|
|
207
|
+
Match.when(
|
|
208
|
+
({ head, anchor }) => (head ? head > anchor : false),
|
|
209
|
+
({ head, anchor }) => ({ from: anchor, to: head! }) as Range,
|
|
210
|
+
),
|
|
211
|
+
Match.when(
|
|
212
|
+
({ head, anchor }) => (head ? head < anchor : false),
|
|
213
|
+
({ head, anchor }) => ({ from: head!, to: anchor }) as Range,
|
|
214
|
+
),
|
|
215
|
+
Match.orElse(({ anchor }) => ({ from: anchor, to: anchor }) as Range),
|
|
216
|
+
);
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
createMarkdownExtensions,
|
|
23
23
|
createThemeExtensions,
|
|
24
24
|
decorateMarkdown,
|
|
25
|
-
|
|
25
|
+
editorSlots,
|
|
26
26
|
formattingKeymap,
|
|
27
27
|
translations,
|
|
28
28
|
useComments,
|
|
@@ -49,7 +49,7 @@ const DefaultStory: FC<{ content?: string }> = ({ content = '' }) => {
|
|
|
49
49
|
formattingObserver,
|
|
50
50
|
createBasicExtensions({ readOnly: toolbarState.viewMode === 'readonly' }),
|
|
51
51
|
createMarkdownExtensions({ themeMode }),
|
|
52
|
-
createThemeExtensions({ themeMode, syntaxHighlighting: true, slots:
|
|
52
|
+
createThemeExtensions({ themeMode, syntaxHighlighting: true, slots: editorSlots }),
|
|
53
53
|
createDataExtensions({ id: text.id, text: createDocAccessor(text, ['content']) }),
|
|
54
54
|
comments({
|
|
55
55
|
onCreate: ({ cursor }) => {
|
package/src/extensions.tsx
CHANGED
|
@@ -16,6 +16,7 @@ import { invariant } from '@dxos/invariant';
|
|
|
16
16
|
import { createDocAccessor, fullyQualifiedId, getSpace, type QueryResult } from '@dxos/react-client/echo';
|
|
17
17
|
import { useIdentity } from '@dxos/react-client/halo';
|
|
18
18
|
import { Icon, ThemeProvider } from '@dxos/react-ui';
|
|
19
|
+
import { type SelectionManager } from '@dxos/react-ui-attention';
|
|
19
20
|
import {
|
|
20
21
|
type AutocompleteResult,
|
|
21
22
|
type EditorStateStore,
|
|
@@ -33,6 +34,9 @@ import {
|
|
|
33
34
|
selectionState,
|
|
34
35
|
typewriter,
|
|
35
36
|
type RenderCallback,
|
|
37
|
+
EditorView,
|
|
38
|
+
documentId,
|
|
39
|
+
Cursor,
|
|
36
40
|
} from '@dxos/react-ui-editor';
|
|
37
41
|
import { defaultTx } from '@dxos/react-ui-theme';
|
|
38
42
|
import { type DataType } from '@dxos/schema';
|
|
@@ -49,6 +53,7 @@ type ExtensionsOptions = {
|
|
|
49
53
|
dispatch?: PromiseIntentDispatcher;
|
|
50
54
|
query?: QueryResult<DocumentType>;
|
|
51
55
|
settings: MarkdownSettingsProps;
|
|
56
|
+
selectionManager?: SelectionManager;
|
|
52
57
|
viewMode?: EditorViewMode;
|
|
53
58
|
editorStateStore?: EditorStateStore;
|
|
54
59
|
};
|
|
@@ -59,6 +64,7 @@ export const useExtensions = ({
|
|
|
59
64
|
id,
|
|
60
65
|
text,
|
|
61
66
|
settings,
|
|
67
|
+
selectionManager,
|
|
62
68
|
viewMode,
|
|
63
69
|
editorStateStore,
|
|
64
70
|
}: ExtensionsOptions): Extension[] => {
|
|
@@ -77,6 +83,7 @@ export const useExtensions = ({
|
|
|
77
83
|
id,
|
|
78
84
|
text,
|
|
79
85
|
settings,
|
|
86
|
+
selectionManager,
|
|
80
87
|
viewMode,
|
|
81
88
|
dispatch,
|
|
82
89
|
// query,
|
|
@@ -93,6 +100,7 @@ export const useExtensions = ({
|
|
|
93
100
|
settings.numberedHeadings,
|
|
94
101
|
settings.debug,
|
|
95
102
|
settings.typewriter,
|
|
103
|
+
selectionManager,
|
|
96
104
|
],
|
|
97
105
|
);
|
|
98
106
|
|
|
@@ -101,18 +109,20 @@ export const useExtensions = ({
|
|
|
101
109
|
//
|
|
102
110
|
// External extensions from other plugins.
|
|
103
111
|
//
|
|
104
|
-
const pluginExtensions = useMemo<Extension[]
|
|
105
|
-
()
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (extension) {
|
|
109
|
-
acc.push(extension);
|
|
110
|
-
}
|
|
112
|
+
const pluginExtensions = useMemo<Extension[]>(() => {
|
|
113
|
+
if (!document) {
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
111
116
|
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
return extensionProviders.flat().reduce((acc: Extension[], provider) => {
|
|
118
|
+
const extension = typeof provider === 'function' ? provider({ document }) : provider;
|
|
119
|
+
if (extension) {
|
|
120
|
+
acc.push(extension);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return acc;
|
|
124
|
+
}, []);
|
|
125
|
+
}, [extensionProviders, document]);
|
|
116
126
|
|
|
117
127
|
//
|
|
118
128
|
// Basic plugins.
|
|
@@ -156,10 +166,12 @@ const createBaseExtensions = ({
|
|
|
156
166
|
id,
|
|
157
167
|
dispatch,
|
|
158
168
|
settings,
|
|
169
|
+
selectionManager,
|
|
159
170
|
query,
|
|
160
171
|
viewMode,
|
|
161
172
|
}: ExtensionsOptions): Extension[] => {
|
|
162
173
|
const extensions: Extension[] = [
|
|
174
|
+
selectionManager && selectionChange(selectionManager),
|
|
163
175
|
settings.editorInputMode && InputModeExtensions[settings.editorInputMode],
|
|
164
176
|
settings.folding && folding(),
|
|
165
177
|
].filter(isNotFalsy);
|
|
@@ -230,6 +242,23 @@ const createBaseExtensions = ({
|
|
|
230
242
|
return extensions;
|
|
231
243
|
};
|
|
232
244
|
|
|
245
|
+
export const selectionChange = (selectionManager: SelectionManager) => {
|
|
246
|
+
return EditorView.updateListener.of((update) => {
|
|
247
|
+
if (update.selectionSet) {
|
|
248
|
+
const id = update.state.facet(documentId);
|
|
249
|
+
const cursorConverter = update.state.facet(Cursor.converter);
|
|
250
|
+
const selection = update.state.selection;
|
|
251
|
+
const ranges = selection.ranges
|
|
252
|
+
.map((range) => ({
|
|
253
|
+
from: cursorConverter.toCursor(range.from),
|
|
254
|
+
to: cursorConverter.toCursor(range.to),
|
|
255
|
+
}))
|
|
256
|
+
.filter(({ from, to }) => to > from);
|
|
257
|
+
selectionManager.updateMultiRange(id, ranges);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
};
|
|
261
|
+
|
|
233
262
|
// TODO(burdon): Factor out styles.
|
|
234
263
|
const style = {
|
|
235
264
|
hover: 'rounded-sm text-primary-500 hover:text-primary-600 dark:text-primary-500 hover:dark:text-primary-400',
|
package/src/types/schema.ts
CHANGED
|
@@ -4,25 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
import { Schema } from 'effect';
|
|
6
6
|
|
|
7
|
-
import { Type } from '@dxos/echo';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { ThreadType } from '@dxos/plugin-space/types';
|
|
7
|
+
import { Type, Ref } from '@dxos/echo';
|
|
8
|
+
import { LabelAnnotation } from '@dxos/echo-schema';
|
|
9
|
+
import { live } from '@dxos/live-object';
|
|
11
10
|
import { DataType } from '@dxos/schema';
|
|
12
11
|
|
|
13
12
|
export const DocumentSchema = Schema.Struct({
|
|
14
13
|
name: Schema.optional(Schema.String),
|
|
15
14
|
fallbackName: Schema.optional(Schema.String),
|
|
16
|
-
content: Ref(DataType.Text),
|
|
17
|
-
|
|
18
|
-
assistantChatQueue: Schema.optional(Ref(Expando)),
|
|
19
|
-
}).annotations({
|
|
20
|
-
// TODO(dmaretskyi): `Schema.Struct(...).pipe(defaultLabel(['name', 'fallbackName']))` for type-safe annotations.
|
|
21
|
-
[LabelAnnotationId]: ['name', 'fallbackName'],
|
|
22
|
-
});
|
|
15
|
+
content: Type.Ref(DataType.Text),
|
|
16
|
+
}).pipe(LabelAnnotation.set(['name', 'fallbackName']));
|
|
23
17
|
|
|
24
18
|
export const DocumentType = DocumentSchema.pipe(
|
|
25
|
-
Type.
|
|
19
|
+
Type.Obj({
|
|
26
20
|
typename: 'dxos.org/type/Document',
|
|
27
21
|
version: '0.1.0',
|
|
28
22
|
}),
|
|
@@ -31,7 +25,7 @@ export type DocumentType = Schema.Schema.Type<typeof DocumentType>;
|
|
|
31
25
|
|
|
32
26
|
// TODO(burdon): Replace when defaults are supported.
|
|
33
27
|
export const createDocument = ({ name, content }: { name: string; content: string }) =>
|
|
34
|
-
live(DocumentType, { name, content:
|
|
28
|
+
live(DocumentType, { name, content: Ref.make(live(DataType.Text, { content })) });
|
|
35
29
|
|
|
36
30
|
/**
|
|
37
31
|
* Checks if an object conforms to the interface needed to render an editor.
|
package/src/util.tsx
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { debounce } from '@dxos/async';
|
|
6
6
|
import { type TypedObjectSerializer } from '@dxos/plugin-space/types';
|
|
7
|
-
import { live, createObject, isEchoObject, loadObjectReferences,
|
|
7
|
+
import { live, createObject, isEchoObject, loadObjectReferences, Ref } from '@dxos/react-client/echo';
|
|
8
8
|
import { DataType } from '@dxos/schema';
|
|
9
9
|
|
|
10
10
|
import { DocumentType, type MarkdownProperties } from './types';
|
|
@@ -42,7 +42,7 @@ export const serializer: TypedObjectSerializer<DocumentType> = {
|
|
|
42
42
|
deserialize: async ({ content: serialized }) => {
|
|
43
43
|
const { name, fallbackName, content } = JSON.parse(serialized);
|
|
44
44
|
return createObject(
|
|
45
|
-
live(DocumentType, { name, fallbackName, content:
|
|
45
|
+
live(DocumentType, { name, fallbackName, content: Ref.make(live(DataType.Text, { content })) }),
|
|
46
46
|
);
|
|
47
47
|
},
|
|
48
48
|
};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/MarkdownContainer.tsx", "../../../src/components/MarkdownEditor/MarkdownEditor.tsx", "../../../src/hooks/useSelectCurrentThread.tsx", "../../../src/extensions.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { useEffect, useMemo } from 'react';\n\nimport { Capabilities, useCapabilities } from '@dxos/app-framework';\nimport { isInstanceOf } from '@dxos/echo-schema';\nimport { fullyQualifiedId, getSpace } from '@dxos/react-client/echo';\nimport { DataType } from '@dxos/schema';\n\nimport { MarkdownEditor, type MarkdownEditorProps } from './MarkdownEditor';\nimport { useExtensions } from '../extensions';\nimport { DocumentType, type MarkdownSettingsProps } from '../types';\nimport { getFallbackName } from '../util';\n\nexport type MarkdownContainerProps = Pick<\n MarkdownEditorProps,\n 'role' | 'extensionProviders' | 'viewMode' | 'editorStateStore' | 'onViewModeChange'\n> & {\n id: string;\n object: DocumentType | DataType.Text | any;\n settings: MarkdownSettingsProps;\n};\n\n// TODO(burdon): Factor out difference for ECHO and non-ECHO objects; i.e., single component.\nconst MarkdownContainer = ({\n id,\n role,\n object,\n settings,\n viewMode,\n editorStateStore,\n onViewModeChange,\n}: MarkdownContainerProps) => {\n const scrollPastEnd = role === 'article';\n const doc = isInstanceOf(DocumentType, object) ? object : undefined;\n const text = isInstanceOf(DataType.Text, object) ? object : undefined;\n const extensions = useExtensions({ document: doc, text, id, settings, viewMode, editorStateStore });\n\n if (doc) {\n return (\n <DocumentEditor\n id={fullyQualifiedId(object)}\n role={role}\n document={doc}\n extensions={extensions}\n viewMode={viewMode}\n settings={settings}\n scrollPastEnd={scrollPastEnd}\n onViewModeChange={onViewModeChange}\n />\n );\n } else if (text) {\n return (\n <MarkdownEditor\n id={id}\n role={role}\n initialValue={text.content}\n extensions={extensions}\n viewMode={viewMode}\n toolbar={settings.toolbar}\n comment={false}\n inputMode={settings.editorInputMode}\n scrollPastEnd={scrollPastEnd}\n onViewModeChange={onViewModeChange}\n />\n );\n } else {\n // TODO(burdon): Normalize with above.\n return (\n <MarkdownEditor\n id={id}\n role={role}\n initialValue={object.text}\n extensions={extensions}\n viewMode={viewMode}\n toolbar={settings.toolbar}\n inputMode={settings.editorInputMode}\n scrollPastEnd={scrollPastEnd}\n onViewModeChange={onViewModeChange}\n />\n );\n }\n};\n\ntype DocumentEditorProps = Omit<MarkdownContainerProps, 'object' | 'extensionProviders' | 'editorStateStore'> &\n Pick<MarkdownEditorProps, 'id' | 'scrollPastEnd' | 'extensions'> & {\n document: DocumentType;\n };\n\nexport const DocumentEditor = ({ id, document: doc, settings, viewMode, ...props }: DocumentEditorProps) => {\n const space = getSpace(doc);\n\n // Migrate gradually to `fallbackName`.\n useEffect(() => {\n if (typeof doc.fallbackName === 'string') {\n return;\n }\n\n const fallbackName = doc.content?.target?.content ? getFallbackName(doc.content.target.content) : undefined;\n if (fallbackName) {\n doc.fallbackName = fallbackName;\n }\n }, [doc, doc.content]);\n\n // File dragging.\n const [upload] = useCapabilities(Capabilities.FileUploader);\n const handleFileUpload = useMemo(() => {\n if (space === undefined || upload === undefined) {\n return undefined;\n }\n\n // TODO(burdon): Re-order props: space, file.\n return async (file: File) => upload!(file, space);\n }, [space, upload]);\n\n return (\n <MarkdownEditor\n id={id}\n initialValue={doc.content?.target?.content}\n viewMode={viewMode}\n toolbar={settings.toolbar}\n inputMode={settings.editorInputMode}\n onFileUpload={handleFileUpload}\n {...props}\n />\n );\n};\n\nexport default MarkdownContainer;\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type EditorView } from '@codemirror/view';\nimport React, { useMemo, useEffect, useCallback } from 'react';\nimport { useDropzone } from 'react-dropzone';\n\nimport { createIntent, type FileInfo, useIntentDispatcher } from '@dxos/app-framework';\nimport { invariant } from '@dxos/invariant';\nimport { ATTENDABLE_PATH_SEPARATOR, DeckAction } from '@dxos/plugin-deck/types';\nimport { useThemeContext, useTranslation } from '@dxos/react-ui';\nimport {\n type DNDOptions,\n type EditorViewMode,\n type EditorInputMode,\n type EditorSelectionState,\n type EditorStateStore,\n EditorToolbar,\n type UseTextEditorProps,\n createBasicExtensions,\n createMarkdownExtensions,\n createThemeExtensions,\n dropFile,\n editorContent,\n editorGutter,\n processEditorPayload,\n stackItemContentEditorClassNames,\n useCommentState,\n useCommentClickListener,\n useFormattingState,\n useTextEditor,\n useEditorToolbarState,\n addLink,\n} from '@dxos/react-ui-editor';\nimport { StackItem } from '@dxos/react-ui-stack';\nimport { isNotFalsy, isNonNullable } from '@dxos/util';\n\nimport { useSelectCurrentThread } from '../../hooks';\nimport { MARKDOWN_PLUGIN } from '../../meta';\nimport { type MarkdownPluginState } from '../../types';\n\nexport type MarkdownEditorProps = {\n id: string;\n role?: string;\n inputMode?: EditorInputMode;\n scrollPastEnd?: boolean;\n toolbar?: boolean;\n // TODO(wittjosiah): Generalize custom toolbar actions (e.g. comment, upload, etc.)\n comment?: boolean;\n viewMode?: EditorViewMode;\n editorStateStore?: EditorStateStore;\n onViewModeChange?: (id: string, mode: EditorViewMode) => void;\n onFileUpload?: (file: File) => Promise<FileInfo | undefined>;\n} & Pick<UseTextEditorProps, 'initialValue' | 'extensions'> &\n Partial<Pick<MarkdownPluginState, 'extensionProviders'>>;\n\n/**\n * Base markdown editor component.\n *\n * This component provides all the features of the markdown editor that do no depend on ECHO.\n * This allows it to be used as a common editor for markdown content on arbitrary backends (e.g. files).\n */\nexport const MarkdownEditor = ({\n id,\n role = 'article',\n initialValue,\n extensions,\n extensionProviders,\n scrollPastEnd,\n toolbar,\n comment = true,\n viewMode,\n editorStateStore,\n onFileUpload,\n onViewModeChange,\n}: MarkdownEditorProps) => {\n const { t } = useTranslation(MARKDOWN_PLUGIN);\n const { themeMode } = useThemeContext();\n const { dispatchPromise: dispatch } = useIntentDispatcher();\n const toolbarState = useEditorToolbarState({ viewMode });\n const formattingObserver = useFormattingState(toolbarState);\n\n // Restore last selection and scroll point.\n const { scrollTo, selection } = useMemo<EditorSelectionState>(() => editorStateStore?.getState(id) ?? {}, [id]);\n\n // Extensions from other plugins.\n // TODO(burdon): Reconcile with DocumentEditor.useExtensions.\n const providerExtensions = useMemo(\n () => extensionProviders?.flatMap((provider) => provider({})).filter(isNonNullable),\n [extensionProviders],\n );\n\n // TODO(Zan): Factor out to thread plugin.\n const commentObserver = useCommentState(toolbarState);\n const onCommentClick = useCallback(async () => {\n await dispatch(\n createIntent(DeckAction.ChangeCompanion, {\n primary: id,\n companion: `${id}${ATTENDABLE_PATH_SEPARATOR}comments`,\n }),\n );\n }, [dispatch]);\n const commentClickObserver = useCommentClickListener(onCommentClick);\n\n // TODO(wittjosiah): Factor out to file uploader plugin.\n // Drag files.\n const handleDrop: DNDOptions['onDrop'] = async (view, { files }) => {\n const file = files[0];\n const info = file && onFileUpload ? await onFileUpload(file) : undefined;\n if (info) {\n processEditorPayload(view, { type: 'image', data: info.url });\n }\n };\n\n const {\n parentRef,\n view: editorView,\n focusAttributes,\n } = useTextEditor(\n () => ({\n initialValue,\n extensions: [\n formattingObserver,\n comment && commentObserver,\n comment && commentClickObserver,\n createBasicExtensions({\n readOnly: viewMode === 'readonly',\n placeholder: t('editor placeholder'),\n scrollPastEnd: role === 'section' ? false : scrollPastEnd,\n }),\n createMarkdownExtensions({ themeMode }),\n createThemeExtensions({\n themeMode,\n syntaxHighlighting: true,\n slots: { content: { className: editorContent } },\n }),\n editorGutter,\n role !== 'section' && onFileUpload && dropFile({ onDrop: handleDrop }),\n providerExtensions,\n extensions,\n ].filter(isNotFalsy),\n ...(role !== 'section' && {\n id,\n scrollTo,\n selection,\n // TODO(wittjosiah): Autofocus based on layout is racy.\n // autoFocus: layoutPlugin?.provides.layout ? layoutPlugin?.provides.layout.scrollIntoView === id : true,\n moveToEndOfLine: true,\n }),\n }),\n [id, formattingObserver, comment, viewMode, themeMode, extensions, providerExtensions],\n );\n\n useTest(editorView);\n useSelectCurrentThread(editorView, id);\n\n // https://react-dropzone.js.org/#src\n const { acceptedFiles, getInputProps, open } = useDropzone({\n multiple: false,\n noDrag: true,\n accept: {\n 'image/*': ['.jpg', '.jpeg', '.png', '.gif'],\n },\n });\n\n useEffect(() => {\n if (editorView && onFileUpload && acceptedFiles.length) {\n requestAnimationFrame(async () => {\n // NOTE: Clone file since react-dropzone patches in a non-standard `path` property, which confuses IPFS.\n const f = acceptedFiles[0];\n const file = new File([f], f.name, {\n type: f.type,\n lastModified: f.lastModified,\n });\n\n const info = await onFileUpload(file);\n if (info) {\n addLink({ url: info.url, image: true })(editorView);\n }\n });\n }\n }, [acceptedFiles, editorView, onFileUpload]);\n\n const getView = useCallback(() => {\n invariant(editorView);\n return editorView;\n }, [editorView]);\n\n const handleViewModeChange = useCallback(\n (mode: EditorViewMode) => onViewModeChange?.(id, mode),\n [id, onViewModeChange],\n );\n\n const handleImageUpload = useCallback(() => {\n if (onFileUpload) {\n open();\n }\n }, [onFileUpload]);\n\n return (\n <StackItem.Content toolbar={!!toolbar}>\n {toolbar && (\n <>\n <EditorToolbar\n attendableId={id}\n role={role}\n state={toolbarState}\n getView={getView}\n comment={comment}\n image={handleImageUpload}\n viewMode={handleViewModeChange}\n />\n <input {...getInputProps()} />\n </>\n )}\n <div\n role='none'\n ref={parentRef}\n data-testid='composer.markdownRoot'\n data-toolbar={toolbar ? 'enabled' : 'disabled'}\n className={stackItemContentEditorClassNames(role)}\n data-popover-collision-boundary={true}\n {...focusAttributes}\n />\n </StackItem.Content>\n );\n};\n\n// Expose editor view for playwright tests.\n// TODO(wittjosiah): Find a better way to expose this or find a way to limit it to test runs.\nconst useTest = (view?: EditorView) => {\n useEffect(() => {\n const composer = (window as any).composer;\n if (composer) {\n composer.editorView = view;\n }\n }, [view]);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { EditorView } from '@codemirror/view';\nimport { Schema } from 'effect';\nimport { useMemo } from 'react';\n\nimport { createResolver, LayoutAction, useIntentResolver } from '@dxos/app-framework';\nimport { invariant } from '@dxos/invariant';\nimport { Cursor, setSelection } from '@dxos/react-ui-editor';\n\nimport { MARKDOWN_PLUGIN } from '../meta';\n\n/**\n * Handle scrolling and selection of the current thread in a markdown editor.\n */\nexport const useSelectCurrentThread = (editorView: EditorView | undefined, documentId: string) => {\n const scrollIntoViewResolver = useMemo(\n () =>\n createResolver({\n intent: LayoutAction.UpdateLayout,\n position: 'hoist',\n filter: (data): data is { part: 'current'; subject: string; options: { cursor: string } } => {\n if (!Schema.is(LayoutAction.ScrollIntoView.fields.input)(data)) {\n return false;\n }\n\n return !!editorView && data.subject === documentId && !!data.options?.cursor;\n },\n resolve: ({ options: { cursor } }) => {\n invariant(editorView, 'Editor view is not defined.');\n const range = Cursor.getRangeFromCursor(editorView.state, cursor!);\n if (range) {\n const selection = editorView.state.selection.main.from !== range.from ? { anchor: range.from } : undefined;\n const effects = [\n // NOTE: This does not use the DOM scrollIntoView function.\n EditorView.scrollIntoView(range.from, { y: 'start', yMargin: 96 }),\n ];\n if (selection) {\n // Update the editor selection to get bi-directional highlighting.\n effects.push(setSelection.of({ current: documentId }));\n }\n\n editorView.dispatch({\n effects,\n selection: selection ? { anchor: range.from } : undefined,\n });\n }\n },\n }),\n [documentId, editorView],\n );\n\n useIntentResolver(MARKDOWN_PLUGIN, scrollIntoViewResolver);\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { type AnchorHTMLAttributes, type ReactNode, useMemo } from 'react';\nimport { createRoot } from 'react-dom/client';\n\nimport {\n createIntent,\n LayoutAction,\n type PromiseIntentDispatcher,\n useCapabilities,\n useIntentDispatcher,\n} from '@dxos/app-framework';\nimport { invariant } from '@dxos/invariant';\nimport { createDocAccessor, fullyQualifiedId, getSpace, type QueryResult } from '@dxos/react-client/echo';\nimport { useIdentity } from '@dxos/react-client/halo';\nimport { Icon, ThemeProvider } from '@dxos/react-ui';\nimport {\n type AutocompleteResult,\n type EditorStateStore,\n type EditorViewMode,\n type Extension,\n InputModeExtensions,\n createDataExtensions,\n autocomplete,\n decorateMarkdown,\n folding,\n formattingKeymap,\n linkTooltip,\n listener,\n preview,\n selectionState,\n typewriter,\n type RenderCallback,\n} from '@dxos/react-ui-editor';\nimport { defaultTx } from '@dxos/react-ui-theme';\nimport { type DataType } from '@dxos/schema';\nimport { isNotFalsy } from '@dxos/util';\n\nimport { MarkdownCapabilities } from './capabilities';\nimport { type DocumentType, type MarkdownSettingsProps } from './types';\nimport { setFallbackName } from './util';\n\ntype ExtensionsOptions = {\n document?: DocumentType;\n id?: string;\n text?: DataType.Text;\n dispatch?: PromiseIntentDispatcher;\n query?: QueryResult<DocumentType>;\n settings: MarkdownSettingsProps;\n viewMode?: EditorViewMode;\n editorStateStore?: EditorStateStore;\n};\n\n// TODO(burdon): Merge with createBaseExtensions below.\nexport const useExtensions = ({\n document,\n id,\n text,\n settings,\n viewMode,\n editorStateStore,\n}: ExtensionsOptions): Extension[] => {\n const { dispatchPromise: dispatch } = useIntentDispatcher();\n const identity = useIdentity();\n const space = getSpace(document) ?? getSpace(text);\n\n // TODO(wittjosiah): Autocomplete is not working and this query is causing performance issues.\n // TODO(burdon): Unsubscribe.\n // const query = space?.db.query(Filter.type(DocumentType));\n // query?.subscribe();\n const baseExtensions = useMemo(\n () =>\n createBaseExtensions({\n document,\n id,\n text,\n settings,\n viewMode,\n dispatch,\n // query,\n }),\n [\n document,\n id,\n text,\n viewMode,\n dispatch,\n settings,\n settings.editorInputMode,\n settings.folding,\n settings.numberedHeadings,\n settings.debug,\n settings.typewriter,\n ],\n );\n\n const extensionProviders = useCapabilities(MarkdownCapabilities.Extensions);\n\n //\n // External extensions from other plugins.\n //\n const pluginExtensions = useMemo<Extension[] | undefined>(\n () =>\n extensionProviders.flat().reduce((acc: Extension[], provider) => {\n const extension = typeof provider === 'function' ? provider({ document }) : provider;\n if (extension) {\n acc.push(extension);\n }\n\n return acc;\n }, []),\n [extensionProviders, document],\n );\n\n //\n // Basic plugins.\n //\n return useMemo<Extension[]>(\n () =>\n [\n // NOTE: Data extensions must be first so that automerge is updated before other extensions compute their state.\n document &&\n createDataExtensions({\n id: document.id,\n text: document.content.target && createDocAccessor(document.content.target, ['content']),\n space,\n identity,\n }),\n text &&\n id &&\n createDataExtensions({\n id,\n text: createDocAccessor(text, ['content']),\n space,\n identity,\n }),\n selectionState(editorStateStore),\n document &&\n listener({\n onChange: (text) => setFallbackName(document, text),\n }),\n baseExtensions,\n pluginExtensions,\n ].filter(isNotFalsy),\n [baseExtensions, pluginExtensions, document, document?.content?.target, text, id, space, identity],\n );\n};\n\n/**\n * Create extension instances for editor.\n */\nconst createBaseExtensions = ({\n document,\n id,\n dispatch,\n settings,\n query,\n viewMode,\n}: ExtensionsOptions): Extension[] => {\n const extensions: Extension[] = [\n settings.editorInputMode && InputModeExtensions[settings.editorInputMode],\n settings.folding && folding(),\n ].filter(isNotFalsy);\n\n //\n // Markdown\n //\n if (viewMode !== 'source') {\n extensions.push(\n ...[\n formattingKeymap(),\n decorateMarkdown({\n selectionChangeDelay: 100,\n numberedHeadings: settings.numberedHeadings ? { from: 2 } : undefined,\n // TODO(wittjosiah): For internal links, consider ignoring the link text and rendering the label of the object being linked to.\n renderLinkButton:\n dispatch && (document || id)\n ? createLinkRenderer((id: string) => {\n void dispatch(\n createIntent(LayoutAction.Open, {\n part: 'main',\n subject: [id],\n options: {\n pivotId: document ? fullyQualifiedId(document) : id,\n },\n }),\n );\n })\n : undefined,\n }),\n linkTooltip(renderLinkTooltip),\n preview(),\n ],\n );\n }\n\n //\n // Autocomplete object links.\n //\n if (query) {\n extensions.push(\n autocomplete({\n onSearch: (text: string) => {\n // TODO(burdon): Specify filter (e.g., stack).\n return query.objects\n .map<AutocompleteResult | undefined>((object) =>\n object.name?.length && object.id !== document?.id\n ? {\n label: object.name,\n // TODO(burdon): Factor out URL builder.\n apply: `[${object.name}](/${fullyQualifiedId(object)})`,\n }\n : undefined,\n )\n .filter(isNotFalsy);\n },\n }),\n );\n }\n\n if (settings.debug) {\n const items = settings.typewriter?.split(/[,\\n]/) ?? '';\n if (items) {\n extensions.push(typewriter({ items }));\n }\n }\n\n return extensions;\n};\n\n// TODO(burdon): Factor out styles.\nconst style = {\n hover: 'rounded-sm text-primary-500 hover:text-primary-600 dark:text-primary-500 hover:dark:text-primary-400',\n icon: 'inline-block leading-none mis-1 cursor-pointer',\n};\n\nconst createLinkRenderer =\n (onSelectObject: (id: string) => void): RenderCallback<{ url: string }> =>\n (el, { url }) => {\n // TODO(burdon): Formalize/document internal link format.\n const isInternal =\n url.startsWith('/') ||\n // TODO(wittjosiah): This should probably be parsed out on paste?\n url.startsWith(window.location.origin);\n\n const options: AnchorHTMLAttributes<any> = isInternal\n ? {\n onClick: () => {\n const qualifiedId = url.split('/').at(-1);\n invariant(qualifiedId, 'Invalid link format.');\n onSelectObject(qualifiedId);\n },\n }\n : {\n href: url,\n rel: 'noreferrer',\n target: '_blank',\n };\n\n renderRoot(\n el,\n <a {...options} className={style.hover}>\n <Icon\n icon={isInternal ? 'ph--arrow-square-down--bold' : 'ph--arrow-square-out--bold'}\n size={4}\n classNames={style.icon}\n />\n </a>,\n );\n };\n\nconst renderLinkTooltip: RenderCallback<{ url: string }> = (el, { url }) => {\n const web = new URL(url);\n renderRoot(\n el,\n <a href={url} rel='noreferrer' target='_blank' className={style.hover}>\n {web.origin}\n <Icon icon='ph--arrow-square-out--bold' size={4} classNames={style.icon} />\n </a>,\n );\n};\n\n// TODO(burdon): Remove react rendering; use DOM directly.\nexport const renderRoot = <T extends Element>(root: T, node: ReactNode): T => {\n createRoot(root).render(<ThemeProvider tx={defaultTx}>{node}</ThemeProvider>);\n return root;\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["React", "useEffect", "useMemo", "Capabilities", "useCapabilities", "isInstanceOf", "fullyQualifiedId", "getSpace", "DataType", "React", "useMemo", "useEffect", "useCallback", "useDropzone", "createIntent", "useIntentDispatcher", "invariant", "ATTENDABLE_PATH_SEPARATOR", "DeckAction", "useThemeContext", "useTranslation", "EditorToolbar", "createBasicExtensions", "createMarkdownExtensions", "createThemeExtensions", "dropFile", "editorContent", "editorGutter", "processEditorPayload", "stackItemContentEditorClassNames", "useCommentState", "useCommentClickListener", "useFormattingState", "useTextEditor", "useEditorToolbarState", "addLink", "StackItem", "isNotFalsy", "isNonNullable", "EditorView", "Schema", "useMemo", "createResolver", "LayoutAction", "useIntentResolver", "invariant", "Cursor", "setSelection", "useSelectCurrentThread", "editorView", "documentId", "scrollIntoViewResolver", "useMemo", "createResolver", "intent", "LayoutAction", "UpdateLayout", "position", "filter", "data", "Schema", "is", "ScrollIntoView", "fields", "input", "subject", "options", "cursor", "resolve", "invariant", "range", "Cursor", "getRangeFromCursor", "state", "selection", "main", "from", "anchor", "undefined", "effects", "EditorView", "scrollIntoView", "y", "yMargin", "push", "setSelection", "of", "current", "dispatch", "useIntentResolver", "MARKDOWN_PLUGIN", "MarkdownEditor", "id", "role", "initialValue", "extensions", "extensionProviders", "scrollPastEnd", "toolbar", "comment", "viewMode", "editorStateStore", "onFileUpload", "onViewModeChange", "t", "useTranslation", "MARKDOWN_PLUGIN", "themeMode", "useThemeContext", "dispatchPromise", "dispatch", "useIntentDispatcher", "toolbarState", "useEditorToolbarState", "formattingObserver", "useFormattingState", "scrollTo", "selection", "useMemo", "getState", "providerExtensions", "flatMap", "provider", "filter", "isNonNullable", "commentObserver", "useCommentState", "onCommentClick", "useCallback", "createIntent", "DeckAction", "ChangeCompanion", "primary", "companion", "ATTENDABLE_PATH_SEPARATOR", "commentClickObserver", "useCommentClickListener", "handleDrop", "view", "files", "file", "info", "undefined", "processEditorPayload", "type", "data", "url", "parentRef", "editorView", "focusAttributes", "useTextEditor", "createBasicExtensions", "readOnly", "placeholder", "createMarkdownExtensions", "createThemeExtensions", "syntaxHighlighting", "slots", "content", "className", "editorContent", "editorGutter", "dropFile", "onDrop", "isNotFalsy", "moveToEndOfLine", "useTest", "useSelectCurrentThread", "acceptedFiles", "getInputProps", "open", "useDropzone", "multiple", "noDrag", "accept", "useEffect", "length", "requestAnimationFrame", "f", "File", "name", "lastModified", "addLink", "image", "getView", "invariant", "handleViewModeChange", "mode", "handleImageUpload", "StackItem", "Content", "EditorToolbar", "attendableId", "state", "input", "div", "ref", "data-testid", "data-toolbar", "stackItemContentEditorClassNames", "data-popover-collision-boundary", "composer", "window", "React", "useMemo", "createRoot", "createIntent", "LayoutAction", "useCapabilities", "useIntentDispatcher", "invariant", "createDocAccessor", "fullyQualifiedId", "getSpace", "useIdentity", "Icon", "ThemeProvider", "InputModeExtensions", "createDataExtensions", "autocomplete", "decorateMarkdown", "folding", "formattingKeymap", "linkTooltip", "listener", "preview", "selectionState", "typewriter", "defaultTx", "isNotFalsy", "useExtensions", "document", "id", "text", "settings", "viewMode", "editorStateStore", "dispatchPromise", "dispatch", "useIntentDispatcher", "identity", "useIdentity", "space", "getSpace", "baseExtensions", "useMemo", "createBaseExtensions", "editorInputMode", "folding", "numberedHeadings", "debug", "typewriter", "extensionProviders", "useCapabilities", "MarkdownCapabilities", "Extensions", "pluginExtensions", "flat", "reduce", "acc", "provider", "extension", "push", "createDataExtensions", "content", "target", "createDocAccessor", "selectionState", "listener", "onChange", "setFallbackName", "filter", "isNotFalsy", "query", "extensions", "InputModeExtensions", "formattingKeymap", "decorateMarkdown", "selectionChangeDelay", "from", "undefined", "renderLinkButton", "createLinkRenderer", "createIntent", "LayoutAction", "Open", "part", "subject", "options", "pivotId", "fullyQualifiedId", "linkTooltip", "renderLinkTooltip", "preview", "autocomplete", "onSearch", "objects", "map", "object", "name", "length", "label", "apply", "items", "split", "style", "hover", "icon", "onSelectObject", "el", "url", "isInternal", "startsWith", "window", "location", "origin", "onClick", "qualifiedId", "at", "invariant", "href", "rel", "renderRoot", "React", "a", "className", "Icon", "size", "classNames", "web", "URL", "root", "node", "createRoot", "render", "ThemeProvider", "tx", "defaultTx", "MarkdownContainer", "id", "role", "object", "settings", "viewMode", "editorStateStore", "onViewModeChange", "scrollPastEnd", "doc", "isInstanceOf", "DocumentType", "undefined", "text", "DataType", "Text", "extensions", "useExtensions", "document", "React", "DocumentEditor", "fullyQualifiedId", "MarkdownEditor", "initialValue", "content", "toolbar", "comment", "inputMode", "editorInputMode", "props", "space", "getSpace", "useEffect", "fallbackName", "target", "getFallbackName", "upload", "useCapabilities", "Capabilities", "FileUploader", "handleFileUpload", "useMemo", "file", "onFileUpload"]
|
|
7
|
-
}
|