@dxos/react-ui-editor 0.3.10-main.dcfebef → 0.3.10-main.e38869c
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 +1181 -372
- 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 +23 -2
- package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts +2 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +3 -0
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
- 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/code.d.ts +2 -0
- package/dist/types/src/components/TextEditor/extensions/code.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/comments.d.ts +2 -2
- package/dist/types/src/components/TextEditor/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/demo.d.ts +2 -1
- package/dist/types/src/components/TextEditor/extensions/demo.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/experimental.d.ts +1 -1
- package/dist/types/src/components/TextEditor/extensions/experimental.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/highlight.d.ts +24 -0
- package/dist/types/src/components/TextEditor/extensions/highlight.d.ts.map +1 -0
- 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.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/markdown/bundle.d.ts +10 -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 +9 -3
- 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 -1
- package/dist/types/src/components/TextEditor/extensions/tasklist.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/themes/default.d.ts +5 -0
- package/dist/types/src/components/TextEditor/themes/default.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextModel.d.ts +6 -0
- package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
- package/dist/types/src/{components/TextEditor → hooks/yjs}/yjs.stories.d.ts +2 -2
- 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 +23 -21
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +124 -32
- package/src/components/TextEditor/TextEditor.stories.tsx +12 -1
- package/src/components/TextEditor/TextEditor.tsx +31 -24
- package/src/components/TextEditor/extensions/autocomplete.ts +5 -20
- package/src/components/TextEditor/extensions/basic.ts +6 -4
- package/src/components/TextEditor/extensions/blast.ts +373 -0
- package/src/components/TextEditor/extensions/code.ts +99 -0
- package/src/components/TextEditor/extensions/comments.ts +29 -46
- package/src/components/TextEditor/extensions/demo.ts +4 -1
- package/src/components/TextEditor/extensions/experimental.tsx +15 -36
- package/src/components/TextEditor/extensions/highlight.ts +128 -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 +17 -25
- package/src/components/TextEditor/extensions/listener.ts +3 -3
- package/src/components/TextEditor/extensions/markdown/bundle.ts +45 -37
- package/src/components/TextEditor/extensions/markdown/highlight.ts +148 -108
- package/src/components/TextEditor/extensions/mention.ts +31 -0
- package/src/components/TextEditor/extensions/table.ts +119 -0
- package/src/components/TextEditor/extensions/tasklist.ts +42 -28
- package/src/components/TextEditor/themes/default.ts +98 -4
- package/src/hooks/automerge/automerge.stories.tsx +1 -0
- package/src/hooks/useTextModel.ts +9 -0
- package/src/{components/TextEditor → hooks/yjs}/yjs.stories.tsx +2 -2
- package/src/styles/markdown.ts +15 -8
- package/src/testing/replicator.ts +1 -0
- package/dist/types/src/components/TextEditor/yjs.stories.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../../../../../src/components/TextEditor/themes/default.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAI3C
|
|
1
|
+
{"version":3,"file":"default.d.ts","sourceRoot":"","sources":["../../../../../../src/components/TextEditor/themes/default.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAI3C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,EAAE;IACzB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAkO/B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE;IACtB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAQ/B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE;IAC1B,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAM/B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE;IACtB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAQ/B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"automerge.stories.d.ts","sourceRoot":"","sources":["../../../../../src/hooks/automerge/automerge.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"automerge.stories.d.ts","sourceRoot":"","sources":["../../../../../src/hooks/automerge/automerge.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,uBAAuB,CAAC;AAQ/B,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAGtD,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C,KAAK,WAAW,GAAG;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,IAAI,EAAE,CAAC;CACd,CAAC;;;;;AA+DF,wBAGE;AAEF,eAAO,MAAM,OAAO;;CAEnB,CAAC"}
|
|
@@ -4,10 +4,16 @@ import { type DocAccessor, type Space, type TextObject } from '@dxos/react-clien
|
|
|
4
4
|
import { type Identity } from '@dxos/react-client/halo';
|
|
5
5
|
import type { YText, YXmlFragment } from '@dxos/text-model';
|
|
6
6
|
type Awareness = awarenessProtocol.Awareness;
|
|
7
|
+
export type DocumentRange = {
|
|
8
|
+
id: string;
|
|
9
|
+
from: number;
|
|
10
|
+
to: number;
|
|
11
|
+
};
|
|
7
12
|
export type EditorModel = {
|
|
8
13
|
id: string;
|
|
9
14
|
content: string | YText | YXmlFragment | DocAccessor;
|
|
10
15
|
text: () => string;
|
|
16
|
+
ranges: DocumentRange[];
|
|
11
17
|
extension?: Extension;
|
|
12
18
|
awareness?: Awareness;
|
|
13
19
|
peer?: {
|
|
@@ -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;
|
|
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;AAE7C,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAGF,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,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,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,12 +1,12 @@
|
|
|
1
1
|
import '@dxosTheme';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
declare const _default: {
|
|
4
|
-
|
|
4
|
+
title: string;
|
|
5
|
+
component: React.ForwardRefExoticComponent<import("../../components").TextEditorProps & React.RefAttributes<import("../../components").TextEditorRef>>;
|
|
5
6
|
decorators: import("@storybook/react").Decorator[];
|
|
6
7
|
};
|
|
7
8
|
export default _default;
|
|
8
9
|
export declare const Default: {
|
|
9
|
-
title: string;
|
|
10
10
|
render: () => JSX.Element;
|
|
11
11
|
};
|
|
12
12
|
//# sourceMappingURL=yjs.stories.d.ts.map
|
|
@@ -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,wBAIE;AA+BF,eAAO,MAAM,OAAO;;CAGnB,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;
|
|
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;AAIjD,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,CAqB1D;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.e38869c",
|
|
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",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"@codemirror/state": "^6.3.3",
|
|
24
24
|
"@codemirror/theme-one-dark": "^6.1.2",
|
|
25
25
|
"@codemirror/view": "^6.22.2",
|
|
26
|
-
"@fluentui/react-tabster": "^9.
|
|
26
|
+
"@fluentui/react-tabster": "^9.16.1",
|
|
27
27
|
"@lezer/common": "^1.1.1",
|
|
28
28
|
"@lezer/highlight": "^1.2.0",
|
|
29
29
|
"@lezer/markdown": "^1.1.1",
|
|
@@ -32,23 +32,24 @@
|
|
|
32
32
|
"lib0": "^0.2.65",
|
|
33
33
|
"lodash.defaultsdeep": "^4.6.1",
|
|
34
34
|
"lodash.get": "^4.4.2",
|
|
35
|
+
"lodash.sortby": "^4.7.0",
|
|
35
36
|
"style-mod": "^4.1.0",
|
|
36
37
|
"y-codemirror.next": "^0.3.2",
|
|
37
38
|
"y-protocols": "^1.0.5",
|
|
38
39
|
"yjs": "^13.6.10",
|
|
39
|
-
"@dxos/async": "0.3.10-main.
|
|
40
|
-
"@dxos/
|
|
41
|
-
"@dxos/
|
|
42
|
-
"@dxos/
|
|
43
|
-
"@dxos/log": "0.3.10-main.
|
|
44
|
-
"@dxos/
|
|
45
|
-
"@dxos/
|
|
46
|
-
"@dxos/
|
|
47
|
-
"@dxos/react-
|
|
48
|
-
"@dxos/
|
|
49
|
-
"@dxos/react-ui
|
|
50
|
-
"@dxos/
|
|
51
|
-
"@dxos/
|
|
40
|
+
"@dxos/async": "0.3.10-main.e38869c",
|
|
41
|
+
"@dxos/debug": "0.3.10-main.e38869c",
|
|
42
|
+
"@dxos/automerge": "0.3.10-main.e38869c",
|
|
43
|
+
"@dxos/invariant": "0.3.10-main.e38869c",
|
|
44
|
+
"@dxos/log": "0.3.10-main.e38869c",
|
|
45
|
+
"@dxos/display-name": "0.3.10-main.e38869c",
|
|
46
|
+
"@dxos/echo-schema": "0.3.10-main.e38869c",
|
|
47
|
+
"@dxos/protocols": "0.3.10-main.e38869c",
|
|
48
|
+
"@dxos/react-async": "0.3.10-main.e38869c",
|
|
49
|
+
"@dxos/react-ui-theme": "0.3.10-main.e38869c",
|
|
50
|
+
"@dxos/react-ui": "0.3.10-main.e38869c",
|
|
51
|
+
"@dxos/text-model": "0.3.10-main.e38869c",
|
|
52
|
+
"@dxos/util": "0.3.10-main.e38869c"
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|
|
54
55
|
"@automerge/automerge-repo-network-broadcastchannel": "^1.0.19",
|
|
@@ -57,21 +58,22 @@
|
|
|
57
58
|
"@preact/signals-react": "^1.3.6",
|
|
58
59
|
"@types/lodash.defaultsdeep": "^4.6.6",
|
|
59
60
|
"@types/lodash.get": "^4.4.7",
|
|
61
|
+
"@types/lodash.sortby": "^4.7.7",
|
|
60
62
|
"@types/react": "^18.0.21",
|
|
61
63
|
"@types/react-dom": "^18.0.6",
|
|
62
64
|
"react": "^18.2.0",
|
|
63
65
|
"react-dom": "^18.2.0",
|
|
64
|
-
"@dxos/config": "0.3.10-main.
|
|
65
|
-
"@dxos/echo-typegen": "0.3.10-main.
|
|
66
|
-
"@dxos/react-client": "0.3.10-main.
|
|
67
|
-
"@dxos/react-ui": "0.3.10-main.
|
|
68
|
-
"@dxos/storybook-utils": "0.3.10-main.
|
|
66
|
+
"@dxos/config": "0.3.10-main.e38869c",
|
|
67
|
+
"@dxos/echo-typegen": "0.3.10-main.e38869c",
|
|
68
|
+
"@dxos/react-client": "0.3.10-main.e38869c",
|
|
69
|
+
"@dxos/react-ui": "0.3.10-main.e38869c",
|
|
70
|
+
"@dxos/storybook-utils": "0.3.10-main.e38869c"
|
|
69
71
|
},
|
|
70
72
|
"peerDependencies": {
|
|
71
73
|
"@phosphor-icons/react": "^2.0.5",
|
|
72
74
|
"react": "^18.2.0",
|
|
73
75
|
"react-dom": "^18.2.0",
|
|
74
|
-
"@dxos/react-client": "0.3.10-main.
|
|
76
|
+
"@dxos/react-client": "0.3.10-main.e38869c"
|
|
75
77
|
},
|
|
76
78
|
"publishConfig": {
|
|
77
79
|
"access": "public"
|
|
@@ -3,9 +3,11 @@
|
|
|
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
|
|
|
@@ -24,18 +26,25 @@ import {
|
|
|
24
26
|
type TooltipOptions,
|
|
25
27
|
type LinkOptions,
|
|
26
28
|
comments,
|
|
29
|
+
table,
|
|
30
|
+
image,
|
|
31
|
+
mention,
|
|
32
|
+
blast,
|
|
33
|
+
demo,
|
|
34
|
+
defaultOptions,
|
|
35
|
+
highlight,
|
|
36
|
+
code,
|
|
27
37
|
} from './extensions';
|
|
28
38
|
import { useTextModel } from '../../hooks';
|
|
29
39
|
|
|
30
|
-
//
|
|
31
|
-
// TODO(burdon):
|
|
32
|
-
// TODO(burdon):
|
|
33
|
-
// TODO(burdon): Block quote.
|
|
34
|
-
// TODO(burdon): Images.
|
|
35
|
-
// TODO(burdon): Tables.
|
|
40
|
+
// Extensions:
|
|
41
|
+
// TODO(burdon): Table of contents.
|
|
42
|
+
// TODO(burdon): Front-matter
|
|
36
43
|
|
|
37
44
|
const str = (...lines: string[]) => lines.join('\n');
|
|
38
45
|
|
|
46
|
+
const num = () => faker.number.int({ min: 0, max: 9999 }).toLocaleString();
|
|
47
|
+
|
|
39
48
|
// prettier-ignore
|
|
40
49
|
const text = {
|
|
41
50
|
tasks: str(
|
|
@@ -75,8 +84,10 @@ const text = {
|
|
|
75
84
|
'```tsx',
|
|
76
85
|
'const Component = () => {',
|
|
77
86
|
' const x = 100;',
|
|
87
|
+
'',
|
|
78
88
|
' return () => <div>Test</div>;',
|
|
79
89
|
'};',
|
|
90
|
+
'',
|
|
80
91
|
'```'
|
|
81
92
|
),
|
|
82
93
|
|
|
@@ -89,11 +100,26 @@ const text = {
|
|
|
89
100
|
'',
|
|
90
101
|
),
|
|
91
102
|
|
|
103
|
+
table: str(
|
|
104
|
+
'# Table',
|
|
105
|
+
'',
|
|
106
|
+
`| ${faker.lorem.word().padStart(8)} | ${faker.lorem.word().padStart(8)} | ${faker.lorem.word().padStart(8)} |`,
|
|
107
|
+
'|----------|----------|----------|',
|
|
108
|
+
`| ${num().padStart(8)} | ${num().padStart(8)} | ${num().padStart(8)} |`,
|
|
109
|
+
`| ${num().padStart(8)} | ${num().padStart(8)} | ${num().padStart(8)} |`,
|
|
110
|
+
`| ${num().padStart(8)} | ${num().padStart(8)} | ${num().padStart(8)} |`,
|
|
111
|
+
'', // TODO(burdon): Possible GFM parsing bug if no newline?
|
|
112
|
+
),
|
|
113
|
+
|
|
114
|
+
image: str('# Image', '', ''),
|
|
115
|
+
|
|
92
116
|
headings: str(
|
|
93
117
|
...[1, 2, 3, 4, 5, 6].map((level) => ['#'.repeat(level) + ` Heading ${level}`, faker.lorem.sentences(), '']).flat(),
|
|
94
118
|
),
|
|
95
119
|
|
|
96
|
-
paragraphs: str(...faker.helpers.multiple(() => [faker.lorem.paragraph(), ''], { count: 3 }).flat())
|
|
120
|
+
paragraphs: str(...faker.helpers.multiple(() => [faker.lorem.paragraph(), ''], { count: 3 }).flat()),
|
|
121
|
+
|
|
122
|
+
footer: str('', '', '', '', '')
|
|
97
123
|
};
|
|
98
124
|
|
|
99
125
|
const document = str(
|
|
@@ -103,9 +129,7 @@ const document = str(
|
|
|
103
129
|
'',
|
|
104
130
|
'This is all about https://dxos.org and related technologies.',
|
|
105
131
|
'',
|
|
106
|
-
'This this is **bold**,
|
|
107
|
-
'',
|
|
108
|
-
'__NOTE__: Fenced code uses the base font.',
|
|
132
|
+
'This this is **bold**, ~~strikethrough~~, _italic_, and `f(INLINE)`.',
|
|
109
133
|
'',
|
|
110
134
|
'---',
|
|
111
135
|
text.links,
|
|
@@ -119,6 +143,12 @@ const document = str(
|
|
|
119
143
|
text.code,
|
|
120
144
|
'---',
|
|
121
145
|
text.headings,
|
|
146
|
+
'---',
|
|
147
|
+
text.table,
|
|
148
|
+
'---',
|
|
149
|
+
text.image,
|
|
150
|
+
'',
|
|
151
|
+
text.footer,
|
|
122
152
|
);
|
|
123
153
|
|
|
124
154
|
const links = [
|
|
@@ -154,11 +184,12 @@ const onRender: LinkOptions['onRender'] = (el, url) => {
|
|
|
154
184
|
);
|
|
155
185
|
};
|
|
156
186
|
|
|
187
|
+
// TODO(burdon): Pass in model.
|
|
157
188
|
const Story = ({
|
|
158
189
|
text,
|
|
159
190
|
automerge,
|
|
160
191
|
...props
|
|
161
|
-
}: { text?: string; automerge?: boolean } & Pick<TextEditorProps, 'extensions' | 'slots'>) => {
|
|
192
|
+
}: { text?: string; automerge?: boolean } & Pick<TextEditorProps, 'readonly' | 'extensions' | 'slots'>) => {
|
|
162
193
|
const ref = useRef<TextEditorRef>(null);
|
|
163
194
|
const [item] = useState({ text: new TextObject(text, undefined, undefined, { useAutomergeBackend: automerge }) });
|
|
164
195
|
const model = useTextModel({ text: item.text });
|
|
@@ -185,38 +216,50 @@ export default {
|
|
|
185
216
|
render: Story,
|
|
186
217
|
};
|
|
187
218
|
|
|
219
|
+
const extensions = [
|
|
220
|
+
autocomplete({
|
|
221
|
+
onSearch: (text) => links.filter(({ label }) => label.toLowerCase().includes(text.toLowerCase())),
|
|
222
|
+
}),
|
|
223
|
+
code(),
|
|
224
|
+
image(),
|
|
225
|
+
link({ onRender }),
|
|
226
|
+
table(),
|
|
227
|
+
tasklist(),
|
|
228
|
+
tooltip({ onHover }),
|
|
229
|
+
];
|
|
230
|
+
|
|
188
231
|
export const Default = {
|
|
189
|
-
render: () =>
|
|
190
|
-
<Story
|
|
191
|
-
text={document}
|
|
192
|
-
extensions={[
|
|
193
|
-
link({ onRender }),
|
|
194
|
-
tooltip({ onHover }),
|
|
195
|
-
tasklist(),
|
|
196
|
-
autocomplete({
|
|
197
|
-
onSearch: (text) => links.filter(({ label }) => label.toLowerCase().includes(text.toLowerCase())),
|
|
198
|
-
}),
|
|
199
|
-
]}
|
|
200
|
-
/>
|
|
201
|
-
),
|
|
232
|
+
render: () => <Story text={document} extensions={extensions} />,
|
|
202
233
|
};
|
|
203
234
|
|
|
204
|
-
export const
|
|
205
|
-
render: () => <Story text={document} />,
|
|
235
|
+
export const Readonly = {
|
|
236
|
+
render: () => <Story text={document} extensions={extensions} readonly />,
|
|
206
237
|
};
|
|
207
238
|
|
|
208
239
|
export const Tooltips = {
|
|
209
|
-
render: () => <Story text={text.links} extensions={[tooltip({ onHover })]} />,
|
|
240
|
+
render: () => <Story text={str(text.links, text.footer)} extensions={[tooltip({ onHover })]} />,
|
|
210
241
|
};
|
|
211
242
|
|
|
212
243
|
export const Links = {
|
|
213
|
-
render: () => <Story text={text.links} extensions={[link({ onRender })]} />,
|
|
244
|
+
render: () => <Story text={str(text.links, text.footer)} extensions={[link({ onRender })]} />,
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
export const Code = {
|
|
248
|
+
render: () => <Story text={str(text.code, text.footer)} extensions={[code()]} readonly />,
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
export const Table = {
|
|
252
|
+
render: () => <Story text={str(text.table, text.footer)} extensions={[table()]} />,
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
export const Image = {
|
|
256
|
+
render: () => <Story text={str(text.image, text.footer)} readonly extensions={[image()]} />,
|
|
214
257
|
};
|
|
215
258
|
|
|
216
259
|
export const TaskList = {
|
|
217
260
|
render: () => (
|
|
218
261
|
<Story
|
|
219
|
-
text={str(text.tasks, '', text.list)}
|
|
262
|
+
text={str(text.tasks, '', text.list, text.footer)}
|
|
220
263
|
extensions={[
|
|
221
264
|
tasklist(),
|
|
222
265
|
listener({
|
|
@@ -232,7 +275,7 @@ export const TaskList = {
|
|
|
232
275
|
export const Autocomplete = {
|
|
233
276
|
render: () => (
|
|
234
277
|
<Story
|
|
235
|
-
text={str('# Autocomplete', '', '
|
|
278
|
+
text={str('# Autocomplete', '', 'Press CTRL-SPACE', text.footer)}
|
|
236
279
|
extensions={[
|
|
237
280
|
link({ onRender }),
|
|
238
281
|
autocomplete({
|
|
@@ -243,18 +286,34 @@ export const Autocomplete = {
|
|
|
243
286
|
),
|
|
244
287
|
};
|
|
245
288
|
|
|
289
|
+
const names = ['adam', 'alice', 'alison', 'bob', 'carol', 'charlie', 'sayuri', 'shoko'];
|
|
290
|
+
|
|
291
|
+
export const Mention = {
|
|
292
|
+
render: () => (
|
|
293
|
+
<Story
|
|
294
|
+
text={str('# Mention', '', 'Type @...', text.footer)}
|
|
295
|
+
extensions={[
|
|
296
|
+
mention({
|
|
297
|
+
onSearch: (text) => names.filter((name) => name.toLowerCase().startsWith(text.toLowerCase())),
|
|
298
|
+
}),
|
|
299
|
+
]}
|
|
300
|
+
/>
|
|
301
|
+
),
|
|
302
|
+
};
|
|
303
|
+
|
|
246
304
|
const mark = () => `[^${PublicKey.random().toHex()}]`;
|
|
247
305
|
export const Comments = {
|
|
248
306
|
render: () => (
|
|
249
307
|
<Story
|
|
250
|
-
text={str(
|
|
308
|
+
text={str(text.paragraphs, mark(), '', mark(), text.footer)}
|
|
251
309
|
extensions={[
|
|
252
310
|
comments({
|
|
253
311
|
onCreate: () => PublicKey.random().toHex(),
|
|
254
312
|
onUpdate: (info) => {
|
|
255
|
-
console.log('update', info);
|
|
313
|
+
// console.log('update', info);
|
|
256
314
|
},
|
|
257
315
|
}),
|
|
316
|
+
highlight(),
|
|
258
317
|
]}
|
|
259
318
|
/>
|
|
260
319
|
),
|
|
@@ -273,3 +332,36 @@ export const Diagnostics = {
|
|
|
273
332
|
/>
|
|
274
333
|
),
|
|
275
334
|
};
|
|
335
|
+
|
|
336
|
+
export const Demo = {
|
|
337
|
+
render: () => <Story text={str(text.paragraphs, text.footer)} extensions={[demo()]} />,
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
export const Blast = {
|
|
341
|
+
render: () => (
|
|
342
|
+
<Story
|
|
343
|
+
text={str(text.paragraphs, text.code, text.paragraphs)}
|
|
344
|
+
extensions={[
|
|
345
|
+
demo({
|
|
346
|
+
items: localStorage.getItem('dxos.composer.extension.demo')?.split(','),
|
|
347
|
+
}),
|
|
348
|
+
blast(
|
|
349
|
+
defaultsDeep(
|
|
350
|
+
{
|
|
351
|
+
effect: 2,
|
|
352
|
+
particleGravity: 0.2,
|
|
353
|
+
particleShrinkRate: 0.995,
|
|
354
|
+
color: () => [faker.number.int({ min: 100, max: 200 }), 0, 0],
|
|
355
|
+
// color: () => [faker.number.int(256), faker.number.int(256), faker.number.int(256)],
|
|
356
|
+
},
|
|
357
|
+
defaultOptions,
|
|
358
|
+
),
|
|
359
|
+
),
|
|
360
|
+
]}
|
|
361
|
+
/>
|
|
362
|
+
),
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
export const NoExtensions = {
|
|
366
|
+
render: () => <Story text={document} />,
|
|
367
|
+
};
|
|
@@ -57,6 +57,17 @@ export default {
|
|
|
57
57
|
};
|
|
58
58
|
|
|
59
59
|
export const Default = {
|
|
60
|
+
render: () => (
|
|
61
|
+
<Story
|
|
62
|
+
slots={defaultsDeep(
|
|
63
|
+
{ editor: { theme: textTheme, placeholder: 'Enter text...' } } satisfies TextEditorSlots,
|
|
64
|
+
defaultSlots,
|
|
65
|
+
)}
|
|
66
|
+
/>
|
|
67
|
+
),
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const Text = {
|
|
60
71
|
render: () => (
|
|
61
72
|
<Story
|
|
62
73
|
text={initialText}
|
|
@@ -71,12 +82,12 @@ export const Default = {
|
|
|
71
82
|
export const Automerge = {
|
|
72
83
|
render: () => (
|
|
73
84
|
<Story
|
|
85
|
+
automerge
|
|
74
86
|
text={initialText}
|
|
75
87
|
slots={defaultsDeep(
|
|
76
88
|
{ editor: { theme: textTheme, placeholder: 'Enter text...' } } satisfies TextEditorSlots,
|
|
77
89
|
defaultSlots,
|
|
78
90
|
)}
|
|
79
|
-
automerge
|
|
80
91
|
/>
|
|
81
92
|
),
|
|
82
93
|
};
|
|
@@ -21,7 +21,7 @@ import { generateName } from '@dxos/display-name';
|
|
|
21
21
|
import { useThemeContext } from '@dxos/react-ui';
|
|
22
22
|
import { getColorForValue, inputSurface, mx } from '@dxos/react-ui-theme';
|
|
23
23
|
|
|
24
|
-
import { basicBundle,
|
|
24
|
+
import { basicBundle, markdownBundle } from './extensions';
|
|
25
25
|
import { defaultTheme, markdownTheme, textTheme } from './themes';
|
|
26
26
|
import { type EditorModel } from '../../hooks';
|
|
27
27
|
import { type ThemeStyles } from '../../styles';
|
|
@@ -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,7 +67,7 @@ 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
|
|
|
@@ -87,6 +88,12 @@ export const BaseTextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
87
88
|
}
|
|
88
89
|
}, [awareness, peer, themeMode]);
|
|
89
90
|
|
|
91
|
+
// TODO(burdon): Get from model.
|
|
92
|
+
// useHighlights(view, [
|
|
93
|
+
// { id: 'c-1', from: 0, to: 20 },
|
|
94
|
+
// { id: 'c-2', from: 100, to: 120 },
|
|
95
|
+
// ]);
|
|
96
|
+
|
|
90
97
|
useEffect(() => {
|
|
91
98
|
if (!root) {
|
|
92
99
|
return;
|
|
@@ -95,10 +102,13 @@ export const BaseTextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
95
102
|
const state = EditorState.create({
|
|
96
103
|
doc: model.text(),
|
|
97
104
|
extensions: [
|
|
105
|
+
readonly && EditorState.readOnly.of(readonly),
|
|
106
|
+
|
|
98
107
|
// TODO(burdon): Factor out VIM mode?
|
|
99
108
|
editorMode === 'vim' && vim(),
|
|
100
109
|
|
|
101
110
|
// Theme.
|
|
111
|
+
// TODO(burdon): Make optional.
|
|
102
112
|
EditorView.baseTheme(defaultTheme),
|
|
103
113
|
EditorView.theme(slots?.editor?.theme ?? {}),
|
|
104
114
|
// TODO(burdon): themeMode doesn't change in storybooks.
|
|
@@ -116,7 +126,17 @@ export const BaseTextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
116
126
|
// If the new state is derived from the old state, it will likely not be visible other than the cursor resetting.
|
|
117
127
|
// Ideally this should not be hit except when changing between text objects.
|
|
118
128
|
view?.destroy();
|
|
119
|
-
setView(
|
|
129
|
+
setView(
|
|
130
|
+
new EditorView({
|
|
131
|
+
state,
|
|
132
|
+
parent: root,
|
|
133
|
+
// NOTE: Uncomment to spy on all transactions.
|
|
134
|
+
// https://codemirror.net/docs/ref/#view.EditorView.dispatch
|
|
135
|
+
// dispatch: (transaction, view) => {
|
|
136
|
+
// view.update([transaction]);
|
|
137
|
+
// },
|
|
138
|
+
}),
|
|
139
|
+
);
|
|
120
140
|
setState(state);
|
|
121
141
|
|
|
122
142
|
return () => {
|
|
@@ -124,7 +144,7 @@ export const BaseTextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
124
144
|
setView(undefined);
|
|
125
145
|
setState(undefined);
|
|
126
146
|
};
|
|
127
|
-
}, [root, model, themeMode, editorMode]);
|
|
147
|
+
}, [root, model, themeMode, readonly, editorMode]);
|
|
128
148
|
|
|
129
149
|
const handleKeyUp = useCallback(
|
|
130
150
|
(event: KeyboardEvent) => {
|
|
@@ -157,25 +177,15 @@ export const BaseTextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
157
177
|
},
|
|
158
178
|
);
|
|
159
179
|
|
|
160
|
-
// TODO(burdon): Allow plugins to set extensions (factory).
|
|
161
|
-
const maybeDebug = (): Extension => {
|
|
162
|
-
// TODO(burdon): Parse JSON script format (with key bindings?)
|
|
163
|
-
const items = localStorage.getItem('dxos.composer.demo');
|
|
164
|
-
if (items) {
|
|
165
|
-
return demo({ items: items.split(',') });
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return [];
|
|
169
|
-
};
|
|
170
|
-
|
|
171
180
|
export const TextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
172
|
-
({ extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
181
|
+
({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
173
182
|
const { themeMode } = useThemeContext();
|
|
174
183
|
const slots = defaultsDeep({}, _slots, defaultTextSlots);
|
|
175
184
|
return (
|
|
176
185
|
<BaseTextEditor
|
|
177
186
|
ref={forwardedRef}
|
|
178
|
-
|
|
187
|
+
readonly={readonly}
|
|
188
|
+
extensions={[basicBundle({ readonly, themeMode, placeholder: slots?.editor?.placeholder }), ...extensions]}
|
|
179
189
|
slots={slots}
|
|
180
190
|
{...props}
|
|
181
191
|
/>
|
|
@@ -184,17 +194,14 @@ export const TextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
184
194
|
);
|
|
185
195
|
|
|
186
196
|
export const MarkdownEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
187
|
-
({ extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
197
|
+
({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
|
|
188
198
|
const { themeMode } = useThemeContext();
|
|
189
199
|
const slots = defaultsDeep({}, _slots, defaultMarkdownSlots);
|
|
190
200
|
return (
|
|
191
201
|
<BaseTextEditor
|
|
192
202
|
ref={forwardedRef}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
maybeDebug(),
|
|
196
|
-
...extensions,
|
|
197
|
-
]}
|
|
203
|
+
readonly={readonly}
|
|
204
|
+
extensions={[markdownBundle({ readonly, themeMode, placeholder: slots?.editor?.placeholder }), ...extensions]}
|
|
198
205
|
slots={slots}
|
|
199
206
|
{...props}
|
|
200
207
|
/>
|
|
@@ -2,23 +2,15 @@
|
|
|
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';
|
|
@@ -51,21 +43,14 @@ export const autocomplete = ({ onSearch }: AutocompleteOptions) => {
|
|
|
51
43
|
// TODO(burdon): Optional decoration via addToOptions
|
|
52
44
|
override: [
|
|
53
45
|
(context: CompletionContext): CompletionResult | null => {
|
|
54
|
-
const
|
|
55
|
-
if (!
|
|
46
|
+
const match = context.matchBefore(/\w*/);
|
|
47
|
+
if (!match || (match.from === match.to && !context.explicit)) {
|
|
56
48
|
return null;
|
|
57
49
|
}
|
|
58
50
|
|
|
59
|
-
// TODO(burdon): Option to convert to links?
|
|
60
51
|
return {
|
|
61
|
-
from:
|
|
62
|
-
options: onSearch(
|
|
63
|
-
// options: [
|
|
64
|
-
// { label: 'apple', type: 'keyword' },
|
|
65
|
-
// { label: 'amazon', type: 'keyword' },
|
|
66
|
-
// { label: 'hello', type: 'variable', info: '(World)' },
|
|
67
|
-
// { label: 'magic', type: 'text', apply: '⠁⭒*.✩.*⭒⠁', detail: 'macro' },
|
|
68
|
-
// ],
|
|
52
|
+
from: match.from,
|
|
53
|
+
options: onSearch(match.text.toLowerCase()),
|
|
69
54
|
};
|
|
70
55
|
},
|
|
71
56
|
],
|