@citisen/litearea 0.1.0
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 +21 -0
- package/README.md +514 -0
- package/README.zh.md +362 -0
- package/dist/grammars.cjs +1228 -0
- package/dist/grammars.cjs.map +1 -0
- package/dist/grammars.js +1213 -0
- package/dist/grammars.js.map +1 -0
- package/dist/index.cjs +3103 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +3040 -0
- package/dist/index.js.map +1 -0
- package/dist/react.cjs +3032 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.js +3010 -0
- package/dist/react.js.map +1 -0
- package/dist/styles.cjs +453 -0
- package/dist/styles.cjs.map +1 -0
- package/dist/styles.css +432 -0
- package/dist/styles.js +447 -0
- package/dist/styles.js.map +1 -0
- package/dist/types/core/complete.d.ts +70 -0
- package/dist/types/core/complete.d.ts.map +1 -0
- package/dist/types/core/format.d.ts +34 -0
- package/dist/types/core/format.d.ts.map +1 -0
- package/dist/types/core/grammar.d.ts +14 -0
- package/dist/types/core/grammar.d.ts.map +1 -0
- package/dist/types/core/hover.d.ts +23 -0
- package/dist/types/core/hover.d.ts.map +1 -0
- package/dist/types/core/index.d.ts +12 -0
- package/dist/types/core/index.d.ts.map +1 -0
- package/dist/types/core/inspect.d.ts +34 -0
- package/dist/types/core/inspect.d.ts.map +1 -0
- package/dist/types/core/rank.d.ts +82 -0
- package/dist/types/core/rank.d.ts.map +1 -0
- package/dist/types/core/scan.d.ts +51 -0
- package/dist/types/core/scan.d.ts.map +1 -0
- package/dist/types/core/segments.d.ts +44 -0
- package/dist/types/core/segments.d.ts.map +1 -0
- package/dist/types/core/text.d.ts +113 -0
- package/dist/types/core/text.d.ts.map +1 -0
- package/dist/types/core/types.d.ts +604 -0
- package/dist/types/core/types.d.ts.map +1 -0
- package/dist/types/core/vocabulary.d.ts +82 -0
- package/dist/types/core/vocabulary.d.ts.map +1 -0
- package/dist/types/dom/create.d.ts +17 -0
- package/dist/types/dom/create.d.ts.map +1 -0
- package/dist/types/dom/editing.d.ts +89 -0
- package/dist/types/dom/editing.d.ts.map +1 -0
- package/dist/types/dom/editor.d.ts +366 -0
- package/dist/types/dom/editor.d.ts.map +1 -0
- package/dist/types/dom/index.d.ts +9 -0
- package/dist/types/dom/index.d.ts.map +1 -0
- package/dist/types/dom/mirror.d.ts +107 -0
- package/dist/types/dom/mirror.d.ts.map +1 -0
- package/dist/types/dom/overlay.d.ts +52 -0
- package/dist/types/dom/overlay.d.ts.map +1 -0
- package/dist/types/dom/popup.d.ts +95 -0
- package/dist/types/dom/popup.d.ts.map +1 -0
- package/dist/types/dom/support.d.ts +41 -0
- package/dist/types/dom/support.d.ts.map +1 -0
- package/dist/types/dom/tooltip.d.ts +39 -0
- package/dist/types/dom/tooltip.d.ts.map +1 -0
- package/dist/types/grammars/dshFont.d.ts +127 -0
- package/dist/types/grammars/dshFont.d.ts.map +1 -0
- package/dist/types/grammars/dshSentry.d.ts +84 -0
- package/dist/types/grammars/dshSentry.d.ts.map +1 -0
- package/dist/types/grammars/index.d.ts +3 -0
- package/dist/types/grammars/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/react/index.d.ts +91 -0
- package/dist/types/react/index.d.ts.map +1 -0
- package/dist/types/styles.d.ts +29 -0
- package/dist/types/styles.d.ts.map +1 -0
- package/docs/architecture.md +316 -0
- package/docs/completion.md +320 -0
- package/docs/grammar.md +823 -0
- package/package.json +105 -0
- package/scripts/browser-check.mjs +838 -0
- package/scripts/build-css.mjs +35 -0
- package/scripts/release.mjs +91 -0
- package/scripts/verify-package.mjs +253 -0
- package/src/core/complete.ts +286 -0
- package/src/core/format.ts +71 -0
- package/src/core/grammar.ts +40 -0
- package/src/core/hover.ts +129 -0
- package/src/core/index.ts +98 -0
- package/src/core/inspect.ts +198 -0
- package/src/core/rank.ts +317 -0
- package/src/core/scan.ts +720 -0
- package/src/core/segments.ts +185 -0
- package/src/core/text.ts +238 -0
- package/src/core/types.ts +681 -0
- package/src/core/vocabulary.ts +196 -0
- package/src/dom/create.ts +31 -0
- package/src/dom/editing.ts +213 -0
- package/src/dom/editor.ts +1143 -0
- package/src/dom/index.ts +46 -0
- package/src/dom/mirror.ts +305 -0
- package/src/dom/overlay.ts +106 -0
- package/src/dom/popup.ts +323 -0
- package/src/dom/support.ts +88 -0
- package/src/dom/tooltip.ts +112 -0
- package/src/grammars/dshFont.ts +1004 -0
- package/src/grammars/dshSentry.ts +742 -0
- package/src/grammars/index.ts +57 -0
- package/src/index.ts +122 -0
- package/src/react/index.tsx +248 -0
- package/src/styles.ts +529 -0
package/dist/styles.cjs
ADDED
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/styles.ts
|
|
4
|
+
var SCOPE_PALETTE = [
|
|
5
|
+
{ scope: "text", light: "var(--litearea-fg)" },
|
|
6
|
+
{ scope: "word", light: "var(--litearea-fg)" },
|
|
7
|
+
{ scope: "family", light: "var(--litearea-fg)" },
|
|
8
|
+
{ scope: "family-generic", light: "#7c3aed", dark: "#c4a2ff" },
|
|
9
|
+
{ scope: "family-unknown", light: "var(--litearea-warning)" },
|
|
10
|
+
{ scope: "family-unclosed", light: "var(--litearea-error)" },
|
|
11
|
+
{ scope: "weight", light: "var(--litearea-accent)" },
|
|
12
|
+
{ scope: "weight-missing", light: "var(--litearea-warning)" },
|
|
13
|
+
{ scope: "state", light: "var(--litearea-accent)" },
|
|
14
|
+
{ scope: "property", light: "#7c3aed", dark: "#c4a2ff" },
|
|
15
|
+
{ scope: "operator", light: "var(--litearea-fg-dim)" },
|
|
16
|
+
{ scope: "separator", light: "var(--litearea-fg-dim)" },
|
|
17
|
+
{ scope: "value-shape", light: "#0f766e", dark: "#5eead4" },
|
|
18
|
+
{ scope: "value-color", light: "#0f766e", dark: "#5eead4" },
|
|
19
|
+
{ scope: "value-pattern", light: "#0f766e", dark: "#5eead4" },
|
|
20
|
+
{ scope: "value-motion", light: "#0f766e", dark: "#5eead4" },
|
|
21
|
+
{ scope: "value-number", light: "#b45309", dark: "#fbbf24" },
|
|
22
|
+
{ scope: "comment", light: "var(--litearea-fg-dim)" },
|
|
23
|
+
{ scope: "invalid", light: "var(--litearea-error)" },
|
|
24
|
+
{ scope: "keyword", light: "var(--litearea-accent)" },
|
|
25
|
+
{ scope: "string", light: "#0f766e", dark: "#5eead4" },
|
|
26
|
+
{ scope: "number", light: "#b45309", dark: "#fbbf24" }
|
|
27
|
+
];
|
|
28
|
+
function scopeVariables(scheme) {
|
|
29
|
+
return SCOPE_PALETTE.filter((entry) => scheme === "light" || entry.dark !== void 0).map((entry) => {
|
|
30
|
+
const value = scheme === "light" ? entry.light : entry.dark;
|
|
31
|
+
return ` --litearea-scope-${entry.scope}: ${String(value)};`;
|
|
32
|
+
}).join("\n");
|
|
33
|
+
}
|
|
34
|
+
function scopeRules() {
|
|
35
|
+
return SCOPE_PALETTE.map(
|
|
36
|
+
(entry) => `.litearea-scope-${entry.scope} { color: var(--litearea-scope-${entry.scope}); }`
|
|
37
|
+
).join("\n");
|
|
38
|
+
}
|
|
39
|
+
var LITEAREA_STYLES = `
|
|
40
|
+
.litearea {
|
|
41
|
+
--litearea-font: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
|
|
42
|
+
--litearea-font-size: 13px;
|
|
43
|
+
--litearea-line-height: 20px;
|
|
44
|
+
--litearea-padding-block: 6px;
|
|
45
|
+
--litearea-padding-inline: 10px;
|
|
46
|
+
--litearea-radius: 8px;
|
|
47
|
+
--litearea-fg: #1f2328;
|
|
48
|
+
--litearea-fg-dim: #6b7280;
|
|
49
|
+
--litearea-fg-strong: #111827;
|
|
50
|
+
--litearea-bg: #ffffff;
|
|
51
|
+
--litearea-bg-raised: #ffffff;
|
|
52
|
+
--litearea-border: #d8dbe0;
|
|
53
|
+
--litearea-border-focus: #4d6bfe;
|
|
54
|
+
--litearea-accent: #4d6bfe;
|
|
55
|
+
--litearea-accent-soft: rgba(77, 107, 254, 0.12);
|
|
56
|
+
--litearea-selection: rgba(77, 107, 254, 0.22);
|
|
57
|
+
--litearea-error: #e5484d;
|
|
58
|
+
--litearea-warning: #d97706;
|
|
59
|
+
--litearea-info: #4d6bfe;
|
|
60
|
+
--litearea-hint: #8b8f97;
|
|
61
|
+
--litearea-shadow: 0 6px 24px rgba(15, 23, 42, 0.14);
|
|
62
|
+
|
|
63
|
+
${scopeVariables("light")}
|
|
64
|
+
|
|
65
|
+
position: relative;
|
|
66
|
+
display: block;
|
|
67
|
+
color: var(--litearea-fg);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@media (prefers-color-scheme: dark) {
|
|
71
|
+
.litearea {
|
|
72
|
+
--litearea-fg: #e6e8eb;
|
|
73
|
+
--litearea-fg-dim: #8b919b;
|
|
74
|
+
--litearea-fg-strong: #ffffff;
|
|
75
|
+
--litearea-bg: #1b1e24;
|
|
76
|
+
--litearea-bg-raised: #23262c;
|
|
77
|
+
--litearea-border: #363b44;
|
|
78
|
+
${scopeVariables("dark")}
|
|
79
|
+
--litearea-error: #ff6b6b;
|
|
80
|
+
--litearea-warning: #f59e0b;
|
|
81
|
+
--litearea-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* \u2500\u2500 the box \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
86
|
+
|
|
87
|
+
.litearea-box {
|
|
88
|
+
position: relative;
|
|
89
|
+
display: block;
|
|
90
|
+
border: 1px solid var(--litearea-border);
|
|
91
|
+
border-radius: var(--litearea-radius);
|
|
92
|
+
background: var(--litearea-bg);
|
|
93
|
+
transition: border-color 120ms ease;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.litearea-box:focus-within {
|
|
97
|
+
border-color: var(--litearea-border-focus);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.litearea-invalid .litearea-box {
|
|
101
|
+
border-color: var(--litearea-error);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/*
|
|
105
|
+
* The layer and the field share this rule and nothing may be added to one alone.
|
|
106
|
+
* Every property here is a property the mirror copies too \u2014 three elements, one
|
|
107
|
+
* typography, or the paint drifts.
|
|
108
|
+
*/
|
|
109
|
+
.litearea-layer,
|
|
110
|
+
.litearea-input {
|
|
111
|
+
box-sizing: border-box;
|
|
112
|
+
width: 100%;
|
|
113
|
+
margin: 0;
|
|
114
|
+
padding: var(--litearea-padding-block) var(--litearea-padding-inline);
|
|
115
|
+
border: none;
|
|
116
|
+
font-family: var(--litearea-font);
|
|
117
|
+
font-size: var(--litearea-font-size);
|
|
118
|
+
font-weight: 400;
|
|
119
|
+
font-style: normal;
|
|
120
|
+
font-stretch: normal;
|
|
121
|
+
font-variant-ligatures: none;
|
|
122
|
+
font-kerning: none;
|
|
123
|
+
font-feature-settings: "liga" 0, "calt" 0, "dlig" 0;
|
|
124
|
+
line-height: var(--litearea-line-height);
|
|
125
|
+
letter-spacing: normal;
|
|
126
|
+
word-spacing: normal;
|
|
127
|
+
text-transform: none;
|
|
128
|
+
text-indent: 0;
|
|
129
|
+
text-align: left;
|
|
130
|
+
direction: ltr;
|
|
131
|
+
tab-size: 2;
|
|
132
|
+
white-space: pre-wrap;
|
|
133
|
+
overflow-wrap: break-word;
|
|
134
|
+
word-break: break-word;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.litearea-layer {
|
|
138
|
+
position: absolute;
|
|
139
|
+
inset: 0;
|
|
140
|
+
overflow: hidden;
|
|
141
|
+
pointer-events: none;
|
|
142
|
+
user-select: none;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/*
|
|
146
|
+
* When the box is clamped to its maximum height the field grows a scrollbar, and a
|
|
147
|
+
* scrollbar narrows the text. If the layer kept the full width it would wrap
|
|
148
|
+
* differently from the field and every colour would slide off its character, so the
|
|
149
|
+
* field's measured scrollbar width is published as --litearea-scrollbar and added
|
|
150
|
+
* here. The value is 0 whenever no scrollbar is shown.
|
|
151
|
+
*/
|
|
152
|
+
.litearea-layer {
|
|
153
|
+
padding-right: calc(var(--litearea-padding-inline) + var(--litearea-scrollbar, 0px));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.litearea-paint {
|
|
157
|
+
position: relative;
|
|
158
|
+
min-height: 100%;
|
|
159
|
+
/* A zero-width space keeps the layer's last line box as tall as the field's:
|
|
160
|
+
a trailing newline would otherwise collapse in the paint alone, and the box
|
|
161
|
+
would jump the moment one was typed. */
|
|
162
|
+
will-change: transform;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.litearea-input {
|
|
166
|
+
position: relative;
|
|
167
|
+
display: block;
|
|
168
|
+
resize: none;
|
|
169
|
+
background: transparent;
|
|
170
|
+
color: transparent;
|
|
171
|
+
caret-color: var(--litearea-fg);
|
|
172
|
+
outline: none;
|
|
173
|
+
overflow-y: hidden;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.litearea-growable .litearea-input {
|
|
177
|
+
resize: none;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.litearea-resizable .litearea-input {
|
|
181
|
+
resize: vertical;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.litearea-input::placeholder {
|
|
185
|
+
color: var(--litearea-fg-dim);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.litearea-input::selection {
|
|
189
|
+
background: var(--litearea-selection);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.litearea-readonly .litearea-input {
|
|
193
|
+
caret-color: transparent;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/*
|
|
197
|
+
* The rules that spend the variables, generated from the same list that declares them. There is
|
|
198
|
+
* deliberately NO catch-all rule setting a property on every painted span: there was one, and a
|
|
199
|
+
* class plus an element outranks a bare class on specificity, so it silently switched off every
|
|
200
|
+
* squiggle in the library.
|
|
201
|
+
*
|
|
202
|
+
* A scope that is not in the list gets no colour from here, and a host writing a grammar of its
|
|
203
|
+
* own styles it with a plain rule \u2014 .litearea-scope-my-thing { color: \u2026 } \u2014 since nothing in
|
|
204
|
+
* this file competes for that selector.
|
|
205
|
+
*/
|
|
206
|
+
${scopeRules()}
|
|
207
|
+
|
|
208
|
+
.litearea-dec-effective {
|
|
209
|
+
border-radius: 3px;
|
|
210
|
+
background: var(--litearea-accent-soft);
|
|
211
|
+
box-shadow: 0 0 0 1px var(--litearea-accent-soft);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/* The four shapes a diagnostic can take. Wavy for the two that mean "fix this", dotted for
|
|
215
|
+
the two that mean "worth knowing" \u2014 the same distinction VSCode draws, and the reason
|
|
216
|
+
severity is a class rather than an inline colour. */
|
|
217
|
+
.litearea-diag-error {
|
|
218
|
+
text-decoration-line: underline;
|
|
219
|
+
text-decoration-style: wavy;
|
|
220
|
+
text-decoration-color: var(--litearea-error);
|
|
221
|
+
text-decoration-skip-ink: none;
|
|
222
|
+
text-underline-offset: 3px;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.litearea-diag-warning {
|
|
226
|
+
text-decoration-line: underline;
|
|
227
|
+
text-decoration-style: wavy;
|
|
228
|
+
text-decoration-color: var(--litearea-warning);
|
|
229
|
+
text-decoration-skip-ink: none;
|
|
230
|
+
text-underline-offset: 3px;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.litearea-diag-info {
|
|
234
|
+
text-decoration-line: underline;
|
|
235
|
+
text-decoration-style: dotted;
|
|
236
|
+
text-decoration-color: var(--litearea-info);
|
|
237
|
+
text-decoration-skip-ink: none;
|
|
238
|
+
text-underline-offset: 3px;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.litearea-diag-hint {
|
|
242
|
+
text-decoration-line: underline;
|
|
243
|
+
text-decoration-style: dotted;
|
|
244
|
+
text-decoration-color: var(--litearea-hint);
|
|
245
|
+
text-decoration-skip-ink: none;
|
|
246
|
+
text-underline-offset: 3px;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/* \u2500\u2500 the completion list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
250
|
+
|
|
251
|
+
/*
|
|
252
|
+
* The container holds two things and scrolls NEITHER of them: the list scrolls itself, and the
|
|
253
|
+
* documentation is pinned below it. Putting the documentation inside the scroll range \u2014 which is
|
|
254
|
+
* what this used to do \u2014 makes it unreachable with a long list and a long explanation: the
|
|
255
|
+
* arrows move the active row rather than the scrollbar, so a keyboard user never sees it, and a
|
|
256
|
+
* mouse user has to scroll down to read it and back up to reach the next row.
|
|
257
|
+
*/
|
|
258
|
+
.litearea-popup {
|
|
259
|
+
position: absolute;
|
|
260
|
+
z-index: 30;
|
|
261
|
+
display: none;
|
|
262
|
+
flex-direction: column;
|
|
263
|
+
max-width: 460px;
|
|
264
|
+
padding: 4px;
|
|
265
|
+
border: 1px solid var(--litearea-border);
|
|
266
|
+
border-radius: 10px;
|
|
267
|
+
background: var(--litearea-bg-raised);
|
|
268
|
+
box-shadow: var(--litearea-shadow);
|
|
269
|
+
font-family: var(--litearea-font);
|
|
270
|
+
font-size: 12px;
|
|
271
|
+
line-height: 18px;
|
|
272
|
+
color: var(--litearea-fg);
|
|
273
|
+
overflow: hidden;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.litearea-popup[data-open="true"] {
|
|
277
|
+
display: flex;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/* The rows, and the only part that scrolls. Its height is bounded so the documentation below
|
|
281
|
+
always has somewhere to live. */
|
|
282
|
+
.litearea-list {
|
|
283
|
+
min-height: 0;
|
|
284
|
+
max-height: 208px;
|
|
285
|
+
overflow-y: auto;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/*
|
|
289
|
+
* The explanation, pinned. Its own height is bounded and it scrolls ITSELF, so a long
|
|
290
|
+
* explanation stays readable while the rows stay put \u2014 and arrowing to the next row swaps the
|
|
291
|
+
* text in place instead of requiring a scroll back up.
|
|
292
|
+
*/
|
|
293
|
+
.litearea-docs {
|
|
294
|
+
flex: none;
|
|
295
|
+
max-height: 132px;
|
|
296
|
+
overflow-y: auto;
|
|
297
|
+
margin: 4px -4px -4px;
|
|
298
|
+
padding: 6px 10px;
|
|
299
|
+
border-top: 1px solid var(--litearea-border);
|
|
300
|
+
background: var(--litearea-bg);
|
|
301
|
+
border-radius: 0 0 10px 10px;
|
|
302
|
+
color: var(--litearea-fg);
|
|
303
|
+
white-space: pre-wrap;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.litearea-popup[data-docs="false"] .litearea-docs {
|
|
307
|
+
display: none;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.litearea-row {
|
|
311
|
+
display: flex;
|
|
312
|
+
align-items: baseline;
|
|
313
|
+
gap: 8px;
|
|
314
|
+
padding: 3px 6px;
|
|
315
|
+
border-radius: 6px;
|
|
316
|
+
cursor: pointer;
|
|
317
|
+
white-space: nowrap;
|
|
318
|
+
overflow: hidden;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.litearea-row[aria-selected="true"] {
|
|
322
|
+
background: var(--litearea-accent-soft);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.litearea-rowKind {
|
|
326
|
+
flex: none;
|
|
327
|
+
width: 7px;
|
|
328
|
+
height: 7px;
|
|
329
|
+
border-radius: 2px;
|
|
330
|
+
background: var(--litearea-fg-dim);
|
|
331
|
+
transform: translateY(-1px);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.litearea-kind-family { background: var(--litearea-scope-family-generic); }
|
|
335
|
+
.litearea-kind-generic { background: var(--litearea-scope-family-generic); }
|
|
336
|
+
.litearea-kind-weight { background: var(--litearea-scope-weight); }
|
|
337
|
+
.litearea-kind-state { background: var(--litearea-scope-state); }
|
|
338
|
+
.litearea-kind-property { background: var(--litearea-scope-property); }
|
|
339
|
+
.litearea-kind-value { background: var(--litearea-scope-value-shape); }
|
|
340
|
+
.litearea-kind-number { background: var(--litearea-scope-value-number); }
|
|
341
|
+
.litearea-kind-custom { background: var(--litearea-fg-dim); }
|
|
342
|
+
|
|
343
|
+
.litearea-rowLabel {
|
|
344
|
+
flex: 1 1 auto;
|
|
345
|
+
min-width: 0;
|
|
346
|
+
overflow: hidden;
|
|
347
|
+
text-overflow: ellipsis;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
.litearea-rowMatch {
|
|
351
|
+
color: var(--litearea-accent);
|
|
352
|
+
font-weight: 600;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
.litearea-rowDetail {
|
|
356
|
+
flex: none;
|
|
357
|
+
color: var(--litearea-fg-dim);
|
|
358
|
+
font-size: 11px;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.litearea-docsTitle {
|
|
362
|
+
font-weight: 600;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.litearea-docsDetail {
|
|
366
|
+
color: var(--litearea-fg-dim);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
.litearea-docsBody {
|
|
370
|
+
margin-top: 2px;
|
|
371
|
+
color: var(--litearea-fg-dim);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/* \u2500\u2500 the hover tooltip \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
375
|
+
|
|
376
|
+
.litearea-tooltip {
|
|
377
|
+
position: absolute;
|
|
378
|
+
z-index: 40;
|
|
379
|
+
display: none;
|
|
380
|
+
max-width: 340px;
|
|
381
|
+
padding: 6px 10px;
|
|
382
|
+
border: 1px solid var(--litearea-border);
|
|
383
|
+
border-radius: 8px;
|
|
384
|
+
background: var(--litearea-bg-raised);
|
|
385
|
+
box-shadow: var(--litearea-shadow);
|
|
386
|
+
font-family: var(--litearea-font);
|
|
387
|
+
font-size: 11px;
|
|
388
|
+
line-height: 16px;
|
|
389
|
+
color: var(--litearea-fg);
|
|
390
|
+
pointer-events: none;
|
|
391
|
+
white-space: pre-wrap;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
.litearea-tooltip[data-open="true"] {
|
|
395
|
+
display: block;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.litearea-tooltipTitle {
|
|
399
|
+
font-weight: 600;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.litearea-tooltipDetail {
|
|
403
|
+
color: var(--litearea-fg-dim);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.litearea-tooltipBody {
|
|
407
|
+
margin-top: 3px;
|
|
408
|
+
color: var(--litearea-fg-dim);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
.litearea-srOnly {
|
|
412
|
+
position: absolute;
|
|
413
|
+
width: 1px;
|
|
414
|
+
height: 1px;
|
|
415
|
+
padding: 0;
|
|
416
|
+
margin: -1px;
|
|
417
|
+
overflow: hidden;
|
|
418
|
+
clip: rect(0, 0, 0, 0);
|
|
419
|
+
white-space: nowrap;
|
|
420
|
+
border: 0;
|
|
421
|
+
}
|
|
422
|
+
`.trim();
|
|
423
|
+
function injectStyles(ownerDocument, nonce) {
|
|
424
|
+
if (ownerDocument === null || ownerDocument === void 0) return void 0;
|
|
425
|
+
const existing = ownerDocument.querySelector("style[data-litearea-styles]");
|
|
426
|
+
if (existing !== null) return existing;
|
|
427
|
+
const style = ownerDocument.createElement("style");
|
|
428
|
+
style.dataset.liteareaStyles = "";
|
|
429
|
+
if (nonce !== void 0) style.nonce = nonce;
|
|
430
|
+
style.textContent = LITEAREA_STYLES;
|
|
431
|
+
const head = ownerDocument.head ?? ownerDocument.documentElement;
|
|
432
|
+
if (head === null || head === void 0) return void 0;
|
|
433
|
+
head.appendChild(style);
|
|
434
|
+
return style;
|
|
435
|
+
}
|
|
436
|
+
function scopeClass(scope) {
|
|
437
|
+
const folded = scope.replace(/[^A-Za-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
438
|
+
return folded === "" ? "litearea-scope-text" : `litearea-scope-${folded}`;
|
|
439
|
+
}
|
|
440
|
+
function decorationClass(kind) {
|
|
441
|
+
return `litearea-dec-${kind.replace(/[^A-Za-z0-9_-]+/g, "-")}`;
|
|
442
|
+
}
|
|
443
|
+
function severityClass(severity) {
|
|
444
|
+
return `litearea-diag-${severity.replace(/[^A-Za-z0-9_-]+/g, "-")}`;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
exports.LITEAREA_STYLES = LITEAREA_STYLES;
|
|
448
|
+
exports.decorationClass = decorationClass;
|
|
449
|
+
exports.injectStyles = injectStyles;
|
|
450
|
+
exports.scopeClass = scopeClass;
|
|
451
|
+
exports.severityClass = severityClass;
|
|
452
|
+
//# sourceMappingURL=styles.cjs.map
|
|
453
|
+
//# sourceMappingURL=styles.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/styles.ts"],"names":[],"mappings":"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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgItB,YAAY;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAwNZ,IAAA;AAYK,SAAS,YAAA,CACd,eACA,KAAA,EAC8B;AAC9B,EAAA,IAAI,aAAA,KAAkB,IAAA,IAAQ,aAAA,KAAkB,MAAA,EAAW,OAAO,MAAA;AAClE,EAAA,MAAM,QAAA,GAAW,aAAA,CAAc,aAAA,CAAgC,6BAA6B,CAAA;AAC5F,EAAA,IAAI,QAAA,KAAa,MAAM,OAAO,QAAA;AAC9B,EAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,aAAA,CAAc,OAAO,CAAA;AACjD,EAAA,KAAA,CAAM,QAAQ,cAAA,GAAiB,EAAA;AAC/B,EAAA,IAAI,KAAA,KAAU,MAAA,EAAW,KAAA,CAAM,KAAA,GAAQ,KAAA;AACvC,EAAA,KAAA,CAAM,WAAA,GAAc,eAAA;AACpB,EAAA,MAAM,IAAA,GAAO,aAAA,CAAc,IAAA,IAAQ,aAAA,CAAc,eAAA;AACjD,EAAA,IAAI,IAAA,KAAS,IAAA,IAAQ,IAAA,KAAS,MAAA,EAAW,OAAO,MAAA;AAChD,EAAA,IAAA,CAAK,YAAY,KAAK,CAAA;AACtB,EAAA,OAAO,KAAA;AACT;AAYO,SAAS,WAAW,KAAA,EAAuB;AAChD,EAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,kBAAA,EAAoB,GAAG,CAAA,CAAE,OAAA,CAAQ,YAAY,EAAE,CAAA;AAC5E,EAAA,OAAO,MAAA,KAAW,EAAA,GAAK,qBAAA,GAAwB,CAAA,eAAA,EAAkB,MAAM,CAAA,CAAA;AACzE;AAGO,SAAS,gBAAgB,IAAA,EAAsB;AACpD,EAAA,OAAO,CAAA,aAAA,EAAgB,IAAA,CAAK,OAAA,CAAQ,kBAAA,EAAoB,GAAG,CAAC,CAAA,CAAA;AAC9D;AAGO,SAAS,cAAc,QAAA,EAA0B;AACtD,EAAA,OAAO,CAAA,cAAA,EAAiB,QAAA,CAAS,OAAA,CAAQ,kBAAA,EAAoB,GAAG,CAAC,CAAA,CAAA;AACnE","file":"styles.cjs","sourcesContent":["// ─── styles: the one stylesheet ─────────────────────────────────────────────\n//\n// The CSS lives in a TypeScript string so it can be injected with no build step\n// and no CSS loader, which is what keeps the library usable from a plain script\n// tag. `scripts/build-css.mjs` also writes it out as `dist/styles.css` for the\n// hosts that would rather link it, from this same string, so the two can never\n// disagree.\n//\n// The alignment contract\n// ----------------------\n// The painted layer sits behind the real textarea and draws the same characters, so it may\n// change only what does not move a glyph: colour, background, and text-decoration. Anything\n// that changes an advance — a different font, a weight, letter-spacing, a font-feature —\n// slides the paint off the character it belongs to, and by a different amount on every\n// character, so it reads as a rendering glitch rather than as a styling mistake.\n//\n// The two elements therefore share ONE rule for their typography, and that rule is the only\n// thing that has to hold. THE FONT ITSELF IS THE HOST'S CHOICE: a proportional face aligns just\n// as well as a monospace one, because the layer, the field, and the measuring mirror all read\n// the same computed font. `--litearea-font` is a variable like any other.\n//\n// What is NOT the host's choice is ligatures and kerning, which are forced off, and the reason\n// is subtler than \"a ligature would look wrong\". A ligature draws one glyph where the field\n// holds two characters — and the layer splits its spans wherever a diagnostic or a decoration\n// begins, which cuts a ligature in half. The field would then render one glyph and the layer\n// two, at different widths, and the rest of the line would slide. Turning them off removes the\n// possibility rather than relying on no span boundary ever landing inside a pair.\n\n/**\n * One colour per scope, in one list, because the variables and the rules that use them MUST\n * agree and once did not.\n *\n * Twenty-nine scope variables were declared here with no rule anywhere that consumed them. The\n * tokenizer painted the right classes, the variables were documented, the stylesheet looked\n * complete — and every scope rendered in the inherited text colour, so the editor had no syntax\n * colouring at all. Nothing in the DOM revealed it: the spans were correct. Generating both\n * halves from this list is the fix, and it is the kind of drift a browser check cannot catch\n * either, since a colourless token is a perfectly ordinary thing to find.\n *\n * A key is the FOLDED scope name, which is what a scope becomes as a class: `value.shape` is\n * written `value-shape` here because `scopeClass` turns its dots into hyphens.\n */\nconst SCOPE_PALETTE: ReadonlyArray<{ scope: string; light: string; dark?: string }> = [\n { scope: 'text', light: 'var(--litearea-fg)' },\n { scope: 'word', light: 'var(--litearea-fg)' },\n { scope: 'family', light: 'var(--litearea-fg)' },\n { scope: 'family-generic', light: '#7c3aed', dark: '#c4a2ff' },\n { scope: 'family-unknown', light: 'var(--litearea-warning)' },\n { scope: 'family-unclosed', light: 'var(--litearea-error)' },\n { scope: 'weight', light: 'var(--litearea-accent)' },\n { scope: 'weight-missing', light: 'var(--litearea-warning)' },\n { scope: 'state', light: 'var(--litearea-accent)' },\n { scope: 'property', light: '#7c3aed', dark: '#c4a2ff' },\n { scope: 'operator', light: 'var(--litearea-fg-dim)' },\n { scope: 'separator', light: 'var(--litearea-fg-dim)' },\n { scope: 'value-shape', light: '#0f766e', dark: '#5eead4' },\n { scope: 'value-color', light: '#0f766e', dark: '#5eead4' },\n { scope: 'value-pattern', light: '#0f766e', dark: '#5eead4' },\n { scope: 'value-motion', light: '#0f766e', dark: '#5eead4' },\n { scope: 'value-number', light: '#b45309', dark: '#fbbf24' },\n { scope: 'comment', light: 'var(--litearea-fg-dim)' },\n { scope: 'invalid', light: 'var(--litearea-error)' },\n { scope: 'keyword', light: 'var(--litearea-accent)' },\n { scope: 'string', light: '#0f766e', dark: '#5eead4' },\n { scope: 'number', light: '#b45309', dark: '#fbbf24' },\n]\n\n/**\n * The variable declarations for one colour scheme.\n * @param scheme - `light` declares every scope; `dark` declares only those that differ.\n * @returns one CSS declaration per line.\n */\nfunction scopeVariables(scheme: 'light' | 'dark'): string {\n return SCOPE_PALETTE.filter((entry) => scheme === 'light' || entry.dark !== undefined)\n .map((entry) => {\n const value = scheme === 'light' ? entry.light : entry.dark\n return ` --litearea-scope-${entry.scope}: ${String(value)};`\n })\n .join('\\n')\n}\n\n/**\n * The rules that spend those variables.\n * @returns one CSS rule per line.\n */\nfunction scopeRules(): string {\n return SCOPE_PALETTE.map(\n (entry) =>\n `.litearea-scope-${entry.scope} { color: var(--litearea-scope-${entry.scope}); }`,\n ).join('\\n')\n}\n\n/** Everything a scope or a mark is painted with comes from one of these. */\nexport const LITEAREA_STYLES = `\n.litearea {\n --litearea-font: ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace;\n --litearea-font-size: 13px;\n --litearea-line-height: 20px;\n --litearea-padding-block: 6px;\n --litearea-padding-inline: 10px;\n --litearea-radius: 8px;\n --litearea-fg: #1f2328;\n --litearea-fg-dim: #6b7280;\n --litearea-fg-strong: #111827;\n --litearea-bg: #ffffff;\n --litearea-bg-raised: #ffffff;\n --litearea-border: #d8dbe0;\n --litearea-border-focus: #4d6bfe;\n --litearea-accent: #4d6bfe;\n --litearea-accent-soft: rgba(77, 107, 254, 0.12);\n --litearea-selection: rgba(77, 107, 254, 0.22);\n --litearea-error: #e5484d;\n --litearea-warning: #d97706;\n --litearea-info: #4d6bfe;\n --litearea-hint: #8b8f97;\n --litearea-shadow: 0 6px 24px rgba(15, 23, 42, 0.14);\n\n${scopeVariables('light')}\n\n position: relative;\n display: block;\n color: var(--litearea-fg);\n}\n\n@media (prefers-color-scheme: dark) {\n .litearea {\n --litearea-fg: #e6e8eb;\n --litearea-fg-dim: #8b919b;\n --litearea-fg-strong: #ffffff;\n --litearea-bg: #1b1e24;\n --litearea-bg-raised: #23262c;\n --litearea-border: #363b44;\n${scopeVariables('dark')}\n --litearea-error: #ff6b6b;\n --litearea-warning: #f59e0b;\n --litearea-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);\n }\n}\n\n/* ── the box ─────────────────────────────────────────────────────────────── */\n\n.litearea-box {\n position: relative;\n display: block;\n border: 1px solid var(--litearea-border);\n border-radius: var(--litearea-radius);\n background: var(--litearea-bg);\n transition: border-color 120ms ease;\n}\n\n.litearea-box:focus-within {\n border-color: var(--litearea-border-focus);\n}\n\n.litearea-invalid .litearea-box {\n border-color: var(--litearea-error);\n}\n\n/*\n * The layer and the field share this rule and nothing may be added to one alone.\n * Every property here is a property the mirror copies too — three elements, one\n * typography, or the paint drifts.\n */\n.litearea-layer,\n.litearea-input {\n box-sizing: border-box;\n width: 100%;\n margin: 0;\n padding: var(--litearea-padding-block) var(--litearea-padding-inline);\n border: none;\n font-family: var(--litearea-font);\n font-size: var(--litearea-font-size);\n font-weight: 400;\n font-style: normal;\n font-stretch: normal;\n font-variant-ligatures: none;\n font-kerning: none;\n font-feature-settings: \"liga\" 0, \"calt\" 0, \"dlig\" 0;\n line-height: var(--litearea-line-height);\n letter-spacing: normal;\n word-spacing: normal;\n text-transform: none;\n text-indent: 0;\n text-align: left;\n direction: ltr;\n tab-size: 2;\n white-space: pre-wrap;\n overflow-wrap: break-word;\n word-break: break-word;\n}\n\n.litearea-layer {\n position: absolute;\n inset: 0;\n overflow: hidden;\n pointer-events: none;\n user-select: none;\n}\n\n/*\n * When the box is clamped to its maximum height the field grows a scrollbar, and a\n * scrollbar narrows the text. If the layer kept the full width it would wrap\n * differently from the field and every colour would slide off its character, so the\n * field's measured scrollbar width is published as --litearea-scrollbar and added\n * here. The value is 0 whenever no scrollbar is shown.\n */\n.litearea-layer {\n padding-right: calc(var(--litearea-padding-inline) + var(--litearea-scrollbar, 0px));\n}\n\n.litearea-paint {\n position: relative;\n min-height: 100%;\n /* A zero-width space keeps the layer's last line box as tall as the field's:\n a trailing newline would otherwise collapse in the paint alone, and the box\n would jump the moment one was typed. */\n will-change: transform;\n}\n\n.litearea-input {\n position: relative;\n display: block;\n resize: none;\n background: transparent;\n color: transparent;\n caret-color: var(--litearea-fg);\n outline: none;\n overflow-y: hidden;\n}\n\n.litearea-growable .litearea-input {\n resize: none;\n}\n\n.litearea-resizable .litearea-input {\n resize: vertical;\n}\n\n.litearea-input::placeholder {\n color: var(--litearea-fg-dim);\n}\n\n.litearea-input::selection {\n background: var(--litearea-selection);\n}\n\n.litearea-readonly .litearea-input {\n caret-color: transparent;\n}\n\n/*\n * The rules that spend the variables, generated from the same list that declares them. There is\n * deliberately NO catch-all rule setting a property on every painted span: there was one, and a\n * class plus an element outranks a bare class on specificity, so it silently switched off every\n * squiggle in the library.\n *\n * A scope that is not in the list gets no colour from here, and a host writing a grammar of its\n * own styles it with a plain rule — .litearea-scope-my-thing { color: … } — since nothing in\n * this file competes for that selector.\n */\n${scopeRules()}\n\n.litearea-dec-effective {\n border-radius: 3px;\n background: var(--litearea-accent-soft);\n box-shadow: 0 0 0 1px var(--litearea-accent-soft);\n}\n\n/* The four shapes a diagnostic can take. Wavy for the two that mean \"fix this\", dotted for\n the two that mean \"worth knowing\" — the same distinction VSCode draws, and the reason\n severity is a class rather than an inline colour. */\n.litearea-diag-error {\n text-decoration-line: underline;\n text-decoration-style: wavy;\n text-decoration-color: var(--litearea-error);\n text-decoration-skip-ink: none;\n text-underline-offset: 3px;\n}\n\n.litearea-diag-warning {\n text-decoration-line: underline;\n text-decoration-style: wavy;\n text-decoration-color: var(--litearea-warning);\n text-decoration-skip-ink: none;\n text-underline-offset: 3px;\n}\n\n.litearea-diag-info {\n text-decoration-line: underline;\n text-decoration-style: dotted;\n text-decoration-color: var(--litearea-info);\n text-decoration-skip-ink: none;\n text-underline-offset: 3px;\n}\n\n.litearea-diag-hint {\n text-decoration-line: underline;\n text-decoration-style: dotted;\n text-decoration-color: var(--litearea-hint);\n text-decoration-skip-ink: none;\n text-underline-offset: 3px;\n}\n\n/* ── the completion list ─────────────────────────────────────────────────── */\n\n/*\n * The container holds two things and scrolls NEITHER of them: the list scrolls itself, and the\n * documentation is pinned below it. Putting the documentation inside the scroll range — which is\n * what this used to do — makes it unreachable with a long list and a long explanation: the\n * arrows move the active row rather than the scrollbar, so a keyboard user never sees it, and a\n * mouse user has to scroll down to read it and back up to reach the next row.\n */\n.litearea-popup {\n position: absolute;\n z-index: 30;\n display: none;\n flex-direction: column;\n max-width: 460px;\n padding: 4px;\n border: 1px solid var(--litearea-border);\n border-radius: 10px;\n background: var(--litearea-bg-raised);\n box-shadow: var(--litearea-shadow);\n font-family: var(--litearea-font);\n font-size: 12px;\n line-height: 18px;\n color: var(--litearea-fg);\n overflow: hidden;\n}\n\n.litearea-popup[data-open=\"true\"] {\n display: flex;\n}\n\n/* The rows, and the only part that scrolls. Its height is bounded so the documentation below\n always has somewhere to live. */\n.litearea-list {\n min-height: 0;\n max-height: 208px;\n overflow-y: auto;\n}\n\n/*\n * The explanation, pinned. Its own height is bounded and it scrolls ITSELF, so a long\n * explanation stays readable while the rows stay put — and arrowing to the next row swaps the\n * text in place instead of requiring a scroll back up.\n */\n.litearea-docs {\n flex: none;\n max-height: 132px;\n overflow-y: auto;\n margin: 4px -4px -4px;\n padding: 6px 10px;\n border-top: 1px solid var(--litearea-border);\n background: var(--litearea-bg);\n border-radius: 0 0 10px 10px;\n color: var(--litearea-fg);\n white-space: pre-wrap;\n}\n\n.litearea-popup[data-docs=\"false\"] .litearea-docs {\n display: none;\n}\n\n.litearea-row {\n display: flex;\n align-items: baseline;\n gap: 8px;\n padding: 3px 6px;\n border-radius: 6px;\n cursor: pointer;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.litearea-row[aria-selected=\"true\"] {\n background: var(--litearea-accent-soft);\n}\n\n.litearea-rowKind {\n flex: none;\n width: 7px;\n height: 7px;\n border-radius: 2px;\n background: var(--litearea-fg-dim);\n transform: translateY(-1px);\n}\n\n.litearea-kind-family { background: var(--litearea-scope-family-generic); }\n.litearea-kind-generic { background: var(--litearea-scope-family-generic); }\n.litearea-kind-weight { background: var(--litearea-scope-weight); }\n.litearea-kind-state { background: var(--litearea-scope-state); }\n.litearea-kind-property { background: var(--litearea-scope-property); }\n.litearea-kind-value { background: var(--litearea-scope-value-shape); }\n.litearea-kind-number { background: var(--litearea-scope-value-number); }\n.litearea-kind-custom { background: var(--litearea-fg-dim); }\n\n.litearea-rowLabel {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.litearea-rowMatch {\n color: var(--litearea-accent);\n font-weight: 600;\n}\n\n.litearea-rowDetail {\n flex: none;\n color: var(--litearea-fg-dim);\n font-size: 11px;\n}\n\n.litearea-docsTitle {\n font-weight: 600;\n}\n\n.litearea-docsDetail {\n color: var(--litearea-fg-dim);\n}\n\n.litearea-docsBody {\n margin-top: 2px;\n color: var(--litearea-fg-dim);\n}\n\n/* ── the hover tooltip ───────────────────────────────────────────────────── */\n\n.litearea-tooltip {\n position: absolute;\n z-index: 40;\n display: none;\n max-width: 340px;\n padding: 6px 10px;\n border: 1px solid var(--litearea-border);\n border-radius: 8px;\n background: var(--litearea-bg-raised);\n box-shadow: var(--litearea-shadow);\n font-family: var(--litearea-font);\n font-size: 11px;\n line-height: 16px;\n color: var(--litearea-fg);\n pointer-events: none;\n white-space: pre-wrap;\n}\n\n.litearea-tooltip[data-open=\"true\"] {\n display: block;\n}\n\n.litearea-tooltipTitle {\n font-weight: 600;\n}\n\n.litearea-tooltipDetail {\n color: var(--litearea-fg-dim);\n}\n\n.litearea-tooltipBody {\n margin-top: 3px;\n color: var(--litearea-fg-dim);\n}\n\n.litearea-srOnly {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n`.trim()\n\n/**\n * Put the stylesheet in a document, once.\n *\n * Marked with a data attribute so two editors on one page, or two copies of the\n * library, do not stack two identical sheets — and so a host can find and replace\n * it.\n * @param ownerDocument - the document to install into.\n * @param nonce - an optional CSP nonce for the style element.\n * @returns the style element, or undefined when there is no document.\n */\nexport function injectStyles(\n ownerDocument: Document,\n nonce?: string,\n): HTMLStyleElement | undefined {\n if (ownerDocument === null || ownerDocument === undefined) return undefined\n const existing = ownerDocument.querySelector<HTMLStyleElement>('style[data-litearea-styles]')\n if (existing !== null) return existing\n const style = ownerDocument.createElement('style')\n style.dataset.liteareaStyles = ''\n if (nonce !== undefined) style.nonce = nonce\n style.textContent = LITEAREA_STYLES\n const head = ownerDocument.head ?? ownerDocument.documentElement\n if (head === null || head === undefined) return undefined\n head.appendChild(style)\n return style\n}\n\n/**\n * The class a scope is painted with.\n *\n * Dots and other punctuation are folded to hyphens, because a scope like\n * `value.shape` is a nice name to write and a terrible one to select: the CSS\n * would need a backslash before the dot at every use, and one forgotten escape\n * silently paints nothing.\n * @param scope - the scope name.\n * @returns the class name.\n */\nexport function scopeClass(scope: string): string {\n const folded = scope.replace(/[^A-Za-z0-9_-]+/g, '-').replace(/^-+|-+$/g, '')\n return folded === '' ? 'litearea-scope-text' : `litearea-scope-${folded}`\n}\n\n/** The class a decoration kind is painted with. */\nexport function decorationClass(kind: string): string {\n return `litearea-dec-${kind.replace(/[^A-Za-z0-9_-]+/g, '-')}`\n}\n\n/** The class a diagnostic severity is underlined with. */\nexport function severityClass(severity: string): string {\n return `litearea-diag-${severity.replace(/[^A-Za-z0-9_-]+/g, '-')}`\n}\n"]}
|