@react-native-rethemed/core 0.1.0 → 0.1.2
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/README.md +2 -0
- package/dist/color-mode-store.cjs +57 -0
- package/dist/color-mode-store.d.cts +11 -0
- package/dist/color-mode-store.d.mts +11 -0
- package/dist/color-mode-store.mjs +56 -0
- package/dist/config.cjs +26 -0
- package/dist/config.d.cts +8 -0
- package/dist/config.d.mts +8 -0
- package/dist/config.mjs +7 -0
- package/dist/create-themed-styles.cjs +31 -0
- package/dist/{esm/create-themed-styles.d.ts → create-themed-styles.d.cts} +4 -2
- package/dist/{cjs/create-themed-styles.d.ts → create-themed-styles.d.mts} +4 -2
- package/dist/create-themed-styles.mjs +31 -0
- package/dist/create-themed.cjs +93 -0
- package/dist/create-themed.d.cts +48 -0
- package/dist/create-themed.d.mts +48 -0
- package/dist/create-themed.mjs +93 -0
- package/dist/define-theme.cjs +15 -0
- package/dist/{esm/define-theme.d.ts → define-theme.d.cts} +3 -1
- package/dist/{cjs/define-theme.d.ts → define-theme.d.mts} +3 -1
- package/dist/define-theme.mjs +15 -0
- package/dist/extend-theme.cjs +109 -0
- package/dist/{esm/extend-theme.d.ts → extend-theme.d.cts} +3 -1
- package/dist/{cjs/extend-theme.d.ts → extend-theme.d.mts} +3 -1
- package/dist/extend-theme.mjs +109 -0
- package/dist/index.cjs +30 -0
- package/dist/index.d.cts +13 -0
- package/dist/index.d.mts +13 -0
- package/dist/index.mjs +9 -0
- package/dist/resolvers/color-resolver.cjs +23 -0
- package/dist/resolvers/color-resolver.d.cts +4 -0
- package/dist/resolvers/color-resolver.d.mts +4 -0
- package/dist/resolvers/color-resolver.mjs +23 -0
- package/dist/resolvers/line-height-resolver.cjs +17 -0
- package/dist/{esm/resolvers/line-height-resolver.d.ts → resolvers/line-height-resolver.d.cts} +3 -1
- package/dist/{cjs/resolvers/line-height-resolver.d.ts → resolvers/line-height-resolver.d.mts} +3 -1
- package/dist/resolvers/line-height-resolver.mjs +16 -0
- package/dist/resolvers/style-resolver.cjs +86 -0
- package/dist/resolvers/style-resolver.mjs +86 -0
- package/dist/semantic-colors.cjs +29 -0
- package/dist/{esm/semantic-colors.d.ts → semantic-colors.d.cts} +3 -1
- package/dist/{cjs/semantic-colors.d.ts → semantic-colors.d.mts} +3 -1
- package/dist/semantic-colors.mjs +28 -0
- package/dist/style-props.cjs +103 -0
- package/dist/{cjs/style-props.d.ts → style-props.d.cts} +2 -1
- package/dist/{esm/style-props.d.ts → style-props.d.mts} +2 -1
- package/dist/style-props.mjs +95 -0
- package/dist/text-tree.cjs +70 -0
- package/dist/{cjs/text-tree.d.ts → text-tree.d.cts} +4 -8
- package/dist/{esm/text-tree.d.ts → text-tree.d.mts} +4 -8
- package/dist/text-tree.mjs +66 -0
- package/dist/text-variants.cjs +25 -0
- package/dist/text-variants.mjs +25 -0
- package/dist/types.d.cts +280 -0
- package/dist/types.d.mts +280 -0
- package/package.json +17 -25
- package/dist/cjs/color-mode-store.d.ts +0 -32
- package/dist/cjs/color-mode-store.js +0 -64
- package/dist/cjs/config.d.ts +0 -14
- package/dist/cjs/config.js +0 -35
- package/dist/cjs/create-themed-styles.js +0 -37
- package/dist/cjs/create-themed.d.ts +0 -46
- package/dist/cjs/create-themed.js +0 -118
- package/dist/cjs/define-theme.js +0 -15
- package/dist/cjs/extend-theme.js +0 -118
- package/dist/cjs/index.d.ts +0 -4
- package/dist/cjs/index.js +0 -22
- package/dist/cjs/package.json +0 -1
- package/dist/cjs/resolvers/color-resolver.d.ts +0 -10
- package/dist/cjs/resolvers/color-resolver.js +0 -26
- package/dist/cjs/resolvers/line-height-resolver.js +0 -20
- package/dist/cjs/resolvers/style-resolver.d.ts +0 -21
- package/dist/cjs/resolvers/style-resolver.js +0 -104
- package/dist/cjs/semantic-colors.js +0 -32
- package/dist/cjs/style-props.js +0 -95
- package/dist/cjs/text-tree.js +0 -79
- package/dist/cjs/text-variants.d.ts +0 -22
- package/dist/cjs/text-variants.js +0 -29
- package/dist/cjs/types.d.ts +0 -281
- package/dist/cjs/types.js +0 -2
- package/dist/esm/color-mode-store.d.ts +0 -32
- package/dist/esm/color-mode-store.js +0 -59
- package/dist/esm/config.d.ts +0 -14
- package/dist/esm/config.js +0 -13
- package/dist/esm/create-themed-styles.js +0 -34
- package/dist/esm/create-themed.d.ts +0 -46
- package/dist/esm/create-themed.js +0 -115
- package/dist/esm/define-theme.js +0 -12
- package/dist/esm/extend-theme.js +0 -115
- package/dist/esm/index.d.ts +0 -4
- package/dist/esm/index.js +0 -3
- package/dist/esm/package.json +0 -1
- package/dist/esm/resolvers/color-resolver.d.ts +0 -10
- package/dist/esm/resolvers/color-resolver.js +0 -23
- package/dist/esm/resolvers/line-height-resolver.js +0 -16
- package/dist/esm/resolvers/style-resolver.d.ts +0 -21
- package/dist/esm/resolvers/style-resolver.js +0 -101
- package/dist/esm/semantic-colors.js +0 -28
- package/dist/esm/style-props.js +0 -92
- package/dist/esm/text-tree.js +0 -72
- package/dist/esm/text-variants.d.ts +0 -22
- package/dist/esm/text-variants.js +0 -26
- package/dist/esm/types.d.ts +0 -281
- package/dist/esm/types.js +0 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region src/semantic-colors.ts
|
|
2
|
+
/**
|
|
3
|
+
* A color of `semanticTokens.colors` (as opposed to a group of them): an
|
|
4
|
+
* object whose `light` or `dark` is a string. A group's values are objects,
|
|
5
|
+
* so a group may still name a token `light` or `dark` (Material UI's
|
|
6
|
+
* `primary.light`).
|
|
7
|
+
*/
|
|
8
|
+
function isSchemeColor(node) {
|
|
9
|
+
if (typeof node !== "object" || node === null) return false;
|
|
10
|
+
const { light, dark } = node;
|
|
11
|
+
return typeof light === "string" || typeof dark === "string";
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Visits every semantic color in definition order with its token name:
|
|
15
|
+
* `'group.token'` inside a group, or the bare name for a top-level color
|
|
16
|
+
* (`'primary'`, `'primary-foreground'`).
|
|
17
|
+
*/
|
|
18
|
+
function walkSemanticColors(colors, visit) {
|
|
19
|
+
for (const [key, node] of Object.entries(colors ?? {})) {
|
|
20
|
+
if (isSchemeColor(node)) {
|
|
21
|
+
visit(key, node, void 0);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
for (const [name, color] of Object.entries(node)) visit(`${key}.${name}`, color, key);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { isSchemeColor, walkSemanticColors };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
//#region src/style-props.ts
|
|
2
|
+
/**
|
|
3
|
+
* The RN style property names each token category resolves, grouped by
|
|
4
|
+
* category. Kept as `const` arrays (not just types) because the resolvers
|
|
5
|
+
* need to iterate them at runtime.
|
|
6
|
+
*/
|
|
7
|
+
const COLOR_KEYS = [
|
|
8
|
+
"color",
|
|
9
|
+
"backgroundColor",
|
|
10
|
+
"borderColor",
|
|
11
|
+
"borderTopColor",
|
|
12
|
+
"borderBottomColor",
|
|
13
|
+
"borderLeftColor",
|
|
14
|
+
"borderRightColor",
|
|
15
|
+
"borderStartColor",
|
|
16
|
+
"borderEndColor",
|
|
17
|
+
"borderBlockColor",
|
|
18
|
+
"borderBlockStartColor",
|
|
19
|
+
"borderBlockEndColor",
|
|
20
|
+
"tintColor",
|
|
21
|
+
"overlayColor",
|
|
22
|
+
"shadowColor",
|
|
23
|
+
"outlineColor",
|
|
24
|
+
"textShadowColor",
|
|
25
|
+
"textDecorationColor"
|
|
26
|
+
];
|
|
27
|
+
const RADIUS_KEYS = [
|
|
28
|
+
"borderRadius",
|
|
29
|
+
"borderTopLeftRadius",
|
|
30
|
+
"borderTopRightRadius",
|
|
31
|
+
"borderTopStartRadius",
|
|
32
|
+
"borderTopEndRadius",
|
|
33
|
+
"borderBottomLeftRadius",
|
|
34
|
+
"borderBottomRightRadius",
|
|
35
|
+
"borderBottomStartRadius",
|
|
36
|
+
"borderBottomEndRadius",
|
|
37
|
+
"borderStartStartRadius",
|
|
38
|
+
"borderStartEndRadius",
|
|
39
|
+
"borderEndStartRadius",
|
|
40
|
+
"borderEndEndRadius"
|
|
41
|
+
];
|
|
42
|
+
const SPACING_KEYS = [
|
|
43
|
+
"padding",
|
|
44
|
+
"paddingTop",
|
|
45
|
+
"paddingBottom",
|
|
46
|
+
"paddingLeft",
|
|
47
|
+
"paddingRight",
|
|
48
|
+
"paddingHorizontal",
|
|
49
|
+
"paddingVertical",
|
|
50
|
+
"paddingStart",
|
|
51
|
+
"paddingEnd",
|
|
52
|
+
"paddingBlock",
|
|
53
|
+
"paddingBlockStart",
|
|
54
|
+
"paddingBlockEnd",
|
|
55
|
+
"paddingInline",
|
|
56
|
+
"paddingInlineStart",
|
|
57
|
+
"paddingInlineEnd",
|
|
58
|
+
"margin",
|
|
59
|
+
"marginTop",
|
|
60
|
+
"marginBottom",
|
|
61
|
+
"marginLeft",
|
|
62
|
+
"marginRight",
|
|
63
|
+
"marginHorizontal",
|
|
64
|
+
"marginVertical",
|
|
65
|
+
"marginStart",
|
|
66
|
+
"marginEnd",
|
|
67
|
+
"marginBlock",
|
|
68
|
+
"marginBlockStart",
|
|
69
|
+
"marginBlockEnd",
|
|
70
|
+
"marginInline",
|
|
71
|
+
"marginInlineStart",
|
|
72
|
+
"marginInlineEnd",
|
|
73
|
+
"gap",
|
|
74
|
+
"rowGap",
|
|
75
|
+
"columnGap"
|
|
76
|
+
];
|
|
77
|
+
const FONT_SIZE_KEYS = ["fontSize"];
|
|
78
|
+
const FONT_WEIGHT_KEYS = ["fontWeight"];
|
|
79
|
+
const LINE_HEIGHT_KEYS = ["lineHeight"];
|
|
80
|
+
const LETTER_SPACING_KEYS = ["letterSpacing"];
|
|
81
|
+
/** Token or raw number, like the typography props. */
|
|
82
|
+
const Z_INDEX_KEYS = ["zIndex"];
|
|
83
|
+
/**
|
|
84
|
+
* The real RN style properties the virtual `shadow` prop expands into.
|
|
85
|
+
* Not resolved as a scale category itself — see `resolvers/style-resolver.ts`.
|
|
86
|
+
*/
|
|
87
|
+
const SHADOW_STYLE_PROPS = [
|
|
88
|
+
"shadowColor",
|
|
89
|
+
"shadowOffset",
|
|
90
|
+
"shadowOpacity",
|
|
91
|
+
"shadowRadius",
|
|
92
|
+
"elevation"
|
|
93
|
+
];
|
|
94
|
+
//#endregion
|
|
95
|
+
exports.COLOR_KEYS = COLOR_KEYS;
|
|
96
|
+
exports.FONT_SIZE_KEYS = FONT_SIZE_KEYS;
|
|
97
|
+
exports.FONT_WEIGHT_KEYS = FONT_WEIGHT_KEYS;
|
|
98
|
+
exports.LETTER_SPACING_KEYS = LETTER_SPACING_KEYS;
|
|
99
|
+
exports.LINE_HEIGHT_KEYS = LINE_HEIGHT_KEYS;
|
|
100
|
+
exports.RADIUS_KEYS = RADIUS_KEYS;
|
|
101
|
+
exports.SHADOW_STYLE_PROPS = SHADOW_STYLE_PROPS;
|
|
102
|
+
exports.SPACING_KEYS = SPACING_KEYS;
|
|
103
|
+
exports.Z_INDEX_KEYS = Z_INDEX_KEYS;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//#region src/style-props.d.ts
|
|
1
2
|
/**
|
|
2
3
|
* The RN style property names each token category resolves, grouped by
|
|
3
4
|
* category. Kept as `const` arrays (not just types) because the resolvers
|
|
@@ -25,4 +26,4 @@ export type ZIndexKeys = (typeof Z_INDEX_KEYS)[number];
|
|
|
25
26
|
* Not resolved as a scale category itself — see `resolvers/style-resolver.ts`.
|
|
26
27
|
*/
|
|
27
28
|
export declare const SHADOW_STYLE_PROPS: readonly ["shadowColor", "shadowOffset", "shadowOpacity", "shadowRadius", "elevation"];
|
|
28
|
-
|
|
29
|
+
//#endregion
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//#region src/style-props.d.ts
|
|
1
2
|
/**
|
|
2
3
|
* The RN style property names each token category resolves, grouped by
|
|
3
4
|
* category. Kept as `const` arrays (not just types) because the resolvers
|
|
@@ -25,4 +26,4 @@ export type ZIndexKeys = (typeof Z_INDEX_KEYS)[number];
|
|
|
25
26
|
* Not resolved as a scale category itself — see `resolvers/style-resolver.ts`.
|
|
26
27
|
*/
|
|
27
28
|
export declare const SHADOW_STYLE_PROPS: readonly ["shadowColor", "shadowOffset", "shadowOpacity", "shadowRadius", "elevation"];
|
|
28
|
-
|
|
29
|
+
//#endregion
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
//#region src/style-props.ts
|
|
2
|
+
/**
|
|
3
|
+
* The RN style property names each token category resolves, grouped by
|
|
4
|
+
* category. Kept as `const` arrays (not just types) because the resolvers
|
|
5
|
+
* need to iterate them at runtime.
|
|
6
|
+
*/
|
|
7
|
+
const COLOR_KEYS = [
|
|
8
|
+
"color",
|
|
9
|
+
"backgroundColor",
|
|
10
|
+
"borderColor",
|
|
11
|
+
"borderTopColor",
|
|
12
|
+
"borderBottomColor",
|
|
13
|
+
"borderLeftColor",
|
|
14
|
+
"borderRightColor",
|
|
15
|
+
"borderStartColor",
|
|
16
|
+
"borderEndColor",
|
|
17
|
+
"borderBlockColor",
|
|
18
|
+
"borderBlockStartColor",
|
|
19
|
+
"borderBlockEndColor",
|
|
20
|
+
"tintColor",
|
|
21
|
+
"overlayColor",
|
|
22
|
+
"shadowColor",
|
|
23
|
+
"outlineColor",
|
|
24
|
+
"textShadowColor",
|
|
25
|
+
"textDecorationColor"
|
|
26
|
+
];
|
|
27
|
+
const RADIUS_KEYS = [
|
|
28
|
+
"borderRadius",
|
|
29
|
+
"borderTopLeftRadius",
|
|
30
|
+
"borderTopRightRadius",
|
|
31
|
+
"borderTopStartRadius",
|
|
32
|
+
"borderTopEndRadius",
|
|
33
|
+
"borderBottomLeftRadius",
|
|
34
|
+
"borderBottomRightRadius",
|
|
35
|
+
"borderBottomStartRadius",
|
|
36
|
+
"borderBottomEndRadius",
|
|
37
|
+
"borderStartStartRadius",
|
|
38
|
+
"borderStartEndRadius",
|
|
39
|
+
"borderEndStartRadius",
|
|
40
|
+
"borderEndEndRadius"
|
|
41
|
+
];
|
|
42
|
+
const SPACING_KEYS = [
|
|
43
|
+
"padding",
|
|
44
|
+
"paddingTop",
|
|
45
|
+
"paddingBottom",
|
|
46
|
+
"paddingLeft",
|
|
47
|
+
"paddingRight",
|
|
48
|
+
"paddingHorizontal",
|
|
49
|
+
"paddingVertical",
|
|
50
|
+
"paddingStart",
|
|
51
|
+
"paddingEnd",
|
|
52
|
+
"paddingBlock",
|
|
53
|
+
"paddingBlockStart",
|
|
54
|
+
"paddingBlockEnd",
|
|
55
|
+
"paddingInline",
|
|
56
|
+
"paddingInlineStart",
|
|
57
|
+
"paddingInlineEnd",
|
|
58
|
+
"margin",
|
|
59
|
+
"marginTop",
|
|
60
|
+
"marginBottom",
|
|
61
|
+
"marginLeft",
|
|
62
|
+
"marginRight",
|
|
63
|
+
"marginHorizontal",
|
|
64
|
+
"marginVertical",
|
|
65
|
+
"marginStart",
|
|
66
|
+
"marginEnd",
|
|
67
|
+
"marginBlock",
|
|
68
|
+
"marginBlockStart",
|
|
69
|
+
"marginBlockEnd",
|
|
70
|
+
"marginInline",
|
|
71
|
+
"marginInlineStart",
|
|
72
|
+
"marginInlineEnd",
|
|
73
|
+
"gap",
|
|
74
|
+
"rowGap",
|
|
75
|
+
"columnGap"
|
|
76
|
+
];
|
|
77
|
+
const FONT_SIZE_KEYS = ["fontSize"];
|
|
78
|
+
const FONT_WEIGHT_KEYS = ["fontWeight"];
|
|
79
|
+
const LINE_HEIGHT_KEYS = ["lineHeight"];
|
|
80
|
+
const LETTER_SPACING_KEYS = ["letterSpacing"];
|
|
81
|
+
/** Token or raw number, like the typography props. */
|
|
82
|
+
const Z_INDEX_KEYS = ["zIndex"];
|
|
83
|
+
/**
|
|
84
|
+
* The real RN style properties the virtual `shadow` prop expands into.
|
|
85
|
+
* Not resolved as a scale category itself — see `resolvers/style-resolver.ts`.
|
|
86
|
+
*/
|
|
87
|
+
const SHADOW_STYLE_PROPS = [
|
|
88
|
+
"shadowColor",
|
|
89
|
+
"shadowOffset",
|
|
90
|
+
"shadowOpacity",
|
|
91
|
+
"shadowRadius",
|
|
92
|
+
"elevation"
|
|
93
|
+
];
|
|
94
|
+
//#endregion
|
|
95
|
+
export { COLOR_KEYS, FONT_SIZE_KEYS, FONT_WEIGHT_KEYS, LETTER_SPACING_KEYS, LINE_HEIGHT_KEYS, RADIUS_KEYS, SHADOW_STYLE_PROPS, SPACING_KEYS, Z_INDEX_KEYS };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
//#region src/text-tree.ts
|
|
2
|
+
/** The fields a `semanticTokens.text` preset (leaf) may have. */
|
|
3
|
+
const TEXT_TOKEN_FIELDS = [
|
|
4
|
+
"fontSize",
|
|
5
|
+
"lineHeight",
|
|
6
|
+
"letterSpacing",
|
|
7
|
+
"fontWeight",
|
|
8
|
+
"textTransform",
|
|
9
|
+
"color"
|
|
10
|
+
];
|
|
11
|
+
const isPrimitive = (value) => typeof value === "string" || typeof value === "number";
|
|
12
|
+
const isPresetField = (key) => TEXT_TOKEN_FIELDS.includes(key);
|
|
13
|
+
/**
|
|
14
|
+
* A node of `semanticTokens.text` is a **preset** (leaf) when it has any
|
|
15
|
+
* preset field (`fontSize`, …, `color`) or when every value is a primitive,
|
|
16
|
+
* and a **group** otherwise (`{ md: {...}, sm: {...} }`). The field check
|
|
17
|
+
* matters because `color` may itself be an object (`{ light, dark }`), so
|
|
18
|
+
* "all primitives" alone can't tell a preset from a group; preset field
|
|
19
|
+
* names are therefore reserved and can't name a group or preset. Mixed
|
|
20
|
+
* nodes are rejected by `@react-native-rethemed/cli codegen`.
|
|
21
|
+
*/
|
|
22
|
+
function isTextPreset(node) {
|
|
23
|
+
return Object.keys(node).some(isPresetField) || Object.values(node).every(isPrimitive);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A preset `color` for one scheme: a string applies to both, an object picks
|
|
27
|
+
* `light` / `dark`, and a missing scheme yields `undefined` (no color).
|
|
28
|
+
*/
|
|
29
|
+
function resolveTextColor(color, scheme) {
|
|
30
|
+
return typeof color === "object" && color !== null ? color[scheme] : color;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The text tree with every preset `color` resolved for `scheme`; a preset
|
|
34
|
+
* whose color doesn't cover the scheme loses its `color` key. Presets
|
|
35
|
+
* without `color` are returned as-is (same object).
|
|
36
|
+
*/
|
|
37
|
+
function resolveTextTree(tree, scheme) {
|
|
38
|
+
const result = {};
|
|
39
|
+
for (const [key, node] of Object.entries(tree ?? {})) {
|
|
40
|
+
if (typeof node !== "object" || node === null) continue;
|
|
41
|
+
if (!isTextPreset(node)) result[key] = resolveTextTree(node, scheme);
|
|
42
|
+
else if (node.color === void 0) result[key] = node;
|
|
43
|
+
else {
|
|
44
|
+
const { color, ...rest } = node;
|
|
45
|
+
const resolved = resolveTextColor(color, scheme);
|
|
46
|
+
result[key] = resolved === void 0 ? rest : {
|
|
47
|
+
...rest,
|
|
48
|
+
color: resolved
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Visits every preset in a text tree, depth-first in definition order,
|
|
56
|
+
* with its path (`['heading', 'display', 'lg']`).
|
|
57
|
+
*/
|
|
58
|
+
function walkTextPresets(tree, visit, path = []) {
|
|
59
|
+
for (const [key, node] of Object.entries(tree ?? {})) {
|
|
60
|
+
if (typeof node !== "object" || node === null) continue;
|
|
61
|
+
if (isTextPreset(node)) visit([...path, key], node);
|
|
62
|
+
else walkTextPresets(node, visit, [...path, key]);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
exports.TEXT_TOKEN_FIELDS = TEXT_TOKEN_FIELDS;
|
|
67
|
+
exports.isTextPreset = isTextPreset;
|
|
68
|
+
exports.resolveTextColor = resolveTextColor;
|
|
69
|
+
exports.resolveTextTree = resolveTextTree;
|
|
70
|
+
exports.walkTextPresets = walkTextPresets;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { TextColor, TextToken, TextTokenTree } from "./types.cjs";
|
|
2
|
+
import { ColorScheme } from "./resolvers/color-resolver.cjs";
|
|
3
|
+
//#region src/text-tree.d.ts
|
|
3
4
|
/** The fields a `semanticTokens.text` preset (leaf) may have. */
|
|
4
5
|
export declare const TEXT_TOKEN_FIELDS: readonly ["fontSize", "lineHeight", "letterSpacing", "fontWeight", "textTransform", "color"];
|
|
5
6
|
/**
|
|
@@ -17,14 +18,9 @@ export declare function isTextPreset(node: TextToken | TextTokenTree): node is T
|
|
|
17
18
|
* `light` / `dark`, and a missing scheme yields `undefined` (no color).
|
|
18
19
|
*/
|
|
19
20
|
export declare function resolveTextColor(color: TextColor | undefined, scheme: ColorScheme): string | undefined;
|
|
20
|
-
/**
|
|
21
|
-
* The text tree with every preset `color` resolved for `scheme`; a preset
|
|
22
|
-
* whose color doesn't cover the scheme loses its `color` key. Presets
|
|
23
|
-
* without `color` are returned as-is (same object).
|
|
24
|
-
*/
|
|
25
|
-
export declare function resolveTextTree(tree: TextTokenTree | undefined, scheme: ColorScheme): TextTokenTree;
|
|
26
21
|
/**
|
|
27
22
|
* Visits every preset in a text tree, depth-first in definition order,
|
|
28
23
|
* with its path (`['heading', 'display', 'lg']`).
|
|
29
24
|
*/
|
|
30
25
|
export declare function walkTextPresets(tree: TextTokenTree | undefined, visit: (path: string[], preset: TextToken) => void, path?: string[]): void;
|
|
26
|
+
//#endregion
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { TextColor, TextToken, TextTokenTree } from "./types.mjs";
|
|
2
|
+
import { ColorScheme } from "./resolvers/color-resolver.mjs";
|
|
3
|
+
//#region src/text-tree.d.ts
|
|
3
4
|
/** The fields a `semanticTokens.text` preset (leaf) may have. */
|
|
4
5
|
export declare const TEXT_TOKEN_FIELDS: readonly ["fontSize", "lineHeight", "letterSpacing", "fontWeight", "textTransform", "color"];
|
|
5
6
|
/**
|
|
@@ -17,14 +18,9 @@ export declare function isTextPreset(node: TextToken | TextTokenTree): node is T
|
|
|
17
18
|
* `light` / `dark`, and a missing scheme yields `undefined` (no color).
|
|
18
19
|
*/
|
|
19
20
|
export declare function resolveTextColor(color: TextColor | undefined, scheme: ColorScheme): string | undefined;
|
|
20
|
-
/**
|
|
21
|
-
* The text tree with every preset `color` resolved for `scheme`; a preset
|
|
22
|
-
* whose color doesn't cover the scheme loses its `color` key. Presets
|
|
23
|
-
* without `color` are returned as-is (same object).
|
|
24
|
-
*/
|
|
25
|
-
export declare function resolveTextTree(tree: TextTokenTree | undefined, scheme: ColorScheme): TextTokenTree;
|
|
26
21
|
/**
|
|
27
22
|
* Visits every preset in a text tree, depth-first in definition order,
|
|
28
23
|
* with its path (`['heading', 'display', 'lg']`).
|
|
29
24
|
*/
|
|
30
25
|
export declare function walkTextPresets(tree: TextTokenTree | undefined, visit: (path: string[], preset: TextToken) => void, path?: string[]): void;
|
|
26
|
+
//#endregion
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
//#region src/text-tree.ts
|
|
2
|
+
/** The fields a `semanticTokens.text` preset (leaf) may have. */
|
|
3
|
+
const TEXT_TOKEN_FIELDS = [
|
|
4
|
+
"fontSize",
|
|
5
|
+
"lineHeight",
|
|
6
|
+
"letterSpacing",
|
|
7
|
+
"fontWeight",
|
|
8
|
+
"textTransform",
|
|
9
|
+
"color"
|
|
10
|
+
];
|
|
11
|
+
const isPrimitive = (value) => typeof value === "string" || typeof value === "number";
|
|
12
|
+
const isPresetField = (key) => TEXT_TOKEN_FIELDS.includes(key);
|
|
13
|
+
/**
|
|
14
|
+
* A node of `semanticTokens.text` is a **preset** (leaf) when it has any
|
|
15
|
+
* preset field (`fontSize`, …, `color`) or when every value is a primitive,
|
|
16
|
+
* and a **group** otherwise (`{ md: {...}, sm: {...} }`). The field check
|
|
17
|
+
* matters because `color` may itself be an object (`{ light, dark }`), so
|
|
18
|
+
* "all primitives" alone can't tell a preset from a group; preset field
|
|
19
|
+
* names are therefore reserved and can't name a group or preset. Mixed
|
|
20
|
+
* nodes are rejected by `@react-native-rethemed/cli codegen`.
|
|
21
|
+
*/
|
|
22
|
+
function isTextPreset(node) {
|
|
23
|
+
return Object.keys(node).some(isPresetField) || Object.values(node).every(isPrimitive);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A preset `color` for one scheme: a string applies to both, an object picks
|
|
27
|
+
* `light` / `dark`, and a missing scheme yields `undefined` (no color).
|
|
28
|
+
*/
|
|
29
|
+
function resolveTextColor(color, scheme) {
|
|
30
|
+
return typeof color === "object" && color !== null ? color[scheme] : color;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The text tree with every preset `color` resolved for `scheme`; a preset
|
|
34
|
+
* whose color doesn't cover the scheme loses its `color` key. Presets
|
|
35
|
+
* without `color` are returned as-is (same object).
|
|
36
|
+
*/
|
|
37
|
+
function resolveTextTree(tree, scheme) {
|
|
38
|
+
const result = {};
|
|
39
|
+
for (const [key, node] of Object.entries(tree ?? {})) {
|
|
40
|
+
if (typeof node !== "object" || node === null) continue;
|
|
41
|
+
if (!isTextPreset(node)) result[key] = resolveTextTree(node, scheme);
|
|
42
|
+
else if (node.color === void 0) result[key] = node;
|
|
43
|
+
else {
|
|
44
|
+
const { color, ...rest } = node;
|
|
45
|
+
const resolved = resolveTextColor(color, scheme);
|
|
46
|
+
result[key] = resolved === void 0 ? rest : {
|
|
47
|
+
...rest,
|
|
48
|
+
color: resolved
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Visits every preset in a text tree, depth-first in definition order,
|
|
56
|
+
* with its path (`['heading', 'display', 'lg']`).
|
|
57
|
+
*/
|
|
58
|
+
function walkTextPresets(tree, visit, path = []) {
|
|
59
|
+
for (const [key, node] of Object.entries(tree ?? {})) {
|
|
60
|
+
if (typeof node !== "object" || node === null) continue;
|
|
61
|
+
if (isTextPreset(node)) visit([...path, key], node);
|
|
62
|
+
else walkTextPresets(node, visit, [...path, key]);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
export { TEXT_TOKEN_FIELDS, isTextPreset, resolveTextColor, resolveTextTree, walkTextPresets };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const require_text_tree = require("./text-tree.cjs");
|
|
2
|
+
//#region src/text-variants.ts
|
|
3
|
+
/**
|
|
4
|
+
* Builds `themed.text.<path>(override?)` by walking whatever tree
|
|
5
|
+
* `config.semanticTokens.text` defines, at any depth — no hand-written
|
|
6
|
+
* per-variant code. Each preset merges with the caller's override (preset
|
|
7
|
+
* first, override wins) and runs through the same `resolve` as
|
|
8
|
+
* `themed.text()` itself, so presets referencing scale keys (e.g.
|
|
9
|
+
* `fontSize: 'lg'`) resolve exactly like caller-passed tokens.
|
|
10
|
+
*
|
|
11
|
+
* `tree` must already have its preset colors resolved for the scheme (see
|
|
12
|
+
* `resolveTextTree`), so a call only merges and resolves tokens.
|
|
13
|
+
*
|
|
14
|
+
* Typed loosely on purpose; the exact tree shape comes from the generated
|
|
15
|
+
* `themed.gen.ts`.
|
|
16
|
+
*/
|
|
17
|
+
function createTextVariants(tree, resolve) {
|
|
18
|
+
const build = (tree) => Object.fromEntries(Object.entries(tree).filter(([, node]) => typeof node === "object" && node !== null).map(([key, node]) => [key, require_text_tree.isTextPreset(node) ? (override) => resolve({
|
|
19
|
+
...node,
|
|
20
|
+
...override
|
|
21
|
+
}) : build(node)]));
|
|
22
|
+
return build(tree);
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
exports.createTextVariants = createTextVariants;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { isTextPreset } from "./text-tree.mjs";
|
|
2
|
+
//#region src/text-variants.ts
|
|
3
|
+
/**
|
|
4
|
+
* Builds `themed.text.<path>(override?)` by walking whatever tree
|
|
5
|
+
* `config.semanticTokens.text` defines, at any depth — no hand-written
|
|
6
|
+
* per-variant code. Each preset merges with the caller's override (preset
|
|
7
|
+
* first, override wins) and runs through the same `resolve` as
|
|
8
|
+
* `themed.text()` itself, so presets referencing scale keys (e.g.
|
|
9
|
+
* `fontSize: 'lg'`) resolve exactly like caller-passed tokens.
|
|
10
|
+
*
|
|
11
|
+
* `tree` must already have its preset colors resolved for the scheme (see
|
|
12
|
+
* `resolveTextTree`), so a call only merges and resolves tokens.
|
|
13
|
+
*
|
|
14
|
+
* Typed loosely on purpose; the exact tree shape comes from the generated
|
|
15
|
+
* `themed.gen.ts`.
|
|
16
|
+
*/
|
|
17
|
+
function createTextVariants(tree, resolve) {
|
|
18
|
+
const build = (tree) => Object.fromEntries(Object.entries(tree).filter(([, node]) => typeof node === "object" && node !== null).map(([key, node]) => [key, isTextPreset(node) ? (override) => resolve({
|
|
19
|
+
...node,
|
|
20
|
+
...override
|
|
21
|
+
}) : build(node)]));
|
|
22
|
+
return build(tree);
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { createTextVariants };
|