@dxos/ui-editor 0.0.0 → 0.8.4-main.05e74ebcff
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/LICENSE +102 -5
- package/README.md +1 -1
- package/dist/lib/browser/index.mjs +8657 -0
- package/dist/lib/browser/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -0
- package/dist/lib/browser/types/index.mjs +33 -0
- package/dist/lib/browser/types/index.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +8659 -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/types/index.mjs +35 -0
- package/dist/lib/node-esm/types/index.mjs.map +7 -0
- package/dist/types/src/defaults.d.ts +6 -0
- package/dist/types/src/defaults.d.ts.map +1 -0
- package/dist/types/src/extensions/annotations.d.ts +9 -0
- package/dist/types/src/extensions/annotations.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/autocomplete.d.ts +17 -0
- package/dist/types/src/extensions/autocomplete/autocomplete.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/index.d.ts +5 -0
- package/dist/types/src/extensions/autocomplete/index.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/match.d.ts +13 -0
- package/dist/types/src/extensions/autocomplete/match.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts +23 -0
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts +10 -0
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/automerge.d.ts +4 -0
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/automerge.test.d.ts +2 -0
- package/dist/types/src/extensions/automerge/automerge.test.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/cursor.d.ts +4 -0
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/defs.d.ts +17 -0
- package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/index.d.ts +2 -0
- package/dist/types/src/extensions/automerge/index.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/sync.d.ts +17 -0
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/update-automerge.d.ts +6 -0
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts +5 -0
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +1 -0
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts +31 -0
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -0
- package/dist/types/src/extensions/awareness/awareness.d.ts +46 -0
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -0
- package/dist/types/src/extensions/awareness/index.d.ts +3 -0
- package/dist/types/src/extensions/awareness/index.d.ts.map +1 -0
- package/dist/types/src/extensions/blast.d.ts +25 -0
- package/dist/types/src/extensions/blast.d.ts.map +1 -0
- package/dist/types/src/extensions/blocks.d.ts +2 -0
- package/dist/types/src/extensions/blocks.d.ts.map +1 -0
- package/dist/types/src/extensions/bookmarks.d.ts +12 -0
- package/dist/types/src/extensions/bookmarks.d.ts.map +1 -0
- package/dist/types/src/extensions/comments.d.ts +90 -0
- package/dist/types/src/extensions/comments.d.ts.map +1 -0
- package/dist/types/src/extensions/debug.d.ts +3 -0
- package/dist/types/src/extensions/debug.d.ts.map +1 -0
- package/dist/types/src/extensions/dnd.d.ts +9 -0
- package/dist/types/src/extensions/dnd.d.ts.map +1 -0
- package/dist/types/src/extensions/factories.d.ts +88 -0
- package/dist/types/src/extensions/factories.d.ts.map +1 -0
- package/dist/types/src/extensions/factories.test.d.ts +2 -0
- package/dist/types/src/extensions/factories.test.d.ts.map +1 -0
- package/dist/types/src/extensions/focus.d.ts +7 -0
- package/dist/types/src/extensions/focus.d.ts.map +1 -0
- package/dist/types/src/extensions/folding.d.ts +6 -0
- package/dist/types/src/extensions/folding.d.ts.map +1 -0
- package/dist/types/src/extensions/hashtag.d.ts +3 -0
- package/dist/types/src/extensions/hashtag.d.ts.map +1 -0
- package/dist/types/src/extensions/index.d.ts +30 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -0
- package/dist/types/src/extensions/json.d.ts +7 -0
- package/dist/types/src/extensions/json.d.ts.map +1 -0
- package/dist/types/src/extensions/listener.d.ts +13 -0
- package/dist/types/src/extensions/listener.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/action.d.ts +12 -0
- package/dist/types/src/extensions/markdown/action.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/bundle.d.ts +25 -0
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/changes.d.ts +10 -0
- package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/changes.test.d.ts +2 -0
- package/dist/types/src/extensions/markdown/changes.test.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/debug.d.ts +11 -0
- package/dist/types/src/extensions/markdown/debug.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/decorate.d.ts +25 -0
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts +63 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/formatting.test.d.ts +3 -0
- package/dist/types/src/extensions/markdown/formatting.test.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/highlight.d.ts +37 -0
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/image.d.ts +7 -0
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/index.d.ts +10 -0
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/link.d.ts +7 -0
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/parser.test.d.ts +2 -0
- package/dist/types/src/extensions/markdown/parser.test.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/styles.d.ts +4 -0
- package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/table.d.ts +8 -0
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -0
- package/dist/types/src/extensions/mention.d.ts +7 -0
- package/dist/types/src/extensions/mention.d.ts.map +1 -0
- package/dist/types/src/extensions/modal.d.ts +7 -0
- package/dist/types/src/extensions/modal.d.ts.map +1 -0
- package/dist/types/src/extensions/modes.d.ts +10 -0
- package/dist/types/src/extensions/modes.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/commands.d.ts +10 -0
- package/dist/types/src/extensions/outliner/commands.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/editor.d.ts +5 -0
- package/dist/types/src/extensions/outliner/editor.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/editor.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/editor.test.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/index.d.ts +4 -0
- package/dist/types/src/extensions/outliner/index.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/menu.d.ts +8 -0
- package/dist/types/src/extensions/outliner/menu.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/outliner.d.ts +11 -0
- package/dist/types/src/extensions/outliner/outliner.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/outliner.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/outliner.test.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/selection.d.ts +12 -0
- package/dist/types/src/extensions/outliner/selection.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/tree.d.ts +79 -0
- package/dist/types/src/extensions/outliner/tree.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/tree.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/tree.test.d.ts.map +1 -0
- package/dist/types/src/extensions/preview/index.d.ts +2 -0
- package/dist/types/src/extensions/preview/index.d.ts.map +1 -0
- package/dist/types/src/extensions/preview/preview.d.ts +34 -0
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -0
- package/dist/types/src/extensions/replacer.d.ts +21 -0
- package/dist/types/src/extensions/replacer.d.ts.map +1 -0
- package/dist/types/src/extensions/replacer.test.d.ts +2 -0
- package/dist/types/src/extensions/replacer.test.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/auto-scroll.d.ts +18 -0
- package/dist/types/src/extensions/scrolling/auto-scroll.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/crawler.d.ts +75 -0
- package/dist/types/src/extensions/scrolling/crawler.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/index.d.ts +5 -0
- package/dist/types/src/extensions/scrolling/index.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/scroll-past-end.d.ts +3 -0
- package/dist/types/src/extensions/scrolling/scroll-past-end.d.ts.map +1 -0
- package/dist/types/src/extensions/scrolling/scroller.d.ts +16 -0
- package/dist/types/src/extensions/scrolling/scroller.d.ts.map +1 -0
- package/dist/types/src/extensions/selection.d.ts +24 -0
- package/dist/types/src/extensions/selection.d.ts.map +1 -0
- package/dist/types/src/extensions/snippets.d.ts +10 -0
- package/dist/types/src/extensions/snippets.d.ts.map +1 -0
- package/dist/types/src/extensions/state.d.ts +2 -0
- package/dist/types/src/extensions/state.d.ts.map +1 -0
- package/dist/types/src/extensions/submit.d.ts +10 -0
- package/dist/types/src/extensions/submit.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/extended-markdown.d.ts +10 -0
- package/dist/types/src/extensions/tags/extended-markdown.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/extended-markdown.test.d.ts +2 -0
- package/dist/types/src/extensions/tags/extended-markdown.test.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/fader.d.ts +12 -0
- package/dist/types/src/extensions/tags/fader.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/index.d.ts +7 -0
- package/dist/types/src/extensions/tags/index.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/typewriter.d.ts +43 -0
- package/dist/types/src/extensions/tags/typewriter.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/typewriter.test.d.ts +2 -0
- package/dist/types/src/extensions/tags/typewriter.test.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts +31 -0
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-formatting.d.ts +24 -0
- package/dist/types/src/extensions/tags/xml-formatting.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-tags.d.ts +117 -0
- package/dist/types/src/extensions/tags/xml-tags.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-util.d.ts +10 -0
- package/dist/types/src/extensions/tags/xml-util.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-util.test.d.ts +2 -0
- package/dist/types/src/extensions/tags/xml-util.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +8 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/styles/index.d.ts +2 -0
- package/dist/types/src/styles/index.d.ts.map +1 -0
- package/dist/types/src/styles/theme.d.ts +58 -0
- package/dist/types/src/styles/theme.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +2 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/src/types/types.d.ts +21 -0
- package/dist/types/src/types/types.d.ts.map +1 -0
- package/dist/types/src/util/cursor.d.ts +31 -0
- package/dist/types/src/util/cursor.d.ts.map +1 -0
- package/dist/types/src/util/debug.d.ts +17 -0
- package/dist/types/src/util/debug.d.ts.map +1 -0
- package/dist/types/src/util/decorations.d.ts +4 -0
- package/dist/types/src/util/decorations.d.ts.map +1 -0
- package/dist/types/src/util/dom.d.ts +10 -0
- package/dist/types/src/util/dom.d.ts.map +1 -0
- package/dist/types/src/util/facet.d.ts +3 -0
- package/dist/types/src/util/facet.d.ts.map +1 -0
- package/dist/types/src/util/index.d.ts +7 -0
- package/dist/types/src/util/index.d.ts.map +1 -0
- package/dist/types/src/util/util.d.ts +8 -0
- package/dist/types/src/util/util.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +43 -44
- package/src/defaults.ts +33 -20
- package/src/extensions/annotations.ts +1 -1
- package/src/extensions/autocomplete/placeholder.ts +37 -18
- package/src/extensions/automerge/automerge.test.tsx +37 -11
- package/src/extensions/automerge/automerge.ts +5 -7
- package/src/extensions/blocks.ts +5 -5
- package/src/extensions/comments.ts +5 -6
- package/src/extensions/dnd.ts +2 -2
- package/src/extensions/factories.test.ts +88 -0
- package/src/extensions/factories.ts +32 -15
- package/src/extensions/folding.ts +5 -22
- package/src/extensions/index.ts +2 -3
- package/src/extensions/markdown/action.ts +0 -1
- package/src/extensions/markdown/bundle.ts +23 -9
- package/src/extensions/markdown/decorate.ts +15 -12
- package/src/extensions/markdown/formatting.ts +5 -10
- package/src/extensions/markdown/highlight.ts +15 -7
- package/src/extensions/markdown/link.ts +27 -33
- package/src/extensions/markdown/parser.test.ts +0 -1
- package/src/extensions/markdown/styles.ts +42 -9
- package/src/extensions/markdown/table.ts +24 -2
- package/src/extensions/outliner/outliner.test.ts +0 -1
- package/src/extensions/outliner/outliner.ts +3 -4
- package/src/extensions/outliner/tree.test.ts +0 -1
- package/src/extensions/preview/preview.ts +62 -15
- package/src/extensions/scrolling/auto-scroll.ts +244 -0
- package/src/extensions/scrolling/crawler.ts +263 -0
- package/src/extensions/scrolling/index.ts +8 -0
- package/src/extensions/scrolling/scroll-past-end.ts +32 -0
- package/src/extensions/scrolling/scroller.ts +27 -0
- package/src/extensions/selection.ts +1 -1
- package/src/extensions/snippets.ts +67 -0
- package/src/extensions/tags/extended-markdown.test.ts +120 -2
- package/src/extensions/tags/extended-markdown.ts +80 -1
- package/src/extensions/tags/fader.ts +195 -0
- package/src/extensions/tags/index.ts +4 -1
- package/src/extensions/tags/testing/text.md +36 -0
- package/src/extensions/tags/testing/text.txt +35 -0
- package/src/extensions/tags/typewriter.test.ts +65 -0
- package/src/extensions/tags/typewriter.ts +594 -0
- package/src/extensions/tags/xml-block-decoration.ts +123 -0
- package/src/extensions/tags/xml-formatting.ts +125 -0
- package/src/extensions/tags/xml-tags.ts +186 -35
- package/src/extensions/tags/xml-util.test.ts +199 -24
- package/src/extensions/tags/xml-util.ts +62 -5
- package/src/index.ts +0 -1
- package/src/styles/index.ts +0 -2
- package/src/styles/theme.ts +125 -33
- package/src/types/types.ts +10 -2
- package/src/typings.d.ts +8 -0
- package/src/util/cursor.ts +1 -2
- package/src/extensions/autoscroll.ts +0 -165
- package/src/extensions/scrolling.ts +0 -189
- package/src/extensions/tags/streamer.ts +0 -243
- package/src/extensions/typewriter.ts +0 -68
- package/src/styles/markdown.ts +0 -26
- package/src/styles/tokens.ts +0 -17
|
@@ -2,47 +2,222 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { syntaxTree } from '@codemirror/language';
|
|
5
|
+
import { ensureSyntaxTree, syntaxTree } from '@codemirror/language';
|
|
6
6
|
import { EditorState } from '@codemirror/state';
|
|
7
|
-
import { describe,
|
|
7
|
+
import { describe, test } from 'vitest';
|
|
8
8
|
|
|
9
|
-
import { Trigger } from '@dxos/async';
|
|
10
9
|
import { trim } from '@dxos/util';
|
|
11
10
|
|
|
12
11
|
import { extendedMarkdown } from './extended-markdown';
|
|
12
|
+
import TEXT from './testing/text.md?raw';
|
|
13
13
|
import { xmlTags } from './xml-tags';
|
|
14
|
-
import { nodeToJson } from './xml-util';
|
|
14
|
+
import { nodeToJson, type Tag } from './xml-util';
|
|
15
|
+
|
|
16
|
+
type ParsedElement = Tag & {
|
|
17
|
+
/** Element spans the entire document (opening through closing tag). */
|
|
18
|
+
complete: boolean;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Helper to extract all parsed XML elements from a document.
|
|
23
|
+
* Checks completeness by verifying the Element node has a CloseTag child.
|
|
24
|
+
*/
|
|
25
|
+
const parseElements = (doc: string, registry: Record<string, any> = {}): ParsedElement[] => {
|
|
26
|
+
const state = EditorState.create({
|
|
27
|
+
doc,
|
|
28
|
+
extensions: [extendedMarkdown({ registry }), xmlTags({ registry })],
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const tree = ensureSyntaxTree(state, doc.length, 5000) ?? syntaxTree(state);
|
|
32
|
+
const elements: ParsedElement[] = [];
|
|
33
|
+
tree.iterate({
|
|
34
|
+
enter: (node) => {
|
|
35
|
+
if (node.type.name === 'Element') {
|
|
36
|
+
const tag = nodeToJson(state, node.node);
|
|
37
|
+
if (tag) {
|
|
38
|
+
const hasCloseTag = !!node.node.getChild('CloseTag');
|
|
39
|
+
const hasSelfClose = !!node.node.getChild('SelfClosingTag');
|
|
40
|
+
elements.push({
|
|
41
|
+
...tag,
|
|
42
|
+
complete: hasCloseTag || hasSelfClose,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
return elements;
|
|
51
|
+
};
|
|
15
52
|
|
|
16
53
|
describe('nodeToJson', () => {
|
|
17
|
-
|
|
54
|
+
test('should parse a simple element', ({ expect }) => {
|
|
18
55
|
const xml = trim`
|
|
19
56
|
# Test
|
|
20
57
|
|
|
21
58
|
<test id="123" foo="100" />
|
|
22
59
|
`;
|
|
23
60
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
const value = new Trigger<any>();
|
|
30
|
-
syntaxTree(state).iterate({
|
|
31
|
-
enter: (node) => {
|
|
32
|
-
switch (node.type.name) {
|
|
33
|
-
case 'Element': {
|
|
34
|
-
const args = nodeToJson(state, node.node);
|
|
35
|
-
value.wake(args);
|
|
36
|
-
break;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
expect(await value.wait()).toEqual({
|
|
61
|
+
const elements = parseElements(xml);
|
|
62
|
+
expect(elements).toHaveLength(1);
|
|
63
|
+
expect(elements[0]).toMatchObject({
|
|
43
64
|
_tag: 'test',
|
|
44
65
|
id: '123',
|
|
45
66
|
foo: '100',
|
|
46
67
|
});
|
|
47
68
|
});
|
|
69
|
+
|
|
70
|
+
test('should parse tag with single-line content', ({ expect }) => {
|
|
71
|
+
const xml = trim`
|
|
72
|
+
<reasoning>The user is asking about markdown.</reasoning>
|
|
73
|
+
`;
|
|
74
|
+
|
|
75
|
+
const registry = { reasoning: { block: true } };
|
|
76
|
+
const elements = parseElements(xml, registry);
|
|
77
|
+
expect(elements).toHaveLength(1);
|
|
78
|
+
expect(elements[0]._tag).toBe('reasoning');
|
|
79
|
+
expect(elements[0].complete).toBe(true);
|
|
80
|
+
expect(elements[0].children).toEqual(['The user is asking about markdown.']);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('should parse tag with multi-line content without blank lines', ({ expect }) => {
|
|
84
|
+
const xml = trim`
|
|
85
|
+
<reasoning>
|
|
86
|
+
The user is asking about markdown.
|
|
87
|
+
This is a follow-up thought.
|
|
88
|
+
</reasoning>
|
|
89
|
+
`;
|
|
90
|
+
|
|
91
|
+
const registry = { reasoning: { block: true } };
|
|
92
|
+
const elements = parseElements(xml, registry);
|
|
93
|
+
expect(elements).toHaveLength(1);
|
|
94
|
+
expect(elements[0]._tag).toBe('reasoning');
|
|
95
|
+
expect(elements[0].complete).toBe(true);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// BUG: Blank lines inside XML tags cause the markdown parser to split the content
|
|
99
|
+
// into multiple blocks (HTMLBlock + Paragraph), preventing the XML mixed parser from
|
|
100
|
+
// seeing the full element. The first HTMLBlock gets an incomplete Element (no CloseTag),
|
|
101
|
+
// and the closing tag ends up in a Paragraph that's never parsed as XML.
|
|
102
|
+
//
|
|
103
|
+
// Syntax tree with blank lines:
|
|
104
|
+
// Document [0-28] → Element (incomplete: OpenTag + Text + ⚠ — no CloseTag)
|
|
105
|
+
// Paragraph [30-60] → "Second paragraph.\n</reasoning>"
|
|
106
|
+
|
|
107
|
+
test('should parse tag with blank lines in content', ({ expect }) => {
|
|
108
|
+
const xml = trim`
|
|
109
|
+
<reasoning>
|
|
110
|
+
The user is asking me to think deeply about what markdown is.
|
|
111
|
+
|
|
112
|
+
But given the context of our conversation - we've been trying to scrape slab data from a website - I think they might be hinting at something specific.
|
|
113
|
+
</reasoning>
|
|
114
|
+
`;
|
|
115
|
+
|
|
116
|
+
const registry = { reasoning: { block: true } };
|
|
117
|
+
const elements = parseElements(xml, registry);
|
|
118
|
+
expect(elements).toHaveLength(1);
|
|
119
|
+
expect(elements[0]._tag).toBe('reasoning');
|
|
120
|
+
expect(elements[0].complete).toBe(true);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Regression: when reasoning text contains escaped XML (e.g. `<foo>`), Lezer XML
|
|
124
|
+
// splits the inline content into Text + EntityReference + Text + EntityReference + Text
|
|
125
|
+
// siblings. The walker used to skip entity references and push each text segment as a
|
|
126
|
+
// separate child, so `getXmlTextChild(children)` only saw the prefix before the first
|
|
127
|
+
// `<` (e.g. ``"The user sent `"``).
|
|
128
|
+
test('should preserve text containing entity references as a single child', ({ expect }) => {
|
|
129
|
+
const xml = trim`
|
|
130
|
+
<reasoning>The user sent \`<foo>\`, which appears to be an XML-like tag.</reasoning>
|
|
131
|
+
`;
|
|
132
|
+
|
|
133
|
+
const registry = { reasoning: { block: true } };
|
|
134
|
+
const elements = parseElements(xml, registry);
|
|
135
|
+
expect(elements).toHaveLength(1);
|
|
136
|
+
expect(elements[0]._tag).toBe('reasoning');
|
|
137
|
+
expect(elements[0].children).toEqual(['The user sent `<foo>`, which appears to be an XML-like tag.']);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
test('should decode numeric character references', ({ expect }) => {
|
|
141
|
+
const xml = trim`
|
|
142
|
+
<reasoning>arrow → and hex →</reasoning>
|
|
143
|
+
`;
|
|
144
|
+
|
|
145
|
+
const registry = { reasoning: { block: true } };
|
|
146
|
+
const elements = parseElements(xml, registry);
|
|
147
|
+
expect(elements).toHaveLength(1);
|
|
148
|
+
expect(elements[0].children).toEqual(['arrow → and hex →']);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('should parse tag with multiple blank lines in content', ({ expect }) => {
|
|
152
|
+
const xml = trim`
|
|
153
|
+
<reasoning>
|
|
154
|
+
First paragraph.
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
Second paragraph after two blank lines.
|
|
158
|
+
</reasoning>
|
|
159
|
+
`;
|
|
160
|
+
|
|
161
|
+
const registry = { reasoning: { block: true } };
|
|
162
|
+
const elements = parseElements(xml, registry);
|
|
163
|
+
expect(elements).toHaveLength(1);
|
|
164
|
+
expect(elements[0]._tag).toBe('reasoning');
|
|
165
|
+
expect(elements[0].complete).toBe(true);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// Regression: when an unregistered XML tag like `<prompt>` appears earlier in the doc,
|
|
169
|
+
// the markdown parser treats it as a paragraph that lazy-continues into subsequent lines,
|
|
170
|
+
// and a later multi-line tag (e.g. `<reasoning>` whose body contains an ordered list) gets
|
|
171
|
+
// its HTMLBlock truncated to its first line — losing the closing tag and breaking widget
|
|
172
|
+
// rendering. Including the surrounding tag in the registry as a block-only entry (no
|
|
173
|
+
// factory/Component) lets `xmlBlockParsers` keep each tag as its own block.
|
|
174
|
+
test('multi-line reasoning is complete when preceded by a registered prompt block', ({ expect }) => {
|
|
175
|
+
const xml = [
|
|
176
|
+
'<prompt>summarize the posts</prompt>',
|
|
177
|
+
'<toolCall id="x" />',
|
|
178
|
+
'<reasoning>multi line content',
|
|
179
|
+
'1. "First" - desc',
|
|
180
|
+
'5. "Last" - desc</reasoning>',
|
|
181
|
+
].join('\n');
|
|
182
|
+
const registry = {
|
|
183
|
+
prompt: { block: true },
|
|
184
|
+
reasoning: { block: true },
|
|
185
|
+
toolCall: { block: true },
|
|
186
|
+
};
|
|
187
|
+
const elements = parseElements(xml, registry);
|
|
188
|
+
expect(elements.map((e) => `${e._tag}${e.complete ? '' : '!'}`)).toEqual(['prompt', 'toolCall', 'reasoning']);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
test('should parse text.md', ({ expect }) => {
|
|
192
|
+
// Mirror the live ChatThread registry, including `prompt` as a block-only entry so
|
|
193
|
+
// unregistered-paragraph lazy-continuation does not break later multi-line tags.
|
|
194
|
+
const registry = {
|
|
195
|
+
prompt: { block: true },
|
|
196
|
+
reasoning: { block: true },
|
|
197
|
+
status: { block: true },
|
|
198
|
+
toolCall: { block: true },
|
|
199
|
+
name: { block: true },
|
|
200
|
+
};
|
|
201
|
+
const elements = parseElements(TEXT, registry);
|
|
202
|
+
const tags = elements.map((element) => element._tag);
|
|
203
|
+
expect(tags).toEqual([
|
|
204
|
+
'prompt',
|
|
205
|
+
'reasoning',
|
|
206
|
+
'status',
|
|
207
|
+
'toolCall',
|
|
208
|
+
'toolCall',
|
|
209
|
+
'reasoning',
|
|
210
|
+
'status',
|
|
211
|
+
'toolCall',
|
|
212
|
+
'reasoning',
|
|
213
|
+
'prompt',
|
|
214
|
+
'reasoning',
|
|
215
|
+
'prompt',
|
|
216
|
+
'name',
|
|
217
|
+
]);
|
|
218
|
+
// Every element must be `complete` so the widget renderer wraps it. The bug we fixed:
|
|
219
|
+
// third multi-line `<reasoning>` (lines 9-14) used to be truncated by markdown's
|
|
220
|
+
// OrderedList parser breaking the HTMLBlock, leaving an Element node with no CloseTag.
|
|
221
|
+
expect(elements.filter((e) => !e.complete)).toEqual([]);
|
|
222
|
+
});
|
|
48
223
|
});
|
|
@@ -65,14 +65,25 @@ export const nodeToJson = (state: EditorState, node: SyntaxNode): Tag | undefine
|
|
|
65
65
|
const children: any[] = [];
|
|
66
66
|
let child = node.node.firstChild;
|
|
67
67
|
|
|
68
|
+
const appendText = (raw: string) => {
|
|
69
|
+
if (raw.length === 0) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const last = children[children.length - 1];
|
|
73
|
+
if (typeof last === 'string') {
|
|
74
|
+
children[children.length - 1] = last + raw;
|
|
75
|
+
} else {
|
|
76
|
+
children.push(raw);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
68
80
|
while (child) {
|
|
69
81
|
// Skip the opening and closing tags.
|
|
70
82
|
if (child.type.name !== 'OpenTag' && child.type.name !== 'CloseTag') {
|
|
71
83
|
if (child.type.name === 'Text') {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
84
|
+
appendText(state.doc.sliceString(child.from, child.to));
|
|
85
|
+
} else if (child.type.name === 'EntityReference' || child.type.name === 'CharacterReference') {
|
|
86
|
+
appendText(decodeXmlEntity(state.doc.sliceString(child.from, child.to)));
|
|
76
87
|
} else if (child.type.name === 'Element') {
|
|
77
88
|
const data = nodeToJson(state, child);
|
|
78
89
|
if (data) {
|
|
@@ -83,11 +94,57 @@ export const nodeToJson = (state: EditorState, node: SyntaxNode): Tag | undefine
|
|
|
83
94
|
child = child.nextSibling;
|
|
84
95
|
}
|
|
85
96
|
|
|
97
|
+
// Trim only leading/trailing whitespace on the outer-boundary string segments —
|
|
98
|
+
// interior strings are preserved verbatim so meaningful whitespace around inline
|
|
99
|
+
// child elements (e.g. `<reasoning>foo <ref/> bar</reasoning>`) is not collapsed.
|
|
100
|
+
if (children.length > 0 && typeof children[0] === 'string') {
|
|
101
|
+
children[0] = children[0].trimStart();
|
|
102
|
+
}
|
|
86
103
|
if (children.length > 0) {
|
|
87
|
-
|
|
104
|
+
const lastIndex = children.length - 1;
|
|
105
|
+
const last = children[lastIndex];
|
|
106
|
+
if (typeof last === 'string') {
|
|
107
|
+
children[lastIndex] = last.trimEnd();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const trimmed = children.filter((value) => typeof value !== 'string' || value.length > 0);
|
|
111
|
+
|
|
112
|
+
if (trimmed.length > 0) {
|
|
113
|
+
tag.children = trimmed;
|
|
88
114
|
}
|
|
89
115
|
}
|
|
90
116
|
|
|
91
117
|
return tag;
|
|
92
118
|
}
|
|
93
119
|
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Decode the common XML named entities and numeric character references that
|
|
123
|
+
* Lezer XML produces as `EntityReference` / `CharacterReference` nodes.
|
|
124
|
+
*/
|
|
125
|
+
const XML_NAMED_ENTITIES: Record<string, string> = {
|
|
126
|
+
'<': '<',
|
|
127
|
+
'>': '>',
|
|
128
|
+
'&': '&',
|
|
129
|
+
'"': '"',
|
|
130
|
+
''': "'",
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const decodeXmlEntity = (raw: string): string => {
|
|
134
|
+
const named = XML_NAMED_ENTITIES[raw];
|
|
135
|
+
if (named !== undefined) {
|
|
136
|
+
return named;
|
|
137
|
+
}
|
|
138
|
+
const numeric = /^&#(x?)([0-9a-fA-F]+);$/.exec(raw);
|
|
139
|
+
if (numeric) {
|
|
140
|
+
const code = parseInt(numeric[2], numeric[1] ? 16 : 10);
|
|
141
|
+
if (Number.isFinite(code)) {
|
|
142
|
+
try {
|
|
143
|
+
return String.fromCodePoint(code);
|
|
144
|
+
} catch {
|
|
145
|
+
// Fall through and return the raw text on out-of-range code points.
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return raw;
|
|
150
|
+
};
|
package/src/index.ts
CHANGED
package/src/styles/index.ts
CHANGED
package/src/styles/theme.ts
CHANGED
|
@@ -5,7 +5,60 @@
|
|
|
5
5
|
import { type Extension } from '@codemirror/state';
|
|
6
6
|
import { EditorView } from '@codemirror/view';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { mx } from '@dxos/ui-theme';
|
|
9
|
+
|
|
10
|
+
export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
11
|
+
|
|
12
|
+
// https://tailwindcss.com/docs/font-weight
|
|
13
|
+
const headings: Record<HeadingLevel, { className: string; fontSize: string; lineHeight: string }> = {
|
|
14
|
+
1: {
|
|
15
|
+
className: 'text-3xl',
|
|
16
|
+
fontSize: 'var(--text-3xl)',
|
|
17
|
+
lineHeight: 'var(--text-4xl--line-height)',
|
|
18
|
+
},
|
|
19
|
+
2: {
|
|
20
|
+
className: 'text-2xl',
|
|
21
|
+
fontSize: 'var(--text-2xl)',
|
|
22
|
+
lineHeight: 'var(--text-3xl--line-height)',
|
|
23
|
+
},
|
|
24
|
+
3: {
|
|
25
|
+
className: 'text-xl',
|
|
26
|
+
fontSize: 'var(--text-xl)',
|
|
27
|
+
lineHeight: 'var(--text-2xl--line-height)',
|
|
28
|
+
},
|
|
29
|
+
4: {
|
|
30
|
+
className: 'text-lg',
|
|
31
|
+
fontSize: 'var(--text-lg)',
|
|
32
|
+
lineHeight: 'var(--text-xl--line-height)',
|
|
33
|
+
},
|
|
34
|
+
5: {
|
|
35
|
+
className: 'text-base',
|
|
36
|
+
fontSize: 'var(--text-base)',
|
|
37
|
+
lineHeight: 'var(--text-lg--line-height)',
|
|
38
|
+
},
|
|
39
|
+
6: {
|
|
40
|
+
className: 'text-base',
|
|
41
|
+
fontSize: 'var(--text-base)',
|
|
42
|
+
lineHeight: 'var(--text-base--line-height)',
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Font families matching --font-body and --font-mono in theme.css.
|
|
47
|
+
export const fontBody = '"Inter Variable", ui-sans-serif, system-ui, sans-serif';
|
|
48
|
+
export const fontMono = '"JetBrains Mono Variable", ui-monospace, "Cascadia Code", "Source Code Pro", monospace';
|
|
49
|
+
|
|
50
|
+
export const markdownTheme = {
|
|
51
|
+
code: 'font-mono! cm-code-inline',
|
|
52
|
+
codeMark: 'font-mono! cm-code-mark',
|
|
53
|
+
mark: 'font-mono!',
|
|
54
|
+
heading: (level: HeadingLevel) => ({
|
|
55
|
+
className: mx(headings[level].className, 'font-light text-(--color-cm-heading-number)'),
|
|
56
|
+
color: 'var(--color-cm-heading) !important',
|
|
57
|
+
lineHeight: headings[level].lineHeight,
|
|
58
|
+
fontSize: headings[level].fontSize,
|
|
59
|
+
fontWeight: '100 !important',
|
|
60
|
+
}),
|
|
61
|
+
};
|
|
9
62
|
|
|
10
63
|
/**
|
|
11
64
|
* Global base theme.
|
|
@@ -43,6 +96,9 @@ import { fontBody, fontMono } from './tokens';
|
|
|
43
96
|
* </div>
|
|
44
97
|
*/
|
|
45
98
|
export const baseTheme = EditorView.baseTheme({
|
|
99
|
+
/**
|
|
100
|
+
* Outer frame.
|
|
101
|
+
*/
|
|
46
102
|
'&': {},
|
|
47
103
|
'&.cm-focused': {
|
|
48
104
|
outline: 'none',
|
|
@@ -52,7 +108,27 @@ export const baseTheme = EditorView.baseTheme({
|
|
|
52
108
|
* Scroller
|
|
53
109
|
*/
|
|
54
110
|
'.cm-scroller': {
|
|
55
|
-
|
|
111
|
+
// Browser scroll-anchoring: see comment in `scrolling/crawler.ts`. `auto` lets the browser pin a
|
|
112
|
+
// stable element near the viewport top so widget resizes (e.g. tool-block TogglePanel
|
|
113
|
+
// open/close) don't jump the user's view.
|
|
114
|
+
overflowAnchor: 'auto',
|
|
115
|
+
},
|
|
116
|
+
'.cm-scroller::-webkit-scrollbar': {
|
|
117
|
+
width: 'var(--scrollbar-size,8px)',
|
|
118
|
+
height: 'var(--scrollbar-size,8px)',
|
|
119
|
+
},
|
|
120
|
+
'.cm-scroller::-webkit-scrollbar-corner': {
|
|
121
|
+
background: 'transparent',
|
|
122
|
+
},
|
|
123
|
+
'.cm-scroller::-webkit-scrollbar-track': {
|
|
124
|
+
background: 'transparent',
|
|
125
|
+
},
|
|
126
|
+
'.cm-scroller::-webkit-scrollbar-thumb': {
|
|
127
|
+
background: 'transparent',
|
|
128
|
+
transition: 'background 0.15s',
|
|
129
|
+
},
|
|
130
|
+
'&:hover .cm-scroller::-webkit-scrollbar-thumb': {
|
|
131
|
+
background: 'var(--color-scrollbar-thumb)',
|
|
56
132
|
},
|
|
57
133
|
|
|
58
134
|
/**
|
|
@@ -61,7 +137,6 @@ export const baseTheme = EditorView.baseTheme({
|
|
|
61
137
|
*/
|
|
62
138
|
'.cm-content': {
|
|
63
139
|
padding: 'unset',
|
|
64
|
-
lineHeight: '24px',
|
|
65
140
|
color: 'unset',
|
|
66
141
|
},
|
|
67
142
|
|
|
@@ -76,8 +151,8 @@ export const baseTheme = EditorView.baseTheme({
|
|
|
76
151
|
'.cm-gutter': {},
|
|
77
152
|
'.cm-gutter.cm-lineNumbers': {
|
|
78
153
|
paddingRight: '4px',
|
|
79
|
-
borderRight: '1px solid var(--
|
|
80
|
-
color: 'var(--
|
|
154
|
+
borderRight: '1px solid var(--color-subdued-separator)',
|
|
155
|
+
color: 'var(--color-subdued)',
|
|
81
156
|
},
|
|
82
157
|
'.cm-gutter.cm-lineNumbers .cm-gutterElement': {
|
|
83
158
|
minWidth: '40px',
|
|
@@ -94,31 +169,38 @@ export const baseTheme = EditorView.baseTheme({
|
|
|
94
169
|
* Line.
|
|
95
170
|
*/
|
|
96
171
|
'.cm-line': {
|
|
97
|
-
lineHeight:
|
|
172
|
+
lineHeight: 1.5,
|
|
98
173
|
paddingInline: 0,
|
|
99
174
|
},
|
|
175
|
+
/**
|
|
176
|
+
* Force all inline children to inherit line-height to prevent monospace font metrics
|
|
177
|
+
* (JetBrains Mono ascent/descent) from inflating the line box beyond 24px.
|
|
178
|
+
*/
|
|
179
|
+
'.cm-line *': {
|
|
180
|
+
lineHeight: 'inherit',
|
|
181
|
+
},
|
|
100
182
|
'.cm-activeLine': {
|
|
101
|
-
background: 'var(--
|
|
183
|
+
background: 'var(--color-cm-active-line)',
|
|
102
184
|
},
|
|
103
185
|
|
|
104
186
|
/**
|
|
105
187
|
* Cursor (layer).
|
|
106
188
|
*/
|
|
107
189
|
'.cm-cursor, .cm-dropCursor': {
|
|
108
|
-
borderLeft: '2px solid var(--
|
|
190
|
+
borderLeft: '2px solid var(--color-cm-cursor)',
|
|
109
191
|
},
|
|
110
192
|
'.cm-placeholder': {
|
|
111
|
-
color: 'var(--
|
|
193
|
+
color: 'var(--color-placeholder)',
|
|
112
194
|
},
|
|
113
195
|
|
|
114
196
|
/**
|
|
115
197
|
* Selection (layer).
|
|
116
198
|
*/
|
|
117
199
|
'.cm-selectionBackground': {
|
|
118
|
-
background: 'var(--
|
|
200
|
+
background: 'var(--color-cm-selection)',
|
|
119
201
|
},
|
|
120
202
|
'&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground': {
|
|
121
|
-
background: 'var(--
|
|
203
|
+
background: 'var(--color-cm-focused-selection)',
|
|
122
204
|
},
|
|
123
205
|
|
|
124
206
|
/**
|
|
@@ -129,8 +211,8 @@ export const baseTheme = EditorView.baseTheme({
|
|
|
129
211
|
margin: '0 -3px',
|
|
130
212
|
padding: '3px',
|
|
131
213
|
borderRadius: '3px',
|
|
132
|
-
background: 'var(--
|
|
133
|
-
color: 'var(--
|
|
214
|
+
background: 'var(--color-cm-highlight-surface)',
|
|
215
|
+
color: 'var(--color-cm-highlight)',
|
|
134
216
|
},
|
|
135
217
|
'.cm-searchMatch-selected': {
|
|
136
218
|
textDecoration: 'underline',
|
|
@@ -142,21 +224,31 @@ export const baseTheme = EditorView.baseTheme({
|
|
|
142
224
|
'.cm-link': {
|
|
143
225
|
textDecorationLine: 'underline',
|
|
144
226
|
textDecorationThickness: '1px',
|
|
145
|
-
textDecorationColor: 'var(--
|
|
227
|
+
textDecorationColor: 'var(--color-separator)',
|
|
146
228
|
textUnderlineOffset: '2px',
|
|
147
229
|
borderRadius: '.125rem',
|
|
230
|
+
cursor: 'pointer',
|
|
148
231
|
},
|
|
149
232
|
'.cm-link > span': {
|
|
150
|
-
color: 'var(--
|
|
233
|
+
color: 'var(--color-accent-text)',
|
|
234
|
+
},
|
|
235
|
+
'.cm-link > span:hover': {
|
|
236
|
+
color: 'var(--color-accent-text-hover)',
|
|
151
237
|
},
|
|
152
238
|
|
|
153
239
|
/**
|
|
154
240
|
* Tooltip.
|
|
155
241
|
*/
|
|
156
242
|
'.cm-tooltip': {
|
|
157
|
-
background: 'var(--
|
|
243
|
+
background: 'var(--color-modal-surface)',
|
|
158
244
|
},
|
|
159
245
|
'.cm-tooltip-below': {},
|
|
246
|
+
'.cm-tooltip-hover': {
|
|
247
|
+
background: 'var(--color-modal-surface)',
|
|
248
|
+
border: '1px solid var(--color-separator)',
|
|
249
|
+
borderRadius: '4px',
|
|
250
|
+
overflow: 'hidden',
|
|
251
|
+
},
|
|
160
252
|
|
|
161
253
|
/**
|
|
162
254
|
* Autocomplete.
|
|
@@ -165,7 +257,7 @@ export const baseTheme = EditorView.baseTheme({
|
|
|
165
257
|
'.cm-tooltip.cm-tooltip-autocomplete': {
|
|
166
258
|
marginTop: '6px',
|
|
167
259
|
marginLeft: '-10px',
|
|
168
|
-
border: '2px solid var(--
|
|
260
|
+
border: '2px solid var(--color-separator)',
|
|
169
261
|
borderRadius: '4px',
|
|
170
262
|
},
|
|
171
263
|
'.cm-tooltip.cm-tooltip-autocomplete > ul': {
|
|
@@ -175,12 +267,12 @@ export const baseTheme = EditorView.baseTheme({
|
|
|
175
267
|
padding: '4px',
|
|
176
268
|
},
|
|
177
269
|
'.cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]': {
|
|
178
|
-
background: 'var(--
|
|
179
|
-
color: 'var(--
|
|
270
|
+
background: 'var(--color-current-surface)',
|
|
271
|
+
color: 'var(--color-base-foreground)',
|
|
180
272
|
},
|
|
181
273
|
'.cm-tooltip.cm-tooltip-autocomplete > ul > completion-section': {
|
|
182
274
|
paddingLeft: '4px !important',
|
|
183
|
-
color: 'var(--
|
|
275
|
+
color: 'var(--color-base-foreground)',
|
|
184
276
|
},
|
|
185
277
|
|
|
186
278
|
/**
|
|
@@ -190,17 +282,17 @@ export const baseTheme = EditorView.baseTheme({
|
|
|
190
282
|
width: '360px !important',
|
|
191
283
|
margin: '-10px 1px 0 1px',
|
|
192
284
|
padding: '8px !important',
|
|
193
|
-
borderColor: 'var(--
|
|
285
|
+
borderColor: 'var(--color-separator)',
|
|
194
286
|
},
|
|
195
287
|
'.cm-completionIcon': {
|
|
196
288
|
display: 'none',
|
|
197
289
|
},
|
|
198
290
|
'.cm-completionLabel': {
|
|
199
|
-
color: 'var(--
|
|
291
|
+
color: 'var(--color-description)',
|
|
200
292
|
padding: '0 4px',
|
|
201
293
|
},
|
|
202
294
|
'.cm-completionMatchedText': {
|
|
203
|
-
color: 'var(--
|
|
295
|
+
color: 'var(--color-base-foreground)',
|
|
204
296
|
textDecoration: 'none !important',
|
|
205
297
|
},
|
|
206
298
|
|
|
@@ -225,7 +317,7 @@ export const baseTheme = EditorView.baseTheme({
|
|
|
225
317
|
backgroundColor: 'var(--surface-bg)',
|
|
226
318
|
},
|
|
227
319
|
'.cm-panel input, .cm-panel button, .cm-panel label': {
|
|
228
|
-
color: 'var(--
|
|
320
|
+
color: 'var(--color-subdued)',
|
|
229
321
|
fontSize: '14px',
|
|
230
322
|
all: 'unset',
|
|
231
323
|
margin: '3px !important',
|
|
@@ -233,10 +325,10 @@ export const baseTheme = EditorView.baseTheme({
|
|
|
233
325
|
outline: '1px solid transparent',
|
|
234
326
|
},
|
|
235
327
|
'.cm-panel input, .cm-panel button': {
|
|
236
|
-
backgroundColor: 'var(--
|
|
328
|
+
backgroundColor: 'var(--color-input-surface)',
|
|
237
329
|
},
|
|
238
330
|
'.cm-panel input:focus, .cm-panel button:focus': {
|
|
239
|
-
outline: '1px solid var(--
|
|
331
|
+
outline: '1px solid var(--color-focus-ring-subtle)',
|
|
240
332
|
},
|
|
241
333
|
'.cm-panel label': {
|
|
242
334
|
display: 'inline-flex',
|
|
@@ -249,26 +341,27 @@ export const baseTheme = EditorView.baseTheme({
|
|
|
249
341
|
height: '8px',
|
|
250
342
|
marginRight: '6px !important',
|
|
251
343
|
padding: '2px !important',
|
|
252
|
-
color: 'var(--
|
|
344
|
+
color: 'var(--color-focus-ring-subtle)',
|
|
253
345
|
},
|
|
254
346
|
'.cm-panel button': {
|
|
255
347
|
'&:hover': {
|
|
256
|
-
|
|
348
|
+
// TODO(burdon): Replace with layer and @apply bg-accent-surface-hover
|
|
349
|
+
backgroundColor: 'var(--color-accent-surface-hover) !important',
|
|
257
350
|
},
|
|
258
351
|
'&:active': {
|
|
259
|
-
backgroundColor: 'var(--
|
|
352
|
+
backgroundColor: 'var(--color-accent-surface-hover)',
|
|
260
353
|
},
|
|
261
354
|
},
|
|
262
355
|
'.cm-panel.cm-search': {
|
|
263
356
|
padding: '4px',
|
|
264
|
-
borderTop: '1px solid var(--
|
|
357
|
+
borderTop: '1px solid var(--color-separator)',
|
|
265
358
|
},
|
|
266
359
|
});
|
|
267
360
|
|
|
268
361
|
export const editorGutter: Extension = EditorView.theme({
|
|
269
362
|
'.cm-gutters': {
|
|
270
363
|
// NOTE: Non-transparent background required to cover content if scrolling horizontally.
|
|
271
|
-
background: 'var(--
|
|
364
|
+
background: 'var(--color-base-surface) !important',
|
|
272
365
|
paddingRight: '1rem',
|
|
273
366
|
},
|
|
274
367
|
});
|
|
@@ -279,10 +372,9 @@ export type FontOptions = {
|
|
|
279
372
|
|
|
280
373
|
export const createFontTheme = ({ monospace }: FontOptions = {}) =>
|
|
281
374
|
EditorView.theme({
|
|
282
|
-
//
|
|
375
|
+
// Main content.
|
|
283
376
|
'.cm-scroller': {
|
|
284
377
|
fontFamily: monospace ? fontMono : fontBody,
|
|
285
|
-
fontSize: '16px',
|
|
286
378
|
},
|
|
287
379
|
|
|
288
380
|
// Maintain defaults for UI components.
|
package/src/types/types.ts
CHANGED
|
@@ -24,9 +24,17 @@ export type Comment = {
|
|
|
24
24
|
export type RenderCallback<Props extends object> = (el: HTMLElement, props: Props, view: EditorView) => void;
|
|
25
25
|
|
|
26
26
|
export const EditorViewModes = ['preview', 'readonly', 'source'] as const;
|
|
27
|
-
export const EditorViewMode = Schema.Union(
|
|
27
|
+
export const EditorViewMode = Schema.Union(
|
|
28
|
+
Schema.Literal('preview').annotations({ title: 'Preview' }),
|
|
29
|
+
Schema.Literal('readonly').annotations({ title: 'Read-only' }),
|
|
30
|
+
Schema.Literal('source').annotations({ title: 'Source' }),
|
|
31
|
+
);
|
|
28
32
|
export type EditorViewMode = Schema.Schema.Type<typeof EditorViewMode>;
|
|
29
33
|
|
|
30
34
|
export const EditorInputModes = ['default', 'vim', 'vscode'] as const;
|
|
31
|
-
export const EditorInputMode = Schema.Union(
|
|
35
|
+
export const EditorInputMode = Schema.Union(
|
|
36
|
+
Schema.Literal('default').annotations({ title: 'Default' }),
|
|
37
|
+
Schema.Literal('vim').annotations({ title: 'Vim' }),
|
|
38
|
+
Schema.Literal('vscode').annotations({ title: 'VS Code' }),
|
|
39
|
+
);
|
|
32
40
|
export type EditorInputMode = Schema.Schema.Type<typeof EditorInputMode>;
|