@tenphi/glaze 0.0.0-snapshot.c13086f → 0.0.0-snapshot.c8281e2
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 +58 -22
- package/dist/index.cjs +59 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -19
- package/dist/index.d.mts +39 -19
- package/dist/index.mjs +59 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -385,33 +385,54 @@ interface GlazeCssResult {
|
|
|
385
385
|
lightContrast: string;
|
|
386
386
|
darkContrast: string;
|
|
387
387
|
}
|
|
388
|
+
/** Options shared by palette `tokens()`, `tasty()`, and `css()` exports. */
|
|
389
|
+
interface GlazePaletteExportOptions {
|
|
390
|
+
/**
|
|
391
|
+
* Prefix mode. `true` uses `"<themeName>-"`, or provide a custom map.
|
|
392
|
+
* Defaults to `true` for palette export methods.
|
|
393
|
+
* Set to `false` explicitly to disable prefixing (last-write-wins on collisions).
|
|
394
|
+
*/
|
|
395
|
+
prefix?: boolean | Record<string, string>;
|
|
396
|
+
/**
|
|
397
|
+
* Name of the primary theme. The primary theme's tokens are duplicated
|
|
398
|
+
* without prefix, providing convenient short aliases alongside the
|
|
399
|
+
* prefixed versions.
|
|
400
|
+
*
|
|
401
|
+
* @example
|
|
402
|
+
* ```ts
|
|
403
|
+
* palette.tokens({ primary: 'brand' })
|
|
404
|
+
* // → { light: { 'brand-surface': '...', 'surface': '...', 'accent-surface': '...' } }
|
|
405
|
+
* ```
|
|
406
|
+
*/
|
|
407
|
+
primary?: string;
|
|
408
|
+
}
|
|
388
409
|
interface GlazePalette {
|
|
389
410
|
/**
|
|
390
411
|
* Export all themes as a flat token map grouped by scheme variant.
|
|
412
|
+
* Prefix defaults to `true` — all tokens are prefixed with the theme name.
|
|
413
|
+
* Use `primary` to duplicate one theme's tokens without prefix.
|
|
391
414
|
*
|
|
392
415
|
* ```ts
|
|
393
|
-
* palette.tokens({
|
|
394
|
-
* // → { light: { '
|
|
416
|
+
* palette.tokens({ primary: 'brand' })
|
|
417
|
+
* // → { light: { 'brand-surface': '...', 'surface': '...', 'accent-surface': '...' } }
|
|
395
418
|
* ```
|
|
396
419
|
*/
|
|
397
|
-
tokens(options?: GlazeJsonOptions &
|
|
398
|
-
prefix?: boolean | Record<string, string>;
|
|
399
|
-
}): Record<string, Record<string, string>>;
|
|
420
|
+
tokens(options?: GlazeJsonOptions & GlazePaletteExportOptions): Record<string, Record<string, string>>;
|
|
400
421
|
/**
|
|
401
422
|
* Export all themes as tasty style-to-state bindings.
|
|
402
423
|
* Uses `#name` color token keys and state aliases (`''`, `@dark`, etc.).
|
|
403
|
-
*
|
|
424
|
+
* Prefix defaults to `true`. Use `primary` to duplicate one theme without prefix.
|
|
404
425
|
* @see https://cube-ui-kit.vercel.app/?path=/docs/tasty-documentation--docs
|
|
405
426
|
*/
|
|
406
|
-
tasty(options?: GlazeTokenOptions
|
|
407
|
-
|
|
427
|
+
tasty(options?: GlazeTokenOptions & {
|
|
428
|
+
primary?: string;
|
|
429
|
+
}): Record<string, Record<string, string>>;
|
|
430
|
+
/** Export all themes as plain JSON grouped by theme name. */
|
|
408
431
|
json(options?: GlazeJsonOptions & {
|
|
409
432
|
prefix?: boolean | Record<string, string>;
|
|
410
433
|
}): Record<string, Record<string, Record<string, string>>>;
|
|
411
434
|
/** Export all themes as CSS custom property declarations. */
|
|
412
|
-
css(options?: GlazeCssOptions &
|
|
413
|
-
prefix?: boolean | Record<string, string>;
|
|
414
|
-
}): GlazeCssResult;
|
|
435
|
+
css(options?: GlazeCssOptions & GlazePaletteExportOptions): GlazeCssResult;
|
|
415
436
|
}
|
|
416
437
|
//#endregion
|
|
417
438
|
//#region src/glaze.d.ts
|
|
@@ -433,16 +454,14 @@ declare function glaze(hueOrOptions: number | {
|
|
|
433
454
|
declare namespace glaze {
|
|
434
455
|
var configure: (config: GlazeConfig) => void;
|
|
435
456
|
var palette: (themes: PaletteInput) => {
|
|
436
|
-
tokens(options?: GlazeJsonOptions &
|
|
437
|
-
|
|
457
|
+
tokens(options?: GlazeJsonOptions & GlazePaletteExportOptions): Record<string, Record<string, string>>;
|
|
458
|
+
tasty(options?: GlazeTokenOptions & {
|
|
459
|
+
primary?: string;
|
|
438
460
|
}): Record<string, Record<string, string>>;
|
|
439
|
-
tasty(options?: GlazeTokenOptions): Record<string, Record<string, string>>;
|
|
440
461
|
json(options?: GlazeJsonOptions & {
|
|
441
462
|
prefix?: boolean | Record<string, string>;
|
|
442
463
|
}): Record<string, Record<string, Record<string, string>>>;
|
|
443
|
-
css(options?: GlazeCssOptions &
|
|
444
|
-
prefix?: boolean | Record<string, string>;
|
|
445
|
-
}): GlazeCssResult;
|
|
464
|
+
css(options?: GlazeCssOptions & GlazePaletteExportOptions): GlazeCssResult;
|
|
446
465
|
};
|
|
447
466
|
var from: (data: GlazeThemeExport) => GlazeTheme;
|
|
448
467
|
var color: (input: GlazeColorInput) => GlazeColorToken;
|
|
@@ -506,7 +525,8 @@ declare function parseHex(hex: string): [number, number, number] | null;
|
|
|
506
525
|
*/
|
|
507
526
|
declare function formatOkhsl(h: number, s: number, l: number): string;
|
|
508
527
|
/**
|
|
509
|
-
* Format OKHSL values as a CSS `rgb(R G B)` string
|
|
528
|
+
* Format OKHSL values as a CSS `rgb(R G B)` string.
|
|
529
|
+
* Uses 2 decimal places to avoid 8-bit quantization contrast loss.
|
|
510
530
|
* h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
|
|
511
531
|
*/
|
|
512
532
|
declare function formatRgb(h: number, s: number, l: number): string;
|
|
@@ -521,5 +541,5 @@ declare function formatHsl(h: number, s: number, l: number): string;
|
|
|
521
541
|
*/
|
|
522
542
|
declare function formatOklch(h: number, s: number, l: number): string;
|
|
523
543
|
//#endregion
|
|
524
|
-
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 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 };
|
|
544
|
+
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 };
|
|
525
545
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -385,33 +385,54 @@ interface GlazeCssResult {
|
|
|
385
385
|
lightContrast: string;
|
|
386
386
|
darkContrast: string;
|
|
387
387
|
}
|
|
388
|
+
/** Options shared by palette `tokens()`, `tasty()`, and `css()` exports. */
|
|
389
|
+
interface GlazePaletteExportOptions {
|
|
390
|
+
/**
|
|
391
|
+
* Prefix mode. `true` uses `"<themeName>-"`, or provide a custom map.
|
|
392
|
+
* Defaults to `true` for palette export methods.
|
|
393
|
+
* Set to `false` explicitly to disable prefixing (last-write-wins on collisions).
|
|
394
|
+
*/
|
|
395
|
+
prefix?: boolean | Record<string, string>;
|
|
396
|
+
/**
|
|
397
|
+
* Name of the primary theme. The primary theme's tokens are duplicated
|
|
398
|
+
* without prefix, providing convenient short aliases alongside the
|
|
399
|
+
* prefixed versions.
|
|
400
|
+
*
|
|
401
|
+
* @example
|
|
402
|
+
* ```ts
|
|
403
|
+
* palette.tokens({ primary: 'brand' })
|
|
404
|
+
* // → { light: { 'brand-surface': '...', 'surface': '...', 'accent-surface': '...' } }
|
|
405
|
+
* ```
|
|
406
|
+
*/
|
|
407
|
+
primary?: string;
|
|
408
|
+
}
|
|
388
409
|
interface GlazePalette {
|
|
389
410
|
/**
|
|
390
411
|
* Export all themes as a flat token map grouped by scheme variant.
|
|
412
|
+
* Prefix defaults to `true` — all tokens are prefixed with the theme name.
|
|
413
|
+
* Use `primary` to duplicate one theme's tokens without prefix.
|
|
391
414
|
*
|
|
392
415
|
* ```ts
|
|
393
|
-
* palette.tokens({
|
|
394
|
-
* // → { light: { '
|
|
416
|
+
* palette.tokens({ primary: 'brand' })
|
|
417
|
+
* // → { light: { 'brand-surface': '...', 'surface': '...', 'accent-surface': '...' } }
|
|
395
418
|
* ```
|
|
396
419
|
*/
|
|
397
|
-
tokens(options?: GlazeJsonOptions &
|
|
398
|
-
prefix?: boolean | Record<string, string>;
|
|
399
|
-
}): Record<string, Record<string, string>>;
|
|
420
|
+
tokens(options?: GlazeJsonOptions & GlazePaletteExportOptions): Record<string, Record<string, string>>;
|
|
400
421
|
/**
|
|
401
422
|
* Export all themes as tasty style-to-state bindings.
|
|
402
423
|
* Uses `#name` color token keys and state aliases (`''`, `@dark`, etc.).
|
|
403
|
-
*
|
|
424
|
+
* Prefix defaults to `true`. Use `primary` to duplicate one theme without prefix.
|
|
404
425
|
* @see https://cube-ui-kit.vercel.app/?path=/docs/tasty-documentation--docs
|
|
405
426
|
*/
|
|
406
|
-
tasty(options?: GlazeTokenOptions
|
|
407
|
-
|
|
427
|
+
tasty(options?: GlazeTokenOptions & {
|
|
428
|
+
primary?: string;
|
|
429
|
+
}): Record<string, Record<string, string>>;
|
|
430
|
+
/** Export all themes as plain JSON grouped by theme name. */
|
|
408
431
|
json(options?: GlazeJsonOptions & {
|
|
409
432
|
prefix?: boolean | Record<string, string>;
|
|
410
433
|
}): Record<string, Record<string, Record<string, string>>>;
|
|
411
434
|
/** Export all themes as CSS custom property declarations. */
|
|
412
|
-
css(options?: GlazeCssOptions &
|
|
413
|
-
prefix?: boolean | Record<string, string>;
|
|
414
|
-
}): GlazeCssResult;
|
|
435
|
+
css(options?: GlazeCssOptions & GlazePaletteExportOptions): GlazeCssResult;
|
|
415
436
|
}
|
|
416
437
|
//#endregion
|
|
417
438
|
//#region src/glaze.d.ts
|
|
@@ -433,16 +454,14 @@ declare function glaze(hueOrOptions: number | {
|
|
|
433
454
|
declare namespace glaze {
|
|
434
455
|
var configure: (config: GlazeConfig) => void;
|
|
435
456
|
var palette: (themes: PaletteInput) => {
|
|
436
|
-
tokens(options?: GlazeJsonOptions &
|
|
437
|
-
|
|
457
|
+
tokens(options?: GlazeJsonOptions & GlazePaletteExportOptions): Record<string, Record<string, string>>;
|
|
458
|
+
tasty(options?: GlazeTokenOptions & {
|
|
459
|
+
primary?: string;
|
|
438
460
|
}): Record<string, Record<string, string>>;
|
|
439
|
-
tasty(options?: GlazeTokenOptions): Record<string, Record<string, string>>;
|
|
440
461
|
json(options?: GlazeJsonOptions & {
|
|
441
462
|
prefix?: boolean | Record<string, string>;
|
|
442
463
|
}): Record<string, Record<string, Record<string, string>>>;
|
|
443
|
-
css(options?: GlazeCssOptions &
|
|
444
|
-
prefix?: boolean | Record<string, string>;
|
|
445
|
-
}): GlazeCssResult;
|
|
464
|
+
css(options?: GlazeCssOptions & GlazePaletteExportOptions): GlazeCssResult;
|
|
446
465
|
};
|
|
447
466
|
var from: (data: GlazeThemeExport) => GlazeTheme;
|
|
448
467
|
var color: (input: GlazeColorInput) => GlazeColorToken;
|
|
@@ -506,7 +525,8 @@ declare function parseHex(hex: string): [number, number, number] | null;
|
|
|
506
525
|
*/
|
|
507
526
|
declare function formatOkhsl(h: number, s: number, l: number): string;
|
|
508
527
|
/**
|
|
509
|
-
* Format OKHSL values as a CSS `rgb(R G B)` string
|
|
528
|
+
* Format OKHSL values as a CSS `rgb(R G B)` string.
|
|
529
|
+
* Uses 2 decimal places to avoid 8-bit quantization contrast loss.
|
|
510
530
|
* h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
|
|
511
531
|
*/
|
|
512
532
|
declare function formatRgb(h: number, s: number, l: number): string;
|
|
@@ -521,5 +541,5 @@ declare function formatHsl(h: number, s: number, l: number): string;
|
|
|
521
541
|
*/
|
|
522
542
|
declare function formatOklch(h: number, s: number, l: number): string;
|
|
523
543
|
//#endregion
|
|
524
|
-
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 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 };
|
|
544
|
+
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 };
|
|
525
545
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -431,12 +431,13 @@ function formatOkhsl(h, s, l) {
|
|
|
431
431
|
return `okhsl(${fmt$1(h, 2)} ${fmt$1(s, 2)}% ${fmt$1(l, 2)}%)`;
|
|
432
432
|
}
|
|
433
433
|
/**
|
|
434
|
-
* Format OKHSL values as a CSS `rgb(R G B)` string
|
|
434
|
+
* Format OKHSL values as a CSS `rgb(R G B)` string.
|
|
435
|
+
* Uses 2 decimal places to avoid 8-bit quantization contrast loss.
|
|
435
436
|
* h: 0–360, s: 0–100, l: 0–100 (percentage scale for s and l).
|
|
436
437
|
*/
|
|
437
438
|
function formatRgb(h, s, l) {
|
|
438
439
|
const [r, g, b] = okhslToSrgb(h, s / 100, l / 100);
|
|
439
|
-
return `rgb(${
|
|
440
|
+
return `rgb(${parseFloat((r * 255).toFixed(2))} ${parseFloat((g * 255).toFixed(2))} ${parseFloat((b * 255).toFixed(2))})`;
|
|
440
441
|
}
|
|
441
442
|
/**
|
|
442
443
|
* Format OKHSL values as a CSS `hsl(H S% L%)` string.
|
|
@@ -467,7 +468,7 @@ function formatOklch(h, s, l) {
|
|
|
467
468
|
const C = Math.sqrt(a * a + b * b);
|
|
468
469
|
let hh = Math.atan2(b, a) * (180 / Math.PI);
|
|
469
470
|
hh = constrainAngle(hh);
|
|
470
|
-
return `oklch(${fmt$1(L, 4)} ${fmt$1(C, 4)} ${fmt$1(hh,
|
|
471
|
+
return `oklch(${fmt$1(L, 4)} ${fmt$1(C, 4)} ${fmt$1(hh, 2)})`;
|
|
471
472
|
}
|
|
472
473
|
|
|
473
474
|
//#endregion
|
|
@@ -617,7 +618,7 @@ function coarseScan(h, s, lo, hi, yBase, target, epsilon, maxIter) {
|
|
|
617
618
|
function findLightnessForContrast(options) {
|
|
618
619
|
const { hue, saturation, preferredLightness, baseLinearRgb, contrast: contrastInput, lightnessRange = [0, 1], epsilon = 1e-4, maxIterations = 14 } = options;
|
|
619
620
|
const target = resolveMinContrast(contrastInput);
|
|
620
|
-
const searchTarget = target
|
|
621
|
+
const searchTarget = target * 1.007;
|
|
621
622
|
const yBase = gamutClampedLuminance(baseLinearRgb);
|
|
622
623
|
const crPref = contrastRatioFromLuminance(cachedLuminance(hue, saturation, preferredLightness), yBase);
|
|
623
624
|
if (crPref >= searchTarget) return {
|
|
@@ -741,7 +742,7 @@ function searchMixBranch(lo, hi, yBase, target, epsilon, maxIter, preferred, lum
|
|
|
741
742
|
function findValueForMixContrast(options) {
|
|
742
743
|
const { preferredValue, baseLinearRgb, contrast: contrastInput, luminanceAtValue, epsilon = 1e-4, maxIterations = 20 } = options;
|
|
743
744
|
const target = resolveMinContrast(contrastInput);
|
|
744
|
-
const searchTarget = target
|
|
745
|
+
const searchTarget = target * 1.01;
|
|
745
746
|
const yBase = gamutClampedLuminance(baseLinearRgb);
|
|
746
747
|
const crPref = contrastRatioFromLuminance(luminanceAtValue(preferredValue), yBase);
|
|
747
748
|
if (crPref >= searchTarget) return {
|
|
@@ -958,13 +959,14 @@ function topoSort(defs) {
|
|
|
958
959
|
for (const name of Object.keys(defs)) visit(name);
|
|
959
960
|
return result;
|
|
960
961
|
}
|
|
961
|
-
function mapLightnessLight(l, mode) {
|
|
962
|
-
if (mode === "static") return l;
|
|
962
|
+
function mapLightnessLight(l, mode, isHighContrast) {
|
|
963
|
+
if (mode === "static" || isHighContrast) return l;
|
|
963
964
|
const [lo, hi] = globalConfig.lightLightness;
|
|
964
965
|
return l * (hi - lo) / 100 + lo;
|
|
965
966
|
}
|
|
966
|
-
function mapLightnessDark(l, mode) {
|
|
967
|
+
function mapLightnessDark(l, mode, isHighContrast) {
|
|
967
968
|
if (mode === "static") return l;
|
|
969
|
+
if (isHighContrast) return mode === "fixed" ? l : 100 - l;
|
|
968
970
|
const [lo, hi] = globalConfig.darkLightness;
|
|
969
971
|
if (mode === "fixed") return l * (hi - lo) / 100 + lo;
|
|
970
972
|
return (100 - l) * (hi - lo) / 100 + lo;
|
|
@@ -973,6 +975,11 @@ function mapSaturationDark(s, mode) {
|
|
|
973
975
|
if (mode === "static") return s;
|
|
974
976
|
return s * (1 - globalConfig.darkDesaturation);
|
|
975
977
|
}
|
|
978
|
+
function schemeLightnessRange(isDark, mode, isHighContrast) {
|
|
979
|
+
if (mode === "static" || isHighContrast) return [0, 1];
|
|
980
|
+
const [lo, hi] = isDark ? globalConfig.darkLightness : globalConfig.lightLightness;
|
|
981
|
+
return [lo / 100, hi / 100];
|
|
982
|
+
}
|
|
976
983
|
function clamp(v, min, max) {
|
|
977
984
|
return Math.max(min, Math.min(max, v));
|
|
978
985
|
}
|
|
@@ -1032,21 +1039,23 @@ function resolveDependentColor(name, def, ctx, isHighContrast, isDark, effective
|
|
|
1032
1039
|
let delta = parsed.value;
|
|
1033
1040
|
if (isDark && mode === "auto") delta = -delta;
|
|
1034
1041
|
preferredL = clamp(baseL + delta, 0, 100);
|
|
1035
|
-
} else if (isDark) preferredL = mapLightnessDark(parsed.value, mode);
|
|
1036
|
-
else preferredL =
|
|
1042
|
+
} else if (isDark) preferredL = mapLightnessDark(parsed.value, mode, isHighContrast);
|
|
1043
|
+
else preferredL = mapLightnessLight(parsed.value, mode, isHighContrast);
|
|
1037
1044
|
}
|
|
1038
1045
|
const rawContrast = def.contrast;
|
|
1039
1046
|
if (rawContrast !== void 0) {
|
|
1040
1047
|
const minCr = isHighContrast ? pairHC(rawContrast) : pairNormal(rawContrast);
|
|
1041
1048
|
const effectiveSat = isDark ? mapSaturationDark(satFactor * ctx.saturation / 100, mode) : satFactor * ctx.saturation / 100;
|
|
1042
1049
|
const baseLinearRgb = okhslToLinearSrgb(baseVariant.h, baseVariant.s, baseVariant.l);
|
|
1050
|
+
const lightnessRange = schemeLightnessRange(isDark, mode, isHighContrast);
|
|
1043
1051
|
return {
|
|
1044
1052
|
l: findLightnessForContrast({
|
|
1045
1053
|
hue: effectiveHue,
|
|
1046
1054
|
saturation: effectiveSat,
|
|
1047
|
-
preferredLightness: preferredL / 100,
|
|
1055
|
+
preferredLightness: clamp(preferredL / 100, lightnessRange[0], lightnessRange[1]),
|
|
1048
1056
|
baseLinearRgb,
|
|
1049
|
-
contrast: minCr
|
|
1057
|
+
contrast: minCr,
|
|
1058
|
+
lightnessRange
|
|
1050
1059
|
}).lightness * 100,
|
|
1051
1060
|
satFactor
|
|
1052
1061
|
};
|
|
@@ -1083,13 +1092,13 @@ function resolveColorForScheme(name, def, ctx, isDark, isHighContrast) {
|
|
|
1083
1092
|
let finalL;
|
|
1084
1093
|
let finalSat;
|
|
1085
1094
|
if (isDark && isRoot) {
|
|
1086
|
-
finalL = mapLightnessDark(lightL, mode);
|
|
1095
|
+
finalL = mapLightnessDark(lightL, mode, isHighContrast);
|
|
1087
1096
|
finalSat = mapSaturationDark(satFactor * ctx.saturation / 100, mode);
|
|
1088
1097
|
} else if (isDark && !isRoot) {
|
|
1089
1098
|
finalL = lightL;
|
|
1090
1099
|
finalSat = mapSaturationDark(satFactor * ctx.saturation / 100, mode);
|
|
1091
1100
|
} else if (isRoot) {
|
|
1092
|
-
finalL = mapLightnessLight(lightL, mode);
|
|
1101
|
+
finalL = mapLightnessLight(lightL, mode, isHighContrast);
|
|
1093
1102
|
finalSat = satFactor * ctx.saturation / 100;
|
|
1094
1103
|
} else {
|
|
1095
1104
|
finalL = lightL;
|
|
@@ -1411,26 +1420,40 @@ function createTheme(hue, saturation, initialColors) {
|
|
|
1411
1420
|
}
|
|
1412
1421
|
};
|
|
1413
1422
|
}
|
|
1414
|
-
function resolvePrefix(options, themeName) {
|
|
1415
|
-
|
|
1416
|
-
if (
|
|
1423
|
+
function resolvePrefix(options, themeName, defaultPrefix = false) {
|
|
1424
|
+
const prefix = options?.prefix ?? defaultPrefix;
|
|
1425
|
+
if (prefix === true) return `${themeName}-`;
|
|
1426
|
+
if (typeof prefix === "object" && prefix !== null) return prefix[themeName] ?? `${themeName}-`;
|
|
1417
1427
|
return "";
|
|
1418
1428
|
}
|
|
1429
|
+
function validatePrimaryTheme(primary, themes) {
|
|
1430
|
+
if (primary !== void 0 && !(primary in themes)) {
|
|
1431
|
+
const available = Object.keys(themes).join(", ");
|
|
1432
|
+
throw new Error(`glaze: primary theme "${primary}" not found in palette. Available: ${available}.`);
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1419
1435
|
function createPalette(themes) {
|
|
1420
1436
|
return {
|
|
1421
1437
|
tokens(options) {
|
|
1438
|
+
validatePrimaryTheme(options?.primary, themes);
|
|
1422
1439
|
const modes = resolveModes(options?.modes);
|
|
1423
1440
|
const allTokens = {};
|
|
1424
1441
|
for (const [themeName, theme] of Object.entries(themes)) {
|
|
1425
|
-
const
|
|
1442
|
+
const resolved = theme.resolve();
|
|
1443
|
+
const tokens = buildFlatTokenMap(resolved, resolvePrefix(options, themeName, true), modes, options?.format);
|
|
1426
1444
|
for (const variant of Object.keys(tokens)) {
|
|
1427
1445
|
if (!allTokens[variant]) allTokens[variant] = {};
|
|
1428
1446
|
Object.assign(allTokens[variant], tokens[variant]);
|
|
1429
1447
|
}
|
|
1448
|
+
if (themeName === options?.primary) {
|
|
1449
|
+
const unprefixed = buildFlatTokenMap(resolved, "", modes, options?.format);
|
|
1450
|
+
for (const variant of Object.keys(unprefixed)) Object.assign(allTokens[variant], unprefixed[variant]);
|
|
1451
|
+
}
|
|
1430
1452
|
}
|
|
1431
1453
|
return allTokens;
|
|
1432
1454
|
},
|
|
1433
1455
|
tasty(options) {
|
|
1456
|
+
validatePrimaryTheme(options?.primary, themes);
|
|
1434
1457
|
const states = {
|
|
1435
1458
|
dark: options?.states?.dark ?? globalConfig.states.dark,
|
|
1436
1459
|
highContrast: options?.states?.highContrast ?? globalConfig.states.highContrast
|
|
@@ -1438,8 +1461,13 @@ function createPalette(themes) {
|
|
|
1438
1461
|
const modes = resolveModes(options?.modes);
|
|
1439
1462
|
const allTokens = {};
|
|
1440
1463
|
for (const [themeName, theme] of Object.entries(themes)) {
|
|
1441
|
-
const
|
|
1464
|
+
const resolved = theme.resolve();
|
|
1465
|
+
const tokens = buildTokenMap(resolved, resolvePrefix(options, themeName, true), states, modes, options?.format);
|
|
1442
1466
|
Object.assign(allTokens, tokens);
|
|
1467
|
+
if (themeName === options?.primary) {
|
|
1468
|
+
const unprefixed = buildTokenMap(resolved, "", states, modes, options?.format);
|
|
1469
|
+
Object.assign(allTokens, unprefixed);
|
|
1470
|
+
}
|
|
1443
1471
|
}
|
|
1444
1472
|
return allTokens;
|
|
1445
1473
|
},
|
|
@@ -1450,6 +1478,7 @@ function createPalette(themes) {
|
|
|
1450
1478
|
return result;
|
|
1451
1479
|
},
|
|
1452
1480
|
css(options) {
|
|
1481
|
+
validatePrimaryTheme(options?.primary, themes);
|
|
1453
1482
|
const suffix = options?.suffix ?? "-color";
|
|
1454
1483
|
const format = options?.format ?? "rgb";
|
|
1455
1484
|
const allLines = {
|
|
@@ -1459,13 +1488,23 @@ function createPalette(themes) {
|
|
|
1459
1488
|
darkContrast: []
|
|
1460
1489
|
};
|
|
1461
1490
|
for (const [themeName, theme] of Object.entries(themes)) {
|
|
1462
|
-
const
|
|
1491
|
+
const resolved = theme.resolve();
|
|
1492
|
+
const css = buildCssMap(resolved, resolvePrefix(options, themeName, true), suffix, format);
|
|
1463
1493
|
for (const key of [
|
|
1464
1494
|
"light",
|
|
1465
1495
|
"dark",
|
|
1466
1496
|
"lightContrast",
|
|
1467
1497
|
"darkContrast"
|
|
1468
1498
|
]) if (css[key]) allLines[key].push(css[key]);
|
|
1499
|
+
if (themeName === options?.primary) {
|
|
1500
|
+
const unprefixed = buildCssMap(resolved, "", suffix, format);
|
|
1501
|
+
for (const key of [
|
|
1502
|
+
"light",
|
|
1503
|
+
"dark",
|
|
1504
|
+
"lightContrast",
|
|
1505
|
+
"darkContrast"
|
|
1506
|
+
]) if (unprefixed[key]) allLines[key].push(unprefixed[key]);
|
|
1507
|
+
}
|
|
1469
1508
|
}
|
|
1470
1509
|
return {
|
|
1471
1510
|
light: allLines.light.join("\n"),
|