@sandlada/mcu-helper 0.0.1-20260719.a

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Kai-Orion & Sandlada
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,366 @@
1
+ # @sandlada/mcu-helper
2
+
3
+ ![NPM Downloads](https://img.shields.io/npm/d18m/@sandlada/mcu-helper?label=NPM%20Downloads&labelColor=%2300531f&color=%23a3f5aa)
4
+ ![npm version](https://img.shields.io/npm/v/@sandlada/mcu-helper?label=NPM%20Version&labelColor=%2300531f&color=%23a3f5aa)
5
+ ![GitHub License](https://img.shields.io/github/license/sandlada/mcu-helper?label=License&labelColor=%2300531f&color=%23a3f5aa)
6
+
7
+ Generate **Material Design 3** (Material You) color tokens, tonal palettes, and CSS custom properties from a source color. Built on top of [`@material/material-color-utilities`](https://github.com/material-foundation/material-color-utilities).
8
+
9
+ ---
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install @sandlada/mcu-helper
15
+ ```
16
+
17
+ ```bash
18
+ yarn add @sandlada/mcu-helper
19
+ ```
20
+
21
+ ```bash
22
+ pnpm add @sandlada/mcu-helper
23
+ ```
24
+
25
+ > `@material/material-color-utilities` is a **peer dependency** — make sure it's installed in your project.
26
+
27
+ ---
28
+
29
+ ## Quick Start
30
+
31
+ ```ts
32
+ import { Hct } from "@material/material-color-utilities"
33
+ import { MaterialColor, Serialization } from "@sandlada/mcu-helper"
34
+
35
+ // 1. Pick a source color (in HCT color space)
36
+ const sourceColor = Hct.fromInt(0xff6750a4) // Seed color
37
+
38
+ // 2. Generate light & dark theme colors
39
+ const theme = MaterialColor.Create({ sourceColor })
40
+
41
+ // 3. Serialize to CSS custom properties
42
+ const css = Serialization.ToCSS({
43
+ lightObject: theme.lightObject,
44
+ darkObject: theme.darkObject,
45
+ })
46
+
47
+ console.log(css)
48
+ ```
49
+
50
+ Output:
51
+
52
+ ```css
53
+ :root {
54
+ --md-sys-color-background: light-dark(#f8fdff, #101416);
55
+ --md-sys-color-error: light-dark(#ba1a1a, #ffb4ab);
56
+ --md-sys-color-error-container: light-dark(#ffdad6, #93000a);
57
+ --md-sys-color-inverse-on-surface: light-dark(#f0f1f1, #111415);
58
+ /* ... more tokens */
59
+ --md-sys-color-primary: light-dark(#6750a4, #d0bcff);
60
+ --md-sys-color-surface-container-lowest: light-dark(#ffffff, #080b0c);
61
+ --md-sys-color-on-surface: light-dark(#191c1d, #e0e3e3);
62
+ }
63
+ ```
64
+
65
+ ---
66
+
67
+ ## API
68
+
69
+ ### `MaterialColor.Create()`
70
+
71
+ Generate a full set of Material Design 3 color tokens for light and dark schemes.
72
+
73
+ ```ts
74
+ import { Hct, TonalPalette } from "@material/material-color-utilities"
75
+ import { MaterialColor } from "@sandlada/mcu-helper"
76
+
77
+ const theme = MaterialColor.Create({
78
+ sourceColor: Hct.fromInt(0xff6750a4),
79
+ contrast: 0, // (optional) MaterialContrastLevel, default: 0
80
+ variant: "tonal_spot", // (optional) MaterialVariant, default: TONAL_SPOT
81
+ platform: "phone", // (optional) Platform, default: "phone"
82
+ specVersion: "2025", // (optional) "2021" | "2025", default: "2025"
83
+ palettes: {}, // (optional) override specific tonal palettes
84
+ whiteList: [], // (optional) only include these tokens
85
+ blackList: [], // (optional) exclude these tokens
86
+ })
87
+ ```
88
+
89
+ **Returns** `Theme`:
90
+
91
+ | Property | Description |
92
+ | ------------- | ---------------------------------------------------------------------------------- |
93
+ | `light` | Light scheme colors with HCT, name, and kebab-case |
94
+ | `dark` | Dark scheme colors with HCT, name, and kebab-case |
95
+ | `lightObject` | Light scheme colors as `{ "token-name": ARGB }` |
96
+ | `darkObject` | Dark scheme colors as `{ "token-name": ARGB }` |
97
+ | `palettes` | Six tonal palettes (primary, secondary, tertiary, error, neutral, neutral-variant) |
98
+
99
+ #### Whitelist / Blacklist
100
+
101
+ Filter which tokens to include:
102
+
103
+ ```ts
104
+ const theme = MaterialColor.Create({
105
+ sourceColor: Hct.fromInt(0xff6750a4),
106
+ whiteList: ["primary", "on-primary", "primary-container"],
107
+ // — or —
108
+ blackList: ["surface-container-low", "surface-container-high"],
109
+ })
110
+ ```
111
+
112
+ > `whiteList` and `blackList` are **mutually exclusive** — passing both throws an error.
113
+
114
+ ---
115
+
116
+ ### `MaterialColor` — Type Exports
117
+
118
+ The library also exports the type union of all available color token names:
119
+
120
+ ```ts
121
+ import type { MaterialColorKebabCaseName } from "@sandlada/mcu-helper"
122
+
123
+ // e.g. "primary" | "on-primary" | "primary-container" | ... (60+ tokens)
124
+ ```
125
+
126
+ ---
127
+
128
+ ### `MaterialPalette.Create()`
129
+
130
+ Generate tone–color pairs from a tonal palette.
131
+
132
+ ```ts
133
+ import { Hct } from "@material/material-color-utilities"
134
+ import { MaterialColor, MaterialPalette } from "@sandlada/mcu-helper"
135
+
136
+ const theme = MaterialColor.Create({ sourceColor: Hct.fromInt(0xff6750a4) })
137
+
138
+ // All 101 tones (0–100)
139
+ const allTones = MaterialPalette.Create({
140
+ palette: theme.palettes.primaryPalette,
141
+ })
142
+
143
+ // Specific tones
144
+ const specificTones = MaterialPalette.Create({
145
+ palette: theme.palettes.secondaryPalette,
146
+ tones: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
147
+ })
148
+ ```
149
+
150
+ **Returns**: `{ tone: number, color: number }[]`
151
+
152
+ ---
153
+
154
+ ### `Serialization.ToCSS()`
155
+
156
+ Serialize theme colors and tonal palettes into CSS custom properties.
157
+
158
+ ```ts
159
+ import { Serialization } from "@sandlada/mcu-helper"
160
+
161
+ const css = Serialization.ToCSS({
162
+ lightObject: theme.lightObject,
163
+ darkObject: theme.darkObject,
164
+ includeTheme: true, // (optional) include theme tokens, default: true
165
+ palettes: theme.palettes, // (optional) include tonal palette tokens
166
+ paletteWhiteList: [{ family: "primary", tone: 40 }], // (optional) filter palette entries
167
+ paletteBlackList: [], // (optional) exclude palette entries
168
+ paletteTones: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], // (optional) palette tones
169
+ varPrefix: "md-sys-color", // (optional) custom CSS variable prefix, default: "md-sys-color"
170
+ customPaletteName: "my-brand", // (optional) emit palette with a custom name
171
+ isCustomPalette: false, // (optional) use custom palette prefix format
172
+ })
173
+ ```
174
+
175
+ Theme tokens use `light-dark()` so they work in both light and dark mode automatically.
176
+
177
+ #### Palette CSS output
178
+
179
+ ```ts
180
+ const css = Serialization.ToCSS({
181
+ lightObject: theme.lightObject,
182
+ darkObject: theme.darkObject,
183
+ palettes: theme.palettes,
184
+ paletteTones: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
185
+ })
186
+ ```
187
+
188
+ Produces:
189
+
190
+ ```css
191
+ :root {
192
+ --md-sys-color-background: light-dark(#f8fdff, #101416);
193
+ /* ... theme tokens ... */
194
+ --md-sys-ref-primary-0: #000000;
195
+ --md-sys-ref-primary-10: #21005e;
196
+ --md-sys-ref-primary-20: #381e72;
197
+ --md-sys-ref-primary-30: #4f378b;
198
+ --md-sys-ref-primary-40: #6750a4;
199
+ --md-sys-ref-primary-50: #7f67be;
200
+ /* ... more palette tones ... */
201
+ }
202
+ ```
203
+
204
+ #### Custom prefix example
205
+
206
+ ```ts
207
+ const css = Serialization.ToCSS({
208
+ lightObject: theme.lightObject,
209
+ darkObject: theme.darkObject,
210
+ varPrefix: "my-custom",
211
+ })
212
+ // → --my-custom-background: light-dark(...)
213
+ ```
214
+
215
+ #### Custom palette example
216
+
217
+ ```ts
218
+ const css = Serialization.ToCSS({
219
+ lightObject: theme.lightObject,
220
+ darkObject: theme.darkObject,
221
+ palettes: theme.palettes,
222
+ customPaletteName: "brand-primary",
223
+ isCustomPalette: true,
224
+ })
225
+ // → --brand-primary-40: #6750a4;
226
+ ```
227
+
228
+ ---
229
+
230
+ ### `MaterialVariant`
231
+
232
+ The available Material Design variant options:
233
+
234
+ ```ts
235
+ import { MaterialVariant } from "@sandlada/mcu-helper"
236
+
237
+ // MaterialVariant.Monochrome
238
+ // MaterialVariant.Neutral
239
+ // MaterialVariant.TonalSpot (default)
240
+ // MaterialVariant.Vibrant
241
+ // MaterialVariant.Expressive
242
+ // MaterialVariant.Fidelity
243
+ // MaterialVariant.Content
244
+ // MaterialVariant.Rainbow
245
+ // MaterialVariant.FruitSalad
246
+ ```
247
+
248
+ ---
249
+
250
+ ### `MaterialContrastLevel`
251
+
252
+ ```ts
253
+ import { MaterialContrastLevel } from "@sandlada/mcu-helper"
254
+
255
+ // MaterialContrastLevel.Reduced → -1.0
256
+ // MaterialContrastLevel.Default → 0 (default)
257
+ // MaterialContrastLevel.Medium → 0.5
258
+ // MaterialContrastLevel.High → 1.0
259
+ ```
260
+
261
+ ---
262
+
263
+ ### `MaterialColors`
264
+
265
+ A utility class that wraps `MaterialDynamicColors` from `@material/material-color-utilities`:
266
+
267
+ ```ts
268
+ import { MaterialColors } from "@sandlada/mcu-helper"
269
+
270
+ const allColorDefs = MaterialColors.ToRecord()
271
+ // → { primary: DynamicColor, onPrimary: DynamicColor, ... }
272
+ ```
273
+
274
+ ---
275
+
276
+ ### `StringUtil`
277
+
278
+ String case conversion utilities:
279
+
280
+ ```ts
281
+ import { StringUtil } from "@sandlada/mcu-helper"
282
+
283
+ StringUtil.ToKebabCase("primaryContainer") // → "primary-container"
284
+ StringUtil.ToSnakeCase("primaryContainer") // → "primary_container"
285
+ StringUtil.ToPascalCase("primary-container") // → "PrimaryContainer"
286
+ ```
287
+
288
+ ---
289
+
290
+ ## Recipes
291
+
292
+ ### Generate and save CSS to a file
293
+
294
+ ```ts
295
+ import { Hct } from "@material/material-color-utilities"
296
+ import { MaterialColor, Serialization } from "@sandlada/mcu-helper"
297
+ import { writeFileSync } from "node:fs"
298
+
299
+ const sourceColor = Hct.fromInt(0xff6750a4)
300
+ const theme = MaterialColor.Create({ sourceColor })
301
+
302
+ const css = Serialization.ToCSS({
303
+ lightObject: theme.lightObject,
304
+ darkObject: theme.darkObject,
305
+ palettes: theme.palettes,
306
+ paletteTones: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
307
+ })
308
+
309
+ writeFileSync("tokens.css", css, "utf-8")
310
+ ```
311
+
312
+ ### Include only specific tokens
313
+
314
+ ```ts
315
+ const theme = MaterialColor.Create({
316
+ sourceColor: Hct.fromInt(0xff6750a4),
317
+ whiteList: [
318
+ "primary",
319
+ "on-primary",
320
+ "primary-container",
321
+ "on-primary-container",
322
+ "secondary",
323
+ "on-secondary",
324
+ "surface",
325
+ "on-surface",
326
+ "background",
327
+ "on-background",
328
+ "error",
329
+ "on-error",
330
+ ],
331
+ })
332
+ ```
333
+
334
+ ### Use a custom variant with high contrast
335
+
336
+ ```ts
337
+ const theme = MaterialColor.Create({
338
+ sourceColor: Hct.fromInt(0xff006b3e),
339
+ variant: MaterialVariant.Vibrant,
340
+ contrast: MaterialContrastLevel.High,
341
+ })
342
+ ```
343
+
344
+ ---
345
+
346
+ ## Development
347
+
348
+ ```bash
349
+ # Install dependencies
350
+ npm install
351
+
352
+ # Run tests
353
+ npm test
354
+
355
+ # Watch mode
356
+ npm run test:watch
357
+
358
+ # Build
359
+ npm run compile
360
+ ```
361
+
362
+ ---
363
+
364
+ ## License
365
+
366
+ [MIT](./LICENSE)
@@ -0,0 +1,51 @@
1
+ import { type Hct, type Platform, type TonalPalette } from "@material/material-color-utilities";
2
+ import type { MaterialContrastLevel } from "../material/material-contrast-level";
3
+ import type { MaterialVariant } from "../material/material-variant";
4
+ export type MaterialColorKebabCaseName = 'primary-palette-key-color' | 'secondary-palette-key-color' | 'tertiary-palette-key-color' | 'neutral-palette-key-color' | 'neutral-variant-palette-key-color' | 'error-palette-key-color' | 'background' | 'on-background' | 'surface' | 'surface-dim' | 'surface-bright' | 'surface-container-lowest' | 'surface-container-low' | 'surface-container' | 'surface-container-high' | 'surface-container-highest' | 'on-surface' | 'surface-variant' | 'on-surface-variant' | 'inverse-surface' | 'inverse-on-surface' | 'outline' | 'outline-variant' | 'shadow' | 'scrim' | 'surface-tint' | 'primary' | 'primary-dim' | 'on-primary' | 'primary-container' | 'on-primary-container' | 'primary-fixed' | 'primary-fixed-dim' | 'on-primary-fixed' | 'on-primary-fixed-variant' | 'inverse-primary' | 'secondary' | 'secondary-dim' | 'on-secondary' | 'secondary-container' | 'on-secondary-container' | 'secondary-fixed' | 'secondary-fixed-dim' | 'on-secondary-fixed' | 'on-secondary-fixed-variant' | 'tertiary' | 'tertiary-dim' | 'on-tertiary' | 'tertiary-container' | 'on-tertiary-container' | 'tertiary-fixed' | 'tertiary-fixed-dim' | 'on-tertiary-fixed' | 'on-tertiary-fixed-variant' | 'error' | 'error-dim' | 'on-error' | 'error-container' | 'on-error-container';
5
+ declare const SchemePaletteNameArray: readonly ["primaryPalette", "secondaryPalette", "tertiaryPalette", "errorPalette", "neutralPalette", "neutralVariantPalette"];
6
+ type SchemePaletteName = (typeof SchemePaletteNameArray)[number];
7
+ type CustomizedTonalPalette = {
8
+ name: string;
9
+ kebabCasedName: string;
10
+ snakeCaseName: string;
11
+ hue: number;
12
+ chroma: number;
13
+ keyColor: Hct;
14
+ tone(tone: number): number;
15
+ getHct(tone: number): Hct;
16
+ };
17
+ type ThemePalettes = Partial<Record<SchemePaletteName, CustomizedTonalPalette>>;
18
+ type CustomizedColor = {
19
+ name: string;
20
+ kebabCasedName: string;
21
+ snakeCaseName: string;
22
+ hct: Hct;
23
+ palette: TonalPalette;
24
+ };
25
+ interface Theme {
26
+ light: CustomizedColor[];
27
+ dark: CustomizedColor[];
28
+ palettes: ThemePalettes;
29
+ lightObject: Record<string, number>;
30
+ darkObject: Record<string, number>;
31
+ }
32
+ export declare class MaterialColor {
33
+ private constructor();
34
+ static Create(args: {
35
+ sourceColor: Hct;
36
+ contrast?: MaterialContrastLevel;
37
+ variant?: MaterialVariant;
38
+ platform?: Platform;
39
+ specVersion?: "2021" | "2025";
40
+ palettes?: Partial<Record<SchemePaletteName, TonalPalette>>;
41
+ whiteList?: MaterialColorKebabCaseName[];
42
+ blackList?: MaterialColorKebabCaseName[];
43
+ }): Theme;
44
+ private static normalizeNames;
45
+ private static createAvailableNameSet;
46
+ private static warnForUnknownNames;
47
+ private static filterCustomizedColors;
48
+ private static createTemplateDarkScheme;
49
+ private static createTemplateLightScheme;
50
+ }
51
+ export {};
@@ -0,0 +1,2 @@
1
+ import{StringUtil as e}from"../utils/string-util.js";import{DynamicScheme as t,Variant as n}from"@material/material-color-utilities";var r=class{constructor(){}static Create(t){let{blackList:r,contrast:i=1,palettes:a={},platform:o=`phone`,sourceColor:s,specVersion:c=`2025`,variant:l=n.TONAL_SPOT,whiteList:u}=t,d=this.normalizeNames(u),f=this.normalizeNames(r);if(d.size>0&&f.size>0)throw Error(`MaterialColor.Create: whiteList and blackList are mutually exclusive.`);let p=this.createTemplateLightScheme(s,i,l,o,c,a),m=this.createTemplateDarkScheme(s,i,l,o,c,a),h=t=>[...t.colors.allColors,t.colors.scrim(),t.colors.shadow(),t.colors.surfaceTint(),t.colors.surfaceVariant(),t.colors.primaryPaletteKeyColor(),t.colors.secondaryPaletteKeyColor(),t.colors.tertiaryPaletteKeyColor(),t.colors.errorPaletteKeyColor(),t.colors.neutralPaletteKeyColor(),t.colors.neutralVariantPaletteKeyColor()].map(n=>({name:n.name,snakeCaseName:e.ToSnakeCase(n.name),kebabCasedName:e.ToKebabCase(n.name),hct:n.getHct(t),palette:n.palette(t)})).sort((e,t)=>e.name.localeCompare(t.name)),g=(t,n)=>({name:t,snakeCaseName:e.ToSnakeCase(t),kebabCasedName:e.ToKebabCase(t),getHct:e=>n.getHct(e),tone:e=>n.tone(e),keyColor:n.keyColor,hue:n.hue,chroma:n.chroma}),_={light:h(p),dark:h(m),palettes:{primaryPalette:g(`primaryPalette`,p.primaryPalette),secondaryPalette:g(`secondaryPalette`,p.secondaryPalette),tertiaryPalette:g(`tertiaryPalette`,p.tertiaryPalette),errorPalette:g(`errorPalette`,p.errorPalette),neutralPalette:g(`neutralPalette`,p.neutralPalette),neutralVariantPalette:g(`neutralVariantPalette`,p.neutralVariantPalette)},lightObject:{},darkObject:{}},v=this.createAvailableNameSet(_);this.warnForUnknownNames(d,v,`whiteList`),this.warnForUnknownNames(f,v,`blackList`);let y=this.filterCustomizedColors(_.light,d,f),b=this.filterCustomizedColors(_.dark,d,f);return{light:y,dark:b,lightObject:Object.fromEntries(y.map(e=>[e.kebabCasedName,e.hct.toInt()])),darkObject:Object.fromEntries(b.map(e=>[e.kebabCasedName,e.hct.toInt()])),palettes:_.palettes}}static normalizeNames(t){return new Set((t??[]).map(t=>e.ToKebabCase(t)).filter(e=>e.length>0))}static createAvailableNameSet(t){return new Set([...t.light.map(t=>e.ToKebabCase(t.name)),...t.dark.map(t=>e.ToKebabCase(t.name)),...Object.keys(t.palettes).map(t=>e.ToKebabCase(t))])}static warnForUnknownNames(e,t,n){let r=[...e].filter(e=>!t.has(e));r.length>0&&console.warn(`MaterialColor.Create: unknown ${n} names ignored: ${r.join(`, `)}`)}static filterCustomizedColors(t,n,r){return n.size>0?t.filter(t=>n.has(e.ToKebabCase(t.name))):r.size>0?t.filter(t=>!r.has(e.ToKebabCase(t.name))):t}static createTemplateDarkScheme(e,n,r,i,a,o){return new t({sourceColorHct:e,contrastLevel:n,variant:r,isDark:!0,specVersion:a,platform:i,...o.primaryPalette?{primaryPalette:o.primaryPalette}:{},...o.secondaryPalette?{secondaryPalette:o.secondaryPalette}:{},...o.tertiaryPalette?{tertiaryPalette:o.tertiaryPalette}:{},...o.errorPalette?{errorPalette:o.errorPalette}:{},...o.neutralPalette?{neutralPalette:o.neutralPalette}:{},...o.neutralVariantPalette?{neutralVariantPalette:o.neutralVariantPalette}:{}})}static createTemplateLightScheme(e,n,r,i,a,o){return new t({sourceColorHct:e,contrastLevel:n,variant:r,isDark:!1,specVersion:a,platform:i,...o.primaryPalette?{primaryPalette:o.primaryPalette}:{},...o.secondaryPalette?{secondaryPalette:o.secondaryPalette}:{},...o.tertiaryPalette?{tertiaryPalette:o.tertiaryPalette}:{},...o.errorPalette?{errorPalette:o.errorPalette}:{},...o.neutralPalette?{neutralPalette:o.neutralPalette}:{},...o.neutralVariantPalette?{neutralVariantPalette:o.neutralVariantPalette}:{}})}};export{r as MaterialColor};
2
+ //# sourceMappingURL=material-color.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"material-color.service.js","names":[],"sources":["../../src/generators/material-color.service.ts"],"sourcesContent":["import { DynamicScheme, Variant, type Hct, type Platform, type TonalPalette } from \"@material/material-color-utilities\"\nimport type { MaterialContrastLevel } from \"../material/material-contrast-level\"\nimport type { MaterialVariant } from \"../material/material-variant\"\nimport { StringUtil } from \"../utils/string-util\"\n\nexport type MaterialColorKebabCaseName\n= 'primary-palette-key-color'\n| 'secondary-palette-key-color'\n| 'tertiary-palette-key-color'\n| 'neutral-palette-key-color'\n| 'neutral-variant-palette-key-color'\n| 'error-palette-key-color'\n| 'background'\n| 'on-background'\n| 'surface'\n| 'surface-dim'\n| 'surface-bright'\n| 'surface-container-lowest'\n| 'surface-container-low'\n| 'surface-container'\n| 'surface-container-high'\n| 'surface-container-highest'\n| 'on-surface'\n| 'surface-variant'\n| 'on-surface-variant'\n| 'inverse-surface'\n| 'inverse-on-surface'\n| 'outline'\n| 'outline-variant'\n| 'shadow'\n| 'scrim'\n| 'surface-tint'\n| 'primary'\n| 'primary-dim'\n| 'on-primary'\n| 'primary-container'\n| 'on-primary-container'\n| 'primary-fixed'\n| 'primary-fixed-dim'\n| 'on-primary-fixed'\n| 'on-primary-fixed-variant'\n| 'inverse-primary'\n| 'secondary'\n| 'secondary-dim'\n| 'on-secondary'\n| 'secondary-container'\n| 'on-secondary-container'\n| 'secondary-fixed'\n| 'secondary-fixed-dim'\n| 'on-secondary-fixed'\n| 'on-secondary-fixed-variant'\n| 'tertiary'\n| 'tertiary-dim'\n| 'on-tertiary'\n| 'tertiary-container'\n| 'on-tertiary-container'\n| 'tertiary-fixed'\n| 'tertiary-fixed-dim'\n| 'on-tertiary-fixed'\n| 'on-tertiary-fixed-variant'\n| 'error'\n| 'error-dim'\n| 'on-error'\n| 'error-container'\n| 'on-error-container'\n\nconst SchemePaletteNameArray = [\n \"primaryPalette\",\n \"secondaryPalette\",\n \"tertiaryPalette\",\n \"errorPalette\",\n \"neutralPalette\",\n \"neutralVariantPalette\",\n] as const\ntype SchemePaletteName = (typeof SchemePaletteNameArray)[number]\n\ntype CustomizedTonalPalette = {\n name : string\n kebabCasedName : string\n snakeCaseName : string\n hue : number\n chroma : number\n keyColor : Hct\n tone(tone: number) : number\n getHct(tone: number): Hct\n}\ntype ThemePalettes = Partial<Record<SchemePaletteName, CustomizedTonalPalette>>\ntype CustomizedColor = {\n name : string\n kebabCasedName: string\n snakeCaseName : string\n hct : Hct\n palette : TonalPalette\n};\n\ninterface Theme {\n light : CustomizedColor[]\n dark : CustomizedColor[]\n palettes : ThemePalettes\n lightObject: Record<string, number>\n darkObject : Record<string, number>\n}\n\nexport class MaterialColor {\n private constructor() { }\n\n public static Create(args: {\n sourceColor : Hct\n contrast ?: MaterialContrastLevel\n variant ?: MaterialVariant\n platform ?: Platform\n specVersion?: \"2021\" | \"2025\"\n palettes ?: Partial<Record<SchemePaletteName, TonalPalette>>\n whiteList ?: MaterialColorKebabCaseName[]\n blackList ?: MaterialColorKebabCaseName[]\n }): Theme {\n const { blackList, contrast = 1, palettes = {}, platform = \"phone\", sourceColor, specVersion = \"2025\", variant = Variant.TONAL_SPOT, whiteList } = args\n const normalizedWhiteList = this.normalizeNames(whiteList)\n const normalizedBlackList = this.normalizeNames(blackList)\n\n if (normalizedWhiteList.size > 0 && normalizedBlackList.size > 0) throw new Error(\"MaterialColor.Create: whiteList and blackList are mutually exclusive.\");\n\n const lightScheme = this.createTemplateLightScheme(sourceColor, contrast, variant, platform, specVersion, palettes)\n const darkScheme = this.createTemplateDarkScheme(sourceColor, contrast, variant, platform, specVersion, palettes)\n\n const toCustomizedMaterialDynamicColors = (scheme: DynamicScheme): CustomizedColor[] => [\n ...scheme.colors.allColors,\n // allColors missed these tokens\n scheme.colors.scrim(),\n scheme.colors.shadow(),\n scheme.colors.surfaceTint(),\n scheme.colors.surfaceVariant(),\n scheme.colors.primaryPaletteKeyColor(),\n scheme.colors.secondaryPaletteKeyColor(),\n scheme.colors.tertiaryPaletteKeyColor(),\n scheme.colors.errorPaletteKeyColor(),\n scheme.colors.neutralPaletteKeyColor(),\n scheme.colors.neutralVariantPaletteKeyColor(),\n ].map((color) => ({\n name : color.name,\n snakeCaseName : StringUtil.ToSnakeCase(color.name),\n kebabCasedName: StringUtil.ToKebabCase(color.name),\n hct : color.getHct(scheme),\n palette : color.palette(scheme),\n })).sort((a, b) => a.name.localeCompare(b.name));\n\n const toCustomizedMaterialTonalPalette = (name: string, palette: TonalPalette): CustomizedTonalPalette => ({\n name : name,\n snakeCaseName : StringUtil.ToSnakeCase(name),\n kebabCasedName: StringUtil.ToKebabCase(name),\n getHct : (tone: number) => palette.getHct(tone),\n tone : (tone: number) => palette.tone(tone),\n keyColor : palette.keyColor,\n hue : palette.hue,\n chroma : palette.chroma\n })\n\n const theme: Theme = {\n light : toCustomizedMaterialDynamicColors(lightScheme),\n dark : toCustomizedMaterialDynamicColors(darkScheme),\n palettes: {\n primaryPalette : toCustomizedMaterialTonalPalette(\"primaryPalette\", lightScheme.primaryPalette),\n secondaryPalette : toCustomizedMaterialTonalPalette(\"secondaryPalette\", lightScheme.secondaryPalette),\n tertiaryPalette : toCustomizedMaterialTonalPalette(\"tertiaryPalette\", lightScheme.tertiaryPalette),\n errorPalette : toCustomizedMaterialTonalPalette(\"errorPalette\", lightScheme.errorPalette),\n neutralPalette : toCustomizedMaterialTonalPalette(\"neutralPalette\", lightScheme.neutralPalette),\n neutralVariantPalette: toCustomizedMaterialTonalPalette(\"neutralVariantPalette\", lightScheme.neutralVariantPalette),\n } as ThemePalettes,\n lightObject: {},\n darkObject : {},\n };\n\n const availableNames = this.createAvailableNameSet(theme);\n this.warnForUnknownNames(normalizedWhiteList, availableNames, \"whiteList\");\n this.warnForUnknownNames(normalizedBlackList, availableNames, \"blackList\");\n\n const light = this.filterCustomizedColors(theme.light, normalizedWhiteList, normalizedBlackList)\n const dark = this.filterCustomizedColors(theme.dark, normalizedWhiteList, normalizedBlackList)\n return {\n light,\n dark,\n lightObject: Object.fromEntries(light.map((color) => [color.kebabCasedName, color.hct.toInt()])),\n darkObject: Object.fromEntries(dark.map((color) => [color.kebabCasedName, color.hct.toInt()])),\n palettes: theme.palettes,\n };\n }\n\n private static normalizeNames(names?: string[]): Set<string> {\n return new Set((names ?? []).map((name) => StringUtil.ToKebabCase(name)).filter((name) => name.length > 0));\n }\n\n private static createAvailableNameSet(theme: Theme): Set<string> {\n return new Set([\n ...theme.light.map((color) => StringUtil.ToKebabCase(color.name)),\n ...theme.dark.map((color) => StringUtil.ToKebabCase(color.name)),\n ...Object.keys(theme.palettes).map((name) => StringUtil.ToKebabCase(name)),\n ]);\n }\n\n private static warnForUnknownNames(names: Set<string>, availableNames: Set<string>, label: \"whiteList\" | \"blackList\") {\n const unknownNames = [...names].filter((name) => !availableNames.has(name))\n\n if (unknownNames.length > 0) {\n console.warn(`MaterialColor.Create: unknown ${label} names ignored: ${unknownNames.join(\", \")}`)\n }\n }\n\n private static filterCustomizedColors(colors: CustomizedColor[], whiteList: Set<string>, blackList: Set<string>): CustomizedColor[] {\n if (whiteList.size > 0) {\n return colors.filter((color) => whiteList.has(StringUtil.ToKebabCase(color.name)))\n }\n\n if (blackList.size > 0) {\n return colors.filter((color) => !blackList.has(StringUtil.ToKebabCase(color.name)))\n }\n\n return colors\n }\n\n private static createTemplateDarkScheme(\n sourceColor: Hct,\n contrast : MaterialContrastLevel,\n variant : MaterialVariant,\n platform : Platform,\n specVersion: \"2021\" | \"2025\",\n palettes : Partial<Record<SchemePaletteName, TonalPalette>>,\n ) {\n return new DynamicScheme({\n sourceColorHct: sourceColor,\n contrastLevel: contrast,\n variant,\n isDark: true,\n specVersion,\n platform,\n ...(palettes.primaryPalette ? { primaryPalette: palettes.primaryPalette } : {}),\n ...(palettes.secondaryPalette ? { secondaryPalette: palettes.secondaryPalette } : {}),\n ...(palettes.tertiaryPalette ? { tertiaryPalette: palettes.tertiaryPalette } : {}),\n ...(palettes.errorPalette ? { errorPalette: palettes.errorPalette } : {}),\n ...(palettes.neutralPalette ? { neutralPalette: palettes.neutralPalette } : {}),\n ...(palettes.neutralVariantPalette ? { neutralVariantPalette: palettes.neutralVariantPalette } : {}),\n })\n }\n\n private static createTemplateLightScheme(\n sourceColor: Hct,\n contrast : MaterialContrastLevel,\n variant : MaterialVariant,\n platform : Platform,\n specVersion: \"2021\" | \"2025\",\n palettes : Partial<Record<SchemePaletteName, TonalPalette>>,\n ) {\n return new DynamicScheme({\n sourceColorHct: sourceColor,\n contrastLevel: contrast,\n variant,\n isDark: false,\n specVersion,\n platform,\n ...(palettes.primaryPalette ? { primaryPalette: palettes.primaryPalette } : {}),\n ...(palettes.secondaryPalette ? { secondaryPalette: palettes.secondaryPalette } : {}),\n ...(palettes.tertiaryPalette ? { tertiaryPalette: palettes.tertiaryPalette } : {}),\n ...(palettes.errorPalette ? { errorPalette: palettes.errorPalette } : {}),\n ...(palettes.neutralPalette ? { neutralPalette: palettes.neutralPalette } : {}),\n ...(palettes.neutralVariantPalette ? { neutralVariantPalette: palettes.neutralVariantPalette } : {}),\n })\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { TonalPalette } from "@material/material-color-utilities";
2
+ export declare const DefaultPaletteTones: number[];
3
+ export declare class MaterialPalette {
4
+ private constructor();
5
+ /**
6
+ * @output
7
+ * [{tone: number, color: argb_number}]
8
+ */
9
+ static Create(args: {
10
+ palette: Pick<TonalPalette, "tone">;
11
+ tones?: number[];
12
+ }): {
13
+ tone: number;
14
+ color: number;
15
+ }[];
16
+ private static normalizeTones;
17
+ private static normalizeTone;
18
+ }
@@ -0,0 +1,2 @@
1
+ const e=Array.from({length:101},(e,t)=>t);var t=class{constructor(){}static Create(e){let{palette:t}=e;return this.normalizeTones(e.tones).map(e=>({tone:e,color:t.tone(e)}))}static normalizeTones(t){if(t===void 0)return[...e];if(t.length===0)throw TypeError(`MaterialPalette.Create: tones cannot be empty.`);return[...new Set(t.map(e=>this.normalizeTone(e)))].sort((e,t)=>e-t)}static normalizeTone(e){if(!Number.isFinite(e)||!Number.isInteger(e)||e<0||e>100)throw TypeError(`MaterialPalette.Create: tones must be integers between 0 and 100.`);return e}};export{e as DefaultPaletteTones,t as MaterialPalette};
2
+ //# sourceMappingURL=material-palette.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"material-palette.service.js","names":[],"sources":["../../src/generators/material-palette.service.ts"],"sourcesContent":["import type { TonalPalette } from \"@material/material-color-utilities\"\n\nexport const DefaultPaletteTones = Array.from({ length: 101 }, (_, tone) => tone);\n\nexport class MaterialPalette {\n private constructor() { }\n\n /**\n * @output\n * [{tone: number, color: argb_number}]\n */\n public static Create(args: { palette: Pick<TonalPalette, \"tone\">; tones?: number[] }) {\n const { palette } = args;\n const tones = this.normalizeTones(args.tones);\n\n return tones.map((tone) => ({\n tone,\n color: palette.tone(tone),\n }));\n }\n\n\n private static normalizeTones(tones?: number[]) {\n if (tones === undefined) {\n return [...DefaultPaletteTones];\n }\n\n if (tones.length === 0) {\n throw new TypeError(\"MaterialPalette.Create: tones cannot be empty.\");\n }\n\n const normalizedTones = [...new Set(tones.map((tone) => this.normalizeTone(tone)))];\n\n return normalizedTones.sort((left, right) => left - right);\n }\n\n private static normalizeTone(tone: number) {\n if (!Number.isFinite(tone) || !Number.isInteger(tone) || tone < 0 || tone > 100) {\n throw new TypeError(\"MaterialPalette.Create: tones must be integers between 0 and 100.\");\n }\n\n return tone;\n }\n}\n"],"mappings":"AAEA,MAAa,EAAsB,MAAM,KAAK,CAAE,OAAQ,GAAI,GAAI,EAAG,IAAS,CAAI,EAEhF,IAAa,EAAb,KAA6B,CACzB,aAAsB,CAAE,CAMxB,OAAc,OAAO,EAAiE,CAClF,GAAM,CAAE,WAAY,EAGpB,OAFc,KAAK,eAAe,EAAK,KAE5B,CAAC,CAAC,IAAK,IAAU,CACxB,OACA,MAAO,EAAQ,KAAK,CAAI,CAC5B,EAAE,CACN,CAGA,OAAe,eAAe,EAAkB,CAC5C,GAAI,IAAU,IAAA,GACV,MAAO,CAAC,GAAG,CAAmB,EAGlC,GAAI,EAAM,SAAW,EACjB,MAAU,UAAU,gDAAgD,EAKxE,MAAO,CAFkB,GAAG,IAAI,IAAI,EAAM,IAAK,GAAS,KAAK,cAAc,CAAI,CAAC,CAAC,CAE5D,CAAC,CAAC,MAAM,EAAM,IAAU,EAAO,CAAK,CAC7D,CAEA,OAAe,cAAc,EAAc,CACvC,GAAI,CAAC,OAAO,SAAS,CAAI,GAAK,CAAC,OAAO,UAAU,CAAI,GAAK,EAAO,GAAK,EAAO,IACxE,MAAU,UAAU,mEAAmE,EAG3F,OAAO,CACX,CACJ"}
@@ -0,0 +1,39 @@
1
+ import { type TonalPalette } from "@material/material-color-utilities";
2
+ type ThemeObject = Record<string, unknown>;
3
+ type ThemePaletteName = "primaryPalette" | "secondaryPalette" | "tertiaryPalette" | "errorPalette" | "neutralPalette" | "neutralVariantPalette";
4
+ export type PaletteSelectorFamilyName = "primary" | "secondary" | "tertiary" | "error" | "neutral" | "neutral-variant";
5
+ export type PaletteSelector = {
6
+ family: PaletteSelectorFamilyName;
7
+ tone?: number;
8
+ };
9
+ type ThemePalettes = Partial<Record<ThemePaletteName, Pick<TonalPalette, "tone">>>;
10
+ export declare class Serialization {
11
+ private constructor();
12
+ static ToCSS(args: {
13
+ lightObject: ThemeObject;
14
+ darkObject: ThemeObject;
15
+ includeTheme?: boolean;
16
+ palettes?: ThemePalettes;
17
+ paletteWhiteList?: PaletteSelector[];
18
+ paletteBlackList?: PaletteSelector[];
19
+ paletteTones?: number[];
20
+ varPrefix?: string;
21
+ customPaletteName?: string;
22
+ isCustomPalette?: boolean;
23
+ }): string;
24
+ private static normalizeThemeEntries;
25
+ private static normalizePaletteEntries;
26
+ private static normalizePaletteSelectors;
27
+ private static normalizePaletteSelector;
28
+ private static normalizePaletteSelectorFamily;
29
+ private static matchesPaletteSelector;
30
+ private static normalizePaletteTones;
31
+ private static normalizePaletteTone;
32
+ private static normalizeThemeObject;
33
+ private static toPaletteTokenName;
34
+ private static toColorValue;
35
+ private static isPlainObject;
36
+ private static buildKeyMismatchMessage;
37
+ private static toCss;
38
+ }
39
+ export {};
@@ -0,0 +1,7 @@
1
+ import{StringUtil as e}from"../utils/string-util.js";import{DefaultPaletteTones as t,MaterialPalette as n}from"./material-palette.service.js";import{hexFromArgb as r}from"@material/material-color-utilities";function i(e,t){if(e===void 0||e.length===0)return{theme:{css:`--md-sys-color-`},palette:{css:`--md-sys-ref-`}};let n=e.replace(/^-+/u,``).replace(/-+$/u,``),r=`--${n.length>0?`${n}-`:``}`;return t?{theme:{css:`${r}color-`},palette:{css:r}}:{theme:{css:r},palette:{css:r}}}const a=[`primaryPalette`,`secondaryPalette`,`tertiaryPalette`,`errorPalette`,`neutralPalette`,`neutralVariantPalette`];var o=class{constructor(){}static ToCSS(e){let t=e.includeTheme!==!1,n=i(e.varPrefix,e.isCustomPalette),r=this.normalizeThemeEntries(e.lightObject,e.darkObject,n),a=this.normalizePaletteEntries(e.palettes,e.paletteTones,e.paletteWhiteList,e.paletteBlackList,n,e.customPaletteName);return this.toCss(r,a,t)}static normalizeThemeEntries(e,t,n){let r=this.normalizeThemeObject(e,`lightObject`),i=this.normalizeThemeObject(t,`darkObject`);if(r.size!==i.size)throw TypeError(this.buildKeyMismatchMessage(r,i));let a=[...r.keys()],o=new Set(i.keys()),s=a.filter(e=>!o.has(e)),c=[...i.keys()].filter(e=>!r.has(e));if(s.length>0||c.length>0)throw TypeError(this.buildKeyMismatchMessage(r,i));return a.map(e=>{let t=r.get(e),a=i.get(e);return{normalizedKey:e,cssKey:`${n.theme.css}${e}`,lightValue:t,darkValue:a}})}static normalizePaletteEntries(e,t,o,s,c,l){if(e===void 0)return[];let u=this.normalizePaletteTones(t),d=this.normalizePaletteSelectors(o),f=this.normalizePaletteSelectors(s),p=[],m=c??i();for(let t of a){let i=e[t];if(i===void 0)continue;let a=this.toPaletteTokenName(t);for(let e of n.Create({palette:i,tones:u})){if(d!==void 0&&l===void 0&&!d.some(t=>this.matchesPaletteSelector(t,a,e.tone))||f!==void 0&&l===void 0&&f.some(t=>this.matchesPaletteSelector(t,a,e.tone)))continue;let t=l===void 0?`${a}-${e.tone}`:`${String(e.tone)}`,n=r(e.color);p.push({normalizedKey:t,cssKey:`${m.palette.css}${t}`,value:n})}}return p}static normalizePaletteSelectors(e){if(e!==void 0&&e.length!==0)return e.map(e=>this.normalizePaletteSelector(e))}static normalizePaletteSelector(e){let t=this.normalizePaletteSelectorFamily(e.family);return e.tone===void 0?{family:t}:{family:t,tone:this.normalizePaletteTone(e.tone)}}static normalizePaletteSelectorFamily(t){let n=e.ToKebabCase(t).replace(/^palette-/u,``);if(n!==`primary`&&n!==`secondary`&&n!==`tertiary`&&n!==`error`&&n!==`neutral`&&n!==`neutral-variant`)throw TypeError(`Serialization: unsupported palette family "${t}".`);return n}static matchesPaletteSelector(e,t,n){return e.family===t&&(e.tone===void 0||e.tone===n)}static normalizePaletteTones(e){if(e===void 0)return[...t];if(e.length===0)throw TypeError(`Serialization: paletteTones cannot be empty.`);return[...new Set(e.map(e=>this.normalizePaletteTone(e)))].sort((e,t)=>e-t)}static normalizePaletteTone(e){if(!Number.isFinite(e)||!Number.isInteger(e)||e<0||e>100)throw TypeError(`Serialization: paletteTones must be integers between 0 and 100.`);return e}static normalizeThemeObject(t,n){if(!this.isPlainObject(t))throw TypeError(`Serialization: ${n} must be a plain object.`);if(Object.getOwnPropertySymbols(t).length>0)throw TypeError(`Serialization: ${n} cannot contain symbol keys.`);let r=new Map;for(let[i,a]of Object.entries(t)){let t=e.ToKebabCase(i);if(!t)throw TypeError(`Serialization: ${n} key "${i}" normalizes to an empty name.`);if(r.has(t))throw TypeError(`Serialization: duplicate normalized key "${t}".`);r.set(t,this.toColorValue(a,`${n} key "${i}"`))}return new Map([...r.entries()].sort(([e],[t])=>e.localeCompare(t)))}static toPaletteTokenName(t){return e.ToKebabCase(t.replace(/Palette$/u,``))}static toColorValue(e,t){if(typeof e==`number`){if(!Number.isFinite(e)||!Number.isInteger(e))throw TypeError(`Serialization: ${t} must be an integer ARGB color value.`);return r(e)}if(typeof e==`string`){let n=e.trim();if(n.length===0)throw TypeError(`Serialization: ${t} cannot be an empty string.`);return n}throw TypeError(`Serialization: ${t} must be a string or ARGB number.`)}static isPlainObject(e){if(typeof e!=`object`||!e||Array.isArray(e))return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}static buildKeyMismatchMessage(e,t){let n=[...e.keys()].filter(e=>!t.has(e)),r=[...t.keys()].filter(t=>!e.has(t));return`Serialization: lightObject and darkObject must contain the same normalized keys. Missing in darkObject: ${n.length>0?n.join(`, `):`none`}; missing in lightObject: ${r.length>0?r.join(`, `):`none`}.`}static toCss(e,t,n){if(n&&e.length===0&&t.length===0)return`:root {
2
+ }
3
+ `;let r=[...n?e.map(e=>` ${e.cssKey}: light-dark(${e.lightValue}, ${e.darkValue});`):[],...t.map(e=>` ${e.cssKey}: ${e.value};`)];return r.length===0?`:root {
4
+ }
5
+ `:`:root {\n${r.join(`
6
+ `)}\n}\n`}};export{o as Serialization};
7
+ //# sourceMappingURL=serialization.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialization.service.js","names":[],"sources":["../../src/generators/serialization.service.ts"],"sourcesContent":["import { hexFromArgb, type TonalPalette } from \"@material/material-color-utilities\"\nimport { StringUtil } from \"../utils/string-util\"\nimport { DefaultPaletteTones, MaterialPalette } from \"./material-palette.service\"\n\ntype ThemeObject = Record<string, unknown>;\n\ntype ThemePaletteName =\n | \"primaryPalette\"\n | \"secondaryPalette\"\n | \"tertiaryPalette\"\n | \"errorPalette\"\n | \"neutralPalette\"\n | \"neutralVariantPalette\";\n\nexport type PaletteSelectorFamilyName = \"primary\" | \"secondary\" | \"tertiary\" | \"error\" | \"neutral\" | \"neutral-variant\";\n\nexport type PaletteSelector = {\n family: PaletteSelectorFamilyName;\n tone?: number;\n};\n\ntype ThemePalettes = Partial<Record<ThemePaletteName, Pick<TonalPalette, \"tone\">>>;\n\ntype ThemeEntry = {\n normalizedKey: string;\n cssKey: string;\n lightValue: string;\n darkValue: string;\n};\n\ntype PaletteEntry = {\n normalizedKey: string;\n cssKey: string;\n value: string;\n};\n\nconst DefaultCssPrefix = \"--md-sys-color-\";\nconst DefaultCssPalettePrefix = \"--md-sys-ref-\";\n\ntype PrefixConfig = {\n theme: { css: string };\n palette: { css: string };\n};\n\nfunction resolvePrefixConfig(varPrefix?: string, isCustomPalette?: boolean): PrefixConfig {\n if (varPrefix === undefined || varPrefix.length === 0) {\n return {\n theme: { css: DefaultCssPrefix },\n palette: { css: DefaultCssPalettePrefix },\n };\n }\n\n const normalized = varPrefix.replace(/^-+/u, \"\").replace(/-+$/u, \"\");\n const prefix = normalized.length > 0 ? `${normalized}-` : \"\";\n const cssDashPrefix = `--${prefix}`;\n\n if (isCustomPalette) {\n return {\n theme: { css: `${cssDashPrefix}color-` },\n palette: { css: cssDashPrefix },\n };\n }\n\n return {\n theme: { css: cssDashPrefix },\n palette: { css: cssDashPrefix },\n };\n}\n\nconst ThemePaletteOrder: ThemePaletteName[] = [\n\t\"primaryPalette\",\n\t\"secondaryPalette\",\n\t\"tertiaryPalette\",\n\t\"errorPalette\",\n\t\"neutralPalette\",\n\t\"neutralVariantPalette\",\n];\n\nexport class Serialization {\n private constructor() { }\n\n public static ToCSS(args: {\n lightObject : ThemeObject;\n darkObject : ThemeObject;\n includeTheme ?: boolean;\n palettes ?: ThemePalettes;\n paletteWhiteList ?: PaletteSelector[];\n paletteBlackList ?: PaletteSelector[];\n paletteTones ?: number[];\n varPrefix ?: string;\n customPaletteName?: string;\n isCustomPalette ?: boolean;\n }) {\n const includeTheme = args.includeTheme !== false;\n const prefix = resolvePrefixConfig(args.varPrefix, args.isCustomPalette);\n const themeEntries = this.normalizeThemeEntries(args.lightObject, args.darkObject, prefix);\n const paletteEntries = this.normalizePaletteEntries(args.palettes, args.paletteTones, args.paletteWhiteList, args.paletteBlackList, prefix, args.customPaletteName);\n\n return this.toCss(themeEntries, paletteEntries, includeTheme);\n }\n\n private static normalizeThemeEntries(lightObject: ThemeObject, darkObject: ThemeObject, prefix: PrefixConfig): ThemeEntry[] {\n const lightEntries = this.normalizeThemeObject(lightObject, \"lightObject\");\n const darkEntries = this.normalizeThemeObject(darkObject, \"darkObject\");\n\n if (lightEntries.size !== darkEntries.size) {\n throw new TypeError(this.buildKeyMismatchMessage(lightEntries, darkEntries));\n }\n\n const lightKeys = [...lightEntries.keys()];\n const darkKeys = new Set(darkEntries.keys());\n\n const missingInDark = lightKeys.filter((key) => !darkKeys.has(key));\n const missingInLight = [...darkEntries.keys()].filter((key) => !lightEntries.has(key));\n\n if (missingInDark.length > 0 || missingInLight.length > 0) {\n throw new TypeError(this.buildKeyMismatchMessage(lightEntries, darkEntries));\n }\n\n return lightKeys.map((normalizedKey) => {\n const lightValue = lightEntries.get(normalizedKey) as string;\n const darkValue = darkEntries.get(normalizedKey) as string;\n\n return {\n normalizedKey,\n cssKey: `${prefix.theme.css}${normalizedKey}`,\n lightValue,\n darkValue,\n };\n });\n }\n\n private static normalizePaletteEntries(palettes?: ThemePalettes, paletteTones?: number[], paletteWhiteList?: PaletteSelector[], paletteBlackList?: PaletteSelector[], prefix?: PrefixConfig, customPaletteName?: string) {\n if (palettes === undefined) {\n return [];\n }\n\n const tones = this.normalizePaletteTones(paletteTones);\n const whiteList = this.normalizePaletteSelectors(paletteWhiteList);\n const blackList = this.normalizePaletteSelectors(paletteBlackList);\n const paletteEntries: PaletteEntry[] = [];\n const palPrefix = prefix ?? resolvePrefixConfig();\n\n for (const paletteName of ThemePaletteOrder) {\n const palette = palettes[paletteName];\n\n if (palette === undefined) {\n continue;\n }\n\n const normalizedPaletteName = this.toPaletteTokenName(paletteName);\n\n for (const toneEntry of MaterialPalette.Create({ palette, tones })) {\n if (whiteList !== undefined && customPaletteName === undefined && !whiteList.some((selector) => this.matchesPaletteSelector(selector, normalizedPaletteName, toneEntry.tone))) {\n continue;\n }\n\n if (blackList !== undefined && customPaletteName === undefined && blackList.some((selector) => this.matchesPaletteSelector(selector, normalizedPaletteName, toneEntry.tone))) {\n continue;\n }\n\n const normalizedKey = customPaletteName !== undefined\n ? `${String(toneEntry.tone)}`\n : `${normalizedPaletteName}-${toneEntry.tone}`;\n const value = hexFromArgb(toneEntry.color);\n\n paletteEntries.push({\n normalizedKey,\n cssKey: `${palPrefix.palette.css}${normalizedKey}`,\n value,\n });\n }\n }\n\n return paletteEntries;\n }\n\n private static normalizePaletteSelectors(values?: PaletteSelector[]) {\n if (values === undefined || values.length === 0) {\n return undefined;\n }\n\n return values.map((value) => this.normalizePaletteSelector(value));\n }\n\n private static normalizePaletteSelector(selector: PaletteSelector): PaletteSelector {\n const family = this.normalizePaletteSelectorFamily(selector.family);\n\n if (selector.tone === undefined) {\n return { family };\n }\n\n return {\n family,\n tone: this.normalizePaletteTone(selector.tone),\n };\n }\n\n private static normalizePaletteSelectorFamily(value: string) {\n const normalizedValue = StringUtil.ToKebabCase(value).replace(/^palette-/u, \"\");\n\n if (\n normalizedValue !== \"primary\" &&\n normalizedValue !== \"secondary\" &&\n normalizedValue !== \"tertiary\" &&\n normalizedValue !== \"error\" &&\n normalizedValue !== \"neutral\" &&\n normalizedValue !== \"neutral-variant\"\n ) {\n throw new TypeError(`Serialization: unsupported palette family \"${value}\".`);\n }\n\n return normalizedValue as PaletteSelectorFamilyName;\n }\n\n private static matchesPaletteSelector(selector: PaletteSelector, family: string, tone: number) {\n return selector.family === family && (selector.tone === undefined || selector.tone === tone);\n }\n\n private static normalizePaletteTones(tones?: number[]) {\n if (tones === undefined) {\n return [...DefaultPaletteTones];\n }\n\n if (tones.length === 0) {\n throw new TypeError(\"Serialization: paletteTones cannot be empty.\");\n }\n\n const normalizedTones = [...new Set(tones.map((tone) => this.normalizePaletteTone(tone)))];\n\n return normalizedTones.sort((left, right) => left - right);\n }\n\n private static normalizePaletteTone(tone: number) {\n if (!Number.isFinite(tone) || !Number.isInteger(tone) || tone < 0 || tone > 100) {\n throw new TypeError(\"Serialization: paletteTones must be integers between 0 and 100.\");\n }\n\n return tone;\n }\n\n private static normalizeThemeObject(object: ThemeObject, label: \"lightObject\" | \"darkObject\") {\n if (!this.isPlainObject(object)) {\n throw new TypeError(`Serialization: ${label} must be a plain object.`);\n }\n\n const symbolKeys = Object.getOwnPropertySymbols(object);\n\n if (symbolKeys.length > 0) {\n throw new TypeError(`Serialization: ${label} cannot contain symbol keys.`);\n }\n\n const normalized = new Map<string, string>();\n\n for (const [key, value] of Object.entries(object)) {\n const normalizedKey = StringUtil.ToKebabCase(key);\n\n if (!normalizedKey) {\n throw new TypeError(`Serialization: ${label} key \"${key}\" normalizes to an empty name.`);\n }\n\n if (normalized.has(normalizedKey)) {\n throw new TypeError(`Serialization: duplicate normalized key \"${normalizedKey}\".`);\n }\n\n normalized.set(normalizedKey, this.toColorValue(value, `${label} key \"${key}\"`));\n }\n\n return new Map([...normalized.entries()].sort(([left], [right]) => left.localeCompare(right)));\n }\n\n private static toPaletteTokenName(paletteName: ThemePaletteName) {\n return StringUtil.ToKebabCase(paletteName.replace(/Palette$/u, \"\"));\n }\n\n private static toColorValue(value: unknown, context: string) {\n if (typeof value === \"number\") {\n if (!Number.isFinite(value) || !Number.isInteger(value)) {\n throw new TypeError(`Serialization: ${context} must be an integer ARGB color value.`);\n }\n\n return hexFromArgb(value);\n }\n\n if (typeof value === \"string\") {\n const normalized = value.trim();\n\n if (normalized.length === 0) {\n throw new TypeError(`Serialization: ${context} cannot be an empty string.`);\n }\n\n return normalized;\n }\n\n throw new TypeError(`Serialization: ${context} must be a string or ARGB number.`);\n }\n\n private static isPlainObject(value: unknown): value is ThemeObject {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(value);\n\n return prototype === Object.prototype || prototype === null;\n }\n\n private static buildKeyMismatchMessage(lightEntries: Map<string, string>, darkEntries: Map<string, string>) {\n const missingInDark = [...lightEntries.keys()].filter((key) => !darkEntries.has(key));\n const missingInLight = [...darkEntries.keys()].filter((key) => !lightEntries.has(key));\n\n return `Serialization: lightObject and darkObject must contain the same normalized keys. Missing in darkObject: ${missingInDark.length > 0 ? missingInDark.join(\", \") : \"none\"}; missing in lightObject: ${missingInLight.length > 0 ? missingInLight.join(\", \") : \"none\"}.`;\n }\n\n private static toCss(themeEntries: ThemeEntry[], paletteEntries: PaletteEntry[], includeTheme: boolean) {\n if (includeTheme && themeEntries.length === 0 && paletteEntries.length === 0) {\n return `:root {\\n}\\n`;\n }\n\n const declarations = [\n ...(includeTheme ? themeEntries.map((entry) => ` ${entry.cssKey}: light-dark(${entry.lightValue}, ${entry.darkValue});`) : []),\n ...paletteEntries.map((entry) => ` ${entry.cssKey}: ${entry.value};`),\n ];\n\n if (declarations.length === 0) {\n return `:root {\\n}\\n`;\n }\n\n return `:root {\\n${declarations.join(\"\\n\")}\\n}\\n`;\n }\n\n}\n"],"mappings":"+MA4CA,SAAS,EAAoB,EAAoB,EAAyC,CACtF,GAAI,IAAc,IAAA,IAAa,EAAU,SAAW,EAChD,MAAO,CACH,MAAO,CAAE,IAAK,iBAAiB,EAC/B,QAAS,CAAE,IAAK,eAAwB,CAC5C,EAGJ,IAAM,EAAa,EAAU,QAAQ,OAAQ,EAAE,CAAC,CAAC,QAAQ,OAAQ,EAAE,EAE7D,EAAgB,KADP,EAAW,OAAS,EAAI,GAAG,EAAW,GAAK,KAU1D,OAPI,EACO,CACH,MAAO,CAAE,IAAK,GAAG,EAAc,OAAQ,EACvC,QAAS,CAAE,IAAK,CAAc,CAClC,EAGG,CACH,MAAO,CAAE,IAAK,CAAc,EAC5B,QAAS,CAAE,IAAK,CAAc,CAClC,CACJ,CAEA,MAAM,EAAwC,CAC7C,iBACA,mBACA,kBACA,eACA,iBACA,uBACD,EAEA,IAAa,EAAb,KAA2B,CACvB,aAAsB,CAAE,CAExB,OAAc,MAAM,EAWjB,CACC,IAAM,EAAe,EAAK,eAAiB,GACrC,EAAS,EAAoB,EAAK,UAAW,EAAK,eAAe,EACjE,EAAe,KAAK,sBAAsB,EAAK,YAAa,EAAK,WAAY,CAAM,EACnF,EAAiB,KAAK,wBAAwB,EAAK,SAAU,EAAK,aAAc,EAAK,iBAAkB,EAAK,iBAAkB,EAAQ,EAAK,iBAAiB,EAElK,OAAO,KAAK,MAAM,EAAc,EAAgB,CAAY,CAChE,CAEA,OAAe,sBAAsB,EAA0B,EAAyB,EAAoC,CACxH,IAAM,EAAe,KAAK,qBAAqB,EAAa,aAAa,EACnE,EAAc,KAAK,qBAAqB,EAAY,YAAY,EAEtE,GAAI,EAAa,OAAS,EAAY,KAClC,MAAU,UAAU,KAAK,wBAAwB,EAAc,CAAW,CAAC,EAG/E,IAAM,EAAY,CAAC,GAAG,EAAa,KAAK,CAAC,EACnC,EAAW,IAAI,IAAI,EAAY,KAAK,CAAC,EAErC,EAAgB,EAAU,OAAQ,GAAQ,CAAC,EAAS,IAAI,CAAG,CAAC,EAC5D,EAAiB,CAAC,GAAG,EAAY,KAAK,CAAC,CAAC,CAAC,OAAQ,GAAQ,CAAC,EAAa,IAAI,CAAG,CAAC,EAErF,GAAI,EAAc,OAAS,GAAK,EAAe,OAAS,EACpD,MAAU,UAAU,KAAK,wBAAwB,EAAc,CAAW,CAAC,EAG/E,OAAO,EAAU,IAAK,GAAkB,CACpC,IAAM,EAAa,EAAa,IAAI,CAAa,EAC3C,EAAY,EAAY,IAAI,CAAa,EAE/C,MAAO,CACH,gBACA,OAAQ,GAAG,EAAO,MAAM,MAAM,IAC9B,aACA,WACJ,CACJ,CAAC,CACL,CAEA,OAAe,wBAAwB,EAA0B,EAAyB,EAAsC,EAAsC,EAAuB,EAA4B,CACrN,GAAI,IAAa,IAAA,GACb,MAAO,CAAC,EAGZ,IAAM,EAAQ,KAAK,sBAAsB,CAAY,EAC/C,EAAY,KAAK,0BAA0B,CAAgB,EAC3D,EAAY,KAAK,0BAA0B,CAAgB,EAC3D,EAAiC,CAAC,EAClC,EAAY,GAAU,EAAoB,EAEhD,IAAK,IAAM,KAAe,EAAmB,CACzC,IAAM,EAAU,EAAS,GAEzB,GAAI,IAAY,IAAA,GACZ,SAGJ,IAAM,EAAwB,KAAK,mBAAmB,CAAW,EAEjE,IAAK,IAAM,KAAa,EAAgB,OAAO,CAAE,UAAS,OAAM,CAAC,EAAG,CAKhE,GAJI,IAAc,IAAA,IAAa,IAAsB,IAAA,IAAa,CAAC,EAAU,KAAM,GAAa,KAAK,uBAAuB,EAAU,EAAuB,EAAU,IAAI,CAAC,GAIxK,IAAc,IAAA,IAAa,IAAsB,IAAA,IAAa,EAAU,KAAM,GAAa,KAAK,uBAAuB,EAAU,EAAuB,EAAU,IAAI,CAAC,EACvK,SAGJ,IAAM,EAAgB,IAAsB,IAAA,GAEtC,GAAG,EAAsB,GAAG,EAAU,OADtC,GAAG,OAAO,EAAU,IAAI,IAExB,EAAQ,EAAY,EAAU,KAAK,EAEzC,EAAe,KAAK,CAChB,gBACA,OAAQ,GAAG,EAAU,QAAQ,MAAM,IACnC,OACJ,CAAC,CACL,CACJ,CAEA,OAAO,CACX,CAEA,OAAe,0BAA0B,EAA4B,CAC7D,OAAW,IAAA,IAAa,EAAO,SAAW,EAI9C,OAAO,EAAO,IAAK,GAAU,KAAK,yBAAyB,CAAK,CAAC,CACrE,CAEA,OAAe,yBAAyB,EAA4C,CAChF,IAAM,EAAS,KAAK,+BAA+B,EAAS,MAAM,EAMlE,OAJI,EAAS,OAAS,IAAA,GACX,CAAE,QAAO,EAGb,CACH,SACA,KAAM,KAAK,qBAAqB,EAAS,IAAI,CACjD,CACJ,CAEA,OAAe,+BAA+B,EAAe,CACzD,IAAM,EAAkB,EAAW,YAAY,CAAK,CAAC,CAAC,QAAQ,aAAc,EAAE,EAE9E,GACI,IAAoB,WACpB,IAAoB,aACpB,IAAoB,YACpB,IAAoB,SACpB,IAAoB,WACpB,IAAoB,kBAEpB,MAAU,UAAU,8CAA8C,EAAM,GAAG,EAG/E,OAAO,CACX,CAEA,OAAe,uBAAuB,EAA2B,EAAgB,EAAc,CAC3F,OAAO,EAAS,SAAW,IAAW,EAAS,OAAS,IAAA,IAAa,EAAS,OAAS,EAC3F,CAEA,OAAe,sBAAsB,EAAkB,CACnD,GAAI,IAAU,IAAA,GACV,MAAO,CAAC,GAAG,CAAmB,EAGlC,GAAI,EAAM,SAAW,EACjB,MAAU,UAAU,8CAA8C,EAKtE,MAAO,CAFkB,GAAG,IAAI,IAAI,EAAM,IAAK,GAAS,KAAK,qBAAqB,CAAI,CAAC,CAAC,CAEnE,CAAC,CAAC,MAAM,EAAM,IAAU,EAAO,CAAK,CAC7D,CAEA,OAAe,qBAAqB,EAAc,CAC9C,GAAI,CAAC,OAAO,SAAS,CAAI,GAAK,CAAC,OAAO,UAAU,CAAI,GAAK,EAAO,GAAK,EAAO,IACxE,MAAU,UAAU,iEAAiE,EAGzF,OAAO,CACX,CAEA,OAAe,qBAAqB,EAAqB,EAAqC,CAC1F,GAAI,CAAC,KAAK,cAAc,CAAM,EAC1B,MAAU,UAAU,kBAAkB,EAAM,yBAAyB,EAKzE,GAFmB,OAAO,sBAAsB,CAEnC,CAAC,CAAC,OAAS,EACpB,MAAU,UAAU,kBAAkB,EAAM,6BAA6B,EAG7E,IAAM,EAAa,IAAI,IAEvB,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAM,EAAG,CAC/C,IAAM,EAAgB,EAAW,YAAY,CAAG,EAEhD,GAAI,CAAC,EACD,MAAU,UAAU,kBAAkB,EAAM,QAAQ,EAAI,+BAA+B,EAG3F,GAAI,EAAW,IAAI,CAAa,EAC5B,MAAU,UAAU,4CAA4C,EAAc,GAAG,EAGrF,EAAW,IAAI,EAAe,KAAK,aAAa,EAAO,GAAG,EAAM,QAAQ,EAAI,EAAE,CAAC,CACnF,CAEA,OAAO,IAAI,IAAI,CAAC,GAAG,EAAW,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAO,CAAC,KAAW,EAAK,cAAc,CAAK,CAAC,CAAC,CACjG,CAEA,OAAe,mBAAmB,EAA+B,CAC7D,OAAO,EAAW,YAAY,EAAY,QAAQ,YAAa,EAAE,CAAC,CACtE,CAEA,OAAe,aAAa,EAAgB,EAAiB,CACzD,GAAI,OAAO,GAAU,SAAU,CAC3B,GAAI,CAAC,OAAO,SAAS,CAAK,GAAK,CAAC,OAAO,UAAU,CAAK,EAClD,MAAU,UAAU,kBAAkB,EAAQ,sCAAsC,EAGxF,OAAO,EAAY,CAAK,CAC5B,CAEA,GAAI,OAAO,GAAU,SAAU,CAC3B,IAAM,EAAa,EAAM,KAAK,EAE9B,GAAI,EAAW,SAAW,EACtB,MAAU,UAAU,kBAAkB,EAAQ,4BAA4B,EAG9E,OAAO,CACX,CAEA,MAAU,UAAU,kBAAkB,EAAQ,kCAAkC,CACpF,CAEA,OAAe,cAAc,EAAsC,CAC/D,GAAsB,OAAO,GAAU,WAAnC,GAA+C,MAAM,QAAQ,CAAK,EAClE,MAAO,GAGX,IAAM,EAAY,OAAO,eAAe,CAAK,EAE7C,OAAO,IAAc,OAAO,WAAa,IAAc,IAC3D,CAEA,OAAe,wBAAwB,EAAmC,EAAkC,CACxG,IAAM,EAAgB,CAAC,GAAG,EAAa,KAAK,CAAC,CAAC,CAAC,OAAQ,GAAQ,CAAC,EAAY,IAAI,CAAG,CAAC,EAC9E,EAAiB,CAAC,GAAG,EAAY,KAAK,CAAC,CAAC,CAAC,OAAQ,GAAQ,CAAC,EAAa,IAAI,CAAG,CAAC,EAErF,MAAO,2GAA2G,EAAc,OAAS,EAAI,EAAc,KAAK,IAAI,EAAI,OAAO,4BAA4B,EAAe,OAAS,EAAI,EAAe,KAAK,IAAI,EAAI,OAAO,EAC9Q,CAEA,OAAe,MAAM,EAA4B,EAAgC,EAAuB,CACpG,GAAI,GAAgB,EAAa,SAAW,GAAK,EAAe,SAAW,EACvE,MAAO;;EAGX,IAAM,EAAe,CACjB,GAAI,EAAe,EAAa,IAAK,GAAU,OAAO,EAAM,OAAO,eAAe,EAAM,WAAW,IAAI,EAAM,UAAU,GAAG,EAAI,CAAC,EAC/H,GAAG,EAAe,IAAK,GAAU,OAAO,EAAM,OAAO,IAAI,EAAM,MAAM,EAAE,CAC3E,EAMA,OAJI,EAAa,SAAW,EACjB;;EAGJ,YAAY,EAAa,KAAK;CAAI,EAAE,MAC/C,CAEJ"}
@@ -0,0 +1,7 @@
1
+ export * from './generators/material-color.service';
2
+ export * from './generators/material-palette.service';
3
+ export * from './generators/serialization.service';
4
+ export * from './material/material-colors';
5
+ export * from './material/material-contrast-level';
6
+ export * from './material/material-variant';
7
+ export * from './utils/string-util';
package/build/index.js ADDED
@@ -0,0 +1 @@
1
+ import{StringUtil as e}from"./utils/string-util.js";import{MaterialColor as t}from"./generators/material-color.service.js";import{DefaultPaletteTones as n,MaterialPalette as r}from"./generators/material-palette.service.js";import{Serialization as i}from"./generators/serialization.service.js";import{MaterialColors as a}from"./material/material-colors.js";import{MaterialContrastLevel as o}from"./material/material-contrast-level.js";import{MaterialVariant as s}from"./material/material-variant.js";export{n as DefaultPaletteTones,t as MaterialColor,a as MaterialColors,o as MaterialContrastLevel,r as MaterialPalette,s as MaterialVariant,i as Serialization,e as StringUtil};
@@ -0,0 +1,63 @@
1
+ import { type DynamicColor } from "@material/material-color-utilities";
2
+ export type MaterialColors = {
3
+ primaryPaletteKeyColor: DynamicColor;
4
+ secondaryPaletteKeyColor: DynamicColor;
5
+ tertiaryPaletteKeyColor: DynamicColor;
6
+ neutralPaletteKeyColor: DynamicColor;
7
+ neutralVariantPaletteKeyColor: DynamicColor;
8
+ background: DynamicColor;
9
+ onBackground: DynamicColor;
10
+ surface: DynamicColor;
11
+ surfaceDim: DynamicColor;
12
+ surfaceBright: DynamicColor;
13
+ surfaceContainerLowest: DynamicColor;
14
+ surfaceContainerLow: DynamicColor;
15
+ surfaceContainer: DynamicColor;
16
+ surfaceContainerHigh: DynamicColor;
17
+ surfaceContainerHighest: DynamicColor;
18
+ onSurface: DynamicColor;
19
+ surfaceVariant: DynamicColor;
20
+ onSurfaceVariant: DynamicColor;
21
+ inverseSurface: DynamicColor;
22
+ inverseOnSurface: DynamicColor;
23
+ outline: DynamicColor;
24
+ outlineVariant: DynamicColor;
25
+ shadow: DynamicColor;
26
+ scrim: DynamicColor;
27
+ surfaceTint: DynamicColor;
28
+ primary: DynamicColor;
29
+ onPrimary: DynamicColor;
30
+ primaryContainer: DynamicColor;
31
+ onPrimaryContainer: DynamicColor;
32
+ inversePrimary: DynamicColor;
33
+ secondary: DynamicColor;
34
+ onSecondary: DynamicColor;
35
+ secondaryContainer: DynamicColor;
36
+ onSecondaryContainer: DynamicColor;
37
+ tertiary: DynamicColor;
38
+ onTertiary: DynamicColor;
39
+ tertiaryContainer: DynamicColor;
40
+ onTertiaryContainer: DynamicColor;
41
+ error: DynamicColor;
42
+ onError: DynamicColor;
43
+ errorContainer: DynamicColor;
44
+ onErrorContainer: DynamicColor;
45
+ primaryFixed: DynamicColor;
46
+ primaryFixedDim: DynamicColor;
47
+ onPrimaryFixed: DynamicColor;
48
+ onPrimaryFixedVariant: DynamicColor;
49
+ secondaryFixed: DynamicColor;
50
+ secondaryFixedDim: DynamicColor;
51
+ onSecondaryFixed: DynamicColor;
52
+ onSecondaryFixedVariant: DynamicColor;
53
+ tertiaryFixed: DynamicColor;
54
+ tertiaryFixedDim: DynamicColor;
55
+ onTertiaryFixed: DynamicColor;
56
+ onTertiaryFixedVariant: DynamicColor;
57
+ };
58
+ export type TMaterialColors = MaterialColors;
59
+ export declare const MaterialColors: {
60
+ new (): {};
61
+ ToRecord(): Record<keyof MaterialColors, DynamicColor>;
62
+ ToArray(): DynamicColor[];
63
+ };
@@ -0,0 +1,2 @@
1
+ import{MaterialDynamicColors as e}from"@material/material-color-utilities";const t=class{constructor(){}static ToRecord(){return{primaryPaletteKeyColor:e.primaryPaletteKeyColor,secondaryPaletteKeyColor:e.secondaryPaletteKeyColor,tertiaryPaletteKeyColor:e.tertiaryPaletteKeyColor,neutralPaletteKeyColor:e.neutralPaletteKeyColor,neutralVariantPaletteKeyColor:e.neutralVariantPaletteKeyColor,background:e.background,onBackground:e.onBackground,surface:e.surface,surfaceDim:e.surfaceDim,surfaceBright:e.surfaceBright,surfaceContainerLowest:e.surfaceContainerLowest,surfaceContainerLow:e.surfaceContainerLow,surfaceContainer:e.surfaceContainer,surfaceContainerHigh:e.surfaceContainerHigh,surfaceContainerHighest:e.surfaceContainerHighest,onSurface:e.onSurface,surfaceVariant:e.surfaceVariant,onSurfaceVariant:e.onSurfaceVariant,inverseSurface:e.inverseSurface,inverseOnSurface:e.inverseOnSurface,outline:e.outline,outlineVariant:e.outlineVariant,shadow:e.shadow,scrim:e.scrim,surfaceTint:e.surfaceTint,primary:e.primary,onPrimary:e.onPrimary,primaryContainer:e.primaryContainer,onPrimaryContainer:e.onPrimaryContainer,inversePrimary:e.inversePrimary,secondary:e.secondary,onSecondary:e.onSecondary,secondaryContainer:e.secondaryContainer,onSecondaryContainer:e.onSecondaryContainer,tertiary:e.tertiary,onTertiary:e.onTertiary,tertiaryContainer:e.tertiaryContainer,onTertiaryContainer:e.onTertiaryContainer,error:e.error,onError:e.onError,errorContainer:e.errorContainer,onErrorContainer:e.onErrorContainer,primaryFixed:e.primaryFixed,primaryFixedDim:e.primaryFixedDim,onPrimaryFixed:e.onPrimaryFixed,onPrimaryFixedVariant:e.onPrimaryFixedVariant,secondaryFixed:e.secondaryFixed,secondaryFixedDim:e.secondaryFixedDim,onSecondaryFixed:e.onSecondaryFixed,onSecondaryFixedVariant:e.onSecondaryFixedVariant,tertiaryFixed:e.tertiaryFixed,tertiaryFixedDim:e.tertiaryFixedDim,onTertiaryFixed:e.onTertiaryFixed,onTertiaryFixedVariant:e.onTertiaryFixedVariant}}static ToArray(){return Object.values(t.ToRecord())}};export{t as MaterialColors};
2
+ //# sourceMappingURL=material-colors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"material-colors.js","names":[],"sources":["../../src/material/material-colors.ts"],"sourcesContent":["import { type DynamicColor, MaterialDynamicColors } from \"@material/material-color-utilities\"\n\nexport type MaterialColors = {\n primaryPaletteKeyColor : DynamicColor\n secondaryPaletteKeyColor : DynamicColor\n tertiaryPaletteKeyColor : DynamicColor\n neutralPaletteKeyColor : DynamicColor\n neutralVariantPaletteKeyColor: DynamicColor\n background : DynamicColor\n onBackground : DynamicColor\n surface : DynamicColor\n surfaceDim : DynamicColor\n surfaceBright : DynamicColor\n surfaceContainerLowest : DynamicColor\n surfaceContainerLow : DynamicColor\n surfaceContainer : DynamicColor\n surfaceContainerHigh : DynamicColor\n surfaceContainerHighest : DynamicColor\n onSurface : DynamicColor\n surfaceVariant : DynamicColor\n onSurfaceVariant : DynamicColor\n inverseSurface : DynamicColor\n inverseOnSurface : DynamicColor\n outline : DynamicColor\n outlineVariant : DynamicColor\n shadow : DynamicColor\n scrim : DynamicColor\n surfaceTint : DynamicColor\n primary : DynamicColor\n onPrimary : DynamicColor\n primaryContainer : DynamicColor\n onPrimaryContainer : DynamicColor\n inversePrimary : DynamicColor\n secondary : DynamicColor\n onSecondary : DynamicColor\n secondaryContainer : DynamicColor\n onSecondaryContainer : DynamicColor\n tertiary : DynamicColor\n onTertiary : DynamicColor\n tertiaryContainer : DynamicColor\n onTertiaryContainer : DynamicColor\n error : DynamicColor\n onError : DynamicColor\n errorContainer : DynamicColor\n onErrorContainer : DynamicColor\n primaryFixed : DynamicColor\n primaryFixedDim : DynamicColor\n onPrimaryFixed : DynamicColor\n onPrimaryFixedVariant : DynamicColor\n secondaryFixed : DynamicColor\n secondaryFixedDim : DynamicColor\n onSecondaryFixed : DynamicColor\n onSecondaryFixedVariant : DynamicColor\n tertiaryFixed : DynamicColor\n tertiaryFixedDim : DynamicColor\n onTertiaryFixed : DynamicColor\n onTertiaryFixedVariant : DynamicColor\n}\n\nexport type TMaterialColors = MaterialColors;\n\nexport const MaterialColors = class {\n private constructor() { }\n\n static ToRecord(): Record<keyof MaterialColors, DynamicColor> {\n return {\n primaryPaletteKeyColor: MaterialDynamicColors.primaryPaletteKeyColor,\n secondaryPaletteKeyColor: MaterialDynamicColors.secondaryPaletteKeyColor,\n tertiaryPaletteKeyColor: MaterialDynamicColors.tertiaryPaletteKeyColor,\n neutralPaletteKeyColor: MaterialDynamicColors.neutralPaletteKeyColor,\n neutralVariantPaletteKeyColor: MaterialDynamicColors.neutralVariantPaletteKeyColor,\n background: MaterialDynamicColors.background,\n onBackground: MaterialDynamicColors.onBackground,\n surface: MaterialDynamicColors.surface,\n surfaceDim: MaterialDynamicColors.surfaceDim,\n surfaceBright: MaterialDynamicColors.surfaceBright,\n surfaceContainerLowest: MaterialDynamicColors.surfaceContainerLowest,\n surfaceContainerLow: MaterialDynamicColors.surfaceContainerLow,\n surfaceContainer: MaterialDynamicColors.surfaceContainer,\n surfaceContainerHigh: MaterialDynamicColors.surfaceContainerHigh,\n surfaceContainerHighest: MaterialDynamicColors.surfaceContainerHighest,\n onSurface: MaterialDynamicColors.onSurface,\n surfaceVariant: MaterialDynamicColors.surfaceVariant,\n onSurfaceVariant: MaterialDynamicColors.onSurfaceVariant,\n inverseSurface: MaterialDynamicColors.inverseSurface,\n inverseOnSurface: MaterialDynamicColors.inverseOnSurface,\n outline: MaterialDynamicColors.outline,\n outlineVariant: MaterialDynamicColors.outlineVariant,\n shadow: MaterialDynamicColors.shadow,\n scrim: MaterialDynamicColors.scrim,\n surfaceTint: MaterialDynamicColors.surfaceTint,\n primary: MaterialDynamicColors.primary,\n onPrimary: MaterialDynamicColors.onPrimary,\n primaryContainer: MaterialDynamicColors.primaryContainer,\n onPrimaryContainer: MaterialDynamicColors.onPrimaryContainer,\n inversePrimary: MaterialDynamicColors.inversePrimary,\n secondary: MaterialDynamicColors.secondary,\n onSecondary: MaterialDynamicColors.onSecondary,\n secondaryContainer: MaterialDynamicColors.secondaryContainer,\n onSecondaryContainer: MaterialDynamicColors.onSecondaryContainer,\n tertiary: MaterialDynamicColors.tertiary,\n onTertiary: MaterialDynamicColors.onTertiary,\n tertiaryContainer: MaterialDynamicColors.tertiaryContainer,\n onTertiaryContainer: MaterialDynamicColors.onTertiaryContainer,\n error: MaterialDynamicColors.error,\n onError: MaterialDynamicColors.onError,\n errorContainer: MaterialDynamicColors.errorContainer,\n onErrorContainer: MaterialDynamicColors.onErrorContainer,\n primaryFixed: MaterialDynamicColors.primaryFixed,\n primaryFixedDim: MaterialDynamicColors.primaryFixedDim,\n onPrimaryFixed: MaterialDynamicColors.onPrimaryFixed,\n onPrimaryFixedVariant: MaterialDynamicColors.onPrimaryFixedVariant,\n secondaryFixed: MaterialDynamicColors.secondaryFixed,\n secondaryFixedDim: MaterialDynamicColors.secondaryFixedDim,\n onSecondaryFixed: MaterialDynamicColors.onSecondaryFixed,\n onSecondaryFixedVariant: MaterialDynamicColors.onSecondaryFixedVariant,\n tertiaryFixed: MaterialDynamicColors.tertiaryFixed,\n tertiaryFixedDim: MaterialDynamicColors.tertiaryFixedDim,\n onTertiaryFixed: MaterialDynamicColors.onTertiaryFixed,\n onTertiaryFixedVariant: MaterialDynamicColors.onTertiaryFixedVariant,\n }\n }\n\n static ToArray(): DynamicColor[] {\n return Object.values(MaterialColors.ToRecord())\n }\n}\n"],"mappings":"2EA6DA,MAAa,EAAiB,KAAM,CAChC,aAAsB,CAAE,CAExB,OAAO,UAAuD,CAC1D,MAAO,CACH,uBAAwB,EAAsB,uBAC9C,yBAA0B,EAAsB,yBAChD,wBAAyB,EAAsB,wBAC/C,uBAAwB,EAAsB,uBAC9C,8BAA+B,EAAsB,8BACrD,WAAY,EAAsB,WAClC,aAAc,EAAsB,aACpC,QAAS,EAAsB,QAC/B,WAAY,EAAsB,WAClC,cAAe,EAAsB,cACrC,uBAAwB,EAAsB,uBAC9C,oBAAqB,EAAsB,oBAC3C,iBAAkB,EAAsB,iBACxC,qBAAsB,EAAsB,qBAC5C,wBAAyB,EAAsB,wBAC/C,UAAW,EAAsB,UACjC,eAAgB,EAAsB,eACtC,iBAAkB,EAAsB,iBACxC,eAAgB,EAAsB,eACtC,iBAAkB,EAAsB,iBACxC,QAAS,EAAsB,QAC/B,eAAgB,EAAsB,eACtC,OAAQ,EAAsB,OAC9B,MAAO,EAAsB,MAC7B,YAAa,EAAsB,YACnC,QAAS,EAAsB,QAC/B,UAAW,EAAsB,UACjC,iBAAkB,EAAsB,iBACxC,mBAAoB,EAAsB,mBAC1C,eAAgB,EAAsB,eACtC,UAAW,EAAsB,UACjC,YAAa,EAAsB,YACnC,mBAAoB,EAAsB,mBAC1C,qBAAsB,EAAsB,qBAC5C,SAAU,EAAsB,SAChC,WAAY,EAAsB,WAClC,kBAAmB,EAAsB,kBACzC,oBAAqB,EAAsB,oBAC3C,MAAO,EAAsB,MAC7B,QAAS,EAAsB,QAC/B,eAAgB,EAAsB,eACtC,iBAAkB,EAAsB,iBACxC,aAAc,EAAsB,aACpC,gBAAiB,EAAsB,gBACvC,eAAgB,EAAsB,eACtC,sBAAuB,EAAsB,sBAC7C,eAAgB,EAAsB,eACtC,kBAAmB,EAAsB,kBACzC,iBAAkB,EAAsB,iBACxC,wBAAyB,EAAsB,wBAC/C,cAAe,EAAsB,cACrC,iBAAkB,EAAsB,iBACxC,gBAAiB,EAAsB,gBACvC,uBAAwB,EAAsB,sBAClD,CACJ,CAEA,OAAO,SAA0B,CAC7B,OAAO,OAAO,OAAO,EAAe,SAAS,CAAC,CAClD,CACJ"}
@@ -0,0 +1,8 @@
1
+ export declare const MaterialContrastLevel: {
2
+ readonly Reduced: -1;
3
+ readonly Default: 0;
4
+ readonly Medium: 0.5;
5
+ readonly High: 1;
6
+ };
7
+ export type MaterialContrastLevel = typeof MaterialContrastLevel[keyof typeof MaterialContrastLevel];
8
+ export type TMaterialContrastLevel = MaterialContrastLevel;
@@ -0,0 +1,2 @@
1
+ const e={Reduced:-1,Default:0,Medium:.5,High:1};export{e as MaterialContrastLevel};
2
+ //# sourceMappingURL=material-contrast-level.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"material-contrast-level.js","names":[],"sources":["../../src/material/material-contrast-level.ts"],"sourcesContent":["export const MaterialContrastLevel = {\n Reduced: -1.0,\n Default: 0,\n Medium : 0.5,\n High : 1.0,\n} as const satisfies Record<string, number>\n\nexport type MaterialContrastLevel = typeof MaterialContrastLevel[keyof typeof MaterialContrastLevel]\nexport type TMaterialContrastLevel = MaterialContrastLevel\n"],"mappings":"AAAA,MAAa,EAAwB,CACjC,QAAS,GACT,QAAS,EACT,OAAS,GACT,KAAS,CACb"}
@@ -0,0 +1,14 @@
1
+ import { Variant } from '@material/material-color-utilities';
2
+ export declare const MaterialVariant: {
3
+ readonly Monochrome: Variant.MONOCHROME;
4
+ readonly Neutral: Variant.NEUTRAL;
5
+ readonly TonalSpot: Variant.TONAL_SPOT;
6
+ readonly Vibrant: Variant.VIBRANT;
7
+ readonly Expressive: Variant.EXPRESSIVE;
8
+ readonly Fidelity: Variant.FIDELITY;
9
+ readonly Content: Variant.CONTENT;
10
+ readonly Rainbow: Variant.RAINBOW;
11
+ readonly FruitSalad: Variant.FRUIT_SALAD;
12
+ };
13
+ export type MaterialVariant = typeof MaterialVariant[keyof typeof MaterialVariant];
14
+ export type TMaterialVariant = MaterialVariant;
@@ -0,0 +1,2 @@
1
+ import{Variant as e}from"@material/material-color-utilities";const t={Monochrome:e.MONOCHROME,Neutral:e.NEUTRAL,TonalSpot:e.TONAL_SPOT,Vibrant:e.VIBRANT,Expressive:e.EXPRESSIVE,Fidelity:e.FIDELITY,Content:e.CONTENT,Rainbow:e.RAINBOW,FruitSalad:e.FRUIT_SALAD};export{t as MaterialVariant};
2
+ //# sourceMappingURL=material-variant.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"material-variant.js","names":[],"sources":["../../src/material/material-variant.ts"],"sourcesContent":["import { Variant } from '@material/material-color-utilities'\n\nexport const MaterialVariant = {\n Monochrome: Variant.MONOCHROME,\n Neutral : Variant.NEUTRAL,\n TonalSpot : Variant.TONAL_SPOT,\n Vibrant : Variant.VIBRANT,\n Expressive: Variant.EXPRESSIVE,\n Fidelity : Variant.FIDELITY,\n Content : Variant.CONTENT,\n Rainbow : Variant.RAINBOW,\n FruitSalad: Variant.FRUIT_SALAD,\n} as const satisfies Record<string, Variant>\n\nexport type MaterialVariant = typeof MaterialVariant[keyof typeof MaterialVariant]\nexport type TMaterialVariant = MaterialVariant\n"],"mappings":"6DAEA,MAAa,EAAkB,CAC3B,WAAY,EAAQ,WACpB,QAAY,EAAQ,QACpB,UAAY,EAAQ,WACpB,QAAY,EAAQ,QACpB,WAAY,EAAQ,WACpB,SAAY,EAAQ,SACpB,QAAY,EAAQ,QACpB,QAAY,EAAQ,QACpB,WAAY,EAAQ,WACxB"}
@@ -0,0 +1,6 @@
1
+ export declare class StringUtil {
2
+ private constructor();
3
+ static ToKebabCase<S extends string>(str: S): string;
4
+ static ToSnakeCase(str: string): string;
5
+ static ToPascalCase(str: string): string;
6
+ }
@@ -0,0 +1,2 @@
1
+ var e=class{constructor(){}static ToKebabCase(e){return e?e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).replace(/[\s_.]+/g,`-`).toLowerCase().replace(/-+/g,`-`).replace(/^-|-$/g,``):``}static ToSnakeCase(e){return e?e.replace(/([a-z0-9])([A-Z])/g,`$1_$2`).replace(/[\s.-]+/g,`_`).toLowerCase().replace(/_+/g,`_`).replace(/^_|_$/g,``):``}static ToPascalCase(e){if(!e)return``;let t=this.ToKebabCase(e);return t?t.split(`-`).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``):``}};export{e as StringUtil};
2
+ //# sourceMappingURL=string-util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string-util.js","names":[],"sources":["../../src/utils/string-util.ts"],"sourcesContent":["export class StringUtil {\n private constructor() { }\n\n public static ToKebabCase<S extends string>(str: S) {\n if (!str) return ''\n return str\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .replace(/[\\s_.]+/g, '-')\n .toLowerCase()\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n }\n\n public static ToSnakeCase(str: string) {\n if (!str) return ''\n return str\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .replace(/[\\s.-]+/g, '_')\n .toLowerCase()\n .replace(/_+/g, '_')\n .replace(/^_|_$/g, '')\n }\n\n public static ToPascalCase(str: string) {\n if (!str) return ''\n\n const kebabCase = this.ToKebabCase(str)\n\n if (!kebabCase) return ''\n\n return kebabCase\n .split('-')\n .filter(Boolean)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join('')\n }\n}\n"],"mappings":"AAAA,IAAa,EAAb,KAAwB,CACpB,aAAsB,CAAE,CAExB,OAAc,YAA8B,EAAQ,CAEhD,OADK,EACE,EACF,QAAQ,qBAAsB,OAAO,CAAC,CACtC,QAAQ,WAAY,GAAG,CAAC,CACxB,YAAY,CAAC,CACb,QAAQ,MAAO,GAAG,CAAC,CACnB,QAAQ,SAAU,EAAE,EANR,EAOrB,CAEA,OAAc,YAAY,EAAa,CAEnC,OADK,EACE,EACF,QAAQ,qBAAsB,OAAO,CAAC,CACtC,QAAQ,WAAY,GAAG,CAAC,CACxB,YAAY,CAAC,CACb,QAAQ,MAAO,GAAG,CAAC,CACnB,QAAQ,SAAU,EAAE,EANR,EAOrB,CAEA,OAAc,aAAa,EAAa,CACpC,GAAI,CAAC,EAAK,MAAO,GAEjB,IAAM,EAAY,KAAK,YAAY,CAAG,EAItC,OAFK,EAEE,EACF,MAAM,GAAG,CAAC,CACV,OAAO,OAAO,CAAC,CACf,IAAK,GAAS,EAAK,OAAO,CAAC,CAAC,CAAC,YAAY,EAAI,EAAK,MAAM,CAAC,CAAC,CAAC,CAC3D,KAAK,EAAE,EANW,EAO3B,CACJ"}
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "@sandlada/mcu-helper",
3
+ "version": "0.0.1-20260719.a",
4
+ "author": "Kai-Orion & Sandlada",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "description": "Generate Material Design 3 color tokens, palettes, and CSS custom properties from a source color using @material/material-color-utilities.",
8
+ "keywords": [
9
+ "color",
10
+ "theme-generator",
11
+ "material",
12
+ "material-design",
13
+ "material-you",
14
+ "material-tokens",
15
+ "tokens",
16
+ "design-tokens",
17
+ "css",
18
+ "css-custom-properties",
19
+ "custom-properties",
20
+ "color-tokens",
21
+ "color-palette",
22
+ "dynamic-color",
23
+ "material-color-utilities",
24
+ "mcu"
25
+ ],
26
+ "homepage": "https://github.com/sandlada/mcu-helper#readme",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/sandlada/mcu-helper.git"
30
+ },
31
+ "bugs": {
32
+ "url": "https://github.com/sandlada/mcu-helper/issues"
33
+ },
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "main": "build/index.js",
38
+ "module": "build/index.js",
39
+ "files": [
40
+ "build/**/*",
41
+ "README.md"
42
+ ],
43
+ "exports": {
44
+ ".": {
45
+ "types": "./build/index.d.ts",
46
+ "import": "./build/index.js",
47
+ "require": "./build/index.js",
48
+ "default": "./build/index.js"
49
+ },
50
+ "./*": {
51
+ "types": "./build/*.d.ts",
52
+ "import": "./build/*.js",
53
+ "require": "./build/*.js",
54
+ "default": "./build/*.js"
55
+ }
56
+ },
57
+ "engines": {
58
+ "node": ">=18"
59
+ },
60
+ "scripts": {
61
+ "compile": "rolldown --config rolldown.config.mjs && tsc --emitDeclarationOnly",
62
+ "test": "vitest run",
63
+ "test:watch": "vitest"
64
+ },
65
+ "devDependencies": {
66
+ "@material/material-color-utilities": "^0.4.0",
67
+ "@types/node": "26.1.1",
68
+ "rolldown": "^1.2.0",
69
+ "typescript": "~7.0.2",
70
+ "vitest": "^4.1.10"
71
+ },
72
+ "peerDependencies": {
73
+ "@material/material-color-utilities": "^0.4.0"
74
+ },
75
+ "workspaces": [
76
+ "dev-app"
77
+ ]
78
+ }