@tamagui/create-theme 2.7.7 → 3.0.0-beta.643.1
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/cjs/createThemes.cjs +100 -0
- package/dist/cjs/createThemes.native.cjs +126 -0
- package/dist/cjs/createThemes.native.js +128 -0
- package/dist/cjs/createThemes.native.js.map +1 -0
- package/dist/cjs/index.cjs +10 -16
- package/dist/cjs/index.native.cjs +21 -0
- package/dist/cjs/index.native.js +11 -16
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/esm/createThemes.mjs +79 -0
- package/dist/esm/createThemes.mjs.map +1 -0
- package/dist/esm/createThemes.native.js +103 -0
- package/dist/esm/createThemes.native.js.map +1 -0
- package/dist/esm/index.js +1 -7
- package/dist/esm/index.mjs +1 -7
- package/dist/esm/index.native.js +1 -7
- package/package.json +6 -7
- package/src/createThemes.tsx +328 -0
- package/src/index.tsx +1 -6
- package/types/createThemes.d.ts +122 -0
- package/types/createThemes.d.ts.map +11 -0
- package/types/index.d.ts +1 -6
- package/types/index.d.ts.map +2 -2
- package/dist/cjs/applyMask.cjs +0 -67
- package/dist/cjs/applyMask.native.js +0 -76
- package/dist/cjs/applyMask.native.js.map +0 -1
- package/dist/cjs/combineMasks.cjs +0 -48
- package/dist/cjs/combineMasks.native.js +0 -73
- package/dist/cjs/combineMasks.native.js.map +0 -1
- package/dist/cjs/createTheme.cjs +0 -105
- package/dist/cjs/createTheme.native.js +0 -111
- package/dist/cjs/createTheme.native.js.map +0 -1
- package/dist/cjs/createThemeTypes.cjs +0 -18
- package/dist/cjs/createThemeTypes.native.js +0 -21
- package/dist/cjs/createThemeTypes.native.js.map +0 -1
- package/dist/cjs/helpers.cjs +0 -36
- package/dist/cjs/helpers.native.js +0 -41
- package/dist/cjs/helpers.native.js.map +0 -1
- package/dist/cjs/isMinusZero.cjs +0 -30
- package/dist/cjs/isMinusZero.native.js +0 -33
- package/dist/cjs/isMinusZero.native.js.map +0 -1
- package/dist/cjs/masks.cjs +0 -146
- package/dist/cjs/masks.native.js +0 -192
- package/dist/cjs/masks.native.js.map +0 -1
- package/dist/cjs/tests.cjs +0 -26
- package/dist/cjs/tests.native.js +0 -29
- package/dist/cjs/tests.native.js.map +0 -1
- package/dist/cjs/themeInfo.cjs +0 -40
- package/dist/cjs/themeInfo.native.js +0 -43
- package/dist/cjs/themeInfo.native.js.map +0 -1
- package/dist/esm/applyMask.mjs +0 -41
- package/dist/esm/applyMask.mjs.map +0 -1
- package/dist/esm/applyMask.native.js +0 -47
- package/dist/esm/applyMask.native.js.map +0 -1
- package/dist/esm/combineMasks.mjs +0 -23
- package/dist/esm/combineMasks.mjs.map +0 -1
- package/dist/esm/combineMasks.native.js +0 -45
- package/dist/esm/combineMasks.native.js.map +0 -1
- package/dist/esm/createTheme.mjs +0 -78
- package/dist/esm/createTheme.mjs.map +0 -1
- package/dist/esm/createTheme.native.js +0 -81
- package/dist/esm/createTheme.native.js.map +0 -1
- package/dist/esm/createThemeTypes.mjs +0 -2
- package/dist/esm/createThemeTypes.mjs.map +0 -1
- package/dist/esm/createThemeTypes.native.js +0 -2
- package/dist/esm/createThemeTypes.native.js.map +0 -1
- package/dist/esm/helpers.mjs +0 -9
- package/dist/esm/helpers.mjs.map +0 -1
- package/dist/esm/helpers.native.js +0 -11
- package/dist/esm/helpers.native.js.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/index.mjs.map +0 -1
- package/dist/esm/index.native.js.map +0 -1
- package/dist/esm/isMinusZero.mjs +0 -5
- package/dist/esm/isMinusZero.mjs.map +0 -1
- package/dist/esm/isMinusZero.native.js +0 -5
- package/dist/esm/isMinusZero.native.js.map +0 -1
- package/dist/esm/masks.mjs +0 -114
- package/dist/esm/masks.mjs.map +0 -1
- package/dist/esm/masks.native.js +0 -157
- package/dist/esm/masks.native.js.map +0 -1
- package/dist/esm/tests.mjs +0 -27
- package/dist/esm/tests.mjs.map +0 -1
- package/dist/esm/tests.native.js +0 -27
- package/dist/esm/tests.native.js.map +0 -1
- package/dist/esm/themeInfo.mjs +0 -14
- package/dist/esm/themeInfo.mjs.map +0 -1
- package/dist/esm/themeInfo.native.js +0 -14
- package/dist/esm/themeInfo.native.js.map +0 -1
- package/src/applyMask.tsx +0 -69
- package/src/combineMasks.tsx +0 -29
- package/src/createTheme.tsx +0 -127
- package/src/createThemeTypes.tsx +0 -85
- package/src/helpers.tsx +0 -44
- package/src/isMinusZero.tsx +0 -3
- package/src/masks.tsx +0 -137
- package/src/tests.tsx +0 -28
- package/src/themeInfo.tsx +0 -36
- package/types/applyMask.d.ts +0 -8
- package/types/applyMask.d.ts.map +0 -11
- package/types/combineMasks.d.ts +0 -4
- package/types/combineMasks.d.ts.map +0 -11
- package/types/createTheme.d.ts +0 -28
- package/types/createTheme.d.ts.map +0 -11
- package/types/createThemeTypes.d.ts +0 -67
- package/types/createThemeTypes.d.ts.map +0 -11
- package/types/helpers.d.ts +0 -18
- package/types/helpers.d.ts.map +0 -11
- package/types/isMinusZero.d.ts +0 -3
- package/types/isMinusZero.d.ts.map +0 -11
- package/types/masks.d.ts +0 -15
- package/types/masks.d.ts.map +0 -11
- package/types/tests.d.ts +0 -3
- package/types/tests.d.ts.map +0 -11
- package/types/themeInfo.d.ts +0 -13
- package/types/themeInfo.d.ts.map +0 -11
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
function createThemes(tokens, tree, options) {
|
|
2
|
+
var rootKeys = Object.keys(tree).filter(function(key) {
|
|
3
|
+
return key !== "children";
|
|
4
|
+
});
|
|
5
|
+
if (rootKeys.length !== 2 || !Object.prototype.hasOwnProperty.call(tree, "light") || !Object.prototype.hasOwnProperty.call(tree, "dark")) {
|
|
6
|
+
throw new Error("createThemes tree must have exactly the roots \"light\" and \"dark\"");
|
|
7
|
+
}
|
|
8
|
+
var themes = {};
|
|
9
|
+
var deduped = /* @__PURE__ */ new Map();
|
|
10
|
+
var add = function(name, definition, parent, inheritedChildren) {
|
|
11
|
+
var _options_getTheme;
|
|
12
|
+
var resolvedDefinition = typeof definition === "function" ? definition({ parent }) : definition;
|
|
13
|
+
if (resolvedDefinition === null) return;
|
|
14
|
+
var { values, children, ...recipeFields } = resolvedDefinition;
|
|
15
|
+
var recipe = {
|
|
16
|
+
...parent,
|
|
17
|
+
...recipeFields
|
|
18
|
+
};
|
|
19
|
+
var unresolved = {
|
|
20
|
+
...options === null || options === void 0 ? void 0 : (_options_getTheme = options.getTheme) === null || _options_getTheme === void 0 ? void 0 : _options_getTheme.call(options, {
|
|
21
|
+
recipe,
|
|
22
|
+
name,
|
|
23
|
+
tokens
|
|
24
|
+
}),
|
|
25
|
+
...values
|
|
26
|
+
};
|
|
27
|
+
var resolved = {};
|
|
28
|
+
for (var key in unresolved) {
|
|
29
|
+
var value = unresolved[key];
|
|
30
|
+
var token = tokens.color[value];
|
|
31
|
+
if (token !== void 0) {
|
|
32
|
+
resolved[key] = token;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
var isColor = value === "transparent" || /^#(?:[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/i.test(value) || /^(?:rgb|rgba|hsl|hsla)\(\s*[^)]+\)$/i.test(value);
|
|
36
|
+
if (isColor) {
|
|
37
|
+
resolved[key] = value;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
var nearest = "";
|
|
41
|
+
var nearestDistance = Number.POSITIVE_INFINITY;
|
|
42
|
+
for (var tokenName in tokens.color) {
|
|
43
|
+
var previous = Array.from({ length: tokenName.length + 1 }, function(_, index) {
|
|
44
|
+
return index;
|
|
45
|
+
});
|
|
46
|
+
for (var valueIndex = 0; valueIndex < value.length; valueIndex++) {
|
|
47
|
+
var diagonal = previous[0];
|
|
48
|
+
previous[0] = valueIndex + 1;
|
|
49
|
+
for (var tokenIndex = 0; tokenIndex < tokenName.length; tokenIndex++) {
|
|
50
|
+
var above = previous[tokenIndex + 1];
|
|
51
|
+
previous[tokenIndex + 1] = Math.min(previous[tokenIndex] + 1, above + 1, diagonal + (value[valueIndex] === tokenName[tokenIndex] ? 0 : 1));
|
|
52
|
+
diagonal = above;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
var distance = previous[tokenName.length];
|
|
56
|
+
if (distance < nearestDistance) {
|
|
57
|
+
nearest = tokenName;
|
|
58
|
+
nearestDistance = distance;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`Invalid color value "${value}" for theme "${name}" key "${key}".${nearest ? ` Did you mean token "${nearest}"?` : ""}`);
|
|
62
|
+
}
|
|
63
|
+
var identity = JSON.stringify(Object.keys(resolved).sort().map(function(key2) {
|
|
64
|
+
return [key2, resolved[key2]];
|
|
65
|
+
}));
|
|
66
|
+
themes[name] = deduped.get(identity) || resolved;
|
|
67
|
+
deduped.set(identity, themes[name]);
|
|
68
|
+
var childSets = [inheritedChildren, children];
|
|
69
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
70
|
+
try {
|
|
71
|
+
for (var _iterator = childSets[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
72
|
+
var childSet = _step.value;
|
|
73
|
+
if (!childSet) continue;
|
|
74
|
+
for (var childName in childSet) {
|
|
75
|
+
var fullName = `${name}_${childName}`;
|
|
76
|
+
if (Object.prototype.hasOwnProperty.call(themes, fullName)) {
|
|
77
|
+
throw new Error(`Duplicate generated theme name "${fullName}"`);
|
|
78
|
+
}
|
|
79
|
+
add(fullName, childSet[childName], recipe);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
} catch (err) {
|
|
83
|
+
_didIteratorError = true;
|
|
84
|
+
_iteratorError = err;
|
|
85
|
+
} finally {
|
|
86
|
+
try {
|
|
87
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
88
|
+
_iterator.return();
|
|
89
|
+
}
|
|
90
|
+
} finally {
|
|
91
|
+
if (_didIteratorError) {
|
|
92
|
+
throw _iteratorError;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
add("light", tree.light, {}, tree.children);
|
|
98
|
+
add("dark", tree.dark, {}, tree.children);
|
|
99
|
+
return themes;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export { createThemes };
|
|
103
|
+
//# sourceMappingURL=createThemes.native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createThemes.native.js","names":[],"sources":["esm/createThemes.native.js"],"sourcesContent":["function createThemes(tokens, tree, options) {\n var rootKeys = Object.keys(tree).filter(function(key) {\n return key !== \"children\";\n });\n if (rootKeys.length !== 2 || !Object.prototype.hasOwnProperty.call(tree, \"light\") || !Object.prototype.hasOwnProperty.call(tree, \"dark\")) {\n throw new Error('createThemes tree must have exactly the roots \"light\" and \"dark\"');\n }\n var themes = {};\n var deduped = /* @__PURE__ */ new Map();\n var add = function(name, definition, parent, inheritedChildren) {\n var _options_getTheme;\n var resolvedDefinition = typeof definition === \"function\" ? definition({\n parent\n }) : definition;\n if (resolvedDefinition === null) return;\n var { values, children, ...recipeFields } = resolvedDefinition;\n var recipe = {\n ...parent,\n ...recipeFields\n };\n var unresolved = {\n ...options === null || options === void 0 ? void 0 : (_options_getTheme = options.getTheme) === null || _options_getTheme === void 0 ? void 0 : _options_getTheme.call(options, {\n recipe,\n name,\n tokens\n }),\n ...values\n };\n var resolved = {};\n for (var key in unresolved) {\n var value = unresolved[key];\n var token = tokens.color[value];\n if (token !== void 0) {\n resolved[key] = token;\n continue;\n }\n var isColor = value === \"transparent\" || /^#(?:[\\da-f]{3,4}|[\\da-f]{6}|[\\da-f]{8})$/i.test(value) || /^(?:rgb|rgba|hsl|hsla)\\(\\s*[^)]+\\)$/i.test(value);\n if (isColor) {\n resolved[key] = value;\n continue;\n }\n var nearest = \"\";\n var nearestDistance = Number.POSITIVE_INFINITY;\n for (var tokenName in tokens.color) {\n var previous = Array.from({\n length: tokenName.length + 1\n }, function(_, index) {\n return index;\n });\n for (var valueIndex = 0; valueIndex < value.length; valueIndex++) {\n var diagonal = previous[0];\n previous[0] = valueIndex + 1;\n for (var tokenIndex = 0; tokenIndex < tokenName.length; tokenIndex++) {\n var above = previous[tokenIndex + 1];\n previous[tokenIndex + 1] = Math.min(previous[tokenIndex] + 1, above + 1, diagonal + (value[valueIndex] === tokenName[tokenIndex] ? 0 : 1));\n diagonal = above;\n }\n }\n var distance = previous[tokenName.length];\n if (distance < nearestDistance) {\n nearest = tokenName;\n nearestDistance = distance;\n }\n }\n throw new Error(`Invalid color value \"${value}\" for theme \"${name}\" key \"${key}\".${nearest ? ` Did you mean token \"${nearest}\"?` : \"\"}`);\n }\n var identity = JSON.stringify(Object.keys(resolved).sort().map(function(key2) {\n return [\n key2,\n resolved[key2]\n ];\n }));\n themes[name] = deduped.get(identity) || resolved;\n deduped.set(identity, themes[name]);\n var childSets = [\n inheritedChildren,\n children\n ];\n var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;\n try {\n for (var _iterator = childSets[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var childSet = _step.value;\n if (!childSet) continue;\n for (var childName in childSet) {\n var fullName = `${name}_${childName}`;\n if (Object.prototype.hasOwnProperty.call(themes, fullName)) {\n throw new Error(`Duplicate generated theme name \"${fullName}\"`);\n }\n add(fullName, childSet[childName], recipe);\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n };\n add(\"light\", tree.light, {}, tree.children);\n add(\"dark\", tree.dark, {}, tree.children);\n return themes;\n}\nexport {\n createThemes\n};\n//# sourceMappingURL=createThemes.js.map\n"],"mappings":"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"}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,7 +1 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export * from "./masks.mjs";
|
|
3
|
-
export * from "./combineMasks.mjs";
|
|
4
|
-
export * from "./applyMask.mjs";
|
|
5
|
-
export * from "./createThemeTypes.mjs";
|
|
6
|
-
export * from "./helpers.mjs";
|
|
7
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
export * from "./createThemes.mjs"
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,7 +1 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export * from "./masks.mjs";
|
|
3
|
-
export * from "./combineMasks.mjs";
|
|
4
|
-
export * from "./applyMask.mjs";
|
|
5
|
-
export * from "./createThemeTypes.mjs";
|
|
6
|
-
export * from "./helpers.mjs";
|
|
7
|
-
//# sourceMappingURL=index.mjs.map
|
|
1
|
+
export * from "./createThemes.mjs"
|
package/dist/esm/index.native.js
CHANGED
|
@@ -1,7 +1 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export * from "./masks.native.js";
|
|
3
|
-
export * from "./combineMasks.native.js";
|
|
4
|
-
export * from "./applyMask.native.js";
|
|
5
|
-
export * from "./createThemeTypes.native.js";
|
|
6
|
-
export * from "./helpers.native.js";
|
|
7
|
-
//# sourceMappingURL=index.native.js.map
|
|
1
|
+
export * from "./createThemes.native.js"
|
package/package.json
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/create-theme",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-beta.643.1",
|
|
4
4
|
"files": [
|
|
5
5
|
"src",
|
|
6
6
|
"types",
|
|
7
|
-
"dist"
|
|
8
|
-
"theme-builder"
|
|
7
|
+
"dist"
|
|
9
8
|
],
|
|
10
9
|
"type": "module",
|
|
11
10
|
"sideEffects": false,
|
|
@@ -29,15 +28,15 @@
|
|
|
29
28
|
},
|
|
30
29
|
"scripts": {
|
|
31
30
|
"build": "tamagui-build",
|
|
31
|
+
"test": "bun test tests/createThemes.test.ts",
|
|
32
|
+
"test:types": "vitest --typecheck --run tests/createThemes.test-d.ts",
|
|
32
33
|
"watch": "tamagui-build --watch",
|
|
33
34
|
"clean": "tamagui-build clean",
|
|
34
35
|
"clean:build": "tamagui-build clean:build"
|
|
35
36
|
},
|
|
36
|
-
"dependencies": {
|
|
37
|
-
"@tamagui/web": "2.7.7"
|
|
38
|
-
},
|
|
39
37
|
"devDependencies": {
|
|
40
|
-
"@tamagui/build": "
|
|
38
|
+
"@tamagui/build": "3.0.0-beta.643.1",
|
|
39
|
+
"vitest": "4.0.4"
|
|
41
40
|
},
|
|
42
41
|
"repository": {
|
|
43
42
|
"type": "git",
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
export type ThemeValue = string
|
|
2
|
+
|
|
3
|
+
export type ThemeTokens = {
|
|
4
|
+
color: Record<string, ThemeValue>
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type ThemeRecipe = Record<string, unknown>
|
|
8
|
+
|
|
9
|
+
export type ThemeDefinitionContext<Parent extends ThemeRecipe = ThemeRecipe> = {
|
|
10
|
+
parent: Parent
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type ThemeDefinitionObject = {
|
|
14
|
+
values?: Record<string, ThemeValue>
|
|
15
|
+
children?: ThemeChildren
|
|
16
|
+
[key: string]: unknown
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type ThemeTreeDefinition<Parent extends ThemeRecipe = ThemeRecipe> =
|
|
20
|
+
| ThemeDefinitionObject
|
|
21
|
+
| ((context: ThemeDefinitionContext<Parent>) => ThemeDefinitionObject | null)
|
|
22
|
+
|
|
23
|
+
export type ThemeChildren = Record<string, ThemeTreeDefinition>
|
|
24
|
+
|
|
25
|
+
export type ThemeTree = {
|
|
26
|
+
light: ThemeTreeDefinition
|
|
27
|
+
dark: ThemeTreeDefinition
|
|
28
|
+
children?: ThemeChildren
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
type ColorLiteral = `#${string}` | `rgb${string}` | `hsl${string}` | 'transparent'
|
|
32
|
+
|
|
33
|
+
type ThemeInputValue<Tokens extends ThemeTokens> =
|
|
34
|
+
| Extract<keyof Tokens['color'], string>
|
|
35
|
+
| ColorLiteral
|
|
36
|
+
|
|
37
|
+
type ResolvedDefinition<Definition> = Definition extends (...args: any[]) => infer Result
|
|
38
|
+
? Exclude<Result, null>
|
|
39
|
+
: Definition
|
|
40
|
+
|
|
41
|
+
type DefinitionChildren<Definition> =
|
|
42
|
+
ResolvedDefinition<Definition> extends {
|
|
43
|
+
children?: infer Children
|
|
44
|
+
}
|
|
45
|
+
? Children
|
|
46
|
+
: never
|
|
47
|
+
|
|
48
|
+
type ChildThemeNames<Parent extends string, Children> =
|
|
49
|
+
Children extends Record<string, unknown>
|
|
50
|
+
? {
|
|
51
|
+
[Name in Extract<keyof Children, string>]:
|
|
52
|
+
| `${Parent}_${Name}`
|
|
53
|
+
| ChildThemeNames<`${Parent}_${Name}`, DefinitionChildren<Children[Name]>>
|
|
54
|
+
}[Extract<keyof Children, string>]
|
|
55
|
+
: never
|
|
56
|
+
|
|
57
|
+
export type ThemeNames<Tree extends ThemeTree> =
|
|
58
|
+
| 'light'
|
|
59
|
+
| 'dark'
|
|
60
|
+
| ChildThemeNames<'light', Tree['children']>
|
|
61
|
+
| ChildThemeNames<'dark', Tree['children']>
|
|
62
|
+
| ChildThemeNames<'light', DefinitionChildren<Tree['light']>>
|
|
63
|
+
| ChildThemeNames<'dark', DefinitionChildren<Tree['dark']>>
|
|
64
|
+
|
|
65
|
+
type RecipeFields<Definition> = Omit<
|
|
66
|
+
ResolvedDefinition<Definition>,
|
|
67
|
+
'children' | 'values'
|
|
68
|
+
>
|
|
69
|
+
|
|
70
|
+
type ChildDefinitions<
|
|
71
|
+
Children,
|
|
72
|
+
Depth extends readonly unknown[],
|
|
73
|
+
> = Depth extends readonly [unknown, ...infer Rest]
|
|
74
|
+
? Children extends Record<string, unknown>
|
|
75
|
+
? Children[keyof Children] | DefinitionsWithin<Children[keyof Children], Rest>
|
|
76
|
+
: never
|
|
77
|
+
: never
|
|
78
|
+
|
|
79
|
+
type DefinitionsWithin<Definition, Depth extends readonly unknown[]> =
|
|
80
|
+
| Definition
|
|
81
|
+
| ChildDefinitions<DefinitionChildren<Definition>, Depth>
|
|
82
|
+
|
|
83
|
+
type DefinitionsInTree<Tree extends ThemeTree> =
|
|
84
|
+
| DefinitionsWithin<Tree['light'], [1, 1, 1, 1, 1, 1]>
|
|
85
|
+
| DefinitionsWithin<Tree['dark'], [1, 1, 1, 1, 1, 1]>
|
|
86
|
+
| ChildDefinitions<Tree['children'], [1, 1, 1, 1, 1, 1]>
|
|
87
|
+
|
|
88
|
+
type KeysOfUnion<Union> = Union extends Union ? keyof Union : never
|
|
89
|
+
|
|
90
|
+
type ValueOfUnion<Union, Key extends PropertyKey> = Union extends Union
|
|
91
|
+
? Key extends keyof Union
|
|
92
|
+
? Union[Key]
|
|
93
|
+
: never
|
|
94
|
+
: never
|
|
95
|
+
|
|
96
|
+
type MergeRecipeUnion<Union> = {
|
|
97
|
+
[Key in KeysOfUnion<Union>]: ValueOfUnion<Union, Key>
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
type RootRecipe<Tree extends ThemeTree> =
|
|
101
|
+
| RecipeFields<Tree['light']>
|
|
102
|
+
| RecipeFields<Tree['dark']>
|
|
103
|
+
|
|
104
|
+
type RecipeForTree<Tree extends ThemeTree> = {
|
|
105
|
+
[Key in keyof RootRecipe<Tree>]: ValueOfUnion<RootRecipe<Tree>, Key>
|
|
106
|
+
} & Partial<MergeRecipeUnion<RecipeFields<DefinitionsInTree<Tree>>>>
|
|
107
|
+
|
|
108
|
+
export type GetThemeContext<
|
|
109
|
+
Tokens extends ThemeTokens = ThemeTokens,
|
|
110
|
+
Recipe extends ThemeRecipe = ThemeRecipe,
|
|
111
|
+
> = {
|
|
112
|
+
recipe: Recipe
|
|
113
|
+
name: string
|
|
114
|
+
tokens: Tokens
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
type InvalidValueKeys<Values, Theme> = Exclude<keyof Values, keyof Theme>
|
|
118
|
+
|
|
119
|
+
type ValidatedValues<Values, Theme, Tokens extends ThemeTokens> =
|
|
120
|
+
Values extends Record<string, unknown>
|
|
121
|
+
? Values & {
|
|
122
|
+
[Key in InvalidValueKeys<Values, Theme>]: never
|
|
123
|
+
} & {
|
|
124
|
+
[Key in keyof Values]: Values[Key] extends ThemeInputValue<Tokens>
|
|
125
|
+
? Values[Key]
|
|
126
|
+
: never
|
|
127
|
+
}
|
|
128
|
+
: never
|
|
129
|
+
|
|
130
|
+
type ValidatedChildren<Children, Theme, Tokens extends ThemeTokens> =
|
|
131
|
+
Children extends Record<string, unknown>
|
|
132
|
+
? {
|
|
133
|
+
[Name in keyof Children]: ValidatedDefinition<Children[Name], Theme, Tokens>
|
|
134
|
+
}
|
|
135
|
+
: never
|
|
136
|
+
|
|
137
|
+
type ValidatedDefinition<
|
|
138
|
+
Definition,
|
|
139
|
+
Theme,
|
|
140
|
+
Tokens extends ThemeTokens,
|
|
141
|
+
> = Definition extends (...args: infer Args) => infer Result
|
|
142
|
+
? (
|
|
143
|
+
...args: Args
|
|
144
|
+
) => Result extends null ? null : ValidatedDefinitionObject<Result, Theme, Tokens>
|
|
145
|
+
: ValidatedDefinitionObject<Definition, Theme, Tokens>
|
|
146
|
+
|
|
147
|
+
type ValidatedDefinitionObject<Definition, Theme, Tokens extends ThemeTokens> =
|
|
148
|
+
Definition extends Record<string, unknown>
|
|
149
|
+
? Definition &
|
|
150
|
+
('values' extends keyof Definition
|
|
151
|
+
? {
|
|
152
|
+
values: ValidatedValues<Definition['values'], Theme, Tokens>
|
|
153
|
+
}
|
|
154
|
+
: unknown) &
|
|
155
|
+
('children' extends keyof Definition
|
|
156
|
+
? {
|
|
157
|
+
children: ValidatedChildren<Definition['children'], Theme, Tokens>
|
|
158
|
+
}
|
|
159
|
+
: unknown)
|
|
160
|
+
: never
|
|
161
|
+
|
|
162
|
+
type ValidatedTree<Tree extends ThemeTree, Theme, Tokens extends ThemeTokens> = Tree & {
|
|
163
|
+
light: ValidatedDefinition<Tree['light'], Theme, Tokens>
|
|
164
|
+
dark: ValidatedDefinition<Tree['dark'], Theme, Tokens>
|
|
165
|
+
children?: ValidatedChildren<Tree['children'], Theme, Tokens>
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
type ValuesInDefinition<Definition> =
|
|
169
|
+
ResolvedDefinition<Definition> extends {
|
|
170
|
+
values?: infer Values
|
|
171
|
+
}
|
|
172
|
+
? Values
|
|
173
|
+
: never
|
|
174
|
+
|
|
175
|
+
type ValueDefinitionsWithin<Definition, Depth extends readonly unknown[]> =
|
|
176
|
+
| ValuesInDefinition<Definition>
|
|
177
|
+
| (Depth extends readonly [unknown, ...infer Rest]
|
|
178
|
+
? DefinitionChildren<Definition> extends infer Children
|
|
179
|
+
? Children extends Record<string, unknown>
|
|
180
|
+
? ValueDefinitionsWithin<Children[keyof Children], Rest>
|
|
181
|
+
: never
|
|
182
|
+
: never
|
|
183
|
+
: never)
|
|
184
|
+
|
|
185
|
+
type ExplicitTheme<Tree extends ThemeTree> = MergeRecipeUnion<
|
|
186
|
+
| ValueDefinitionsWithin<Tree['light'], [1, 1, 1, 1, 1, 1]>
|
|
187
|
+
| ValueDefinitionsWithin<Tree['dark'], [1, 1, 1, 1, 1, 1]>
|
|
188
|
+
| (Tree['children'] extends infer Children
|
|
189
|
+
? Children extends Record<string, unknown>
|
|
190
|
+
? ValueDefinitionsWithin<Children[keyof Children], [1, 1, 1, 1, 1, 1]>
|
|
191
|
+
: never
|
|
192
|
+
: never)
|
|
193
|
+
>
|
|
194
|
+
|
|
195
|
+
export type CreatedThemes<Names extends string, Theme extends Record<string, string>> = {
|
|
196
|
+
[Name in Names]: { [Key in keyof Theme]: string }
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export function createThemes<
|
|
200
|
+
const Tokens extends ThemeTokens,
|
|
201
|
+
const Tree extends ThemeTree,
|
|
202
|
+
const Theme extends Record<string, ThemeInputValue<Tokens>>,
|
|
203
|
+
>(
|
|
204
|
+
tokens: Tokens,
|
|
205
|
+
tree: ValidatedTree<Tree, Theme, Tokens>,
|
|
206
|
+
options: {
|
|
207
|
+
getTheme: (context: GetThemeContext<Tokens, RecipeForTree<Tree>>) => Theme
|
|
208
|
+
}
|
|
209
|
+
): CreatedThemes<ThemeNames<Tree>, Theme>
|
|
210
|
+
|
|
211
|
+
export function createThemes<
|
|
212
|
+
const Tokens extends ThemeTokens,
|
|
213
|
+
const Tree extends ThemeTree,
|
|
214
|
+
>(
|
|
215
|
+
tokens: Tokens,
|
|
216
|
+
tree: ValidatedTree<Tree, Record<string, string>, Tokens>,
|
|
217
|
+
options?: { getTheme?: undefined }
|
|
218
|
+
): CreatedThemes<ThemeNames<Tree>, ExplicitTheme<Tree>>
|
|
219
|
+
|
|
220
|
+
export function createThemes(
|
|
221
|
+
tokens: ThemeTokens,
|
|
222
|
+
tree: ThemeTree,
|
|
223
|
+
options?: {
|
|
224
|
+
getTheme?: (context: GetThemeContext) => Record<string, string>
|
|
225
|
+
}
|
|
226
|
+
): Record<string, Record<string, string>> {
|
|
227
|
+
const rootKeys = Object.keys(tree).filter((key) => key !== 'children')
|
|
228
|
+
if (
|
|
229
|
+
rootKeys.length !== 2 ||
|
|
230
|
+
!Object.prototype.hasOwnProperty.call(tree, 'light') ||
|
|
231
|
+
!Object.prototype.hasOwnProperty.call(tree, 'dark')
|
|
232
|
+
) {
|
|
233
|
+
throw new Error('createThemes tree must have exactly the roots "light" and "dark"')
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const themes: Record<string, Record<string, string>> = {}
|
|
237
|
+
const deduped = new Map<string, Record<string, string>>()
|
|
238
|
+
|
|
239
|
+
const add = (
|
|
240
|
+
name: string,
|
|
241
|
+
definition: ThemeTreeDefinition,
|
|
242
|
+
parent: ThemeRecipe,
|
|
243
|
+
inheritedChildren?: ThemeChildren
|
|
244
|
+
): void => {
|
|
245
|
+
const resolvedDefinition =
|
|
246
|
+
typeof definition === 'function' ? definition({ parent }) : definition
|
|
247
|
+
if (resolvedDefinition === null) return
|
|
248
|
+
|
|
249
|
+
const { values, children, ...recipeFields } = resolvedDefinition
|
|
250
|
+
const recipe = { ...parent, ...recipeFields }
|
|
251
|
+
const unresolved = {
|
|
252
|
+
...options?.getTheme?.({ recipe, name, tokens }),
|
|
253
|
+
...values,
|
|
254
|
+
}
|
|
255
|
+
const resolved: Record<string, string> = {}
|
|
256
|
+
|
|
257
|
+
for (const key in unresolved) {
|
|
258
|
+
const value = unresolved[key]
|
|
259
|
+
const token = tokens.color[value]
|
|
260
|
+
if (token !== undefined) {
|
|
261
|
+
resolved[key] = token
|
|
262
|
+
continue
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const isColor =
|
|
266
|
+
value === 'transparent' ||
|
|
267
|
+
/^#(?:[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/i.test(value) ||
|
|
268
|
+
/^(?:rgb|rgba|hsl|hsla)\(\s*[^)]+\)$/i.test(value)
|
|
269
|
+
if (isColor) {
|
|
270
|
+
resolved[key] = value
|
|
271
|
+
continue
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
let nearest = ''
|
|
275
|
+
let nearestDistance = Number.POSITIVE_INFINITY
|
|
276
|
+
for (const tokenName in tokens.color) {
|
|
277
|
+
const previous = Array.from({ length: tokenName.length + 1 }, (_, index) => index)
|
|
278
|
+
for (let valueIndex = 0; valueIndex < value.length; valueIndex++) {
|
|
279
|
+
let diagonal = previous[0]!
|
|
280
|
+
previous[0] = valueIndex + 1
|
|
281
|
+
for (let tokenIndex = 0; tokenIndex < tokenName.length; tokenIndex++) {
|
|
282
|
+
const above = previous[tokenIndex + 1]!
|
|
283
|
+
previous[tokenIndex + 1] = Math.min(
|
|
284
|
+
previous[tokenIndex]! + 1,
|
|
285
|
+
above + 1,
|
|
286
|
+
diagonal + (value[valueIndex] === tokenName[tokenIndex] ? 0 : 1)
|
|
287
|
+
)
|
|
288
|
+
diagonal = above
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
const distance = previous[tokenName.length]!
|
|
292
|
+
if (distance < nearestDistance) {
|
|
293
|
+
nearest = tokenName
|
|
294
|
+
nearestDistance = distance
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
throw new Error(
|
|
299
|
+
`Invalid color value "${value}" for theme "${name}" key "${key}".${nearest ? ` Did you mean token "${nearest}"?` : ''}`
|
|
300
|
+
)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const identity = JSON.stringify(
|
|
304
|
+
Object.keys(resolved)
|
|
305
|
+
.sort()
|
|
306
|
+
.map((key) => [key, resolved[key]])
|
|
307
|
+
)
|
|
308
|
+
themes[name] = deduped.get(identity) || resolved
|
|
309
|
+
deduped.set(identity, themes[name]!)
|
|
310
|
+
|
|
311
|
+
const childSets = [inheritedChildren, children]
|
|
312
|
+
for (const childSet of childSets) {
|
|
313
|
+
if (!childSet) continue
|
|
314
|
+
for (const childName in childSet) {
|
|
315
|
+
const fullName = `${name}_${childName}`
|
|
316
|
+
if (Object.prototype.hasOwnProperty.call(themes, fullName)) {
|
|
317
|
+
throw new Error(`Duplicate generated theme name "${fullName}"`)
|
|
318
|
+
}
|
|
319
|
+
add(fullName, childSet[childName]!, recipe)
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
add('light', tree.light, {}, tree.children)
|
|
325
|
+
add('dark', tree.dark, {}, tree.children)
|
|
326
|
+
|
|
327
|
+
return themes
|
|
328
|
+
}
|
package/src/index.tsx
CHANGED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
export type ThemeValue = string;
|
|
2
|
+
export type ThemeTokens = {
|
|
3
|
+
color: Record<string, ThemeValue>;
|
|
4
|
+
};
|
|
5
|
+
export type ThemeRecipe = Record<string, unknown>;
|
|
6
|
+
export type ThemeDefinitionContext<Parent extends ThemeRecipe = ThemeRecipe> = {
|
|
7
|
+
parent: Parent;
|
|
8
|
+
};
|
|
9
|
+
export type ThemeDefinitionObject = {
|
|
10
|
+
values?: Record<string, ThemeValue>;
|
|
11
|
+
children?: ThemeChildren;
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
};
|
|
14
|
+
export type ThemeTreeDefinition<Parent extends ThemeRecipe = ThemeRecipe> = ThemeDefinitionObject | ((context: ThemeDefinitionContext<Parent>) => ThemeDefinitionObject | null);
|
|
15
|
+
export type ThemeChildren = Record<string, ThemeTreeDefinition>;
|
|
16
|
+
export type ThemeTree = {
|
|
17
|
+
light: ThemeTreeDefinition;
|
|
18
|
+
dark: ThemeTreeDefinition;
|
|
19
|
+
children?: ThemeChildren;
|
|
20
|
+
};
|
|
21
|
+
type ColorLiteral = `#${string}` | `rgb${string}` | `hsl${string}` | "transparent";
|
|
22
|
+
type ThemeInputValue<Tokens extends ThemeTokens> = Extract<keyof Tokens["color"], string> | ColorLiteral;
|
|
23
|
+
type ResolvedDefinition<Definition> = Definition extends (...args: any[]) => infer Result ? Exclude<Result, null> : Definition;
|
|
24
|
+
type DefinitionChildren<Definition> = ResolvedDefinition<Definition> extends {
|
|
25
|
+
children?: infer Children;
|
|
26
|
+
} ? Children : never;
|
|
27
|
+
type ChildThemeNames<
|
|
28
|
+
Parent extends string,
|
|
29
|
+
Children
|
|
30
|
+
> = Children extends Record<string, unknown> ? { [Name in Extract<keyof Children, string>] : `${Parent}_${Name}` | ChildThemeNames<`${Parent}_${Name}`, DefinitionChildren<Children[Name]>> }[Extract<keyof Children, string>] : never;
|
|
31
|
+
export type ThemeNames<Tree extends ThemeTree> = "light" | "dark" | ChildThemeNames<"light", Tree["children"]> | ChildThemeNames<"dark", Tree["children"]> | ChildThemeNames<"light", DefinitionChildren<Tree["light"]>> | ChildThemeNames<"dark", DefinitionChildren<Tree["dark"]>>;
|
|
32
|
+
type RecipeFields<Definition> = Omit<ResolvedDefinition<Definition>, "children" | "values">;
|
|
33
|
+
type ChildDefinitions<
|
|
34
|
+
Children,
|
|
35
|
+
Depth extends readonly unknown[]
|
|
36
|
+
> = Depth extends readonly [unknown, ...infer Rest] ? Children extends Record<string, unknown> ? Children[keyof Children] | DefinitionsWithin<Children[keyof Children], Rest> : never : never;
|
|
37
|
+
type DefinitionsWithin<
|
|
38
|
+
Definition,
|
|
39
|
+
Depth extends readonly unknown[]
|
|
40
|
+
> = Definition | ChildDefinitions<DefinitionChildren<Definition>, Depth>;
|
|
41
|
+
type DefinitionsInTree<Tree extends ThemeTree> = DefinitionsWithin<Tree["light"], [1, 1, 1, 1, 1, 1]> | DefinitionsWithin<Tree["dark"], [1, 1, 1, 1, 1, 1]> | ChildDefinitions<Tree["children"], [1, 1, 1, 1, 1, 1]>;
|
|
42
|
+
type KeysOfUnion<Union> = Union extends Union ? keyof Union : never;
|
|
43
|
+
type ValueOfUnion<
|
|
44
|
+
Union,
|
|
45
|
+
Key extends PropertyKey
|
|
46
|
+
> = Union extends Union ? Key extends keyof Union ? Union[Key] : never : never;
|
|
47
|
+
type MergeRecipeUnion<Union> = { [Key in KeysOfUnion<Union>] : ValueOfUnion<Union, Key> };
|
|
48
|
+
type RootRecipe<Tree extends ThemeTree> = RecipeFields<Tree["light"]> | RecipeFields<Tree["dark"]>;
|
|
49
|
+
type RecipeForTree<Tree extends ThemeTree> = { [Key in keyof RootRecipe<Tree>] : ValueOfUnion<RootRecipe<Tree>, Key> } & Partial<MergeRecipeUnion<RecipeFields<DefinitionsInTree<Tree>>>>;
|
|
50
|
+
export type GetThemeContext<
|
|
51
|
+
Tokens extends ThemeTokens = ThemeTokens,
|
|
52
|
+
Recipe extends ThemeRecipe = ThemeRecipe
|
|
53
|
+
> = {
|
|
54
|
+
recipe: Recipe;
|
|
55
|
+
name: string;
|
|
56
|
+
tokens: Tokens;
|
|
57
|
+
};
|
|
58
|
+
type InvalidValueKeys<
|
|
59
|
+
Values,
|
|
60
|
+
Theme
|
|
61
|
+
> = Exclude<keyof Values, keyof Theme>;
|
|
62
|
+
type ValidatedValues<
|
|
63
|
+
Values,
|
|
64
|
+
Theme,
|
|
65
|
+
Tokens extends ThemeTokens
|
|
66
|
+
> = Values extends Record<string, unknown> ? Values & { [Key in InvalidValueKeys<Values, Theme>] : never } & { [Key in keyof Values] : Values[Key] extends ThemeInputValue<Tokens> ? Values[Key] : never } : never;
|
|
67
|
+
type ValidatedChildren<
|
|
68
|
+
Children,
|
|
69
|
+
Theme,
|
|
70
|
+
Tokens extends ThemeTokens
|
|
71
|
+
> = Children extends Record<string, unknown> ? { [Name in keyof Children] : ValidatedDefinition<Children[Name], Theme, Tokens> } : never;
|
|
72
|
+
type ValidatedDefinition<
|
|
73
|
+
Definition,
|
|
74
|
+
Theme,
|
|
75
|
+
Tokens extends ThemeTokens
|
|
76
|
+
> = Definition extends (...args: infer Args) => infer Result ? (...args: Args) => Result extends null ? null : ValidatedDefinitionObject<Result, Theme, Tokens> : ValidatedDefinitionObject<Definition, Theme, Tokens>;
|
|
77
|
+
type ValidatedDefinitionObject<
|
|
78
|
+
Definition,
|
|
79
|
+
Theme,
|
|
80
|
+
Tokens extends ThemeTokens
|
|
81
|
+
> = Definition extends Record<string, unknown> ? Definition & ("values" extends keyof Definition ? {
|
|
82
|
+
values: ValidatedValues<Definition["values"], Theme, Tokens>;
|
|
83
|
+
} : unknown) & ("children" extends keyof Definition ? {
|
|
84
|
+
children: ValidatedChildren<Definition["children"], Theme, Tokens>;
|
|
85
|
+
} : unknown) : never;
|
|
86
|
+
type ValidatedTree<
|
|
87
|
+
Tree extends ThemeTree,
|
|
88
|
+
Theme,
|
|
89
|
+
Tokens extends ThemeTokens
|
|
90
|
+
> = Tree & {
|
|
91
|
+
light: ValidatedDefinition<Tree["light"], Theme, Tokens>;
|
|
92
|
+
dark: ValidatedDefinition<Tree["dark"], Theme, Tokens>;
|
|
93
|
+
children?: ValidatedChildren<Tree["children"], Theme, Tokens>;
|
|
94
|
+
};
|
|
95
|
+
type ValuesInDefinition<Definition> = ResolvedDefinition<Definition> extends {
|
|
96
|
+
values?: infer Values;
|
|
97
|
+
} ? Values : never;
|
|
98
|
+
type ValueDefinitionsWithin<
|
|
99
|
+
Definition,
|
|
100
|
+
Depth extends readonly unknown[]
|
|
101
|
+
> = ValuesInDefinition<Definition> | (Depth extends readonly [unknown, ...infer Rest] ? DefinitionChildren<Definition> extends infer Children ? Children extends Record<string, unknown> ? ValueDefinitionsWithin<Children[keyof Children], Rest> : never : never : never);
|
|
102
|
+
type ExplicitTheme<Tree extends ThemeTree> = MergeRecipeUnion<ValueDefinitionsWithin<Tree["light"], [1, 1, 1, 1, 1, 1]> | ValueDefinitionsWithin<Tree["dark"], [1, 1, 1, 1, 1, 1]> | (Tree["children"] extends infer Children ? Children extends Record<string, unknown> ? ValueDefinitionsWithin<Children[keyof Children], [1, 1, 1, 1, 1, 1]> : never : never)>;
|
|
103
|
+
export type CreatedThemes<
|
|
104
|
+
Names extends string,
|
|
105
|
+
Theme extends Record<string, string>
|
|
106
|
+
> = { [Name in Names] : { [Key in keyof Theme] : string } };
|
|
107
|
+
export declare function createThemes<
|
|
108
|
+
const Tokens extends ThemeTokens,
|
|
109
|
+
const Tree extends ThemeTree,
|
|
110
|
+
const Theme extends Record<string, ThemeInputValue<Tokens>>
|
|
111
|
+
>(tokens: Tokens, tree: ValidatedTree<Tree, Theme, Tokens>, options: {
|
|
112
|
+
getTheme: (context: GetThemeContext<Tokens, RecipeForTree<Tree>>) => Theme;
|
|
113
|
+
}): CreatedThemes<ThemeNames<Tree>, Theme>;
|
|
114
|
+
export declare function createThemes<
|
|
115
|
+
const Tokens extends ThemeTokens,
|
|
116
|
+
const Tree extends ThemeTree
|
|
117
|
+
>(tokens: Tokens, tree: ValidatedTree<Tree, Record<string, string>, Tokens>, options?: {
|
|
118
|
+
getTheme?: undefined;
|
|
119
|
+
}): CreatedThemes<ThemeNames<Tree>, ExplicitTheme<Tree>>;
|
|
120
|
+
export {};
|
|
121
|
+
|
|
122
|
+
//# sourceMappingURL=createThemes.d.ts.map
|