@arbor-css/css-eval 0.0.109

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.
Files changed (58) hide show
  1. package/LICENSE.md +7 -0
  2. package/dist/browser.d.ts +3 -0
  3. package/dist/browser.d.ts.map +1 -0
  4. package/dist/browser.js +7 -0
  5. package/dist/browser.js.map +1 -0
  6. package/dist/computation.d.ts +9 -0
  7. package/dist/computation.d.ts.map +1 -0
  8. package/dist/computation.js +12 -0
  9. package/dist/computation.js.map +1 -0
  10. package/dist/computation.test.d.ts +2 -0
  11. package/dist/computation.test.d.ts.map +1 -0
  12. package/dist/computation.test.js +59 -0
  13. package/dist/computation.test.js.map +1 -0
  14. package/dist/index.d.ts +6 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +6 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/interpolation.d.ts +20 -0
  19. package/dist/interpolation.d.ts.map +1 -0
  20. package/dist/interpolation.js +96 -0
  21. package/dist/interpolation.js.map +1 -0
  22. package/dist/interpolation.test.d.ts +2 -0
  23. package/dist/interpolation.test.d.ts.map +1 -0
  24. package/dist/interpolation.test.js +29 -0
  25. package/dist/interpolation.test.js.map +1 -0
  26. package/dist/node.d.ts +2 -0
  27. package/dist/node.d.ts.map +1 -0
  28. package/dist/node.js +4 -0
  29. package/dist/node.js.map +1 -0
  30. package/dist/print.d.ts +3 -0
  31. package/dist/print.d.ts.map +1 -0
  32. package/dist/print.js +4 -0
  33. package/dist/print.js.map +1 -0
  34. package/dist/resolveProperties.d.ts +11 -0
  35. package/dist/resolveProperties.d.ts.map +1 -0
  36. package/dist/resolveProperties.js +108 -0
  37. package/dist/resolveProperties.js.map +1 -0
  38. package/dist/resolveProperties.test.d.ts +2 -0
  39. package/dist/resolveProperties.test.d.ts.map +1 -0
  40. package/dist/resolveProperties.test.js +97 -0
  41. package/dist/resolveProperties.test.js.map +1 -0
  42. package/dist/simplification.d.ts +19 -0
  43. package/dist/simplification.d.ts.map +1 -0
  44. package/dist/simplification.js +34 -0
  45. package/dist/simplification.js.map +1 -0
  46. package/dist/simplification.test.d.ts +2 -0
  47. package/dist/simplification.test.d.ts.map +1 -0
  48. package/dist/simplification.test.js +15 -0
  49. package/dist/simplification.test.js.map +1 -0
  50. package/dist/util.d.ts +10 -0
  51. package/dist/util.d.ts.map +1 -0
  52. package/dist/util.js +30 -0
  53. package/dist/util.js.map +1 -0
  54. package/dist/util.test.d.ts +2 -0
  55. package/dist/util.test.d.ts.map +1 -0
  56. package/dist/util.test.js +34 -0
  57. package/dist/util.test.js.map +1 -0
  58. package/package.json +50 -0
package/LICENSE.md ADDED
@@ -0,0 +1,7 @@
1
+ Copyright 2026 Grant Forrest
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,3 @@
1
+ import { CssSimplifier } from './simplification.js';
2
+ export declare const loadSimplifier: () => Promise<CssSimplifier>;
3
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoB,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEtE,eAAO,MAAM,cAAc,QAAa,OAAO,CAAC,aAAa,CAG5D,CAAC"}
@@ -0,0 +1,7 @@
1
+ import init, { transform as transformNative, } from 'https://esm.run/lightningcss-wasm';
2
+ import { createSimplifier } from './simplification.js';
3
+ export const loadSimplifier = async () => {
4
+ await init();
5
+ return createSimplifier({ transform: transformNative });
6
+ };
7
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,EAAE,EACZ,SAAS,IAAI,eAAe,GAC5B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAiB,MAAM,qBAAqB,CAAC;AAEtE,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,IAA4B,EAAE;IAChE,MAAM,IAAI,EAAE,CAAC;IACb,OAAO,gBAAgB,CAAC,EAAE,SAAS,EAAE,eAAsB,EAAE,CAAC,CAAC;AAChE,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { Css } from './interpolation.js';
2
+ import { CssSimplifier } from './simplification.js';
3
+ export interface CssResolutionContext {
4
+ propertyValues?: Record<string, string | Css>;
5
+ skipBaking?: boolean;
6
+ simplifier?: CssSimplifier;
7
+ }
8
+ export declare function resolveCss(input: Css, { propertyValues, skipBaking, simplifier }: CssResolutionContext): string;
9
+ //# sourceMappingURL=computation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computation.d.ts","sourceRoot":"","sources":["../src/computation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,WAAW,oBAAoB;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,CAAC;IAC9C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,aAAa,CAAC;CAC3B;AAED,wBAAgB,UAAU,CACzB,KAAK,EAAE,GAAG,EACV,EAAE,cAAmB,EAAE,UAAkB,EAAE,UAAU,EAAE,EAAE,oBAAoB,UAa7E"}
@@ -0,0 +1,12 @@
1
+ import { resolveProperties } from './resolveProperties.js';
2
+ export function resolveCss(input, { propertyValues = {}, skipBaking = false, simplifier }) {
3
+ let result = skipBaking ? input.text : resolveProperties(input, propertyValues).text;
4
+ if (simplifier) {
5
+ result = simplifier({
6
+ ...input,
7
+ text: result,
8
+ });
9
+ }
10
+ return result;
11
+ }
12
+ //# sourceMappingURL=computation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computation.js","sourceRoot":"","sources":["../src/computation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAS3D,MAAM,UAAU,UAAU,CACzB,KAAU,EACV,EAAE,cAAc,GAAG,EAAE,EAAE,UAAU,GAAG,KAAK,EAAE,UAAU,EAAwB;IAE7E,IAAI,MAAM,GACT,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC;IAEzE,IAAI,UAAU,EAAE,CAAC;QAChB,MAAM,GAAG,UAAU,CAAC;YACnB,GAAG,KAAK;YACR,IAAI,EAAE,MAAM;SACZ,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=computation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computation.test.d.ts","sourceRoot":"","sources":["../src/computation.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,59 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { resolveCss } from './computation.js';
3
+ import { css } from './interpolation.js';
4
+ import { simplifier } from './node.js';
5
+ describe('resolveCss with simplification', () => {
6
+ // calc simplification not working yet?
7
+ it('should simplify calc() with a single value', async () => {
8
+ const result = resolveCss(css `calc(10px)`, { simplifier });
9
+ expect(result).toBe('10px');
10
+ });
11
+ it('should substitute variables with their values', async () => {
12
+ const result = resolveCss(css `var(--x)`, {
13
+ propertyValues: { '--x': '20px' },
14
+ simplifier,
15
+ });
16
+ expect(result).toBe('20px');
17
+ });
18
+ it('should simplify calc arithmetic', async () => {
19
+ const result = resolveCss(css `calc(10px + 5px)`, { simplifier });
20
+ expect(result).toBe('15px');
21
+ });
22
+ it('should simplify nested calc expressions', async () => {
23
+ const result = resolveCss(css `calc(10px + calc(5px + 2px))`, {
24
+ simplifier,
25
+ });
26
+ expect(result).toBe('17px');
27
+ });
28
+ it('should simplify calc expressions with variables', async () => {
29
+ const result = resolveCss(css `calc(var(--x) + 5px)`, {
30
+ propertyValues: { '--x': '10px' },
31
+ simplifier,
32
+ });
33
+ expect(result).toBe('15px');
34
+ });
35
+ it('should simplify math fn expressions with static values', async () => {
36
+ let result = resolveCss(css `max(10px, 20px)`, { simplifier });
37
+ expect(result).toBe('20px');
38
+ result = resolveCss(css `min(10px, 20px)`, { simplifier });
39
+ expect(result).toBe('10px');
40
+ result = resolveCss(css `calc(clamp(5px, 10px, 15px))`, { simplifier });
41
+ expect(result).toBe('10px');
42
+ result = resolveCss(css `calc(clamp(5px, calc(10px + 5px), 30px))`, {
43
+ simplifier,
44
+ });
45
+ expect(result).toBe('15px');
46
+ result = resolveCss(css `calc(clamp(5px, var(--x), 30px))`, {
47
+ propertyValues: { '--x': '10px' },
48
+ simplifier,
49
+ });
50
+ expect(result).toBe('10px');
51
+ });
52
+ it('should simplify division of like units', async () => {
53
+ let result = resolveCss(css `calc(10px / 5px)`, { simplifier });
54
+ expect(result).toBe('2');
55
+ result = resolveCss(css `calc((4px / 2px) * 2 * 10px)`, { simplifier });
56
+ expect(result).toBe('40px');
57
+ });
58
+ });
59
+ //# sourceMappingURL=computation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computation.test.js","sourceRoot":"","sources":["../src/computation.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export * from './computation.js';
2
+ export * from './interpolation.js';
3
+ export * from './print.js';
4
+ export * from './resolveProperties.js';
5
+ export * from './simplification.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export * from './computation.js';
2
+ export * from './interpolation.js';
3
+ export * from './print.js';
4
+ export * from './resolveProperties.js';
5
+ export * from './simplification.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { Token } from '@arbor-css/tokens';
2
+ export interface Css {
3
+ text: string;
4
+ tokens: Token[];
5
+ _isCssBrand: true;
6
+ type: 'value' | 'stylesheet';
7
+ }
8
+ export declare function isCss(value: any): value is Css;
9
+ export type TokenFallbackInterpolation = [Token, CssInterpolation];
10
+ export type CssInterpolation = string | number | Token | TokenFallbackInterpolation | Css | Css[];
11
+ export declare function isTokenFallbackInterpolation(value: CssInterpolation): value is TokenFallbackInterpolation;
12
+ export declare function isCssInterpolation(value: any): value is CssInterpolation;
13
+ /**
14
+ * Constructs a CSS value from a string template. Include other
15
+ * values by interpolating them with ${...}. Interpolated tokens
16
+ * will be tracked.
17
+ */
18
+ export declare function css(strings: TemplateStringsArray, ...values: CssInterpolation[]): Css;
19
+ export type CssTemplate = typeof css;
20
+ //# sourceMappingURL=interpolation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interpolation.d.ts","sourceRoot":"","sources":["../src/interpolation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAGnD,MAAM,WAAW,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,WAAW,EAAE,IAAI,CAAC;IAClB,IAAI,EAAE,OAAO,GAAG,YAAY,CAAC;CAC7B;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,IAAI,GAAG,CAS9C;AAED,MAAM,MAAM,0BAA0B,GAAG,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;AACnE,MAAM,MAAM,gBAAgB,GACzB,MAAM,GACN,MAAM,GACN,KAAK,GACL,0BAA0B,GAC1B,GAAG,GACH,GAAG,EAAE,CAAC;AAET,wBAAgB,4BAA4B,CAC3C,KAAK,EAAE,gBAAgB,GACrB,KAAK,IAAI,0BAA0B,CAUrC;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,IAAI,gBAAgB,CAgBxE;AAED;;;;GAIG;AACH,wBAAgB,GAAG,CAClB,OAAO,EAAE,oBAAoB,EAC7B,GAAG,MAAM,EAAE,gBAAgB,EAAE,GAC3B,GAAG,CA4BL;AAED,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,CAAC"}
@@ -0,0 +1,96 @@
1
+ import { isToken } from '@arbor-css/tokens';
2
+ import { isSingleValue } from './util.js';
3
+ export function isCss(value) {
4
+ return (value &&
5
+ typeof value === 'object' &&
6
+ typeof value.text === 'string' &&
7
+ Array.isArray(value.tokens) &&
8
+ value.tokens.every(isToken) &&
9
+ '_isCssBrand' in value);
10
+ }
11
+ export function isTokenFallbackInterpolation(value) {
12
+ return (Array.isArray(value) &&
13
+ value.length === 2 &&
14
+ isToken(value[0]) &&
15
+ (typeof value[1] === 'string' ||
16
+ typeof value[1] === 'number' ||
17
+ isToken(value[1]) ||
18
+ isCss(value[1])));
19
+ }
20
+ export function isCssInterpolation(value) {
21
+ return (typeof value === 'string' ||
22
+ typeof value === 'number' ||
23
+ isToken(value) ||
24
+ isCss(value) ||
25
+ isTokenFallbackInterpolation(value) ||
26
+ (Array.isArray(value) &&
27
+ value.every((v) => typeof v === 'string' ||
28
+ typeof v === 'number' ||
29
+ isToken(v) ||
30
+ isCss(v))));
31
+ }
32
+ /**
33
+ * Constructs a CSS value from a string template. Include other
34
+ * values by interpolating them with ${...}. Interpolated tokens
35
+ * will be tracked.
36
+ */
37
+ export function css(strings, ...values) {
38
+ let text = '';
39
+ const tokens = [];
40
+ strings.forEach((str, i) => {
41
+ text += str;
42
+ if (i < values.length) {
43
+ const value = values[i];
44
+ if (typeof value === 'number' && isNaN(value)) {
45
+ throw new Error(`Invalid CSS interpolation value: ${value} (preceded by ${text}...)`);
46
+ }
47
+ // lookahead past whitespace for next meaningful token char
48
+ const nextTokenMatch = /\S/.exec(strings[i + 1]);
49
+ const nextTokenChar = nextTokenMatch ? nextTokenMatch[0] : '';
50
+ text += resolveInterpolation(value, tokens, nextTokenChar);
51
+ }
52
+ });
53
+ const finalText = text.trim().replace(/\s+/g, ' ');
54
+ // warnArithmeticNotCalcWrapped(finalText);
55
+ return {
56
+ text: finalText,
57
+ tokens,
58
+ _isCssBrand: true,
59
+ type: isSingleValue(finalText) ? 'value' : 'stylesheet',
60
+ };
61
+ }
62
+ function resolveInterpolation(value, tokens, nextCssToken) {
63
+ if (typeof value === 'string' || typeof value === 'number') {
64
+ return `${value}`;
65
+ }
66
+ else if (isCss(value)) {
67
+ tokens.push(...value.tokens);
68
+ return value.text;
69
+ }
70
+ else if (isToken(value)) {
71
+ // for left-hand of assignment, interpolate name and don't add a dependency.
72
+ if (nextCssToken === ':') {
73
+ return value.name;
74
+ }
75
+ tokens.push(value);
76
+ return value.var;
77
+ }
78
+ else if (isTokenFallbackInterpolation(value)) {
79
+ const [token, fallback] = value;
80
+ tokens.push(token);
81
+ const resolvedFallback = resolveInterpolation(fallback, tokens, nextCssToken);
82
+ return token.varFallback(resolvedFallback);
83
+ }
84
+ else if (Array.isArray(value) && value.every(isCss)) {
85
+ return value
86
+ .map((v) => resolveInterpolation(v, tokens, nextCssToken))
87
+ .join('');
88
+ }
89
+ throw new Error(`Invalid CSS interpolation value: ${value}`);
90
+ }
91
+ function warnArithmeticNotCalcWrapped(finalText) {
92
+ if (/\s[+\-*/]\s/.test(finalText) && !/calc\(/.test(finalText)) {
93
+ console.warn(`Warning: CSS value "${finalText}" contains arithmetic operators but does not include calc(). This may lead to unexpected results. Consider wrapping it in calc() for proper evaluation.`);
94
+ }
95
+ }
96
+ //# sourceMappingURL=interpolation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interpolation.js","sourceRoot":"","sources":["../src/interpolation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=interpolation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interpolation.test.d.ts","sourceRoot":"","sources":["../src/interpolation.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import { createTokenFactory } from '@arbor-css/tokens';
2
+ import { expect, it } from 'vitest';
3
+ import { css } from './interpolation.js';
4
+ const createToken = createTokenFactory({ tokenPrefix: '--x-' });
5
+ it('interpolates string and number values', () => {
6
+ expect(css `
7
+ width: ${10}px;
8
+ `.text).toBe('width: 10px;');
9
+ expect(css `
10
+ content: '${'hello'}';
11
+ `.text).toBe("content: 'hello';");
12
+ });
13
+ it('interpolates left-hand usage of token', () => {
14
+ const token = createToken('color');
15
+ const value = css `
16
+ ${token}: red;
17
+ `;
18
+ expect(value.text).toBe('--x-color: red;');
19
+ expect(value.tokens).toEqual([]);
20
+ });
21
+ it('interpolates token values and tracks dependencies', () => {
22
+ const token = createToken('color');
23
+ const value = css `
24
+ color: ${token};
25
+ `;
26
+ expect(value.text).toBe('color: var(--x-color);');
27
+ expect(value.tokens).toEqual([token]);
28
+ });
29
+ //# sourceMappingURL=interpolation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interpolation.test.js","sourceRoot":"","sources":["../src/interpolation.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAEzC,MAAM,WAAW,GAAG,kBAAkB,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;AAEhE,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;IAChD,MAAM,CAAC,GAAG,CAAA;WACA,EAAE;EACX,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC7B,MAAM,CAAC,GAAG,CAAA;cACG,OAAO;EACnB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;AACnC,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;IAChD,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,GAAG,CAAA;IACd,KAAK;EACP,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC3C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAClC,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;IAC5D,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,GAAG,CAAA;WACP,KAAK;EACd,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC"}
package/dist/node.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare const simplifier: (css: import("./interpolation.js").Css) => string;
2
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,UAAU,mDAAmD,CAAC"}
package/dist/node.js ADDED
@@ -0,0 +1,4 @@
1
+ import { transform as transformNative } from 'lightningcss';
2
+ import { createSimplifier } from './simplification.js';
3
+ export const simplifier = createSimplifier({ transform: transformNative });
4
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,CAAC,MAAM,UAAU,GAAG,gBAAgB,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Css } from './interpolation.js';
2
+ export declare function printCss(css: Css): string;
3
+ //# sourceMappingURL=print.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"print.d.ts","sourceRoot":"","sources":["../src/print.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAEzC,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,UAEhC"}
package/dist/print.js ADDED
@@ -0,0 +1,4 @@
1
+ export function printCss(css) {
2
+ return css.text;
3
+ }
4
+ //# sourceMappingURL=print.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"print.js","sourceRoot":"","sources":["../src/print.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,QAAQ,CAAC,GAAQ;IAChC,OAAO,GAAG,CAAC,IAAI,CAAC;AACjB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { Css, CssInterpolation } from './interpolation.js';
2
+ /**
3
+ * Resolves (replaces) property references in the provided CSS
4
+ * with the values from propertyValues. This is used to bake known
5
+ * custom property values into CSS during build time. It also
6
+ * handles updating token dependencies of the returned CSS
7
+ * to reflect any resolved property values, including tokens
8
+ * referenced within the values of resolved properties.
9
+ */
10
+ export declare function resolveProperties(css: Css, propertyValues: Record<string, CssInterpolation>, resolvingStack?: string[]): Css;
11
+ //# sourceMappingURL=resolveProperties.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveProperties.d.ts","sourceRoot":"","sources":["../src/resolveProperties.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,GAAG,EACH,gBAAgB,EAGhB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,GAAG,EAAE,GAAG,EACR,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAChD,cAAc,GAAE,MAAM,EAAO,GAC3B,GAAG,CAwDL"}
@@ -0,0 +1,108 @@
1
+ import { isToken } from '@arbor-css/tokens';
2
+ import { css, isCss, isTokenFallbackInterpolation, } from './interpolation.js';
3
+ /**
4
+ * Resolves (replaces) property references in the provided CSS
5
+ * with the values from propertyValues. This is used to bake known
6
+ * custom property values into CSS during build time. It also
7
+ * handles updating token dependencies of the returned CSS
8
+ * to reflect any resolved property values, including tokens
9
+ * referenced within the values of resolved properties.
10
+ */
11
+ export function resolveProperties(css, propertyValues, resolvingStack = []) {
12
+ const inputText = css.text;
13
+ const tokens = [...css.tokens];
14
+ let result = '';
15
+ let searchIndex = 0;
16
+ while (searchIndex < inputText.length) {
17
+ const startIndex = inputText.indexOf('var(', searchIndex);
18
+ if (startIndex === -1) {
19
+ result += inputText.slice(searchIndex);
20
+ break;
21
+ }
22
+ const endIndex = findMatchingParen(inputText, startIndex + 3);
23
+ if (endIndex === -1) {
24
+ result += inputText.slice(searchIndex);
25
+ break;
26
+ }
27
+ const inner = inputText.slice(startIndex + 4, endIndex);
28
+ const nameMatch = inner.match(/^\s*([^\s,]+)/);
29
+ const property = nameMatch?.[1];
30
+ result += inputText.slice(searchIndex, startIndex);
31
+ searchIndex = endIndex + 1;
32
+ if (property && resolvingStack.includes(property)) {
33
+ // circular - leave unresolved.
34
+ result += `var(${property})`;
35
+ }
36
+ else {
37
+ const propertyValue = !!property && propertyValues[property];
38
+ if (propertyValue) {
39
+ const resolved = resolvePropertyValue(propertyValue, propertyValues, [
40
+ ...resolvingStack,
41
+ property,
42
+ ]);
43
+ tokens.push(...resolved.tokens);
44
+ // remove successfully resolved properties from token dependencies, if present
45
+ for (let i = tokens.length - 1; i >= 0; i--) {
46
+ if (tokens[i].name === property) {
47
+ tokens.splice(i, 1);
48
+ }
49
+ }
50
+ result += resolved.text;
51
+ }
52
+ else {
53
+ result += inputText.slice(startIndex, endIndex + 1);
54
+ }
55
+ }
56
+ }
57
+ return {
58
+ text: result,
59
+ tokens,
60
+ _isCssBrand: true,
61
+ type: css.type,
62
+ };
63
+ }
64
+ function resolvePropertyValue(value, propertyValues, resolvingStack = []) {
65
+ if (typeof value === 'string' || typeof value === 'number') {
66
+ return resolveProperties(css `
67
+ ${value}
68
+ `, propertyValues, resolvingStack);
69
+ }
70
+ else if (isTokenFallbackInterpolation(value)) {
71
+ const [token, fallback] = value;
72
+ const resolvedFallback = resolvePropertyValue(fallback, propertyValues, resolvingStack);
73
+ return css `
74
+ ${[token, resolvedFallback]}
75
+ `;
76
+ }
77
+ else if (isToken(value)) {
78
+ return css `
79
+ ${value}
80
+ `;
81
+ }
82
+ else if (isCss(value)) {
83
+ return resolveProperties(value, propertyValues, resolvingStack);
84
+ }
85
+ else if (Array.isArray(value)) {
86
+ const resolvedParts = value.map((part) => resolvePropertyValue(part, propertyValues, resolvingStack));
87
+ return css `
88
+ ${resolvedParts}
89
+ `;
90
+ }
91
+ throw new Error(`Unsupported property value: ${value}`);
92
+ }
93
+ function findMatchingParen(text, openParenIndex) {
94
+ let depth = 0;
95
+ for (let i = openParenIndex; i < text.length; i++) {
96
+ if (text[i] === '(') {
97
+ depth++;
98
+ }
99
+ else if (text[i] === ')') {
100
+ depth--;
101
+ if (depth === 0) {
102
+ return i;
103
+ }
104
+ }
105
+ }
106
+ return -1;
107
+ }
108
+ //# sourceMappingURL=resolveProperties.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveProperties.js","sourceRoot":"","sources":["../src/resolveProperties.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=resolveProperties.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveProperties.test.d.ts","sourceRoot":"","sources":["../src/resolveProperties.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,97 @@
1
+ import { createTokenFactory } from '@arbor-css/tokens';
2
+ import { expect, it } from 'vitest';
3
+ import { css } from './interpolation.js';
4
+ import { resolveProperties } from './resolveProperties.js';
5
+ const createToken = createTokenFactory({ tokenPrefix: '--' });
6
+ it('replaces plain var values', () => {
7
+ expect(resolveProperties(css `
8
+ color: var(--x);
9
+ `, { '--x': 'red' })).toEqual(css `
10
+ color: red;
11
+ `);
12
+ });
13
+ it('replaces var values with fallbacks', () => {
14
+ expect(resolveProperties(css `
15
+ color: var(--x, blue);
16
+ `, { '--x': 'red' })).toEqual(css `
17
+ color: red;
18
+ `);
19
+ });
20
+ it('resolves properties which are CSS templates', () => {
21
+ expect(resolveProperties(css `
22
+ color: var(--x);
23
+ `, { '--x': css `lighten(red, 10%)` })).toEqual(css `
24
+ color: lighten(red, 10%);
25
+ `);
26
+ });
27
+ it('resolves nested property references', () => {
28
+ expect(resolveProperties(css `
29
+ color: var(--x);
30
+ `, { '--x': 'var(--y)', '--y': 'red' })).toEqual(css `
31
+ color: red;
32
+ `);
33
+ });
34
+ it('resolves nested property references with fallbacks', () => {
35
+ expect(resolveProperties(css `
36
+ color: var(--x, blue);
37
+ `, {
38
+ '--x': 'var(--y, green)',
39
+ '--y': 'red',
40
+ })).toEqual(css `
41
+ color: red;
42
+ `);
43
+ });
44
+ it('resolves nested property references within CSS templates', () => {
45
+ const y = createToken('y');
46
+ expect(resolveProperties(css `
47
+ line-height: var(--x);
48
+ `, {
49
+ '--x': css `calc(${y} * 10%)`,
50
+ [y.name]: '2',
51
+ })).toEqual(css `
52
+ line-height: calc(2 * 10%);
53
+ `);
54
+ // y is resolved, so it should not be included in dependencies.
55
+ });
56
+ it('adds unresolved tokens within property references to dependencies', () => {
57
+ const y = createToken('y');
58
+ const result = resolveProperties(css `
59
+ color: var(--x);
60
+ `, {
61
+ '--x': css `lighten(${y}, 10%)`,
62
+ });
63
+ expect(result.tokens).toContain(y);
64
+ });
65
+ it('does not resolve cyclic token references', () => {
66
+ expect(resolveProperties(css `
67
+ color: var(--x);
68
+ `, {
69
+ '--x': 'var(--y)',
70
+ '--y': 'var(--x)',
71
+ })).toEqual(css `
72
+ color: var(--x);
73
+ `);
74
+ });
75
+ it('handles var(..., ...) wrapped in other params', () => {
76
+ expect(resolveProperties(css `calc(100% - var(--x, 20px))`, {
77
+ '--x': '20px',
78
+ })).toEqual(css `calc(100% - 20px)`);
79
+ });
80
+ it('handles var(..., calc(...)) wrapped in other params', () => {
81
+ expect(resolveProperties(css `calc(100% - var(--x, calc(20px - 1rem)))`, {
82
+ '--x': '20px',
83
+ })).toEqual(css `calc(100% - 20px)`);
84
+ });
85
+ it('handles multiple complex token resolutions', () => {
86
+ const primitiveSpacingSm = createToken('m-primitive-spacing-sm');
87
+ const globalDensity = createToken('m-global-density');
88
+ const baseSpacingSize = createToken('m-global-baseSpacingSize');
89
+ const baseFontSize = createToken('m-global-baseFontSize');
90
+ expect(resolveProperties(css `calc(${primitiveSpacingSm} / ${globalDensity})`, {
91
+ [globalDensity.name]: css `calc(1 + 1)`,
92
+ [primitiveSpacingSm.name]: css `calc((${baseSpacingSize} / ${baseFontSize}) * 1rem * pow(2, 1 * -1))`,
93
+ [baseSpacingSize.name]: '8px',
94
+ [baseFontSize.name]: '16px',
95
+ })).toEqual(css `calc(calc((8px / 16px) * 1rem * pow(2, 1 * -1)) / calc(1 + 1))`);
96
+ });
97
+ //# sourceMappingURL=resolveProperties.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveProperties.test.js","sourceRoot":"","sources":["../src/resolveProperties.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { Css } from './interpolation.js';
2
+ /**
3
+ * Applies simplifications not covered by LightningCSS.
4
+ */
5
+ export declare function simplifyPreprocessCss(css: string): string;
6
+ export type CssSimplifier = (css: Css) => string;
7
+ export type CssTransformFunction = ({ filename, code, }: {
8
+ filename: string;
9
+ code: Uint8Array;
10
+ }) => {
11
+ code: Uint8Array;
12
+ };
13
+ export declare function createSimplifier(config: {
14
+ /**
15
+ * A LightningCSS transform function
16
+ */
17
+ transform: CssTransformFunction;
18
+ }): (css: Css) => string;
19
+ //# sourceMappingURL=simplification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simplification.d.ts","sourceRoot":"","sources":["../src/simplification.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAMzC;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,UAIhD;AAYD,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,CAAC;AACjD,MAAM,MAAM,oBAAoB,GAAG,CAAC,EACnC,QAAQ,EACR,IAAI,GACJ,EAAE;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;CACjB,KAAK;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC;AAE3B,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACxC;;OAEG;IACH,SAAS,EAAE,oBAAoB,CAAC;CAChC,IAGQ,KAAK,GAAG,YAoBhB"}
@@ -0,0 +1,34 @@
1
+ import { unwrapDummyAssignment, wrapWithDummyAssignment } from './util.js';
2
+ const braceMatchingCalcContentExtractor = /calc\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)/g;
3
+ /**
4
+ * Applies simplifications not covered by LightningCSS.
5
+ */
6
+ export function simplifyPreprocessCss(css) {
7
+ return css.replace(braceMatchingCalcContentExtractor, (match) => simplifyLikeUnitDivision(match));
8
+ }
9
+ function simplifyLikeUnitDivision(content) {
10
+ return content.replace(/([0-9]+)([a-z]+)\s*\/\s*([0-9]+)\2/g, (_match, num1, _unit1, num2) => {
11
+ const simplifiedValue = parseFloat(num1) / parseFloat(num2);
12
+ return simplifiedValue.toString();
13
+ });
14
+ }
15
+ export function createSimplifier(config) {
16
+ const enc = new TextEncoder();
17
+ const dec = new TextDecoder();
18
+ return (css) => {
19
+ let cssToTransform = css.text;
20
+ cssToTransform = simplifyPreprocessCss(cssToTransform);
21
+ if (css.type === 'value') {
22
+ cssToTransform = wrapWithDummyAssignment(cssToTransform);
23
+ }
24
+ const result = config.transform({
25
+ filename: 'input.css',
26
+ code: enc.encode(cssToTransform),
27
+ });
28
+ if (css.type === 'value') {
29
+ return unwrapDummyAssignment(dec.decode(result.code));
30
+ }
31
+ return dec.decode(result.code);
32
+ };
33
+ }
34
+ //# sourceMappingURL=simplification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simplification.js","sourceRoot":"","sources":["../src/simplification.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAE3E,MAAM,iCAAiC,GACtC,iDAAiD,CAAC;AAEnD;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAChD,OAAO,GAAG,CAAC,OAAO,CAAC,iCAAiC,EAAE,CAAC,KAAK,EAAE,EAAE,CAC/D,wBAAwB,CAAC,KAAK,CAAC,CAC/B,CAAC;AACH,CAAC;AAED,SAAS,wBAAwB,CAAC,OAAe;IAChD,OAAO,OAAO,CAAC,OAAO,CACrB,qCAAqC,EACrC,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;QAC9B,MAAM,eAAe,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAC5D,OAAO,eAAe,CAAC,QAAQ,EAAE,CAAC;IACnC,CAAC,CACD,CAAC;AACH,CAAC;AAWD,MAAM,UAAU,gBAAgB,CAAC,MAKhC;IACA,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;IAC9B,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;IAC9B,OAAO,CAAC,GAAQ,EAAE,EAAE;QACnB,IAAI,cAAc,GAAG,GAAG,CAAC,IAAI,CAAC;QAE9B,cAAc,GAAG,qBAAqB,CAAC,cAAc,CAAC,CAAC;QAEvD,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC1B,cAAc,GAAG,uBAAuB,CAAC,cAAc,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC;YAC/B,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC;SAChC,CAAC,CAAC;QAEH,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC1B,OAAO,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QACvD,CAAC;QAED,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=simplification.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simplification.test.d.ts","sourceRoot":"","sources":["../src/simplification.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ import { expect, it } from 'vitest';
2
+ import { simplifyPreprocessCss } from './simplification.js';
3
+ it('simplifies same-unit division in calc()', () => {
4
+ expect(simplifyPreprocessCss(`calc(10px / 5px)`)).toEqual(`calc(2)`);
5
+ });
6
+ it('simplifies nested same-unit division in calc()', () => {
7
+ expect(simplifyPreprocessCss(`calc((4px / 2px) * 2 * 10px)`)).toEqual(`calc((2) * 2 * 10px)`);
8
+ });
9
+ it('does not simplify division of different units', () => {
10
+ expect(simplifyPreprocessCss(`calc(10px / 5em)`)).toEqual(`calc(10px / 5em)`);
11
+ });
12
+ it('does not simplify division when units are missing', () => {
13
+ expect(simplifyPreprocessCss(`calc(10 / 5)`)).toEqual(`calc(10 / 5)`);
14
+ });
15
+ //# sourceMappingURL=simplification.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simplification.test.js","sourceRoot":"","sources":["../src/simplification.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;IAClD,MAAM,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;IACzD,MAAM,CAAC,qBAAqB,CAAC,8BAA8B,CAAC,CAAC,CAAC,OAAO,CACpE,sBAAsB,CACtB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;IACxD,MAAM,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAC/E,CAAC,CAAC,CAAC;AAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;IAC5D,MAAM,CAAC,qBAAqB,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;AACvE,CAAC,CAAC,CAAC"}
package/dist/util.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * LightningCSS only supports parsing full
3
+ * stylesheets, but we often need to resolve
4
+ * single CSS values. This checks to see if we
5
+ * need to apply special processing to handle that case.
6
+ */
7
+ export declare function isSingleValue(css: string): boolean;
8
+ export declare function wrapWithDummyAssignment(css: string): string;
9
+ export declare function unwrapDummyAssignment(css: string): string;
10
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAUlD;AAKD,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI3D;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CASzD"}
package/dist/util.js ADDED
@@ -0,0 +1,30 @@
1
+ /**
2
+ * LightningCSS only supports parsing full
3
+ * stylesheets, but we often need to resolve
4
+ * single CSS values. This checks to see if we
5
+ * need to apply special processing to handle that case.
6
+ */
7
+ export function isSingleValue(css) {
8
+ // CSS if() syntax includes colons and semicolons internally.
9
+ // without that, it would be easy... so remove all
10
+ // if(...) calls, using a regex that handles nested parentheses, and then
11
+ // check for colons and semicolons.
12
+ const withoutIf = css.replace(/if\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)/g, '');
13
+ return !withoutIf.includes(':') && !withoutIf.includes(';');
14
+ }
15
+ const dummyPreamble = '[data-arbor-result]{font-size:';
16
+ const dummyPostamble = '}';
17
+ export function wrapWithDummyAssignment(css) {
18
+ // Wrap the input in a dummy assignment to make it parseable as a stylesheet.
19
+ // We can remove this later since we only care about the value of the variable.
20
+ return `${dummyPreamble}${css}${dummyPostamble}`;
21
+ }
22
+ export function unwrapDummyAssignment(css) {
23
+ // Extract the original value from the dummy assignment.
24
+ const match = css.match(/\[data-arbor-result\]\s*{\s*font-size\s*:\s*(.+?)\s*;?\s*}/);
25
+ if (!match) {
26
+ throw new Error('Invalid dummy assignment format');
27
+ }
28
+ return match[1];
29
+ }
30
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IACxC,6DAA6D;IAC7D,kDAAkD;IAClD,yEAAyE;IACzE,mCAAmC;IACnC,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAC5B,+CAA+C,EAC/C,EAAE,CACF,CAAC;IACF,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,aAAa,GAAG,gCAAgC,CAAC;AACvD,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B,MAAM,UAAU,uBAAuB,CAAC,GAAW;IAClD,6EAA6E;IAC7E,+EAA+E;IAC/E,OAAO,GAAG,aAAa,GAAG,GAAG,GAAG,cAAc,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAChD,wDAAwD;IACxD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CACtB,4DAA4D,CAC5D,CAAC;IACF,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=util.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.test.d.ts","sourceRoot":"","sources":["../src/util.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,34 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { isSingleValue, unwrapDummyAssignment, wrapWithDummyAssignment, } from './util.js';
3
+ describe('isSingleValue', () => {
4
+ it('should match literals', () => {
5
+ expect(isSingleValue('10px')).toBe(true);
6
+ expect(isSingleValue('var(--x)')).toBe(true);
7
+ });
8
+ it('should match if() usage', () => {
9
+ expect(isSingleValue('if(style(--foo: 1): 10px)')).toBe(true);
10
+ expect(isSingleValue('if(style(--foo: 1): 10px; else: 20px)')).toBe(true);
11
+ });
12
+ it('should not match assignments', () => {
13
+ expect(isSingleValue('--x: 10px')).toBe(false);
14
+ expect(isSingleValue('--x: var(--y)')).toBe(false);
15
+ });
16
+ it('should not match blocks', () => {
17
+ expect(isSingleValue('color: red;')).toBe(false);
18
+ expect(isSingleValue('&:hover { color: red; }')).toBe(false);
19
+ });
20
+ });
21
+ // more of a sanity check - the transform does something,
22
+ // and is reversed by the unwrap function.
23
+ describe('wrapWithDummyAssignment', () => {
24
+ it('should wrap a single value with a dummy assignment', () => {
25
+ expect(wrapWithDummyAssignment('10px')).not.toBe('10px');
26
+ expect(unwrapDummyAssignment(wrapWithDummyAssignment('10px'))).toBe(`10px`);
27
+ });
28
+ it('should wrap a complex value with a dummy assignment', () => {
29
+ const complexValue = 'if(style(--foo: 1): 10px; else: 20px)';
30
+ expect(wrapWithDummyAssignment(complexValue)).not.toBe(complexValue);
31
+ expect(unwrapDummyAssignment(wrapWithDummyAssignment(complexValue))).toBe(complexValue);
32
+ });
33
+ });
34
+ //# sourceMappingURL=util.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.test.js","sourceRoot":"","sources":["../src/util.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACN,aAAa,EACb,qBAAqB,EACrB,uBAAuB,GACvB,MAAM,WAAW,CAAC;AAEnB,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,aAAa,CAAC,2BAA2B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9D,MAAM,CAAC,aAAa,CAAC,uCAAuC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjD,MAAM,CAAC,aAAa,CAAC,yBAAyB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,yDAAyD;AACzD,0CAA0C;AAC1C,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC7D,MAAM,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzD,MAAM,CAAC,qBAAqB,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC9D,MAAM,YAAY,GAAG,uCAAuC,CAAC;QAC7D,MAAM,CAAC,uBAAuB,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACrE,MAAM,CAAC,qBAAqB,CAAC,uBAAuB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CACxE,YAAY,CACZ,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@arbor-css/css-eval",
3
+ "version": "0.0.109",
4
+ "type": "module",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "repository": {
9
+ "url": "https://github.com/a-type/arbor"
10
+ },
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "exports": {
15
+ ".": {
16
+ "import": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "default": "./dist/index.js"
19
+ },
20
+ "./node": {
21
+ "import": "./dist/node.js",
22
+ "node": "./dist/node.js",
23
+ "types": "./dist/node.d.ts",
24
+ "default": "./dist/node.js"
25
+ },
26
+ "./browser": {
27
+ "import": "./dist/browser.js",
28
+ "browser": "./dist/browser.js",
29
+ "types": "./dist/browser.d.ts",
30
+ "default": "./dist/browser.js"
31
+ }
32
+ },
33
+ "sideEffects": false,
34
+ "devDependencies": {
35
+ "@types/node": "^25.9.1",
36
+ "lightningcss-wasm": "1.32.0",
37
+ "typescript": "^6.0.3",
38
+ "vitest": "^4.1.7"
39
+ },
40
+ "dependencies": {
41
+ "lightningcss": "^1.32.0",
42
+ "@arbor-css/tokens": "0.0.109"
43
+ },
44
+ "scripts": {
45
+ "build": "tsc",
46
+ "dev": "tsc -w --preserveWatchOutput",
47
+ "test": "vitest",
48
+ "test:ci": "vitest --run"
49
+ }
50
+ }