theme-vir 28.24.0 → 28.25.0
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.
|
@@ -43,6 +43,17 @@ export type ArrayOrSelectParam<T extends PropertyKey> = ReadonlyArray<T> | Reado
|
|
|
43
43
|
export declare const defaultLightThemePair: RequiredAndNotNull<NoRefColorInit>;
|
|
44
44
|
/** @category Internal */
|
|
45
45
|
export declare const defaultContrastLevels: Readonly<ArrayOrSelectParam<ContrastLevelName>>;
|
|
46
|
+
/**
|
|
47
|
+
* Extra contrast levels generated by {@link buildColorTheme} beyond the standard `ContrastLevelName`
|
|
48
|
+
* values. `highest-contrast` always picks the palette color with the most contrast against the
|
|
49
|
+
* fixed color; `lowest-contrast` always picks the closest.
|
|
50
|
+
*
|
|
51
|
+
* @category Internal
|
|
52
|
+
*/
|
|
53
|
+
export declare enum ExtremeContrastLevel {
|
|
54
|
+
HighestContrast = "highest-contrast",
|
|
55
|
+
LowestContrast = "lowest-contrast"
|
|
56
|
+
}
|
|
46
57
|
/**
|
|
47
58
|
* Options for {@link buildColorTheme}.
|
|
48
59
|
*
|
|
@@ -90,6 +90,55 @@ export const defaultLightThemePair = {
|
|
|
90
90
|
};
|
|
91
91
|
/** @category Internal */
|
|
92
92
|
export const defaultContrastLevels = getEnumValues(ContrastLevelName);
|
|
93
|
+
/**
|
|
94
|
+
* Extra contrast levels generated by {@link buildColorTheme} beyond the standard `ContrastLevelName`
|
|
95
|
+
* values. `highest-contrast` always picks the palette color with the most contrast against the
|
|
96
|
+
* fixed color; `lowest-contrast` always picks the closest.
|
|
97
|
+
*
|
|
98
|
+
* @category Internal
|
|
99
|
+
*/
|
|
100
|
+
export var ExtremeContrastLevel;
|
|
101
|
+
(function (ExtremeContrastLevel) {
|
|
102
|
+
ExtremeContrastLevel["HighestContrast"] = "highest-contrast";
|
|
103
|
+
ExtremeContrastLevel["LowestContrast"] = "lowest-contrast";
|
|
104
|
+
})(ExtremeContrastLevel || (ExtremeContrastLevel = {}));
|
|
105
|
+
/**
|
|
106
|
+
* Picks the absolute lightest or darkest palette color based on which extreme produces the most (or
|
|
107
|
+
* least) contrast against the fixed color.
|
|
108
|
+
*/
|
|
109
|
+
function resolveExtremeContrastColor({ comparison, isHighestContrast, lightestColorString, darkestColorString, }) {
|
|
110
|
+
const paletteIsBackground = check.isArray(comparison.background);
|
|
111
|
+
const fixedColor = paletteIsBackground
|
|
112
|
+
? comparison.foreground
|
|
113
|
+
: comparison.background;
|
|
114
|
+
const lightContrastParams = paletteIsBackground
|
|
115
|
+
? {
|
|
116
|
+
foreground: fixedColor,
|
|
117
|
+
background: lightestColorString,
|
|
118
|
+
}
|
|
119
|
+
: {
|
|
120
|
+
foreground: lightestColorString,
|
|
121
|
+
background: fixedColor,
|
|
122
|
+
};
|
|
123
|
+
const darkContrastParams = paletteIsBackground
|
|
124
|
+
? {
|
|
125
|
+
foreground: fixedColor,
|
|
126
|
+
background: darkestColorString,
|
|
127
|
+
}
|
|
128
|
+
: {
|
|
129
|
+
foreground: darkestColorString,
|
|
130
|
+
background: fixedColor,
|
|
131
|
+
};
|
|
132
|
+
const lightestContrast = Math.abs(calculateContrast(lightContrastParams).contrast);
|
|
133
|
+
const darkestContrast = Math.abs(calculateContrast(darkContrastParams).contrast);
|
|
134
|
+
return isHighestContrast
|
|
135
|
+
? lightestContrast > darkestContrast
|
|
136
|
+
? lightestColorString
|
|
137
|
+
: darkestColorString
|
|
138
|
+
: lightestContrast < darkestContrast
|
|
139
|
+
? lightestColorString
|
|
140
|
+
: darkestColorString;
|
|
141
|
+
}
|
|
93
142
|
function findColorWithPreference(colors, desiredContrastLevel, preference,
|
|
94
143
|
/** Pre-computed contrast-against-white values per color string. Higher = darker. */
|
|
95
144
|
lightnessProxies) {
|
|
@@ -140,6 +189,11 @@ export function buildColorTheme(colorPalette, { omittedColorValues = defaultOmit
|
|
|
140
189
|
const lightThemeColors = {};
|
|
141
190
|
const darkThemeOverrides = {};
|
|
142
191
|
// Compute these once outside the loop since they don't change
|
|
192
|
+
const allContrastLevels = [
|
|
193
|
+
ExtremeContrastLevel.HighestContrast,
|
|
194
|
+
...contrastLevels,
|
|
195
|
+
ExtremeContrastLevel.LowestContrast,
|
|
196
|
+
];
|
|
143
197
|
const allCrosses = crossProduct({
|
|
144
198
|
crossWith: [
|
|
145
199
|
'color-in-foreground-light-mode',
|
|
@@ -151,7 +205,7 @@ export function buildColorTheme(colorPalette, { omittedColorValues = defaultOmit
|
|
|
151
205
|
'color-on-self-light-mode',
|
|
152
206
|
'color-on-self-dark-mode',
|
|
153
207
|
],
|
|
154
|
-
contrast:
|
|
208
|
+
contrast: allContrastLevels,
|
|
155
209
|
});
|
|
156
210
|
const defaultForegroundString = noRefColorInitToString(defaultTheme.foreground);
|
|
157
211
|
const defaultBackgroundString = noRefColorInitToString(defaultTheme.background);
|
|
@@ -196,6 +250,15 @@ export function buildColorTheme(colorPalette, { omittedColorValues = defaultOmit
|
|
|
196
250
|
foreground: colorStrings,
|
|
197
251
|
background: darkestColorString,
|
|
198
252
|
}, ContrastLevelName.SmallBodyText, 'darkest', lightnessProxies), `Failed to find dark mode on-self foreground color for ${firstColor.colorName}`);
|
|
253
|
+
/**
|
|
254
|
+
* Reversed palette order for dark mode on-self backgrounds. `findColorAtContrastLevel`
|
|
255
|
+
* picks the last qualifying color in array order. With the natural lightest-to-darkest
|
|
256
|
+
* order, high-contrast backgrounds end up as the darkest palette colors, which are
|
|
257
|
+
* indistinguishable from the dark page background. Reversing the order makes it select
|
|
258
|
+
* the lightest palette color that still achieves the required contrast level, producing
|
|
259
|
+
* backgrounds that are visible against the dark page.
|
|
260
|
+
*/
|
|
261
|
+
const reversedColorStrings = colorStrings.toReversed();
|
|
199
262
|
// Pre-compute base name parts that don't change per cross
|
|
200
263
|
const baseNameParts = [
|
|
201
264
|
prefix,
|
|
@@ -215,7 +278,7 @@ export function buildColorTheme(colorPalette, { omittedColorValues = defaultOmit
|
|
|
215
278
|
: cross.crossWith === 'color-on-self-dark-mode'
|
|
216
279
|
? {
|
|
217
280
|
foreground: darkSelfFgString,
|
|
218
|
-
background:
|
|
281
|
+
background: reversedColorStrings,
|
|
219
282
|
}
|
|
220
283
|
: cross.crossWith === 'color-on-self-light-mode'
|
|
221
284
|
? {
|
|
@@ -285,7 +348,15 @@ export function buildColorTheme(colorPalette, { omittedColorValues = defaultOmit
|
|
|
285
348
|
if (!comparison) {
|
|
286
349
|
throw new Error(`Forgot to handle crossWith: '${cross.crossWith}'`);
|
|
287
350
|
}
|
|
288
|
-
const matchedColorString =
|
|
351
|
+
const matchedColorString = cross.contrast === ExtremeContrastLevel.HighestContrast ||
|
|
352
|
+
cross.contrast === ExtremeContrastLevel.LowestContrast
|
|
353
|
+
? resolveExtremeContrastColor({
|
|
354
|
+
comparison,
|
|
355
|
+
isHighestContrast: cross.contrast === ExtremeContrastLevel.HighestContrast,
|
|
356
|
+
lightestColorString,
|
|
357
|
+
darkestColorString,
|
|
358
|
+
})
|
|
359
|
+
: findColorAtContrastLevel(comparison, cross.contrast);
|
|
289
360
|
const matchedColor = matchedColorString
|
|
290
361
|
? colorByDefault[matchedColorString]
|
|
291
362
|
: undefined;
|