@dxos/react-ui-editor 0.6.12-main.ed7cda7 → 0.6.12-staging.e11e696
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/chunk-AZWYO7TE.mjs +148 -0
- package/dist/lib/browser/chunk-AZWYO7TE.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +152 -269
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/state/index.mjs +17 -0
- package/dist/lib/browser/state/index.mjs.map +7 -0
- package/dist/lib/node/chunk-5RSKGJRI.cjs +169 -0
- package/dist/lib/node/chunk-5RSKGJRI.cjs.map +7 -0
- package/dist/lib/node/index.cjs +5480 -0
- package/dist/lib/node/index.cjs.map +7 -0
- package/dist/lib/node/meta.json +1 -0
- package/dist/lib/node/state/index.cjs +39 -0
- package/dist/lib/node/state/index.cjs.map +7 -0
- package/dist/lib/node-esm/chunk-RCIWLRIY.mjs +150 -0
- package/dist/lib/node-esm/chunk-RCIWLRIY.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +5472 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/lib/node-esm/state/index.mjs +18 -0
- package/dist/lib/node-esm/state/index.mjs.map +7 -0
- package/dist/types/src/TextEditor.stories.d.ts +3 -0
- package/dist/types/src/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/autocomplete.d.ts +2 -1
- package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts +1 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
- package/dist/types/src/extensions/awareness/awareness.d.ts +2 -2
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -1
- package/dist/types/src/extensions/command/state.d.ts +2 -2
- package/dist/types/src/extensions/command/state.d.ts.map +1 -1
- package/dist/types/src/extensions/comments.d.ts +1 -1
- package/dist/types/src/extensions/comments.d.ts.map +1 -1
- package/dist/types/src/extensions/debug.d.ts +2 -2
- package/dist/types/src/extensions/debug.d.ts.map +1 -1
- package/dist/types/src/extensions/folding.d.ts.map +1 -1
- package/dist/types/src/extensions/index.d.ts +0 -4
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts +1 -1
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
- package/dist/types/src/extensions/modes.d.ts +3 -3
- package/dist/types/src/extensions/modes.d.ts.map +1 -1
- package/dist/types/src/extensions/util/overlap.d.ts +1 -1
- package/dist/types/src/extensions/util/overlap.d.ts.map +1 -1
- package/dist/types/src/extensions/util/react.d.ts +1 -1
- package/dist/types/src/extensions/util/react.d.ts.map +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts +1 -1
- package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/{extensions → state}/cursor.d.ts +2 -2
- package/dist/types/src/state/cursor.d.ts.map +1 -0
- package/dist/types/src/state/doc.d.ts +5 -0
- package/dist/types/src/state/doc.d.ts.map +1 -0
- package/dist/types/src/state/index.d.ts +6 -0
- package/dist/types/src/state/index.d.ts.map +1 -0
- package/dist/types/src/state/state.d.ts.map +1 -0
- package/dist/types/src/state/types.d.ts.map +1 -0
- package/dist/types/src/state/util.d.ts +3 -0
- package/dist/types/src/state/util.d.ts.map +1 -0
- package/dist/types/src/styles/markdown.d.ts +1 -2
- package/dist/types/src/styles/markdown.d.ts.map +1 -1
- package/dist/types/src/styles/theme.d.ts.map +1 -1
- package/package.json +45 -33
- package/src/TextEditor.stories.tsx +9 -5
- package/src/extensions/annotations.ts +1 -1
- package/src/extensions/autocomplete.ts +9 -8
- package/src/extensions/automerge/automerge.stories.tsx +1 -1
- package/src/extensions/automerge/automerge.ts +1 -1
- package/src/extensions/automerge/cursor.ts +1 -1
- package/src/extensions/awareness/awareness.ts +3 -5
- package/src/extensions/command/state.ts +3 -4
- package/src/extensions/comments.ts +37 -43
- package/src/extensions/debug.ts +2 -2
- package/src/extensions/folding.tsx +4 -2
- package/src/extensions/index.ts +0 -4
- package/src/extensions/markdown/decorate.ts +49 -6
- package/src/extensions/markdown/highlight.ts +0 -5
- package/src/extensions/markdown/link.ts +3 -2
- package/src/extensions/markdown/styles.ts +10 -0
- package/src/extensions/markdown/table.ts +3 -3
- package/src/extensions/modes.ts +6 -5
- package/src/extensions/util/overlap.ts +1 -1
- package/src/extensions/util/react.tsx +5 -1
- package/src/hooks/useTextEditor.ts +3 -2
- package/src/index.ts +1 -0
- package/src/{extensions → state}/cursor.ts +3 -6
- package/src/state/doc.ts +10 -0
- package/src/state/index.ts +11 -0
- package/src/{extensions → state}/state.ts +1 -0
- package/src/state/util.ts +13 -0
- package/src/styles/markdown.ts +1 -3
- package/src/styles/theme.ts +2 -0
- package/dist/types/src/extensions/cursor.d.ts.map +0 -1
- package/dist/types/src/extensions/doc.d.ts +0 -6
- package/dist/types/src/extensions/doc.d.ts.map +0 -1
- package/dist/types/src/extensions/state.d.ts.map +0 -1
- package/dist/types/src/extensions/types.d.ts.map +0 -1
- package/src/extensions/doc.ts +0 -17
- /package/dist/types/src/{extensions → state}/state.d.ts +0 -0
- /package/dist/types/src/{extensions → state}/types.d.ts +0 -0
- /package/src/{extensions → state}/types.ts +0 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@dxos/react-ui-editor",
|
3
|
-
"version": "0.6.12-
|
3
|
+
"version": "0.6.12-staging.e11e696",
|
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",
|
@@ -9,7 +9,19 @@
|
|
9
9
|
"exports": {
|
10
10
|
".": {
|
11
11
|
"browser": "./dist/lib/browser/index.mjs",
|
12
|
+
"node": {
|
13
|
+
"require": "./dist/lib/node/index.cjs",
|
14
|
+
"default": "./dist/lib/node-esm/index.mjs"
|
15
|
+
},
|
12
16
|
"types": "./dist/types/src/index.d.ts"
|
17
|
+
},
|
18
|
+
"./state": {
|
19
|
+
"browser": "./dist/lib/browser/state/index.mjs",
|
20
|
+
"node": {
|
21
|
+
"require": "./dist/lib/node/state/index.cjs",
|
22
|
+
"default": "./dist/lib/node-esm/state/index.mjs"
|
23
|
+
},
|
24
|
+
"types": "./dist/types/src/state/index.d.ts"
|
13
25
|
}
|
14
26
|
},
|
15
27
|
"types": "dist/types/src/index.d.ts",
|
@@ -21,24 +33,24 @@
|
|
21
33
|
"src"
|
22
34
|
],
|
23
35
|
"dependencies": {
|
24
|
-
"@codemirror/autocomplete": "^6.18.
|
25
|
-
"@codemirror/commands": "^6.6.
|
36
|
+
"@codemirror/autocomplete": "^6.18.1",
|
37
|
+
"@codemirror/commands": "^6.6.2",
|
26
38
|
"@codemirror/lang-javascript": "^6.2.2",
|
27
|
-
"@codemirror/lang-markdown": "^6.
|
28
|
-
"@codemirror/language": "^6.10.
|
39
|
+
"@codemirror/lang-markdown": "^6.3.0",
|
40
|
+
"@codemirror/language": "^6.10.3",
|
29
41
|
"@codemirror/language-data": "^6.5.1",
|
30
|
-
"@codemirror/lint": "^6.8.
|
42
|
+
"@codemirror/lint": "^6.8.2",
|
31
43
|
"@codemirror/search": "^6.5.6",
|
32
44
|
"@codemirror/state": "^6.4.1",
|
33
45
|
"@codemirror/theme-one-dark": "^6.1.2",
|
34
|
-
"@codemirror/view": "^6.
|
46
|
+
"@codemirror/view": "^6.34.1",
|
35
47
|
"@fluentui/react-tabster": "^9.19.0",
|
36
|
-
"@lezer/common": "^1.2.
|
48
|
+
"@lezer/common": "^1.2.2",
|
37
49
|
"@lezer/generator": "^1.7.1",
|
38
|
-
"@lezer/highlight": "^1.2.
|
39
|
-
"@lezer/markdown": "^1.3.
|
50
|
+
"@lezer/highlight": "^1.2.1",
|
51
|
+
"@lezer/markdown": "^1.3.1",
|
40
52
|
"@radix-ui/react-context": "^1.0.0",
|
41
|
-
"@replit/codemirror-vim": "^6.
|
53
|
+
"@replit/codemirror-vim": "^6.2.1",
|
42
54
|
"@replit/codemirror-vscode-keymap": "^6.0.2",
|
43
55
|
"codemirror": "^6.0.1",
|
44
56
|
"lib0": "^0.2.65",
|
@@ -48,19 +60,19 @@
|
|
48
60
|
"lodash.sortby": "^4.7.0",
|
49
61
|
"react-dropzone": "^14.2.3",
|
50
62
|
"style-mod": "^4.1.0",
|
51
|
-
"@dxos/async": "0.6.12-
|
52
|
-
"@dxos/automerge": "0.6.12-
|
53
|
-
"@dxos/
|
54
|
-
"@dxos/
|
55
|
-
"@dxos/display-name": "0.6.12-
|
56
|
-
"@dxos/
|
57
|
-
"@dxos/
|
58
|
-
"@dxos/
|
59
|
-
"@dxos/protocols": "0.6.12-
|
60
|
-
"@dxos/react-
|
61
|
-
"@dxos/react-
|
62
|
-
"@dxos/react-ui-theme": "0.6.12-
|
63
|
-
"@dxos/util": "0.6.12-
|
63
|
+
"@dxos/async": "0.6.12-staging.e11e696",
|
64
|
+
"@dxos/automerge": "0.6.12-staging.e11e696",
|
65
|
+
"@dxos/debug": "0.6.12-staging.e11e696",
|
66
|
+
"@dxos/context": "0.6.12-staging.e11e696",
|
67
|
+
"@dxos/display-name": "0.6.12-staging.e11e696",
|
68
|
+
"@dxos/invariant": "0.6.12-staging.e11e696",
|
69
|
+
"@dxos/echo-schema": "0.6.12-staging.e11e696",
|
70
|
+
"@dxos/log": "0.6.12-staging.e11e696",
|
71
|
+
"@dxos/protocols": "0.6.12-staging.e11e696",
|
72
|
+
"@dxos/react-hooks": "0.6.12-staging.e11e696",
|
73
|
+
"@dxos/react-ui": "0.6.12-staging.e11e696",
|
74
|
+
"@dxos/react-ui-theme": "0.6.12-staging.e11e696",
|
75
|
+
"@dxos/util": "0.6.12-staging.e11e696"
|
64
76
|
},
|
65
77
|
"devDependencies": {
|
66
78
|
"@phosphor-icons/react": "^2.1.5",
|
@@ -88,20 +100,20 @@
|
|
88
100
|
"vite": "5.4.7",
|
89
101
|
"vite-plugin-top-level-await": "^1.4.1",
|
90
102
|
"vite-plugin-wasm": "^3.3.0",
|
91
|
-
"@dxos/automerge": "0.6.12-
|
92
|
-
"@dxos/config": "0.6.12-
|
93
|
-
"@dxos/
|
94
|
-
"@dxos/
|
95
|
-
"@dxos/
|
96
|
-
"@dxos/react-client": "0.6.12-
|
97
|
-
"@dxos/
|
98
|
-
"@dxos/
|
103
|
+
"@dxos/automerge": "0.6.12-staging.e11e696",
|
104
|
+
"@dxos/config": "0.6.12-staging.e11e696",
|
105
|
+
"@dxos/keyboard": "0.6.12-staging.e11e696",
|
106
|
+
"@dxos/random": "0.6.12-staging.e11e696",
|
107
|
+
"@dxos/echo-signals": "0.6.12-staging.e11e696",
|
108
|
+
"@dxos/react-client": "0.6.12-staging.e11e696",
|
109
|
+
"@dxos/storybook-utils": "0.6.12-staging.e11e696",
|
110
|
+
"@dxos/react-ui": "0.6.12-staging.e11e696"
|
99
111
|
},
|
100
112
|
"peerDependencies": {
|
101
113
|
"@phosphor-icons/react": "^2.1.5",
|
102
114
|
"react": "~18.2.0",
|
103
115
|
"react-dom": "~18.2.0",
|
104
|
-
"@dxos/react-client": "0.6.12-
|
116
|
+
"@dxos/react-client": "0.6.12-staging.e11e696"
|
105
117
|
},
|
106
118
|
"publishConfig": {
|
107
119
|
"access": "public"
|
@@ -47,18 +47,16 @@ import {
|
|
47
47
|
linkTooltip,
|
48
48
|
listener,
|
49
49
|
mention,
|
50
|
-
state,
|
51
50
|
table,
|
52
51
|
typewriter,
|
53
52
|
type CommandAction,
|
54
|
-
type Comment,
|
55
53
|
type CommentsOptions,
|
56
|
-
type EditorSelectionState,
|
57
54
|
debugTree,
|
58
55
|
type DebugNode,
|
59
56
|
} from './extensions';
|
60
57
|
import { renderRoot } from './extensions/util';
|
61
58
|
import { useTextEditor, type UseTextEditorProps } from './hooks';
|
59
|
+
import { type Comment, type EditorSelectionState, state } from './state';
|
62
60
|
import translations from './translations';
|
63
61
|
|
64
62
|
faker.seed(101);
|
@@ -165,8 +163,8 @@ const content = {
|
|
165
163
|
'> This is a long wrapping block quote. Neque reiciendis ullam quae error labore sit, at, et, nulla, aut at nostrum omnis quas nostrum, at consectetur vitae eos asperiores non omnis ullam in beatae at vitae deserunt asperiores sapiente.',
|
166
164
|
'',
|
167
165
|
'> This is ...',
|
168
|
-
'
|
169
|
-
'
|
166
|
+
'... a multi-line ...',
|
167
|
+
'block quote.',
|
170
168
|
'',
|
171
169
|
),
|
172
170
|
|
@@ -453,6 +451,12 @@ export const ScrollTo = {
|
|
453
451
|
// Markdown
|
454
452
|
//
|
455
453
|
|
454
|
+
export const Blockquote = {
|
455
|
+
render: () => (
|
456
|
+
<Story text={str('> Blockquote', 'continuation', content.footer)} extensions={decorateMarkdown()} debug='raw' />
|
457
|
+
),
|
458
|
+
};
|
459
|
+
|
456
460
|
export const Headings = {
|
457
461
|
render: () => <Story text={headings} extensions={decorateMarkdown({ numberedHeadings: { from: 2, to: 4 } })} />,
|
458
462
|
};
|
@@ -2,10 +2,6 @@
|
|
2
2
|
// Copyright 2023 DXOS.org
|
3
3
|
//
|
4
4
|
|
5
|
-
// https://codemirror.net/examples/autocompletion
|
6
|
-
// https://codemirror.net/docs/ref/#autocomplete.autocompletion
|
7
|
-
// https://codemirror.net/docs/ref/#autocomplete.Completion
|
8
|
-
|
9
5
|
import {
|
10
6
|
autocompletion,
|
11
7
|
completionKeymap,
|
@@ -15,6 +11,7 @@ import {
|
|
15
11
|
type CompletionResult,
|
16
12
|
} from '@codemirror/autocomplete';
|
17
13
|
import { markdownLanguage } from '@codemirror/lang-markdown';
|
14
|
+
import { type Extension } from '@codemirror/state';
|
18
15
|
import { keymap } from '@codemirror/view';
|
19
16
|
|
20
17
|
export type AutocompleteResult = Completion;
|
@@ -25,11 +22,15 @@ export type AutocompleteOptions = {
|
|
25
22
|
onSearch?: (text: string) => Completion[];
|
26
23
|
};
|
27
24
|
|
25
|
+
// https://codemirror.net/examples/autocompletion
|
26
|
+
// https://codemirror.net/docs/ref/#autocomplete.autocompletion
|
27
|
+
// https://codemirror.net/docs/ref/#autocomplete.Completion
|
28
|
+
|
28
29
|
/**
|
29
30
|
* Autocomplete extension.
|
30
31
|
*/
|
31
|
-
export const autocomplete = ({ activateOnTyping, override, onSearch }: AutocompleteOptions = {}) => {
|
32
|
-
const
|
32
|
+
export const autocomplete = ({ activateOnTyping, override, onSearch }: AutocompleteOptions = {}): Extension => {
|
33
|
+
const extensions: Extension[] = [
|
33
34
|
// https://codemirror.net/docs/ref/#view.keymap
|
34
35
|
// https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
|
35
36
|
// TODO(burdon): Set custom keymap.
|
@@ -50,7 +51,7 @@ export const autocomplete = ({ activateOnTyping, override, onSearch }: Autocompl
|
|
50
51
|
];
|
51
52
|
|
52
53
|
if (onSearch) {
|
53
|
-
|
54
|
+
extensions.push(
|
54
55
|
// TODO(burdon): Optional decoration via addToOptions
|
55
56
|
markdownLanguage.data.of({
|
56
57
|
autocomplete: (context: CompletionContext): CompletionResult | null => {
|
@@ -68,5 +69,5 @@ export const autocomplete = ({ activateOnTyping, override, onSearch }: Autocompl
|
|
68
69
|
);
|
69
70
|
}
|
70
71
|
|
71
|
-
return
|
72
|
+
return extensions;
|
72
73
|
};
|
@@ -13,7 +13,7 @@ import { type DocAccessor } from '@dxos/react-client/echo';
|
|
13
13
|
import { cursorConverter } from './cursor';
|
14
14
|
import { updateHeadsEffect, isReconcile, type State } from './defs';
|
15
15
|
import { Syncer } from './sync';
|
16
|
-
import { Cursor } from '
|
16
|
+
import { Cursor } from '../../state';
|
17
17
|
|
18
18
|
export const automerge = (accessor: DocAccessor): Extension => {
|
19
19
|
const syncState = StateField.define<State>({
|
@@ -5,7 +5,7 @@
|
|
5
5
|
import { log } from '@dxos/log';
|
6
6
|
import { type DocAccessor, fromCursor, toCursor } from '@dxos/react-client/echo';
|
7
7
|
|
8
|
-
import { type CursorConverter } from '
|
8
|
+
import { type CursorConverter } from '../../state';
|
9
9
|
|
10
10
|
export const cursorConverter = (accessor: DocAccessor): CursorConverter => ({
|
11
11
|
toCursor: (pos, assoc) => {
|
@@ -2,7 +2,7 @@
|
|
2
2
|
// Copyright 2024 DXOS.org
|
3
3
|
//
|
4
4
|
|
5
|
-
import { Annotation,
|
5
|
+
import { Annotation, type Extension, RangeSet, type Range } from '@codemirror/state';
|
6
6
|
import {
|
7
7
|
Decoration,
|
8
8
|
type DecorationSet,
|
@@ -16,7 +16,7 @@ import {
|
|
16
16
|
import { Event } from '@dxos/async';
|
17
17
|
import { Context } from '@dxos/context';
|
18
18
|
|
19
|
-
import { Cursor, type CursorConverter } from '
|
19
|
+
import { singleValueFacet, Cursor, type CursorConverter } from '../../state';
|
20
20
|
|
21
21
|
export interface AwarenessProvider {
|
22
22
|
remoteStateChange: Event<void>;
|
@@ -38,9 +38,7 @@ const dummyProvider: AwarenessProvider = {
|
|
38
38
|
update: () => {},
|
39
39
|
};
|
40
40
|
|
41
|
-
export const awarenessProvider =
|
42
|
-
combine: (providers) => providers[0] ?? dummyProvider,
|
43
|
-
});
|
41
|
+
export const awarenessProvider = singleValueFacet<AwarenessProvider>(dummyProvider);
|
44
42
|
|
45
43
|
// TODO(dmaretskyi): Specify the users that actually changed. Currently, we recalculate positions for every user.
|
46
44
|
const RemoteSelectionChangedAnnotation = Annotation.define();
|
@@ -2,7 +2,7 @@
|
|
2
2
|
// Copyright 2024 DXOS.org
|
3
3
|
//
|
4
4
|
|
5
|
-
import {
|
5
|
+
import { StateEffect, StateField } from '@codemirror/state';
|
6
6
|
import {
|
7
7
|
type Command,
|
8
8
|
type EditorView,
|
@@ -13,14 +13,13 @@ import {
|
|
13
13
|
} from '@codemirror/view';
|
14
14
|
|
15
15
|
import { type CommandOptions } from './command';
|
16
|
+
import { singleValueFacet } from '../../state';
|
16
17
|
|
17
18
|
type CommandState = {
|
18
19
|
tooltip?: Tooltip | null;
|
19
20
|
};
|
20
21
|
|
21
|
-
export const commandConfig =
|
22
|
-
combine: (providers) => providers[0],
|
23
|
-
});
|
22
|
+
export const commandConfig = singleValueFacet<CommandOptions>();
|
24
23
|
|
25
24
|
export const commandState = StateField.define<CommandState>({
|
26
25
|
create: () => ({}),
|
@@ -5,7 +5,6 @@
|
|
5
5
|
import { invertedEffects } from '@codemirror/commands';
|
6
6
|
import {
|
7
7
|
type Extension,
|
8
|
-
Facet,
|
9
8
|
StateEffect,
|
10
9
|
StateField,
|
11
10
|
type Text,
|
@@ -29,18 +28,15 @@ import { debounce, type UnsubscribeCallback } from '@dxos/async';
|
|
29
28
|
import { log } from '@dxos/log';
|
30
29
|
import { nonNullable } from '@dxos/util';
|
31
30
|
|
32
|
-
import { Cursor } from './cursor';
|
33
|
-
import { type Comment, type Range } from './types';
|
34
31
|
import { overlap } from './util';
|
32
|
+
import { Cursor, documentId, singleValueFacet } from '../state';
|
33
|
+
import { type Comment, type Range } from '../state';
|
35
34
|
import { callbackWrapper } from '../util';
|
36
35
|
|
37
36
|
//
|
38
37
|
// State management.
|
39
38
|
//
|
40
39
|
|
41
|
-
// TODO(wittjosiah): Factor out, not comments-specific.
|
42
|
-
const documentId = Facet.define<string | undefined, string | undefined>({ combine: (values) => values[0] });
|
43
|
-
|
44
40
|
type CommentState = {
|
45
41
|
comment: Comment;
|
46
42
|
range: Range;
|
@@ -369,7 +365,7 @@ export type CommentsOptions = {
|
|
369
365
|
onHover?: (el: Element, shortcut: string) => void;
|
370
366
|
};
|
371
367
|
|
372
|
-
const optionsFacet =
|
368
|
+
const optionsFacet = singleValueFacet<CommentsOptions>();
|
373
369
|
|
374
370
|
/**
|
375
371
|
* Comment threads.
|
@@ -389,7 +385,7 @@ export const comments = (options: CommentsOptions = {}): Extension => {
|
|
389
385
|
|
390
386
|
return [
|
391
387
|
optionsFacet.of(options),
|
392
|
-
documentId.of(options.id),
|
388
|
+
options.id ? documentId.of(options.id) : undefined,
|
393
389
|
commentsState,
|
394
390
|
commentsDecorations,
|
395
391
|
handleCommentClick,
|
@@ -398,45 +394,43 @@ export const comments = (options: CommentsOptions = {}): Extension => {
|
|
398
394
|
//
|
399
395
|
// Keymap.
|
400
396
|
//
|
401
|
-
options.onCreate
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
: [],
|
397
|
+
options.onCreate &&
|
398
|
+
keymap.of([
|
399
|
+
{
|
400
|
+
key: shortcut,
|
401
|
+
run: callbackWrapper(createComment),
|
402
|
+
},
|
403
|
+
]),
|
409
404
|
|
410
405
|
//
|
411
406
|
// Hover tooltip (for key shortcut hints, etc.)
|
412
407
|
// TODO(burdon): Factor out to generic hints extension for current selection/line.
|
413
408
|
//
|
414
|
-
options.onHover
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
409
|
+
options.onHover &&
|
410
|
+
hoverTooltip(
|
411
|
+
(view, pos) => {
|
412
|
+
const selection = view.state.selection.main;
|
413
|
+
if (selection && pos >= selection.from && pos <= selection.to) {
|
414
|
+
return {
|
415
|
+
pos: selection.from,
|
416
|
+
end: selection.to,
|
417
|
+
above: true,
|
418
|
+
create: () => {
|
419
|
+
const el = document.createElement('div');
|
420
|
+
options.onHover!(el, shortcut);
|
421
|
+
return { dom: el, offset: { x: 0, y: 8 } };
|
422
|
+
},
|
423
|
+
};
|
424
|
+
}
|
430
425
|
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
: [],
|
426
|
+
return null;
|
427
|
+
},
|
428
|
+
{
|
429
|
+
// TODO(burdon): Hide on change triggered immediately?
|
430
|
+
// hideOnChange: true,
|
431
|
+
hoverTime: 1_000,
|
432
|
+
},
|
433
|
+
),
|
440
434
|
|
441
435
|
//
|
442
436
|
// Track deleted ranges and update ranges for decorations.
|
@@ -511,8 +505,8 @@ export const comments = (options: CommentsOptions = {}): Extension => {
|
|
511
505
|
}
|
512
506
|
}),
|
513
507
|
|
514
|
-
options.onUpdate
|
515
|
-
];
|
508
|
+
options.onUpdate && trackPastedComments(options.onUpdate),
|
509
|
+
].filter(nonNullable);
|
516
510
|
};
|
517
511
|
|
518
512
|
//
|
package/src/extensions/debug.ts
CHANGED
@@ -3,10 +3,10 @@
|
|
3
3
|
//
|
4
4
|
|
5
5
|
import { syntaxTree } from '@codemirror/language';
|
6
|
-
import { type EditorState, type RangeSet, StateField, type Transaction } from '@codemirror/state';
|
6
|
+
import { type EditorState, type Extension, type RangeSet, StateField, type Transaction } from '@codemirror/state';
|
7
7
|
|
8
8
|
// eslint-disable-next-line no-console
|
9
|
-
export const debugNodeLogger = (log: (...args: any[]) => void = console.log) => {
|
9
|
+
export const debugNodeLogger = (log: (...args: any[]) => void = console.log): Extension => {
|
10
10
|
const logTokens = (state: EditorState) => syntaxTree(state).iterate({ enter: (node) => log(node.type) });
|
11
11
|
return StateField.define<any>({
|
12
12
|
create: (state) => logTokens(state),
|
@@ -17,7 +17,7 @@ export type FoldingOptions = {};
|
|
17
17
|
/**
|
18
18
|
* https://codemirror.net/examples/gutter
|
19
19
|
*/
|
20
|
-
// TODO(burdon): Remember folding state.
|
20
|
+
// TODO(burdon): Remember folding state (to state).
|
21
21
|
export const folding = (_props: FoldingOptions = {}): Extension => [
|
22
22
|
codeFolding({
|
23
23
|
placeholderDOM: () => {
|
@@ -26,8 +26,10 @@ export const folding = (_props: FoldingOptions = {}): Extension => [
|
|
26
26
|
}),
|
27
27
|
foldGutter({
|
28
28
|
markerDOM: (open) => {
|
29
|
+
// TODO(burdon): Use sprite directly.
|
30
|
+
const el = createElement('div', { className: 'flex h-full items-center' });
|
29
31
|
return renderRoot(
|
30
|
-
|
32
|
+
el,
|
31
33
|
<Icon icon='ph--caret-right--regular' classNames={[getSize(3), 'mx-3 cursor-pointer', open && 'rotate-90']} />,
|
32
34
|
);
|
33
35
|
},
|
package/src/extensions/index.ts
CHANGED
@@ -9,9 +9,7 @@ export * from './awareness';
|
|
9
9
|
export * from './blast';
|
10
10
|
export * from './command';
|
11
11
|
export * from './comments';
|
12
|
-
export * from './cursor';
|
13
12
|
export * from './debug';
|
14
|
-
export * from './doc';
|
15
13
|
export * from './dnd';
|
16
14
|
export * from './factories';
|
17
15
|
export * from './folding';
|
@@ -19,6 +17,4 @@ export * from './listener';
|
|
19
17
|
export * from './markdown';
|
20
18
|
export * from './mention';
|
21
19
|
export * from './modes';
|
22
|
-
export * from './state';
|
23
|
-
export * from './types';
|
24
20
|
export * from './typewriter';
|
@@ -45,7 +45,7 @@ class HorizontalRuleWidget extends WidgetType {
|
|
45
45
|
class LinkButton extends WidgetType {
|
46
46
|
constructor(
|
47
47
|
private readonly url: string,
|
48
|
-
private readonly render: (el:
|
48
|
+
private readonly render: (el: HTMLElement, url: string) => void,
|
49
49
|
) {
|
50
50
|
super();
|
51
51
|
}
|
@@ -54,6 +54,7 @@ class LinkButton extends WidgetType {
|
|
54
54
|
return this.url === other.url;
|
55
55
|
}
|
56
56
|
|
57
|
+
// TODO(burdon): Create icon and link directly without react?
|
57
58
|
override toDOM(view: EditorView) {
|
58
59
|
const el = document.createElement('span');
|
59
60
|
this.render(el, this.url);
|
@@ -127,6 +128,7 @@ class TextWidget extends WidgetType {
|
|
127
128
|
}
|
128
129
|
|
129
130
|
const hide = Decoration.replace({});
|
131
|
+
const blockQuote = Decoration.line({ class: mx('cm-blockquote') });
|
130
132
|
const fencedCodeLine = Decoration.line({ class: mx('cm-code cm-codeblock-line') });
|
131
133
|
const fencedCodeLineFirst = Decoration.line({ class: mx('cm-code cm-codeblock-line', 'cm-codeblock-first') });
|
132
134
|
const fencedCodeLineLast = Decoration.line({ class: mx('cm-code cm-codeblock-line', 'cm-codeblock-last') });
|
@@ -199,7 +201,7 @@ const buildDecorations = (view: EditorView, options: DecorateOptions, focus: boo
|
|
199
201
|
return listLevels[listLevels.length - 1];
|
200
202
|
};
|
201
203
|
|
202
|
-
//
|
204
|
+
// let count = 0;
|
203
205
|
const enterNode = (node: SyntaxNodeRef) => {
|
204
206
|
// console.log(`[${count++}]`, { node: node.name, from: node.from, to: node.to });
|
205
207
|
switch (node.name) {
|
@@ -329,7 +331,36 @@ const buildDecorations = (view: EditorView, options: DecorateOptions, focus: boo
|
|
329
331
|
break;
|
330
332
|
}
|
331
333
|
|
334
|
+
//
|
335
|
+
// Blockquote > QuoteMark > Paragraph
|
336
|
+
//
|
337
|
+
|
338
|
+
case 'Blockquote': {
|
339
|
+
const editing = editingRange(state, node, focus);
|
340
|
+
const quoteMark = node.node.getChild('QuoteMark');
|
341
|
+
const paragraph = node.node.getChild('Paragraph');
|
342
|
+
if (!editing && quoteMark && paragraph) {
|
343
|
+
atomicDeco.add(quoteMark.from, paragraph.from, hide);
|
344
|
+
}
|
345
|
+
|
346
|
+
for (const block of view.viewportLineBlocks) {
|
347
|
+
if (block.to < node.from) {
|
348
|
+
continue;
|
349
|
+
}
|
350
|
+
if (block.from > node.to) {
|
351
|
+
break;
|
352
|
+
}
|
353
|
+
|
354
|
+
deco.add(block.from, block.from, blockQuote);
|
355
|
+
}
|
356
|
+
|
357
|
+
break;
|
358
|
+
}
|
359
|
+
|
360
|
+
//
|
332
361
|
// CommentBlock
|
362
|
+
//
|
363
|
+
|
333
364
|
case 'CommentBlock': {
|
334
365
|
const editing = editingRange(state, node, focus);
|
335
366
|
for (const block of view.viewportLineBlocks) {
|
@@ -339,21 +370,27 @@ const buildDecorations = (view: EditorView, options: DecorateOptions, focus: boo
|
|
339
370
|
if (block.from > node.to) {
|
340
371
|
break;
|
341
372
|
}
|
342
|
-
|
343
|
-
const
|
373
|
+
|
374
|
+
const isFirst = block.from <= node.from;
|
375
|
+
const isLast = block.to >= node.to && /^(\s>)*-->$/.test(state.doc.sliceString(block.from, block.to));
|
376
|
+
|
344
377
|
deco.add(
|
345
378
|
block.from,
|
346
379
|
block.from,
|
347
|
-
|
380
|
+
isFirst ? commentBlockLineFirst : isLast ? commentBlockLineLast : commentBlockLine,
|
348
381
|
);
|
349
|
-
|
382
|
+
|
383
|
+
if (!editing && (isFirst || isLast)) {
|
350
384
|
atomicDeco.add(block.from, block.to, hide);
|
351
385
|
}
|
352
386
|
}
|
353
387
|
break;
|
354
388
|
}
|
355
389
|
|
390
|
+
//
|
356
391
|
// FencedCode > CodeMark > [CodeInfo] > CodeText > CodeMark
|
392
|
+
//
|
393
|
+
|
357
394
|
case 'FencedCode': {
|
358
395
|
for (const block of view.viewportLineBlocks) {
|
359
396
|
if (block.to < node.from) {
|
@@ -375,7 +412,10 @@ const buildDecorations = (view: EditorView, options: DecorateOptions, focus: boo
|
|
375
412
|
return false;
|
376
413
|
}
|
377
414
|
|
415
|
+
//
|
378
416
|
// Link > [LinkMark, URL]
|
417
|
+
//
|
418
|
+
|
379
419
|
case 'Link': {
|
380
420
|
const marks = node.node.getChildren('LinkMark');
|
381
421
|
const urlNode = node.node.getChild('URL');
|
@@ -412,7 +452,10 @@ const buildDecorations = (view: EditorView, options: DecorateOptions, focus: boo
|
|
412
452
|
break;
|
413
453
|
}
|
414
454
|
|
455
|
+
//
|
415
456
|
// HR
|
457
|
+
//
|
458
|
+
|
416
459
|
case 'HorizontalRule': {
|
417
460
|
if (!editingRange(state, node, focus)) {
|
418
461
|
deco.add(node.from, node.to, horizontalRule);
|
@@ -168,11 +168,6 @@ export const markdownHighlightStyle = (_options: HighlightOptions = {}) => {
|
|
168
168
|
class: theme.code,
|
169
169
|
},
|
170
170
|
|
171
|
-
{
|
172
|
-
tag: [markdownTags.QuoteMark],
|
173
|
-
class: theme.blockquote,
|
174
|
-
},
|
175
|
-
|
176
171
|
{
|
177
172
|
tag: [markdownTags.TableCell],
|
178
173
|
class: 'font-mono',
|
@@ -9,8 +9,8 @@ import { type SyntaxNode } from '@lezer/common';
|
|
9
9
|
|
10
10
|
import { tooltipContent } from '@dxos/react-ui-theme';
|
11
11
|
|
12
|
-
export const linkTooltip = (render: (el:
|
13
|
-
hoverTooltip((view, pos, side) => {
|
12
|
+
export const linkTooltip = (render: (el: HTMLElement, url: string) => void) => {
|
13
|
+
return hoverTooltip((view, pos, side) => {
|
14
14
|
const syntax = syntaxTree(view.state).resolveInner(pos, side);
|
15
15
|
let link = null;
|
16
16
|
for (let i = 0, node: SyntaxNode | null = syntax; !link && node && i < 5; node = node.parent, i++) {
|
@@ -35,3 +35,4 @@ export const linkTooltip = (render: (el: Element, url: string) => void) =>
|
|
35
35
|
},
|
36
36
|
};
|
37
37
|
});
|
38
|
+
};
|