-
Notifications
You must be signed in to change notification settings - Fork 307
/
Copy pathvars.ts
103 lines (87 loc) · 2.71 KB
/
vars.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import {
get,
walkObject,
Contract,
MapLeafNodes,
CSSVarFunction,
} from '@vanilla-extract/private';
import cssesc from 'cssesc';
import { Tokens, NullableTokens, ThemeVars } from './types';
import { validateContract } from './validateContract';
import { generateIdentifier } from './identifier';
export function createVar(debugId?: string): CSSVarFunction {
const cssVarName = cssesc(
generateIdentifier({
debugId,
debugFileName: false,
}),
{ isIdentifier: true },
);
return `var(--${cssVarName})` as const;
}
export function fallbackVar(
...values: [string, ...Array<string>]
): CSSVarFunction {
let finalValue = '';
values.reverse().forEach((value) => {
if (finalValue === '') {
finalValue = String(value);
} else {
if (typeof value !== 'string' || !/^var\(--.*\)$/.test(value)) {
throw new Error(`Invalid variable name: ${value}`);
}
finalValue = value.replace(/\)$/, `, ${finalValue})`);
}
});
return finalValue as CSSVarFunction;
}
export function assignVars<VarContract extends Contract>(
varContract: VarContract,
tokens: MapLeafNodes<VarContract, string>,
): Record<CSSVarFunction, string> {
const varSetters: { [cssVarName: string]: string } = {};
const { valid, diffString } = validateContract(varContract, tokens);
if (!valid) {
throw new Error(`Tokens don't match contract.\n${diffString}`);
}
walkObject(tokens, (value, path) => {
varSetters[get(varContract, path)] = String(value);
});
return varSetters;
}
export function createThemeContract<ThemeTokens extends NullableTokens>(
tokens: ThemeTokens,
): ThemeVars<ThemeTokens> {
return walkObject(tokens, (_value, path) => {
return createVar(path.join('-'));
});
}
export function createGlobalThemeContract<ThemeTokens extends Tokens>(
tokens: ThemeTokens,
): ThemeVars<ThemeTokens>;
export function createGlobalThemeContract<ThemeTokens extends NullableTokens>(
tokens: ThemeTokens,
mapFn: (value: string | null, path: Array<string>) => string,
): ThemeVars<ThemeTokens>;
export function createGlobalThemeContract(
tokens: Tokens | NullableTokens,
mapFn?: (value: string | null, path: Array<string>) => string,
) {
return walkObject(tokens, (value, path) => {
const rawVarName =
typeof mapFn === 'function'
? mapFn(value as string | null, path)
: (value as string);
const varName =
typeof rawVarName === 'string' ? rawVarName.replace(/^\-\-/, '') : null;
if (
typeof varName !== 'string' ||
varName !== cssesc(varName, { isIdentifier: true })
) {
throw new Error(
`Invalid variable name for "${path.join('.')}": ${varName}`,
);
}
return `var(--${varName})`;
});
}