@tenphi/glaze 0.0.0-snapshot.7e2a1da → 0.0.0-snapshot.7f7cab2
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 +67 -27
- package/dist/index.cjs +85 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +49 -25
- package/dist/index.d.mts +49 -25
- package/dist/index.mjs +85 -33
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -133,6 +133,11 @@ interface RegularColorDef {
|
|
|
133
133
|
* should not be combined (a console.warn is emitted).
|
|
134
134
|
*/
|
|
135
135
|
opacity?: number;
|
|
136
|
+
/**
|
|
137
|
+
* Whether this color is inherited by child themes created via `extend()`.
|
|
138
|
+
* Default: true. Set to false to make this color local to the current theme.
|
|
139
|
+
*/
|
|
140
|
+
inherit?: boolean;
|
|
136
141
|
}
|
|
137
142
|
/** Shadow tuning knobs. All values use the 0–1 scale (OKHSL). */
|
|
138
143
|
interface ShadowTuning {
|
|
@@ -177,6 +182,11 @@ interface ShadowColorDef {
|
|
|
177
182
|
intensity: HCPair<number>;
|
|
178
183
|
/** Override default tuning. Merged field-by-field with global `shadowTuning`. */
|
|
179
184
|
tuning?: ShadowTuning;
|
|
185
|
+
/**
|
|
186
|
+
* Whether this color is inherited by child themes created via `extend()`.
|
|
187
|
+
* Default: true. Set to false to make this color local to the current theme.
|
|
188
|
+
*/
|
|
189
|
+
inherit?: boolean;
|
|
180
190
|
}
|
|
181
191
|
interface MixColorDef {
|
|
182
192
|
type: 'mix';
|
|
@@ -211,6 +221,11 @@ interface MixColorDef {
|
|
|
211
221
|
* Supports [normal, highContrast] pair.
|
|
212
222
|
*/
|
|
213
223
|
contrast?: HCPair<MinContrast>;
|
|
224
|
+
/**
|
|
225
|
+
* Whether this color is inherited by child themes created via `extend()`.
|
|
226
|
+
* Default: true. Set to false to make this color local to the current theme.
|
|
227
|
+
*/
|
|
228
|
+
inherit?: boolean;
|
|
214
229
|
}
|
|
215
230
|
type ColorDef = RegularColorDef | ShadowColorDef | MixColorDef;
|
|
216
231
|
type ColorMap = Record<string, ColorDef>;
|
|
@@ -243,11 +258,12 @@ interface GlazeConfig {
|
|
|
243
258
|
/** Saturation reduction factor for dark scheme (0–1). Default: 0.1. */
|
|
244
259
|
darkDesaturation?: number;
|
|
245
260
|
/**
|
|
246
|
-
*
|
|
261
|
+
* Möbius beta for dark auto-inversion (0–1).
|
|
247
262
|
* Lower values expand subtle near-white distinctions in dark mode.
|
|
248
263
|
* Set to 1 for linear (legacy) behavior. Default: 0.5.
|
|
264
|
+
* Accepts [normal, highContrast] pair for separate HC tuning.
|
|
249
265
|
*/
|
|
250
|
-
darkCurve?: number
|
|
266
|
+
darkCurve?: HCPair<number>;
|
|
251
267
|
/** State alias names for token export. */
|
|
252
268
|
states?: {
|
|
253
269
|
dark?: string;
|
|
@@ -262,7 +278,7 @@ interface GlazeConfigResolved {
|
|
|
262
278
|
lightLightness: [number, number];
|
|
263
279
|
darkLightness: [number, number];
|
|
264
280
|
darkDesaturation: number;
|
|
265
|
-
darkCurve: number
|
|
281
|
+
darkCurve: HCPair<number>;
|
|
266
282
|
states: {
|
|
267
283
|
dark: string;
|
|
268
284
|
highContrast: string;
|
|
@@ -392,35 +408,47 @@ interface GlazeCssResult {
|
|
|
392
408
|
lightContrast: string;
|
|
393
409
|
darkContrast: string;
|
|
394
410
|
}
|
|
395
|
-
/** Options
|
|
396
|
-
interface
|
|
397
|
-
/**
|
|
398
|
-
* Prefix mode. `true` uses `"<themeName>-"`, or provide a custom map.
|
|
399
|
-
* Defaults to `true` for palette export methods.
|
|
400
|
-
* Set to `false` explicitly to disable prefixing (last-write-wins on collisions).
|
|
401
|
-
*/
|
|
402
|
-
prefix?: boolean | Record<string, string>;
|
|
411
|
+
/** Options for `glaze.palette()` creation. */
|
|
412
|
+
interface GlazePaletteOptions {
|
|
403
413
|
/**
|
|
404
414
|
* Name of the primary theme. The primary theme's tokens are duplicated
|
|
405
|
-
* without prefix, providing convenient short aliases
|
|
406
|
-
* prefixed versions.
|
|
415
|
+
* without prefix in all exports, providing convenient short aliases
|
|
416
|
+
* alongside the prefixed versions. Can be overridden per-export.
|
|
407
417
|
*
|
|
408
418
|
* @example
|
|
409
419
|
* ```ts
|
|
410
|
-
* palette.
|
|
420
|
+
* const palette = glaze.palette({ brand, accent }, { primary: 'brand' });
|
|
421
|
+
* palette.tokens()
|
|
411
422
|
* // → { light: { 'brand-surface': '...', 'surface': '...', 'accent-surface': '...' } }
|
|
412
423
|
* ```
|
|
413
424
|
*/
|
|
414
425
|
primary?: string;
|
|
415
426
|
}
|
|
427
|
+
/** Options shared by palette `tokens()`, `tasty()`, and `css()` exports. */
|
|
428
|
+
interface GlazePaletteExportOptions {
|
|
429
|
+
/**
|
|
430
|
+
* Prefix mode. `true` uses `"<themeName>-"`, or provide a custom map.
|
|
431
|
+
* Defaults to `true` for palette export methods.
|
|
432
|
+
* Set to `false` explicitly to disable prefixing. Colliding keys
|
|
433
|
+
* produce a console.warn and the first-written value wins.
|
|
434
|
+
*/
|
|
435
|
+
prefix?: boolean | Record<string, string>;
|
|
436
|
+
/**
|
|
437
|
+
* Override the palette-level primary theme for this export.
|
|
438
|
+
* Pass a theme name to set/change the primary, or `false` to disable it.
|
|
439
|
+
* When omitted, inherits the palette-level `primary`.
|
|
440
|
+
*/
|
|
441
|
+
primary?: string | false;
|
|
442
|
+
}
|
|
416
443
|
interface GlazePalette {
|
|
417
444
|
/**
|
|
418
445
|
* Export all themes as a flat token map grouped by scheme variant.
|
|
419
446
|
* Prefix defaults to `true` — all tokens are prefixed with the theme name.
|
|
420
|
-
*
|
|
447
|
+
* Inherits the palette-level `primary`; override per-call or pass `false` to disable.
|
|
421
448
|
*
|
|
422
449
|
* ```ts
|
|
423
|
-
* palette.
|
|
450
|
+
* const palette = glaze.palette({ brand, accent }, { primary: 'brand' });
|
|
451
|
+
* palette.tokens()
|
|
424
452
|
* // → { light: { 'brand-surface': '...', 'surface': '...', 'accent-surface': '...' } }
|
|
425
453
|
* ```
|
|
426
454
|
*/
|
|
@@ -428,12 +456,10 @@ interface GlazePalette {
|
|
|
428
456
|
/**
|
|
429
457
|
* Export all themes as tasty style-to-state bindings.
|
|
430
458
|
* Uses `#name` color token keys and state aliases (`''`, `@dark`, etc.).
|
|
431
|
-
* Prefix defaults to `true`.
|
|
459
|
+
* Prefix defaults to `true`. Inherits the palette-level `primary`.
|
|
432
460
|
* @see https://cube-ui-kit.vercel.app/?path=/docs/tasty-documentation--docs
|
|
433
461
|
*/
|
|
434
|
-
tasty(options?: GlazeTokenOptions &
|
|
435
|
-
primary?: string;
|
|
436
|
-
}): Record<string, Record<string, string>>;
|
|
462
|
+
tasty(options?: GlazeTokenOptions & GlazePaletteExportOptions): Record<string, Record<string, string>>;
|
|
437
463
|
/** Export all themes as plain JSON grouped by theme name. */
|
|
438
464
|
json(options?: GlazeJsonOptions & {
|
|
439
465
|
prefix?: boolean | Record<string, string>;
|
|
@@ -460,11 +486,9 @@ declare function glaze(hueOrOptions: number | {
|
|
|
460
486
|
}, saturation?: number): GlazeTheme;
|
|
461
487
|
declare namespace glaze {
|
|
462
488
|
var configure: (config: GlazeConfig) => void;
|
|
463
|
-
var palette: (themes: PaletteInput) => {
|
|
489
|
+
var palette: (themes: PaletteInput, options?: GlazePaletteOptions) => {
|
|
464
490
|
tokens(options?: GlazeJsonOptions & GlazePaletteExportOptions): Record<string, Record<string, string>>;
|
|
465
|
-
tasty(options?: GlazeTokenOptions &
|
|
466
|
-
primary?: string;
|
|
467
|
-
}): Record<string, Record<string, string>>;
|
|
491
|
+
tasty(options?: GlazeTokenOptions & GlazePaletteExportOptions): Record<string, Record<string, string>>;
|
|
468
492
|
json(options?: GlazeJsonOptions & {
|
|
469
493
|
prefix?: boolean | Record<string, string>;
|
|
470
494
|
}): Record<string, Record<string, Record<string, string>>>;
|
|
@@ -548,5 +572,5 @@ declare function formatHsl(h: number, s: number, l: number): string;
|
|
|
548
572
|
*/
|
|
549
573
|
declare function formatOklch(h: number, s: number, l: number): string;
|
|
550
574
|
//#endregion
|
|
551
|
-
export { type AdaptationMode, type ColorDef, type ColorMap, type ContrastPreset, type FindLightnessForContrastOptions, type FindLightnessForContrastResult, type FindValueForMixContrastOptions, type FindValueForMixContrastResult, type GlazeColorFormat, type GlazeColorInput, type GlazeColorToken, type GlazeConfig, type GlazeCssOptions, type GlazeCssResult, type GlazeExtendOptions, type GlazeJsonOptions, type GlazeOutputModes, type GlazePalette, type GlazePaletteExportOptions, type GlazeShadowInput, type GlazeTheme, type GlazeThemeExport, type GlazeTokenOptions, type HCPair, type HexColor, type MinContrast, type MixColorDef, type OkhslColor, type RegularColorDef, type RelativeValue, type ResolvedColor, type ResolvedColorVariant, type ShadowColorDef, type ShadowTuning, contrastRatioFromLuminance, findLightnessForContrast, findValueForMixContrast, formatHsl, formatOkhsl, formatOklch, formatRgb, gamutClampedLuminance, glaze, okhslToLinearSrgb, okhslToOklab, okhslToSrgb, parseHex, relativeLuminanceFromLinearRgb, resolveMinContrast, srgbToOkhsl };
|
|
575
|
+
export { type AdaptationMode, type ColorDef, type ColorMap, type ContrastPreset, type FindLightnessForContrastOptions, type FindLightnessForContrastResult, type FindValueForMixContrastOptions, type FindValueForMixContrastResult, type GlazeColorFormat, type GlazeColorInput, type GlazeColorToken, type GlazeConfig, type GlazeCssOptions, type GlazeCssResult, type GlazeExtendOptions, type GlazeJsonOptions, type GlazeOutputModes, type GlazePalette, type GlazePaletteExportOptions, type GlazePaletteOptions, type GlazeShadowInput, type GlazeTheme, type GlazeThemeExport, type GlazeTokenOptions, type HCPair, type HexColor, type MinContrast, type MixColorDef, type OkhslColor, type RegularColorDef, type RelativeValue, type ResolvedColor, type ResolvedColorVariant, type ShadowColorDef, type ShadowTuning, contrastRatioFromLuminance, findLightnessForContrast, findValueForMixContrast, formatHsl, formatOkhsl, formatOklch, formatRgb, gamutClampedLuminance, glaze, okhslToLinearSrgb, okhslToOklab, okhslToSrgb, parseHex, relativeLuminanceFromLinearRgb, resolveMinContrast, srgbToOkhsl };
|
|
552
576
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -133,6 +133,11 @@ interface RegularColorDef {
|
|
|
133
133
|
* should not be combined (a console.warn is emitted).
|
|
134
134
|
*/
|
|
135
135
|
opacity?: number;
|
|
136
|
+
/**
|
|
137
|
+
* Whether this color is inherited by child themes created via `extend()`.
|
|
138
|
+
* Default: true. Set to false to make this color local to the current theme.
|
|
139
|
+
*/
|
|
140
|
+
inherit?: boolean;
|
|
136
141
|
}
|
|
137
142
|
/** Shadow tuning knobs. All values use the 0–1 scale (OKHSL). */
|
|
138
143
|
interface ShadowTuning {
|
|
@@ -177,6 +182,11 @@ interface ShadowColorDef {
|
|
|
177
182
|
intensity: HCPair<number>;
|
|
178
183
|
/** Override default tuning. Merged field-by-field with global `shadowTuning`. */
|
|
179
184
|
tuning?: ShadowTuning;
|
|
185
|
+
/**
|
|
186
|
+
* Whether this color is inherited by child themes created via `extend()`.
|
|
187
|
+
* Default: true. Set to false to make this color local to the current theme.
|
|
188
|
+
*/
|
|
189
|
+
inherit?: boolean;
|
|
180
190
|
}
|
|
181
191
|
interface MixColorDef {
|
|
182
192
|
type: 'mix';
|
|
@@ -211,6 +221,11 @@ interface MixColorDef {
|
|
|
211
221
|
* Supports [normal, highContrast] pair.
|
|
212
222
|
*/
|
|
213
223
|
contrast?: HCPair<MinContrast>;
|
|
224
|
+
/**
|
|
225
|
+
* Whether this color is inherited by child themes created via `extend()`.
|
|
226
|
+
* Default: true. Set to false to make this color local to the current theme.
|
|
227
|
+
*/
|
|
228
|
+
inherit?: boolean;
|
|
214
229
|
}
|
|
215
230
|
type ColorDef = RegularColorDef | ShadowColorDef | MixColorDef;
|
|
216
231
|
type ColorMap = Record<string, ColorDef>;
|
|
@@ -243,11 +258,12 @@ interface GlazeConfig {
|
|
|
243
258
|
/** Saturation reduction factor for dark scheme (0–1). Default: 0.1. */
|
|
244
259
|
darkDesaturation?: number;
|
|
245
260
|
/**
|
|
246
|
-
*
|
|
261
|
+
* Möbius beta for dark auto-inversion (0–1).
|
|
247
262
|
* Lower values expand subtle near-white distinctions in dark mode.
|
|
248
263
|
* Set to 1 for linear (legacy) behavior. Default: 0.5.
|
|
264
|
+
* Accepts [normal, highContrast] pair for separate HC tuning.
|
|
249
265
|
*/
|
|
250
|
-
darkCurve?: number
|
|
266
|
+
darkCurve?: HCPair<number>;
|
|
251
267
|
/** State alias names for token export. */
|
|
252
268
|
states?: {
|
|
253
269
|
dark?: string;
|
|
@@ -262,7 +278,7 @@ interface GlazeConfigResolved {
|
|
|
262
278
|
lightLightness: [number, number];
|
|
263
279
|
darkLightness: [number, number];
|
|
264
280
|
darkDesaturation: number;
|
|
265
|
-
darkCurve: number
|
|
281
|
+
darkCurve: HCPair<number>;
|
|
266
282
|
states: {
|
|
267
283
|
dark: string;
|
|
268
284
|
highContrast: string;
|
|
@@ -392,35 +408,47 @@ interface GlazeCssResult {
|
|
|
392
408
|
lightContrast: string;
|
|
393
409
|
darkContrast: string;
|
|
394
410
|
}
|
|
395
|
-
/** Options
|
|
396
|
-
interface
|
|
397
|
-
/**
|
|
398
|
-
* Prefix mode. `true` uses `"<themeName>-"`, or provide a custom map.
|
|
399
|
-
* Defaults to `true` for palette export methods.
|
|
400
|
-
* Set to `false` explicitly to disable prefixing (last-write-wins on collisions).
|
|
401
|
-
*/
|
|
402
|
-
prefix?: boolean | Record<string, string>;
|
|
411
|
+
/** Options for `glaze.palette()` creation. */
|
|
412
|
+
interface GlazePaletteOptions {
|
|
403
413
|
/**
|
|
404
414
|
* Name of the primary theme. The primary theme's tokens are duplicated
|
|
405
|
-
* without prefix, providing convenient short aliases
|
|
406
|
-
* prefixed versions.
|
|
415
|
+
* without prefix in all exports, providing convenient short aliases
|
|
416
|
+
* alongside the prefixed versions. Can be overridden per-export.
|
|
407
417
|
*
|
|
408
418
|
* @example
|
|
409
419
|
* ```ts
|
|
410
|
-
* palette.
|
|
420
|
+
* const palette = glaze.palette({ brand, accent }, { primary: 'brand' });
|
|
421
|
+
* palette.tokens()
|
|
411
422
|
* // → { light: { 'brand-surface': '...', 'surface': '...', 'accent-surface': '...' } }
|
|
412
423
|
* ```
|
|
413
424
|
*/
|
|
414
425
|
primary?: string;
|
|
415
426
|
}
|
|
427
|
+
/** Options shared by palette `tokens()`, `tasty()`, and `css()` exports. */
|
|
428
|
+
interface GlazePaletteExportOptions {
|
|
429
|
+
/**
|
|
430
|
+
* Prefix mode. `true` uses `"<themeName>-"`, or provide a custom map.
|
|
431
|
+
* Defaults to `true` for palette export methods.
|
|
432
|
+
* Set to `false` explicitly to disable prefixing. Colliding keys
|
|
433
|
+
* produce a console.warn and the first-written value wins.
|
|
434
|
+
*/
|
|
435
|
+
prefix?: boolean | Record<string, string>;
|
|
436
|
+
/**
|
|
437
|
+
* Override the palette-level primary theme for this export.
|
|
438
|
+
* Pass a theme name to set/change the primary, or `false` to disable it.
|
|
439
|
+
* When omitted, inherits the palette-level `primary`.
|
|
440
|
+
*/
|
|
441
|
+
primary?: string | false;
|
|
442
|
+
}
|
|
416
443
|
interface GlazePalette {
|
|
417
444
|
/**
|
|
418
445
|
* Export all themes as a flat token map grouped by scheme variant.
|
|
419
446
|
* Prefix defaults to `true` — all tokens are prefixed with the theme name.
|
|
420
|
-
*
|
|
447
|
+
* Inherits the palette-level `primary`; override per-call or pass `false` to disable.
|
|
421
448
|
*
|
|
422
449
|
* ```ts
|
|
423
|
-
* palette.
|
|
450
|
+
* const palette = glaze.palette({ brand, accent }, { primary: 'brand' });
|
|
451
|
+
* palette.tokens()
|
|
424
452
|
* // → { light: { 'brand-surface': '...', 'surface': '...', 'accent-surface': '...' } }
|
|
425
453
|
* ```
|
|
426
454
|
*/
|
|
@@ -428,12 +456,10 @@ interface GlazePalette {
|
|
|
428
456
|
/**
|
|
429
457
|
* Export all themes as tasty style-to-state bindings.
|
|
430
458
|
* Uses `#name` color token keys and state aliases (`''`, `@dark`, etc.).
|
|
431
|
-
* Prefix defaults to `true`.
|
|
459
|
+
* Prefix defaults to `true`. Inherits the palette-level `primary`.
|
|
432
460
|
* @see https://cube-ui-kit.vercel.app/?path=/docs/tasty-documentation--docs
|
|
433
461
|
*/
|
|
434
|
-
tasty(options?: GlazeTokenOptions &
|
|
435
|
-
primary?: string;
|
|
436
|
-
}): Record<string, Record<string, string>>;
|
|
462
|
+
tasty(options?: GlazeTokenOptions & GlazePaletteExportOptions): Record<string, Record<string, string>>;
|
|
437
463
|
/** Export all themes as plain JSON grouped by theme name. */
|
|
438
464
|
json(options?: GlazeJsonOptions & {
|
|
439
465
|
prefix?: boolean | Record<string, string>;
|
|
@@ -460,11 +486,9 @@ declare function glaze(hueOrOptions: number | {
|
|
|
460
486
|
}, saturation?: number): GlazeTheme;
|
|
461
487
|
declare namespace glaze {
|
|
462
488
|
var configure: (config: GlazeConfig) => void;
|
|
463
|
-
var palette: (themes: PaletteInput) => {
|
|
489
|
+
var palette: (themes: PaletteInput, options?: GlazePaletteOptions) => {
|
|
464
490
|
tokens(options?: GlazeJsonOptions & GlazePaletteExportOptions): Record<string, Record<string, string>>;
|
|
465
|
-
tasty(options?: GlazeTokenOptions &
|
|
466
|
-
primary?: string;
|
|
467
|
-
}): Record<string, Record<string, string>>;
|
|
491
|
+
tasty(options?: GlazeTokenOptions & GlazePaletteExportOptions): Record<string, Record<string, string>>;
|
|
468
492
|
json(options?: GlazeJsonOptions & {
|
|
469
493
|
prefix?: boolean | Record<string, string>;
|
|
470
494
|
}): Record<string, Record<string, Record<string, string>>>;
|
|
@@ -548,5 +572,5 @@ declare function formatHsl(h: number, s: number, l: number): string;
|
|
|
548
572
|
*/
|
|
549
573
|
declare function formatOklch(h: number, s: number, l: number): string;
|
|
550
574
|
//#endregion
|
|
551
|
-
export { type AdaptationMode, type ColorDef, type ColorMap, type ContrastPreset, type FindLightnessForContrastOptions, type FindLightnessForContrastResult, type FindValueForMixContrastOptions, type FindValueForMixContrastResult, type GlazeColorFormat, type GlazeColorInput, type GlazeColorToken, type GlazeConfig, type GlazeCssOptions, type GlazeCssResult, type GlazeExtendOptions, type GlazeJsonOptions, type GlazeOutputModes, type GlazePalette, type GlazePaletteExportOptions, type GlazeShadowInput, type GlazeTheme, type GlazeThemeExport, type GlazeTokenOptions, type HCPair, type HexColor, type MinContrast, type MixColorDef, type OkhslColor, type RegularColorDef, type RelativeValue, type ResolvedColor, type ResolvedColorVariant, type ShadowColorDef, type ShadowTuning, contrastRatioFromLuminance, findLightnessForContrast, findValueForMixContrast, formatHsl, formatOkhsl, formatOklch, formatRgb, gamutClampedLuminance, glaze, okhslToLinearSrgb, okhslToOklab, okhslToSrgb, parseHex, relativeLuminanceFromLinearRgb, resolveMinContrast, srgbToOkhsl };
|
|
575
|
+
export { type AdaptationMode, type ColorDef, type ColorMap, type ContrastPreset, type FindLightnessForContrastOptions, type FindLightnessForContrastResult, type FindValueForMixContrastOptions, type FindValueForMixContrastResult, type GlazeColorFormat, type GlazeColorInput, type GlazeColorToken, type GlazeConfig, type GlazeCssOptions, type GlazeCssResult, type GlazeExtendOptions, type GlazeJsonOptions, type GlazeOutputModes, type GlazePalette, type GlazePaletteExportOptions, type GlazePaletteOptions, type GlazeShadowInput, type GlazeTheme, type GlazeThemeExport, type GlazeTokenOptions, type HCPair, type HexColor, type MinContrast, type MixColorDef, type OkhslColor, type RegularColorDef, type RelativeValue, type ResolvedColor, type ResolvedColorVariant, type ShadowColorDef, type ShadowTuning, contrastRatioFromLuminance, findLightnessForContrast, findValueForMixContrast, formatHsl, formatOkhsl, formatOklch, formatRgb, gamutClampedLuminance, glaze, okhslToLinearSrgb, okhslToOklab, okhslToSrgb, parseHex, relativeLuminanceFromLinearRgb, resolveMinContrast, srgbToOkhsl };
|
|
552
576
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -960,31 +960,42 @@ function topoSort(defs) {
|
|
|
960
960
|
for (const name of Object.keys(defs)) visit(name);
|
|
961
961
|
return result;
|
|
962
962
|
}
|
|
963
|
+
function lightnessWindow(isHighContrast, kind) {
|
|
964
|
+
if (isHighContrast) return [0, 100];
|
|
965
|
+
return kind === "dark" ? globalConfig.darkLightness : globalConfig.lightLightness;
|
|
966
|
+
}
|
|
963
967
|
function mapLightnessLight(l, mode, isHighContrast) {
|
|
964
|
-
if (mode === "static"
|
|
965
|
-
const [lo, hi] =
|
|
968
|
+
if (mode === "static") return l;
|
|
969
|
+
const [lo, hi] = lightnessWindow(isHighContrast, "light");
|
|
966
970
|
return l * (hi - lo) / 100 + lo;
|
|
967
971
|
}
|
|
972
|
+
function mobiusCurve(t, beta) {
|
|
973
|
+
if (beta >= 1) return t;
|
|
974
|
+
return t / (t + beta * (1 - t));
|
|
975
|
+
}
|
|
968
976
|
function mapLightnessDark(l, mode, isHighContrast) {
|
|
969
977
|
if (mode === "static") return l;
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
const t = (100 - l) / 100;
|
|
973
|
-
return 100 * Math.pow(t, globalConfig.darkCurve);
|
|
974
|
-
}
|
|
975
|
-
const [darkLo, darkHi] = globalConfig.darkLightness;
|
|
978
|
+
const beta = isHighContrast ? pairHC(globalConfig.darkCurve) : pairNormal(globalConfig.darkCurve);
|
|
979
|
+
const [darkLo, darkHi] = lightnessWindow(isHighContrast, "dark");
|
|
976
980
|
if (mode === "fixed") return l * (darkHi - darkLo) / 100 + darkLo;
|
|
977
|
-
const [lightLo, lightHi] =
|
|
981
|
+
const [lightLo, lightHi] = lightnessWindow(isHighContrast, "light");
|
|
978
982
|
const t = (lightHi - (l * (lightHi - lightLo) / 100 + lightLo)) / (lightHi - lightLo);
|
|
979
|
-
return darkLo + (darkHi - darkLo) *
|
|
983
|
+
return darkLo + (darkHi - darkLo) * mobiusCurve(t, beta);
|
|
984
|
+
}
|
|
985
|
+
function lightMappedToDark(lightL, isHighContrast) {
|
|
986
|
+
const beta = isHighContrast ? pairHC(globalConfig.darkCurve) : pairNormal(globalConfig.darkCurve);
|
|
987
|
+
const [lightLo, lightHi] = lightnessWindow(isHighContrast, "light");
|
|
988
|
+
const [darkLo, darkHi] = lightnessWindow(isHighContrast, "dark");
|
|
989
|
+
const t = (lightHi - clamp(lightL, lightLo, lightHi)) / (lightHi - lightLo);
|
|
990
|
+
return darkLo + (darkHi - darkLo) * mobiusCurve(t, beta);
|
|
980
991
|
}
|
|
981
992
|
function mapSaturationDark(s, mode) {
|
|
982
993
|
if (mode === "static") return s;
|
|
983
994
|
return s * (1 - globalConfig.darkDesaturation);
|
|
984
995
|
}
|
|
985
996
|
function schemeLightnessRange(isDark, mode, isHighContrast) {
|
|
986
|
-
if (mode === "static"
|
|
987
|
-
const [lo, hi] = isDark ?
|
|
997
|
+
if (mode === "static") return [0, 1];
|
|
998
|
+
const [lo, hi] = lightnessWindow(isHighContrast, isDark ? "dark" : "light");
|
|
988
999
|
return [lo / 100, hi / 100];
|
|
989
1000
|
}
|
|
990
1001
|
function clamp(v, min, max) {
|
|
@@ -1043,9 +1054,9 @@ function resolveDependentColor(name, def, ctx, isHighContrast, isDark, effective
|
|
|
1043
1054
|
else {
|
|
1044
1055
|
const parsed = parseRelativeOrAbsolute(isHighContrast ? pairHC(rawLightness) : pairNormal(rawLightness));
|
|
1045
1056
|
if (parsed.relative) {
|
|
1046
|
-
|
|
1047
|
-
if (isDark && mode === "auto")
|
|
1048
|
-
preferredL = clamp(baseL + delta, 0, 100);
|
|
1057
|
+
const delta = parsed.value;
|
|
1058
|
+
if (isDark && mode === "auto") preferredL = lightMappedToDark(clamp(getSchemeVariant(baseResolved, false, isHighContrast).l * 100 + delta, 0, 100), isHighContrast);
|
|
1059
|
+
else preferredL = clamp(baseL + delta, 0, 100);
|
|
1049
1060
|
} else if (isDark) preferredL = mapLightnessDark(parsed.value, mode, isHighContrast);
|
|
1050
1061
|
else preferredL = mapLightnessLight(parsed.value, mode, isHighContrast);
|
|
1051
1062
|
}
|
|
@@ -1402,10 +1413,14 @@ function createTheme(hue, saturation, initialColors) {
|
|
|
1402
1413
|
};
|
|
1403
1414
|
},
|
|
1404
1415
|
extend(options) {
|
|
1405
|
-
|
|
1406
|
-
|
|
1416
|
+
const newHue = options.hue ?? hue;
|
|
1417
|
+
const newSat = options.saturation ?? saturation;
|
|
1418
|
+
const inheritedColors = {};
|
|
1419
|
+
for (const [name, def] of Object.entries(colorDefs)) if (def.inherit !== false) inheritedColors[name] = def;
|
|
1420
|
+
return createTheme(newHue, newSat, options.colors ? {
|
|
1421
|
+
...inheritedColors,
|
|
1407
1422
|
...options.colors
|
|
1408
|
-
} : { ...
|
|
1423
|
+
} : { ...inheritedColors });
|
|
1409
1424
|
},
|
|
1410
1425
|
resolve() {
|
|
1411
1426
|
return resolveAllColors(hue, saturation, colorDefs);
|
|
@@ -1439,40 +1454,74 @@ function validatePrimaryTheme(primary, themes) {
|
|
|
1439
1454
|
throw new Error(`glaze: primary theme "${primary}" not found in palette. Available: ${available}.`);
|
|
1440
1455
|
}
|
|
1441
1456
|
}
|
|
1442
|
-
|
|
1457
|
+
/**
|
|
1458
|
+
* Resolve the effective primary for an export call.
|
|
1459
|
+
* `false` disables, a string overrides, `undefined` inherits from palette.
|
|
1460
|
+
*/
|
|
1461
|
+
function resolveEffectivePrimary(exportPrimary, palettePrimary) {
|
|
1462
|
+
if (exportPrimary === false) return void 0;
|
|
1463
|
+
return exportPrimary ?? palettePrimary;
|
|
1464
|
+
}
|
|
1465
|
+
/**
|
|
1466
|
+
* Filter a resolved color map, skipping keys already in `seen`.
|
|
1467
|
+
* Warns on collision and keeps the first-written value (first-write-wins).
|
|
1468
|
+
* Returns a new map containing only non-colliding entries.
|
|
1469
|
+
*/
|
|
1470
|
+
function filterCollisions(resolved, prefix, seen, themeName, isPrimary) {
|
|
1471
|
+
const filtered = /* @__PURE__ */ new Map();
|
|
1472
|
+
const label = isPrimary ? `${themeName} (primary)` : themeName;
|
|
1473
|
+
for (const [name, color] of resolved) {
|
|
1474
|
+
const key = `${prefix}${name}`;
|
|
1475
|
+
if (seen.has(key)) {
|
|
1476
|
+
console.warn(`glaze: token "${key}" from theme "${label}" collides with theme "${seen.get(key)}" — skipping.`);
|
|
1477
|
+
continue;
|
|
1478
|
+
}
|
|
1479
|
+
seen.set(key, label);
|
|
1480
|
+
filtered.set(name, color);
|
|
1481
|
+
}
|
|
1482
|
+
return filtered;
|
|
1483
|
+
}
|
|
1484
|
+
function createPalette(themes, paletteOptions) {
|
|
1485
|
+
validatePrimaryTheme(paletteOptions?.primary, themes);
|
|
1443
1486
|
return {
|
|
1444
1487
|
tokens(options) {
|
|
1445
|
-
|
|
1488
|
+
const effectivePrimary = resolveEffectivePrimary(options?.primary, paletteOptions?.primary);
|
|
1489
|
+
if (options?.primary !== void 0) validatePrimaryTheme(effectivePrimary, themes);
|
|
1446
1490
|
const modes = resolveModes(options?.modes);
|
|
1447
1491
|
const allTokens = {};
|
|
1492
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1448
1493
|
for (const [themeName, theme] of Object.entries(themes)) {
|
|
1449
1494
|
const resolved = theme.resolve();
|
|
1450
|
-
const
|
|
1495
|
+
const prefix = resolvePrefix(options, themeName, true);
|
|
1496
|
+
const tokens = buildFlatTokenMap(filterCollisions(resolved, prefix, seen, themeName), prefix, modes, options?.format);
|
|
1451
1497
|
for (const variant of Object.keys(tokens)) {
|
|
1452
1498
|
if (!allTokens[variant]) allTokens[variant] = {};
|
|
1453
1499
|
Object.assign(allTokens[variant], tokens[variant]);
|
|
1454
1500
|
}
|
|
1455
|
-
if (themeName ===
|
|
1456
|
-
const unprefixed = buildFlatTokenMap(resolved, "", modes, options?.format);
|
|
1501
|
+
if (themeName === effectivePrimary) {
|
|
1502
|
+
const unprefixed = buildFlatTokenMap(filterCollisions(resolved, "", seen, themeName, true), "", modes, options?.format);
|
|
1457
1503
|
for (const variant of Object.keys(unprefixed)) Object.assign(allTokens[variant], unprefixed[variant]);
|
|
1458
1504
|
}
|
|
1459
1505
|
}
|
|
1460
1506
|
return allTokens;
|
|
1461
1507
|
},
|
|
1462
1508
|
tasty(options) {
|
|
1463
|
-
|
|
1509
|
+
const effectivePrimary = resolveEffectivePrimary(options?.primary, paletteOptions?.primary);
|
|
1510
|
+
if (options?.primary !== void 0) validatePrimaryTheme(effectivePrimary, themes);
|
|
1464
1511
|
const states = {
|
|
1465
1512
|
dark: options?.states?.dark ?? globalConfig.states.dark,
|
|
1466
1513
|
highContrast: options?.states?.highContrast ?? globalConfig.states.highContrast
|
|
1467
1514
|
};
|
|
1468
1515
|
const modes = resolveModes(options?.modes);
|
|
1469
1516
|
const allTokens = {};
|
|
1517
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1470
1518
|
for (const [themeName, theme] of Object.entries(themes)) {
|
|
1471
1519
|
const resolved = theme.resolve();
|
|
1472
|
-
const
|
|
1520
|
+
const prefix = resolvePrefix(options, themeName, true);
|
|
1521
|
+
const tokens = buildTokenMap(filterCollisions(resolved, prefix, seen, themeName), prefix, states, modes, options?.format);
|
|
1473
1522
|
Object.assign(allTokens, tokens);
|
|
1474
|
-
if (themeName ===
|
|
1475
|
-
const unprefixed = buildTokenMap(resolved, "", states, modes, options?.format);
|
|
1523
|
+
if (themeName === effectivePrimary) {
|
|
1524
|
+
const unprefixed = buildTokenMap(filterCollisions(resolved, "", seen, themeName, true), "", states, modes, options?.format);
|
|
1476
1525
|
Object.assign(allTokens, unprefixed);
|
|
1477
1526
|
}
|
|
1478
1527
|
}
|
|
@@ -1485,7 +1534,8 @@ function createPalette(themes) {
|
|
|
1485
1534
|
return result;
|
|
1486
1535
|
},
|
|
1487
1536
|
css(options) {
|
|
1488
|
-
|
|
1537
|
+
const effectivePrimary = resolveEffectivePrimary(options?.primary, paletteOptions?.primary);
|
|
1538
|
+
if (options?.primary !== void 0) validatePrimaryTheme(effectivePrimary, themes);
|
|
1489
1539
|
const suffix = options?.suffix ?? "-color";
|
|
1490
1540
|
const format = options?.format ?? "rgb";
|
|
1491
1541
|
const allLines = {
|
|
@@ -1494,17 +1544,19 @@ function createPalette(themes) {
|
|
|
1494
1544
|
lightContrast: [],
|
|
1495
1545
|
darkContrast: []
|
|
1496
1546
|
};
|
|
1547
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1497
1548
|
for (const [themeName, theme] of Object.entries(themes)) {
|
|
1498
1549
|
const resolved = theme.resolve();
|
|
1499
|
-
const
|
|
1550
|
+
const prefix = resolvePrefix(options, themeName, true);
|
|
1551
|
+
const css = buildCssMap(filterCollisions(resolved, prefix, seen, themeName), prefix, suffix, format);
|
|
1500
1552
|
for (const key of [
|
|
1501
1553
|
"light",
|
|
1502
1554
|
"dark",
|
|
1503
1555
|
"lightContrast",
|
|
1504
1556
|
"darkContrast"
|
|
1505
1557
|
]) if (css[key]) allLines[key].push(css[key]);
|
|
1506
|
-
if (themeName ===
|
|
1507
|
-
const unprefixed = buildCssMap(resolved, "", suffix, format);
|
|
1558
|
+
if (themeName === effectivePrimary) {
|
|
1559
|
+
const unprefixed = buildCssMap(filterCollisions(resolved, "", seen, themeName, true), "", suffix, format);
|
|
1508
1560
|
for (const key of [
|
|
1509
1561
|
"light",
|
|
1510
1562
|
"dark",
|
|
@@ -1586,8 +1638,8 @@ glaze.configure = function configure(config) {
|
|
|
1586
1638
|
/**
|
|
1587
1639
|
* Compose multiple themes into a palette.
|
|
1588
1640
|
*/
|
|
1589
|
-
glaze.palette = function palette(themes) {
|
|
1590
|
-
return createPalette(themes);
|
|
1641
|
+
glaze.palette = function palette(themes, options) {
|
|
1642
|
+
return createPalette(themes, options);
|
|
1591
1643
|
};
|
|
1592
1644
|
/**
|
|
1593
1645
|
* Create a theme from a serialized export.
|