material-theme-builder 2.1.1 → 2.2.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 +19 -4
- package/dist/cli.js +784 -446
- package/dist/index.d.ts +78 -104
- package/dist/index.js +763 -566
- package/dist/react.d.ts +195 -0
- package/dist/react.js +4604 -0
- package/dist/tailwind.css +0 -2
- package/package.json +22 -4
- package/src/tailwind.css +0 -2
package/dist/index.js
CHANGED
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
1
|
// src/lib/builder.ts
|
|
4
2
|
import {
|
|
5
|
-
argbFromHex,
|
|
3
|
+
argbFromHex as argbFromHex2,
|
|
6
4
|
Blend,
|
|
7
|
-
blueFromArgb,
|
|
8
5
|
DynamicColor,
|
|
9
|
-
DynamicScheme,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
hexFromArgb,
|
|
13
|
-
MaterialDynamicColors,
|
|
14
|
-
redFromArgb,
|
|
6
|
+
DynamicScheme as DynamicScheme2,
|
|
7
|
+
Hct as Hct2,
|
|
8
|
+
MaterialDynamicColors as MaterialDynamicColors2,
|
|
15
9
|
SchemeContent,
|
|
16
10
|
SchemeExpressive,
|
|
17
11
|
SchemeFidelity,
|
|
@@ -19,9 +13,682 @@ import {
|
|
|
19
13
|
SchemeNeutral,
|
|
20
14
|
SchemeTonalSpot,
|
|
21
15
|
SchemeVibrant,
|
|
16
|
+
TonalPalette as TonalPalette2
|
|
17
|
+
} from "@material/material-color-utilities";
|
|
18
|
+
import { kebabCase as kebabCase4, upperFirst as upperFirst2 } from "lodash-es";
|
|
19
|
+
|
|
20
|
+
// src/lib/builder.css.ts
|
|
21
|
+
import {
|
|
22
|
+
hexFromArgb
|
|
23
|
+
} from "@material/material-color-utilities";
|
|
24
|
+
import { kebabCase } from "lodash-es";
|
|
25
|
+
function buildCss(ctx) {
|
|
26
|
+
const {
|
|
27
|
+
prefix,
|
|
28
|
+
allPalettes,
|
|
29
|
+
mergedColorsLight,
|
|
30
|
+
mergedColorsDark,
|
|
31
|
+
tokenToPalette,
|
|
32
|
+
allPaletteNamesKebab
|
|
33
|
+
} = ctx;
|
|
34
|
+
function buildRefPaletteLookup() {
|
|
35
|
+
const lookup = {};
|
|
36
|
+
for (const [name, palette] of Object.entries(allPalettes)) {
|
|
37
|
+
const paletteName = kebabCase(name);
|
|
38
|
+
for (const tone of STANDARD_TONES) {
|
|
39
|
+
const hex = hexFromArgb(palette.tone(tone));
|
|
40
|
+
if (!lookup[hex]) lookup[hex] = [];
|
|
41
|
+
lookup[hex].push({ paletteName, tone });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return lookup;
|
|
45
|
+
}
|
|
46
|
+
function sysColorVar(colorName, colorValue, lookup) {
|
|
47
|
+
const name = `--${prefix}-sys-color-${kebabCase(colorName)}`;
|
|
48
|
+
const hex = hexFromArgb(colorValue);
|
|
49
|
+
const matches = lookup[hex];
|
|
50
|
+
if (matches && matches.length > 0) {
|
|
51
|
+
const preferred = tokenToPalette[colorName] ?? deriveCustomPaletteName(colorName, allPaletteNamesKebab);
|
|
52
|
+
const match = (preferred ? matches.find((m) => m.paletteName === preferred) : void 0) ?? matches[0];
|
|
53
|
+
if (match) {
|
|
54
|
+
return `${name}:var(--${prefix}-ref-palette-${match.paletteName}-${match.tone});`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return `${name}:${hex};`;
|
|
58
|
+
}
|
|
59
|
+
function toCssVars(mergedColors, lookup) {
|
|
60
|
+
return Object.entries(mergedColors).map(([name, value]) => sysColorVar(name, value, lookup)).join(" ");
|
|
61
|
+
}
|
|
62
|
+
function refPaletteVar(paletteName, tone, colorValue) {
|
|
63
|
+
const name = `--${prefix}-ref-palette-${paletteName}-${tone}`;
|
|
64
|
+
const value = hexFromArgb(colorValue);
|
|
65
|
+
return `${name}:${value};`;
|
|
66
|
+
}
|
|
67
|
+
function generateTonalPaletteVars(paletteName, palette) {
|
|
68
|
+
return STANDARD_TONES.map((tone) => {
|
|
69
|
+
const color = palette.tone(tone);
|
|
70
|
+
return refPaletteVar(paletteName, tone, color);
|
|
71
|
+
}).join(" ");
|
|
72
|
+
}
|
|
73
|
+
function generateTonalVars() {
|
|
74
|
+
return Object.entries(allPalettes).map(
|
|
75
|
+
([name, palette]) => generateTonalPaletteVars(kebabCase(name), palette)
|
|
76
|
+
).join(" ");
|
|
77
|
+
}
|
|
78
|
+
const refPaletteLookup = buildRefPaletteLookup();
|
|
79
|
+
const lightVars = toCssVars(mergedColorsLight, refPaletteLookup);
|
|
80
|
+
const darkVars = toCssVars(mergedColorsDark, refPaletteLookup);
|
|
81
|
+
const tonalVars = generateTonalVars();
|
|
82
|
+
return `
|
|
83
|
+
:root { ${lightVars} ${tonalVars} }
|
|
84
|
+
.dark { ${darkVars} ${tonalVars} }
|
|
85
|
+
`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/lib/builder.figma.ts
|
|
89
|
+
import {
|
|
90
|
+
blueFromArgb,
|
|
91
|
+
greenFromArgb,
|
|
92
|
+
hexFromArgb as hexFromArgb2,
|
|
93
|
+
redFromArgb
|
|
94
|
+
} from "@material/material-color-utilities";
|
|
95
|
+
import { kebabCase as kebabCase2, startCase } from "lodash-es";
|
|
96
|
+
function buildFigmaVariables(ctx) {
|
|
97
|
+
const {
|
|
98
|
+
allPalettes,
|
|
99
|
+
mergedColorsLight,
|
|
100
|
+
mergedColorsDark,
|
|
101
|
+
tokenToPalette,
|
|
102
|
+
allPaletteNamesKebab
|
|
103
|
+
} = ctx;
|
|
104
|
+
const variables = [];
|
|
105
|
+
const paletteHexMap = {};
|
|
106
|
+
for (const [name, palette] of Object.entries(allPalettes)) {
|
|
107
|
+
const paletteName = startCase(name);
|
|
108
|
+
paletteHexMap[paletteName] = {};
|
|
109
|
+
for (const tone of STANDARD_TONES) {
|
|
110
|
+
const argb = palette.tone(tone);
|
|
111
|
+
const path = `ref/palette/${paletteName}/${tone}`;
|
|
112
|
+
const hex = hexFromArgb2(argb).toUpperCase();
|
|
113
|
+
paletteHexMap[paletteName][hex] = path;
|
|
114
|
+
const color = {
|
|
115
|
+
r: redFromArgb(argb) / 255,
|
|
116
|
+
g: greenFromArgb(argb) / 255,
|
|
117
|
+
b: blueFromArgb(argb) / 255,
|
|
118
|
+
a: 1
|
|
119
|
+
};
|
|
120
|
+
variables.push({
|
|
121
|
+
path,
|
|
122
|
+
scopes: ["ALL_SCOPES"],
|
|
123
|
+
values: { Light: color, Dark: color }
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function findAlias(hex, tokenName) {
|
|
128
|
+
const preferredKebab = tokenToPalette[tokenName] ?? deriveCustomPaletteName(tokenName, allPaletteNamesKebab);
|
|
129
|
+
const preferred = preferredKebab ? startCase(preferredKebab) : void 0;
|
|
130
|
+
if (preferred && paletteHexMap[preferred]?.[hex]) {
|
|
131
|
+
return paletteHexMap[preferred][hex];
|
|
132
|
+
}
|
|
133
|
+
for (const palHexes of Object.values(paletteHexMap)) {
|
|
134
|
+
if (palHexes[hex]) return palHexes[hex];
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
function resolveValue(argb, tokenName) {
|
|
139
|
+
const hex = hexFromArgb2(argb).toUpperCase();
|
|
140
|
+
const aliasPath = findAlias(hex, tokenName);
|
|
141
|
+
if (aliasPath) return { alias: aliasPath };
|
|
142
|
+
return {
|
|
143
|
+
r: redFromArgb(argb) / 255,
|
|
144
|
+
g: greenFromArgb(argb) / 255,
|
|
145
|
+
b: blueFromArgb(argb) / 255,
|
|
146
|
+
a: 1
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
for (const [name, lightArgb] of Object.entries(mergedColorsLight)) {
|
|
150
|
+
const darkArgb = mergedColorsDark[name] ?? lightArgb;
|
|
151
|
+
const description = isTokenName(name) ? tokenDescriptions[name] : void 0;
|
|
152
|
+
variables.push({
|
|
153
|
+
path: `sys/color/${startCase(name)}`,
|
|
154
|
+
...description ? { description } : {},
|
|
155
|
+
scopes: ["ALL_SCOPES"],
|
|
156
|
+
values: {
|
|
157
|
+
Light: resolveValue(lightArgb, name),
|
|
158
|
+
Dark: resolveValue(darkArgb, name)
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return variables;
|
|
163
|
+
}
|
|
164
|
+
function buildFigmaTokens(ctx) {
|
|
165
|
+
const { prefix } = ctx;
|
|
166
|
+
const variables = buildFigmaVariables(ctx);
|
|
167
|
+
function rgbToHex(r, g, b) {
|
|
168
|
+
const toHex = (c) => Math.round(c * 255).toString(16).padStart(2, "0");
|
|
169
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}`.toUpperCase();
|
|
170
|
+
}
|
|
171
|
+
function toDtcgValue(modeValue) {
|
|
172
|
+
if ("alias" in modeValue) {
|
|
173
|
+
return `{${modeValue.alias.replaceAll("/", ".")}}`;
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
colorSpace: "srgb",
|
|
177
|
+
components: [modeValue.r, modeValue.g, modeValue.b],
|
|
178
|
+
alpha: modeValue.a,
|
|
179
|
+
hex: rgbToHex(modeValue.r, modeValue.g, modeValue.b)
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
function toDtcgExtensions(v) {
|
|
183
|
+
if (v.path.startsWith("ref/palette/")) {
|
|
184
|
+
return {
|
|
185
|
+
"com.figma.scopes": v.scopes ?? ["ALL_SCOPES"],
|
|
186
|
+
"com.figma.isOverride": true
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
const lastSegment = v.path.split("/").at(-1);
|
|
190
|
+
if (!lastSegment) return { "com.figma.scopes": v.scopes ?? ["ALL_SCOPES"] };
|
|
191
|
+
const tokenName = kebabCase2(lastSegment);
|
|
192
|
+
return {
|
|
193
|
+
"com.figma.scopes": v.scopes ?? ["ALL_SCOPES"],
|
|
194
|
+
"css.variable": `--${prefix}-sys-color-${tokenName}`
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
function buildToken(v, modeValue) {
|
|
198
|
+
return {
|
|
199
|
+
$type: "color",
|
|
200
|
+
$value: toDtcgValue(modeValue),
|
|
201
|
+
...v.description ? { $description: v.description } : {},
|
|
202
|
+
$extensions: toDtcgExtensions(v)
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function parsePath(path) {
|
|
206
|
+
const parts = path.split("/");
|
|
207
|
+
if (parts[0] === "ref" && parts[1] === "palette" && parts[2] && parts[3]) {
|
|
208
|
+
return {
|
|
209
|
+
kind: "palette",
|
|
210
|
+
paletteName: parts[2],
|
|
211
|
+
tone: parts[3]
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
if (parts[0] === "sys" && parts[1] === "color" && parts[2]) {
|
|
215
|
+
return { kind: "color", tokenName: parts[2] };
|
|
216
|
+
}
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
function buildModeFile(modeName) {
|
|
220
|
+
const palette = {};
|
|
221
|
+
const color = {};
|
|
222
|
+
for (const v of variables) {
|
|
223
|
+
const modeValue = v.values[modeName];
|
|
224
|
+
if (!modeValue) continue;
|
|
225
|
+
const parsed = parsePath(v.path);
|
|
226
|
+
if (!parsed) continue;
|
|
227
|
+
if (parsed.kind === "palette") {
|
|
228
|
+
const group = palette[parsed.paletteName] ??= {};
|
|
229
|
+
group[parsed.tone] = buildToken(v, modeValue);
|
|
230
|
+
} else {
|
|
231
|
+
color[parsed.tokenName] = buildToken(v, modeValue);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return {
|
|
235
|
+
$extensions: { "com.figma.modeName": modeName },
|
|
236
|
+
ref: { palette },
|
|
237
|
+
sys: { color }
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
"Light.tokens.json": buildModeFile("Light"),
|
|
242
|
+
"Dark.tokens.json": buildModeFile("Dark")
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// src/lib/builder.flutter.ts
|
|
247
|
+
import { hexFromArgb as hexFromArgb3 } from "@material/material-color-utilities";
|
|
248
|
+
import { upperFirst } from "lodash-es";
|
|
249
|
+
var FLUTTER_PROPERTIES = [
|
|
250
|
+
"primary",
|
|
251
|
+
"surfaceTint",
|
|
252
|
+
"onPrimary",
|
|
253
|
+
"primaryContainer",
|
|
254
|
+
"onPrimaryContainer",
|
|
255
|
+
"secondary",
|
|
256
|
+
"onSecondary",
|
|
257
|
+
"secondaryContainer",
|
|
258
|
+
"onSecondaryContainer",
|
|
259
|
+
"tertiary",
|
|
260
|
+
"onTertiary",
|
|
261
|
+
"tertiaryContainer",
|
|
262
|
+
"onTertiaryContainer",
|
|
263
|
+
"error",
|
|
264
|
+
"onError",
|
|
265
|
+
"errorContainer",
|
|
266
|
+
"onErrorContainer",
|
|
267
|
+
"background",
|
|
268
|
+
"onBackground",
|
|
269
|
+
"surface",
|
|
270
|
+
"onSurface",
|
|
271
|
+
"surfaceVariant",
|
|
272
|
+
"onSurfaceVariant",
|
|
273
|
+
"outline",
|
|
274
|
+
"outlineVariant",
|
|
275
|
+
"shadow",
|
|
276
|
+
"scrim",
|
|
277
|
+
"inverseSurface",
|
|
278
|
+
"inverseOnSurface",
|
|
279
|
+
"inversePrimary",
|
|
280
|
+
"primaryFixed",
|
|
281
|
+
"onPrimaryFixed",
|
|
282
|
+
"primaryFixedDim",
|
|
283
|
+
"onPrimaryFixedVariant",
|
|
284
|
+
"secondaryFixed",
|
|
285
|
+
"onSecondaryFixed",
|
|
286
|
+
"secondaryFixedDim",
|
|
287
|
+
"onSecondaryFixedVariant",
|
|
288
|
+
"tertiaryFixed",
|
|
289
|
+
"onTertiaryFixed",
|
|
290
|
+
"tertiaryFixedDim",
|
|
291
|
+
"onTertiaryFixedVariant",
|
|
292
|
+
"surfaceDim",
|
|
293
|
+
"surfaceBright",
|
|
294
|
+
"surfaceContainerLowest",
|
|
295
|
+
"surfaceContainerLow",
|
|
296
|
+
"surfaceContainer",
|
|
297
|
+
"surfaceContainerHigh",
|
|
298
|
+
"surfaceContainerHighest"
|
|
299
|
+
];
|
|
300
|
+
var TOKEN_TO_FLUTTER = {
|
|
301
|
+
inverseOnSurface: "onInverseSurface"
|
|
302
|
+
};
|
|
303
|
+
function toFlutterColor(argb) {
|
|
304
|
+
const hex = hexFromArgb3(argb).replace("#", "").toUpperCase();
|
|
305
|
+
return `Color(0xFF${hex})`;
|
|
306
|
+
}
|
|
307
|
+
function flutterPropName(m3Token) {
|
|
308
|
+
return TOKEN_TO_FLUTTER[m3Token] ?? m3Token;
|
|
309
|
+
}
|
|
310
|
+
function buildFlutter(ctx) {
|
|
311
|
+
const { mergedColorsLight, mergedColorsDark, hexCustomColors } = ctx;
|
|
312
|
+
function buildColorScheme(name, brightness, colors) {
|
|
313
|
+
const lines = [];
|
|
314
|
+
lines.push(`const ${name} = ColorScheme(`);
|
|
315
|
+
lines.push(` brightness: Brightness.${brightness},`);
|
|
316
|
+
for (const token of FLUTTER_PROPERTIES) {
|
|
317
|
+
const argb = colors[token];
|
|
318
|
+
if (argb === void 0) continue;
|
|
319
|
+
lines.push(` ${flutterPropName(token)}: ${toFlutterColor(argb)},`);
|
|
320
|
+
}
|
|
321
|
+
lines.push(");");
|
|
322
|
+
return lines.join("\n");
|
|
323
|
+
}
|
|
324
|
+
function buildCustomColors() {
|
|
325
|
+
if (hexCustomColors.length === 0) return "";
|
|
326
|
+
const sections = [];
|
|
327
|
+
for (const cc of hexCustomColors) {
|
|
328
|
+
const ccName = cc.name;
|
|
329
|
+
const tokens = [
|
|
330
|
+
ccName,
|
|
331
|
+
`on${upperFirst(ccName)}`,
|
|
332
|
+
`${ccName}Container`,
|
|
333
|
+
`on${upperFirst(ccName)}Container`
|
|
334
|
+
];
|
|
335
|
+
const lightLines = [];
|
|
336
|
+
const darkLines = [];
|
|
337
|
+
for (const token of tokens) {
|
|
338
|
+
const lightArgb = mergedColorsLight[token];
|
|
339
|
+
const darkArgb = mergedColorsDark[token];
|
|
340
|
+
if (lightArgb !== void 0) {
|
|
341
|
+
lightLines.push(
|
|
342
|
+
`const light${upperFirst(token)} = ${toFlutterColor(lightArgb)};`
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
if (darkArgb !== void 0) {
|
|
346
|
+
darkLines.push(
|
|
347
|
+
`const dark${upperFirst(token)} = ${toFlutterColor(darkArgb)};`
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
sections.push([...lightLines, ...darkLines].join("\n"));
|
|
352
|
+
}
|
|
353
|
+
return "\n\n" + sections.join("\n\n");
|
|
354
|
+
}
|
|
355
|
+
const header = "import 'package:flutter/material.dart';";
|
|
356
|
+
const light = buildColorScheme(
|
|
357
|
+
"lightColorScheme",
|
|
358
|
+
"light",
|
|
359
|
+
mergedColorsLight
|
|
360
|
+
);
|
|
361
|
+
const dark = buildColorScheme("darkColorScheme", "dark", mergedColorsDark);
|
|
362
|
+
const custom = buildCustomColors();
|
|
363
|
+
return `${header}
|
|
364
|
+
|
|
365
|
+
${light}
|
|
366
|
+
|
|
367
|
+
${dark}${custom}
|
|
368
|
+
`;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// src/lib/builder.json.ts
|
|
372
|
+
import {
|
|
373
|
+
argbFromHex,
|
|
374
|
+
DynamicScheme,
|
|
375
|
+
Hct,
|
|
376
|
+
hexFromArgb as hexFromArgb4,
|
|
377
|
+
MaterialDynamicColors,
|
|
22
378
|
TonalPalette
|
|
23
379
|
} from "@material/material-color-utilities";
|
|
24
|
-
|
|
380
|
+
var MTB_TONES = [
|
|
381
|
+
0,
|
|
382
|
+
5,
|
|
383
|
+
10,
|
|
384
|
+
15,
|
|
385
|
+
20,
|
|
386
|
+
25,
|
|
387
|
+
30,
|
|
388
|
+
35,
|
|
389
|
+
40,
|
|
390
|
+
50,
|
|
391
|
+
60,
|
|
392
|
+
70,
|
|
393
|
+
80,
|
|
394
|
+
90,
|
|
395
|
+
95,
|
|
396
|
+
98,
|
|
397
|
+
99,
|
|
398
|
+
100
|
|
399
|
+
];
|
|
400
|
+
var FIXTURE_TOKEN_ORDER = [
|
|
401
|
+
"primary",
|
|
402
|
+
"surfaceTint",
|
|
403
|
+
"onPrimary",
|
|
404
|
+
"primaryContainer",
|
|
405
|
+
"onPrimaryContainer",
|
|
406
|
+
"secondary",
|
|
407
|
+
"onSecondary",
|
|
408
|
+
"secondaryContainer",
|
|
409
|
+
"onSecondaryContainer",
|
|
410
|
+
"tertiary",
|
|
411
|
+
"onTertiary",
|
|
412
|
+
"tertiaryContainer",
|
|
413
|
+
"onTertiaryContainer",
|
|
414
|
+
"error",
|
|
415
|
+
"onError",
|
|
416
|
+
"errorContainer",
|
|
417
|
+
"onErrorContainer",
|
|
418
|
+
"background",
|
|
419
|
+
"onBackground",
|
|
420
|
+
"surface",
|
|
421
|
+
"onSurface",
|
|
422
|
+
"surfaceVariant",
|
|
423
|
+
"onSurfaceVariant",
|
|
424
|
+
"outline",
|
|
425
|
+
"outlineVariant",
|
|
426
|
+
"shadow",
|
|
427
|
+
"scrim",
|
|
428
|
+
"inverseSurface",
|
|
429
|
+
"inverseOnSurface",
|
|
430
|
+
"inversePrimary",
|
|
431
|
+
"primaryFixed",
|
|
432
|
+
"onPrimaryFixed",
|
|
433
|
+
"primaryFixedDim",
|
|
434
|
+
"onPrimaryFixedVariant",
|
|
435
|
+
"secondaryFixed",
|
|
436
|
+
"onSecondaryFixed",
|
|
437
|
+
"secondaryFixedDim",
|
|
438
|
+
"onSecondaryFixedVariant",
|
|
439
|
+
"tertiaryFixed",
|
|
440
|
+
"onTertiaryFixed",
|
|
441
|
+
"tertiaryFixedDim",
|
|
442
|
+
"onTertiaryFixedVariant",
|
|
443
|
+
"surfaceDim",
|
|
444
|
+
"surfaceBright",
|
|
445
|
+
"surfaceContainerLowest",
|
|
446
|
+
"surfaceContainerLow",
|
|
447
|
+
"surfaceContainer",
|
|
448
|
+
"surfaceContainerHigh",
|
|
449
|
+
"surfaceContainerHighest"
|
|
450
|
+
];
|
|
451
|
+
function buildJson(ctx) {
|
|
452
|
+
const {
|
|
453
|
+
hexSource,
|
|
454
|
+
sourceHct,
|
|
455
|
+
effectiveSourceArgb,
|
|
456
|
+
primaryHct,
|
|
457
|
+
SchemeClass,
|
|
458
|
+
scheme,
|
|
459
|
+
primary,
|
|
460
|
+
secondary,
|
|
461
|
+
tertiary,
|
|
462
|
+
error,
|
|
463
|
+
neutral,
|
|
464
|
+
neutralVariant,
|
|
465
|
+
hexCustomColors
|
|
466
|
+
} = ctx;
|
|
467
|
+
const neuHct = neutral ? Hct.fromInt(argbFromHex(neutral)) : sourceHct;
|
|
468
|
+
const nvHct = neutralVariant ? Hct.fromInt(argbFromHex(neutralVariant)) : sourceHct;
|
|
469
|
+
const rawPalettes = {
|
|
470
|
+
primary: TonalPalette.fromInt(effectiveSourceArgb),
|
|
471
|
+
secondary: secondary ? TonalPalette.fromInt(argbFromHex(secondary)) : TonalPalette.fromHueAndChroma(sourceHct.hue, sourceHct.chroma / 3),
|
|
472
|
+
tertiary: tertiary ? TonalPalette.fromInt(argbFromHex(tertiary)) : TonalPalette.fromHueAndChroma(
|
|
473
|
+
(sourceHct.hue + 60) % 360,
|
|
474
|
+
sourceHct.chroma / 2
|
|
475
|
+
),
|
|
476
|
+
neutral: TonalPalette.fromHueAndChroma(
|
|
477
|
+
neuHct.hue,
|
|
478
|
+
Math.min(neuHct.chroma / 12, 4)
|
|
479
|
+
),
|
|
480
|
+
"neutral-variant": TonalPalette.fromHueAndChroma(
|
|
481
|
+
nvHct.hue,
|
|
482
|
+
Math.min(nvHct.chroma / 6, 8)
|
|
483
|
+
)
|
|
484
|
+
};
|
|
485
|
+
function buildJsonSchemes() {
|
|
486
|
+
function extractSchemeColors(scheme2, backgroundScheme) {
|
|
487
|
+
const colors = {};
|
|
488
|
+
for (const tokenName of FIXTURE_TOKEN_ORDER) {
|
|
489
|
+
const dynamicColor = MaterialDynamicColors[tokenName];
|
|
490
|
+
const useScheme = backgroundScheme && (tokenName === "background" || tokenName === "onBackground") ? backgroundScheme : scheme2;
|
|
491
|
+
colors[tokenName] = hexFromArgb4(
|
|
492
|
+
dynamicColor.getArgb(useScheme)
|
|
493
|
+
).toUpperCase();
|
|
494
|
+
}
|
|
495
|
+
return colors;
|
|
496
|
+
}
|
|
497
|
+
function resolveOverridePalette(hex, role) {
|
|
498
|
+
if (!hex) return null;
|
|
499
|
+
return new SchemeClass(Hct.fromInt(argbFromHex(hex)), false, 0)[role];
|
|
500
|
+
}
|
|
501
|
+
const secPalette = resolveOverridePalette(secondary, "primaryPalette");
|
|
502
|
+
const terPalette = resolveOverridePalette(tertiary, "primaryPalette");
|
|
503
|
+
const errPalette = resolveOverridePalette(error, "primaryPalette");
|
|
504
|
+
const neuPalette = resolveOverridePalette(neutral, "neutralPalette");
|
|
505
|
+
const nvPalette = resolveOverridePalette(
|
|
506
|
+
neutralVariant,
|
|
507
|
+
"neutralVariantPalette"
|
|
508
|
+
);
|
|
509
|
+
const jsonSchemes = {};
|
|
510
|
+
const jsonContrastLevels = [
|
|
511
|
+
{ name: "light", isDark: false, contrast: 0 },
|
|
512
|
+
{ name: "light-medium-contrast", isDark: false, contrast: 0.5 },
|
|
513
|
+
{ name: "light-high-contrast", isDark: false, contrast: 1 },
|
|
514
|
+
{ name: "dark", isDark: true, contrast: 0 },
|
|
515
|
+
{ name: "dark-medium-contrast", isDark: true, contrast: 0.5 },
|
|
516
|
+
{ name: "dark-high-contrast", isDark: true, contrast: 1 }
|
|
517
|
+
];
|
|
518
|
+
for (const { name, isDark, contrast } of jsonContrastLevels) {
|
|
519
|
+
const baseScheme = new SchemeClass(primaryHct, isDark, contrast);
|
|
520
|
+
const composedScheme = new DynamicScheme({
|
|
521
|
+
sourceColorArgb: effectiveSourceArgb,
|
|
522
|
+
variant: schemeToVariant[scheme],
|
|
523
|
+
contrastLevel: contrast,
|
|
524
|
+
isDark,
|
|
525
|
+
primaryPalette: baseScheme.primaryPalette,
|
|
526
|
+
secondaryPalette: secPalette || baseScheme.secondaryPalette,
|
|
527
|
+
tertiaryPalette: terPalette || baseScheme.tertiaryPalette,
|
|
528
|
+
neutralPalette: neuPalette || baseScheme.neutralPalette,
|
|
529
|
+
neutralVariantPalette: nvPalette || baseScheme.neutralVariantPalette
|
|
530
|
+
});
|
|
531
|
+
if (errPalette) composedScheme.errorPalette = errPalette;
|
|
532
|
+
jsonSchemes[name] = extractSchemeColors(composedScheme, baseScheme);
|
|
533
|
+
}
|
|
534
|
+
return jsonSchemes;
|
|
535
|
+
}
|
|
536
|
+
function rawPalettesToJson() {
|
|
537
|
+
const jsonPalettes = {};
|
|
538
|
+
const RAW_PALETTE_NAMES = [
|
|
539
|
+
"primary",
|
|
540
|
+
"secondary",
|
|
541
|
+
"tertiary",
|
|
542
|
+
"neutral",
|
|
543
|
+
"neutral-variant"
|
|
544
|
+
];
|
|
545
|
+
for (const name of RAW_PALETTE_NAMES) {
|
|
546
|
+
const palette = rawPalettes[name];
|
|
547
|
+
const tones = {};
|
|
548
|
+
for (const tone of MTB_TONES) {
|
|
549
|
+
tones[tone.toString()] = hexFromArgb4(palette.tone(tone)).toUpperCase();
|
|
550
|
+
}
|
|
551
|
+
jsonPalettes[name] = tones;
|
|
552
|
+
}
|
|
553
|
+
return jsonPalettes;
|
|
554
|
+
}
|
|
555
|
+
function buildCoreColors(opts) {
|
|
556
|
+
const colors = { primary: opts.primary };
|
|
557
|
+
if (opts.secondary) colors.secondary = opts.secondary.toUpperCase();
|
|
558
|
+
if (opts.tertiary) colors.tertiary = opts.tertiary.toUpperCase();
|
|
559
|
+
if (opts.error) colors.error = opts.error.toUpperCase();
|
|
560
|
+
if (opts.neutral) colors.neutral = opts.neutral.toUpperCase();
|
|
561
|
+
if (opts.neutralVariant)
|
|
562
|
+
colors.neutralVariant = opts.neutralVariant.toUpperCase();
|
|
563
|
+
return colors;
|
|
564
|
+
}
|
|
565
|
+
const seed = hexSource.toUpperCase();
|
|
566
|
+
const coreColors = buildCoreColors({
|
|
567
|
+
primary: (primary || hexSource).toUpperCase(),
|
|
568
|
+
secondary,
|
|
569
|
+
tertiary,
|
|
570
|
+
error,
|
|
571
|
+
neutral,
|
|
572
|
+
neutralVariant
|
|
573
|
+
});
|
|
574
|
+
const extendedColors = hexCustomColors.map((c) => ({
|
|
575
|
+
name: c.name,
|
|
576
|
+
color: c.hex.toUpperCase(),
|
|
577
|
+
description: "",
|
|
578
|
+
harmonized: c.blend ?? DEFAULT_BLEND
|
|
579
|
+
}));
|
|
580
|
+
return {
|
|
581
|
+
seed,
|
|
582
|
+
coreColors,
|
|
583
|
+
extendedColors,
|
|
584
|
+
schemes: buildJsonSchemes(),
|
|
585
|
+
palettes: rawPalettesToJson()
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// src/lib/builder.tailwind.ts
|
|
590
|
+
import { kebabCase as kebabCase3 } from "lodash-es";
|
|
591
|
+
var SHADE_TO_TONE = [
|
|
592
|
+
[50, 95],
|
|
593
|
+
[100, 90],
|
|
594
|
+
[200, 80],
|
|
595
|
+
[300, 70],
|
|
596
|
+
[400, 60],
|
|
597
|
+
[500, 50],
|
|
598
|
+
[600, 40],
|
|
599
|
+
[700, 30],
|
|
600
|
+
[800, 20],
|
|
601
|
+
[900, 10],
|
|
602
|
+
[950, 5]
|
|
603
|
+
];
|
|
604
|
+
var CORE_PALETTES = [
|
|
605
|
+
"primary",
|
|
606
|
+
"secondary",
|
|
607
|
+
"tertiary",
|
|
608
|
+
"error",
|
|
609
|
+
"neutral",
|
|
610
|
+
"neutral-variant"
|
|
611
|
+
];
|
|
612
|
+
var SHADCN_MAPPING = [
|
|
613
|
+
["--background", "surface"],
|
|
614
|
+
["--foreground", "on-surface"],
|
|
615
|
+
["--card", "surface-container-low"],
|
|
616
|
+
["--card-foreground", "on-surface"],
|
|
617
|
+
["--popover", "surface-container-high"],
|
|
618
|
+
["--popover-foreground", "on-surface"],
|
|
619
|
+
["--primary", "primary"],
|
|
620
|
+
["--primary-foreground", "on-primary"],
|
|
621
|
+
["--secondary", "secondary-container"],
|
|
622
|
+
["--secondary-foreground", "on-secondary-container"],
|
|
623
|
+
["--muted", "surface-container-highest"],
|
|
624
|
+
["--muted-foreground", "on-surface-variant"],
|
|
625
|
+
["--accent", "secondary-container"],
|
|
626
|
+
["--accent-foreground", "on-secondary-container"],
|
|
627
|
+
["--destructive", "error"],
|
|
628
|
+
["--border", "outline-variant"],
|
|
629
|
+
["--input", "outline"],
|
|
630
|
+
["--ring", "primary"],
|
|
631
|
+
["--chart-1", "primary-fixed"],
|
|
632
|
+
["--chart-2", "secondary-fixed"],
|
|
633
|
+
["--chart-3", "tertiary-fixed"],
|
|
634
|
+
["--chart-4", "primary-fixed-dim"],
|
|
635
|
+
["--chart-5", "secondary-fixed-dim"],
|
|
636
|
+
["--sidebar", "surface-container-low"],
|
|
637
|
+
["--sidebar-foreground", "on-surface"],
|
|
638
|
+
["--sidebar-primary", "primary"],
|
|
639
|
+
["--sidebar-primary-foreground", "on-primary"],
|
|
640
|
+
["--sidebar-accent", "secondary-container"],
|
|
641
|
+
["--sidebar-accent-foreground", "on-secondary-container"],
|
|
642
|
+
["--sidebar-border", "outline-variant"],
|
|
643
|
+
["--sidebar-ring", "primary"]
|
|
644
|
+
];
|
|
645
|
+
function buildTailwind(ctx, options) {
|
|
646
|
+
const { prefix, mergedColorsLight, hexCustomColors } = ctx;
|
|
647
|
+
const lines = [];
|
|
648
|
+
for (const name of Object.keys(mergedColorsLight)) {
|
|
649
|
+
const kebab = kebabCase3(name);
|
|
650
|
+
lines.push(`--color-${kebab}: var(--${prefix}-sys-color-${kebab});`);
|
|
651
|
+
}
|
|
652
|
+
lines.push("");
|
|
653
|
+
lines.push("/* Shades */");
|
|
654
|
+
for (const palette of CORE_PALETTES) {
|
|
655
|
+
lines.push("");
|
|
656
|
+
for (const [shade, tone] of SHADE_TO_TONE) {
|
|
657
|
+
lines.push(
|
|
658
|
+
`--color-${palette}-${shade}: var(--${prefix}-ref-palette-${palette}-${tone});`
|
|
659
|
+
);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
if (hexCustomColors.length > 0) {
|
|
663
|
+
for (const customColor of hexCustomColors) {
|
|
664
|
+
const kebab = kebabCase3(customColor.name);
|
|
665
|
+
lines.push("");
|
|
666
|
+
for (const [shade, tone] of SHADE_TO_TONE) {
|
|
667
|
+
lines.push(
|
|
668
|
+
`--color-${kebab}-${shade}: var(--${prefix}-ref-palette-${kebab}-${tone});`
|
|
669
|
+
);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
let output = `@theme inline {
|
|
674
|
+
${lines.join("\n ")}
|
|
675
|
+
}
|
|
676
|
+
`;
|
|
677
|
+
if (options?.shadcn) {
|
|
678
|
+
const shadcnLines = SHADCN_MAPPING.map(
|
|
679
|
+
([shadcnVar, m3Token]) => `${shadcnVar}: var(--${prefix}-sys-color-${m3Token});`
|
|
680
|
+
);
|
|
681
|
+
output += `
|
|
682
|
+
:root,
|
|
683
|
+
.dark {
|
|
684
|
+
${shadcnLines.join("\n ")}
|
|
685
|
+
}
|
|
686
|
+
`;
|
|
687
|
+
}
|
|
688
|
+
return output;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// src/lib/builder.ts
|
|
25
692
|
var schemesMap = {
|
|
26
693
|
tonalSpot: SchemeTonalSpot,
|
|
27
694
|
monochrome: SchemeMonochrome,
|
|
@@ -66,26 +733,6 @@ var STANDARD_TONES = [
|
|
|
66
733
|
99,
|
|
67
734
|
100
|
|
68
735
|
];
|
|
69
|
-
var MTB_TONES = [
|
|
70
|
-
0,
|
|
71
|
-
5,
|
|
72
|
-
10,
|
|
73
|
-
15,
|
|
74
|
-
20,
|
|
75
|
-
25,
|
|
76
|
-
30,
|
|
77
|
-
35,
|
|
78
|
-
40,
|
|
79
|
-
50,
|
|
80
|
-
60,
|
|
81
|
-
70,
|
|
82
|
-
80,
|
|
83
|
-
90,
|
|
84
|
-
95,
|
|
85
|
-
98,
|
|
86
|
-
99,
|
|
87
|
-
100
|
|
88
|
-
];
|
|
89
736
|
var Variant = {
|
|
90
737
|
MONOCHROME: 0,
|
|
91
738
|
NEUTRAL: 1,
|
|
@@ -157,9 +804,21 @@ var tokenDescriptions = {
|
|
|
157
804
|
tertiaryFixed: "Fixed tertiary color that stays the same in light and dark themes.",
|
|
158
805
|
tertiaryFixedDim: "Dimmed variant of the fixed tertiary color for lower emphasis."
|
|
159
806
|
};
|
|
160
|
-
|
|
161
|
-
tokenDescriptions
|
|
162
|
-
|
|
807
|
+
function isTokenName(key) {
|
|
808
|
+
return key in tokenDescriptions;
|
|
809
|
+
}
|
|
810
|
+
var tokenNames = Object.keys(tokenDescriptions).filter(isTokenName);
|
|
811
|
+
function deriveCustomPaletteName(tokenName, allPaletteNamesKebab) {
|
|
812
|
+
let baseName = tokenName;
|
|
813
|
+
if (/^on[A-Z]/.test(baseName) && baseName.length > 2) {
|
|
814
|
+
baseName = baseName.charAt(2).toLowerCase() + baseName.slice(3);
|
|
815
|
+
}
|
|
816
|
+
if (baseName.endsWith("Container")) {
|
|
817
|
+
baseName = baseName.slice(0, -"Container".length);
|
|
818
|
+
}
|
|
819
|
+
const kebab = kebabCase4(baseName);
|
|
820
|
+
return allPaletteNamesKebab.has(kebab) ? kebab : void 0;
|
|
821
|
+
}
|
|
163
822
|
function toRecord(arr, getEntry) {
|
|
164
823
|
return Object.fromEntries(arr.map(getEntry));
|
|
165
824
|
}
|
|
@@ -174,58 +833,55 @@ function getPalette(palettes, colorName) {
|
|
|
174
833
|
}
|
|
175
834
|
function mergeBaseAndCustomColors(scheme, customColors, colorPalettes) {
|
|
176
835
|
const baseVars = toRecord(tokenNames, (tokenName) => {
|
|
177
|
-
const dynamicColor =
|
|
836
|
+
const dynamicColor = MaterialDynamicColors2[tokenName];
|
|
178
837
|
const argb = dynamicColor.getArgb(scheme);
|
|
179
838
|
return [tokenName, argb];
|
|
180
839
|
});
|
|
181
840
|
const customVars = {};
|
|
182
841
|
customColors.forEach((color) => {
|
|
183
842
|
const colorname = color.name;
|
|
184
|
-
const getPaletteForColor = (
|
|
185
|
-
const getTone = (baseTone) => (_s) => {
|
|
186
|
-
return baseTone;
|
|
187
|
-
};
|
|
843
|
+
const getPaletteForColor = () => getPalette(colorPalettes, colorname);
|
|
188
844
|
const colorDynamicColor = new DynamicColor(
|
|
189
845
|
colorname,
|
|
190
846
|
getPaletteForColor,
|
|
191
|
-
(s) =>
|
|
847
|
+
(s) => s.isDark ? 80 : 40,
|
|
192
848
|
// Main color: lighter in dark mode, darker in light mode
|
|
193
849
|
true
|
|
194
850
|
// background
|
|
195
851
|
);
|
|
196
852
|
const onColorDynamicColor = new DynamicColor(
|
|
197
|
-
`on${
|
|
853
|
+
`on${upperFirst2(colorname)}`,
|
|
198
854
|
getPaletteForColor,
|
|
199
|
-
(s) =>
|
|
855
|
+
(s) => s.isDark ? 20 : 100,
|
|
200
856
|
// Text on main color: high contrast (dark on light, light on dark)
|
|
201
857
|
false
|
|
202
858
|
);
|
|
203
859
|
const containerDynamicColor = new DynamicColor(
|
|
204
860
|
`${colorname}Container`,
|
|
205
861
|
getPaletteForColor,
|
|
206
|
-
(s) =>
|
|
862
|
+
(s) => s.isDark ? 30 : 90,
|
|
207
863
|
// Container: subtle variant (darker in dark mode, lighter in light mode)
|
|
208
864
|
true
|
|
209
865
|
// background
|
|
210
866
|
);
|
|
211
867
|
const onContainerDynamicColor = new DynamicColor(
|
|
212
|
-
`on${
|
|
868
|
+
`on${upperFirst2(colorname)}Container`,
|
|
213
869
|
getPaletteForColor,
|
|
214
|
-
(s) =>
|
|
870
|
+
(s) => s.isDark ? 90 : 30,
|
|
215
871
|
// Text on container: high contrast against container background
|
|
216
872
|
false
|
|
217
873
|
);
|
|
218
874
|
customVars[colorname] = colorDynamicColor.getArgb(scheme);
|
|
219
|
-
customVars[`on${
|
|
875
|
+
customVars[`on${upperFirst2(colorname)}`] = onColorDynamicColor.getArgb(scheme);
|
|
220
876
|
customVars[`${colorname}Container`] = containerDynamicColor.getArgb(scheme);
|
|
221
|
-
customVars[`on${
|
|
877
|
+
customVars[`on${upperFirst2(colorname)}Container`] = onContainerDynamicColor.getArgb(scheme);
|
|
222
878
|
});
|
|
223
879
|
return { ...baseVars, ...customVars };
|
|
224
880
|
}
|
|
225
881
|
function createColorPalette(colorDef, baseScheme, effectiveSourceForHarmonization) {
|
|
226
|
-
const colorArgb =
|
|
882
|
+
const colorArgb = argbFromHex2(colorDef.hex);
|
|
227
883
|
const harmonizedArgb = colorDef.blend ? Blend.harmonize(colorArgb, effectiveSourceForHarmonization) : colorArgb;
|
|
228
|
-
const hct =
|
|
884
|
+
const hct = Hct2.fromInt(harmonizedArgb);
|
|
229
885
|
let targetChroma;
|
|
230
886
|
if (colorDef.core && colorDef.chromaSource) {
|
|
231
887
|
if (colorDef.chromaSource === "neutral") {
|
|
@@ -238,7 +894,25 @@ function createColorPalette(colorDef, baseScheme, effectiveSourceForHarmonizatio
|
|
|
238
894
|
} else {
|
|
239
895
|
targetChroma = baseScheme.primaryPalette.chroma;
|
|
240
896
|
}
|
|
241
|
-
return
|
|
897
|
+
return TonalPalette2.fromHueAndChroma(hct.hue, targetChroma);
|
|
898
|
+
}
|
|
899
|
+
function buildTokenToPaletteMap(schemePalettes, scheme) {
|
|
900
|
+
const result = {};
|
|
901
|
+
for (const propName of Object.getOwnPropertyNames(MaterialDynamicColors2)) {
|
|
902
|
+
const dc = Object.getOwnPropertyDescriptor(
|
|
903
|
+
MaterialDynamicColors2,
|
|
904
|
+
propName
|
|
905
|
+
)?.value;
|
|
906
|
+
if (!(dc instanceof DynamicColor)) continue;
|
|
907
|
+
const palette = dc.palette(scheme);
|
|
908
|
+
for (const [palName, pal] of schemePalettes) {
|
|
909
|
+
if (palette === pal) {
|
|
910
|
+
result[propName] = palName;
|
|
911
|
+
break;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
return result;
|
|
242
916
|
}
|
|
243
917
|
function builder(hexSource, {
|
|
244
918
|
scheme = DEFAULT_SCHEME,
|
|
@@ -252,13 +926,13 @@ function builder(hexSource, {
|
|
|
252
926
|
customColors: hexCustomColors = DEFAULT_CUSTOM_COLORS,
|
|
253
927
|
prefix = DEFAULT_PREFIX
|
|
254
928
|
} = {}) {
|
|
255
|
-
const sourceArgb =
|
|
256
|
-
const sourceHct =
|
|
929
|
+
const sourceArgb = argbFromHex2(hexSource);
|
|
930
|
+
const sourceHct = Hct2.fromInt(sourceArgb);
|
|
257
931
|
const effectiveSource = primary || hexSource;
|
|
258
|
-
const effectiveSourceArgb =
|
|
259
|
-
const effectiveSourceForHarmonization = primary ?
|
|
932
|
+
const effectiveSourceArgb = argbFromHex2(effectiveSource);
|
|
933
|
+
const effectiveSourceForHarmonization = primary ? argbFromHex2(primary) : sourceArgb;
|
|
260
934
|
const SchemeClass = schemesMap[scheme];
|
|
261
|
-
const primaryHct =
|
|
935
|
+
const primaryHct = Hct2.fromInt(effectiveSourceArgb);
|
|
262
936
|
const baseScheme = new SchemeClass(primaryHct, false, contrast);
|
|
263
937
|
const allColors = [
|
|
264
938
|
// Core colors (hex may be undefined)
|
|
@@ -323,8 +997,8 @@ function builder(hexSource, {
|
|
|
323
997
|
neutralPalette: colorPalettes["neutral"] || baseScheme.neutralPalette,
|
|
324
998
|
neutralVariantPalette: colorPalettes["neutralVariant"] || baseScheme.neutralVariantPalette
|
|
325
999
|
};
|
|
326
|
-
const lightScheme = new
|
|
327
|
-
const darkScheme = new
|
|
1000
|
+
const lightScheme = new DynamicScheme2({ ...schemeConfig, isDark: false });
|
|
1001
|
+
const darkScheme = new DynamicScheme2({ ...schemeConfig, isDark: true });
|
|
328
1002
|
const errorPalette = colorPalettes["error"];
|
|
329
1003
|
if (errorPalette) {
|
|
330
1004
|
lightScheme.errorPalette = errorPalette;
|
|
@@ -345,7 +1019,7 @@ function builder(hexSource, {
|
|
|
345
1019
|
const customColors = definedColors.filter((c) => !c.core).map((c) => ({
|
|
346
1020
|
name: c.name,
|
|
347
1021
|
blend: c.blend ?? DEFAULT_BLEND,
|
|
348
|
-
value:
|
|
1022
|
+
value: argbFromHex2(c.hex)
|
|
349
1023
|
}));
|
|
350
1024
|
const mergedColorsLight = mergeBaseAndCustomColors(
|
|
351
1025
|
lightScheme,
|
|
@@ -365,523 +1039,46 @@ function builder(hexSource, {
|
|
|
365
1039
|
["neutral", lightScheme.neutralPalette],
|
|
366
1040
|
["neutral-variant", lightScheme.neutralVariantPalette]
|
|
367
1041
|
];
|
|
368
|
-
function buildTokenToPaletteMap(schemePalettes2, scheme2) {
|
|
369
|
-
const result = {};
|
|
370
|
-
for (const propName of Object.getOwnPropertyNames(MaterialDynamicColors)) {
|
|
371
|
-
const dc = MaterialDynamicColors[propName];
|
|
372
|
-
if (!(dc instanceof DynamicColor)) continue;
|
|
373
|
-
const palette = dc.palette(scheme2);
|
|
374
|
-
for (const [palName, pal] of schemePalettes2) {
|
|
375
|
-
if (palette === pal) {
|
|
376
|
-
result[propName] = palName;
|
|
377
|
-
break;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
return result;
|
|
382
|
-
}
|
|
383
1042
|
const tokenToPalette = buildTokenToPaletteMap(schemePalettes, lightScheme);
|
|
384
|
-
const allPaletteNamesKebab = new Set(Object.keys(allPalettes).map(
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
1043
|
+
const allPaletteNamesKebab = new Set(Object.keys(allPalettes).map(kebabCase4));
|
|
1044
|
+
const ctx = {
|
|
1045
|
+
hexSource,
|
|
1046
|
+
prefix,
|
|
1047
|
+
scheme,
|
|
1048
|
+
primary,
|
|
1049
|
+
secondary,
|
|
1050
|
+
tertiary,
|
|
1051
|
+
neutral,
|
|
1052
|
+
neutralVariant,
|
|
1053
|
+
error,
|
|
1054
|
+
hexCustomColors,
|
|
1055
|
+
sourceHct,
|
|
1056
|
+
effectiveSourceArgb,
|
|
1057
|
+
primaryHct,
|
|
1058
|
+
SchemeClass,
|
|
1059
|
+
allPalettes,
|
|
1060
|
+
mergedColorsLight,
|
|
1061
|
+
mergedColorsDark,
|
|
1062
|
+
tokenToPalette,
|
|
1063
|
+
allPaletteNamesKebab
|
|
1064
|
+
};
|
|
396
1065
|
return {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
//
|
|
404
|
-
toCss() {
|
|
405
|
-
function buildRefPaletteLookup() {
|
|
406
|
-
const lookup = {};
|
|
407
|
-
for (const [name, palette] of Object.entries(allPalettes)) {
|
|
408
|
-
const paletteName = kebabCase(name);
|
|
409
|
-
for (const tone of STANDARD_TONES) {
|
|
410
|
-
const hex = hexFromArgb(palette.tone(tone));
|
|
411
|
-
if (!lookup[hex]) lookup[hex] = [];
|
|
412
|
-
lookup[hex].push({ paletteName, tone });
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
return lookup;
|
|
416
|
-
}
|
|
417
|
-
function sysColorVar(colorName, colorValue, lookup) {
|
|
418
|
-
const name = `--${prefix}-sys-color-${kebabCase(colorName)}`;
|
|
419
|
-
const hex = hexFromArgb(colorValue);
|
|
420
|
-
const matches = lookup[hex];
|
|
421
|
-
if (matches && matches.length > 0) {
|
|
422
|
-
const preferred = tokenToPalette[colorName] ?? deriveCustomPaletteName(colorName);
|
|
423
|
-
const match = (preferred ? matches.find((m) => m.paletteName === preferred) : void 0) ?? matches[0];
|
|
424
|
-
return `${name}:var(--${prefix}-ref-palette-${match.paletteName}-${match.tone});`;
|
|
425
|
-
}
|
|
426
|
-
return `${name}:${hex};`;
|
|
427
|
-
}
|
|
428
|
-
function toCssVars(mergedColors, lookup) {
|
|
429
|
-
return Object.entries(mergedColors).map(([name, value]) => sysColorVar(name, value, lookup)).join(" ");
|
|
430
|
-
}
|
|
431
|
-
function refPaletteVar(paletteName, tone, colorValue) {
|
|
432
|
-
const name = `--${prefix}-ref-palette-${paletteName}-${tone}`;
|
|
433
|
-
const value = hexFromArgb(colorValue);
|
|
434
|
-
return `${name}:${value};`;
|
|
435
|
-
}
|
|
436
|
-
function generateTonalPaletteVars(paletteName, palette) {
|
|
437
|
-
return STANDARD_TONES.map((tone) => {
|
|
438
|
-
const color = palette.tone(tone);
|
|
439
|
-
return refPaletteVar(paletteName, tone, color);
|
|
440
|
-
}).join(" ");
|
|
441
|
-
}
|
|
442
|
-
function generateTonalVars() {
|
|
443
|
-
return Object.entries(allPalettes).map(
|
|
444
|
-
([name, palette]) => generateTonalPaletteVars(kebabCase(name), palette)
|
|
445
|
-
).join(" ");
|
|
446
|
-
}
|
|
447
|
-
const refPaletteLookup = buildRefPaletteLookup();
|
|
448
|
-
const lightVars = toCssVars(mergedColorsLight, refPaletteLookup);
|
|
449
|
-
const darkVars = toCssVars(mergedColorsDark, refPaletteLookup);
|
|
450
|
-
const tonalVars = generateTonalVars();
|
|
451
|
-
return `
|
|
452
|
-
:root { ${lightVars} ${tonalVars} }
|
|
453
|
-
.dark { ${darkVars} ${tonalVars} }
|
|
454
|
-
`;
|
|
455
|
-
},
|
|
456
|
-
//
|
|
457
|
-
// ██ ███████ ██████ ███ ██
|
|
458
|
-
// ██ ██ ██ ██ ████ ██
|
|
459
|
-
// ██ ███████ ██ ██ ██ ██ ██
|
|
460
|
-
// ██ ██ ██ ██ ██ ██ ██ ██
|
|
461
|
-
// █████ ███████ ██████ ██ ████
|
|
462
|
-
//
|
|
463
|
-
toJson() {
|
|
464
|
-
const fixtureTokenOrder = [
|
|
465
|
-
"primary",
|
|
466
|
-
"surfaceTint",
|
|
467
|
-
"onPrimary",
|
|
468
|
-
"primaryContainer",
|
|
469
|
-
"onPrimaryContainer",
|
|
470
|
-
"secondary",
|
|
471
|
-
"onSecondary",
|
|
472
|
-
"secondaryContainer",
|
|
473
|
-
"onSecondaryContainer",
|
|
474
|
-
"tertiary",
|
|
475
|
-
"onTertiary",
|
|
476
|
-
"tertiaryContainer",
|
|
477
|
-
"onTertiaryContainer",
|
|
478
|
-
"error",
|
|
479
|
-
"onError",
|
|
480
|
-
"errorContainer",
|
|
481
|
-
"onErrorContainer",
|
|
482
|
-
"background",
|
|
483
|
-
"onBackground",
|
|
484
|
-
"surface",
|
|
485
|
-
"onSurface",
|
|
486
|
-
"surfaceVariant",
|
|
487
|
-
"onSurfaceVariant",
|
|
488
|
-
"outline",
|
|
489
|
-
"outlineVariant",
|
|
490
|
-
"shadow",
|
|
491
|
-
"scrim",
|
|
492
|
-
"inverseSurface",
|
|
493
|
-
"inverseOnSurface",
|
|
494
|
-
"inversePrimary",
|
|
495
|
-
"primaryFixed",
|
|
496
|
-
"onPrimaryFixed",
|
|
497
|
-
"primaryFixedDim",
|
|
498
|
-
"onPrimaryFixedVariant",
|
|
499
|
-
"secondaryFixed",
|
|
500
|
-
"onSecondaryFixed",
|
|
501
|
-
"secondaryFixedDim",
|
|
502
|
-
"onSecondaryFixedVariant",
|
|
503
|
-
"tertiaryFixed",
|
|
504
|
-
"onTertiaryFixed",
|
|
505
|
-
"tertiaryFixedDim",
|
|
506
|
-
"onTertiaryFixedVariant",
|
|
507
|
-
"surfaceDim",
|
|
508
|
-
"surfaceBright",
|
|
509
|
-
"surfaceContainerLowest",
|
|
510
|
-
"surfaceContainerLow",
|
|
511
|
-
"surfaceContainer",
|
|
512
|
-
"surfaceContainerHigh",
|
|
513
|
-
"surfaceContainerHighest"
|
|
514
|
-
];
|
|
515
|
-
const neuHct = neutral ? Hct.fromInt(argbFromHex(neutral)) : sourceHct;
|
|
516
|
-
const nvHct = neutralVariant ? Hct.fromInt(argbFromHex(neutralVariant)) : sourceHct;
|
|
517
|
-
const rawPalettes = {
|
|
518
|
-
primary: TonalPalette.fromInt(effectiveSourceArgb),
|
|
519
|
-
secondary: secondary ? TonalPalette.fromInt(argbFromHex(secondary)) : TonalPalette.fromHueAndChroma(sourceHct.hue, sourceHct.chroma / 3),
|
|
520
|
-
tertiary: tertiary ? TonalPalette.fromInt(argbFromHex(tertiary)) : TonalPalette.fromHueAndChroma(
|
|
521
|
-
(sourceHct.hue + 60) % 360,
|
|
522
|
-
sourceHct.chroma / 2
|
|
523
|
-
),
|
|
524
|
-
neutral: TonalPalette.fromHueAndChroma(
|
|
525
|
-
neuHct.hue,
|
|
526
|
-
Math.min(neuHct.chroma / 12, 4)
|
|
527
|
-
),
|
|
528
|
-
"neutral-variant": TonalPalette.fromHueAndChroma(
|
|
529
|
-
nvHct.hue,
|
|
530
|
-
Math.min(nvHct.chroma / 6, 8)
|
|
531
|
-
)
|
|
532
|
-
};
|
|
533
|
-
function buildJsonSchemes() {
|
|
534
|
-
function extractSchemeColors(scheme2, backgroundScheme) {
|
|
535
|
-
const colors = {};
|
|
536
|
-
for (const tokenName of fixtureTokenOrder) {
|
|
537
|
-
const dynamicColor = MaterialDynamicColors[tokenName];
|
|
538
|
-
const useScheme = backgroundScheme && (tokenName === "background" || tokenName === "onBackground") ? backgroundScheme : scheme2;
|
|
539
|
-
colors[tokenName] = hexFromArgb(
|
|
540
|
-
dynamicColor.getArgb(useScheme)
|
|
541
|
-
).toUpperCase();
|
|
542
|
-
}
|
|
543
|
-
return colors;
|
|
544
|
-
}
|
|
545
|
-
function resolveOverridePalette(hex, role) {
|
|
546
|
-
if (!hex) return null;
|
|
547
|
-
return new SchemeClass(Hct.fromInt(argbFromHex(hex)), false, 0)[role];
|
|
548
|
-
}
|
|
549
|
-
const secPalette = resolveOverridePalette(secondary, "primaryPalette");
|
|
550
|
-
const terPalette = resolveOverridePalette(tertiary, "primaryPalette");
|
|
551
|
-
const errPalette = resolveOverridePalette(error, "primaryPalette");
|
|
552
|
-
const neuPalette = resolveOverridePalette(neutral, "neutralPalette");
|
|
553
|
-
const nvPalette = resolveOverridePalette(
|
|
554
|
-
neutralVariant,
|
|
555
|
-
"neutralVariantPalette"
|
|
556
|
-
);
|
|
557
|
-
const jsonSchemes = {};
|
|
558
|
-
const jsonContrastLevels = [
|
|
559
|
-
{ name: "light", isDark: false, contrast: 0 },
|
|
560
|
-
{ name: "light-medium-contrast", isDark: false, contrast: 0.5 },
|
|
561
|
-
{ name: "light-high-contrast", isDark: false, contrast: 1 },
|
|
562
|
-
{ name: "dark", isDark: true, contrast: 0 },
|
|
563
|
-
{ name: "dark-medium-contrast", isDark: true, contrast: 0.5 },
|
|
564
|
-
{ name: "dark-high-contrast", isDark: true, contrast: 1 }
|
|
565
|
-
];
|
|
566
|
-
for (const { name, isDark, contrast: contrast2 } of jsonContrastLevels) {
|
|
567
|
-
const baseScheme2 = new SchemeClass(primaryHct, isDark, contrast2);
|
|
568
|
-
const composedScheme = new DynamicScheme({
|
|
569
|
-
sourceColorArgb: effectiveSourceArgb,
|
|
570
|
-
variant: schemeToVariant[scheme],
|
|
571
|
-
contrastLevel: contrast2,
|
|
572
|
-
isDark,
|
|
573
|
-
primaryPalette: baseScheme2.primaryPalette,
|
|
574
|
-
secondaryPalette: secPalette || baseScheme2.secondaryPalette,
|
|
575
|
-
tertiaryPalette: terPalette || baseScheme2.tertiaryPalette,
|
|
576
|
-
neutralPalette: neuPalette || baseScheme2.neutralPalette,
|
|
577
|
-
neutralVariantPalette: nvPalette || baseScheme2.neutralVariantPalette
|
|
578
|
-
});
|
|
579
|
-
if (errPalette) composedScheme.errorPalette = errPalette;
|
|
580
|
-
jsonSchemes[name] = extractSchemeColors(composedScheme, baseScheme2);
|
|
581
|
-
}
|
|
582
|
-
return jsonSchemes;
|
|
583
|
-
}
|
|
584
|
-
function rawPalettesToJson() {
|
|
585
|
-
const jsonPalettes = {};
|
|
586
|
-
const RAW_PALETTE_NAMES = [
|
|
587
|
-
"primary",
|
|
588
|
-
"secondary",
|
|
589
|
-
"tertiary",
|
|
590
|
-
"neutral",
|
|
591
|
-
"neutral-variant"
|
|
592
|
-
];
|
|
593
|
-
for (const name of RAW_PALETTE_NAMES) {
|
|
594
|
-
const palette = rawPalettes[name];
|
|
595
|
-
const tones = {};
|
|
596
|
-
for (const tone of MTB_TONES) {
|
|
597
|
-
tones[tone.toString()] = hexFromArgb(
|
|
598
|
-
palette.tone(tone)
|
|
599
|
-
).toUpperCase();
|
|
600
|
-
}
|
|
601
|
-
jsonPalettes[name] = tones;
|
|
602
|
-
}
|
|
603
|
-
return jsonPalettes;
|
|
604
|
-
}
|
|
605
|
-
function buildCoreColors(opts) {
|
|
606
|
-
const colors = { primary: opts.primary };
|
|
607
|
-
if (opts.secondary) colors.secondary = opts.secondary.toUpperCase();
|
|
608
|
-
if (opts.tertiary) colors.tertiary = opts.tertiary.toUpperCase();
|
|
609
|
-
if (opts.error) colors.error = opts.error.toUpperCase();
|
|
610
|
-
if (opts.neutral) colors.neutral = opts.neutral.toUpperCase();
|
|
611
|
-
if (opts.neutralVariant)
|
|
612
|
-
colors.neutralVariant = opts.neutralVariant.toUpperCase();
|
|
613
|
-
return colors;
|
|
614
|
-
}
|
|
615
|
-
const seed = hexSource.toUpperCase();
|
|
616
|
-
const coreColors = buildCoreColors({
|
|
617
|
-
primary: (primary || hexSource).toUpperCase(),
|
|
618
|
-
secondary,
|
|
619
|
-
tertiary,
|
|
620
|
-
error,
|
|
621
|
-
neutral,
|
|
622
|
-
neutralVariant
|
|
623
|
-
});
|
|
624
|
-
const extendedColors = hexCustomColors.map((c) => ({
|
|
625
|
-
name: c.name,
|
|
626
|
-
color: c.hex.toUpperCase(),
|
|
627
|
-
description: "",
|
|
628
|
-
harmonized: c.blend ?? DEFAULT_BLEND
|
|
629
|
-
}));
|
|
630
|
-
return {
|
|
631
|
-
seed,
|
|
632
|
-
coreColors,
|
|
633
|
-
extendedColors,
|
|
634
|
-
schemes: buildJsonSchemes(),
|
|
635
|
-
palettes: rawPalettesToJson()
|
|
636
|
-
};
|
|
637
|
-
},
|
|
638
|
-
//
|
|
639
|
-
// ███████ ██ ██████ ███ ███ █████
|
|
640
|
-
// ██ ██ ██ ████ ████ ██ ██
|
|
641
|
-
// █████ ██ ██ ███ ██ ████ ██ ███████
|
|
642
|
-
// ██ ██ ██ ██ ██ ██ ██ ██ ██
|
|
643
|
-
// ██ ██ ██████ ██ ██ ██ ██
|
|
644
|
-
//
|
|
645
|
-
toFigmaTokens() {
|
|
646
|
-
function argbToFigmaColorValue(argb) {
|
|
647
|
-
return {
|
|
648
|
-
colorSpace: "srgb",
|
|
649
|
-
components: [
|
|
650
|
-
redFromArgb(argb) / 255,
|
|
651
|
-
greenFromArgb(argb) / 255,
|
|
652
|
-
blueFromArgb(argb) / 255
|
|
653
|
-
],
|
|
654
|
-
alpha: 1,
|
|
655
|
-
hex: hexFromArgb(argb).toUpperCase()
|
|
656
|
-
};
|
|
657
|
-
}
|
|
658
|
-
function figmaToken(argb) {
|
|
659
|
-
return {
|
|
660
|
-
$type: "color",
|
|
661
|
-
$value: argbToFigmaColorValue(argb),
|
|
662
|
-
$extensions: {
|
|
663
|
-
"com.figma.scopes": ["ALL_SCOPES"],
|
|
664
|
-
"com.figma.isOverride": true
|
|
665
|
-
}
|
|
666
|
-
};
|
|
667
|
-
}
|
|
668
|
-
function buildRefPaletteTokens() {
|
|
669
|
-
const palettes = {};
|
|
670
|
-
for (const [name, palette] of Object.entries(allPalettes)) {
|
|
671
|
-
const tones = {};
|
|
672
|
-
for (const tone of STANDARD_TONES) {
|
|
673
|
-
const argb = palette.tone(tone);
|
|
674
|
-
tones[tone.toString()] = figmaToken(argb);
|
|
675
|
-
}
|
|
676
|
-
palettes[startCase(name)] = tones;
|
|
677
|
-
}
|
|
678
|
-
return palettes;
|
|
679
|
-
}
|
|
680
|
-
function findToneInPalette(hex, paletteName, tones) {
|
|
681
|
-
for (const [tone, token] of Object.entries(tones)) {
|
|
682
|
-
if (token.$value.hex === hex) {
|
|
683
|
-
return `{ref.palette.${paletteName}.${tone}}`;
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
return null;
|
|
687
|
-
}
|
|
688
|
-
function findAlias(hex, tokenName, refPalettes2) {
|
|
689
|
-
const preferredPaletteKebab = tokenToPalette[tokenName] ?? deriveCustomPaletteName(tokenName);
|
|
690
|
-
const preferredPalette = preferredPaletteKebab ? startCase(preferredPaletteKebab) : void 0;
|
|
691
|
-
if (preferredPalette && refPalettes2[preferredPalette]) {
|
|
692
|
-
const match = findToneInPalette(
|
|
693
|
-
hex,
|
|
694
|
-
preferredPalette,
|
|
695
|
-
refPalettes2[preferredPalette]
|
|
696
|
-
);
|
|
697
|
-
if (match) return match;
|
|
698
|
-
}
|
|
699
|
-
for (const [palName, tones] of Object.entries(refPalettes2)) {
|
|
700
|
-
const match = findToneInPalette(hex, palName, tones);
|
|
701
|
-
if (match) return match;
|
|
702
|
-
}
|
|
703
|
-
return null;
|
|
704
|
-
}
|
|
705
|
-
function resolveModeValue(argb, tokenName, refPalettes2) {
|
|
706
|
-
const hex = hexFromArgb(argb).toUpperCase();
|
|
707
|
-
return findAlias(hex, tokenName, refPalettes2) ?? argbToFigmaColorValue(argb);
|
|
708
|
-
}
|
|
709
|
-
function buildSysColorTokens(mergedColors, refPalettes2) {
|
|
710
|
-
const tokens = {};
|
|
711
|
-
for (const [name, argb] of Object.entries(mergedColors)) {
|
|
712
|
-
const description = tokenDescriptions[name];
|
|
713
|
-
const cssVar = `--${prefix}-sys-color-${kebabCase(name)}`;
|
|
714
|
-
const value = resolveModeValue(argb, name, refPalettes2);
|
|
715
|
-
tokens[startCase(name)] = {
|
|
716
|
-
$type: "color",
|
|
717
|
-
$value: value,
|
|
718
|
-
...description ? { $description: description } : {},
|
|
719
|
-
$extensions: {
|
|
720
|
-
"com.figma.scopes": ["ALL_SCOPES"],
|
|
721
|
-
"css.variable": cssVar
|
|
722
|
-
}
|
|
723
|
-
};
|
|
724
|
-
}
|
|
725
|
-
return tokens;
|
|
726
|
-
}
|
|
727
|
-
const refPalettes = buildRefPaletteTokens();
|
|
728
|
-
function buildModeFile(modeName, mergedColors) {
|
|
729
|
-
return {
|
|
730
|
-
ref: {
|
|
731
|
-
palette: refPalettes
|
|
732
|
-
},
|
|
733
|
-
sys: {
|
|
734
|
-
color: buildSysColorTokens(mergedColors, refPalettes)
|
|
735
|
-
},
|
|
736
|
-
$extensions: {
|
|
737
|
-
"com.figma.modeName": modeName
|
|
738
|
-
}
|
|
739
|
-
};
|
|
740
|
-
}
|
|
741
|
-
return {
|
|
742
|
-
"Light.tokens.json": buildModeFile("Light", mergedColorsLight),
|
|
743
|
-
"Dark.tokens.json": buildModeFile("Dark", mergedColorsDark)
|
|
744
|
-
};
|
|
745
|
-
},
|
|
746
|
-
//
|
|
747
|
-
// API
|
|
748
|
-
//
|
|
1066
|
+
toCss: () => buildCss(ctx),
|
|
1067
|
+
toJson: () => buildJson(ctx),
|
|
1068
|
+
toFigmaVariables: () => buildFigmaVariables(ctx),
|
|
1069
|
+
toFigmaTokens: () => buildFigmaTokens(ctx),
|
|
1070
|
+
toTailwind: (options) => buildTailwind(ctx, options),
|
|
1071
|
+
toFlutter: () => buildFlutter(ctx),
|
|
749
1072
|
mergedColorsLight,
|
|
750
1073
|
mergedColorsDark,
|
|
751
1074
|
allPalettes
|
|
752
1075
|
};
|
|
753
1076
|
}
|
|
754
1077
|
|
|
755
|
-
// src/
|
|
756
|
-
import {
|
|
757
|
-
|
|
758
|
-
// src/Mcu.context.tsx
|
|
759
|
-
import {
|
|
760
|
-
hexFromArgb as hexFromArgb2
|
|
761
|
-
} from "@material/material-color-utilities";
|
|
762
|
-
import React, {
|
|
763
|
-
useCallback,
|
|
764
|
-
useInsertionEffect,
|
|
765
|
-
useMemo,
|
|
766
|
-
useState
|
|
767
|
-
} from "react";
|
|
768
|
-
|
|
769
|
-
// src/lib/createRequiredContext.ts
|
|
770
|
-
import { createContext, useContext } from "react";
|
|
771
|
-
var createRequiredContext = () => {
|
|
772
|
-
const Ctx = createContext(null);
|
|
773
|
-
const useCtx = () => {
|
|
774
|
-
const contextValue = useContext(Ctx);
|
|
775
|
-
if (contextValue === null) {
|
|
776
|
-
throw new Error("Context value is null");
|
|
777
|
-
}
|
|
778
|
-
return contextValue;
|
|
779
|
-
};
|
|
780
|
-
return [useCtx, Ctx.Provider, Ctx];
|
|
781
|
-
};
|
|
782
|
-
|
|
783
|
-
// src/Mcu.context.tsx
|
|
784
|
-
import { jsx } from "react/jsx-runtime";
|
|
785
|
-
var [useMcu, Provider, McuContext] = createRequiredContext();
|
|
786
|
-
var McuProvider = ({
|
|
787
|
-
styleId,
|
|
788
|
-
children,
|
|
789
|
-
...configProps
|
|
790
|
-
}) => {
|
|
791
|
-
const [initials] = useState(() => configProps);
|
|
792
|
-
const [mcuConfig, setMcuConfig] = useState(initials);
|
|
793
|
-
const configKey = JSON.stringify(configProps);
|
|
794
|
-
React.useEffect(() => {
|
|
795
|
-
setMcuConfig(configProps);
|
|
796
|
-
}, [configKey]);
|
|
797
|
-
const { css, mergedColorsLight, mergedColorsDark, allPalettes } = useMemo(() => {
|
|
798
|
-
const { toCss, ...rest } = builder(mcuConfig.source, mcuConfig);
|
|
799
|
-
return { css: toCss(), ...rest };
|
|
800
|
-
}, [mcuConfig]);
|
|
801
|
-
useInsertionEffect(() => {
|
|
802
|
-
let tag = document.getElementById(styleId);
|
|
803
|
-
if (!tag) {
|
|
804
|
-
tag = document.createElement("style");
|
|
805
|
-
tag.id = styleId;
|
|
806
|
-
document.head.appendChild(tag);
|
|
807
|
-
}
|
|
808
|
-
tag.textContent = css;
|
|
809
|
-
}, [css, styleId]);
|
|
810
|
-
const getMcuColor = useCallback(
|
|
811
|
-
(colorName, theme) => {
|
|
812
|
-
const mergedColors = theme === "light" ? mergedColorsLight : mergedColorsDark;
|
|
813
|
-
const colorValue = mergedColors[colorName];
|
|
814
|
-
if (colorValue === void 0) {
|
|
815
|
-
throw new Error(`Unknown MCU token '${colorName}'`);
|
|
816
|
-
}
|
|
817
|
-
return hexFromArgb2(colorValue);
|
|
818
|
-
},
|
|
819
|
-
[mergedColorsDark, mergedColorsLight]
|
|
820
|
-
);
|
|
821
|
-
const value = useMemo(
|
|
822
|
-
() => ({
|
|
823
|
-
initials,
|
|
824
|
-
setMcuConfig,
|
|
825
|
-
getMcuColor,
|
|
826
|
-
allPalettes
|
|
827
|
-
}),
|
|
828
|
-
[getMcuColor, initials, allPalettes]
|
|
829
|
-
);
|
|
830
|
-
return /* @__PURE__ */ jsx(Provider, { value, children });
|
|
831
|
-
};
|
|
832
|
-
|
|
833
|
-
// src/Mcu.tsx
|
|
834
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
835
|
-
var mcuStyleId = "mcu-styles";
|
|
836
|
-
var DEFAULT_COLOR_MATCH = false;
|
|
837
|
-
function Mcu({
|
|
838
|
-
source,
|
|
839
|
-
scheme = DEFAULT_SCHEME,
|
|
840
|
-
contrast = DEFAULT_CONTRAST,
|
|
841
|
-
primary,
|
|
842
|
-
secondary,
|
|
843
|
-
tertiary,
|
|
844
|
-
neutral,
|
|
845
|
-
neutralVariant,
|
|
846
|
-
error,
|
|
847
|
-
colorMatch = DEFAULT_COLOR_MATCH,
|
|
848
|
-
customColors = DEFAULT_CUSTOM_COLORS,
|
|
849
|
-
prefix = DEFAULT_PREFIX,
|
|
850
|
-
children
|
|
851
|
-
}) {
|
|
852
|
-
const config = useMemo2(
|
|
853
|
-
() => ({
|
|
854
|
-
source,
|
|
855
|
-
scheme,
|
|
856
|
-
contrast,
|
|
857
|
-
primary,
|
|
858
|
-
secondary,
|
|
859
|
-
tertiary,
|
|
860
|
-
neutral,
|
|
861
|
-
neutralVariant,
|
|
862
|
-
error,
|
|
863
|
-
colorMatch,
|
|
864
|
-
customColors,
|
|
865
|
-
prefix
|
|
866
|
-
}),
|
|
867
|
-
[
|
|
868
|
-
contrast,
|
|
869
|
-
customColors,
|
|
870
|
-
scheme,
|
|
871
|
-
source,
|
|
872
|
-
primary,
|
|
873
|
-
secondary,
|
|
874
|
-
tertiary,
|
|
875
|
-
neutral,
|
|
876
|
-
neutralVariant,
|
|
877
|
-
error,
|
|
878
|
-
colorMatch,
|
|
879
|
-
prefix
|
|
880
|
-
]
|
|
881
|
-
);
|
|
882
|
-
return /* @__PURE__ */ jsx2(McuProvider, { ...config, styleId: mcuStyleId, children });
|
|
883
|
-
}
|
|
1078
|
+
// src/index.ts
|
|
1079
|
+
import { ExportButton, Mcu, useMcu } from "./react.js";
|
|
884
1080
|
export {
|
|
1081
|
+
ExportButton,
|
|
885
1082
|
Mcu,
|
|
886
1083
|
builder,
|
|
887
1084
|
useMcu
|