@multiplatform.one/theme 7.88.5 → 7.88.7
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/theme/accentInk.cjs +122 -0
- package/dist/cjs/theme/accentInk.native.js +200 -0
- package/dist/cjs/theme/accentInk.native.js.map +1 -0
- package/dist/cjs/theme/createThemes.cjs +7 -6
- package/dist/cjs/theme/createThemes.native.js +7 -6
- package/dist/cjs/theme/createThemes.native.js.map +1 -1
- package/dist/cjs/theme/readableColor.cjs +11 -77
- package/dist/cjs/theme/readableColor.native.js +13 -148
- package/dist/cjs/theme/readableColor.native.js.map +1 -1
- package/dist/cjs/theme/tintHues.cjs +28 -0
- package/dist/cjs/theme/tintHues.native.js +31 -0
- package/dist/cjs/theme/tintHues.native.js.map +1 -0
- package/dist/esm/theme/accentInk.mjs +91 -0
- package/dist/esm/theme/accentInk.mjs.map +1 -0
- package/dist/esm/theme/accentInk.native.js +166 -0
- package/dist/esm/theme/accentInk.native.js.map +1 -0
- package/dist/esm/theme/createThemes.mjs +5 -4
- package/dist/esm/theme/createThemes.mjs.map +1 -1
- package/dist/esm/theme/createThemes.native.js +5 -4
- package/dist/esm/theme/createThemes.native.js.map +1 -1
- package/dist/esm/theme/readableColor.mjs +6 -72
- package/dist/esm/theme/readableColor.mjs.map +1 -1
- package/dist/esm/theme/readableColor.native.js +7 -142
- package/dist/esm/theme/readableColor.native.js.map +1 -1
- package/dist/esm/theme/tintHues.mjs +3 -0
- package/dist/esm/theme/tintHues.mjs.map +1 -0
- package/dist/esm/theme/tintHues.native.js +3 -0
- package/dist/esm/theme/tintHues.native.js.map +1 -0
- package/package.json +5 -5
- package/src/theme/accentInk.ts +134 -0
- package/src/theme/accentOnSurface.flip.spec.tsx +155 -0
- package/src/theme/accentOnSurface.palette.spec.tsx +2 -1
- package/src/theme/accentOnSurface.spec.tsx +2 -1
- package/src/theme/createDefaultThemeConfig.spec.ts +2 -2
- package/src/theme/createThemes.ts +21 -47
- package/src/theme/readableColor.ts +15 -100
- package/src/theme/tintHues.ts +36 -0
- package/types/theme/accentInk.d.ts +34 -0
- package/types/theme/accentInk.d.ts.map +1 -0
- package/types/theme/createThemes.d.ts +2 -1
- package/types/theme/createThemes.d.ts.map +1 -1
- package/types/theme/readableColor.d.ts +2 -21
- package/types/theme/readableColor.d.ts.map +1 -1
- package/types/theme/tintHues.d.ts +2 -0
- package/types/theme/tintHues.d.ts.map +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useMemo","useTheme","useTamaguiTheme","useThemeName","aaTextContrastRatio","contrastRatio","holdHueToFloor","holdInkFloor","normalizeToHex","pickReadableForeground","relativeLuminance","isDarkThemeName","
|
|
1
|
+
{"version":3,"names":["useMemo","isWeb","useTheme","useTamaguiTheme","useThemeName","accentStepKeys","chromaOf","identityKeys","pickIdentityInk","resolveAccentOnSurface","resolveIdentityInk","aaTextContrastRatio","contrastRatio","holdHueToFloor","holdInkFloor","normalizeToHex","pickReadableForeground","relativeLuminance","isDarkThemeName","resolveTokenValue","theme","token","key","startsWith","slice","val","useReadableTextOn","fill_","fill","paper","ink","resolveLegibleInkOn","preferred","fillHex","preferredHex","fillLum","anchor","useLegibleInkOn","preferredValue","resolved","useIdentityInputs","themeName","keys","candidates","map","accentSteps","c1","c2","useAccentOnSurface","candidateKey","join","stepKey","picked","identity","surfaces","accentOnSurface","useIdentityInkOnSurface","useIdentityHue","hue","ACCENT_WASH_RATIO","resolveAccentTintedSurface","solid","solidHex","paperHex","paperLum","solidRgb","offset","parseInt","paperRgb","step","share","mix","channel","index","Math","round","toString","padStart","useAccentTintedSurface","ACTIVE_TAB_CHROMA_FLOOR","resolveActiveTabInk","dark","useActiveTabInk"],"sources":["../../../src/theme/readableColor.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
|
-
import { useTheme as useTamaguiTheme, useThemeName } from "tamagui";
|
|
2
|
+
import { isWeb, useTheme as useTamaguiTheme, useThemeName } from "tamagui";
|
|
3
|
+
import { accentStepKeys, chromaOf, identityKeys, pickIdentityInk, resolveAccentOnSurface, resolveIdentityInk } from "./accentInk.native.js";
|
|
3
4
|
import { aaTextContrastRatio, contrastRatio, holdHueToFloor, holdInkFloor, normalizeToHex, pickReadableForeground, relativeLuminance } from "./colorRules.native.js";
|
|
4
5
|
import { isDarkThemeName } from "./controlTiers.native.js";
|
|
5
|
-
import { tintHueNames } from "./createThemes.native.js";
|
|
6
6
|
function _type_of(obj) {
|
|
7
7
|
"@swc/helpers - typeof";
|
|
8
8
|
|
|
@@ -58,149 +58,11 @@ function useLegibleInkOn(fill_, preferred) {
|
|
|
58
58
|
return !resolved || resolved === preferredValue ? preferred : resolved;
|
|
59
59
|
}, [fill, preferred, preferredValue, paper, ink]);
|
|
60
60
|
}
|
|
61
|
-
var IDENTITY_CHROMA_FLOOR = 0.1;
|
|
62
|
-
function chromaOf(hex) {
|
|
63
|
-
var rgb = [1, 3, 5].map(function (offset) {
|
|
64
|
-
return parseInt(hex.slice(offset, offset + 2), 16) / 255;
|
|
65
|
-
});
|
|
66
|
-
return Math.max(...rgb) - Math.min(...rgb);
|
|
67
|
-
}
|
|
68
|
-
function surfaceLuminances(surfaces) {
|
|
69
|
-
var lums = [];
|
|
70
|
-
var _iteratorNormalCompletion = true,
|
|
71
|
-
_didIteratorError = false,
|
|
72
|
-
_iteratorError = void 0;
|
|
73
|
-
try {
|
|
74
|
-
for (var _iterator = surfaces[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
75
|
-
var surface = _step.value;
|
|
76
|
-
var hex = surface ? normalizeToHex(surface) : null;
|
|
77
|
-
if (!hex) return null;
|
|
78
|
-
lums.push(relativeLuminance(hex));
|
|
79
|
-
}
|
|
80
|
-
} catch (err) {
|
|
81
|
-
_didIteratorError = true;
|
|
82
|
-
_iteratorError = err;
|
|
83
|
-
} finally {
|
|
84
|
-
try {
|
|
85
|
-
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
86
|
-
_iterator.return();
|
|
87
|
-
}
|
|
88
|
-
} finally {
|
|
89
|
-
if (_didIteratorError) {
|
|
90
|
-
throw _iteratorError;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return lums;
|
|
95
|
-
}
|
|
96
|
-
function pickIdentityInk(candidates, surfaces) {
|
|
97
|
-
var surfaceLums = surfaceLuminances(surfaces);
|
|
98
|
-
if (!surfaceLums) return void 0;
|
|
99
|
-
var best;
|
|
100
|
-
var bestChroma = IDENTITY_CHROMA_FLOOR;
|
|
101
|
-
var _iteratorNormalCompletion = true,
|
|
102
|
-
_didIteratorError = false,
|
|
103
|
-
_iteratorError = void 0;
|
|
104
|
-
try {
|
|
105
|
-
var _loop = function () {
|
|
106
|
-
var candidate = _step.value;
|
|
107
|
-
var hex = candidate ? normalizeToHex(candidate) : null;
|
|
108
|
-
if (!candidate || !hex) return "continue";
|
|
109
|
-
var lum = relativeLuminance(hex);
|
|
110
|
-
if (surfaceLums.some(function (surface) {
|
|
111
|
-
return contrastRatio(lum, surface) < aaTextContrastRatio;
|
|
112
|
-
})) return "continue";
|
|
113
|
-
var chroma = chromaOf(hex);
|
|
114
|
-
if (chroma > bestChroma) {
|
|
115
|
-
bestChroma = chroma;
|
|
116
|
-
best = candidate;
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
for (var _iterator = candidates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) _loop();
|
|
120
|
-
} catch (err) {
|
|
121
|
-
_didIteratorError = true;
|
|
122
|
-
_iteratorError = err;
|
|
123
|
-
} finally {
|
|
124
|
-
try {
|
|
125
|
-
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
126
|
-
_iterator.return();
|
|
127
|
-
}
|
|
128
|
-
} finally {
|
|
129
|
-
if (_didIteratorError) {
|
|
130
|
-
throw _iteratorError;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return best;
|
|
135
|
-
}
|
|
136
|
-
function resolveIdentityInk(param) {
|
|
137
|
-
var {
|
|
138
|
-
candidates,
|
|
139
|
-
surfaces,
|
|
140
|
-
ink
|
|
141
|
-
} = param;
|
|
142
|
-
var _pickIdentityInk;
|
|
143
|
-
return (_pickIdentityInk = pickIdentityInk(candidates, surfaces)) !== null && _pickIdentityInk !== void 0 ? _pickIdentityInk : ink;
|
|
144
|
-
}
|
|
145
|
-
function resolveAccentOnSurface(param) {
|
|
146
|
-
var {
|
|
147
|
-
identity,
|
|
148
|
-
accentSteps,
|
|
149
|
-
surfaces,
|
|
150
|
-
ink
|
|
151
|
-
} = param;
|
|
152
|
-
var hued = pickIdentityInk(identity, surfaces);
|
|
153
|
-
if (hued) return hued;
|
|
154
|
-
var surfaceLums = surfaceLuminances(surfaces);
|
|
155
|
-
if (!surfaceLums) return ink;
|
|
156
|
-
var best;
|
|
157
|
-
var bestMin = Number.POSITIVE_INFINITY;
|
|
158
|
-
var _iteratorNormalCompletion = true,
|
|
159
|
-
_didIteratorError = false,
|
|
160
|
-
_iteratorError = void 0;
|
|
161
|
-
try {
|
|
162
|
-
var _loop = function () {
|
|
163
|
-
var step = _step.value;
|
|
164
|
-
var hex = step ? normalizeToHex(step) : null;
|
|
165
|
-
if (!step || !hex) return "continue";
|
|
166
|
-
var stepLum = relativeLuminance(hex);
|
|
167
|
-
var min = Math.min(...surfaceLums.map(function (surface) {
|
|
168
|
-
return contrastRatio(stepLum, surface);
|
|
169
|
-
}));
|
|
170
|
-
if (min >= aaTextContrastRatio && min < bestMin) {
|
|
171
|
-
bestMin = min;
|
|
172
|
-
best = step;
|
|
173
|
-
}
|
|
174
|
-
};
|
|
175
|
-
for (var _iterator = accentSteps[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) _loop();
|
|
176
|
-
} catch (err) {
|
|
177
|
-
_didIteratorError = true;
|
|
178
|
-
_iteratorError = err;
|
|
179
|
-
} finally {
|
|
180
|
-
try {
|
|
181
|
-
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
182
|
-
_iterator.return();
|
|
183
|
-
}
|
|
184
|
-
} finally {
|
|
185
|
-
if (_didIteratorError) {
|
|
186
|
-
throw _iteratorError;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
return best !== null && best !== void 0 ? best : ink;
|
|
191
|
-
}
|
|
192
|
-
var accentStepKeys = Array.from({
|
|
193
|
-
length: 12
|
|
194
|
-
}, function (_, index) {
|
|
195
|
-
return `accent${index + 1}`;
|
|
196
|
-
});
|
|
197
61
|
function useIdentityInputs() {
|
|
198
62
|
var _useThemeName, _resolveTokenValue;
|
|
199
63
|
var themeName = (_useThemeName = useThemeName()) !== null && _useThemeName !== void 0 ? _useThemeName : "";
|
|
200
64
|
var theme = useTamaguiTheme();
|
|
201
|
-
var
|
|
202
|
-
var isTint = hue !== void 0 && tintHueNames.has(hue);
|
|
203
|
-
var keys = isTint ? ["color8", "color9", "color10", `${hue}11`, `${hue}12`] : accentStepKeys;
|
|
65
|
+
var keys = identityKeys(themeName);
|
|
204
66
|
return {
|
|
205
67
|
candidates: keys.map(function (key) {
|
|
206
68
|
return resolveTokenValue(theme, key);
|
|
@@ -214,6 +76,7 @@ function useIdentityInputs() {
|
|
|
214
76
|
};
|
|
215
77
|
}
|
|
216
78
|
function useAccentOnSurface() {
|
|
79
|
+
var _theme_accentOnSurface;
|
|
217
80
|
var {
|
|
218
81
|
candidates,
|
|
219
82
|
accentSteps,
|
|
@@ -221,9 +84,10 @@ function useAccentOnSurface() {
|
|
|
221
84
|
c2,
|
|
222
85
|
ink
|
|
223
86
|
} = useIdentityInputs();
|
|
87
|
+
var theme = useTamaguiTheme();
|
|
224
88
|
var candidateKey = candidates.join("|");
|
|
225
89
|
var stepKey = accentSteps.join("|");
|
|
226
|
-
|
|
90
|
+
var picked = useMemo(function () {
|
|
227
91
|
return resolveAccentOnSurface({
|
|
228
92
|
identity: candidates,
|
|
229
93
|
accentSteps,
|
|
@@ -233,6 +97,7 @@ function useAccentOnSurface() {
|
|
|
233
97
|
},
|
|
234
98
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
235
99
|
[candidateKey, stepKey, c1, c2, ink]);
|
|
100
|
+
return isWeb && ((_theme_accentOnSurface = theme.accentOnSurface) === null || _theme_accentOnSurface === void 0 ? void 0 : _theme_accentOnSurface.val) === picked ? "$accentOnSurface" : picked;
|
|
236
101
|
}
|
|
237
102
|
function useIdentityInkOnSurface() {
|
|
238
103
|
var {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useMemo","useTheme","useTamaguiTheme","useThemeName","aaTextContrastRatio","contrastRatio","holdHueToFloor","holdInkFloor","normalizeToHex","pickReadableForeground","relativeLuminance","isDarkThemeName","
|
|
1
|
+
{"version":3,"names":["useMemo","isWeb","useTheme","useTamaguiTheme","useThemeName","accentStepKeys","chromaOf","identityKeys","pickIdentityInk","resolveAccentOnSurface","resolveIdentityInk","aaTextContrastRatio","contrastRatio","holdHueToFloor","holdInkFloor","normalizeToHex","pickReadableForeground","relativeLuminance","isDarkThemeName","_type_of","obj","Symbol","constructor","resolveTokenValue","theme","token","_theme_key","key","startsWith","slice","val","useReadableTextOn","fill_","fill","paper","ink","resolveLegibleInkOn","param","preferred","fillHex","preferredHex","fillLum","anchor","useLegibleInkOn","preferredValue","resolved","useIdentityInputs","_useThemeName","_resolveTokenValue","themeName","keys","candidates","map","accentSteps","c1","c2","useAccentOnSurface","_theme_accentOnSurface","candidateKey","join","stepKey","picked","identity","surfaces","accentOnSurface","useIdentityInkOnSurface","useIdentityHue","hue"],"sources":["../../../src/theme/readableColor.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
const tintHueNames = /* @__PURE__ */new Set(["amber", "blue", "bronze", "brown", "crimson", "cyan", "gold", "grass", "gray", "green", "indigo", "lime", "mauve", "mint", "olive", "orange", "pink", "plum", "purple", "red", "sage", "sand", "sky", "slate", "teal", "tomato", "violet", "yellow"]);
|
|
2
|
+
export { tintHueNames };
|
|
3
|
+
//# sourceMappingURL=tintHues.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["tintHueNames","Set"],"sources":["../../../src/theme/tintHues.ts"],"sourcesContent":[null],"mappings":"AAMO,MAAMA,YAAA,GAAe,mBAAIC,GAAA,CAAI,CAClC,SACA,QACA,UACA,SACA,WACA,QACA,QACA,SACA,QACA,SACA,UACA,QACA,SACA,QACA,SACA,UACA,QACA,QACA,UACA,OACA,QACA,QACA,OACA,SACA,QACA,UACA,UACA,SACD","ignoreList":[]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
var tintHueNames = /* @__PURE__ */new Set(["amber", "blue", "bronze", "brown", "crimson", "cyan", "gold", "grass", "gray", "green", "indigo", "lime", "mauve", "mint", "olive", "orange", "pink", "plum", "purple", "red", "sage", "sand", "sky", "slate", "teal", "tomato", "violet", "yellow"]);
|
|
2
|
+
export { tintHueNames };
|
|
3
|
+
//# sourceMappingURL=tintHues.native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["tintHueNames","Set"],"sources":["../../../src/theme/tintHues.ts"],"sourcesContent":[null],"mappings":"AAMO,IAAAA,YAAM,kBAAe,IAAAC,GAAI,EAC9B,SACA,QACA,UACA,SACA,WACA,QACA,QACA,SACA,QACA,SACA,UACA,QACA,SACA,QACA,SACA,UACA,QACA,QACA,UACA,OACA,QACA,QACA,OACA,SACA,QACA,UACA,UACA,SACD","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@multiplatform.one/theme",
|
|
3
|
-
"version": "7.88.
|
|
3
|
+
"version": "7.88.7",
|
|
4
4
|
"description": "Tamagui theme system for multiplatform.one",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"multiplatform",
|
|
@@ -115,8 +115,8 @@
|
|
|
115
115
|
"access": "public"
|
|
116
116
|
},
|
|
117
117
|
"dependencies": {
|
|
118
|
-
"@multiplatform.one/platform": "^7.88.
|
|
119
|
-
"@multiplatform.one/store": "^7.88.
|
|
118
|
+
"@multiplatform.one/platform": "^7.88.7",
|
|
119
|
+
"@multiplatform.one/store": "^7.88.7",
|
|
120
120
|
"@tamagui/animations-react-native": "2.7.6",
|
|
121
121
|
"@tamagui/colors": "2.7.6",
|
|
122
122
|
"@tamagui/config": "2.7.6",
|
|
@@ -132,8 +132,8 @@
|
|
|
132
132
|
},
|
|
133
133
|
"devDependencies": {
|
|
134
134
|
"@expo/prebuild-config": "55.0.18",
|
|
135
|
-
"@multiplatform.one/config": "7.88.
|
|
136
|
-
"@multiplatform.one/test-utils": "7.88.
|
|
135
|
+
"@multiplatform.one/config": "7.88.7",
|
|
136
|
+
"@multiplatform.one/test-utils": "7.88.7",
|
|
137
137
|
"@tamagui/animations-css": "2.7.6",
|
|
138
138
|
"@tamagui/animations-reanimated": "2.7.6",
|
|
139
139
|
"@tamagui/build": "2.7.6",
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import {
|
|
2
|
+
aaTextContrastRatio,
|
|
3
|
+
contrastRatio,
|
|
4
|
+
normalizeToHex,
|
|
5
|
+
relativeLuminance,
|
|
6
|
+
} from "./colorRules";
|
|
7
|
+
import { resolveThemeThroughParents } from "./dedupeInherited";
|
|
8
|
+
import { tintHueNames } from "./tintHues";
|
|
9
|
+
|
|
10
|
+
/** Below this sRGB chroma a step reads as grey, not as a hue. */
|
|
11
|
+
const IDENTITY_CHROMA_FLOOR = 0.1;
|
|
12
|
+
|
|
13
|
+
export function chromaOf(hex: string): number {
|
|
14
|
+
const rgb = [1, 3, 5].map((offset) => parseInt(hex.slice(offset, offset + 2), 16) / 255);
|
|
15
|
+
return Math.max(...rgb) - Math.min(...rgb);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function surfaceLuminances(surfaces: readonly (string | undefined)[]): number[] | null {
|
|
19
|
+
const lums: number[] = [];
|
|
20
|
+
for (const surface of surfaces) {
|
|
21
|
+
const hex = surface ? normalizeToHex(surface) : null;
|
|
22
|
+
if (!hex) return null;
|
|
23
|
+
lums.push(relativeLuminance(hex));
|
|
24
|
+
}
|
|
25
|
+
return lums;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function pickIdentityInk(
|
|
29
|
+
candidates: readonly (string | undefined)[],
|
|
30
|
+
surfaces: readonly (string | undefined)[],
|
|
31
|
+
): string | undefined {
|
|
32
|
+
const surfaceLums = surfaceLuminances(surfaces);
|
|
33
|
+
if (!surfaceLums) return undefined;
|
|
34
|
+
let best: string | undefined;
|
|
35
|
+
let bestChroma = IDENTITY_CHROMA_FLOOR;
|
|
36
|
+
for (const candidate of candidates) {
|
|
37
|
+
const hex = candidate ? normalizeToHex(candidate) : null;
|
|
38
|
+
if (!candidate || !hex) continue;
|
|
39
|
+
const lum = relativeLuminance(hex);
|
|
40
|
+
if (surfaceLums.some((surface) => contrastRatio(lum, surface) < aaTextContrastRatio)) continue;
|
|
41
|
+
const chroma = chromaOf(hex);
|
|
42
|
+
if (chroma > bestChroma) {
|
|
43
|
+
bestChroma = chroma;
|
|
44
|
+
best = candidate;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return best;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Pure resolver behind {@link useIdentityInkOnSurface}: the most chromatic
|
|
52
|
+
* candidate that clears AA text contrast on every surface, else `ink`.
|
|
53
|
+
*/
|
|
54
|
+
export function resolveIdentityInk({
|
|
55
|
+
candidates,
|
|
56
|
+
surfaces,
|
|
57
|
+
ink,
|
|
58
|
+
}: {
|
|
59
|
+
candidates: readonly (string | undefined)[];
|
|
60
|
+
surfaces: readonly (string | undefined)[];
|
|
61
|
+
ink: string;
|
|
62
|
+
}): string {
|
|
63
|
+
return pickIdentityInk(candidates, surfaces) ?? ink;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Pure resolver behind {@link useAccentOnSurface}. The identity hue first
|
|
68
|
+
* (`identity`, see {@link useIdentityInkOnSurface}), so a colour theme's
|
|
69
|
+
* accent ink is that colour. With no hue, the accent ramp's least-contrast
|
|
70
|
+
* step that still clears AA on every surface, else `ink`.
|
|
71
|
+
*/
|
|
72
|
+
export function resolveAccentOnSurface({
|
|
73
|
+
identity,
|
|
74
|
+
accentSteps,
|
|
75
|
+
surfaces,
|
|
76
|
+
ink,
|
|
77
|
+
}: {
|
|
78
|
+
identity: readonly (string | undefined)[];
|
|
79
|
+
accentSteps: readonly (string | undefined)[];
|
|
80
|
+
surfaces: readonly (string | undefined)[];
|
|
81
|
+
ink: string;
|
|
82
|
+
}): string {
|
|
83
|
+
const hued = pickIdentityInk(identity, surfaces);
|
|
84
|
+
if (hued) return hued;
|
|
85
|
+
const surfaceLums = surfaceLuminances(surfaces);
|
|
86
|
+
if (!surfaceLums) return ink;
|
|
87
|
+
let best: string | undefined;
|
|
88
|
+
let bestMin = Number.POSITIVE_INFINITY;
|
|
89
|
+
for (const step of accentSteps) {
|
|
90
|
+
const hex = step ? normalizeToHex(step) : null;
|
|
91
|
+
if (!step || !hex) continue;
|
|
92
|
+
const stepLum = relativeLuminance(hex);
|
|
93
|
+
const min = Math.min(...surfaceLums.map((surface) => contrastRatio(stepLum, surface)));
|
|
94
|
+
if (min >= aaTextContrastRatio && min < bestMin) {
|
|
95
|
+
bestMin = min;
|
|
96
|
+
best = step;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return best ?? ink;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export const accentStepKeys = Array.from({ length: 12 }, (_, index) => `accent${index + 1}`);
|
|
103
|
+
|
|
104
|
+
/** The identity candidates' keys for `themeName`: a tint's own ramp, else the accent ramp. */
|
|
105
|
+
export function identityKeys(themeName: string): string[] {
|
|
106
|
+
const hue = themeName.split("_")[1];
|
|
107
|
+
return hue !== undefined && tintHueNames.has(hue as never)
|
|
108
|
+
? ["color8", "color9", "color10", `${hue}11`, `${hue}12`]
|
|
109
|
+
: accentStepKeys;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* FZ-9608. Every theme with the ink {@link useAccentOnSurface} picks inside it,
|
|
114
|
+
* as `accentOnSurface`. On web the hook then hands back `$accentOnSurface`, so
|
|
115
|
+
* consumers paint a CSS variable that follows a light/dark flip with no
|
|
116
|
+
* re-render. A picked literal stayed on the scheme it was picked in.
|
|
117
|
+
*/
|
|
118
|
+
export function withAccentOnSurface(
|
|
119
|
+
themes: Record<string, Record<string, string>>,
|
|
120
|
+
): Record<string, Record<string, string>> {
|
|
121
|
+
return Object.fromEntries(
|
|
122
|
+
Object.entries(themes).map(([name, theme]) => {
|
|
123
|
+
const values = resolveThemeThroughParents(themes, name);
|
|
124
|
+
if (!values.color12) return [name, theme];
|
|
125
|
+
const accentOnSurface = resolveAccentOnSurface({
|
|
126
|
+
identity: identityKeys(name).map((key) => values[key]),
|
|
127
|
+
accentSteps: accentStepKeys.map((key) => values[key]),
|
|
128
|
+
surfaces: [values.color1, values.color2],
|
|
129
|
+
ink: values.color12,
|
|
130
|
+
});
|
|
131
|
+
return [name, { ...theme, accentOnSurface }];
|
|
132
|
+
}),
|
|
133
|
+
);
|
|
134
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vitest-environment jsdom
|
|
3
|
+
*
|
|
4
|
+
* FZ-9608: `useAccentOnSurface()` picked a literal from the scheme current at
|
|
5
|
+
* render, and every consumer (links, Toast, DatePicker, table filters,
|
|
6
|
+
* Button) painted it. A flip that moves only the root's t_light/t_dark class
|
|
7
|
+
* never re-renders them, so a link kept the old scheme's ink on the new page.
|
|
8
|
+
* The house link (Anchor) stands in for them here, at the root and under a
|
|
9
|
+
* tint, a colour accent and the accent slot.
|
|
10
|
+
*
|
|
11
|
+
* jsdom cascades no Tamagui CSS, so this reads the atomic `_col-` class, the
|
|
12
|
+
* injected rule behind it, and for a `var(--token)` rule the house theme
|
|
13
|
+
* table of the scope that paints it.
|
|
14
|
+
*/
|
|
15
|
+
import type { ThemeName } from "@tamagui/web";
|
|
16
|
+
import { act, cleanup, render, screen } from "@testing-library/react";
|
|
17
|
+
import { type ReactElement, type ReactNode, useState } from "react";
|
|
18
|
+
import { TamaguiProvider, Theme } from "tamagui";
|
|
19
|
+
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
|
|
20
|
+
import { Anchor } from "./Text";
|
|
21
|
+
import { activateThemeConfig } from "./activateThemeConfig";
|
|
22
|
+
import { createDefaultThemeConfig } from "./createDefaultThemeConfig";
|
|
23
|
+
import { createThemesBuilder } from "./createThemes";
|
|
24
|
+
import { defaultAccentTheme, defaultBaseTheme } from "./defaults";
|
|
25
|
+
import { defaultBuilderOptions } from "./defaults/builderOptions";
|
|
26
|
+
|
|
27
|
+
vi.hoisted(() => {
|
|
28
|
+
vi.stubGlobal("matchMedia", () => ({
|
|
29
|
+
matches: false,
|
|
30
|
+
addEventListener() {},
|
|
31
|
+
removeEventListener() {},
|
|
32
|
+
addListener() {},
|
|
33
|
+
removeListener() {},
|
|
34
|
+
}));
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const house = createDefaultThemeConfig();
|
|
38
|
+
const houseThemes = createThemesBuilder(
|
|
39
|
+
defaultBaseTheme,
|
|
40
|
+
defaultAccentTheme,
|
|
41
|
+
defaultBuilderOptions,
|
|
42
|
+
).themes() as Record<string, Record<string, string>>;
|
|
43
|
+
|
|
44
|
+
const FLIPS = [
|
|
45
|
+
["light", "dark"],
|
|
46
|
+
["dark", "light"],
|
|
47
|
+
] as const;
|
|
48
|
+
type Scheme = (typeof FLIPS)[number][number];
|
|
49
|
+
const SCOPES = [undefined, "orange", "purple", "blue", "accent"] as const;
|
|
50
|
+
|
|
51
|
+
beforeAll(() => activateThemeConfig(house));
|
|
52
|
+
afterEach(cleanup);
|
|
53
|
+
|
|
54
|
+
function injectedRuleValue(className: string, property: string): string {
|
|
55
|
+
for (const sheet of Array.from(document.styleSheets)) {
|
|
56
|
+
for (const rule of Array.from(sheet.cssRules)) {
|
|
57
|
+
if (!(rule instanceof CSSStyleRule)) continue;
|
|
58
|
+
if (!rule.selectorText.endsWith(`.${className}`)) continue;
|
|
59
|
+
const value = rule.style.getPropertyValue(property);
|
|
60
|
+
if (value) return value.trim();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
throw new Error(`no injected ${property} rule for .${className}`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function scopeOf(el: Element): string | null {
|
|
67
|
+
for (let node: Element | null = el; node; node = node.parentElement) {
|
|
68
|
+
const names = Array.from(node.classList)
|
|
69
|
+
.filter((c) => c.startsWith("t_") && c !== "t_sub_theme")
|
|
70
|
+
.map((c) => c.slice(2))
|
|
71
|
+
.filter((c) => c !== "light" && c !== "dark");
|
|
72
|
+
if (names.length) return names.sort((a, b) => b.length - a.length)[0] ?? null;
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function resolveInScope(value: string, scheme: Scheme, scope: string | null): string {
|
|
78
|
+
const token = value.match(/^var\(--([\w-]+)\)$/)?.[1];
|
|
79
|
+
if (!token) return value;
|
|
80
|
+
const chain: string[] = [];
|
|
81
|
+
if (scope) {
|
|
82
|
+
const parts = scope.split("_");
|
|
83
|
+
for (let i = parts.length; i > 0; i--) chain.push(`${scheme}_${parts.slice(0, i).join("_")}`);
|
|
84
|
+
}
|
|
85
|
+
chain.push(scheme);
|
|
86
|
+
for (const name of chain) {
|
|
87
|
+
const hit = houseThemes[name]?.[token];
|
|
88
|
+
if (hit) return hit;
|
|
89
|
+
}
|
|
90
|
+
throw new Error(`--${token} resolves in none of ${chain.join(", ")}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function linkInk(scheme: Scheme): string {
|
|
94
|
+
const link = screen.getByText("Docs");
|
|
95
|
+
const cls = Array.from(link.classList).find(
|
|
96
|
+
(c) => c.startsWith("_col-") && !/^_col-0(hover|active|focus|press)/.test(c),
|
|
97
|
+
);
|
|
98
|
+
if (!cls) throw new Error("the link carries no _col- class");
|
|
99
|
+
return resolveInScope(injectedRuleValue(cls, "color"), scheme, scopeOf(link));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
let flipScheme: (scheme: Scheme) => void = () => {};
|
|
103
|
+
|
|
104
|
+
function SchemeRoot({ initial, children }: { initial: Scheme; children: ReactNode }) {
|
|
105
|
+
const [scheme, setScheme] = useState<Scheme>(initial);
|
|
106
|
+
flipScheme = setScheme;
|
|
107
|
+
return (
|
|
108
|
+
<TamaguiProvider config={house.tamagui} defaultTheme={scheme} disableInjectCSS>
|
|
109
|
+
{children}
|
|
110
|
+
</TamaguiProvider>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function swapSchemeClass(from: Scheme, to: Scheme) {
|
|
115
|
+
for (const el of Array.from(document.querySelectorAll(`.t_${from}`))) {
|
|
116
|
+
el.classList.replace(`t_${from}`, `t_${to}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function link(scope: (typeof SCOPES)[number]): ReactElement {
|
|
121
|
+
const anchor = <Anchor href="#">Docs</Anchor>;
|
|
122
|
+
return scope ? <Theme name={scope as ThemeName}>{anchor}</Theme> : anchor;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
describe("FZ-9608: an accent link follows a scheme flip with no re-render", () => {
|
|
126
|
+
for (const [from, to] of FLIPS) {
|
|
127
|
+
for (const scope of SCOPES) {
|
|
128
|
+
const label = `${from} -> ${to} ${scope ?? "root"}`;
|
|
129
|
+
|
|
130
|
+
it(`${label}: a flip that never re-renders it inks what a fresh ${to} mount inks`, () => {
|
|
131
|
+
render(<SchemeRoot initial={to}>{link(scope)}</SchemeRoot>);
|
|
132
|
+
const fresh = linkInk(to);
|
|
133
|
+
cleanup();
|
|
134
|
+
render(<SchemeRoot initial={from}>{link(scope)}</SchemeRoot>);
|
|
135
|
+
const before = linkInk(from);
|
|
136
|
+
swapSchemeClass(from, to);
|
|
137
|
+
try {
|
|
138
|
+
expect(linkInk(to)).toBe(fresh);
|
|
139
|
+
expect(fresh).not.toBe(before);
|
|
140
|
+
} finally {
|
|
141
|
+
swapSchemeClass(to, from);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it(`${label}: a provider flip inks what a fresh ${to} mount inks`, () => {
|
|
146
|
+
render(<SchemeRoot initial={to}>{link(scope)}</SchemeRoot>);
|
|
147
|
+
const fresh = linkInk(to);
|
|
148
|
+
cleanup();
|
|
149
|
+
render(<SchemeRoot initial={from}>{link(scope)}</SchemeRoot>);
|
|
150
|
+
act(() => flipScheme(to));
|
|
151
|
+
expect(linkInk(to)).toBe(fresh);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
});
|
|
@@ -46,7 +46,8 @@ interface Seen {
|
|
|
46
46
|
|
|
47
47
|
function Probe({ seen }: { seen: Seen }) {
|
|
48
48
|
const theme = useTheme() as unknown as Record<string, { val?: string } | undefined>;
|
|
49
|
-
|
|
49
|
+
const accent = useAccentOnSurface();
|
|
50
|
+
seen.accent = accent.startsWith("$") ? (theme[accent.slice(1)]?.val ?? accent) : accent;
|
|
50
51
|
seen.surfaces = [theme.color1?.val ?? "", theme.color2?.val ?? ""];
|
|
51
52
|
seen.accentSteps = Array.from({ length: 12 }, (_, i) => theme[`accent${i + 1}`]?.val ?? "");
|
|
52
53
|
return null;
|