theme-vir 28.16.1 → 28.17.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/dist/{color → color-theme}/build-color-theme.d.ts +18 -5
- package/dist/{color → color-theme}/build-color-theme.js +115 -40
- package/dist/{color → color-theme}/color-palette-book-pages.js +4 -2
- package/dist/{color → color-theme}/color-theme-book-pages.js +33 -9
- package/dist/color-theme/color-theme-code.d.ts +12 -0
- package/dist/color-theme/color-theme-code.js +150 -0
- package/dist/{color → color-theme}/color-theme.d.ts +0 -6
- package/dist/{color → color-theme}/color-theme.js +0 -101
- package/dist/index.d.ts +7 -6
- package/dist/index.js +7 -6
- package/package.json +3 -2
- /package/dist/{color → color-theme}/color-css.d.ts +0 -0
- /package/dist/{color → color-theme}/color-css.js +0 -0
- /package/dist/{color → color-theme}/color-palette-book-pages.d.ts +0 -0
- /package/dist/{color → color-theme}/color-theme-book-pages.d.ts +0 -0
- /package/dist/{color → color-theme}/color-theme-override.d.ts +0 -0
- /package/dist/{color → color-theme}/color-theme-override.js +0 -0
|
@@ -43,7 +43,7 @@ export declare const defaultLightThemePair: RequiredAndNotNull<NoRefColorInit>;
|
|
|
43
43
|
/** @category Internal */
|
|
44
44
|
export declare const defaultContrastLevels: Readonly<ArrayOrSelectParam<ContrastLevelName>>;
|
|
45
45
|
/**
|
|
46
|
-
* Options for {@link
|
|
46
|
+
* Options for {@link buildColorTheme}.
|
|
47
47
|
*
|
|
48
48
|
* @category Internal
|
|
49
49
|
*/
|
|
@@ -74,8 +74,8 @@ export type BuildLowLevelColorThemeOptions = PartialWithUndefined<{
|
|
|
74
74
|
*
|
|
75
75
|
* @category Color Theme
|
|
76
76
|
*/
|
|
77
|
-
export declare function
|
|
78
|
-
|
|
77
|
+
export declare function buildColorTheme(colorPalette: Readonly<ColorPaletteVars>, { omittedColorValues, crossContrastLevels, }?: Readonly<BuildLowLevelColorThemeOptions>): {
|
|
78
|
+
defaultLight: import("./color-theme.js").ColorTheme<Record<`${Lowercase<string>}-${Lowercase<string>}`, ((Required<Pick<{
|
|
79
79
|
foreground: import("./color-theme.js").ColorInitValue;
|
|
80
80
|
background: import("./color-theme.js").ColorInitValue;
|
|
81
81
|
}, "foreground">> & Partial<Pick<{
|
|
@@ -87,5 +87,18 @@ export declare function buildLowLevelColorTheme(colorPalette: Readonly<ColorPale
|
|
|
87
87
|
}, "background">> & Partial<Pick<{
|
|
88
88
|
foreground: import("./color-theme.js").ColorInitValue;
|
|
89
89
|
background: import("./color-theme.js").ColorInitValue;
|
|
90
|
-
}, "foreground">>)) & {}
|
|
91
|
-
}
|
|
90
|
+
}, "foreground">>)) & {}>>;
|
|
91
|
+
darkOverride: import("./color-theme-override.js").ColorThemeOverride<Record<`${Lowercase<string>}-${Lowercase<string>}`, ((Required<Pick<{
|
|
92
|
+
foreground: import("./color-theme.js").ColorInitValue;
|
|
93
|
+
background: import("./color-theme.js").ColorInitValue;
|
|
94
|
+
}, "foreground">> & Partial<Pick<{
|
|
95
|
+
foreground: import("./color-theme.js").ColorInitValue;
|
|
96
|
+
background: import("./color-theme.js").ColorInitValue;
|
|
97
|
+
}, "background">>) | (Required<Pick<{
|
|
98
|
+
foreground: import("./color-theme.js").ColorInitValue;
|
|
99
|
+
background: import("./color-theme.js").ColorInitValue;
|
|
100
|
+
}, "background">> & Partial<Pick<{
|
|
101
|
+
foreground: import("./color-theme.js").ColorInitValue;
|
|
102
|
+
background: import("./color-theme.js").ColorInitValue;
|
|
103
|
+
}, "foreground">>)) & {}>>;
|
|
104
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { assert, assertWrap, check } from '@augment-vir/assert';
|
|
2
2
|
import { crossProduct, filterMap, getOrSet, log, mapObjectValues, removeDuplicates, stringify, } from '@augment-vir/common';
|
|
3
3
|
import { ContrastLevelName, contrastLevelLabel, findClosestColor, findColorAtContrastLevel, } from '@electrovir/color';
|
|
4
|
+
import { defineColorThemeOverride } from './color-theme-override.js';
|
|
4
5
|
import { defineColorTheme, noRefColorInitToString, } from './color-theme.js';
|
|
5
6
|
/**
|
|
6
7
|
* Black and white color values.
|
|
@@ -99,22 +100,28 @@ export const defaultContrastLevels = {
|
|
|
99
100
|
*
|
|
100
101
|
* @category Color Theme
|
|
101
102
|
*/
|
|
102
|
-
export function
|
|
103
|
+
export function buildColorTheme(colorPalette, { omittedColorValues = defaultOmittedColorGroupColorValues, crossContrastLevels = defaultContrastLevels, } = {}) {
|
|
103
104
|
const contrastLevels = extractParam(crossContrastLevels, {
|
|
104
105
|
mapFrom: contrastLevelLabel,
|
|
105
106
|
});
|
|
106
107
|
const colorGroups = groupColors(colorPalette, omittedColorValues);
|
|
107
|
-
const
|
|
108
|
+
const defaultTheme = {
|
|
109
|
+
background: 'white',
|
|
110
|
+
foreground: 'black',
|
|
111
|
+
};
|
|
112
|
+
const lightThemeColors = {};
|
|
113
|
+
const darkThemeOverrides = {};
|
|
114
|
+
Object.entries(colorGroups).forEach(([colorGroupName, colors,]) => {
|
|
108
115
|
assert.isLengthAtLeast(colors, 1);
|
|
109
116
|
const colorStrings = colors.map((color) => color.definition.default);
|
|
110
117
|
const allCrosses = crossProduct({
|
|
111
118
|
crossWith: [
|
|
112
|
-
'
|
|
113
|
-
'
|
|
114
|
-
'
|
|
115
|
-
'
|
|
116
|
-
'self-
|
|
117
|
-
'self-light-
|
|
119
|
+
'color-in-foreground-light-mode',
|
|
120
|
+
'color-in-background-light-mode',
|
|
121
|
+
'color-in-foreground-dark-mode',
|
|
122
|
+
'color-in-background-dark-mode',
|
|
123
|
+
'color-on-self-dark-mode',
|
|
124
|
+
'color-on-self-light-mode',
|
|
118
125
|
],
|
|
119
126
|
contrast: contrastLevels,
|
|
120
127
|
// fontWeight: fontWeights,
|
|
@@ -123,61 +130,129 @@ export function buildLowLevelColorTheme(colorPalette, { defaultTheme = defaultLi
|
|
|
123
130
|
const defaultForegroundString = noRefColorInitToString(defaultTheme.foreground);
|
|
124
131
|
const defaultBackgroundString = noRefColorInitToString(defaultTheme.background);
|
|
125
132
|
const lightestSelf = findClosestColor('white', colorStrings);
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
firstColor.colorName,
|
|
130
|
-
cross.crossWith,
|
|
131
|
-
cross.contrast,
|
|
132
|
-
// cross.fontWeight,
|
|
133
|
-
].join('-');
|
|
134
|
-
const comparison = cross.crossWith === 'ahead-background'
|
|
133
|
+
const darkestSelf = findClosestColor('black', colorStrings);
|
|
134
|
+
allCrosses.forEach((cross) => {
|
|
135
|
+
const comparison = cross.crossWith === 'color-in-foreground-light-mode'
|
|
135
136
|
? {
|
|
136
137
|
foreground: colorStrings,
|
|
137
138
|
background: defaultBackgroundString,
|
|
138
139
|
}
|
|
139
|
-
: cross.crossWith === '
|
|
140
|
+
: cross.crossWith === 'color-in-background-light-mode'
|
|
140
141
|
? {
|
|
141
142
|
foreground: defaultBackgroundString,
|
|
142
143
|
background: colorStrings,
|
|
143
144
|
}
|
|
144
|
-
: cross.crossWith === '
|
|
145
|
+
: cross.crossWith === 'color-in-foreground-dark-mode'
|
|
145
146
|
? {
|
|
146
147
|
foreground: colorStrings,
|
|
147
148
|
background: defaultForegroundString,
|
|
148
149
|
}
|
|
149
|
-
: cross.crossWith === '
|
|
150
|
+
: cross.crossWith === 'color-in-background-dark-mode'
|
|
150
151
|
? {
|
|
151
152
|
foreground: defaultForegroundString,
|
|
152
153
|
background: colorStrings,
|
|
153
154
|
}
|
|
154
|
-
: cross.crossWith === 'self-
|
|
155
|
+
: cross.crossWith === 'color-on-self-dark-mode'
|
|
155
156
|
? {
|
|
156
157
|
foreground: colorStrings,
|
|
157
|
-
background:
|
|
158
|
+
background: darkestSelf,
|
|
158
159
|
}
|
|
159
|
-
:
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
160
|
+
: // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
161
|
+
cross.crossWith === 'color-on-self-light-mode'
|
|
162
|
+
? {
|
|
163
|
+
foreground: colorStrings,
|
|
164
|
+
background: lightestSelf,
|
|
165
|
+
}
|
|
166
|
+
: undefined;
|
|
167
|
+
if (!comparison) {
|
|
168
|
+
throw new Error(`Forgot to handle crossWith: '${cross.crossWith}'`);
|
|
169
|
+
}
|
|
163
170
|
const matchedColorString = findColorAtContrastLevel(comparison, cross.contrast);
|
|
164
171
|
const matchedColor = colors.find((color) => color.definition.default === matchedColorString);
|
|
165
172
|
if (!matchedColor) {
|
|
166
173
|
log.error(`No valid '${colorGroupName}' color cross found for: ${stringify(cross)} with ${stringify(colorStrings)}`);
|
|
167
174
|
return undefined;
|
|
168
175
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
176
|
+
const colorValue = mapObjectValues(comparison, (key, value) => {
|
|
177
|
+
if (check.isString(value)) {
|
|
178
|
+
return value;
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
return matchedColor.definition.value;
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
if (cross.crossWith === 'color-in-foreground-light-mode') {
|
|
185
|
+
const name = [
|
|
186
|
+
firstColor.prefix,
|
|
187
|
+
firstColor.colorName,
|
|
188
|
+
'foreground',
|
|
189
|
+
cross.contrast,
|
|
190
|
+
].join('-');
|
|
191
|
+
lightThemeColors[name] = colorValue;
|
|
192
|
+
}
|
|
193
|
+
else if (cross.crossWith === 'color-in-background-light-mode') {
|
|
194
|
+
const name = [
|
|
195
|
+
firstColor.prefix,
|
|
196
|
+
firstColor.colorName,
|
|
197
|
+
'background',
|
|
198
|
+
cross.contrast,
|
|
199
|
+
].join('-');
|
|
200
|
+
lightThemeColors[name] = colorValue;
|
|
201
|
+
}
|
|
202
|
+
else if (cross.crossWith === 'color-on-self-light-mode') {
|
|
203
|
+
const name = [
|
|
204
|
+
firstColor.prefix,
|
|
205
|
+
firstColor.colorName,
|
|
206
|
+
'on',
|
|
207
|
+
'self',
|
|
208
|
+
cross.contrast,
|
|
209
|
+
].join('-');
|
|
210
|
+
lightThemeColors[name] = colorValue;
|
|
211
|
+
}
|
|
212
|
+
else if (cross.crossWith === 'color-in-foreground-dark-mode') {
|
|
213
|
+
const name = [
|
|
214
|
+
firstColor.prefix,
|
|
215
|
+
firstColor.colorName,
|
|
216
|
+
'foreground',
|
|
217
|
+
cross.contrast,
|
|
218
|
+
].join('-');
|
|
219
|
+
darkThemeOverrides[name] = colorValue;
|
|
220
|
+
}
|
|
221
|
+
else if (cross.crossWith === 'color-in-background-dark-mode') {
|
|
222
|
+
const name = [
|
|
223
|
+
firstColor.prefix,
|
|
224
|
+
firstColor.colorName,
|
|
225
|
+
'background',
|
|
226
|
+
cross.contrast,
|
|
227
|
+
].join('-');
|
|
228
|
+
darkThemeOverrides[name] = colorValue;
|
|
229
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
230
|
+
}
|
|
231
|
+
else if (cross.crossWith === 'color-on-self-dark-mode') {
|
|
232
|
+
const name = [
|
|
233
|
+
firstColor.prefix,
|
|
234
|
+
firstColor.colorName,
|
|
235
|
+
'on',
|
|
236
|
+
'self',
|
|
237
|
+
cross.contrast,
|
|
238
|
+
].join('-');
|
|
239
|
+
darkThemeOverrides[name] = colorValue;
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
assert.tsType(cross.crossWith).equals();
|
|
243
|
+
throw new Error(`crossWith not handled: ${String(cross.crossWith)}`);
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
const defaultLightTheme = defineColorTheme(defaultTheme, lightThemeColors);
|
|
248
|
+
return {
|
|
249
|
+
defaultLight: defaultLightTheme,
|
|
250
|
+
darkOverride: defineColorThemeOverride(defaultLightTheme, 'dark', {
|
|
251
|
+
defaultOverride: {
|
|
252
|
+
background: 'black',
|
|
253
|
+
foreground: 'white',
|
|
254
|
+
},
|
|
255
|
+
colorOverrides: darkThemeOverrides,
|
|
256
|
+
}),
|
|
257
|
+
};
|
|
183
258
|
}
|
|
@@ -3,7 +3,7 @@ import { VirColorPair } from '@electrovir/color';
|
|
|
3
3
|
import { defineBookPage } from 'element-book';
|
|
4
4
|
import { css, html, unsafeCSS } from 'element-vir';
|
|
5
5
|
import { noNativeSpacing, viraColorPalette } from 'vira';
|
|
6
|
-
import {
|
|
6
|
+
import { buildColorTheme, groupColors, } from './build-color-theme.js';
|
|
7
7
|
import { createColorThemeBookPages } from './color-theme-book-pages.js';
|
|
8
8
|
const blackWhiteCells = [
|
|
9
9
|
{
|
|
@@ -211,6 +211,7 @@ export function createColorPaletteBookPages({ colors, parent, title, includeCont
|
|
|
211
211
|
};
|
|
212
212
|
}));
|
|
213
213
|
}
|
|
214
|
+
const generatedTheme = buildColorTheme(colors, options);
|
|
214
215
|
return [
|
|
215
216
|
topColorsPage,
|
|
216
217
|
colorPalettePage,
|
|
@@ -222,10 +223,11 @@ export function createColorPaletteBookPages({ colors, parent, title, includeCont
|
|
|
222
223
|
? createColorThemeBookPages({
|
|
223
224
|
parent: topColorsPage,
|
|
224
225
|
title: 'Theme (auto)',
|
|
225
|
-
theme:
|
|
226
|
+
theme: generatedTheme.defaultLight,
|
|
226
227
|
hideInverseColors: true,
|
|
227
228
|
useVerticalLayout: useVerticalTheme,
|
|
228
229
|
prefixGroupByCount: 2,
|
|
230
|
+
overrides: [generatedTheme.darkOverride],
|
|
229
231
|
})
|
|
230
232
|
: []),
|
|
231
233
|
].filter(check.isTruthy);
|
|
@@ -3,13 +3,14 @@ import { groupArrayBy } from '@augment-vir/common';
|
|
|
3
3
|
import { VirColorPair } from '@electrovir/color';
|
|
4
4
|
import { BookPageControlType, defineBookPage, definePageControl, } from 'element-book';
|
|
5
5
|
import { css, html, listen, nothing } from 'element-vir';
|
|
6
|
-
import { generateThemeCode } from './color-theme.js';
|
|
6
|
+
import { generateThemeCode } from './color-theme-code.js';
|
|
7
|
+
const noneOverridesSelectionValue = 'None';
|
|
7
8
|
/**
|
|
8
9
|
* Create multiple element-book pages to showcase a theme its overrides (if any).
|
|
9
10
|
*
|
|
10
11
|
* @category Color Theme
|
|
11
12
|
*/
|
|
12
|
-
export function createColorThemeBookPages({ parent, title, theme, hideInverseColors, overrides, useVerticalLayout, prefixGroupByCount =
|
|
13
|
+
export function createColorThemeBookPages({ parent, title, theme, hideInverseColors, overrides, useVerticalLayout, prefixGroupByCount = 2, }) {
|
|
13
14
|
const themeControls = {
|
|
14
15
|
'Show Var Names': definePageControl({
|
|
15
16
|
controlType: BookPageControlType.Checkbox,
|
|
@@ -20,6 +21,21 @@ export function createColorThemeBookPages({ parent, title, theme, hideInverseCol
|
|
|
20
21
|
initValue: true,
|
|
21
22
|
}),
|
|
22
23
|
};
|
|
24
|
+
const defaultThemeControls = {
|
|
25
|
+
'Theme Override': definePageControl({
|
|
26
|
+
controlType: BookPageControlType.Dropdown,
|
|
27
|
+
initValue: noneOverridesSelectionValue,
|
|
28
|
+
options: [
|
|
29
|
+
noneOverridesSelectionValue,
|
|
30
|
+
...(overrides || []).map((override) => {
|
|
31
|
+
if (override.name === noneOverridesSelectionValue) {
|
|
32
|
+
throw new Error(`Cannot have theme override named '${noneOverridesSelectionValue}'`);
|
|
33
|
+
}
|
|
34
|
+
return override.name;
|
|
35
|
+
}),
|
|
36
|
+
],
|
|
37
|
+
}),
|
|
38
|
+
};
|
|
23
39
|
const themeParentPage = defineBookPage({
|
|
24
40
|
parent,
|
|
25
41
|
title,
|
|
@@ -60,8 +76,8 @@ export function createColorThemeBookPages({ parent, title, theme, hideInverseCol
|
|
|
60
76
|
<div class="with-inverse">${normalTemplate}${inverseTemplate}</div>
|
|
61
77
|
`;
|
|
62
78
|
}
|
|
63
|
-
function createThemePageExamples(defineExample,
|
|
64
|
-
const groups = groupArrayBy(Object.keys(
|
|
79
|
+
function createThemePageExamples(defineExample, defaultTheme, overrides) {
|
|
80
|
+
const groups = groupArrayBy(Object.keys(defaultTheme.colors), (value) => {
|
|
65
81
|
if (prefixGroupByCount) {
|
|
66
82
|
return value.split('-').slice(0, prefixGroupByCount).join('-');
|
|
67
83
|
}
|
|
@@ -89,9 +105,13 @@ export function createColorThemeBookPages({ parent, title, theme, hideInverseCol
|
|
|
89
105
|
}
|
|
90
106
|
`,
|
|
91
107
|
render({ controls }) {
|
|
108
|
+
const selectedOverride = ('Theme Override' in controls &&
|
|
109
|
+
controls['Theme Override'] &&
|
|
110
|
+
overrides?.find((override) => override.name === controls['Theme Override'])) ||
|
|
111
|
+
undefined;
|
|
92
112
|
return group.map((entry) => buildThemeColorTemplate({
|
|
93
113
|
controls,
|
|
94
|
-
theme,
|
|
114
|
+
theme: selectedOverride?.asTheme || defaultTheme,
|
|
95
115
|
themeColorName: entry,
|
|
96
116
|
}));
|
|
97
117
|
},
|
|
@@ -103,7 +123,7 @@ export function createColorThemeBookPages({ parent, title, theme, hideInverseCol
|
|
|
103
123
|
];
|
|
104
124
|
const defaultThemePage = defineBookPage({
|
|
105
125
|
parent: themeParentPage,
|
|
106
|
-
title: 'Default
|
|
126
|
+
title: 'Default',
|
|
107
127
|
descriptionParagraphs,
|
|
108
128
|
useVerticalExamples: useVerticalLayout,
|
|
109
129
|
controls: {
|
|
@@ -112,7 +132,10 @@ export function createColorThemeBookPages({ parent, title, theme, hideInverseCol
|
|
|
112
132
|
content: html `
|
|
113
133
|
<button
|
|
114
134
|
${listen('click', async () => {
|
|
115
|
-
const code = generateThemeCode(theme,
|
|
135
|
+
const code = generateThemeCode(theme, {
|
|
136
|
+
paletteVarName: 'viraColorPalette',
|
|
137
|
+
overrides,
|
|
138
|
+
});
|
|
116
139
|
await navigator.clipboard.writeText(code);
|
|
117
140
|
})}
|
|
118
141
|
>
|
|
@@ -120,9 +143,10 @@ export function createColorThemeBookPages({ parent, title, theme, hideInverseCol
|
|
|
120
143
|
</button>
|
|
121
144
|
`,
|
|
122
145
|
}),
|
|
146
|
+
...defaultThemeControls,
|
|
123
147
|
},
|
|
124
148
|
defineExamples({ defineExample }) {
|
|
125
|
-
createThemePageExamples(defineExample, theme);
|
|
149
|
+
createThemePageExamples(defineExample, theme, overrides);
|
|
126
150
|
},
|
|
127
151
|
});
|
|
128
152
|
const overridePages = (overrides || []).map((override) => {
|
|
@@ -132,7 +156,7 @@ export function createColorThemeBookPages({ parent, title, theme, hideInverseCol
|
|
|
132
156
|
useVerticalExamples: useVerticalLayout,
|
|
133
157
|
descriptionParagraphs,
|
|
134
158
|
defineExamples({ defineExample }) {
|
|
135
|
-
createThemePageExamples(defineExample, override.asTheme);
|
|
159
|
+
createThemePageExamples(defineExample, override.asTheme, undefined);
|
|
136
160
|
},
|
|
137
161
|
});
|
|
138
162
|
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type PartialWithUndefined } from '@augment-vir/common';
|
|
2
|
+
import { type ColorThemeOverride } from './color-theme-override.js';
|
|
3
|
+
import { type ColorTheme } from './color-theme.js';
|
|
4
|
+
/**
|
|
5
|
+
* Convert a color theme into code to define that color theme.
|
|
6
|
+
*
|
|
7
|
+
* @category Color Theme
|
|
8
|
+
*/
|
|
9
|
+
export declare function generateThemeCode(theme: ColorTheme, options?: Readonly<PartialWithUndefined<{
|
|
10
|
+
paletteVarName: string;
|
|
11
|
+
overrides: ReadonlyArray<Readonly<ColorThemeOverride>>;
|
|
12
|
+
}>>): string;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { getObjectTypedEntries, } from '@augment-vir/common';
|
|
2
|
+
/**
|
|
3
|
+
* Convert a color theme into code to define that color theme.
|
|
4
|
+
*
|
|
5
|
+
* @category Color Theme
|
|
6
|
+
*/
|
|
7
|
+
export function generateThemeCode(theme, options) {
|
|
8
|
+
const paletteVarName = options?.paletteVarName;
|
|
9
|
+
const defaultInitCode = colorInitToCode(theme.init.default, 1, undefined, paletteVarName);
|
|
10
|
+
const colorsInitCode = colorThemeInitToCode(theme.init.colors, 1, theme.init.default, paletteVarName);
|
|
11
|
+
const themeCode = `const theme = defineColorTheme(\n${defaultInitCode},\n${colorsInitCode},\n);`;
|
|
12
|
+
const overridesCodes = (options?.overrides || []).map((override) => {
|
|
13
|
+
return generateOverrideCode(override, paletteVarName);
|
|
14
|
+
});
|
|
15
|
+
return [
|
|
16
|
+
themeCode,
|
|
17
|
+
...overridesCodes,
|
|
18
|
+
].join('\n\n');
|
|
19
|
+
}
|
|
20
|
+
function generateOverrideCode(override, paletteVarName) {
|
|
21
|
+
const parts = [];
|
|
22
|
+
// Check if default colors differ
|
|
23
|
+
const defaultOverrideEntries = [];
|
|
24
|
+
if (!colorInitValuesEqual(override.asTheme.init.default.foreground, override.originalTheme.init.default.foreground)) {
|
|
25
|
+
defaultOverrideEntries.push(`${tab(3)}foreground: ${colorInitValueToCode(override.asTheme.init.default.foreground, 3, paletteVarName)},`);
|
|
26
|
+
}
|
|
27
|
+
if (!colorInitValuesEqual(override.asTheme.init.default.background, override.originalTheme.init.default.background)) {
|
|
28
|
+
defaultOverrideEntries.push(`${tab(3)}background: ${colorInitValueToCode(override.asTheme.init.default.background, 3, paletteVarName)},`);
|
|
29
|
+
}
|
|
30
|
+
if (defaultOverrideEntries.length > 0) {
|
|
31
|
+
parts.push(`${tab(2)}defaultOverride: {\n${defaultOverrideEntries.join('\n')}\n${tab(2)}},`);
|
|
32
|
+
}
|
|
33
|
+
// Check for color overrides
|
|
34
|
+
const colorOverrideEntries = [];
|
|
35
|
+
getObjectTypedEntries(override.asTheme.init.colors).forEach(([colorName, colorInit,]) => {
|
|
36
|
+
const originalColorInit = override.originalTheme.init.colors[colorName];
|
|
37
|
+
if (!originalColorInit) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const colorEntries = [];
|
|
41
|
+
if ('foreground' in colorInit &&
|
|
42
|
+
(!('foreground' in originalColorInit) ||
|
|
43
|
+
!colorInitValuesEqual(colorInit.foreground, originalColorInit.foreground))) {
|
|
44
|
+
colorEntries.push(`${tab(4)}foreground: ${colorInitValueToCode(colorInit.foreground, 4, paletteVarName)},`);
|
|
45
|
+
}
|
|
46
|
+
if ('background' in colorInit &&
|
|
47
|
+
(!('background' in originalColorInit) ||
|
|
48
|
+
!colorInitValuesEqual(colorInit.background, originalColorInit.background))) {
|
|
49
|
+
colorEntries.push(`${tab(4)}background: ${colorInitValueToCode(colorInit.background, 4, paletteVarName)},`);
|
|
50
|
+
}
|
|
51
|
+
if (colorEntries.length > 0) {
|
|
52
|
+
colorOverrideEntries.push(`${tab(3)}'${colorName}': {\n${colorEntries.join('\n')}\n${tab(3)}},`);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
if (colorOverrideEntries.length > 0) {
|
|
56
|
+
parts.push(`${tab(2)}colorOverrides: {\n${colorOverrideEntries.join('\n')}\n${tab(2)}},`);
|
|
57
|
+
}
|
|
58
|
+
return `const ${override.name}Override = defineColorThemeOverride(\n${tab(1)}theme,\n${tab(1)}'${override.name}',\n${tab(1)}{\n${parts.join('\n')}\n${tab(1)}},\n);`;
|
|
59
|
+
}
|
|
60
|
+
function tab(level) {
|
|
61
|
+
return ' '.repeat(level);
|
|
62
|
+
}
|
|
63
|
+
function colorInitValuesEqual(a, b) {
|
|
64
|
+
if (typeof a !== typeof b) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
if (typeof a === 'string' || typeof a === 'number') {
|
|
68
|
+
return a === b;
|
|
69
|
+
}
|
|
70
|
+
if ('_$cssResult$' in a && '_$cssResult$' in b) {
|
|
71
|
+
return a.cssText === b.cssText;
|
|
72
|
+
}
|
|
73
|
+
// For references and SingleCssVarDefinition, compare as JSON
|
|
74
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
75
|
+
}
|
|
76
|
+
function extractCssVarName(cssValue) {
|
|
77
|
+
const match = cssValue.match(/^var\(--([^,)]+)/);
|
|
78
|
+
return match ? match[1] : undefined;
|
|
79
|
+
}
|
|
80
|
+
function colorInitValueToCode(value, indentLevel, paletteVarName) {
|
|
81
|
+
if (typeof value === 'string') {
|
|
82
|
+
return `'${value}'`;
|
|
83
|
+
}
|
|
84
|
+
else if (typeof value === 'number') {
|
|
85
|
+
return String(value);
|
|
86
|
+
}
|
|
87
|
+
else if ('_$cssResult$' in value) {
|
|
88
|
+
const cssText = String(value);
|
|
89
|
+
if (paletteVarName) {
|
|
90
|
+
const varName = extractCssVarName(cssText);
|
|
91
|
+
if (varName) {
|
|
92
|
+
return `${paletteVarName}['${varName}']`;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return `css\`${cssText}\``;
|
|
96
|
+
}
|
|
97
|
+
else if ('refBackground' in value ||
|
|
98
|
+
'refForeground' in value ||
|
|
99
|
+
'refDefaultBackground' in value ||
|
|
100
|
+
'refDefaultForeground' in value) {
|
|
101
|
+
const entries = [];
|
|
102
|
+
if ('refForeground' in value) {
|
|
103
|
+
entries.push(`${tab(indentLevel + 1)}refForeground: '${value.refForeground}',`);
|
|
104
|
+
}
|
|
105
|
+
if ('refBackground' in value) {
|
|
106
|
+
entries.push(`${tab(indentLevel + 1)}refBackground: '${value.refBackground}',`);
|
|
107
|
+
}
|
|
108
|
+
if ('refDefaultForeground' in value) {
|
|
109
|
+
entries.push(`${tab(indentLevel + 1)}refDefaultForeground: true,`);
|
|
110
|
+
}
|
|
111
|
+
if ('refDefaultBackground' in value) {
|
|
112
|
+
entries.push(`${tab(indentLevel + 1)}refDefaultBackground: true,`);
|
|
113
|
+
}
|
|
114
|
+
return `{\n${entries.join('\n')}\n${tab(indentLevel)}}`;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
// SingleCssVarDefinition
|
|
118
|
+
return `'${value.default}'`;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function colorInitToCode(colorInit, indentLevel, defaultInit, paletteVarName) {
|
|
122
|
+
const entries = [];
|
|
123
|
+
if ('foreground' in colorInit &&
|
|
124
|
+
(!defaultInit || !colorInitValuesEqual(colorInit.foreground, defaultInit.foreground))) {
|
|
125
|
+
// Check if foreground matches default background (use refDefaultBackground)
|
|
126
|
+
if (defaultInit && colorInitValuesEqual(colorInit.foreground, defaultInit.background)) {
|
|
127
|
+
entries.push(`${tab(indentLevel + 1)}foreground: {\n${tab(indentLevel + 2)}refDefaultBackground: true,\n${tab(indentLevel + 1)}},`);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
entries.push(`${tab(indentLevel + 1)}foreground: ${colorInitValueToCode(colorInit.foreground, indentLevel + 1, paletteVarName)},`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if ('background' in colorInit &&
|
|
134
|
+
(!defaultInit || !colorInitValuesEqual(colorInit.background, defaultInit.background))) {
|
|
135
|
+
// Check if background matches default foreground (use refDefaultForeground)
|
|
136
|
+
if (defaultInit && colorInitValuesEqual(colorInit.background, defaultInit.foreground)) {
|
|
137
|
+
entries.push(`${tab(indentLevel + 1)}background: {\n${tab(indentLevel + 2)}refDefaultForeground: true,\n${tab(indentLevel + 1)}},`);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
entries.push(`${tab(indentLevel + 1)}background: ${colorInitValueToCode(colorInit.background, indentLevel + 1, paletteVarName)},`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return `${tab(indentLevel)}{\n${entries.join('\n')}\n${tab(indentLevel)}}`;
|
|
144
|
+
}
|
|
145
|
+
function colorThemeInitToCode(colorsInit, indentLevel, defaultInit, paletteVarName) {
|
|
146
|
+
const entries = getObjectTypedEntries(colorsInit).map(([colorName, colorInit,]) => {
|
|
147
|
+
return `${tab(indentLevel + 1)}'${colorName}': ${colorInitToCode(colorInit, indentLevel + 1, defaultInit, paletteVarName).trimStart()},`;
|
|
148
|
+
});
|
|
149
|
+
return `${tab(indentLevel)}{\n${entries.join('\n')}\n${tab(indentLevel)}}`;
|
|
150
|
+
}
|
|
@@ -103,9 +103,3 @@ export declare const themeDefaultKey = "theme-default";
|
|
|
103
103
|
* @category Color Theme
|
|
104
104
|
*/
|
|
105
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;
|
|
@@ -175,104 +175,3 @@ function createCssVarNames(colorName) {
|
|
|
175
175
|
].join('-'),
|
|
176
176
|
};
|
|
177
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/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export * from './color/build-color-theme.js';
|
|
2
|
-
export * from './color/color-css.js';
|
|
3
|
-
export * from './color/color-palette-book-pages.js';
|
|
4
|
-
export * from './color/color-theme-book-pages.js';
|
|
5
|
-
export * from './color/color-theme-
|
|
6
|
-
export * from './color/color-theme.js';
|
|
1
|
+
export * from './color-theme/build-color-theme.js';
|
|
2
|
+
export * from './color-theme/color-css.js';
|
|
3
|
+
export * from './color-theme/color-palette-book-pages.js';
|
|
4
|
+
export * from './color-theme/color-theme-book-pages.js';
|
|
5
|
+
export * from './color-theme/color-theme-code.js';
|
|
6
|
+
export * from './color-theme/color-theme-override.js';
|
|
7
|
+
export * from './color-theme/color-theme.js';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export * from './color/build-color-theme.js';
|
|
2
|
-
export * from './color/color-css.js';
|
|
3
|
-
export * from './color/color-palette-book-pages.js';
|
|
4
|
-
export * from './color/color-theme-book-pages.js';
|
|
5
|
-
export * from './color/color-theme-
|
|
6
|
-
export * from './color/color-theme.js';
|
|
1
|
+
export * from './color-theme/build-color-theme.js';
|
|
2
|
+
export * from './color-theme/color-css.js';
|
|
3
|
+
export * from './color-theme/color-palette-book-pages.js';
|
|
4
|
+
export * from './color-theme/color-theme-book-pages.js';
|
|
5
|
+
export * from './color-theme/color-theme-code.js';
|
|
6
|
+
export * from './color-theme/color-theme-override.js';
|
|
7
|
+
export * from './color-theme/color-theme.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "theme-vir",
|
|
3
|
-
"version": "28.
|
|
3
|
+
"version": "28.17.0",
|
|
4
4
|
"description": "Create an entire web theme.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"design",
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
"start": "virmator frontend",
|
|
40
40
|
"test": "virmator test web",
|
|
41
41
|
"test:coverage": "npm run test coverage",
|
|
42
|
-
"test:docs": "virmator docs check"
|
|
42
|
+
"test:docs": "virmator docs check",
|
|
43
|
+
"test:update": "virmator test web update"
|
|
43
44
|
},
|
|
44
45
|
"dependencies": {
|
|
45
46
|
"@augment-vir/assert": "^31.57.5",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|