@adia-ai/web-components 0.0.11 → 0.0.13
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/README.md +8 -8
- package/components/calendar-picker/calendar-picker.css +8 -2
- package/components/chat/chat-input.css +41 -5
- package/components/code/code-editor.js +103 -0
- package/components/code/code.css +146 -0
- package/components/code/code.js +221 -24
- package/components/field/field.a2ui.json +149 -0
- package/components/field/field.css +111 -0
- package/components/field/field.js +306 -0
- package/components/field/field.test.js +146 -0
- package/components/field/field.yaml +155 -0
- package/components/index.js +1 -0
- package/components/input/input.css +10 -3
- package/components/range/range.css +10 -3
- package/components/select/select.css +9 -4
- package/components/slider/slider.js +8 -3
- package/components/textarea/textarea.css +12 -2
- package/components/upload/upload.css +5 -2
- package/core/element.test.js +234 -0
- package/core/form.js +26 -0
- package/core/index.js +25 -0
- package/core/markdown.js +8 -2
- package/index.css +26 -0
- package/index.js +18 -0
- package/package.json +14 -6
- package/patterns/adia-chat/adia-chat.js +1 -1
- package/styles/colors/semantics.css +41 -14
- package/styles/{styles.css → components.css} +9 -111
- package/styles/resets.css +116 -0
- package/styles/tokens.css +8 -2
package/README.md
CHANGED
|
@@ -5,9 +5,9 @@ elements**, a reactive core, a trait system, and a renderer that turns
|
|
|
5
5
|
A2UI protocol messages into live DOM.
|
|
6
6
|
|
|
7
7
|
> This package ships UI atoms only. The generation pipeline lives in
|
|
8
|
-
> [`@adia-ai/
|
|
9
|
-
> [`@adia-ai/
|
|
10
|
-
> [`@adia-ai/
|
|
8
|
+
> [`@adia-ai/a2ui-compose`](../a2ui/compose); the pattern corpus in
|
|
9
|
+
> [`@adia-ai/a2ui-corpus`](../a2ui/corpus); the MCP server in
|
|
10
|
+
> [`@adia-ai/a2ui-mcp`](../a2ui/mcp).
|
|
11
11
|
|
|
12
12
|
## Quick start
|
|
13
13
|
|
|
@@ -80,7 +80,7 @@ web-components/
|
|
|
80
80
|
Build + dev utilities (including `build-a2ui-data.mjs`, `qa-training.mjs`,
|
|
81
81
|
`a2ui-to-html.cjs`, `mcp-call.cjs`, `mcp-pipeline.cjs`, `screenshot.cjs`)
|
|
82
82
|
live at the repo-root `scripts/` directory rather than inside this
|
|
83
|
-
package — they span the monorepo (MCP server,
|
|
83
|
+
package — they span the monorepo (MCP server, a2ui-corpus data,
|
|
84
84
|
component catalog) and aren't scoped to web-components alone.
|
|
85
85
|
|
|
86
86
|
## Component contract
|
|
@@ -165,7 +165,7 @@ output is robust to name drift.
|
|
|
165
165
|
npm run build:components # regenerate all .a2ui.json from YAML
|
|
166
166
|
```
|
|
167
167
|
|
|
168
|
-
The build also writes `packages/
|
|
168
|
+
The build also writes `packages/a2ui/corpus/catalog-a2ui_0_9.json` and
|
|
169
169
|
`catalog-a2ui_0_9_rules.txt` — the flat-file catalog the MCP server and
|
|
170
170
|
generation engine consume.
|
|
171
171
|
|
|
@@ -189,11 +189,11 @@ Each is a CSS-variable override; no class toggles, no re-imports.
|
|
|
189
189
|
## Dependency direction
|
|
190
190
|
|
|
191
191
|
```
|
|
192
|
-
|
|
193
|
-
|
|
192
|
+
a2ui-compose ──reads──> a2ui-corpus ←─reads── web-components
|
|
193
|
+
a2ui-mcp ──reads──> a2ui-compose, a2ui-corpus
|
|
194
194
|
```
|
|
195
195
|
|
|
196
|
-
Web-components never imports from
|
|
196
|
+
Web-components never imports from a2ui-compose or a2ui-mcp. The A2UI renderer
|
|
197
197
|
consumes a protocol, not a generator — anything that emits valid A2UI
|
|
198
198
|
messages drives it.
|
|
199
199
|
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
--calendar-picker-trigger-fg: var(--a-ui-text-subtle);
|
|
20
20
|
--calendar-picker-trigger-border: var(--a-ui-border);
|
|
21
21
|
--calendar-picker-trigger-border-hover: var(--a-ui-border-hover);
|
|
22
|
-
--calendar-picker-trigger-
|
|
22
|
+
--calendar-picker-trigger-focus-ring: var(--a-focus-ring);
|
|
23
|
+
--calendar-picker-trigger-focus-ring-invalid: var(--a-focus-ring-invalid);
|
|
23
24
|
--calendar-picker-trigger-placeholder-fg: var(--a-ui-text-placeholder);
|
|
24
25
|
--calendar-picker-trigger-fg-disabled: var(--a-ui-text-disabled);
|
|
25
26
|
|
|
@@ -138,7 +139,12 @@
|
|
|
138
139
|
|
|
139
140
|
:scope:focus-visible { outline: none; }
|
|
140
141
|
:scope:focus-visible [slot="trigger"] {
|
|
141
|
-
|
|
142
|
+
/* Canonical ring via L3 token (see semantics.css FOCUS block). */
|
|
143
|
+
box-shadow: var(--calendar-picker-trigger-focus-ring);
|
|
144
|
+
}
|
|
145
|
+
:scope[aria-invalid="true"]:focus-visible [slot="trigger"],
|
|
146
|
+
:scope[error]:focus-visible [slot="trigger"] {
|
|
147
|
+
box-shadow: var(--calendar-picker-trigger-focus-ring-invalid);
|
|
142
148
|
}
|
|
143
149
|
|
|
144
150
|
[slot="display"] {
|
|
@@ -11,10 +11,18 @@
|
|
|
11
11
|
/* ── Colors ── */
|
|
12
12
|
--chat-input-bg: var(--a-canvas-0);
|
|
13
13
|
--chat-input-border: var(--a-border-subtle);
|
|
14
|
-
--chat-input-border-focus: var(--a-fg);
|
|
15
14
|
--chat-input-caret-color: var(--a-fg-subtle);
|
|
16
15
|
--chat-input-border-disabled: var(--a-border-subtle);
|
|
17
16
|
|
|
17
|
+
/* Canonical focus ring — chat-input is a *nested-control host*.
|
|
18
|
+
See semantics.css FOCUS block + the nested-control pattern
|
|
19
|
+
note below. The inner textarea-ui suppresses its own ring
|
|
20
|
+
inside this @scope; the host paints the ring via
|
|
21
|
+
:focus-within so it wraps BOTH the editable area and the
|
|
22
|
+
toolbar as a single affordance. */
|
|
23
|
+
--chat-input-focus-ring: var(--a-focus-ring);
|
|
24
|
+
--chat-input-focus-ring-invalid: var(--a-focus-ring-invalid);
|
|
25
|
+
|
|
18
26
|
/* ── Image preview ── */
|
|
19
27
|
--chat-input-image-size: 3rem; /* 48px at d=1 */
|
|
20
28
|
--chat-input-image-radius: var(--a-radius-sm);
|
|
@@ -42,11 +50,30 @@
|
|
|
42
50
|
border: 1px solid var(--chat-input-border);
|
|
43
51
|
border-radius: var(--chat-input-radius);
|
|
44
52
|
background: var(--chat-input-bg);
|
|
45
|
-
transition: border-color var(--chat-input-duration) var(--chat-input-easing);
|
|
46
53
|
}
|
|
47
54
|
|
|
48
|
-
|
|
49
|
-
|
|
55
|
+
/* ── Nested-control focus pattern ────────────────────────────────────
|
|
56
|
+
chat-input-ui is a composite whose "primary surface" is the
|
|
57
|
+
combined textarea + toolbar, not the textarea alone. Focus should
|
|
58
|
+
wrap the whole composite, not just the inner input. Two rules
|
|
59
|
+
enforce that:
|
|
60
|
+
|
|
61
|
+
1. `:scope:focus-within` paints the canonical ring around the
|
|
62
|
+
composite via box-shadow (matches every other form control).
|
|
63
|
+
2. The inner textarea-ui's own focus treatments are suppressed
|
|
64
|
+
inside this @scope — the host owns the affordance.
|
|
65
|
+
|
|
66
|
+
The @scope block's containment is the signal: no data attribute
|
|
67
|
+
or explicit opt-in required. Any future composite that wants the
|
|
68
|
+
same pattern drops its inner control(s) into its @scope and
|
|
69
|
+
suppresses their focus rules with equivalent rules below.
|
|
70
|
+
─────────────────────────────────────────────────────────────── */
|
|
71
|
+
:scope:focus-within {
|
|
72
|
+
box-shadow: var(--chat-input-focus-ring);
|
|
73
|
+
}
|
|
74
|
+
:scope[aria-invalid="true"]:focus-within,
|
|
75
|
+
:scope[error]:focus-within {
|
|
76
|
+
box-shadow: var(--chat-input-focus-ring-invalid);
|
|
50
77
|
}
|
|
51
78
|
|
|
52
79
|
/* Textarea: no border/bg of its own — container handles it. The
|
|
@@ -66,7 +93,16 @@
|
|
|
66
93
|
padding: var(--chat-input-textarea-pt) var(--chat-input-textarea-px) 0;
|
|
67
94
|
}
|
|
68
95
|
|
|
69
|
-
textarea-ui
|
|
96
|
+
/* Suppress the nested textarea-ui's own focus ring — the host (this
|
|
97
|
+
scope) owns the affordance. Required because textarea.css's default
|
|
98
|
+
rule paints a ring via box-shadow; without this override, the
|
|
99
|
+
composite would show both the host's outer ring AND the inner
|
|
100
|
+
control's ring simultaneously.
|
|
101
|
+
|
|
102
|
+
textarea.css's rule is `:scope:not([disabled]) [slot="text"]:focus`
|
|
103
|
+
with specificity (0,4,0); we need to beat that — using the same
|
|
104
|
+
`:not([disabled])` guard on the host lifts ours to (0,4,1). */
|
|
105
|
+
:scope textarea-ui:not([disabled]) [slot="text"]:focus {
|
|
70
106
|
border: none;
|
|
71
107
|
box-shadow: none;
|
|
72
108
|
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* code-editor — CodeMirror 6 runtime bundled for <code-ui>.
|
|
3
|
+
*
|
|
4
|
+
* Single file for the whole integration: CM core re-exports, the AdiaUI
|
|
5
|
+
* base theme + highlight style, the per-language lazy-load map, and the
|
|
6
|
+
* load-timeout helper. `code.js` does `import('./code-editor.js')` once
|
|
7
|
+
* per element mount.
|
|
8
|
+
*
|
|
9
|
+
* Styling contract: `EditorView.theme()` can't emit CSS custom properties
|
|
10
|
+
* (per CodeMirror docs), so the base theme below is structural-only.
|
|
11
|
+
* Every color, padding, border, and syntax-token style lives in
|
|
12
|
+
* `code.css` under `@scope (code-ui)`. See SPEC-CODE-EDITOR-001 §6.
|
|
13
|
+
*
|
|
14
|
+
* In Vite dev, the bare-specifier imports resolve through node_modules.
|
|
15
|
+
* In production, `scripts/build-site.mjs` runs esbuild with
|
|
16
|
+
* `splitting: true` on this file; each `languages[…]()` dynamic import
|
|
17
|
+
* becomes its own chunk, lazy-loaded on first use.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import {
|
|
21
|
+
EditorState, EditorSelection, Compartment, StateEffect,
|
|
22
|
+
} from '@codemirror/state';
|
|
23
|
+
import {
|
|
24
|
+
EditorView,
|
|
25
|
+
lineNumbers, highlightActiveLine, highlightActiveLineGutter,
|
|
26
|
+
placeholder, drawSelection, keymap,
|
|
27
|
+
} from '@codemirror/view';
|
|
28
|
+
import {
|
|
29
|
+
defaultKeymap, history, historyKeymap, indentWithTab,
|
|
30
|
+
} from '@codemirror/commands';
|
|
31
|
+
import {
|
|
32
|
+
HighlightStyle, syntaxHighlighting, LanguageSupport, defaultHighlightStyle,
|
|
33
|
+
} from '@codemirror/language';
|
|
34
|
+
import { tags as t } from '@lezer/highlight';
|
|
35
|
+
|
|
36
|
+
// ── Base theme (structural only — colors live in code.css) ───────────
|
|
37
|
+
|
|
38
|
+
export const adiaBaseTheme = EditorView.theme({
|
|
39
|
+
'&': { fontFamily: 'inherit', fontSize: 'inherit', color: 'inherit', backgroundColor: 'transparent' },
|
|
40
|
+
'.cm-content': { padding: '0', caretColor: 'inherit' },
|
|
41
|
+
'.cm-focused': { outline: 'none' },
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// ── Syntax highlight (class-based so CSS owns the colors) ────────────
|
|
45
|
+
|
|
46
|
+
export const adiaHighlightStyle = HighlightStyle.define([
|
|
47
|
+
{ tag: [t.comment, t.lineComment, t.blockComment, t.docComment], class: 'tok-comment' },
|
|
48
|
+
{ tag: [t.keyword, t.controlKeyword, t.modifier, t.operatorKeyword], class: 'tok-keyword' },
|
|
49
|
+
{ tag: [t.string, t.character, t.regexp, t.escape, t.special(t.string)], class: 'tok-string' },
|
|
50
|
+
{ tag: [t.number, t.integer, t.float], class: 'tok-number' },
|
|
51
|
+
{ tag: [t.bool, t.null, t.atom], class: 'tok-boolean' },
|
|
52
|
+
{ tag: [t.operator, t.logicOperator, t.arithmeticOperator, t.compareOperator,
|
|
53
|
+
t.updateOperator, t.definitionOperator], class: 'tok-operator' },
|
|
54
|
+
{ tag: [t.punctuation, t.bracket, t.paren, t.brace, t.squareBracket,
|
|
55
|
+
t.angleBracket, t.separator], class: 'tok-punctuation' },
|
|
56
|
+
{ tag: [t.function(t.variableName), t.function(t.propertyName), t.macroName], class: 'tok-function' },
|
|
57
|
+
{ tag: [t.variableName, t.local(t.variableName), t.self], class: 'tok-variable' },
|
|
58
|
+
{ tag: [t.typeName, t.className, t.namespace], class: 'tok-type' },
|
|
59
|
+
{ tag: [t.propertyName, t.labelName, t.definition(t.variableName)], class: 'tok-property' },
|
|
60
|
+
{ tag: [t.tagName, t.heading, t.contentSeparator], class: 'tok-tag' },
|
|
61
|
+
{ tag: [t.attributeName, t.attributeValue], class: 'tok-attribute' },
|
|
62
|
+
{ tag: [t.url, t.link], class: 'tok-url' },
|
|
63
|
+
{ tag: [t.invalid, t.deleted], class: 'tok-invalid' },
|
|
64
|
+
]);
|
|
65
|
+
|
|
66
|
+
// ── Per-language lazy loaders ────────────────────────────────────────
|
|
67
|
+
|
|
68
|
+
export const languages = {
|
|
69
|
+
json: () => import('@codemirror/lang-json').then((m) => ({ extension: m.json() })),
|
|
70
|
+
html: () => import('@codemirror/lang-html').then((m) => ({ extension: m.html() })),
|
|
71
|
+
javascript: () => import('@codemirror/lang-javascript').then((m) => ({ extension: m.javascript({ jsx: false, typescript: false }) })),
|
|
72
|
+
css: () => import('@codemirror/lang-css').then((m) => ({ extension: m.css() })),
|
|
73
|
+
markdown: () => import('@codemirror/lang-markdown').then((m) => ({ extension: m.markdown() })),
|
|
74
|
+
yaml: () => import('@codemirror/lang-yaml').then((m) => ({ extension: m.yaml() })),
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// ── Load helper ──────────────────────────────────────────────────────
|
|
78
|
+
|
|
79
|
+
/** 10s ceiling on any single dynamic import. Per SPEC-CODE-EDITOR-001 §7.4. */
|
|
80
|
+
export const LOAD_TIMEOUT_MS = 10_000;
|
|
81
|
+
|
|
82
|
+
export function importWithTimeout(loader, label) {
|
|
83
|
+
return Promise.race([
|
|
84
|
+
loader(),
|
|
85
|
+
new Promise((_, reject) =>
|
|
86
|
+
setTimeout(
|
|
87
|
+
() => reject(new Error(`code-editor: ${label} load timed out after ${LOAD_TIMEOUT_MS}ms`)),
|
|
88
|
+
LOAD_TIMEOUT_MS,
|
|
89
|
+
),
|
|
90
|
+
),
|
|
91
|
+
]);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ── Re-exports (so code.js gets everything from one import) ─────────
|
|
95
|
+
|
|
96
|
+
export {
|
|
97
|
+
EditorState, EditorSelection, Compartment, StateEffect,
|
|
98
|
+
EditorView,
|
|
99
|
+
lineNumbers, highlightActiveLine, highlightActiveLineGutter,
|
|
100
|
+
placeholder, drawSelection, keymap,
|
|
101
|
+
defaultKeymap, history, historyKeymap, indentWithTab,
|
|
102
|
+
HighlightStyle, syntaxHighlighting, LanguageSupport, defaultHighlightStyle,
|
|
103
|
+
};
|
package/components/code/code.css
CHANGED
|
@@ -24,6 +24,39 @@
|
|
|
24
24
|
/* ── Transition ── */
|
|
25
25
|
--code-duration: var(--a-duration-fast);
|
|
26
26
|
--code-easing: var(--a-easing);
|
|
27
|
+
|
|
28
|
+
/* ── Editor chrome (CodeMirror 6) ──
|
|
29
|
+
Active only when `[language]` triggers the CM mount. Still safe
|
|
30
|
+
to emit in read-only mode; unused until `.cm-editor` is in the
|
|
31
|
+
DOM. See docs/specs/code-editor.md §6. */
|
|
32
|
+
--code-gutter-bg: var(--a-bg-subtle);
|
|
33
|
+
--code-gutter-fg: var(--a-fg-muted);
|
|
34
|
+
--code-active-line-bg: color-mix(in oklch, var(--a-accent-muted) 40%, transparent);
|
|
35
|
+
--code-selection-bg: color-mix(in oklch, var(--a-accent-muted) 60%, transparent);
|
|
36
|
+
--code-selection-match: color-mix(in oklch, var(--a-accent-muted) 30%, transparent);
|
|
37
|
+
--code-cursor: var(--a-accent-strong);
|
|
38
|
+
--code-focus-ring: var(--a-focus-ring);
|
|
39
|
+
|
|
40
|
+
/* ── Syntax highlight tokens ──
|
|
41
|
+
Map Lezer/CodeMirror highlight tag names to AdiaUI semantic
|
|
42
|
+
tokens. Overridable per-instance by setting `--code-tok-*` on
|
|
43
|
+
any ancestor. See docs/specs/code-editor.md §6.3 for the tag →
|
|
44
|
+
class → role map. */
|
|
45
|
+
--code-tok-comment: var(--a-fg-subtle);
|
|
46
|
+
--code-tok-keyword: var(--a-accent-strong);
|
|
47
|
+
--code-tok-string: var(--a-success-strong);
|
|
48
|
+
--code-tok-number: var(--a-info-strong);
|
|
49
|
+
--code-tok-boolean: var(--a-info-strong);
|
|
50
|
+
--code-tok-operator: var(--a-fg);
|
|
51
|
+
--code-tok-punctuation: var(--a-fg-muted);
|
|
52
|
+
--code-tok-function: var(--a-brand-strong);
|
|
53
|
+
--code-tok-variable: var(--a-fg);
|
|
54
|
+
--code-tok-type: var(--a-warning-strong);
|
|
55
|
+
--code-tok-property: var(--a-fg);
|
|
56
|
+
--code-tok-tag: var(--a-accent-strong);
|
|
57
|
+
--code-tok-attribute: var(--a-warning-strong);
|
|
58
|
+
--code-tok-url: var(--a-info-strong);
|
|
59
|
+
--code-tok-invalid: var(--a-danger-strong);
|
|
27
60
|
}
|
|
28
61
|
|
|
29
62
|
/* ── Block (default) ── */
|
|
@@ -132,4 +165,117 @@
|
|
|
132
165
|
font-size: 0.9em;
|
|
133
166
|
overflow: visible;
|
|
134
167
|
}
|
|
168
|
+
|
|
169
|
+
/* ── Bare mode — no chrome ──
|
|
170
|
+
Strips border, background, radius, and padding. Header is hidden
|
|
171
|
+
via #stampBlock (it's never added in bare). Used by the A2UI Editor
|
|
172
|
+
and any pane-level context where <code-ui> is framed by a parent
|
|
173
|
+
surface and should not carry its own. Height flows from the parent
|
|
174
|
+
container, so CM's internal scroll handles overflow. */
|
|
175
|
+
:scope[bare] {
|
|
176
|
+
border: none;
|
|
177
|
+
border-radius: 0;
|
|
178
|
+
background: transparent;
|
|
179
|
+
overflow: visible;
|
|
180
|
+
height: 100%;
|
|
181
|
+
}
|
|
182
|
+
:scope[bare] > pre {
|
|
183
|
+
padding: 0;
|
|
184
|
+
height: 100%;
|
|
185
|
+
}
|
|
186
|
+
:scope[bare] > [data-cm-mount] {
|
|
187
|
+
height: 100%;
|
|
188
|
+
}
|
|
189
|
+
:scope[bare] .cm-editor {
|
|
190
|
+
height: 100%;
|
|
191
|
+
}
|
|
192
|
+
:scope[bare] .cm-scroller {
|
|
193
|
+
padding: 0;
|
|
194
|
+
}
|
|
195
|
+
:scope[bare] .cm-gutters {
|
|
196
|
+
background: transparent;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* ── CodeMirror mount ──
|
|
200
|
+
`<code-ui>` inserts `<div data-cm-mount>` in place of `<pre><code>`
|
|
201
|
+
when `[language]` triggers the CM lazy-load. Styles below apply to
|
|
202
|
+
the CodeMirror DOM that CM renders inside that mount.
|
|
203
|
+
|
|
204
|
+
Selector discipline: `.cm-*` classes are CodeMirror's; `.tok-*`
|
|
205
|
+
classes come from our `adiaHighlightStyle` (see core/_cm-theme.js).
|
|
206
|
+
CM's CSS-in-JS stylesheets load first + at lower specificity, so
|
|
207
|
+
these rules override without !important. */
|
|
208
|
+
|
|
209
|
+
> [data-cm-mount] {
|
|
210
|
+
display: block;
|
|
211
|
+
overflow: hidden;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
:scope .cm-editor {
|
|
215
|
+
background: transparent;
|
|
216
|
+
color: var(--code-fg);
|
|
217
|
+
font-family: var(--code-font);
|
|
218
|
+
font-size: var(--code-font-size);
|
|
219
|
+
line-height: 1.5;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
:scope .cm-scroller {
|
|
223
|
+
font-family: inherit;
|
|
224
|
+
line-height: inherit;
|
|
225
|
+
padding: var(--code-py) var(--code-px);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
:scope .cm-content {
|
|
229
|
+
padding: 0;
|
|
230
|
+
caret-color: var(--code-cursor);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
:scope .cm-editor.cm-focused {
|
|
234
|
+
outline: 2px solid var(--code-focus-ring);
|
|
235
|
+
outline-offset: -2px;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
:scope .cm-gutters {
|
|
239
|
+
background: var(--code-gutter-bg);
|
|
240
|
+
color: var(--code-gutter-fg);
|
|
241
|
+
border-right: 1px solid var(--code-border);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
:scope .cm-activeLine {
|
|
245
|
+
background: var(--code-active-line-bg);
|
|
246
|
+
}
|
|
247
|
+
:scope .cm-activeLineGutter {
|
|
248
|
+
background: var(--code-active-line-bg);
|
|
249
|
+
color: var(--code-fg);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
:scope .cm-selectionBackground,
|
|
253
|
+
:scope ::selection {
|
|
254
|
+
background: var(--code-selection-bg);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
:scope .cm-selectionMatch {
|
|
258
|
+
background: var(--code-selection-match);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
:scope .cm-cursor {
|
|
262
|
+
border-left-color: var(--code-cursor);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/* Syntax highlight — one rule per token role (see core/_cm-theme.js) */
|
|
266
|
+
:scope .tok-comment { color: var(--code-tok-comment); font-style: italic; }
|
|
267
|
+
:scope .tok-keyword { color: var(--code-tok-keyword); font-weight: 500; }
|
|
268
|
+
:scope .tok-string { color: var(--code-tok-string); }
|
|
269
|
+
:scope .tok-number { color: var(--code-tok-number); }
|
|
270
|
+
:scope .tok-boolean { color: var(--code-tok-boolean); }
|
|
271
|
+
:scope .tok-operator { color: var(--code-tok-operator); }
|
|
272
|
+
:scope .tok-punctuation { color: var(--code-tok-punctuation); }
|
|
273
|
+
:scope .tok-function { color: var(--code-tok-function); }
|
|
274
|
+
:scope .tok-variable { color: var(--code-tok-variable); }
|
|
275
|
+
:scope .tok-type { color: var(--code-tok-type); font-weight: 500; }
|
|
276
|
+
:scope .tok-property { color: var(--code-tok-property); }
|
|
277
|
+
:scope .tok-tag { color: var(--code-tok-tag); }
|
|
278
|
+
:scope .tok-attribute { color: var(--code-tok-attribute); }
|
|
279
|
+
:scope .tok-url { color: var(--code-tok-url); text-decoration: underline; }
|
|
280
|
+
:scope .tok-invalid { color: var(--code-tok-invalid); text-decoration: wavy underline; }
|
|
135
281
|
}
|