@dxos/react-ui-editor 0.3.10 → 0.3.11-main.3f845e1
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 +1928 -1717
- 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 +16 -9
- 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/extensions/code.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/comments.d.ts +38 -8
- package/dist/types/src/components/TextEditor/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/hr.d.ts +2 -0
- package/dist/types/src/components/TextEditor/extensions/hr.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/index.d.ts +3 -2
- package/dist/types/src/components/TextEditor/extensions/index.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/markdown/highlight.d.ts +0 -1
- package/dist/types/src/components/TextEditor/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/mermaid.d.ts +3 -0
- package/dist/types/src/components/TextEditor/extensions/mermaid.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/table.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/tooltip.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/extensions/{demo.d.ts → typewriter.d.ts} +2 -3
- package/dist/types/src/components/TextEditor/extensions/typewriter.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/extensions/util.d.ts +5 -0
- package/dist/types/src/components/TextEditor/extensions/util.d.ts.map +1 -0
- package/dist/types/src/components/TextEditor/themes/default.d.ts +5 -13
- package/dist/types/src/components/TextEditor/themes/default.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/automerge.stories.d.ts +2 -3
- package/dist/types/src/hooks/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/plugin.d.ts.map +1 -1
- package/dist/types/src/hooks/automerge/{PatchSemaphore.d.ts → semaphore.d.ts} +1 -1
- package/dist/types/src/hooks/automerge/semaphore.d.ts.map +1 -0
- package/dist/types/src/hooks/automerge/update-automerge.d.ts +6 -0
- package/dist/types/src/hooks/automerge/update-automerge.d.ts.map +1 -0
- package/dist/types/src/hooks/automerge/update-codemirror.d.ts +5 -0
- package/dist/types/src/hooks/automerge/update-codemirror.d.ts.map +1 -0
- package/dist/types/src/hooks/useTextModel.d.ts +14 -6
- package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
- package/dist/types/src/hooks/yjs/yjs.test.d.ts +2 -0
- package/dist/types/src/hooks/yjs/yjs.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/testing/replicator.d.ts.map +1 -1
- package/package.json +24 -20
- package/src/components/TextEditor/MarkdownEditor.stories.tsx +128 -67
- package/src/components/TextEditor/TextEditor.stories.tsx +1 -1
- package/src/components/TextEditor/TextEditor.tsx +26 -22
- package/src/components/TextEditor/extensions/code.ts +12 -12
- package/src/components/TextEditor/extensions/comments.ts +307 -92
- package/src/components/TextEditor/extensions/hr.ts +74 -0
- package/src/components/TextEditor/extensions/image.ts +3 -1
- package/src/components/TextEditor/extensions/index.ts +3 -2
- package/src/components/TextEditor/extensions/markdown/highlight.ts +5 -8
- package/src/components/TextEditor/extensions/mermaid.ts +11 -0
- package/src/components/TextEditor/extensions/table.ts +14 -1
- package/src/components/TextEditor/extensions/{tooltip.tsx → tooltip.ts} +1 -1
- package/src/components/TextEditor/extensions/{demo.ts → typewriter.ts} +1 -2
- package/src/components/TextEditor/extensions/util.ts +18 -0
- package/src/components/TextEditor/themes/default.ts +61 -38
- package/src/hooks/automerge/automerge.stories.tsx +2 -3
- package/src/hooks/automerge/plugin.ts +1 -1
- package/src/hooks/automerge/{PatchSemaphore.ts → semaphore.ts} +4 -3
- package/src/hooks/automerge/{translation/codemirror-to-automerge.ts → update-automerge.ts} +3 -3
- package/src/hooks/automerge/{translation/automerge-to-codemirror.ts → update-codemirror.ts} +2 -7
- package/src/hooks/useTextModel.ts +59 -22
- package/src/hooks/yjs/yjs.test.ts +59 -0
- package/src/index.ts +1 -0
- package/src/testing/replicator.ts +0 -1
- package/dist/types/src/components/TextEditor/extensions/demo.d.ts.map +0 -1
- package/dist/types/src/components/TextEditor/extensions/experimental.d.ts +0 -10
- package/dist/types/src/components/TextEditor/extensions/experimental.d.ts.map +0 -1
- package/dist/types/src/components/TextEditor/extensions/highlight.d.ts +0 -24
- package/dist/types/src/components/TextEditor/extensions/highlight.d.ts.map +0 -1
- package/dist/types/src/hooks/automerge/PatchSemaphore.d.ts.map +0 -1
- package/dist/types/src/hooks/automerge/translation/automerge-to-codemirror.d.ts +0 -5
- package/dist/types/src/hooks/automerge/translation/automerge-to-codemirror.d.ts.map +0 -1
- package/dist/types/src/hooks/automerge/translation/codemirror-to-automerge.d.ts +0 -6
- package/dist/types/src/hooks/automerge/translation/codemirror-to-automerge.d.ts.map +0 -1
- package/dist/types/src/hooks/automerge/translation/index.d.ts +0 -3
- package/dist/types/src/hooks/automerge/translation/index.d.ts.map +0 -1
- package/src/components/TextEditor/extensions/experimental.tsx +0 -114
- package/src/components/TextEditor/extensions/highlight.ts +0 -128
- package/src/hooks/automerge/translation/index.ts +0 -6
|
@@ -1,19 +1,27 @@
|
|
|
1
|
-
import { type Extension } from '@codemirror/state';
|
|
1
|
+
import { type Extension, StateField } from '@codemirror/state';
|
|
2
2
|
import type * as awarenessProtocol from 'y-protocols/awareness';
|
|
3
3
|
import { type DocAccessor, type Space, type TextObject } from '@dxos/react-client/echo';
|
|
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
|
-
|
|
8
|
-
|
|
7
|
+
/**
|
|
8
|
+
* State field makes the model available to other extensions.
|
|
9
|
+
*/
|
|
10
|
+
export declare const modelState: StateField<EditorModel | undefined>;
|
|
11
|
+
export type Range = {
|
|
9
12
|
from: number;
|
|
10
13
|
to: number;
|
|
11
14
|
};
|
|
15
|
+
export type CommentRange = {
|
|
16
|
+
id: string;
|
|
17
|
+
cursor: string;
|
|
18
|
+
};
|
|
12
19
|
export type EditorModel = {
|
|
13
20
|
id: string;
|
|
14
21
|
content: string | YText | YXmlFragment | DocAccessor;
|
|
15
22
|
text: () => string;
|
|
16
|
-
|
|
23
|
+
getCursorFromRange?: (value: Range) => string;
|
|
24
|
+
getRangeFromCursor?: (cursor: string) => Range;
|
|
17
25
|
extension?: Extension;
|
|
18
26
|
awareness?: Awareness;
|
|
19
27
|
peer?: {
|
|
@@ -21,11 +29,11 @@ export type EditorModel = {
|
|
|
21
29
|
name?: string;
|
|
22
30
|
};
|
|
23
31
|
};
|
|
24
|
-
export type
|
|
32
|
+
export type UseTextModelProps = {
|
|
25
33
|
identity?: Identity | null;
|
|
26
34
|
space?: Space;
|
|
27
35
|
text?: TextObject;
|
|
28
36
|
};
|
|
29
|
-
export declare const useTextModel: (
|
|
37
|
+
export declare const useTextModel: (props: UseTextModelProps) => EditorModel | undefined;
|
|
30
38
|
export {};
|
|
31
39
|
//# sourceMappingURL=useTextModel.d.ts.map
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"useTextModel.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useTextModel.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,SAAS,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAI/D,OAAO,KAAK,KAAK,iBAAiB,MAAM,uBAAuB,CAAC;AAIhE,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;AAO5D,KAAK,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC;AAE7C;;GAEG;AAEH,eAAO,MAAM,UAAU,qCAGrB,CAAC;AAEH,MAAM,MAAM,KAAK,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IAEX,MAAM,EAAE,MAAM,CAAC;CAChB,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,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC;IAC9C,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,KAAK,CAAC;IAC/C,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,iBAAiB,GAAG;IAC9B,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,UAAW,iBAAiB,KAAG,WAAW,GAAG,SAKrE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yjs.test.d.ts","sourceRoot":"","sources":["../../../../../src/hooks/yjs/yjs.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { TextKind } from '@dxos/protocols/proto/dxos/echo/model/text';
|
|
2
2
|
export { Doc, YText, YXmlFragment } from '@dxos/text-model';
|
|
3
|
+
export { type Extension } from '@codemirror/state';
|
|
3
4
|
export * from './components';
|
|
4
5
|
export * from './hooks';
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,MAAM,4CAA4C,CAAC;AACtE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,MAAM,4CAA4C,CAAC;AACtE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,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.
|
|
3
|
+
"version": "0.3.11-main.3f845e1",
|
|
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",
|
|
@@ -32,24 +32,25 @@
|
|
|
32
32
|
"lib0": "^0.2.65",
|
|
33
33
|
"lodash.defaultsdeep": "^4.6.1",
|
|
34
34
|
"lodash.get": "^4.4.2",
|
|
35
|
+
"lodash.pick": "^4.4.0",
|
|
35
36
|
"lodash.sortby": "^4.7.0",
|
|
36
37
|
"style-mod": "^4.1.0",
|
|
37
38
|
"y-codemirror.next": "^0.3.2",
|
|
38
39
|
"y-protocols": "^1.0.5",
|
|
39
40
|
"yjs": "^13.6.10",
|
|
40
|
-
"@dxos/
|
|
41
|
-
"@dxos/
|
|
42
|
-
"@dxos/
|
|
43
|
-
"@dxos/display-name": "0.3.
|
|
44
|
-
"@dxos/
|
|
45
|
-
"@dxos/
|
|
46
|
-
"@dxos/
|
|
47
|
-
"@dxos/
|
|
48
|
-
"@dxos/
|
|
49
|
-
"@dxos/react-ui": "0.3.
|
|
50
|
-
"@dxos/react-ui-theme": "0.3.
|
|
51
|
-
"@dxos/
|
|
52
|
-
"@dxos/
|
|
41
|
+
"@dxos/async": "0.3.11-main.3f845e1",
|
|
42
|
+
"@dxos/debug": "0.3.11-main.3f845e1",
|
|
43
|
+
"@dxos/automerge": "0.3.11-main.3f845e1",
|
|
44
|
+
"@dxos/display-name": "0.3.11-main.3f845e1",
|
|
45
|
+
"@dxos/echo-schema": "0.3.11-main.3f845e1",
|
|
46
|
+
"@dxos/invariant": "0.3.11-main.3f845e1",
|
|
47
|
+
"@dxos/log": "0.3.11-main.3f845e1",
|
|
48
|
+
"@dxos/protocols": "0.3.11-main.3f845e1",
|
|
49
|
+
"@dxos/react-async": "0.3.11-main.3f845e1",
|
|
50
|
+
"@dxos/react-ui": "0.3.11-main.3f845e1",
|
|
51
|
+
"@dxos/react-ui-theme": "0.3.11-main.3f845e1",
|
|
52
|
+
"@dxos/util": "0.3.11-main.3f845e1",
|
|
53
|
+
"@dxos/text-model": "0.3.11-main.3f845e1"
|
|
53
54
|
},
|
|
54
55
|
"devDependencies": {
|
|
55
56
|
"@automerge/automerge-repo-network-broadcastchannel": "^1.0.19",
|
|
@@ -58,22 +59,25 @@
|
|
|
58
59
|
"@preact/signals-react": "^1.3.6",
|
|
59
60
|
"@types/lodash.defaultsdeep": "^4.6.6",
|
|
60
61
|
"@types/lodash.get": "^4.4.7",
|
|
62
|
+
"@types/lodash.pick": "^4.4.7",
|
|
61
63
|
"@types/lodash.sortby": "^4.7.7",
|
|
62
64
|
"@types/react": "^18.0.21",
|
|
63
65
|
"@types/react-dom": "^18.0.6",
|
|
66
|
+
"deepsignal": "1.4.0-shallow.0",
|
|
64
67
|
"react": "^18.2.0",
|
|
65
68
|
"react-dom": "^18.2.0",
|
|
66
|
-
"@dxos/
|
|
67
|
-
"@dxos/echo-typegen": "0.3.
|
|
68
|
-
"@dxos/
|
|
69
|
-
"@dxos/
|
|
70
|
-
"@dxos/
|
|
69
|
+
"@dxos/echo-signals": "0.3.11-main.3f845e1",
|
|
70
|
+
"@dxos/echo-typegen": "0.3.11-main.3f845e1",
|
|
71
|
+
"@dxos/config": "0.3.11-main.3f845e1",
|
|
72
|
+
"@dxos/react-client": "0.3.11-main.3f845e1",
|
|
73
|
+
"@dxos/storybook-utils": "0.3.11-main.3f845e1",
|
|
74
|
+
"@dxos/react-ui": "0.3.11-main.3f845e1"
|
|
71
75
|
},
|
|
72
76
|
"peerDependencies": {
|
|
73
77
|
"@phosphor-icons/react": "^2.0.5",
|
|
74
78
|
"react": "^18.2.0",
|
|
75
79
|
"react-dom": "^18.2.0",
|
|
76
|
-
"@dxos/react-client": "0.3.
|
|
80
|
+
"@dxos/react-client": "0.3.11-main.3f845e1"
|
|
77
81
|
},
|
|
78
82
|
"publishConfig": {
|
|
79
83
|
"access": "public"
|
|
@@ -8,7 +8,7 @@ import { EditorView } from '@codemirror/view';
|
|
|
8
8
|
import { faker } from '@faker-js/faker';
|
|
9
9
|
import { ArrowSquareOut } from '@phosphor-icons/react';
|
|
10
10
|
import defaultsDeep from 'lodash.defaultsdeep';
|
|
11
|
-
import React, { StrictMode, useRef, useState } from 'react';
|
|
11
|
+
import React, { type FC, StrictMode, useRef, useState } from 'react';
|
|
12
12
|
import { createRoot } from 'react-dom/client';
|
|
13
13
|
|
|
14
14
|
import { TextObject } from '@dxos/echo-schema';
|
|
@@ -19,28 +19,32 @@ import { withTheme } from '@dxos/storybook-utils';
|
|
|
19
19
|
import { MarkdownEditor, type TextEditorProps, type TextEditorRef } from './TextEditor';
|
|
20
20
|
import {
|
|
21
21
|
autocomplete,
|
|
22
|
+
blast,
|
|
23
|
+
code,
|
|
24
|
+
comments,
|
|
25
|
+
defaultOptions,
|
|
26
|
+
hr,
|
|
27
|
+
image,
|
|
22
28
|
listener,
|
|
23
29
|
link,
|
|
30
|
+
mention,
|
|
31
|
+
table,
|
|
24
32
|
tasklist,
|
|
25
33
|
tooltip,
|
|
34
|
+
typewriter,
|
|
35
|
+
type CommentsOptions,
|
|
26
36
|
type TooltipOptions,
|
|
27
37
|
type LinkOptions,
|
|
28
|
-
|
|
29
|
-
table,
|
|
30
|
-
image,
|
|
31
|
-
mention,
|
|
32
|
-
blast,
|
|
33
|
-
demo,
|
|
34
|
-
defaultOptions,
|
|
35
|
-
highlight,
|
|
36
|
-
code,
|
|
38
|
+
mermaid,
|
|
37
39
|
} from './extensions';
|
|
38
|
-
import { useTextModel } from '../../hooks';
|
|
40
|
+
import { type CommentRange, useTextModel } from '../../hooks';
|
|
39
41
|
|
|
40
42
|
// Extensions:
|
|
41
43
|
// TODO(burdon): Table of contents.
|
|
42
44
|
// TODO(burdon): Front-matter
|
|
43
45
|
|
|
46
|
+
faker.seed(101);
|
|
47
|
+
|
|
44
48
|
const str = (...lines: string[]) => lines.join('\n');
|
|
45
49
|
|
|
46
50
|
const num = () => faker.number.int({ min: 0, max: 9999 }).toLocaleString();
|
|
@@ -55,6 +59,7 @@ const text = {
|
|
|
55
59
|
' - [ ] state',
|
|
56
60
|
' - [ ] indent',
|
|
57
61
|
' - [x] style',
|
|
62
|
+
'',
|
|
58
63
|
),
|
|
59
64
|
|
|
60
65
|
list: str(
|
|
@@ -63,6 +68,7 @@ const text = {
|
|
|
63
68
|
'- new york',
|
|
64
69
|
'- london',
|
|
65
70
|
'- tokyo',
|
|
71
|
+
'',
|
|
66
72
|
),
|
|
67
73
|
|
|
68
74
|
numbered: str(
|
|
@@ -87,8 +93,8 @@ const text = {
|
|
|
87
93
|
'',
|
|
88
94
|
' return () => <div>Test</div>;',
|
|
89
95
|
'};',
|
|
96
|
+
'```',
|
|
90
97
|
'',
|
|
91
|
-
'```'
|
|
92
98
|
),
|
|
93
99
|
|
|
94
100
|
links: str(
|
|
@@ -103,11 +109,11 @@ const text = {
|
|
|
103
109
|
table: str(
|
|
104
110
|
'# Table',
|
|
105
111
|
'',
|
|
106
|
-
`| ${faker.lorem.word().padStart(
|
|
107
|
-
'
|
|
108
|
-
`| ${num().padStart(
|
|
109
|
-
`| ${num().padStart(
|
|
110
|
-
`| ${num().padStart(
|
|
112
|
+
`| ${faker.lorem.word().padStart(12)} | ${faker.lorem.word().padStart(12)} | ${faker.lorem.word().padStart(12)} |`,
|
|
113
|
+
`|-${''.padStart(12, '-')}-|-${''.padStart(12, '-')}-|-${''.padStart(12, '-')}-|`,
|
|
114
|
+
`| ${num().padStart(12)} | ${num().padStart(12)} | ${num().padStart(12)} |`,
|
|
115
|
+
`| ${num().padStart(12)} | ${num().padStart(12)} | ${num().padStart(12)} |`,
|
|
116
|
+
`| ${num().padStart(12)} | ${num().padStart(12)} | ${num().padStart(12)} |`,
|
|
111
117
|
'', // TODO(burdon): Possible GFM parsing bug if no newline?
|
|
112
118
|
),
|
|
113
119
|
|
|
@@ -119,6 +125,8 @@ const text = {
|
|
|
119
125
|
|
|
120
126
|
paragraphs: str(...faker.helpers.multiple(() => [faker.lorem.paragraph(), ''], { count: 3 }).flat()),
|
|
121
127
|
|
|
128
|
+
mermaid: str('```mermaid', 'graph TD;', 'A-->B;', 'A-->C;', 'B-->D;', 'C-->D;', '```'),
|
|
129
|
+
|
|
122
130
|
footer: str('', '', '', '', '')
|
|
123
131
|
};
|
|
124
132
|
|
|
@@ -147,7 +155,6 @@ const document = str(
|
|
|
147
155
|
text.table,
|
|
148
156
|
'---',
|
|
149
157
|
text.image,
|
|
150
|
-
'',
|
|
151
158
|
text.footer,
|
|
152
159
|
);
|
|
153
160
|
|
|
@@ -162,7 +169,7 @@ const links = [
|
|
|
162
169
|
const hover =
|
|
163
170
|
'rounded-sm text-base text-primary-600 hover:text-primary-500 dark:text-primary-300 hover:dark:text-primary-200';
|
|
164
171
|
|
|
165
|
-
const
|
|
172
|
+
const onTooltipHover: TooltipOptions['onHover'] = (el, url) => {
|
|
166
173
|
const web = new URL(url);
|
|
167
174
|
createRoot(el).render(
|
|
168
175
|
<StrictMode>
|
|
@@ -174,7 +181,28 @@ const onHover: TooltipOptions['onHover'] = (el, url) => {
|
|
|
174
181
|
);
|
|
175
182
|
};
|
|
176
183
|
|
|
177
|
-
const
|
|
184
|
+
const Key: FC<{ char: string }> = ({ char }) => (
|
|
185
|
+
<span className='flex justify-center items-center w-[24px] h-[24px] rounded text-xs bg-neutral-200 text-black'>
|
|
186
|
+
{char}
|
|
187
|
+
</span>
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
const onCommentsHover: CommentsOptions['onHover'] = (el) => {
|
|
191
|
+
createRoot(el).render(
|
|
192
|
+
<StrictMode>
|
|
193
|
+
<div className='flex items-center gap-2 px-2 py-2 bg-neutral-700 text-white text-xs rounded'>
|
|
194
|
+
<div>Create comment</div>
|
|
195
|
+
{/* TODO(burdon): Unify shortcuts. */}
|
|
196
|
+
<div className='flex gap-1'>
|
|
197
|
+
<Key char='⌘' />
|
|
198
|
+
<Key char="'" />
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
</StrictMode>,
|
|
202
|
+
);
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const onLinkRender: LinkOptions['onRender'] = (el, url) => {
|
|
178
206
|
createRoot(el).render(
|
|
179
207
|
<StrictMode>
|
|
180
208
|
<a href={url} target='_blank' rel='noreferrer' className={hover}>
|
|
@@ -184,14 +212,14 @@ const onRender: LinkOptions['onRender'] = (el, url) => {
|
|
|
184
212
|
);
|
|
185
213
|
};
|
|
186
214
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
215
|
+
type StoryProps = {
|
|
216
|
+
text?: string;
|
|
217
|
+
automerge?: boolean;
|
|
218
|
+
} & Pick<TextEditorProps, 'comments' | 'readonly' | 'extensions' | 'slots'>;
|
|
219
|
+
|
|
220
|
+
const Story = ({ text, automerge, ...props }: StoryProps) => {
|
|
193
221
|
const ref = useRef<TextEditorRef>(null);
|
|
194
|
-
const [item] = useState({ text: new TextObject(text, undefined, undefined, {
|
|
222
|
+
const [item] = useState({ text: new TextObject(text, undefined, undefined, { automerge }) });
|
|
195
223
|
const model = useTextModel({ text: item.text });
|
|
196
224
|
if (!model) {
|
|
197
225
|
return null;
|
|
@@ -221,11 +249,12 @@ const extensions = [
|
|
|
221
249
|
onSearch: (text) => links.filter(({ label }) => label.toLowerCase().includes(text.toLowerCase())),
|
|
222
250
|
}),
|
|
223
251
|
code(),
|
|
252
|
+
hr(),
|
|
224
253
|
image(),
|
|
225
|
-
link({ onRender }),
|
|
254
|
+
link({ onRender: onLinkRender }),
|
|
226
255
|
table(),
|
|
227
256
|
tasklist(),
|
|
228
|
-
tooltip({ onHover }),
|
|
257
|
+
tooltip({ onHover: onTooltipHover }),
|
|
229
258
|
];
|
|
230
259
|
|
|
231
260
|
export const Default = {
|
|
@@ -236,12 +265,26 @@ export const Readonly = {
|
|
|
236
265
|
render: () => <Story text={document} extensions={extensions} readonly />,
|
|
237
266
|
};
|
|
238
267
|
|
|
268
|
+
export const NoExtensions = {
|
|
269
|
+
render: () => <Story text={document} />,
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
// TODO(burdon): Cursor bug if no newline after BR (cursor down just loops back to start of each paragraph).
|
|
273
|
+
export const HorizontalRule = {
|
|
274
|
+
render: () => (
|
|
275
|
+
<Story
|
|
276
|
+
text={str('# Horizontal Rule', '', text.paragraphs, '---', '', text.paragraphs, '---', '', text.paragraphs)}
|
|
277
|
+
extensions={[hr()]}
|
|
278
|
+
/>
|
|
279
|
+
),
|
|
280
|
+
};
|
|
281
|
+
|
|
239
282
|
export const Tooltips = {
|
|
240
|
-
render: () => <Story text={str(text.links, text.footer)} extensions={[tooltip({ onHover })]} />,
|
|
283
|
+
render: () => <Story text={str(text.links, text.footer)} extensions={[tooltip({ onHover: onTooltipHover })]} />,
|
|
241
284
|
};
|
|
242
285
|
|
|
243
286
|
export const Links = {
|
|
244
|
-
render: () => <Story text={str(text.links, text.footer)} extensions={[link({ onRender })]} />,
|
|
287
|
+
render: () => <Story text={str(text.links, text.footer)} extensions={[link({ onRender: onLinkRender })]} />,
|
|
245
288
|
};
|
|
246
289
|
|
|
247
290
|
export const Code = {
|
|
@@ -256,7 +299,7 @@ export const Image = {
|
|
|
256
299
|
render: () => <Story text={str(text.image, text.footer)} readonly extensions={[image()]} />,
|
|
257
300
|
};
|
|
258
301
|
|
|
259
|
-
export const
|
|
302
|
+
export const Tasklist = {
|
|
260
303
|
render: () => (
|
|
261
304
|
<Story
|
|
262
305
|
text={str(text.tasks, '', text.list, text.footer)}
|
|
@@ -277,7 +320,7 @@ export const Autocomplete = {
|
|
|
277
320
|
<Story
|
|
278
321
|
text={str('# Autocomplete', '', 'Press CTRL-SPACE', text.footer)}
|
|
279
322
|
extensions={[
|
|
280
|
-
link({ onRender }),
|
|
323
|
+
link({ onRender: onLinkRender }),
|
|
281
324
|
autocomplete({
|
|
282
325
|
onSearch: (text) => links.filter(({ label }) => label.toLowerCase().includes(text.toLowerCase())),
|
|
283
326
|
}),
|
|
@@ -301,48 +344,56 @@ export const Mention = {
|
|
|
301
344
|
),
|
|
302
345
|
};
|
|
303
346
|
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
-
render: () => (
|
|
307
|
-
<Story
|
|
308
|
-
text={str(text.paragraphs, mark(), '', mark(), text.footer)}
|
|
309
|
-
extensions={[
|
|
310
|
-
comments({
|
|
311
|
-
onCreate: () => PublicKey.random().toHex(),
|
|
312
|
-
onUpdate: (info) => {
|
|
313
|
-
// console.log('update', info);
|
|
314
|
-
},
|
|
315
|
-
}),
|
|
316
|
-
highlight(),
|
|
317
|
-
]}
|
|
318
|
-
/>
|
|
319
|
-
),
|
|
347
|
+
export const Mermaid = {
|
|
348
|
+
render: () => <Story text={str('# Mermaid', '', text.mermaid, text.footer)} extensions={[code(), mermaid()]} />,
|
|
320
349
|
};
|
|
321
350
|
|
|
322
|
-
export const
|
|
323
|
-
render: () =>
|
|
324
|
-
<
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
351
|
+
export const Comments = {
|
|
352
|
+
render: () => {
|
|
353
|
+
const [commentsStates, setCommentStates] = useState<CommentRange[]>([]);
|
|
354
|
+
|
|
355
|
+
return (
|
|
356
|
+
<Story
|
|
357
|
+
text={str('# Comments', '', text.paragraphs, text.footer)}
|
|
358
|
+
comments={commentsStates}
|
|
359
|
+
extensions={[
|
|
360
|
+
comments({
|
|
361
|
+
onHover: onCommentsHover,
|
|
362
|
+
onCreate: (relPos) => {
|
|
363
|
+
const id = PublicKey.random().toHex();
|
|
364
|
+
setCommentStates((comments) => [...comments, { id, cursor: relPos }]);
|
|
365
|
+
return id;
|
|
366
|
+
},
|
|
367
|
+
onSelect: (state) => {
|
|
368
|
+
const debug = false;
|
|
369
|
+
if (debug) {
|
|
370
|
+
console.log(
|
|
371
|
+
'update',
|
|
372
|
+
JSON.stringify({
|
|
373
|
+
active: state.active?.slice(0, 8),
|
|
374
|
+
closest: state.closest?.slice(0, 8),
|
|
375
|
+
ranges: state.ranges.length,
|
|
376
|
+
}),
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
}),
|
|
381
|
+
]}
|
|
382
|
+
/>
|
|
383
|
+
);
|
|
384
|
+
},
|
|
334
385
|
};
|
|
335
386
|
|
|
336
|
-
export const
|
|
337
|
-
render: () => <Story text={str(text.paragraphs, text.footer)} extensions={[
|
|
387
|
+
export const Typewriter = {
|
|
388
|
+
render: () => <Story text={str('# Typewriter', '', text.paragraphs, text.footer)} extensions={[typewriter()]} />,
|
|
338
389
|
};
|
|
339
390
|
|
|
340
391
|
export const Blast = {
|
|
341
392
|
render: () => (
|
|
342
393
|
<Story
|
|
343
|
-
text={str(text.paragraphs, text.code, text.paragraphs)}
|
|
394
|
+
text={str('# Blast', '', text.paragraphs, text.code, text.paragraphs)}
|
|
344
395
|
extensions={[
|
|
345
|
-
|
|
396
|
+
typewriter({
|
|
346
397
|
items: localStorage.getItem('dxos.composer.extension.demo')?.split(','),
|
|
347
398
|
}),
|
|
348
399
|
blast(
|
|
@@ -362,6 +413,16 @@ export const Blast = {
|
|
|
362
413
|
),
|
|
363
414
|
};
|
|
364
415
|
|
|
365
|
-
export const
|
|
366
|
-
render: () =>
|
|
416
|
+
export const Diagnostics = {
|
|
417
|
+
render: () => (
|
|
418
|
+
<Story
|
|
419
|
+
text={document}
|
|
420
|
+
extensions={[
|
|
421
|
+
// Cursor moved.
|
|
422
|
+
EditorView.updateListener.of((update) => {
|
|
423
|
+
console.log('update', update.view.state.selection.main.head);
|
|
424
|
+
}),
|
|
425
|
+
]}
|
|
426
|
+
/>
|
|
427
|
+
),
|
|
367
428
|
};
|
|
@@ -31,7 +31,7 @@ const Story = ({
|
|
|
31
31
|
...props
|
|
32
32
|
}: { text?: string; automerge?: boolean } & Pick<TextEditorProps, 'extensions' | 'slots'>) => {
|
|
33
33
|
const ref = useRef<TextEditorRef>(null);
|
|
34
|
-
const [item] = useState({ text: new TextObject(text, undefined, undefined, {
|
|
34
|
+
const [item] = useState({ text: new TextObject(text, undefined, undefined, { automerge }) });
|
|
35
35
|
const model = useTextModel({ text: item.text });
|
|
36
36
|
if (!model) {
|
|
37
37
|
return null;
|
|
@@ -21,9 +21,9 @@ 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, markdownBundle } from './extensions';
|
|
24
|
+
import { basicBundle, markdownBundle, setCommentRange } from './extensions';
|
|
25
25
|
import { defaultTheme, markdownTheme, textTheme } from './themes';
|
|
26
|
-
import { type EditorModel } from '../../hooks';
|
|
26
|
+
import { type CommentRange, type EditorModel } from '../../hooks';
|
|
27
27
|
import { type ThemeStyles } from '../../styles';
|
|
28
28
|
|
|
29
29
|
export const EditorModes = ['default', 'vim'] as const;
|
|
@@ -56,6 +56,7 @@ export type TextEditorSlots = {
|
|
|
56
56
|
|
|
57
57
|
export type TextEditorProps = {
|
|
58
58
|
model: EditorModel;
|
|
59
|
+
comments?: CommentRange[];
|
|
59
60
|
readonly?: boolean;
|
|
60
61
|
editorMode?: EditorMode;
|
|
61
62
|
extensions?: Extension[];
|
|
@@ -67,13 +68,13 @@ export type TextEditorProps = {
|
|
|
67
68
|
* NOTE: Rather than adding properties, try to create extensions that can be reused.
|
|
68
69
|
*/
|
|
69
70
|
export const BaseTextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
70
|
-
({ model, readonly, editorMode, extensions = [], slots = defaultSlots }, forwardedRef) => {
|
|
71
|
+
({ model, comments, readonly, editorMode, extensions = [], slots = defaultSlots }, forwardedRef) => {
|
|
71
72
|
const { themeMode } = useThemeContext();
|
|
72
73
|
const tabsterDOMAttribute = useFocusableGroup({ tabBehavior: 'limited' });
|
|
73
|
-
|
|
74
74
|
const [root, setRoot] = useState<HTMLDivElement | null>(null);
|
|
75
|
-
const [state,
|
|
76
|
-
|
|
75
|
+
const [{ state = undefined, view = undefined } = {}, setEditor] = useState<
|
|
76
|
+
{ state?: EditorState; view?: EditorView } | undefined
|
|
77
|
+
>();
|
|
77
78
|
useImperativeHandle(forwardedRef, () => ({ root, state, view }), [view, state, root]);
|
|
78
79
|
|
|
79
80
|
// TODO(burdon): Factor out?
|
|
@@ -88,30 +89,34 @@ export const BaseTextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
88
89
|
}
|
|
89
90
|
}, [awareness, peer, themeMode]);
|
|
90
91
|
|
|
91
|
-
// TODO(burdon):
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
// TODO(burdon): Factor out as extension.
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
if (view && comments?.length) {
|
|
95
|
+
view.dispatch({
|
|
96
|
+
effects: setCommentRange.of({ model, comments }),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}, [view, comments]);
|
|
96
100
|
|
|
97
101
|
useEffect(() => {
|
|
98
102
|
if (!root) {
|
|
99
103
|
return;
|
|
100
104
|
}
|
|
101
105
|
|
|
106
|
+
// TODO(burdon): Remember cursor position.
|
|
107
|
+
// https://codemirror.net/docs/ref/#state.EditorStateConfig
|
|
102
108
|
const state = EditorState.create({
|
|
103
109
|
doc: model.text(),
|
|
104
110
|
extensions: [
|
|
105
111
|
readonly && EditorState.readOnly.of(readonly),
|
|
106
112
|
|
|
107
|
-
// TODO(burdon): Factor out VIM mode?
|
|
113
|
+
// TODO(burdon): Factor out VIM mode? (manage via MarkdownPlugin).
|
|
108
114
|
editorMode === 'vim' && vim(),
|
|
109
115
|
|
|
110
116
|
// Theme.
|
|
111
|
-
// TODO(burdon): Make
|
|
117
|
+
// TODO(burdon): Make theme configurable.
|
|
112
118
|
EditorView.baseTheme(defaultTheme),
|
|
113
119
|
EditorView.theme(slots?.editor?.theme ?? {}),
|
|
114
|
-
// TODO(burdon): themeMode doesn't change in storybooks.
|
|
115
120
|
EditorView.darkTheme.of(themeMode === 'dark'),
|
|
116
121
|
|
|
117
122
|
// Storage and replication.
|
|
@@ -124,10 +129,11 @@ export const BaseTextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
124
129
|
|
|
125
130
|
// NOTE: This repaints the editor.
|
|
126
131
|
// If the new state is derived from the old state, it will likely not be visible other than the cursor resetting.
|
|
127
|
-
// Ideally this should not
|
|
132
|
+
// Ideally this should not happen except when changing between text objects.
|
|
128
133
|
view?.destroy();
|
|
129
|
-
|
|
130
|
-
|
|
134
|
+
setEditor({
|
|
135
|
+
state,
|
|
136
|
+
view: new EditorView({
|
|
131
137
|
state,
|
|
132
138
|
parent: root,
|
|
133
139
|
// NOTE: Uncomment to spy on all transactions.
|
|
@@ -136,15 +142,13 @@ export const BaseTextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
136
142
|
// view.update([transaction]);
|
|
137
143
|
// },
|
|
138
144
|
}),
|
|
139
|
-
);
|
|
140
|
-
setState(state);
|
|
145
|
+
});
|
|
141
146
|
|
|
142
147
|
return () => {
|
|
143
148
|
view?.destroy();
|
|
144
|
-
|
|
145
|
-
setState(undefined);
|
|
149
|
+
setEditor(undefined);
|
|
146
150
|
};
|
|
147
|
-
}, [root, model,
|
|
151
|
+
}, [root, model, readonly, editorMode, themeMode]);
|
|
148
152
|
|
|
149
153
|
const handleKeyUp = useCallback(
|
|
150
154
|
(event: KeyboardEvent) => {
|