theme-vir 28.13.0 → 28.15.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.
- package/README.md +2 -2
- package/dist/color/build-color-theme.d.ts +85 -0
- package/dist/color/build-color-theme.js +183 -0
- package/dist/color/color-palette-book-pages.d.ts +18 -0
- package/dist/color/color-palette-book-pages.js +232 -0
- package/dist/color/color-theme-book-pages.d.ts +12 -5
- package/dist/color/color-theme-book-pages.js +101 -64
- package/dist/color/color-theme.d.ts +13 -3
- package/dist/color/color-theme.js +129 -10
- package/dist/color/contrast.d.ts +61 -11
- package/dist/color/contrast.js +106 -15
- package/dist/color/elements/theme-vir-color-example.element.d.ts +4 -3
- package/dist/color/elements/theme-vir-color-example.element.js +17 -15
- package/dist/color/elements/theme-vir-contrast-indicator.element.d.ts +2 -1
- package/dist/color/elements/theme-vir-contrast-indicator.element.js +4 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/package.json +12 -10
|
@@ -1,79 +1,99 @@
|
|
|
1
|
+
import { check } from '@augment-vir/assert';
|
|
2
|
+
import { groupArrayBy } from '@augment-vir/common';
|
|
1
3
|
import { BookPageControlType, defineBookPage, definePageControl, } from 'element-book';
|
|
2
4
|
import { css, html, listen, nothing } from 'element-vir';
|
|
5
|
+
import { generateThemeCode } from './color-theme.js';
|
|
3
6
|
import { ThemeVirColorExample } from './elements/theme-vir-color-example.element.js';
|
|
4
7
|
/**
|
|
5
8
|
* Create multiple element-book pages to showcase a theme its overrides (if any).
|
|
6
9
|
*
|
|
7
10
|
* @category Color Theme
|
|
8
11
|
*/
|
|
9
|
-
export function createColorThemeBookPages({ parent, title, theme, hideInverseColors, overrides, }) {
|
|
12
|
+
export function createColorThemeBookPages({ parent, title, theme, hideInverseColors, overrides, useVerticalLayout, prefixGroupByCount = 0, }) {
|
|
13
|
+
const themeControls = {
|
|
14
|
+
'Show Var Names': definePageControl({
|
|
15
|
+
controlType: BookPageControlType.Checkbox,
|
|
16
|
+
initValue: false,
|
|
17
|
+
}),
|
|
18
|
+
'Show Contrast Tips': definePageControl({
|
|
19
|
+
controlType: BookPageControlType.Checkbox,
|
|
20
|
+
initValue: true,
|
|
21
|
+
}),
|
|
22
|
+
};
|
|
10
23
|
const themeParentPage = defineBookPage({
|
|
11
24
|
parent,
|
|
12
25
|
title,
|
|
13
|
-
controls:
|
|
14
|
-
'Show Var Names': definePageControl({
|
|
15
|
-
controlType: BookPageControlType.Checkbox,
|
|
16
|
-
initValue: false,
|
|
17
|
-
}),
|
|
18
|
-
'Show Contrast Tips': definePageControl({
|
|
19
|
-
controlType: BookPageControlType.Checkbox,
|
|
20
|
-
initValue: true,
|
|
21
|
-
}),
|
|
22
|
-
},
|
|
26
|
+
controls: themeControls,
|
|
23
27
|
});
|
|
24
|
-
function
|
|
25
|
-
|
|
28
|
+
function buildThemeColorTemplate({ controls, theme, themeColorName, }) {
|
|
29
|
+
const themeColor = check.isKeyOf(themeColorName, theme.colors)
|
|
30
|
+
? theme.colors[themeColorName]
|
|
31
|
+
: undefined;
|
|
32
|
+
const inverseThemeColor = check.isKeyOf(themeColorName, theme.inverse)
|
|
33
|
+
? theme.inverse[themeColorName]
|
|
34
|
+
: undefined;
|
|
35
|
+
if (!themeColor || !inverseThemeColor) {
|
|
36
|
+
throw new Error(`No theme color found by name '${themeColorName}'`);
|
|
37
|
+
}
|
|
38
|
+
const normalTemplate = html `
|
|
39
|
+
<${ThemeVirColorExample.assign({
|
|
40
|
+
color: themeColor,
|
|
41
|
+
showVarValues: true,
|
|
42
|
+
showVarNames: controls['Show Var Names'],
|
|
43
|
+
showContrast: controls['Show Contrast Tips'],
|
|
44
|
+
fontWeight: 400,
|
|
45
|
+
})}></${ThemeVirColorExample}>
|
|
46
|
+
`;
|
|
47
|
+
const inverseColor = hideInverseColors ? undefined : inverseThemeColor;
|
|
48
|
+
const inverseTemplate = inverseColor
|
|
49
|
+
? html `
|
|
50
|
+
<${ThemeVirColorExample.assign({
|
|
51
|
+
color: inverseColor,
|
|
52
|
+
showVarValues: false,
|
|
53
|
+
showVarNames: controls['Show Var Names'],
|
|
54
|
+
showContrast: controls['Show Contrast Tips'],
|
|
55
|
+
fontWeight: 400,
|
|
56
|
+
})}></${ThemeVirColorExample}>
|
|
57
|
+
`
|
|
58
|
+
: nothing;
|
|
59
|
+
return html `
|
|
60
|
+
<div class="with-inverse">${normalTemplate}${inverseTemplate}</div>
|
|
61
|
+
`;
|
|
62
|
+
}
|
|
63
|
+
function createThemePageExamples(defineExample, theme) {
|
|
64
|
+
const groups = groupArrayBy(Object.keys(theme.colors), (value) => {
|
|
65
|
+
if (prefixGroupByCount) {
|
|
66
|
+
return value.split('-').slice(0, prefixGroupByCount).join('-');
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
return value;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
Object.entries(groups).forEach(([groupName, group,]) => {
|
|
73
|
+
if (!group) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
26
76
|
defineExample({
|
|
27
|
-
title:
|
|
77
|
+
title: groupName,
|
|
28
78
|
styles: css `
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
})}
|
|
48
|
-
${listen(ThemeVirColorExample.events.toggleShowVars, () => {
|
|
49
|
-
updateState({
|
|
50
|
-
forceShowEverything: !state.forceShowEverything,
|
|
51
|
-
});
|
|
52
|
-
})}
|
|
53
|
-
></${ThemeVirColorExample}>
|
|
54
|
-
`;
|
|
55
|
-
const inverseColor = hideInverseColors
|
|
56
|
-
? undefined
|
|
57
|
-
: theme.inverse[themeColor.name];
|
|
58
|
-
const inverseTemplate = inverseColor
|
|
59
|
-
? html `
|
|
60
|
-
<${ThemeVirColorExample.assign({
|
|
61
|
-
color: inverseColor,
|
|
62
|
-
showVarValues: false,
|
|
63
|
-
showVarNames: controls['Show Var Names'] || state.forceShowEverything,
|
|
64
|
-
showContrast: controls['Show Contrast Tips'] || state.forceShowEverything,
|
|
65
|
-
})}
|
|
66
|
-
${listen(ThemeVirColorExample.events.toggleShowVars, () => {
|
|
67
|
-
updateState({
|
|
68
|
-
forceShowEverything: !state.forceShowEverything,
|
|
69
|
-
});
|
|
70
|
-
})}
|
|
71
|
-
></${ThemeVirColorExample}>
|
|
72
|
-
`
|
|
73
|
-
: nothing;
|
|
74
|
-
return html `
|
|
75
|
-
${normalTemplate}${inverseTemplate}
|
|
76
|
-
`;
|
|
79
|
+
:host {
|
|
80
|
+
display: flex;
|
|
81
|
+
flex-direction: column;
|
|
82
|
+
gap: 4px;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.with-inverse {
|
|
86
|
+
display: flex;
|
|
87
|
+
flex-direction: column;
|
|
88
|
+
gap: 4px;
|
|
89
|
+
}
|
|
90
|
+
`,
|
|
91
|
+
render({ controls }) {
|
|
92
|
+
return group.map((entry) => buildThemeColorTemplate({
|
|
93
|
+
controls,
|
|
94
|
+
theme,
|
|
95
|
+
themeColorName: entry,
|
|
96
|
+
}));
|
|
77
97
|
},
|
|
78
98
|
});
|
|
79
99
|
});
|
|
@@ -85,17 +105,34 @@ export function createColorThemeBookPages({ parent, title, theme, hideInverseCol
|
|
|
85
105
|
parent: themeParentPage,
|
|
86
106
|
title: 'Default Theme',
|
|
87
107
|
descriptionParagraphs,
|
|
108
|
+
useVerticalExamples: useVerticalLayout,
|
|
109
|
+
controls: {
|
|
110
|
+
copy: definePageControl({
|
|
111
|
+
controlType: BookPageControlType.Custom,
|
|
112
|
+
content: html `
|
|
113
|
+
<button
|
|
114
|
+
${listen('click', async () => {
|
|
115
|
+
const code = generateThemeCode(theme, 'viraColorPalette');
|
|
116
|
+
await navigator.clipboard.writeText(code);
|
|
117
|
+
})}
|
|
118
|
+
>
|
|
119
|
+
Copy Code
|
|
120
|
+
</button>
|
|
121
|
+
`,
|
|
122
|
+
}),
|
|
123
|
+
},
|
|
88
124
|
defineExamples({ defineExample }) {
|
|
89
|
-
|
|
125
|
+
createThemePageExamples(defineExample, theme);
|
|
90
126
|
},
|
|
91
127
|
});
|
|
92
128
|
const overridePages = (overrides || []).map((override) => {
|
|
93
129
|
return defineBookPage({
|
|
94
130
|
parent: themeParentPage,
|
|
95
131
|
title: override.name,
|
|
132
|
+
useVerticalExamples: useVerticalLayout,
|
|
96
133
|
descriptionParagraphs,
|
|
97
134
|
defineExamples({ defineExample }) {
|
|
98
|
-
|
|
135
|
+
createThemePageExamples(defineExample, override.asTheme);
|
|
99
136
|
},
|
|
100
137
|
});
|
|
101
138
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type RequiredAndNotNull } from '@augment-vir/common';
|
|
1
|
+
import { type RequiredAndNotNull, type Values } from '@augment-vir/common';
|
|
2
2
|
import { type CSSResult } from 'element-vir';
|
|
3
3
|
import { type CssVarName, type SingleCssVarDefinition } from 'lit-css-vars';
|
|
4
4
|
import { type RequireAtLeastOne } from 'type-fest';
|
|
@@ -10,13 +10,15 @@ import { type RequireAtLeastOne } from 'type-fest';
|
|
|
10
10
|
export type ColorInitReference = RequireAtLeastOne<{
|
|
11
11
|
refForeground: CssVarName;
|
|
12
12
|
refBackground: CssVarName;
|
|
13
|
+
refDefaultBackground: true;
|
|
14
|
+
refDefaultForeground: true;
|
|
13
15
|
}>;
|
|
14
16
|
/**
|
|
15
17
|
* All possible types for {@link ColorInit}.
|
|
16
18
|
*
|
|
17
19
|
* @category Internal
|
|
18
20
|
*/
|
|
19
|
-
export type ColorInitValue = string | number | CSSResult | ColorInitReference;
|
|
21
|
+
export type ColorInitValue = string | number | CSSResult | ColorInitReference | SingleCssVarDefinition;
|
|
20
22
|
/**
|
|
21
23
|
* An individual theme color init.
|
|
22
24
|
*
|
|
@@ -80,12 +82,14 @@ export type AllColorThemeColors<Init extends ColorThemeInit = ColorThemeInit> =
|
|
|
80
82
|
} & {
|
|
81
83
|
[themeDefaultKey]: ColorThemeColor<RequiredAndNotNull<NoRefColorInit>, typeof themeDefaultKey>;
|
|
82
84
|
};
|
|
85
|
+
/** @category Internal */
|
|
86
|
+
export declare function noRefColorInitToString(init: Values<NoRefColorInit>): string;
|
|
83
87
|
/**
|
|
84
88
|
* Handles a color init value.
|
|
85
89
|
*
|
|
86
90
|
* @category Internal
|
|
87
91
|
*/
|
|
88
|
-
export declare function createColorCssVarDefault(fromName: string, init: ColorInitValue, defaultInit: RequiredAndNotNull<NoRefColorInit>, colorsInit: ColorThemeInit):
|
|
92
|
+
export declare function createColorCssVarDefault(fromName: string, init: ColorInitValue, defaultInit: RequiredAndNotNull<NoRefColorInit>, colorsInit: ColorThemeInit): string | number | CSSResult;
|
|
89
93
|
/**
|
|
90
94
|
* Default foreground/background color theme used in {@link ColorTheme}. Do not define a theme color
|
|
91
95
|
* with this name!
|
|
@@ -99,3 +103,9 @@ export declare const themeDefaultKey = "theme-default";
|
|
|
99
103
|
* @category Color Theme
|
|
100
104
|
*/
|
|
101
105
|
export declare function defineColorTheme<const Init extends ColorThemeInit>(defaultInit: RequiredAndNotNull<NoRefColorInit>, allColorsInit: Init): ColorTheme<Init>;
|
|
106
|
+
/**
|
|
107
|
+
* Convert a color theme into code to define that color theme.
|
|
108
|
+
*
|
|
109
|
+
* @category Color Theme
|
|
110
|
+
*/
|
|
111
|
+
export declare function generateThemeCode(theme: ColorTheme, paletteVarName?: string | undefined): string;
|
|
@@ -1,21 +1,39 @@
|
|
|
1
1
|
import { assert, check } from '@augment-vir/assert';
|
|
2
|
-
import { getObjectTypedEntries, log } from '@augment-vir/common';
|
|
2
|
+
import { getObjectTypedEntries, log, } from '@augment-vir/common';
|
|
3
3
|
import { defineCssVars, } from 'lit-css-vars';
|
|
4
|
+
/** @category Internal */
|
|
5
|
+
export function noRefColorInitToString(init) {
|
|
6
|
+
if (check.isPrimitive(init) || '_$cssResult$' in init) {
|
|
7
|
+
return String(init);
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
return init.default;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
4
13
|
/**
|
|
5
14
|
* Handles a color init value.
|
|
6
15
|
*
|
|
7
16
|
* @category Internal
|
|
8
17
|
*/
|
|
9
18
|
export function createColorCssVarDefault(fromName, init, defaultInit, colorsInit) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (
|
|
19
|
+
if (check.isPrimitive(init) || '_$cssResult$' in init) {
|
|
20
|
+
return init;
|
|
21
|
+
}
|
|
22
|
+
else if ('refDefaultBackground' in init) {
|
|
23
|
+
return '--var(default-bg)';
|
|
24
|
+
}
|
|
25
|
+
else if ('refDefaultForeground' in init) {
|
|
26
|
+
return '--var(default-fg)';
|
|
27
|
+
}
|
|
28
|
+
else if ('refBackground' in init || 'refForeground' in init) {
|
|
29
|
+
const referenceKey = check.hasKey(init, 'refBackground')
|
|
30
|
+
? 'refBackground'
|
|
31
|
+
: check.hasKey(init, 'refForeground')
|
|
32
|
+
? 'refForeground'
|
|
33
|
+
: undefined;
|
|
34
|
+
const reference = referenceKey && check.hasKey(init, referenceKey) ? init[referenceKey] : undefined;
|
|
17
35
|
const layerKey = referenceKey === 'refBackground' ? 'background' : 'foreground';
|
|
18
|
-
const referenced = colorsInit[reference];
|
|
36
|
+
const referenced = reference && colorsInit[reference];
|
|
19
37
|
if (!referenced) {
|
|
20
38
|
throw new Error(`Color theme ${referenceKey} reference '${reference}' does not exist. (Referenced from '${fromName}'.)`);
|
|
21
39
|
}
|
|
@@ -26,7 +44,7 @@ export function createColorCssVarDefault(fromName, init, defaultInit, colorsInit
|
|
|
26
44
|
return `var(--${reference}-${layerKey === 'foreground' ? 'fg' : 'bg'}, ${createColorCssVarDefault(reference, colorValue, defaultInit, colorsInit)})`;
|
|
27
45
|
}
|
|
28
46
|
else {
|
|
29
|
-
return init;
|
|
47
|
+
return init.value;
|
|
30
48
|
}
|
|
31
49
|
}
|
|
32
50
|
/**
|
|
@@ -157,3 +175,104 @@ function createCssVarNames(colorName) {
|
|
|
157
175
|
].join('-'),
|
|
158
176
|
};
|
|
159
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Convert a color theme into code to define that color theme.
|
|
180
|
+
*
|
|
181
|
+
* @category Color Theme
|
|
182
|
+
*/
|
|
183
|
+
export function generateThemeCode(theme, paletteVarName) {
|
|
184
|
+
const defaultInitCode = colorInitToCode(theme.init.default, 1, undefined, paletteVarName);
|
|
185
|
+
const colorsInitCode = colorThemeInitToCode(theme.init.colors, 1, theme.init.default, paletteVarName);
|
|
186
|
+
return `defineColorTheme(\n${defaultInitCode},\n${colorsInitCode},\n)`;
|
|
187
|
+
}
|
|
188
|
+
function tab(level) {
|
|
189
|
+
return ' '.repeat(level);
|
|
190
|
+
}
|
|
191
|
+
function colorInitValuesEqual(a, b) {
|
|
192
|
+
if (typeof a !== typeof b) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
if (typeof a === 'string' || typeof a === 'number') {
|
|
196
|
+
return a === b;
|
|
197
|
+
}
|
|
198
|
+
if ('_$cssResult$' in a && '_$cssResult$' in b) {
|
|
199
|
+
return a.cssText === b.cssText;
|
|
200
|
+
}
|
|
201
|
+
// For references and SingleCssVarDefinition, compare as JSON
|
|
202
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
203
|
+
}
|
|
204
|
+
function extractCssVarName(cssValue) {
|
|
205
|
+
const match = cssValue.match(/^var\(--([^,)]+)/);
|
|
206
|
+
return match ? match[1] : undefined;
|
|
207
|
+
}
|
|
208
|
+
function colorInitValueToCode(value, indentLevel, paletteVarName) {
|
|
209
|
+
if (typeof value === 'string') {
|
|
210
|
+
return `'${value}'`;
|
|
211
|
+
}
|
|
212
|
+
else if (typeof value === 'number') {
|
|
213
|
+
return String(value);
|
|
214
|
+
}
|
|
215
|
+
else if ('_$cssResult$' in value) {
|
|
216
|
+
const cssText = String(value);
|
|
217
|
+
if (paletteVarName) {
|
|
218
|
+
const varName = extractCssVarName(cssText);
|
|
219
|
+
if (varName) {
|
|
220
|
+
return `${paletteVarName}['${varName}']`;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return `css\`${cssText}\``;
|
|
224
|
+
}
|
|
225
|
+
else if ('refBackground' in value ||
|
|
226
|
+
'refForeground' in value ||
|
|
227
|
+
'refDefaultBackground' in value ||
|
|
228
|
+
'refDefaultForeground' in value) {
|
|
229
|
+
const entries = [];
|
|
230
|
+
if ('refForeground' in value) {
|
|
231
|
+
entries.push(`${tab(indentLevel + 1)}refForeground: '${value.refForeground}',`);
|
|
232
|
+
}
|
|
233
|
+
if ('refBackground' in value) {
|
|
234
|
+
entries.push(`${tab(indentLevel + 1)}refBackground: '${value.refBackground}',`);
|
|
235
|
+
}
|
|
236
|
+
if ('refDefaultForeground' in value) {
|
|
237
|
+
entries.push(`${tab(indentLevel + 1)}refDefaultForeground: true,`);
|
|
238
|
+
}
|
|
239
|
+
if ('refDefaultBackground' in value) {
|
|
240
|
+
entries.push(`${tab(indentLevel + 1)}refDefaultBackground: true,`);
|
|
241
|
+
}
|
|
242
|
+
return `{\n${entries.join('\n')}\n${tab(indentLevel)}}`;
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
// SingleCssVarDefinition
|
|
246
|
+
return `'${value.default}'`;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
function colorInitToCode(colorInit, indentLevel, defaultInit, paletteVarName) {
|
|
250
|
+
const entries = [];
|
|
251
|
+
if ('foreground' in colorInit &&
|
|
252
|
+
(!defaultInit || !colorInitValuesEqual(colorInit.foreground, defaultInit.foreground))) {
|
|
253
|
+
// Check if foreground matches default background (use refDefaultBackground)
|
|
254
|
+
if (defaultInit && colorInitValuesEqual(colorInit.foreground, defaultInit.background)) {
|
|
255
|
+
entries.push(`${tab(indentLevel + 1)}foreground: {\n${tab(indentLevel + 2)}refDefaultBackground: true,\n${tab(indentLevel + 1)}},`);
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
entries.push(`${tab(indentLevel + 1)}foreground: ${colorInitValueToCode(colorInit.foreground, indentLevel + 1, paletteVarName)},`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if ('background' in colorInit &&
|
|
262
|
+
(!defaultInit || !colorInitValuesEqual(colorInit.background, defaultInit.background))) {
|
|
263
|
+
// Check if background matches default foreground (use refDefaultForeground)
|
|
264
|
+
if (defaultInit && colorInitValuesEqual(colorInit.background, defaultInit.foreground)) {
|
|
265
|
+
entries.push(`${tab(indentLevel + 1)}background: {\n${tab(indentLevel + 2)}refDefaultForeground: true,\n${tab(indentLevel + 1)}},`);
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
entries.push(`${tab(indentLevel + 1)}background: ${colorInitValueToCode(colorInit.background, indentLevel + 1, paletteVarName)},`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return `${tab(indentLevel)}{\n${entries.join('\n')}\n${tab(indentLevel)}}`;
|
|
272
|
+
}
|
|
273
|
+
function colorThemeInitToCode(colorsInit, indentLevel, defaultInit, paletteVarName) {
|
|
274
|
+
const entries = getObjectTypedEntries(colorsInit).map(([colorName, colorInit,]) => {
|
|
275
|
+
return `${tab(indentLevel + 1)}'${colorName}': ${colorInitToCode(colorInit, indentLevel + 1, defaultInit, paletteVarName).trimStart()},`;
|
|
276
|
+
});
|
|
277
|
+
return `${tab(indentLevel)}{\n${entries.join('\n')}\n${tab(indentLevel)}}`;
|
|
278
|
+
}
|
package/dist/color/contrast.d.ts
CHANGED
|
@@ -1,17 +1,52 @@
|
|
|
1
|
-
import { type ArrayElement } from '@augment-vir/common';
|
|
1
|
+
import { type ArrayElement, type ExtractKeysWithMatchingValues, type Values } from '@augment-vir/common';
|
|
2
2
|
/**
|
|
3
3
|
* All font weights that font sizes are calculated for. Used in {@link FontSizes} and
|
|
4
4
|
* {@link calculateFontSizes}.
|
|
5
5
|
*
|
|
6
6
|
* @category Internal
|
|
7
7
|
*/
|
|
8
|
-
export type
|
|
8
|
+
export type FontWeight = 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
|
|
9
|
+
/**
|
|
10
|
+
* All considered font weights in {@link FontWeight} mapped by their weight name.
|
|
11
|
+
*
|
|
12
|
+
* @category Internal
|
|
13
|
+
*/
|
|
14
|
+
export declare const fontWeightByName: {
|
|
15
|
+
readonly Thin: 100;
|
|
16
|
+
readonly ExtraLight: 200;
|
|
17
|
+
readonly Light: 300;
|
|
18
|
+
readonly Normal: 400;
|
|
19
|
+
readonly Medium: 500;
|
|
20
|
+
readonly SemiBold: 600;
|
|
21
|
+
readonly Bold: 700;
|
|
22
|
+
readonly ExtraBold: 800;
|
|
23
|
+
readonly Heavy: 900;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* All font weight names from {@link fontWeightByName}.
|
|
27
|
+
*
|
|
28
|
+
* @category Internal
|
|
29
|
+
*/
|
|
30
|
+
export type FontWeightName = keyof typeof fontWeightByName;
|
|
31
|
+
/**
|
|
32
|
+
* All font weight names from {@link fontWeightByName}.
|
|
33
|
+
*
|
|
34
|
+
* @category Internal
|
|
35
|
+
*/
|
|
36
|
+
export declare const FontWeightName: { [Key in FontWeightName]: Key; };
|
|
37
|
+
/**
|
|
38
|
+
* All considered font weights in {@link FontWeight} mapped to their weight name from
|
|
39
|
+
* {@link fontWeightByName}.
|
|
40
|
+
*
|
|
41
|
+
* @category Internal
|
|
42
|
+
*/
|
|
43
|
+
export declare const fontWeightToName: { [Weight in Values<typeof fontWeightByName>]: ExtractKeysWithMatchingValues<typeof fontWeightByName, Weight>; };
|
|
9
44
|
/**
|
|
10
45
|
* A mapping of font weights to font sizes. Used in {@link calculateFontSizes}.
|
|
11
46
|
*
|
|
12
47
|
* @category Internal
|
|
13
48
|
*/
|
|
14
|
-
export type FontSizes = Record<
|
|
49
|
+
export type FontSizes = Record<FontWeight, number>;
|
|
15
50
|
/**
|
|
16
51
|
* Contrast calculations produced by {@link calculateContrast}.
|
|
17
52
|
*
|
|
@@ -41,6 +76,21 @@ export type ColorPair = {
|
|
|
41
76
|
* @category Internal
|
|
42
77
|
*/
|
|
43
78
|
export declare function calculateContrast({ background, foreground, }: Readonly<ColorPair>): CalculatedContrast;
|
|
79
|
+
/** @category Internal */
|
|
80
|
+
export declare function findClosestColor(baseColor: string, possibleColors: ReadonlyArray<string>): string;
|
|
81
|
+
/**
|
|
82
|
+
* Find a color from an array that matches the desired contrast level.
|
|
83
|
+
*
|
|
84
|
+
* @category Internal
|
|
85
|
+
* @returns `undefined` if no color match is found.
|
|
86
|
+
*/
|
|
87
|
+
export declare function findColorAtContrastLevel(colors: Readonly<{
|
|
88
|
+
foreground: string;
|
|
89
|
+
background: string[];
|
|
90
|
+
} | {
|
|
91
|
+
foreground: string[];
|
|
92
|
+
background: string;
|
|
93
|
+
}>, desiredContrastLevel: ContrastLevelName): string | undefined;
|
|
44
94
|
/**
|
|
45
95
|
* Calculated needed font sizes for each font weight for the given color contrast.
|
|
46
96
|
*
|
|
@@ -59,11 +109,11 @@ export declare function determineContrastLevel(contrast: number): ContrastLevel;
|
|
|
59
109
|
* @category Internal
|
|
60
110
|
*/
|
|
61
111
|
export declare enum ContrastLevelName {
|
|
62
|
-
SmallBodyText = "small-body
|
|
63
|
-
BodyText = "body
|
|
64
|
-
NonBodyText = "non-body
|
|
65
|
-
|
|
66
|
-
|
|
112
|
+
SmallBodyText = "small-body",
|
|
113
|
+
BodyText = "body",
|
|
114
|
+
NonBodyText = "non-body",
|
|
115
|
+
Header = "header",
|
|
116
|
+
Placeholder = "placeholder",
|
|
67
117
|
Decoration = "decoration",
|
|
68
118
|
Invisible = "invisible"
|
|
69
119
|
}
|
|
@@ -78,7 +128,7 @@ export declare const contrastLevelLabel: Record<ContrastLevelName, string>;
|
|
|
78
128
|
*
|
|
79
129
|
* @category Internal
|
|
80
130
|
*/
|
|
81
|
-
export declare const orderedContrastLevelNames: readonly [ContrastLevelName.SmallBodyText, ContrastLevelName.BodyText, ContrastLevelName.NonBodyText, ContrastLevelName.
|
|
131
|
+
export declare const orderedContrastLevelNames: readonly [ContrastLevelName.SmallBodyText, ContrastLevelName.BodyText, ContrastLevelName.NonBodyText, ContrastLevelName.Header, ContrastLevelName.Placeholder, ContrastLevelName.Decoration, ContrastLevelName.Invisible];
|
|
82
132
|
/**
|
|
83
133
|
* Color contrast level details.
|
|
84
134
|
*
|
|
@@ -121,13 +171,13 @@ export declare const contrastLevels: readonly [{
|
|
|
121
171
|
readonly apcaDescription: "The minimum level recommended for content text that is not body, column, or block text. In other words, text you want people to read. The minimums: no smaller than 48px/200, 36px/300, 24px normal weight (400), 21px/500, 18px/600, 16px/700 (bold). These values based on the reference font Helvetica. To use these sizes as body text, add Lc 15 to the minimum contrast.";
|
|
122
172
|
}, {
|
|
123
173
|
readonly min: 45;
|
|
124
|
-
readonly name: ContrastLevelName.
|
|
174
|
+
readonly name: ContrastLevelName.Header;
|
|
125
175
|
readonly description: "Okay for large or headline text.";
|
|
126
176
|
readonly apcaName: "large & sub-fluent text";
|
|
127
177
|
readonly apcaDescription: "The minimum for larger, heavier text (36px normal weight or 24px bold) such as headlines, and large text that should be fluently readable but is not body text. This is also the minimum for pictograms with fine details, or smaller outline icons, , no less than 4px in its smallest dimension.";
|
|
128
178
|
}, {
|
|
129
179
|
readonly min: 30;
|
|
130
|
-
readonly name: ContrastLevelName.
|
|
180
|
+
readonly name: ContrastLevelName.Placeholder;
|
|
131
181
|
readonly description: "Okay for disabled or placeholder text, copyright lines, icons, or non-text elements.";
|
|
132
182
|
readonly apcaName: "spot & non text only";
|
|
133
183
|
readonly apcaDescription: "The absolute minimum for any text not listed above, which means non-content text considered as \"spot readable\". This includes placeholder text and disabled element text, and some non-content like a copyright bug. This is also the minimum for large/solid semantic & understandable non-text elements such as \"mostly solid\" icons or pictograms, no less than 10px in its smallest dimension.";
|