@animus-ui/properties 0.1.20 → 0.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,160 @@
1
- export { SHORTHAND_PROPERTIES } from './shorthands';
2
- export { isUnitlessProperty, UNITLESS_PROPERTIES } from './unitless';
3
- export { dependsOnContext, foldInitialValue, registeredInitialValue, substitutesValue, } from './registration-values.js';
4
- export type { FoldedInitialValue } from './registration-values.js';
1
+ //#region src/shorthands.d.ts
2
+ /**
3
+ * Covers only shorthands registered in the prop system, not all CSS shorthands.
4
+ */
5
+ export declare const SHORTHAND_PROPERTIES: readonly ['border', 'borderTop', 'borderBottom', 'borderLeft', 'borderRight', 'borderWidth', 'borderStyle', 'borderColor', 'background', 'flex', 'margin', 'padding', 'transition', 'gap', 'grid', 'gridArea', 'gridColumn', 'gridRow', 'gridTemplate', 'overflow'];
6
+ //#endregion
7
+ //#region src/unitless.d.ts
8
+ export declare const UNITLESS_PROPERTIES: Set<string>;
9
+ /** Accepts either spelling: `line-height` or `lineHeight`,
10
+ * `-webkit-line-clamp` or `WebkitLineClamp`. */
11
+ export declare function isUnitlessProperty(property: string): boolean;
12
+ //#endregion
13
+ //#region src/css-tokens.d.ts
14
+ /**
15
+ * CSS tokens as CSS Syntax Level 3 reads them, with their source offsets.
16
+ * Comments are trivia and make no token. Identifiers, function names,
17
+ * at-keywords, hashes and units are decoded, escapes included. A quoted
18
+ * string and an unquoted `url()` are each one opaque token, so nothing inside
19
+ * them reads as a name or a function.
20
+ */
21
+ type CssTokenType = 'whitespace' | 'ident' | 'function' | 'at-keyword' | 'hash' | 'string' | 'bad-string' | 'url' | 'bad-url' | 'number' | 'percentage' | 'dimension' | 'delim' | 'CDO' | 'CDC' | '(' | ')' | '[' | ']' | '{' | '}' | ',' | ':' | ';';
22
+ interface CssToken {
23
+ type: CssTokenType;
24
+ start: number;
25
+ end: number;
26
+ /** The decoded name of an ident, function, at-keyword or hash, the
27
+ * decoded unit of a dimension, or a delim's character; otherwise `''`. */
28
+ value: string;
29
+ /** A number, percentage or dimension's numeric value; otherwise `0`. */
30
+ number: number;
31
+ }
32
+ /** The identifier starting at `index`, decoded, or `undefined` when none
33
+ * starts there. */
34
+ export declare function identifierAt(css: string, index: number): {
35
+ name: string;
36
+ end: number;
37
+ } | undefined;
38
+ /** `name` decoded when it is one whole identifier, else as written. */
39
+ export declare function decodedIdentifier(name: string): string;
40
+ /** Every token of `css`, in order. */
41
+ export declare function tokenize(css: string): CssToken[];
42
+ /** A component value: a function, or a `()`, `[]` or `{}` block, with its
43
+ * contents, or a single token. Offsets span the whole value. */
44
+ type ComponentValue = {
45
+ kind: 'block';
46
+ /** The function token, or the `(`, `[` or `{` token. */
47
+ open: CssToken;
48
+ /** `undefined` when the block is never closed. */
49
+ close: CssToken | undefined;
50
+ children: ComponentValue[];
51
+ start: number;
52
+ end: number;
53
+ } | {
54
+ kind: 'token';
55
+ token: CssToken;
56
+ start: number;
57
+ end: number;
58
+ };
59
+ /**
60
+ * `tokens` as component values. Only the innermost open block's own closer
61
+ * closes it; any other closer stays a token, and a block left open closes at
62
+ * the end, as CSS reads them.
63
+ */
64
+ export declare function componentValues(tokens: readonly CssToken[]): ComponentValue[];
65
+ /** Whether `test` holds for a value at any depth. */
66
+ export declare function someValue(values: readonly ComponentValue[], test: (value: ComponentValue) => boolean): boolean;
67
+ /** A `var()` read: the decoded custom-property name, the call's offsets,
68
+ * and its fallback's: after the comma, the first value's start, and before
69
+ * the closing parenthesis. */
70
+ interface VariableRead {
71
+ name: string;
72
+ start: number;
73
+ end: number;
74
+ fallback: {
75
+ start: number;
76
+ first: number;
77
+ end: number;
78
+ } | undefined;
79
+ }
80
+ /** Whether `value` is whitespace. */
81
+ export declare const isSpace: (value: ComponentValue | undefined) => boolean;
82
+ /**
83
+ * Every `var()` call in `values` at any depth, fallbacks included, outer
84
+ * calls first: a function whose decoded name is `var` in any case, and whose
85
+ * first argument is a custom-property name.
86
+ */
87
+ export declare function variableReads(values: readonly ComponentValue[]): VariableRead[];
88
+ /** How a value spells the `!important` it ends with: `hidden !important`,
89
+ * any case and spacing, or the shorthand `hidden!`. */
90
+ type ImportantSpelling = 'important' | 'shorthand';
91
+ interface ImportantPriority {
92
+ spelling: ImportantSpelling;
93
+ /** Where the value before the priority ends. */
94
+ end: number;
95
+ }
96
+ /**
97
+ * The `!important` `css` ends with; kept in step with `important_priority`
98
+ * in the Rust engine. The value has one `!`, a delim token, so a `!` inside
99
+ * a string, a `url()` or an escape is no priority, and neither is a lone `!`
100
+ * or `!important`.
101
+ */
102
+ export declare function importantPriority(css: string): ImportantPriority | undefined;
103
+ //#endregion
104
+ //#region src/registration-values.d.ts
105
+ /**
106
+ * Reads a custom-property registration's initial value as CSS component
107
+ * values: what it substitutes, which units make it depend on context, and
108
+ * what an all-absolute math function computes to. Tokens come from the shared
109
+ * CSS reader, so comments are trivia, quoted strings and `url()` stay text,
110
+ * and escaped names are decoded.
111
+ */
112
+ /** Whether `value` substitutes another value (`var()`, `env()`, `attr()`),
113
+ * which no registration's initial value may. */
114
+ export declare function substitutesValue(value: string): boolean;
115
+ /** Whether `value` uses a font- or container-relative unit, inside math
116
+ * functions too, which makes a typed initial value depend on context. */
117
+ export declare function dependsOnContext(value: string): boolean;
118
+ /** What an all-absolute math expression computes to. */
119
+ interface Computed {
120
+ type: 'number' | 'length' | 'angle' | 'time' | 'resolution';
121
+ value: number;
122
+ }
123
+ /** What a math initial value folds to. */
124
+ type FoldedInitialValue =
125
+ /** The computed value the syntax accepts, as CSS text such as `1`, `16px`
126
+ * or `90deg`. */
127
+ {
128
+ kind: 'folded';
129
+ text: string;
130
+ } |
131
+ /** A computed value no syntax alternative accepts. */
132
+ {
133
+ kind: 'rejected';
134
+ text: string;
135
+ type: Computed['type'];
136
+ } |
137
+ /** Math that breaks CSS calculation syntax, which browsers ignore. */
138
+ {
139
+ kind: 'invalid';
140
+ reason: string;
141
+ } |
142
+ /** An infinite or NaN result: browsers clamp it, and it has no plain
143
+ * value to write. */
144
+ {
145
+ kind: 'not-finite';
146
+ };
147
+ /**
148
+ * The computed value of an initial value that is one math function (`calc()`,
149
+ * `min()`, `max()`, `clamp()`) over numbers and absolute units, such as
150
+ * `calc(1px / 1px)` → `1`. The browser computes the same value, and CSS
151
+ * tooling that cannot parse the function in that position reads the result.
152
+ * The syntax's alternatives are tried in their declared order, and an
153
+ * `<integer>` one rounds a number result to the nearest integer, halves
154
+ * toward positive infinity, as CSS does. `undefined` for anything else, and
155
+ * for the universal syntax, whose initial value is kept as written.
156
+ */
157
+ export declare function foldInitialValue(syntax: string, initialValue: string): FoldedInitialValue | undefined;
158
+ //#endregion
159
+ export type { ComponentValue, CssToken, FoldedInitialValue, ImportantPriority, ImportantSpelling, VariableRead };
5
160
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/shorthands.ts","../src/unitless.ts","../src/css-tokens.ts","../src/registration-values.ts"],"mappings":";;;;qBAGa;;;qBCHA,qBAAmB;;;wBAgHhB,mBAAmB;;;;;;;;;;KCxGvB;UA0BK;EACf,MAAM;EACN;EACA;;;EAGA;;EAEA;;;;wBAiFc,aACd,aACA;EACG;EAAc;;;wBAOH,kBAAkB;;wBAyFlB,SAAS,cAAc;;;KA0E3B;EAEN;;EAEA,MAAM;;EAEN,OAAO;EACP,UAAU;EACV;EACA;;EAEA;EAAe,OAAO;EAAU;EAAe;;;;;;;wBAgBrC,gBAAgB,iBAAiB,aAAa;;wBAoC9C,UACd,iBAAiB,kBACjB,OAAO,OAAO;;;;UAWC;EACf;EACA;EACA;EACA;IAAY;IAAe;IAAe;;;;qBAI/B,UAAO,OAAW;;;;;;wBAQf,cACd,iBAAiB,mBAChB;;;KAiCS;UAEK;EACf,UAAU;;EAEV;;;;;;;;wBASc,kBAAkB,cAAc;;;;;;;;;;;;wBCtZhC,iBAAiB;;;wBA6BjB,iBAAiB;;UAWvB;EACR;EACA;;;KA+NU;;;;EAGN;EAAgB;;;;EAEhB;EAAkB;EAAc,MAAM;;;;EAEtC;EAAiB;;;;;EAGjB;;;;;;;;;;;;wBAYU,iBACd,gBACA,uBACC"}
package/dist/index.js CHANGED
@@ -71,97 +71,415 @@ const UNITLESS_PROPERTIES = /* @__PURE__ */ new Set([
71
71
  "tab-size",
72
72
  "widows",
73
73
  "z-index",
74
- "zoom"
74
+ "zoom",
75
+ "-moz-animation-iteration-count",
76
+ "-moz-animation-name",
77
+ "-moz-box-flex",
78
+ "-moz-box-ordinal-group",
79
+ "-moz-column-count",
80
+ "-moz-columns",
81
+ "-moz-opacity",
82
+ "-moz-tab-size",
83
+ "-ms-flex",
84
+ "-ms-flex-positive",
85
+ "-ms-order",
86
+ "-o-animation-iteration-count",
87
+ "-o-animation-name",
88
+ "-o-tab-size",
89
+ "-webkit-animation-iteration-count",
90
+ "-webkit-animation-name",
91
+ "-webkit-border-image-slice",
92
+ "-webkit-box-flex",
93
+ "-webkit-box-flex-group",
94
+ "-webkit-box-ordinal-group",
95
+ "-webkit-column-count",
96
+ "-webkit-columns",
97
+ "-webkit-flex",
98
+ "-webkit-flex-grow",
99
+ "-webkit-flex-shrink",
100
+ "-webkit-line-clamp",
101
+ "-webkit-order"
75
102
  ]);
103
+ /**
104
+ * A style key's vendor prefix and the CSS prefix it stands for:
105
+ * `WebkitLineClamp` is `-webkit-line-clamp`, `msFlex` is `-ms-flex`. The
106
+ * extractor reads this table through `property_table.json`.
107
+ */
108
+ const VENDOR_PREFIXES = [
109
+ ["Webkit", "-webkit-"],
110
+ ["Moz", "-moz-"],
111
+ ["ms", "-ms-"],
112
+ ["O", "-o-"]
113
+ ];
114
+ /** The camelCase style key of a CSS property name. */
115
+ function styleKey(property) {
116
+ const vendor = VENDOR_PREFIXES.find(([, prefix]) => property.startsWith(prefix));
117
+ const [key, rest] = vendor ? [vendor[0], property.slice(vendor[1].length - 1)] : ["", property];
118
+ return key + rest.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
119
+ }
76
120
  const UNITLESS_PROPERTY_SPELLINGS = /* @__PURE__ */ new Set();
77
121
  for (const property of UNITLESS_PROPERTIES) {
78
122
  UNITLESS_PROPERTY_SPELLINGS.add(property);
79
- UNITLESS_PROPERTY_SPELLINGS.add(property.replace(/-([a-z])/g, (_, char) => char.toUpperCase()));
123
+ UNITLESS_PROPERTY_SPELLINGS.add(styleKey(property));
80
124
  }
81
- /** Accepts either spelling: `line-height` or `lineHeight`. */
125
+ /** Accepts either spelling: `line-height` or `lineHeight`,
126
+ * `-webkit-line-clamp` or `WebkitLineClamp`. */
82
127
  function isUnitlessProperty(property) {
83
128
  return UNITLESS_PROPERTY_SPELLINGS.has(property);
84
129
  }
85
130
  //#endregion
86
- //#region src/registration-values.ts
87
- const NUMBER = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?/i;
88
- const IDENT = /^(?:--|-?[a-zA-Z_])[\w-]*/;
89
- /** The component values of `text`; `undefined` when it does not parse. */
90
- function parse(text) {
91
- let at = 0;
92
- function values(nested) {
93
- const out = [];
94
- while (at < text.length) {
95
- const char = text[at];
96
- if (/\s/.test(char)) {
97
- at += 1;
98
- continue;
99
- }
100
- if (char === ")") {
101
- at += 1;
102
- return nested ? out : void 0;
103
- }
104
- if (char === "\"" || char === "'") {
105
- const end = stringEnd(text, at);
106
- if (end === void 0) return void 0;
107
- out.push({
108
- kind: "token",
109
- text: text.slice(at, end)
110
- });
111
- at = end;
112
- continue;
113
- }
114
- const rest = text.slice(at);
115
- const ident = IDENT.exec(rest)?.[0];
116
- if (char === "(" || ident && rest[ident.length] === "(") {
117
- const name = (ident ?? "").toLowerCase();
118
- at += (ident?.length ?? 0) + 1;
119
- if (name === "url") {
120
- const end = text.indexOf(")", at);
121
- if (end < 0) return void 0;
122
- out.push({
123
- kind: "token",
124
- text: "url()"
125
- });
126
- at = end + 1;
127
- continue;
131
+ //#region src/css-tokens.ts
132
+ const at = (css, index) => index < css.length ? css.charCodeAt(index) : -1;
133
+ const isNewline = (c) => c === 10 || c === 13 || c === 12;
134
+ const isWhitespace = (c) => c === 32 || c === 9 || isNewline(c);
135
+ const isDigit = (c) => c >= 48 && c <= 57;
136
+ const isHexDigit = (c) => isDigit(c) || c >= 65 && c <= 70 || c >= 97 && c <= 102;
137
+ const isIdentStart = (c) => c >= 65 && c <= 90 || c >= 97 && c <= 122 || c === 95 || c >= 128;
138
+ const isIdentChar = (c) => isIdentStart(c) || isDigit(c) || c === 45;
139
+ const isNonPrintable = (c) => c >= 0 && c <= 8 || c === 11 || c >= 14 && c <= 31 || c === 127;
140
+ /** Whether a `\` at `index` starts an escape. */
141
+ const isEscape = (css, index) => at(css, index) === 92 && !isNewline(at(css, index + 1));
142
+ function startsIdentifier(css, index) {
143
+ const c = at(css, index);
144
+ if (c === 45) {
145
+ const next = at(css, index + 1);
146
+ return isIdentStart(next) || next === 45 || isEscape(css, index + 1);
147
+ }
148
+ return isIdentStart(c) || isEscape(css, index);
149
+ }
150
+ function startsNumber(css, index) {
151
+ const signed = at(css, index) === 43 || at(css, index) === 45 ? 1 : 0;
152
+ const c = at(css, index + signed);
153
+ return isDigit(c) || c === 46 && isDigit(at(css, index + signed + 1));
154
+ }
155
+ /** The code point the escape at `index` stands for, and the index after it. */
156
+ function readEscape(css, index) {
157
+ let i = index + 1;
158
+ if (i >= css.length) return ["�", i];
159
+ if (!isHexDigit(at(css, i))) {
160
+ const char = String.fromCodePoint(css.codePointAt(i) ?? 65533);
161
+ return [char, i + char.length];
162
+ }
163
+ const digitsEnd = Math.min(i + 6, css.length);
164
+ let value = 0;
165
+ while (i < digitsEnd && isHexDigit(at(css, i))) {
166
+ value = value * 16 + parseInt(css[i], 16);
167
+ i += 1;
168
+ }
169
+ if (at(css, i) === 13 && at(css, i + 1) === 10) i += 2;
170
+ else if (isWhitespace(at(css, i))) i += 1;
171
+ const valid = value !== 0 && value <= 1114111 && (value < 55296 || value > 57343);
172
+ return [String.fromCodePoint(valid ? value : 65533), i];
173
+ }
174
+ /** The identifier sequence at `index`, decoded, and the index after it. */
175
+ function readName(css, index) {
176
+ let name = "";
177
+ let from = index;
178
+ let i = index;
179
+ for (;;) if (isIdentChar(at(css, i))) i += 1;
180
+ else if (isEscape(css, i)) {
181
+ const [char, next] = readEscape(css, i);
182
+ name += css.slice(from, i) + char;
183
+ i = next;
184
+ from = i;
185
+ } else return [name + css.slice(from, i), i];
186
+ }
187
+ /** The identifier starting at `index`, decoded, or `undefined` when none
188
+ * starts there. */
189
+ function identifierAt(css, index) {
190
+ if (!startsIdentifier(css, index)) return void 0;
191
+ const [name, end] = readName(css, index);
192
+ return {
193
+ name,
194
+ end
195
+ };
196
+ }
197
+ /** `name` decoded when it is one whole identifier, else as written. */
198
+ function decodedIdentifier(name) {
199
+ const read = identifierAt(name, 0);
200
+ return read?.end === name.length ? read.name : name;
201
+ }
202
+ function readString(css, index) {
203
+ const quote = at(css, index);
204
+ let i = index + 1;
205
+ for (;;) {
206
+ const c = at(css, i);
207
+ if (c === -1) return ["string", i];
208
+ if (c === quote) return ["string", i + 1];
209
+ if (isNewline(c)) return ["bad-string", i];
210
+ if (c === 92) {
211
+ const next = at(css, i + 1);
212
+ if (next === -1) i += 1;
213
+ else if (isNewline(next)) i += next === 13 && at(css, i + 2) === 10 ? 3 : 2;
214
+ else i = readEscape(css, i)[1];
215
+ } else i += 1;
216
+ }
217
+ }
218
+ function badUrlEnd(css, index) {
219
+ let i = index;
220
+ for (;;) {
221
+ const c = at(css, i);
222
+ if (c === -1) return i;
223
+ if (c === 41) return i + 1;
224
+ i = isEscape(css, i) ? readEscape(css, i)[1] : i + 1;
225
+ }
226
+ }
227
+ /** An unquoted `url(` body starting at `index`. */
228
+ function readUrl(css, index) {
229
+ let i = index;
230
+ while (isWhitespace(at(css, i))) i += 1;
231
+ for (;;) {
232
+ const c = at(css, i);
233
+ if (c === -1) return ["url", i];
234
+ if (c === 41) return ["url", i + 1];
235
+ if (isWhitespace(c)) {
236
+ while (isWhitespace(at(css, i))) i += 1;
237
+ const next = at(css, i);
238
+ if (next === -1) return ["url", i];
239
+ if (next === 41) return ["url", i + 1];
240
+ return ["bad-url", badUrlEnd(css, i)];
241
+ }
242
+ if (c === 34 || c === 39 || c === 40 || isNonPrintable(c)) return ["bad-url", badUrlEnd(css, i)];
243
+ if (c === 92) {
244
+ if (!isEscape(css, i)) return ["bad-url", badUrlEnd(css, i)];
245
+ i = readEscape(css, i)[1];
246
+ } else i += 1;
247
+ }
248
+ }
249
+ function numberEnd(css, index) {
250
+ let i = index;
251
+ if (at(css, i) === 43 || at(css, i) === 45) i += 1;
252
+ while (isDigit(at(css, i))) i += 1;
253
+ if (at(css, i) === 46 && isDigit(at(css, i + 1))) {
254
+ i += 2;
255
+ while (isDigit(at(css, i))) i += 1;
256
+ }
257
+ const e = at(css, i);
258
+ if (e === 69 || e === 101) {
259
+ const sign = at(css, i + 1) === 43 || at(css, i + 1) === 45 ? 1 : 0;
260
+ if (isDigit(at(css, i + 1 + sign))) {
261
+ i += 2 + sign;
262
+ while (isDigit(at(css, i))) i += 1;
263
+ }
264
+ }
265
+ return i;
266
+ }
267
+ const SINGLE = new Map([
268
+ "(",
269
+ ")",
270
+ "[",
271
+ "]",
272
+ "{",
273
+ "}",
274
+ ",",
275
+ ":",
276
+ ";"
277
+ ].map((c) => [c, c]));
278
+ /** Every token of `css`, in order. */
279
+ function tokenize(css) {
280
+ const tokens = [];
281
+ let index = 0;
282
+ const push = (type, end, value = "", number = 0) => {
283
+ tokens.push({
284
+ type,
285
+ start: index,
286
+ end,
287
+ value,
288
+ number
289
+ });
290
+ index = end;
291
+ };
292
+ while (index < css.length) {
293
+ const c = css.charCodeAt(index);
294
+ if (c === 47 && at(css, index + 1) === 42) {
295
+ const close = css.indexOf("*/", index + 2);
296
+ index = close === -1 ? css.length : close + 2;
297
+ } else if (isWhitespace(c)) {
298
+ let end = index + 1;
299
+ while (isWhitespace(at(css, end))) end += 1;
300
+ push("whitespace", end);
301
+ } else if (c === 34 || c === 39) {
302
+ const [type, end] = readString(css, index);
303
+ push(type, end);
304
+ } else if (startsNumber(css, index)) {
305
+ const end = numberEnd(css, index);
306
+ const number = Number(css.slice(index, end));
307
+ if (startsIdentifier(css, end)) {
308
+ const [unit, unitEnd] = readName(css, end);
309
+ push("dimension", unitEnd, unit, number);
310
+ } else if (at(css, end) === 37) push("percentage", end + 1, "", number);
311
+ else push("number", end, "", number);
312
+ } else if (c === 45 && css.startsWith("->", index + 1)) push("CDC", index + 3);
313
+ else if (startsIdentifier(css, index)) {
314
+ const [name, end] = readName(css, index);
315
+ if (at(css, end) !== 40) push("ident", end, name);
316
+ else if (!/^url$/i.test(name)) push("function", end + 1, name);
317
+ else {
318
+ let body = end + 1;
319
+ while (isWhitespace(at(css, body)) && isWhitespace(at(css, body + 1))) body += 1;
320
+ const first = at(css, body);
321
+ const quote = isWhitespace(first) ? at(css, body + 1) : first;
322
+ if (quote === 34 || quote === 39) push("function", body, name);
323
+ else {
324
+ const [type, urlEnd] = readUrl(css, end + 1);
325
+ push(type, urlEnd);
128
326
  }
129
- const args = values(true);
130
- if (args === void 0) return void 0;
131
- out.push({
132
- kind: "function",
133
- name,
134
- args
135
- });
136
- continue;
137
- }
138
- const number = NUMBER.exec(rest)?.[0];
139
- if (number !== void 0) {
140
- const unit = /^(?:%|[a-zA-Z]+)/.exec(rest.slice(number.length))?.[0];
141
- out.push({
142
- kind: "numeric",
143
- value: Number(number),
144
- unit: (unit ?? "").toLowerCase()
145
- });
146
- at += number.length + (unit?.length ?? 0);
147
- continue;
148
327
  }
149
- out.push({
150
- kind: "token",
151
- text: ident ?? char
328
+ } else if (c === 35 && (isIdentChar(at(css, index + 1)) || isEscape(css, index + 1))) {
329
+ const [name, end] = readName(css, index + 1);
330
+ push("hash", end, name);
331
+ } else if (c === 64 && startsIdentifier(css, index + 1)) {
332
+ const [name, end] = readName(css, index + 1);
333
+ push("at-keyword", end, name);
334
+ } else if (c === 60 && css.startsWith("!--", index + 1)) push("CDO", index + 4);
335
+ else {
336
+ const single = SINGLE.get(css[index]);
337
+ if (single === void 0) push("delim", index + 1, css[index]);
338
+ else push(single, index + 1);
339
+ }
340
+ }
341
+ return tokens;
342
+ }
343
+ const CLOSERS = /* @__PURE__ */ new Map([
344
+ ["function", ")"],
345
+ ["(", ")"],
346
+ ["[", "]"],
347
+ ["{", "}"]
348
+ ]);
349
+ /**
350
+ * `tokens` as component values. Only the innermost open block's own closer
351
+ * closes it; any other closer stays a token, and a block left open closes at
352
+ * the end, as CSS reads them.
353
+ */
354
+ function componentValues(tokens) {
355
+ const root = [];
356
+ const open = [];
357
+ for (const token of tokens) {
358
+ const top = open.at(-1);
359
+ if (top !== void 0 && token.type === top.closer) {
360
+ top.block.close = token;
361
+ top.block.end = token.end;
362
+ open.pop();
363
+ continue;
364
+ }
365
+ const list = top === void 0 ? root : top.block.children;
366
+ const closer = CLOSERS.get(token.type);
367
+ if (closer === void 0) list.push({
368
+ kind: "token",
369
+ token,
370
+ start: token.start,
371
+ end: token.end
372
+ });
373
+ else {
374
+ const block = {
375
+ kind: "block",
376
+ open: token,
377
+ close: void 0,
378
+ children: [],
379
+ start: token.start,
380
+ end: token.end
381
+ };
382
+ list.push(block);
383
+ open.push({
384
+ block,
385
+ closer
152
386
  });
153
- at += ident?.length ?? 1;
154
387
  }
155
- return nested ? void 0 : out;
156
388
  }
157
- return values(false);
389
+ for (let i = open.length - 1; i >= 0; i -= 1) {
390
+ const { block } = open[i];
391
+ block.end = Math.max(block.end, block.children.at(-1)?.end ?? block.end);
392
+ }
393
+ return root;
158
394
  }
159
- function stringEnd(text, start) {
160
- for (let at = start + 1; at < text.length; at += 1) if (text[at] === "\\") at += 1;
161
- else if (text[at] === text[start]) return at + 1;
395
+ /** Whether `test` holds for a value at any depth. */
396
+ function someValue(values, test) {
397
+ return values.some((value) => test(value) || value.kind === "block" && someValue(value.children, test));
162
398
  }
163
- function some(values, test) {
164
- return values.some((value) => test(value) || value.kind === "function" && some(value.args, test));
399
+ /** Whether `value` is whitespace. */
400
+ const isSpace = (value) => value?.kind === "token" && value.token.type === "whitespace";
401
+ /**
402
+ * Every `var()` call in `values` at any depth, fallbacks included, outer
403
+ * calls first: a function whose decoded name is `var` in any case, and whose
404
+ * first argument is a custom-property name.
405
+ */
406
+ function variableReads(values) {
407
+ const reads = [];
408
+ const visit = (list) => {
409
+ for (const value of list) {
410
+ if (value.kind !== "block") continue;
411
+ if (value.open.type === "function" && /^var$/i.test(value.open.value)) {
412
+ const [name, comma, first] = value.children.filter((c) => !isSpace(c));
413
+ if (name?.kind === "token" && name.token.type === "ident" && name.token.value.startsWith("--")) {
414
+ const end = value.close?.start ?? value.end;
415
+ reads.push({
416
+ name: name.token.value,
417
+ start: value.start,
418
+ end: value.end,
419
+ fallback: comma?.kind === "token" && comma.token.type === "," ? {
420
+ start: comma.end,
421
+ first: first?.start ?? end,
422
+ end
423
+ } : void 0
424
+ });
425
+ }
426
+ }
427
+ visit(value.children);
428
+ }
429
+ };
430
+ visit(values);
431
+ return reads;
432
+ }
433
+ /**
434
+ * The `!important` `css` ends with; kept in step with `important_priority`
435
+ * in the Rust engine. The value has one `!`, a delim token, so a `!` inside
436
+ * a string, a `url()` or an escape is no priority, and neither is a lone `!`
437
+ * or `!important`.
438
+ */
439
+ function importantPriority(css) {
440
+ const trimmed = css.trimEnd();
441
+ const endsImportant = trimmed.length >= 9 && /^important$/i.test(trimmed.slice(-9));
442
+ if (!css.endsWith("!") && !endsImportant) return void 0;
443
+ const tokens = tokenize(css);
444
+ let bang = -1;
445
+ for (let index = 0; index < tokens.length; index += 1) {
446
+ if (tokens[index].type !== "delim" || tokens[index].value !== "!") continue;
447
+ if (bang !== -1) return void 0;
448
+ bang = index;
449
+ }
450
+ if (bang === -1) return void 0;
451
+ if (bang === tokens.length - 1) {
452
+ const previous = tokens[bang - 1];
453
+ return previous !== void 0 && previous.type !== "whitespace" && previous.end === tokens[bang].start ? {
454
+ spelling: "shorthand",
455
+ end: previous.end
456
+ } : void 0;
457
+ }
458
+ const after = tokens.slice(bang + 1).filter((t) => t.type !== "whitespace");
459
+ if (after.length !== 1 || after[0].type !== "ident" || !/^important$/i.test(after[0].value)) return;
460
+ const value = tokens.slice(0, bang).findLast((t) => t.type !== "whitespace");
461
+ return value && {
462
+ spelling: "important",
463
+ end: value.end
464
+ };
465
+ }
466
+ //#endregion
467
+ //#region src/registration-values.ts
468
+ /**
469
+ * Reads a custom-property registration's initial value as CSS component
470
+ * values: what it substitutes, which units make it depend on context, and
471
+ * what an all-absolute math function computes to. Tokens come from the shared
472
+ * CSS reader, so comments are trivia, quoted strings and `url()` stay text,
473
+ * and escaped names are decoded.
474
+ */
475
+ const asciiLower = (text) => text.replace(/[A-Z]/g, (letter) => letter.toLowerCase());
476
+ const parse = (text) => componentValues(tokenize(text));
477
+ /** A function's ASCII-lowercase name, `''` for a parenthesized block, and
478
+ * `undefined` for anything else. */
479
+ function functionName(value) {
480
+ if (value?.kind !== "block") return void 0;
481
+ if (value.open.type === "function") return asciiLower(value.open.value);
482
+ return value.open.type === "(" ? "" : void 0;
165
483
  }
166
484
  const SUBSTITUTIONS = /* @__PURE__ */ new Set([
167
485
  "var",
@@ -169,12 +487,9 @@ const SUBSTITUTIONS = /* @__PURE__ */ new Set([
169
487
  "attr"
170
488
  ]);
171
489
  /** Whether `value` substitutes another value (`var()`, `env()`, `attr()`),
172
- * which no registration's initial value may. Unparseable text is read as
173
- * substituting when it names one of them. */
490
+ * which no registration's initial value may. */
174
491
  function substitutesValue(value) {
175
- const values = parse(value);
176
- if (values === void 0) return /\b(?:var|env|attr)\(/i.test(value);
177
- return some(values, (component) => component.kind === "function" && SUBSTITUTIONS.has(component.name));
492
+ return someValue(parse(value), (component) => SUBSTITUTIONS.has(functionName(component) ?? ""));
178
493
  }
179
494
  const CONTEXT_UNITS = /* @__PURE__ */ new Set([
180
495
  "em",
@@ -199,9 +514,7 @@ const CONTEXT_UNITS = /* @__PURE__ */ new Set([
199
514
  /** Whether `value` uses a font- or container-relative unit, inside math
200
515
  * functions too, which makes a typed initial value depend on context. */
201
516
  function dependsOnContext(value) {
202
- const values = parse(value);
203
- if (values === void 0) return false;
204
- return some(values, (component) => component.kind === "numeric" && CONTEXT_UNITS.has(component.unit));
517
+ return someValue(parse(value), (component) => component.kind === "token" && component.token.type === "dimension" && CONTEXT_UNITS.has(asciiLower(component.token.value)));
205
518
  }
206
519
  /** Absolute units, by the canonical unit each converts to. */
207
520
  const ABSOLUTE_UNITS = /* @__PURE__ */ new Map([
@@ -236,94 +549,157 @@ const MATH_FUNCTIONS = /* @__PURE__ */ new Set([
236
549
  "max",
237
550
  "clamp"
238
551
  ]);
239
- /** Evaluates a math function's arguments: `+ - * /` over numbers and
240
- * absolute dimensions, nested `calc()`, `min()`, `max()` and `clamp()`. */
241
- function evaluate(values) {
242
- let at = 0;
243
- const operator = (...ops) => {
244
- const value = values[at];
245
- if (value?.kind === "token" && ops.includes(value.text)) {
246
- at += 1;
247
- return value.text;
248
- }
552
+ const operatorOf = (value) => value?.kind === "token" && value.token.type === "delim" && "+-*/".includes(value.token.value) ? value.token.value : void 0;
553
+ /**
554
+ * A math function's argument read as CSS calculation syntax, or what is out
555
+ * of place: `+` and `-` need whitespace on both sides, every operator needs a
556
+ * value on each side, and two values need an operator between them.
557
+ */
558
+ function readCalculation(values) {
559
+ let start = 0;
560
+ let end = values.length;
561
+ while (start < end && isSpace(values[start])) start += 1;
562
+ while (end > start && isSpace(values[end - 1])) end -= 1;
563
+ if (start === end) return { invalid: "a calculation needs a value" };
564
+ let at = start;
565
+ const skipSpace = () => {
566
+ while (at < end && isSpace(values[at])) at += 1;
249
567
  };
250
- function factor() {
568
+ const operand = () => {
569
+ skipSpace();
251
570
  const value = values[at];
571
+ if (at >= end || operatorOf(value) !== void 0) return { invalid: "an operator needs a value on each side" };
252
572
  at += 1;
253
- if (value === void 0) return void 0;
254
- if (value.kind === "numeric") {
255
- if (value.unit === "") return {
256
- type: "number",
257
- value: value.value
258
- };
259
- const unit = ABSOLUTE_UNITS.get(value.unit);
260
- return unit && {
261
- type: unit[0],
262
- value: value.value * unit[1]
263
- };
264
- }
265
- if (value.kind === "function") return mathFunction(value);
266
- }
267
- function product() {
268
- let left = factor();
269
- for (let op = operator("*", "/"); op && left; op = operator("*", "/")) {
270
- const right = factor();
271
- if (right === void 0) return void 0;
272
- if (op === "*") {
273
- if (left.type !== "number" && right.type !== "number") return void 0;
274
- left = {
275
- type: left.type === "number" ? right.type : left.type,
276
- value: left.value * right.value
277
- };
278
- } else if (right.type === "number") left = {
279
- type: left.type,
280
- value: left.value / right.value
281
- };
282
- else if (right.type === left.type) left = {
283
- type: "number",
284
- value: left.value / right.value
285
- };
286
- else return;
287
- }
288
- return left;
289
- }
290
- function sum() {
291
- let left = product();
292
- for (let op = operator("+", "-"); op && left; op = operator("+", "-")) {
293
- const right = product();
294
- if (right === void 0 || right.type !== left.type) return void 0;
573
+ return { value };
574
+ };
575
+ const product = () => {
576
+ let left = operand();
577
+ while (!("invalid" in left)) {
578
+ const before = at;
579
+ skipSpace();
580
+ const op = operatorOf(values[at]);
581
+ if (op !== "*" && op !== "/") {
582
+ at = before;
583
+ return left;
584
+ }
585
+ at += 1;
586
+ const right = operand();
587
+ if ("invalid" in right) return right;
295
588
  left = {
296
- type: left.type,
297
- value: op === "+" ? left.value + right.value : left.value - right.value
589
+ op,
590
+ left,
591
+ right
298
592
  };
299
593
  }
300
594
  return left;
595
+ };
596
+ let sum = product();
597
+ while (!("invalid" in sum) && at < end) {
598
+ const spaced = isSpace(values[at]);
599
+ skipSpace();
600
+ const op = operatorOf(values[at]);
601
+ if (op !== "+" && op !== "-") return { invalid: "two values need an operator between them" };
602
+ if (at + 1 >= end) return { invalid: "an operator needs a value on each side" };
603
+ if (!spaced || !isSpace(values[at + 1])) return { invalid: "\"+\" and \"-\" need whitespace on both sides" };
604
+ at += 1;
605
+ const right = product();
606
+ if ("invalid" in right) return right;
607
+ sum = {
608
+ op,
609
+ left: sum,
610
+ right
611
+ };
301
612
  }
302
- const result = sum();
303
- return at === values.length ? result : void 0;
613
+ return sum;
304
614
  }
615
+ /** Both sides evaluated, so a broken expression on either side is reported
616
+ * even where the other cannot be evaluated. */
617
+ function combine(op, left, right) {
618
+ if (left !== void 0 && "invalid" in left) return left;
619
+ if (right !== void 0 && "invalid" in right) return right;
620
+ if (left === void 0 || right === void 0) return void 0;
621
+ if (op === "+" || op === "-") {
622
+ if (left.type !== right.type) return void 0;
623
+ return {
624
+ type: left.type,
625
+ value: op === "+" ? left.value + right.value : left.value - right.value
626
+ };
627
+ }
628
+ if (op === "*") {
629
+ if (left.type !== "number" && right.type !== "number") return void 0;
630
+ return {
631
+ type: left.type === "number" ? right.type : left.type,
632
+ value: left.value * right.value
633
+ };
634
+ }
635
+ if (right.type === "number") return {
636
+ type: left.type,
637
+ value: left.value / right.value
638
+ };
639
+ return right.type === left.type ? {
640
+ type: "number",
641
+ value: left.value / right.value
642
+ } : void 0;
643
+ }
644
+ /** The calculation constants, by their ASCII-lowercase name. */
645
+ const CONSTANTS = /* @__PURE__ */ new Map([
646
+ ["e", Math.E],
647
+ ["pi", Math.PI],
648
+ ["infinity", Infinity],
649
+ ["-infinity", -Infinity],
650
+ ["nan", NaN]
651
+ ]);
652
+ function evaluate(node) {
653
+ if ("op" in node) return combine(node.op, evaluate(node.left), evaluate(node.right));
654
+ const { value } = node;
655
+ if (value.kind === "block") return mathFunction(value);
656
+ const { token } = value;
657
+ if (token.type === "number") return {
658
+ type: "number",
659
+ value: token.number
660
+ };
661
+ if (token.type === "dimension") {
662
+ const unit = ABSOLUTE_UNITS.get(asciiLower(token.value));
663
+ return unit && {
664
+ type: unit[0],
665
+ value: token.number * unit[1]
666
+ };
667
+ }
668
+ const constant = token.type === "ident" ? CONSTANTS.get(asciiLower(token.value)) : void 0;
669
+ return constant === void 0 ? void 0 : {
670
+ type: "number",
671
+ value: constant
672
+ };
673
+ }
674
+ /** `calc()`, `min()`, `max()` and `clamp()` over numbers and absolute
675
+ * dimensions, nested ones and parenthesized blocks included. */
305
676
  function mathFunction(value) {
306
- if (value.name === "calc" || value.name === "") return evaluate(value.args);
307
- if (!MATH_FUNCTIONS.has(value.name)) return void 0;
677
+ const name = functionName(value);
678
+ if (name === void 0 || name !== "" && !MATH_FUNCTIONS.has(name)) return;
679
+ const parts = [[]];
680
+ for (const arg of value.children) if (arg.kind === "token" && arg.token.type === ",") parts.push([]);
681
+ else parts[parts.length - 1].push(arg);
682
+ if ((name === "" || name === "calc") && parts.length > 1) return { invalid: "commas separate only the arguments of min(), max() and clamp()" };
308
683
  const args = [];
309
- let start = 0;
310
- for (let at = 0; at <= value.args.length; at += 1) {
311
- const arg = value.args[at];
312
- if (at === value.args.length || arg?.kind === "token" && arg.text === ",") {
313
- const computed = evaluate(value.args.slice(start, at));
314
- if (computed === void 0) return void 0;
315
- args.push(computed);
316
- start = at + 1;
317
- }
684
+ let unsupported = false;
685
+ for (const part of parts) {
686
+ const calculation = readCalculation(part);
687
+ if ("invalid" in calculation) return calculation;
688
+ const computed = evaluate(calculation);
689
+ if (computed !== void 0 && "invalid" in computed) return computed;
690
+ if (computed === void 0) unsupported = true;
691
+ else args.push(computed);
318
692
  }
319
- const type = args[0]?.type;
320
- if (type === void 0 || args.some((arg) => arg.type !== type)) return;
693
+ if (unsupported) return void 0;
694
+ if (name === "" || name === "calc") return args[0];
695
+ const type = args[0].type;
696
+ if (args.some((arg) => arg.type !== type)) return void 0;
321
697
  const values = args.map((arg) => arg.value);
322
- if (value.name === "min") return {
698
+ if (name === "min") return {
323
699
  type,
324
700
  value: Math.min(...values)
325
701
  };
326
- if (value.name === "max") return {
702
+ if (name === "max") return {
327
703
  type,
328
704
  value: Math.max(...values)
329
705
  };
@@ -349,32 +725,39 @@ const ACCEPTING_SYNTAX_TYPES = /* @__PURE__ */ new Map([
349
725
  * `min()`, `max()`, `clamp()`) over numbers and absolute units, such as
350
726
  * `calc(1px / 1px)` → `1`. The browser computes the same value, and CSS
351
727
  * tooling that cannot parse the function in that position reads the result.
352
- * `undefined` for anything else, and for the universal syntax, whose initial
353
- * value is kept as written.
728
+ * The syntax's alternatives are tried in their declared order, and an
729
+ * `<integer>` one rounds a number result to the nearest integer, halves
730
+ * toward positive infinity, as CSS does. `undefined` for anything else, and
731
+ * for the universal syntax, whose initial value is kept as written.
354
732
  */
355
733
  function foldInitialValue(syntax, initialValue) {
356
734
  if (syntax.trim() === "*") return void 0;
357
- const values = parse(initialValue);
358
- const only = values?.length === 1 ? values[0] : void 0;
359
- if (only?.kind !== "function" || !MATH_FUNCTIONS.has(only.name)) return;
735
+ const values = parse(initialValue).filter((value) => !isSpace(value));
736
+ const only = values.length === 1 ? values[0] : void 0;
737
+ if (only?.kind !== "block" || !MATH_FUNCTIONS.has(functionName(only) ?? "")) return;
360
738
  const computed = mathFunction(only);
361
739
  if (computed === void 0) return void 0;
362
- const accepted = syntax.split("|").some((component) => {
740
+ if ("invalid" in computed) return {
741
+ kind: "invalid",
742
+ reason: computed.invalid
743
+ };
744
+ if (!Number.isFinite(computed.value)) return { kind: "not-finite" };
745
+ for (const component of syntax.split("|")) {
363
746
  const type = /<([a-z-]+)>/.exec(component)?.[1];
364
- if (type === void 0 || ACCEPTING_SYNTAX_TYPES.get(type) !== computed.type) return false;
365
- return type !== "integer" || Number.isInteger(computed.value);
366
- });
747
+ if (type === void 0 || ACCEPTING_SYNTAX_TYPES.get(type) !== computed.type) continue;
748
+ return {
749
+ kind: "folded",
750
+ text: type === "integer" ? BigInt(Math.round(computed.value)).toString() : written(computed)
751
+ };
752
+ }
367
753
  return {
368
- text: `${Number(computed.value.toPrecision(12))}${CANONICAL_UNITS[computed.type]}`,
369
- accepted,
754
+ kind: "rejected",
755
+ text: written(computed),
370
756
  type: computed.type
371
757
  };
372
758
  }
373
- /** An initial value folded when its syntax accepts the computed value, and
374
- * unchanged otherwise: what a registration records and emits. */
375
- function registeredInitialValue(syntax, initialValue) {
376
- const folded = foldInitialValue(syntax, initialValue);
377
- return folded?.accepted ? folded.text : initialValue;
759
+ function written(computed) {
760
+ return `${Number(computed.value.toPrecision(12))}${CANONICAL_UNITS[computed.type]}`;
378
761
  }
379
762
  //#endregion
380
- export { SHORTHAND_PROPERTIES, UNITLESS_PROPERTIES, dependsOnContext, foldInitialValue, isUnitlessProperty, registeredInitialValue, substitutesValue };
763
+ export { SHORTHAND_PROPERTIES, UNITLESS_PROPERTIES, componentValues, decodedIdentifier, dependsOnContext, foldInitialValue, identifierAt, importantPriority, isSpace, isUnitlessProperty, someValue, substitutesValue, tokenize, variableReads };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@animus-ui/properties",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "description": "CSS property classification data — unitless set, shorthand list, type re-exports",
5
5
  "keywords": [
6
6
  "animus",
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "scripts": {
38
38
  "build": "bun run build:ts",
39
- "build:ts": "tsdown && tsc -p tsconfig.build.json",
39
+ "build:ts": "tsdown",
40
40
  "compile": "tsc --noEmit"
41
41
  },
42
42
  "dependencies": {},
@@ -1,41 +0,0 @@
1
- /**
2
- * Reads a custom-property registration's initial value as CSS component
3
- * values: what it substitutes, which units make it depend on context, and
4
- * what an all-absolute math function computes to. Quoted text and `url()`
5
- * stay text.
6
- */
7
- /** Whether `value` substitutes another value (`var()`, `env()`, `attr()`),
8
- * which no registration's initial value may. Unparseable text is read as
9
- * substituting when it names one of them. */
10
- export declare function substitutesValue(value: string): boolean;
11
- /** Whether `value` uses a font- or container-relative unit, inside math
12
- * functions too, which makes a typed initial value depend on context. */
13
- export declare function dependsOnContext(value: string): boolean;
14
- /** What an all-absolute math expression computes to. */
15
- interface Computed {
16
- type: 'number' | 'length' | 'angle' | 'time' | 'resolution';
17
- value: number;
18
- }
19
- /** A math initial value folded to its computed value. */
20
- export interface FoldedInitialValue {
21
- /** The computed value as CSS text, such as `1`, `16px` or `90deg`. */
22
- text: string;
23
- /** Whether the registration's syntax accepts it. */
24
- accepted: boolean;
25
- /** The computed value's data type, for a diagnostic. */
26
- type: Computed['type'];
27
- }
28
- /**
29
- * The computed value of an initial value that is one math function (`calc()`,
30
- * `min()`, `max()`, `clamp()`) over numbers and absolute units, such as
31
- * `calc(1px / 1px)` → `1`. The browser computes the same value, and CSS
32
- * tooling that cannot parse the function in that position reads the result.
33
- * `undefined` for anything else, and for the universal syntax, whose initial
34
- * value is kept as written.
35
- */
36
- export declare function foldInitialValue(syntax: string, initialValue: string): FoldedInitialValue | undefined;
37
- /** An initial value folded when its syntax accepts the computed value, and
38
- * unchanged otherwise: what a registration records and emits. */
39
- export declare function registeredInitialValue(syntax: string, initialValue: string): string;
40
- export {};
41
- //# sourceMappingURL=registration-values.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"registration-values.d.ts","sourceRoot":"","sources":["../src/registration-values.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAyFH;;8CAE8C;AAC9C,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAQvD;AAuBD;0EAC0E;AAC1E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAQvD;AAED,wDAAwD;AACxD,UAAU,QAAQ;IAChB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC;IAC5D,KAAK,EAAE,MAAM,CAAC;CACf;AAwID,yDAAyD;AACzD,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,QAAQ,EAAE,OAAO,CAAC;IAClB,wDAAwD;IACxD,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GACnB,kBAAkB,GAAG,SAAS,CAyBhC;AAED;kEACkE;AAClE,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GACnB,MAAM,CAGR"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Covers only shorthands registered in the prop system, not all CSS shorthands.
3
- */
4
- export declare const SHORTHAND_PROPERTIES: readonly ['border', 'borderTop', 'borderBottom', 'borderLeft', 'borderRight', 'borderWidth', 'borderStyle', 'borderColor', 'background', 'flex', 'margin', 'padding', 'transition', 'gap', 'grid', 'gridArea', 'gridColumn', 'gridRow', 'gridTemplate', 'overflow'];
5
- //# sourceMappingURL=shorthands.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"shorthands.d.ts","sourceRoot":"","sources":["../src/shorthands.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,oBAAoB,YAC/B,QAAQ,EACR,WAAW,EACX,cAAc,EACd,YAAY,EACZ,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,YAAY,EACZ,MAAM,EACN,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,KAAK,EACL,MAAM,EACN,UAAU,EACV,YAAY,EACZ,SAAS,EACT,cAAc,EACd,UAAU,CACF,CAAC"}
@@ -1,4 +0,0 @@
1
- export declare const UNITLESS_PROPERTIES: Set<string>;
2
- /** Accepts either spelling: `line-height` or `lineHeight`. */
3
- export declare function isUnitlessProperty(property: string): boolean;
4
- //# sourceMappingURL=unitless.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"unitless.d.ts","sourceRoot":"","sources":["../src/unitless.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,aAgD9B,CAAC;AAUH,8DAA8D;AAC9D,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE5D"}