@dxos/react-ui-editor 0.3.10-main.a21ec31 → 0.3.10-main.c5193cc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +1006 -219
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +22 -1
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts +3 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/autocomplete.d.ts +3 -2
- package/dist/types/src/components/TextEditor/extensions/autocomplete.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/basic.d.ts +2 -1
- package/dist/types/src/components/TextEditor/extensions/basic.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/blast.d.ts +25 -0
- package/dist/types/src/components/TextEditor/extensions/blast.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/comments.d.ts +18 -0
- package/dist/types/src/components/TextEditor/extensions/comments.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/demo.d.ts +11 -0
- package/dist/types/src/components/TextEditor/extensions/demo.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/experimental.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/image.d.ts +4 -0
- package/dist/types/src/components/TextEditor/extensions/image.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/index.d.ts +6 -0
- package/dist/types/src/components/TextEditor/extensions/index.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/link.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/listener.d.ts +4 -2
- package/dist/types/src/components/TextEditor/extensions/listener.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/markdown/bundle.d.ts +2 -1
- package/dist/types/src/components/TextEditor/extensions/markdown/bundle.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/markdown/highlight.d.ts +6 -2
- package/dist/types/src/components/TextEditor/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/mention.d.ts +6 -0
- package/dist/types/src/components/TextEditor/extensions/mention.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/table.d.ts +8 -0
- package/dist/types/src/components/TextEditor/extensions/table.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/tasklist.d.ts +2 -4
- package/dist/types/src/components/TextEditor/extensions/tasklist.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/themes/default.d.ts +8 -0
- package/dist/types/src/components/TextEditor/themes/default.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/PatchSemaphore.d.ts +3 -0
- package/dist/types/src/hooks/automerge/PatchSemaphore.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/automerge.stories.d.ts +8 -1
- package/dist/types/src/hooks/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/index.d.ts +1 -1
- package/dist/types/src/hooks/automerge/index.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/plugin.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/translation/automerge-to-codemirror.d.ts +5 -0
- package/dist/types/src/hooks/automerge/translation/automerge-to-codemirror.d.ts.map +1 -0
- package/dist/types/src/hooks/automerge/translation/codemirror-to-automerge.d.ts +6 -0
- package/dist/types/src/hooks/automerge/translation/codemirror-to-automerge.d.ts.map +1 -0
- package/dist/types/src/hooks/automerge/translation/index.d.ts +3 -0
- package/dist/types/src/hooks/automerge/translation/index.d.ts.map +1 -0
- package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
- package/dist/types/src/{components/TextEditor → hooks/yjs}/yjs.stories.d.ts +1 -1
- package/dist/types/src/hooks/yjs/yjs.stories.d.ts.map +1 -0
- package/dist/types/src/styles/markdown.d.ts +3 -2
- package/dist/types/src/styles/markdown.d.ts.map +1 -1
- package/dist/types/src/testing/replicator.d.ts.map +1 -1
- package/package.json +20 -19
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +140 -31
- package/src/components/TextEditor/TextEditor.tsx +26 -15
- package/src/components/TextEditor/extensions/autocomplete.ts +9 -22
- package/src/components/TextEditor/extensions/basic.ts +2 -1
- package/src/components/TextEditor/extensions/blast.ts +387 -0
- package/src/components/TextEditor/extensions/comments.ts +191 -0
- package/src/components/TextEditor/extensions/demo.ts +69 -0
- package/src/components/TextEditor/extensions/experimental.tsx +1 -0
- package/src/components/TextEditor/extensions/image.ts +67 -0
- package/src/components/TextEditor/extensions/index.ts +6 -0
- package/src/components/TextEditor/extensions/link.ts +26 -25
- package/src/components/TextEditor/extensions/listener.ts +4 -3
- package/src/components/TextEditor/extensions/markdown/bundle.ts +29 -26
- package/src/components/TextEditor/extensions/markdown/highlight.ts +118 -103
- package/src/components/TextEditor/extensions/mention.ts +31 -0
- package/src/components/TextEditor/extensions/table.ts +123 -0
- package/src/components/TextEditor/extensions/tasklist.ts +89 -81
- package/src/components/TextEditor/themes/default.ts +69 -2
- package/src/hooks/automerge/PatchSemaphore.ts +12 -9
- package/src/hooks/automerge/automerge.stories.tsx +3 -2
- package/src/hooks/automerge/index.ts +1 -1
- package/src/hooks/automerge/plugin.ts +1 -0
- package/src/hooks/automerge/{amToCodemirror.ts → translation/automerge-to-codemirror.ts} +10 -2
- package/src/hooks/automerge/{codeMirrorToAm.ts → translation/codemirror-to-automerge.ts} +7 -4
- package/src/hooks/automerge/translation/index.ts +6 -0
- package/src/hooks/useTextModel.ts +13 -11
- package/src/{components/TextEditor → hooks/yjs}/yjs.stories.tsx +1 -1
- package/src/styles/markdown.ts +14 -8
- package/src/testing/replicator.ts +5 -5
- package/dist/types/src/components/TextEditor/yjs.stories.d.ts.map +0 -1
- package/dist/types/src/hooks/automerge/amToCodemirror.d.ts +0 -6
- package/dist/types/src/hooks/automerge/amToCodemirror.d.ts.map +0 -1
- package/dist/types/src/hooks/automerge/codeMirrorToAm.d.ts +0 -7
- package/dist/types/src/hooks/automerge/codeMirrorToAm.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../../../src/hooks/automerge/plugin.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,SAAS,EAEd,WAAW,EACX,UAAU,EACV,KAAK,WAAW,EAChB,KAAK,eAAe,EACrB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,SAAS,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAGlE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,MAAM,KAAK,GAAG;IAClB,SAAS,EAAE,KAAK,CAAC;IACjB,IAAI,EAAE,IAAI,EAAE,CAAC;IACb,wBAAwB,EAAE,WAAW,EAAE,CAAC;CACzC,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,KAAK,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,UAAU,0DAAsC,CAAC;AAE9D,eAAO,MAAM,WAAW,sCAAsB,YAAY,WAAW,CAAgC,CAAC;AAEtG,eAAO,MAAM,YAAY,UAAW,WAAW,uCAAsD,CAAC;AAEtG,eAAO,MAAM,OAAO,UAAW,WAAW,mBAAiB,IAAI,EAA6B,CAAC;AAE7F,MAAM,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;AAMtC,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,eAAe,WAAY,UAAU,QAAQ,IAAI,EAAE,KAAG,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../../../src/hooks/automerge/plugin.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,SAAS,EAEd,WAAW,EACX,UAAU,EACV,KAAK,WAAW,EAChB,KAAK,eAAe,EACrB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,SAAS,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAGlE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,MAAM,KAAK,GAAG;IAClB,SAAS,EAAE,KAAK,CAAC;IACjB,IAAI,EAAE,IAAI,EAAE,CAAC;IACb,wBAAwB,EAAE,WAAW,EAAE,CAAC;CACzC,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,QAAQ,EAAE,KAAK,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,UAAU,0DAAsC,CAAC;AAE9D,eAAO,MAAM,WAAW,sCAAsB,YAAY,WAAW,CAAgC,CAAC;AAEtG,eAAO,MAAM,YAAY,UAAW,WAAW,uCAAsD,CAAC;AAEtG,eAAO,MAAM,OAAO,UAAW,WAAW,mBAAiB,IAAI,EAA6B,CAAC;AAE7F,MAAM,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;AAMtC,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,eAAe,WAAY,UAAU,QAAQ,IAAI,EAAE,KAAG,eA+DlE,CAAC;AAEF,eAAO,MAAM,uBAAuB,qDAA+B,CAAC;AAEpE,eAAO,MAAM,aAAa,OAAQ,WAAW,KAAG,OAAmD,CAAC;AAEpG,eAAO,MAAM,aAAa,OAAQ,eAAe,SAchD,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type EditorSelection } from '@codemirror/state';
|
|
2
|
+
import { type EditorView } from '@codemirror/view';
|
|
3
|
+
import { type Patch, type Prop } from '@dxos/automerge/automerge';
|
|
4
|
+
export declare const automergeToCodemirror: (view: EditorView, selection: EditorSelection, target: Prop[], patches: Patch[]) => void;
|
|
5
|
+
//# sourceMappingURL=automerge-to-codemirror.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automerge-to-codemirror.d.ts","sourceRoot":"","sources":["../../../../../../src/hooks/automerge/translation/automerge-to-codemirror.ts"],"names":[],"mappings":"AAMA,OAAO,EAA8B,KAAK,eAAe,EAAoB,MAAM,mBAAmB,CAAC;AACvG,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EAGL,KAAK,KAAK,EACV,KAAK,IAAI,EAGV,MAAM,2BAA2B,CAAC;AAInC,eAAO,MAAM,qBAAqB,SAC1B,UAAU,aACL,eAAe,UAClB,IAAI,EAAE,WACL,KAAK,EAAE,SAkBjB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type EditorState, type Transaction } from '@codemirror/state';
|
|
2
|
+
import { type Heads } from '@dxos/automerge/automerge';
|
|
3
|
+
import { type IDocHandle } from '../handle';
|
|
4
|
+
import { type Field } from '../plugin';
|
|
5
|
+
export declare const codemirrorToAutomerge: (field: Field, handle: IDocHandle, transactions: Transaction[], state: EditorState) => Heads | undefined;
|
|
6
|
+
//# sourceMappingURL=codemirror-to-automerge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codemirror-to-automerge.d.ts","sourceRoot":"","sources":["../../../../../../src/hooks/automerge/translation/codemirror-to-automerge.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,WAAW,EAAa,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAElF,OAAO,EAAc,KAAK,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAEnE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,WAAW,CAAC;AAEvC,eAAO,MAAM,qBAAqB,yBAExB,UAAU,gBACJ,WAAW,EAAE,SACpB,WAAW,KACjB,KAAK,GAAG,SAyBV,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/hooks/automerge/translation/index.ts"],"names":[],"mappings":"AAIA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTextModel.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useTextModel.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAInD,OAAO,KAAK,KAAK,iBAAiB,MAAM,uBAAuB,CAAC;AAGhE,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,KAAK,EACV,KAAK,UAAU,EAIhB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAM5D,KAAK,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC;AAG7C,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"useTextModel.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useTextModel.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAInD,OAAO,KAAK,KAAK,iBAAiB,MAAM,uBAAuB,CAAC;AAGhE,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,KAAK,EACV,KAAK,UAAU,EAIhB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAM5D,KAAK,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC;AAG7C,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IAEX,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,YAAY,GAAG,WAAW,CAAC;IACrD,IAAI,EAAE,MAAM,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,IAAI,CAAC,EAAE;QACL,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH,CAAC;AAGF,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC3B,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB,CAAC;AAIF,eAAO,MAAM,YAAY,8BAA+B,mBAAmB,KAAG,WAAW,GAAG,SAM3F,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import '@dxosTheme';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
declare const _default: {
|
|
4
|
-
component: React.ForwardRefExoticComponent<import("
|
|
4
|
+
component: React.ForwardRefExoticComponent<import("../../components").TextEditorProps & React.RefAttributes<import("../../components").TextEditorRef>>;
|
|
5
5
|
decorators: import("@storybook/react").Decorator[];
|
|
6
6
|
};
|
|
7
7
|
export default _default;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yjs.stories.d.ts","sourceRoot":"","sources":["../../../../../src/hooks/yjs/yjs.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,YAAY,CAAC;AAEpB,OAAO,KAAmB,MAAM,OAAO,CAAC;;;;;AAWxC,wBAGE;AA+BF,eAAO,MAAM,OAAO;;;CAInB,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const headings: Record<HeadingLevel, string[]>;
|
|
3
|
+
export declare const heading: (level: HeadingLevel, readonly?: boolean) => string;
|
|
3
4
|
export declare const text = "text-neutral-800 dark:text-neutral-200";
|
|
4
5
|
export declare const light = "text-neutral-200 dark:text-neutral-800";
|
|
5
6
|
export declare const mark: string;
|
|
@@ -12,7 +13,7 @@ export declare const codeMark = "font-mono text-primary-500";
|
|
|
12
13
|
export declare const codeBlock = "mlb-2 font-mono bg-neutral-500/10 p-3 rounded";
|
|
13
14
|
export declare const inlineUrl: string;
|
|
14
15
|
export declare const blockquote: string;
|
|
15
|
-
export declare const horizontalRule = "flex mlb-4 border-b text-neutral-100 dark:text-neutral-900 border-neutral-
|
|
16
|
+
export declare const horizontalRule = "flex mlb-4 border-b text-neutral-100 dark:text-neutral-900 border-neutral-200 dark:border-neutral-800";
|
|
16
17
|
export declare const unorderedList = "mlb-2 grid grid-cols-[min-content_1fr] [&>li:before]:content-[attr(marker)] [&>li:before]:mlb-1 [&>li:before]:mie-2";
|
|
17
18
|
export declare const orderedList = "mlb-2 grid grid-cols-[min-content_1fr] [&>li:before]:content-[counters(section,_\".\")_\"._\"] [counter-reset:section] [&>li:before]:mlb-1";
|
|
18
19
|
export declare const listItem = "contents before:[counter-increment:section]";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../../../src/styles/markdown.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAGjD,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../../../src/styles/markdown.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAGjD,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,CAOnD,CAAC;AAEF,eAAO,MAAM,OAAO,UAAW,YAAY,aAAa,OAAO,WAG9D,CAAC;AAEF,eAAO,MAAM,IAAI,2CAA2C,CAAC;AAC7D,eAAO,MAAM,KAAK,2CAA2C,CAAC;AAE9D,eAAO,MAAM,IAAI,QAAmE,CAAC;AAErF,eAAO,MAAM,SAAS,UAAU,CAAC;AAEjC,eAAO,MAAM,IAAI,cAAc,CAAC;AAChC,eAAO,MAAM,MAAM,WAAW,CAAC;AAC/B,eAAO,MAAM,aAAa,iBAAiB,CAAC;AAE5C,eAAO,MAAM,IAAI,mEAAmE,CAAC;AACrF,eAAO,MAAM,QAAQ,+BAA+B,CAAC;AACrD,eAAO,MAAM,SAAS,kDAAkD,CAAC;AAEzE,eAAO,MAAM,SAAS,QAAmB,CAAC;AAG1C,eAAO,MAAM,UAAU,QAAsF,CAAC;AAG9G,eAAO,MAAM,cAAc,0GAC8E,CAAC;AAG1G,eAAO,MAAM,aAAa,wHAC6F,CAAC;AACxH,eAAO,MAAM,WAAW,+IACkH,CAAC;AAE3I,eAAO,MAAM,QAAQ,gDAAgD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replicator.d.ts","sourceRoot":"","sources":["../../../../src/testing/replicator.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,KAAK,iBAAiB,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,OAAO,EAAE,QAAQ,EAAE,MAAM,4CAA4C,CAAC;AAEtE,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAEzD,KAAK,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC;AAM7C;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,UAAU,CAAC,GAAG,CAAC;IACpD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;IACvC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAM;gBAEf,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE;QAAE,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QAAC,GAAG,EAAE,GAAG,CAAC;QAAC,SAAS,CAAC,EAAE,SAAS,CAAA;KAAE;IA+BtG,IAAI,SAAS,IAAI,SAAS,CAEzB;IAED,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,sBAAsB;IAY9B,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,YAAY;IA0CpB,OAAO,CAAC,mBAAmB;CAG5B;AAED;;GAEG;AACH,qBAAa,UAAU;IAIT,OAAO,CAAC,QAAQ,CAAC,KAAK;IAHlC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,MAAM,CAAqB;gBAEN,KAAK,EAAE,QAAQ;IAE5C,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE;IAI7B,UAAU,OAAQ,MAAM,QAAO,GAAG,KAAe,WAAW,
|
|
1
|
+
{"version":3,"file":"replicator.d.ts","sourceRoot":"","sources":["../../../../src/testing/replicator.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,KAAK,iBAAiB,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,OAAO,EAAE,QAAQ,EAAE,MAAM,4CAA4C,CAAC;AAEtE,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAEzD,KAAK,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC;AAM7C;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,UAAU,CAAC,GAAG,CAAC;IACpD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;IACvC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAM;gBAEf,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE;QAAE,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QAAC,GAAG,EAAE,GAAG,CAAC;QAAC,SAAS,CAAC,EAAE,SAAS,CAAA;KAAE;IA+BtG,IAAI,SAAS,IAAI,SAAS,CAEzB;IAED,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,sBAAsB;IAY9B,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,YAAY;IA0CpB,OAAO,CAAC,mBAAmB;CAG5B;AAED;;GAEG;AACH,qBAAa,UAAU;IAIT,OAAO,CAAC,QAAQ,CAAC,KAAK;IAHlC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,MAAM,CAAqB;gBAEN,KAAK,EAAE,QAAQ;IAE5C,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE;IAI7B,UAAU,OAAQ,MAAM,QAAO,GAAG,KAAe,WAAW,CAoB1D;CACH;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,EAAE,UAAU,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,CAAC,EAAE,GAAG,CAAC;CACX,CAAC;AAEF,eAAO,MAAM,WAAW,4BAA6B,kBAAkB,KAAG,WAEzE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-ui-editor",
|
|
3
|
-
"version": "0.3.10-main.
|
|
3
|
+
"version": "0.3.10-main.c5193cc",
|
|
4
4
|
"description": "Document editing experience within a DXOS shell.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -36,18 +36,19 @@
|
|
|
36
36
|
"y-codemirror.next": "^0.3.2",
|
|
37
37
|
"y-protocols": "^1.0.5",
|
|
38
38
|
"yjs": "^13.6.10",
|
|
39
|
-
"@dxos/
|
|
40
|
-
"@dxos/
|
|
41
|
-
"@dxos/
|
|
42
|
-
"@dxos/
|
|
43
|
-
"@dxos/
|
|
44
|
-
"@dxos/
|
|
45
|
-
"@dxos/
|
|
46
|
-
"@dxos/
|
|
47
|
-
"@dxos/react-async": "0.3.10-main.
|
|
48
|
-
"@dxos/
|
|
49
|
-
"@dxos/
|
|
50
|
-
"@dxos/util": "0.3.10-main.
|
|
39
|
+
"@dxos/automerge": "0.3.10-main.c5193cc",
|
|
40
|
+
"@dxos/async": "0.3.10-main.c5193cc",
|
|
41
|
+
"@dxos/debug": "0.3.10-main.c5193cc",
|
|
42
|
+
"@dxos/display-name": "0.3.10-main.c5193cc",
|
|
43
|
+
"@dxos/echo-schema": "0.3.10-main.c5193cc",
|
|
44
|
+
"@dxos/protocols": "0.3.10-main.c5193cc",
|
|
45
|
+
"@dxos/invariant": "0.3.10-main.c5193cc",
|
|
46
|
+
"@dxos/log": "0.3.10-main.c5193cc",
|
|
47
|
+
"@dxos/react-async": "0.3.10-main.c5193cc",
|
|
48
|
+
"@dxos/text-model": "0.3.10-main.c5193cc",
|
|
49
|
+
"@dxos/react-ui": "0.3.10-main.c5193cc",
|
|
50
|
+
"@dxos/util": "0.3.10-main.c5193cc",
|
|
51
|
+
"@dxos/react-ui-theme": "0.3.10-main.c5193cc"
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
53
54
|
"@automerge/automerge-repo-network-broadcastchannel": "^1.0.19",
|
|
@@ -60,17 +61,17 @@
|
|
|
60
61
|
"@types/react-dom": "^18.0.6",
|
|
61
62
|
"react": "^18.2.0",
|
|
62
63
|
"react-dom": "^18.2.0",
|
|
63
|
-
"@dxos/config": "0.3.10-main.
|
|
64
|
-
"@dxos/react-
|
|
65
|
-
"@dxos/
|
|
66
|
-
"@dxos/
|
|
67
|
-
"@dxos/
|
|
64
|
+
"@dxos/config": "0.3.10-main.c5193cc",
|
|
65
|
+
"@dxos/react-client": "0.3.10-main.c5193cc",
|
|
66
|
+
"@dxos/echo-typegen": "0.3.10-main.c5193cc",
|
|
67
|
+
"@dxos/react-ui": "0.3.10-main.c5193cc",
|
|
68
|
+
"@dxos/storybook-utils": "0.3.10-main.c5193cc"
|
|
68
69
|
},
|
|
69
70
|
"peerDependencies": {
|
|
70
71
|
"@phosphor-icons/react": "^2.0.5",
|
|
71
72
|
"react": "^18.2.0",
|
|
72
73
|
"react-dom": "^18.2.0",
|
|
73
|
-
"@dxos/react-client": "0.3.10-main.
|
|
74
|
+
"@dxos/react-client": "0.3.10-main.c5193cc"
|
|
74
75
|
},
|
|
75
76
|
"publishConfig": {
|
|
76
77
|
"access": "public"
|
|
@@ -3,37 +3,52 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import '@dxosTheme';
|
|
6
|
+
|
|
6
7
|
import { EditorView } from '@codemirror/view';
|
|
7
8
|
import { faker } from '@faker-js/faker';
|
|
8
9
|
import { ArrowSquareOut } from '@phosphor-icons/react';
|
|
10
|
+
import defaultsDeep from 'lodash.defaultsdeep';
|
|
9
11
|
import React, { StrictMode, useRef, useState } from 'react';
|
|
10
12
|
import { createRoot } from 'react-dom/client';
|
|
11
13
|
|
|
12
14
|
import { TextObject } from '@dxos/echo-schema';
|
|
15
|
+
import { PublicKey } from '@dxos/keys';
|
|
13
16
|
import { fixedInsetFlexLayout, getSize, groupSurface, mx } from '@dxos/react-ui-theme';
|
|
14
17
|
import { withTheme } from '@dxos/storybook-utils';
|
|
15
18
|
|
|
16
19
|
import { MarkdownEditor, type TextEditorProps, type TextEditorRef } from './TextEditor';
|
|
17
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
autocomplete,
|
|
22
|
+
listener,
|
|
23
|
+
link,
|
|
24
|
+
tasklist,
|
|
25
|
+
tooltip,
|
|
26
|
+
type TooltipOptions,
|
|
27
|
+
type LinkOptions,
|
|
28
|
+
comments,
|
|
29
|
+
table,
|
|
30
|
+
image,
|
|
31
|
+
mention,
|
|
32
|
+
blast,
|
|
33
|
+
demo,
|
|
34
|
+
defaultOptions,
|
|
35
|
+
} from './extensions';
|
|
18
36
|
import { useTextModel } from '../../hooks';
|
|
19
37
|
|
|
20
|
-
// TODO(burdon): Read-only render mode (presentation).
|
|
21
|
-
// TODO(burdon): Slides.
|
|
22
|
-
// TODO(burdon): Autocomplete.
|
|
23
|
-
// TODO(burdon): Block quote.
|
|
24
|
-
// TODO(burdon): Images.
|
|
25
|
-
// TODO(burdon): Tables.
|
|
26
|
-
|
|
27
38
|
const str = (...lines: string[]) => lines.join('\n');
|
|
28
39
|
|
|
40
|
+
const num = () => faker.number.int({ min: 0, max: 9999 }).toLocaleString();
|
|
41
|
+
|
|
29
42
|
// prettier-ignore
|
|
30
43
|
const text = {
|
|
31
44
|
tasks: str(
|
|
32
45
|
'## Tasks',
|
|
33
46
|
'',
|
|
34
|
-
'- [x]
|
|
35
|
-
'- [ ]
|
|
36
|
-
'- [ ]
|
|
47
|
+
'- [x] decorator',
|
|
48
|
+
'- [ ] checkbox',
|
|
49
|
+
' - [ ] state',
|
|
50
|
+
' - [ ] indent',
|
|
51
|
+
' - [x] style',
|
|
37
52
|
),
|
|
38
53
|
|
|
39
54
|
list: str(
|
|
@@ -65,6 +80,7 @@ const text = {
|
|
|
65
80
|
' const x = 100;',
|
|
66
81
|
' return () => <div>Test</div>;',
|
|
67
82
|
'};',
|
|
83
|
+
'',
|
|
68
84
|
'```'
|
|
69
85
|
),
|
|
70
86
|
|
|
@@ -80,6 +96,21 @@ const text = {
|
|
|
80
96
|
headings: str(
|
|
81
97
|
...[1, 2, 3, 4, 5, 6].map((level) => ['#'.repeat(level) + ` Heading ${level}`, faker.lorem.sentences(), '']).flat(),
|
|
82
98
|
),
|
|
99
|
+
|
|
100
|
+
paragraphs: str(...faker.helpers.multiple(() => [faker.lorem.paragraph(), ''], { count: 3 }).flat()),
|
|
101
|
+
|
|
102
|
+
table: str(
|
|
103
|
+
'# Table',
|
|
104
|
+
'',
|
|
105
|
+
`| ${faker.lorem.word()} | ${faker.lorem.word()} | ${faker.lorem.word()} |`,
|
|
106
|
+
'|---|---|---|',
|
|
107
|
+
`| ${num()} | ${num()} | ${num()} |`,
|
|
108
|
+
`| ${num()} | ${num()} | ${num()} |`,
|
|
109
|
+
`| ${num()} | ${num()} | ${num()} |`,
|
|
110
|
+
'', // TODO(burdon): Possible GFM parsing bug if no newline?
|
|
111
|
+
),
|
|
112
|
+
|
|
113
|
+
image: str('# Image', '', ''),
|
|
83
114
|
};
|
|
84
115
|
|
|
85
116
|
const document = str(
|
|
@@ -89,9 +120,7 @@ const document = str(
|
|
|
89
120
|
'',
|
|
90
121
|
'This is all about https://dxos.org and related technologies.',
|
|
91
122
|
'',
|
|
92
|
-
'This this is **bold**,
|
|
93
|
-
'',
|
|
94
|
-
'__NOTE__: Fenced code uses the base font.',
|
|
123
|
+
'This this is **bold**, ~~strikethrough~~, _italic_, and `f(INLINE)`.',
|
|
95
124
|
'',
|
|
96
125
|
'---',
|
|
97
126
|
text.links,
|
|
@@ -105,6 +134,10 @@ const document = str(
|
|
|
105
134
|
text.code,
|
|
106
135
|
'---',
|
|
107
136
|
text.headings,
|
|
137
|
+
'---',
|
|
138
|
+
text.table,
|
|
139
|
+
'---',
|
|
140
|
+
text.image,
|
|
108
141
|
);
|
|
109
142
|
|
|
110
143
|
const links = [
|
|
@@ -144,7 +177,7 @@ const Story = ({
|
|
|
144
177
|
text,
|
|
145
178
|
automerge,
|
|
146
179
|
...props
|
|
147
|
-
}: { text?: string; automerge?: boolean } & Pick<TextEditorProps, 'extensions' | 'slots'>) => {
|
|
180
|
+
}: { text?: string; automerge?: boolean } & Pick<TextEditorProps, 'readonly' | 'extensions' | 'slots'>) => {
|
|
148
181
|
const ref = useRef<TextEditorRef>(null);
|
|
149
182
|
const [item] = useState({ text: new TextObject(text, undefined, undefined, { useAutomergeBackend: automerge }) });
|
|
150
183
|
const model = useTextModel({ text: item.text });
|
|
@@ -171,20 +204,23 @@ export default {
|
|
|
171
204
|
render: Story,
|
|
172
205
|
};
|
|
173
206
|
|
|
207
|
+
const extensions = [
|
|
208
|
+
link({ onRender }),
|
|
209
|
+
tooltip({ onHover }),
|
|
210
|
+
tasklist(),
|
|
211
|
+
table(),
|
|
212
|
+
image(),
|
|
213
|
+
autocomplete({
|
|
214
|
+
onSearch: (text) => links.filter(({ label }) => label.toLowerCase().includes(text.toLowerCase())),
|
|
215
|
+
}),
|
|
216
|
+
];
|
|
217
|
+
|
|
174
218
|
export const Default = {
|
|
175
|
-
render: () =>
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
tooltip({ onHover }),
|
|
181
|
-
tasklist(),
|
|
182
|
-
autocomplete({
|
|
183
|
-
getOptions: (text) => links.filter(({ label }) => label.toLowerCase().includes(text.toLowerCase())),
|
|
184
|
-
}),
|
|
185
|
-
]}
|
|
186
|
-
/>
|
|
187
|
-
),
|
|
219
|
+
render: () => <Story text={document} extensions={extensions} />,
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
export const Readonly = {
|
|
223
|
+
render: () => <Story text={document} extensions={extensions} readonly />,
|
|
188
224
|
};
|
|
189
225
|
|
|
190
226
|
export const Simple = {
|
|
@@ -199,14 +235,26 @@ export const Links = {
|
|
|
199
235
|
render: () => <Story text={text.links} extensions={[link({ onRender })]} />,
|
|
200
236
|
};
|
|
201
237
|
|
|
238
|
+
export const Table = {
|
|
239
|
+
render: () => (
|
|
240
|
+
<Story text={str('This is a table', '', text.table, '', text.table, '', '')} readonly extensions={[table()]} />
|
|
241
|
+
),
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
export const Image = {
|
|
245
|
+
render: () => <Story text={str('This is an image', '', text.image, '', '')} readonly extensions={[image()]} />,
|
|
246
|
+
};
|
|
247
|
+
|
|
202
248
|
export const TaskList = {
|
|
203
249
|
render: () => (
|
|
204
250
|
<Story
|
|
205
251
|
text={str(text.tasks, '', text.list)}
|
|
206
252
|
extensions={[
|
|
207
253
|
tasklist(),
|
|
208
|
-
listener(
|
|
209
|
-
|
|
254
|
+
listener({
|
|
255
|
+
onChange: (text) => {
|
|
256
|
+
console.log(text);
|
|
257
|
+
},
|
|
210
258
|
}),
|
|
211
259
|
]}
|
|
212
260
|
/>
|
|
@@ -220,7 +268,39 @@ export const Autocomplete = {
|
|
|
220
268
|
extensions={[
|
|
221
269
|
link({ onRender }),
|
|
222
270
|
autocomplete({
|
|
223
|
-
|
|
271
|
+
onSearch: (text) => links.filter(({ label }) => label.toLowerCase().includes(text.toLowerCase())),
|
|
272
|
+
}),
|
|
273
|
+
]}
|
|
274
|
+
/>
|
|
275
|
+
),
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const names = ['adam', 'alice', 'alison', 'bob', 'carol', 'charlie', 'sayuri', 'shoko'];
|
|
279
|
+
|
|
280
|
+
export const Mention = {
|
|
281
|
+
render: () => (
|
|
282
|
+
<Story
|
|
283
|
+
text={str('# Mention', '', '', '', '', '', '')}
|
|
284
|
+
extensions={[
|
|
285
|
+
mention({
|
|
286
|
+
onSearch: (text) => names.filter((name) => name.toLowerCase().startsWith(text.toLowerCase())),
|
|
287
|
+
}),
|
|
288
|
+
]}
|
|
289
|
+
/>
|
|
290
|
+
),
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
const mark = () => `[^${PublicKey.random().toHex()}]`;
|
|
294
|
+
export const Comments = {
|
|
295
|
+
render: () => (
|
|
296
|
+
<Story
|
|
297
|
+
text={str(mark(), '', text.paragraphs, mark(), '', mark(), '')}
|
|
298
|
+
extensions={[
|
|
299
|
+
comments({
|
|
300
|
+
onCreate: () => PublicKey.random().toHex(),
|
|
301
|
+
onUpdate: (info) => {
|
|
302
|
+
console.log('update', info);
|
|
303
|
+
},
|
|
224
304
|
}),
|
|
225
305
|
]}
|
|
226
306
|
/>
|
|
@@ -240,3 +320,32 @@ export const Diagnostics = {
|
|
|
240
320
|
/>
|
|
241
321
|
),
|
|
242
322
|
};
|
|
323
|
+
|
|
324
|
+
export const Demo = {
|
|
325
|
+
render: () => <Story text={text.paragraphs} extensions={[demo()]} />,
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
export const Blast = {
|
|
329
|
+
render: () => (
|
|
330
|
+
<Story
|
|
331
|
+
text={str(text.paragraphs, text.code, text.paragraphs)}
|
|
332
|
+
extensions={[
|
|
333
|
+
demo({
|
|
334
|
+
items: localStorage.getItem('dxos.composer.extension.demo')?.split(','),
|
|
335
|
+
}),
|
|
336
|
+
blast(
|
|
337
|
+
defaultsDeep(
|
|
338
|
+
{
|
|
339
|
+
effect: 2,
|
|
340
|
+
particleGravity: 0.2,
|
|
341
|
+
particleShrinkRate: 0.995,
|
|
342
|
+
color: () => [faker.number.int({ min: 100, max: 200 }), 0, 0],
|
|
343
|
+
// color: () => [faker.number.int(256), faker.number.int(256), faker.number.int(256)],
|
|
344
|
+
},
|
|
345
|
+
defaultOptions,
|
|
346
|
+
),
|
|
347
|
+
),
|
|
348
|
+
]}
|
|
349
|
+
/>
|
|
350
|
+
),
|
|
351
|
+
};
|
|
@@ -22,7 +22,7 @@ import { useThemeContext } from '@dxos/react-ui';
|
|
|
22
22
|
import { getColorForValue, inputSurface, mx } from '@dxos/react-ui-theme';
|
|
23
23
|
|
|
24
24
|
import { basicBundle, markdownBundle } from './extensions';
|
|
25
|
-
import { defaultTheme, textTheme } from './themes';
|
|
25
|
+
import { defaultTheme, markdownTheme, textTheme } from './themes';
|
|
26
26
|
import { type EditorModel } from '../../hooks';
|
|
27
27
|
import { type ThemeStyles } from '../../styles';
|
|
28
28
|
|
|
@@ -56,9 +56,10 @@ export type TextEditorSlots = {
|
|
|
56
56
|
|
|
57
57
|
export type TextEditorProps = {
|
|
58
58
|
model: EditorModel;
|
|
59
|
+
readonly?: boolean;
|
|
60
|
+
editorMode?: EditorMode;
|
|
59
61
|
extensions?: Extension[];
|
|
60
62
|
slots?: TextEditorSlots;
|
|
61
|
-
editorMode?: EditorMode;
|
|
62
63
|
};
|
|
63
64
|
|
|
64
65
|
/**
|
|
@@ -66,10 +67,15 @@ export type TextEditorProps = {
|
|
|
66
67
|
* NOTE: Rather than adding properties, try to create extensions that can be reused.
|
|
67
68
|
*/
|
|
68
69
|
export const BaseTextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
69
|
-
({ model, extensions = [], slots = defaultSlots
|
|
70
|
+
({ model, readonly, editorMode, extensions = [], slots = defaultSlots }, forwardedRef) => {
|
|
70
71
|
const { themeMode } = useThemeContext();
|
|
71
72
|
const tabsterDOMAttribute = useFocusableGroup({ tabBehavior: 'limited' });
|
|
72
73
|
|
|
74
|
+
const [root, setRoot] = useState<HTMLDivElement | null>(null);
|
|
75
|
+
const [state, setState] = useState<EditorState>();
|
|
76
|
+
const [view, setView] = useState<EditorView>();
|
|
77
|
+
useImperativeHandle(forwardedRef, () => ({ root, state, view }), [view, state, root]);
|
|
78
|
+
|
|
73
79
|
// TODO(burdon): Factor out?
|
|
74
80
|
const { awareness, peer } = model;
|
|
75
81
|
useEffect(() => {
|
|
@@ -82,11 +88,6 @@ export const BaseTextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
82
88
|
}
|
|
83
89
|
}, [awareness, peer, themeMode]);
|
|
84
90
|
|
|
85
|
-
const [root, setRoot] = useState<HTMLDivElement | null>(null);
|
|
86
|
-
const [state, setState] = useState<EditorState>();
|
|
87
|
-
const [view, setView] = useState<EditorView>();
|
|
88
|
-
useImperativeHandle(forwardedRef, () => ({ root, state, view }), [view, state, root]);
|
|
89
|
-
|
|
90
91
|
useEffect(() => {
|
|
91
92
|
if (!root) {
|
|
92
93
|
return;
|
|
@@ -95,6 +96,8 @@ export const BaseTextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
95
96
|
const state = EditorState.create({
|
|
96
97
|
doc: model.text(),
|
|
97
98
|
extensions: [
|
|
99
|
+
readonly && EditorState.readOnly.of(readonly),
|
|
100
|
+
|
|
98
101
|
// TODO(burdon): Factor out VIM mode?
|
|
99
102
|
editorMode === 'vim' && vim(),
|
|
100
103
|
|
|
@@ -124,7 +127,7 @@ export const BaseTextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
124
127
|
setView(undefined);
|
|
125
128
|
setState(undefined);
|
|
126
129
|
};
|
|
127
|
-
}, [root, model, themeMode, editorMode]);
|
|
130
|
+
}, [root, model, themeMode, readonly, editorMode]);
|
|
128
131
|
|
|
129
132
|
const handleKeyUp = useCallback(
|
|
130
133
|
(event: KeyboardEvent) => {
|
|
@@ -157,15 +160,15 @@ export const BaseTextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
157
160
|
},
|
|
158
161
|
);
|
|
159
162
|
|
|
160
|
-
// TODO(burdon): Set default text theme?
|
|
161
163
|
export const TextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
162
|
-
({ extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
164
|
+
({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
163
165
|
const { themeMode } = useThemeContext();
|
|
164
166
|
const slots = defaultsDeep({}, _slots, defaultTextSlots);
|
|
165
167
|
return (
|
|
166
168
|
<BaseTextEditor
|
|
167
169
|
ref={forwardedRef}
|
|
168
|
-
|
|
170
|
+
readonly={readonly}
|
|
171
|
+
extensions={[basicBundle({ readonly, themeMode, placeholder: slots?.editor?.placeholder }), ...extensions]}
|
|
169
172
|
slots={slots}
|
|
170
173
|
{...props}
|
|
171
174
|
/>
|
|
@@ -174,13 +177,14 @@ export const TextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
174
177
|
);
|
|
175
178
|
|
|
176
179
|
export const MarkdownEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
177
|
-
({ extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
180
|
+
({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
178
181
|
const { themeMode } = useThemeContext();
|
|
179
|
-
const slots = defaultsDeep({}, _slots,
|
|
182
|
+
const slots = defaultsDeep({}, _slots, defaultMarkdownSlots);
|
|
180
183
|
return (
|
|
181
184
|
<BaseTextEditor
|
|
182
185
|
ref={forwardedRef}
|
|
183
|
-
|
|
186
|
+
readonly={readonly}
|
|
187
|
+
extensions={[markdownBundle({ readonly, themeMode, placeholder: slots?.editor?.placeholder }), ...extensions]}
|
|
184
188
|
slots={slots}
|
|
185
189
|
{...props}
|
|
186
190
|
/>
|
|
@@ -200,3 +204,10 @@ export const defaultTextSlots: TextEditorSlots = {
|
|
|
200
204
|
theme: textTheme,
|
|
201
205
|
},
|
|
202
206
|
};
|
|
207
|
+
|
|
208
|
+
export const defaultMarkdownSlots: TextEditorSlots = {
|
|
209
|
+
...defaultSlots,
|
|
210
|
+
editor: {
|
|
211
|
+
theme: markdownTheme,
|
|
212
|
+
},
|
|
213
|
+
};
|
|
@@ -2,35 +2,29 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
// TODO(burdon): Automcomplete: https://codemirror.net/5/doc/manual.html#addon_runmode
|
|
6
|
-
// TODO(burdon): Modes: parallel parsing and decoration (e.g., associated with language).
|
|
7
|
-
// TODO(burdon): Add-on: runmode: run lexer over content (with rendering codemirror).
|
|
8
|
-
// https://codemirror.net/5/doc/manual.html#addon_runmode
|
|
9
|
-
// TODO(burdon): Add-on: dialog.
|
|
10
|
-
// TODO(burdon): Comments: https://codemirror.net/5/doc/manual.html#setBookmark
|
|
11
|
-
// TODO(burdon): Split view: https://codemirror.net/examples/split
|
|
12
|
-
|
|
13
5
|
// https://codemirror.net/examples/autocompletion
|
|
14
6
|
// https://codemirror.net/docs/ref/#autocomplete.autocompletion
|
|
15
7
|
// https://codemirror.net/docs/ref/#autocomplete.Completion
|
|
16
8
|
|
|
17
9
|
import {
|
|
18
10
|
autocompletion,
|
|
11
|
+
completionKeymap,
|
|
19
12
|
type Completion,
|
|
20
13
|
type CompletionContext,
|
|
21
|
-
completionKeymap,
|
|
22
14
|
type CompletionResult,
|
|
23
15
|
} from '@codemirror/autocomplete';
|
|
24
16
|
import { keymap } from '@codemirror/view';
|
|
25
17
|
|
|
18
|
+
export type AutocompleteResult = Completion;
|
|
19
|
+
|
|
26
20
|
export type AutocompleteOptions = {
|
|
27
|
-
|
|
21
|
+
onSearch: (text: string) => Completion[];
|
|
28
22
|
};
|
|
29
23
|
|
|
30
24
|
/**
|
|
31
25
|
* Autocomplete extension.
|
|
32
26
|
*/
|
|
33
|
-
export const autocomplete = ({
|
|
27
|
+
export const autocomplete = ({ onSearch }: AutocompleteOptions) => {
|
|
34
28
|
return [
|
|
35
29
|
// https://codemirror.net/docs/ref/#view.keymap
|
|
36
30
|
// https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
|
|
@@ -49,21 +43,14 @@ export const autocomplete = ({ getOptions }: AutocompleteOptions) => {
|
|
|
49
43
|
// TODO(burdon): Optional decoration via addToOptions
|
|
50
44
|
override: [
|
|
51
45
|
(context: CompletionContext): CompletionResult | null => {
|
|
52
|
-
const
|
|
53
|
-
if (!
|
|
46
|
+
const match = context.matchBefore(/\w*/);
|
|
47
|
+
if (!match || (match.from === match.to && !context.explicit)) {
|
|
54
48
|
return null;
|
|
55
49
|
}
|
|
56
50
|
|
|
57
|
-
// TODO(burdon): Option to convert to links?
|
|
58
51
|
return {
|
|
59
|
-
from:
|
|
60
|
-
options:
|
|
61
|
-
// options: [
|
|
62
|
-
// { label: 'apple', type: 'keyword' },
|
|
63
|
-
// { label: 'amazon', type: 'keyword' },
|
|
64
|
-
// { label: 'hello', type: 'variable', info: '(World)' },
|
|
65
|
-
// { label: 'magic', type: 'text', apply: '⠁⭒*.✩.*⭒⠁', detail: 'macro' },
|
|
66
|
-
// ],
|
|
52
|
+
from: match.from,
|
|
53
|
+
options: onSearch(match.text.toLowerCase()),
|
|
67
54
|
};
|
|
68
55
|
},
|
|
69
56
|
],
|
|
@@ -11,11 +11,12 @@ import { EditorView, placeholder } from '@codemirror/view';
|
|
|
11
11
|
import type { ThemeMode } from '@dxos/react-ui';
|
|
12
12
|
|
|
13
13
|
export type BasicBundleOptions = {
|
|
14
|
+
readonly?: boolean;
|
|
14
15
|
themeMode?: ThemeMode;
|
|
15
16
|
placeholder?: string;
|
|
16
17
|
};
|
|
17
18
|
|
|
18
|
-
export const basicBundle = ({ themeMode, placeholder: _placeholder }: BasicBundleOptions): Extension[] =>
|
|
19
|
+
export const basicBundle = ({ readonly, themeMode, placeholder: _placeholder }: BasicBundleOptions): Extension[] =>
|
|
19
20
|
[
|
|
20
21
|
// TODO(burdon): Compare with minimalSetup.
|
|
21
22
|
// https://codemirror.net/docs/ref/#codemirror.minimalSetup
|