@tenphi/glaze 1.0.0 → 1.1.1
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 +1 -1
- package/dist/index.cjs +398 -237
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +101 -36
- package/dist/index.d.mts +101 -36
- package/dist/index.mjs +395 -238
- package/dist/index.mjs.map +1 -1
- package/docs/api.md +111 -53
- package/docs/migration.md +5 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -673,6 +673,8 @@ function okhslToOklch(h, s, l, pastel = false) {
|
|
|
673
673
|
/**
|
|
674
674
|
* Build a fresh defaults object. Called from module init and from
|
|
675
675
|
* `resetConfig()` so the two paths can't drift.
|
|
676
|
+
*
|
|
677
|
+
* `pastel: false` is a fixed instance default — not globally configurable.
|
|
676
678
|
*/
|
|
677
679
|
function defaultConfig() {
|
|
678
680
|
return {
|
|
@@ -737,7 +739,7 @@ function configure(config) {
|
|
|
737
739
|
},
|
|
738
740
|
shadowTuning: config.shadowTuning ?? globalConfig.shadowTuning,
|
|
739
741
|
autoFlip: config.autoFlip ?? globalConfig.autoFlip,
|
|
740
|
-
pastel:
|
|
742
|
+
pastel: false,
|
|
741
743
|
inferRole: config.inferRole ?? globalConfig.inferRole
|
|
742
744
|
};
|
|
743
745
|
}
|
|
@@ -750,9 +752,15 @@ function resetConfig() {
|
|
|
750
752
|
* Only fields present in `override` are replaced; others fall through
|
|
751
753
|
* from `base`. `false` for tone windows passes through as-is
|
|
752
754
|
* (treated as the full range by `activeWindow()` in okhst.ts).
|
|
755
|
+
*
|
|
756
|
+
* `pastel` is instance-only: `override.pastel ?? false`, never inherited
|
|
757
|
+
* from the global base.
|
|
753
758
|
*/
|
|
754
759
|
function mergeConfig(base, override) {
|
|
755
|
-
if (!override) return base
|
|
760
|
+
if (!override) return base.pastel === false ? base : {
|
|
761
|
+
...base,
|
|
762
|
+
pastel: false
|
|
763
|
+
};
|
|
756
764
|
return {
|
|
757
765
|
lightTone: override.lightTone !== void 0 ? override.lightTone : base.lightTone,
|
|
758
766
|
darkTone: override.darkTone !== void 0 ? override.darkTone : base.darkTone,
|
|
@@ -761,10 +769,99 @@ function mergeConfig(base, override) {
|
|
|
761
769
|
modes: base.modes,
|
|
762
770
|
shadowTuning: override.shadowTuning ?? base.shadowTuning,
|
|
763
771
|
autoFlip: override.autoFlip ?? base.autoFlip,
|
|
764
|
-
pastel: override.pastel ??
|
|
772
|
+
pastel: override.pastel ?? false,
|
|
765
773
|
inferRole: override.inferRole ?? base.inferRole
|
|
766
774
|
};
|
|
767
775
|
}
|
|
776
|
+
/**
|
|
777
|
+
* Freeze `getConfig() ∪ instanceLocal ∪ exportArg` as a plain, resolve-relevant
|
|
778
|
+
* override for authoring export, so restored snapshots pin these fields. Later
|
|
779
|
+
* wins; nested objects (`shadowTuning`) replace wholesale. The final
|
|
780
|
+
* `structuredClone` detaches tone-window / shadow objects that `mergeConfig`
|
|
781
|
+
* may still share with the live global config.
|
|
782
|
+
*/
|
|
783
|
+
function freezeConfigForExport(instanceLocal, exportArg) {
|
|
784
|
+
const effective = mergeConfig(getConfig(), {
|
|
785
|
+
...instanceLocal,
|
|
786
|
+
...exportArg
|
|
787
|
+
});
|
|
788
|
+
const out = {
|
|
789
|
+
lightTone: effective.lightTone,
|
|
790
|
+
darkTone: effective.darkTone,
|
|
791
|
+
darkDesaturation: effective.darkDesaturation,
|
|
792
|
+
autoFlip: effective.autoFlip,
|
|
793
|
+
pastel: effective.pastel,
|
|
794
|
+
inferRole: effective.inferRole
|
|
795
|
+
};
|
|
796
|
+
if (effective.shadowTuning !== void 0) out.shadowTuning = effective.shadowTuning;
|
|
797
|
+
return structuredClone(out);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
//#endregion
|
|
801
|
+
//#region src/types.ts
|
|
802
|
+
/**
|
|
803
|
+
* Current authoring-export schema version. Bump when the export shape
|
|
804
|
+
* changes in a non-compatible way. Written on every `.export()` snapshot.
|
|
805
|
+
*/
|
|
806
|
+
const GLAZE_EXPORT_VERSION = 1;
|
|
807
|
+
|
|
808
|
+
//#endregion
|
|
809
|
+
//#region src/serialize.ts
|
|
810
|
+
/**
|
|
811
|
+
* Authoring-export helpers: schema version, type guards, and restore
|
|
812
|
+
* validation shared by `themeFrom` / `colorFrom` / `paletteFrom`.
|
|
813
|
+
*/
|
|
814
|
+
function isPlainObject(data) {
|
|
815
|
+
return typeof data === "object" && data !== null && !Array.isArray(data);
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Reject unknown / invalid schema versions. Missing `version` is allowed
|
|
819
|
+
* (legacy snapshots). Present versions must be an integer in
|
|
820
|
+
* `1..=GLAZE_EXPORT_VERSION`.
|
|
821
|
+
*/
|
|
822
|
+
function assertExportVersion(data, factory) {
|
|
823
|
+
if (data.version === void 0) return;
|
|
824
|
+
if (typeof data.version !== "number" || !Number.isInteger(data.version) || data.version < 1) throw new Error(`${factory}: invalid "version" field — expected an integer >= 1 (got ${JSON.stringify(data.version)}).`);
|
|
825
|
+
if (data.version > GLAZE_EXPORT_VERSION) throw new Error(`${factory}: unsupported export version ${data.version} (this library supports version ${GLAZE_EXPORT_VERSION}). Upgrade @tenphi/glaze to load this snapshot.`);
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* When `kind` is present, it must match the factory. Missing `kind` is
|
|
829
|
+
* allowed for legacy snapshots.
|
|
830
|
+
*/
|
|
831
|
+
function assertExportKind(data, expected, factory) {
|
|
832
|
+
if (data.kind === void 0) return;
|
|
833
|
+
if (data.kind !== expected) throw new Error(`${factory}: expected kind "${expected}", got ${JSON.stringify(data.kind)}.`);
|
|
834
|
+
}
|
|
835
|
+
function hasThemeShape(data) {
|
|
836
|
+
return typeof data.hue === "number" && typeof data.saturation === "number" && !("form" in data) && !("themes" in data);
|
|
837
|
+
}
|
|
838
|
+
function hasColorTokenShape(data) {
|
|
839
|
+
return data.form === "value" || data.form === "structured";
|
|
840
|
+
}
|
|
841
|
+
function hasPaletteShape(data) {
|
|
842
|
+
return isPlainObject(data.themes) && !("form" in data) && typeof data.hue !== "number";
|
|
843
|
+
}
|
|
844
|
+
/** Type guard for theme authoring snapshots (prefers `kind`, falls back to shape). */
|
|
845
|
+
function isThemeExport(data) {
|
|
846
|
+
if (!isPlainObject(data)) return false;
|
|
847
|
+
if (data.kind === "theme") return hasThemeShape(data);
|
|
848
|
+
if (data.kind !== void 0) return false;
|
|
849
|
+
return hasThemeShape(data);
|
|
850
|
+
}
|
|
851
|
+
/** Type guard for color-token authoring snapshots. */
|
|
852
|
+
function isColorTokenExport(data) {
|
|
853
|
+
if (!isPlainObject(data)) return false;
|
|
854
|
+
if (data.kind === "color") return hasColorTokenShape(data);
|
|
855
|
+
if (data.kind !== void 0) return false;
|
|
856
|
+
return hasColorTokenShape(data);
|
|
857
|
+
}
|
|
858
|
+
/** Type guard for palette authoring snapshots. */
|
|
859
|
+
function isPaletteExport(data) {
|
|
860
|
+
if (!isPlainObject(data)) return false;
|
|
861
|
+
if (data.kind === "palette") return hasPaletteShape(data);
|
|
862
|
+
if (data.kind !== void 0) return false;
|
|
863
|
+
return hasPaletteShape(data);
|
|
864
|
+
}
|
|
768
865
|
|
|
769
866
|
//#endregion
|
|
770
867
|
//#region src/format-guard.ts
|
|
@@ -809,7 +906,7 @@ function assertAllPastel(resolved, modes) {
|
|
|
809
906
|
}
|
|
810
907
|
}
|
|
811
908
|
if (nonPastel.length === 0) return;
|
|
812
|
-
throw new Error(`glaze: splitHue requires every color to be pastel (hue rotation is only clip-free when chroma is bounded by the hue-independent safe chroma). Non-pastel: ${nonPastel.join(", ")}. Set pastel: true (
|
|
909
|
+
throw new Error(`glaze: splitHue requires every color to be pastel (hue rotation is only clip-free when chroma is bounded by the hue-independent safe chroma). Non-pastel: ${nonPastel.join(", ")}. Set pastel: true (per-theme, per-token, or per-color) or drop splitHue.`);
|
|
813
910
|
}
|
|
814
911
|
|
|
815
912
|
//#endregion
|
|
@@ -1880,15 +1977,18 @@ function resolveContrastSpec(spec, isHighContrast, polarity) {
|
|
|
1880
1977
|
/**
|
|
1881
1978
|
* Apply the relative-tone delta against a base, honoring `flip`.
|
|
1882
1979
|
*
|
|
1883
|
-
* When `flip` is on and `base + delta` falls outside `[0, 100]`,
|
|
1884
|
-
* delta to the other side of the base
|
|
1885
|
-
*
|
|
1980
|
+
* When `flip` is on and `base + delta` falls outside `[0, 100]`, try mirroring
|
|
1981
|
+
* the delta to the other side of the base. If the mirrored target is also out
|
|
1982
|
+
* of range, keep the original delta so the caller clamps on the authored side.
|
|
1983
|
+
* When off, the caller clamps as usual.
|
|
1886
1984
|
*/
|
|
1887
1985
|
function applyToneFlip(delta, baseTone, flip) {
|
|
1888
1986
|
if (!flip) return delta;
|
|
1889
1987
|
const target = baseTone + delta;
|
|
1890
1988
|
if (target >= 0 && target <= 100) return delta;
|
|
1891
|
-
|
|
1989
|
+
const mirrored = baseTone - delta;
|
|
1990
|
+
if (mirrored >= 0 && mirrored <= 100) return -delta;
|
|
1991
|
+
return delta;
|
|
1892
1992
|
}
|
|
1893
1993
|
function resolveRootColor(def, isHighContrast) {
|
|
1894
1994
|
const rawT = def.tone;
|
|
@@ -2650,12 +2750,10 @@ function buildTailwindMap(resolved, themePrefix, cssPrefix, modes, format, darkS
|
|
|
2650
2750
|
* `{ l, c, h }`), the structured-input validator, the two factory paths
|
|
2651
2751
|
* (value vs structured), and the JSON-safe export / rehydration round-trip.
|
|
2652
2752
|
*
|
|
2653
|
-
*
|
|
2654
|
-
*
|
|
2655
|
-
*
|
|
2656
|
-
* `
|
|
2657
|
-
* The token's resolved variants are then memoized on first
|
|
2658
|
-
* `.resolve()` / `.token()` / ... call.
|
|
2753
|
+
* Tokens store a sparse local config override only. Resolve merges the
|
|
2754
|
+
* live global config with that local override (invalidated on
|
|
2755
|
+
* `configure()`). Authoring `.export(override?)` freezes
|
|
2756
|
+
* `getConfig() ∪ local ∪ override` at call time.
|
|
2659
2757
|
*/
|
|
2660
2758
|
/** Internal name of the user-facing standalone color in the synthesized def map. */
|
|
2661
2759
|
const STANDALONE_VALUE = "value";
|
|
@@ -2670,47 +2768,16 @@ const RESERVED_STANDALONE_NAMES = new Set([
|
|
|
2670
2768
|
STANDALONE_BASE
|
|
2671
2769
|
]);
|
|
2672
2770
|
/**
|
|
2673
|
-
*
|
|
2674
|
-
*
|
|
2675
|
-
* Light window defaults to `false` (preserve input tone exactly).
|
|
2676
|
-
* All other fields snapshot from global at create time. User override
|
|
2677
|
-
* fields win over all defaults.
|
|
2771
|
+
* Value-form local override: `lightTone` defaults to `false` (preserve
|
|
2772
|
+
* input tone). User override fields win.
|
|
2678
2773
|
*/
|
|
2679
|
-
function
|
|
2680
|
-
const cfg = getConfig();
|
|
2774
|
+
function sparseValueFormLocal(userOverride) {
|
|
2681
2775
|
return {
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
darkDesaturation: userOverride?.darkDesaturation ?? cfg.darkDesaturation,
|
|
2685
|
-
autoFlip: userOverride?.autoFlip ?? cfg.autoFlip,
|
|
2686
|
-
shadowTuning: userOverride?.shadowTuning ?? cfg.shadowTuning
|
|
2776
|
+
...userOverride,
|
|
2777
|
+
lightTone: userOverride?.lightTone !== void 0 ? userOverride.lightTone : false
|
|
2687
2778
|
};
|
|
2688
2779
|
}
|
|
2689
2780
|
/**
|
|
2690
|
-
* Build the per-token effective config override for a structured-form color.
|
|
2691
|
-
*
|
|
2692
|
-
* Both light and dark windows snapshot from global at create time.
|
|
2693
|
-
* User override fields win.
|
|
2694
|
-
*/
|
|
2695
|
-
function buildStructuredConfigOverride(userOverride) {
|
|
2696
|
-
const cfg = getConfig();
|
|
2697
|
-
return {
|
|
2698
|
-
lightTone: userOverride?.lightTone !== void 0 ? userOverride.lightTone : cfg.lightTone,
|
|
2699
|
-
darkTone: userOverride?.darkTone !== void 0 ? userOverride.darkTone : cfg.darkTone,
|
|
2700
|
-
darkDesaturation: userOverride?.darkDesaturation ?? cfg.darkDesaturation,
|
|
2701
|
-
autoFlip: userOverride?.autoFlip ?? cfg.autoFlip,
|
|
2702
|
-
shadowTuning: userOverride?.shadowTuning ?? cfg.shadowTuning
|
|
2703
|
-
};
|
|
2704
|
-
}
|
|
2705
|
-
/**
|
|
2706
|
-
* Build the `GlazeConfigResolved` to pass to `resolveAllColors` from a
|
|
2707
|
-
* snapshot override. Uses `defaultConfig()` as the base so all required
|
|
2708
|
-
* fields are present; the snapshot fields win.
|
|
2709
|
-
*/
|
|
2710
|
-
function resolvedConfigFromOverride(override) {
|
|
2711
|
-
return mergeConfig(defaultConfig(), override);
|
|
2712
|
-
}
|
|
2713
|
-
/**
|
|
2714
2781
|
* Matches the CSS color functions Glaze itself emits (`rgb()`, `hsl()`,
|
|
2715
2782
|
* `okhsl()`, `oklch()`) plus their legacy alpha aliases (`rgba()`, `hsla()`).
|
|
2716
2783
|
*
|
|
@@ -3000,12 +3067,30 @@ function buildStandaloneValueDefs(main, options) {
|
|
|
3000
3067
|
primary
|
|
3001
3068
|
};
|
|
3002
3069
|
}
|
|
3003
|
-
function createColorTokenFromDefs(seedHue, seedSaturation, defs, primary,
|
|
3004
|
-
let
|
|
3070
|
+
function createColorTokenFromDefs(seedHue, seedSaturation, defs, primary, configOverride, baseToken, buildExport) {
|
|
3071
|
+
let cache = null;
|
|
3072
|
+
function getEffectiveConfig() {
|
|
3073
|
+
const version = getConfigVersion();
|
|
3074
|
+
if (cache && cache.version === version) return cache.effectiveConfig;
|
|
3075
|
+
const effectiveConfig = mergeConfig(getConfig(), configOverride);
|
|
3076
|
+
cache = {
|
|
3077
|
+
map: null,
|
|
3078
|
+
version,
|
|
3079
|
+
effectiveConfig
|
|
3080
|
+
};
|
|
3081
|
+
return effectiveConfig;
|
|
3082
|
+
}
|
|
3005
3083
|
const resolveOnce = () => {
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3084
|
+
const version = getConfigVersion();
|
|
3085
|
+
if (cache && cache.version === version && cache.map) return cache.map;
|
|
3086
|
+
const effectiveConfig = getEffectiveConfig();
|
|
3087
|
+
const map = resolveAllColors(seedHue, seedSaturation, defs, effectiveConfig, baseToken ? new Map([[STANDALONE_BASE, baseToken.resolve()]]) : void 0);
|
|
3088
|
+
cache = {
|
|
3089
|
+
map,
|
|
3090
|
+
version,
|
|
3091
|
+
effectiveConfig
|
|
3092
|
+
};
|
|
3093
|
+
return map;
|
|
3009
3094
|
};
|
|
3010
3095
|
const resolveStates = (options) => {
|
|
3011
3096
|
const cfg = getConfig();
|
|
@@ -3015,7 +3100,7 @@ function createColorTokenFromDefs(seedHue, seedSaturation, defs, primary, effect
|
|
|
3015
3100
|
};
|
|
3016
3101
|
};
|
|
3017
3102
|
const tokenLike = (options) => {
|
|
3018
|
-
return buildTokenMap(resolveOnce(), "", resolveStates(options), resolveModes(options?.modes), options?.format ?? "oklch",
|
|
3103
|
+
return buildTokenMap(resolveOnce(), "", resolveStates(options), resolveModes(options?.modes), options?.format ?? "oklch", getEffectiveConfig().pastel)[`#${primary}`];
|
|
3019
3104
|
};
|
|
3020
3105
|
return {
|
|
3021
3106
|
resolve() {
|
|
@@ -3026,7 +3111,7 @@ function createColorTokenFromDefs(seedHue, seedSaturation, defs, primary, effect
|
|
|
3026
3111
|
json(options) {
|
|
3027
3112
|
const format = options?.format ?? "oklch";
|
|
3028
3113
|
assertNativeFormat(format, "json");
|
|
3029
|
-
return buildJsonMap(resolveOnce(), resolveModes(options?.modes), format,
|
|
3114
|
+
return buildJsonMap(resolveOnce(), resolveModes(options?.modes), format, getEffectiveConfig().pastel)[primary];
|
|
3030
3115
|
},
|
|
3031
3116
|
css(options) {
|
|
3032
3117
|
const format = options.format ?? "oklch";
|
|
@@ -3045,11 +3130,11 @@ function createColorTokenFromDefs(seedHue, seedSaturation, defs, primary, effect
|
|
|
3045
3130
|
resolvedHue: resolved.light.h
|
|
3046
3131
|
};
|
|
3047
3132
|
}
|
|
3048
|
-
return buildCssMap(renamed, "", options.suffix ?? "-color", format,
|
|
3133
|
+
return buildCssMap(renamed, "", options.suffix ?? "-color", format, getEffectiveConfig().pastel, channelCtx);
|
|
3049
3134
|
},
|
|
3050
3135
|
dtcg(options) {
|
|
3051
3136
|
const modes = resolveModes(options?.modes);
|
|
3052
|
-
const doc = buildDtcgMap(resolveOnce(), "", modes, options?.colorSpace ?? "srgb",
|
|
3137
|
+
const doc = buildDtcgMap(resolveOnce(), "", modes, options?.colorSpace ?? "srgb", getEffectiveConfig().pastel);
|
|
3053
3138
|
const result = { light: doc.light[primary] };
|
|
3054
3139
|
if (doc.dark) result.dark = doc.dark[primary];
|
|
3055
3140
|
if (doc.lightContrast) result.lightContrast = doc.lightContrast[primary];
|
|
@@ -3057,7 +3142,7 @@ function createColorTokenFromDefs(seedHue, seedSaturation, defs, primary, effect
|
|
|
3057
3142
|
return result;
|
|
3058
3143
|
},
|
|
3059
3144
|
dtcgResolver(options) {
|
|
3060
|
-
const doc = buildDtcgMap(resolveOnce(), "", resolveModes(options?.modes), options?.colorSpace ?? "srgb",
|
|
3145
|
+
const doc = buildDtcgMap(resolveOnce(), "", resolveModes(options?.modes), options?.colorSpace ?? "srgb", getEffectiveConfig().pastel);
|
|
3061
3146
|
const name = options.name;
|
|
3062
3147
|
const result = { light: { [name]: doc.light[primary] } };
|
|
3063
3148
|
if (doc.dark) result.dark = { [name]: doc.dark[primary] };
|
|
@@ -3068,9 +3153,11 @@ function createColorTokenFromDefs(seedHue, seedSaturation, defs, primary, effect
|
|
|
3068
3153
|
tailwind(options) {
|
|
3069
3154
|
const format = options.format ?? "oklch";
|
|
3070
3155
|
assertNativeFormat(format, "tailwind");
|
|
3071
|
-
return buildTailwindMap(new Map([[options.name, resolveOnce().get(primary)]]), "", options.namespace ?? "color-", resolveModes(options?.modes), format, options.darkSelector ?? ".dark", options.highContrastSelector ?? ".high-contrast",
|
|
3156
|
+
return buildTailwindMap(new Map([[options.name, resolveOnce().get(primary)]]), "", options.namespace ?? "color-", resolveModes(options?.modes), format, options.darkSelector ?? ".dark", options.highContrastSelector ?? ".high-contrast", getEffectiveConfig().pastel);
|
|
3072
3157
|
},
|
|
3073
|
-
export
|
|
3158
|
+
export(override) {
|
|
3159
|
+
return buildExport(override);
|
|
3160
|
+
}
|
|
3074
3161
|
};
|
|
3075
3162
|
}
|
|
3076
3163
|
/**
|
|
@@ -3137,35 +3224,35 @@ function createColorToken(input, configOverride) {
|
|
|
3137
3224
|
mode: "static"
|
|
3138
3225
|
};
|
|
3139
3226
|
}
|
|
3140
|
-
const
|
|
3141
|
-
|
|
3142
|
-
|
|
3227
|
+
const localOverride = configOverride;
|
|
3228
|
+
return createColorTokenFromDefs(input.hue, input.saturation, defs, primary, localOverride, baseToken, (exportArg) => ({
|
|
3229
|
+
kind: "color",
|
|
3230
|
+
version: GLAZE_EXPORT_VERSION,
|
|
3143
3231
|
form: "structured",
|
|
3144
|
-
input: buildStructuredInputExport(input),
|
|
3145
|
-
config:
|
|
3146
|
-
});
|
|
3147
|
-
return createColorTokenFromDefs(input.hue, input.saturation, defs, primary, effectiveConfig, baseToken, exportData);
|
|
3232
|
+
input: buildStructuredInputExport(input, exportArg),
|
|
3233
|
+
config: freezeConfigForExport(localOverride, exportArg)
|
|
3234
|
+
}));
|
|
3148
3235
|
}
|
|
3149
3236
|
function createColorTokenFromValue(value, options, configOverride) {
|
|
3150
3237
|
const main = extractOkhslFromValue(value);
|
|
3151
3238
|
const linkingBase = toLinkingBase(resolveBaseToken(options?.base));
|
|
3152
3239
|
const { seedHue, seedSaturation, defs, primary } = buildStandaloneValueDefs(main, options);
|
|
3153
|
-
const
|
|
3154
|
-
|
|
3155
|
-
|
|
3240
|
+
const localOverride = sparseValueFormLocal(configOverride);
|
|
3241
|
+
return createColorTokenFromDefs(seedHue, seedSaturation, defs, primary, localOverride, linkingBase, (exportArg) => ({
|
|
3242
|
+
kind: "color",
|
|
3243
|
+
version: GLAZE_EXPORT_VERSION,
|
|
3156
3244
|
form: "value",
|
|
3157
3245
|
input: value,
|
|
3158
|
-
...options !== void 0 ? { overrides: buildOverridesExport(options) } : {},
|
|
3159
|
-
config:
|
|
3160
|
-
});
|
|
3161
|
-
return createColorTokenFromDefs(seedHue, seedSaturation, defs, primary, effectiveConfig, linkingBase, exportData);
|
|
3246
|
+
...options !== void 0 ? { overrides: buildOverridesExport(options, exportArg) } : {},
|
|
3247
|
+
config: freezeConfigForExport(localOverride, exportArg)
|
|
3248
|
+
}));
|
|
3162
3249
|
}
|
|
3163
3250
|
/**
|
|
3164
3251
|
* Build a JSON-safe snapshot of `GlazeColorOverrides`. `base` is
|
|
3165
3252
|
* recursively serialized when it was originally a token; raw values are
|
|
3166
3253
|
* preserved as-is so `glaze.colorFrom(...)` round-trips them.
|
|
3167
3254
|
*/
|
|
3168
|
-
function buildOverridesExport(options) {
|
|
3255
|
+
function buildOverridesExport(options, exportArg) {
|
|
3169
3256
|
const out = {};
|
|
3170
3257
|
if (options.hue !== void 0) out.hue = options.hue;
|
|
3171
3258
|
if (options.saturation !== void 0) out.saturation = options.saturation;
|
|
@@ -3178,10 +3265,10 @@ function buildOverridesExport(options) {
|
|
|
3178
3265
|
if (options.name !== void 0) out.name = options.name;
|
|
3179
3266
|
if (options.pastel !== void 0) out.pastel = options.pastel;
|
|
3180
3267
|
if (options.role !== void 0) out.role = options.role;
|
|
3181
|
-
if (options.base !== void 0) out.base = isGlazeColorToken(options.base) ? options.base.export() : options.base;
|
|
3268
|
+
if (options.base !== void 0) out.base = isGlazeColorToken(options.base) ? options.base.export(exportArg) : options.base;
|
|
3182
3269
|
return out;
|
|
3183
3270
|
}
|
|
3184
|
-
function buildStructuredInputExport(input) {
|
|
3271
|
+
function buildStructuredInputExport(input, exportArg) {
|
|
3185
3272
|
const out = {
|
|
3186
3273
|
hue: input.hue,
|
|
3187
3274
|
saturation: input.saturation,
|
|
@@ -3195,14 +3282,14 @@ function buildStructuredInputExport(input) {
|
|
|
3195
3282
|
if (input.name !== void 0) out.name = input.name;
|
|
3196
3283
|
if (input.pastel !== void 0) out.pastel = input.pastel;
|
|
3197
3284
|
if (input.role !== void 0) out.role = input.role;
|
|
3198
|
-
if (input.base !== void 0) out.base = isGlazeColorToken(input.base) ? input.base.export() : input.base;
|
|
3285
|
+
if (input.base !== void 0) out.base = isGlazeColorToken(input.base) ? input.base.export(exportArg) : input.base;
|
|
3199
3286
|
return out;
|
|
3200
3287
|
}
|
|
3201
3288
|
/**
|
|
3202
3289
|
* Discriminate a `GlazeColorTokenExport` from a raw `GlazeColorValue`.
|
|
3203
3290
|
*/
|
|
3204
3291
|
function isExportedToken(candidate) {
|
|
3205
|
-
return
|
|
3292
|
+
return isColorTokenExport(candidate);
|
|
3206
3293
|
}
|
|
3207
3294
|
function rehydrateOverrides(data) {
|
|
3208
3295
|
const out = {};
|
|
@@ -3241,12 +3328,14 @@ function rehydrateStructuredInput(data) {
|
|
|
3241
3328
|
* Rehydrate a token from its `.export()` snapshot. Recursively rebuilds
|
|
3242
3329
|
* any base dependency. Inverse of `GlazeColorToken.export()`.
|
|
3243
3330
|
*
|
|
3244
|
-
* The stored `config` field
|
|
3245
|
-
*
|
|
3246
|
-
*
|
|
3331
|
+
* The stored `config` field is the freeze from export time — passed as
|
|
3332
|
+
* the instance local override so the rehydrated token stays pinned
|
|
3333
|
+
* against later `glaze.configure()` calls.
|
|
3247
3334
|
*/
|
|
3248
3335
|
function colorFromExport(data) {
|
|
3249
3336
|
if (data === null || typeof data !== "object") throw new Error(`glaze.colorFrom: expected an object from token.export(), got ${data === null ? "null" : typeof data}.`);
|
|
3337
|
+
assertExportKind(data, "color", "glaze.colorFrom");
|
|
3338
|
+
assertExportVersion(data, "glaze.colorFrom");
|
|
3250
3339
|
if (data.form !== "value" && data.form !== "structured") throw new Error(`glaze.colorFrom: invalid "form" field — expected "value" or "structured" (got ${JSON.stringify(data.form)}).`);
|
|
3251
3340
|
if (data.input === void 0) throw new Error(`glaze.colorFrom: missing "input" field — expected the original ${data.form === "value" ? "GlazeColorValue" : "GlazeColorInput"}.`);
|
|
3252
3341
|
if (data.form === "value") {
|
|
@@ -3256,6 +3345,157 @@ function colorFromExport(data) {
|
|
|
3256
3345
|
return createColorToken(rehydrateStructuredInput(data.input), data.config);
|
|
3257
3346
|
}
|
|
3258
3347
|
|
|
3348
|
+
//#endregion
|
|
3349
|
+
//#region src/theme.ts
|
|
3350
|
+
function createTheme(hue, saturation, initialColors, configOverride) {
|
|
3351
|
+
let colorDefs = initialColors ? { ...initialColors } : {};
|
|
3352
|
+
let cache = null;
|
|
3353
|
+
function getEffectiveConfig() {
|
|
3354
|
+
const version = getConfigVersion();
|
|
3355
|
+
if (cache && cache.version === version) return cache.effectiveConfig;
|
|
3356
|
+
const effectiveConfig = mergeConfig(getConfig(), configOverride);
|
|
3357
|
+
cache = {
|
|
3358
|
+
map: null,
|
|
3359
|
+
version,
|
|
3360
|
+
effectiveConfig
|
|
3361
|
+
};
|
|
3362
|
+
return effectiveConfig;
|
|
3363
|
+
}
|
|
3364
|
+
function resolveCached() {
|
|
3365
|
+
const version = getConfigVersion();
|
|
3366
|
+
if (cache && cache.version === version && cache.map) return cache.map;
|
|
3367
|
+
const effectiveConfig = getEffectiveConfig();
|
|
3368
|
+
const map = resolveAllColors(hue, saturation, colorDefs, effectiveConfig);
|
|
3369
|
+
cache = {
|
|
3370
|
+
map,
|
|
3371
|
+
version,
|
|
3372
|
+
effectiveConfig
|
|
3373
|
+
};
|
|
3374
|
+
return map;
|
|
3375
|
+
}
|
|
3376
|
+
function invalidate() {
|
|
3377
|
+
cache = null;
|
|
3378
|
+
}
|
|
3379
|
+
function channelCtxFor(options, formatDefault, prefix) {
|
|
3380
|
+
const format = options?.format ?? formatDefault;
|
|
3381
|
+
if (!options?.splitHue || format !== "oklch") return void 0;
|
|
3382
|
+
assertAllPastel(resolveCached(), resolveModes(options?.modes));
|
|
3383
|
+
return {
|
|
3384
|
+
seedHue: hue,
|
|
3385
|
+
baseName: options.name ?? "theme",
|
|
3386
|
+
prefix,
|
|
3387
|
+
defs: colorDefs,
|
|
3388
|
+
mode: "theme"
|
|
3389
|
+
};
|
|
3390
|
+
}
|
|
3391
|
+
return {
|
|
3392
|
+
get hue() {
|
|
3393
|
+
return hue;
|
|
3394
|
+
},
|
|
3395
|
+
get saturation() {
|
|
3396
|
+
return saturation;
|
|
3397
|
+
},
|
|
3398
|
+
getConfig() {
|
|
3399
|
+
return getEffectiveConfig();
|
|
3400
|
+
},
|
|
3401
|
+
colors(defs) {
|
|
3402
|
+
colorDefs = {
|
|
3403
|
+
...colorDefs,
|
|
3404
|
+
...defs
|
|
3405
|
+
};
|
|
3406
|
+
invalidate();
|
|
3407
|
+
},
|
|
3408
|
+
color(name, def) {
|
|
3409
|
+
if (def === void 0) return colorDefs[name];
|
|
3410
|
+
colorDefs[name] = def;
|
|
3411
|
+
invalidate();
|
|
3412
|
+
},
|
|
3413
|
+
remove(names) {
|
|
3414
|
+
const list = Array.isArray(names) ? names : [names];
|
|
3415
|
+
for (const name of list) delete colorDefs[name];
|
|
3416
|
+
invalidate();
|
|
3417
|
+
},
|
|
3418
|
+
has(name) {
|
|
3419
|
+
return name in colorDefs;
|
|
3420
|
+
},
|
|
3421
|
+
list() {
|
|
3422
|
+
return Object.keys(colorDefs);
|
|
3423
|
+
},
|
|
3424
|
+
reset() {
|
|
3425
|
+
colorDefs = {};
|
|
3426
|
+
invalidate();
|
|
3427
|
+
},
|
|
3428
|
+
export(override) {
|
|
3429
|
+
return {
|
|
3430
|
+
kind: "theme",
|
|
3431
|
+
version: GLAZE_EXPORT_VERSION,
|
|
3432
|
+
hue,
|
|
3433
|
+
saturation,
|
|
3434
|
+
colors: structuredClone(colorDefs),
|
|
3435
|
+
config: freezeConfigForExport(configOverride, override)
|
|
3436
|
+
};
|
|
3437
|
+
},
|
|
3438
|
+
extend(options) {
|
|
3439
|
+
const newHue = options.hue ?? hue;
|
|
3440
|
+
const newSat = options.saturation ?? saturation;
|
|
3441
|
+
const inheritedColors = {};
|
|
3442
|
+
for (const [name, def] of Object.entries(colorDefs)) if (def.inherit !== false) inheritedColors[name] = def;
|
|
3443
|
+
return createTheme(newHue, newSat, options.colors ? {
|
|
3444
|
+
...inheritedColors,
|
|
3445
|
+
...options.colors
|
|
3446
|
+
} : { ...inheritedColors }, configOverride || options.config ? {
|
|
3447
|
+
...configOverride ?? {},
|
|
3448
|
+
...options.config ?? {}
|
|
3449
|
+
} : void 0);
|
|
3450
|
+
},
|
|
3451
|
+
resolve() {
|
|
3452
|
+
return new Map(resolveCached());
|
|
3453
|
+
},
|
|
3454
|
+
tokens(options) {
|
|
3455
|
+
const format = options?.format ?? "oklch";
|
|
3456
|
+
assertNativeFormat(format, "tokens");
|
|
3457
|
+
const modes = resolveModes(options?.modes);
|
|
3458
|
+
return buildFlatTokenMap(resolveCached(), "", modes, format, getEffectiveConfig().pastel);
|
|
3459
|
+
},
|
|
3460
|
+
tasty(options) {
|
|
3461
|
+
const cfg = getEffectiveConfig();
|
|
3462
|
+
const states = {
|
|
3463
|
+
dark: options?.states?.dark ?? cfg.states.dark,
|
|
3464
|
+
highContrast: options?.states?.highContrast ?? cfg.states.highContrast
|
|
3465
|
+
};
|
|
3466
|
+
const modes = resolveModes(options?.modes);
|
|
3467
|
+
const format = options?.format ?? "oklch";
|
|
3468
|
+
const channelCtx = channelCtxFor(options, "oklch", "");
|
|
3469
|
+
return buildTokenMap(resolveCached(), "", states, modes, format, cfg.pastel, channelCtx);
|
|
3470
|
+
},
|
|
3471
|
+
json(options) {
|
|
3472
|
+
const format = options?.format ?? "oklch";
|
|
3473
|
+
assertNativeFormat(format, "json");
|
|
3474
|
+
const modes = resolveModes(options?.modes);
|
|
3475
|
+
return buildJsonMap(resolveCached(), modes, format, getEffectiveConfig().pastel);
|
|
3476
|
+
},
|
|
3477
|
+
css(options) {
|
|
3478
|
+
const format = options?.format ?? "oklch";
|
|
3479
|
+
assertNativeFormat(format, "css");
|
|
3480
|
+
const channelCtx = channelCtxFor(options, "oklch", "");
|
|
3481
|
+
return buildCssMap(resolveCached(), "", options?.suffix ?? "-color", format, getEffectiveConfig().pastel, channelCtx);
|
|
3482
|
+
},
|
|
3483
|
+
dtcg(options) {
|
|
3484
|
+
const modes = resolveModes(options?.modes);
|
|
3485
|
+
return buildDtcgMap(resolveCached(), "", modes, options?.colorSpace ?? "srgb", getEffectiveConfig().pastel);
|
|
3486
|
+
},
|
|
3487
|
+
dtcgResolver(options) {
|
|
3488
|
+
return buildDtcgResolver(buildDtcgMap(resolveCached(), "", resolveModes(options?.modes), options?.colorSpace ?? "srgb", getEffectiveConfig().pastel), options);
|
|
3489
|
+
},
|
|
3490
|
+
tailwind(options) {
|
|
3491
|
+
const format = options?.format ?? "oklch";
|
|
3492
|
+
assertNativeFormat(format, "tailwind");
|
|
3493
|
+
const modes = resolveModes(options?.modes);
|
|
3494
|
+
return buildTailwindMap(resolveCached(), "", options?.namespace ?? "color-", modes, format, options?.darkSelector ?? ".dark", options?.highContrastSelector ?? ".high-contrast", getEffectiveConfig().pastel);
|
|
3495
|
+
}
|
|
3496
|
+
};
|
|
3497
|
+
}
|
|
3498
|
+
|
|
3259
3499
|
//#endregion
|
|
3260
3500
|
//#region src/palette.ts
|
|
3261
3501
|
function resolvePrefix(options, themeName, defaultPrefix = false) {
|
|
@@ -3335,6 +3575,26 @@ function buildPaletteOutput(themes, paletteOptions, options, buildOne, merge, em
|
|
|
3335
3575
|
}
|
|
3336
3576
|
return acc;
|
|
3337
3577
|
}
|
|
3578
|
+
/** Rebuild a theme from a `theme.export()` snapshot. */
|
|
3579
|
+
function createThemeFromExport(data, factory = "glaze.themeFrom") {
|
|
3580
|
+
if (data === null || typeof data !== "object") throw new Error(`${factory}: expected an object from theme.export(), got ${data === null ? "null" : typeof data}.`);
|
|
3581
|
+
assertExportKind(data, "theme", factory);
|
|
3582
|
+
assertExportVersion(data, factory);
|
|
3583
|
+
if (typeof data.hue !== "number" || typeof data.saturation !== "number") throw new Error(`${factory}: expected numeric "hue" and "saturation" fields.`);
|
|
3584
|
+
return createTheme(data.hue, data.saturation, data.colors, data.config);
|
|
3585
|
+
}
|
|
3586
|
+
/**
|
|
3587
|
+
* Rebuild a palette from a `palette.export()` snapshot.
|
|
3588
|
+
*/
|
|
3589
|
+
function createPaletteFromExport(data) {
|
|
3590
|
+
if (data === null || typeof data !== "object") throw new Error(`glaze.paletteFrom: expected an object from palette.export(), got ${data === null ? "null" : typeof data}.`);
|
|
3591
|
+
assertExportKind(data, "palette", "glaze.paletteFrom");
|
|
3592
|
+
assertExportVersion(data, "glaze.paletteFrom");
|
|
3593
|
+
if (data.themes === null || typeof data.themes !== "object") throw new Error(`glaze.paletteFrom: expected a "themes" object map of theme exports.`);
|
|
3594
|
+
const rebuilt = {};
|
|
3595
|
+
for (const [name, themeExport] of Object.entries(data.themes)) rebuilt[name] = createThemeFromExport(themeExport, `glaze.paletteFrom (theme "${name}")`);
|
|
3596
|
+
return createPalette(rebuilt, { primary: data.primary });
|
|
3597
|
+
}
|
|
3338
3598
|
function createPalette(themes, paletteOptions) {
|
|
3339
3599
|
validatePrimaryTheme(paletteOptions?.primary, themes);
|
|
3340
3600
|
const buildDtcgResult = (options) => {
|
|
@@ -3348,6 +3608,29 @@ function createPalette(themes, paletteOptions) {
|
|
|
3348
3608
|
}, () => ({ light: {} }));
|
|
3349
3609
|
};
|
|
3350
3610
|
return {
|
|
3611
|
+
list() {
|
|
3612
|
+
return Object.keys(themes);
|
|
3613
|
+
},
|
|
3614
|
+
get primary() {
|
|
3615
|
+
return paletteOptions?.primary;
|
|
3616
|
+
},
|
|
3617
|
+
theme(name) {
|
|
3618
|
+
return themes[name];
|
|
3619
|
+
},
|
|
3620
|
+
themes() {
|
|
3621
|
+
return { ...themes };
|
|
3622
|
+
},
|
|
3623
|
+
export(override) {
|
|
3624
|
+
const themesExport = {};
|
|
3625
|
+
for (const [name, theme] of Object.entries(themes)) themesExport[name] = theme.export(override);
|
|
3626
|
+
const out = {
|
|
3627
|
+
kind: "palette",
|
|
3628
|
+
version: GLAZE_EXPORT_VERSION,
|
|
3629
|
+
themes: themesExport
|
|
3630
|
+
};
|
|
3631
|
+
if (paletteOptions?.primary !== void 0) out.primary = paletteOptions.primary;
|
|
3632
|
+
return out;
|
|
3633
|
+
},
|
|
3351
3634
|
tokens(options) {
|
|
3352
3635
|
const format = options?.format ?? "oklch";
|
|
3353
3636
|
assertNativeFormat(format, "tokens");
|
|
@@ -3436,150 +3719,6 @@ function createPalette(themes, paletteOptions) {
|
|
|
3436
3719
|
};
|
|
3437
3720
|
}
|
|
3438
3721
|
|
|
3439
|
-
//#endregion
|
|
3440
|
-
//#region src/theme.ts
|
|
3441
|
-
function createTheme(hue, saturation, initialColors, configOverride) {
|
|
3442
|
-
let colorDefs = initialColors ? { ...initialColors } : {};
|
|
3443
|
-
let cache = null;
|
|
3444
|
-
function getEffectiveConfig() {
|
|
3445
|
-
const version = getConfigVersion();
|
|
3446
|
-
if (cache && cache.version === version) return cache.effectiveConfig;
|
|
3447
|
-
return mergeConfig(getConfig(), configOverride);
|
|
3448
|
-
}
|
|
3449
|
-
function resolveCached() {
|
|
3450
|
-
const version = getConfigVersion();
|
|
3451
|
-
if (cache && cache.version === version) return cache.map;
|
|
3452
|
-
const effectiveConfig = mergeConfig(getConfig(), configOverride);
|
|
3453
|
-
const map = resolveAllColors(hue, saturation, colorDefs, effectiveConfig);
|
|
3454
|
-
cache = {
|
|
3455
|
-
map,
|
|
3456
|
-
version,
|
|
3457
|
-
effectiveConfig
|
|
3458
|
-
};
|
|
3459
|
-
return map;
|
|
3460
|
-
}
|
|
3461
|
-
function invalidate() {
|
|
3462
|
-
cache = null;
|
|
3463
|
-
}
|
|
3464
|
-
function channelCtxFor(options, formatDefault, prefix) {
|
|
3465
|
-
const format = options?.format ?? formatDefault;
|
|
3466
|
-
if (!options?.splitHue || format !== "oklch") return void 0;
|
|
3467
|
-
assertAllPastel(resolveCached(), resolveModes(options?.modes));
|
|
3468
|
-
return {
|
|
3469
|
-
seedHue: hue,
|
|
3470
|
-
baseName: options.name ?? "theme",
|
|
3471
|
-
prefix,
|
|
3472
|
-
defs: colorDefs,
|
|
3473
|
-
mode: "theme"
|
|
3474
|
-
};
|
|
3475
|
-
}
|
|
3476
|
-
return {
|
|
3477
|
-
get hue() {
|
|
3478
|
-
return hue;
|
|
3479
|
-
},
|
|
3480
|
-
get saturation() {
|
|
3481
|
-
return saturation;
|
|
3482
|
-
},
|
|
3483
|
-
getConfig() {
|
|
3484
|
-
return getEffectiveConfig();
|
|
3485
|
-
},
|
|
3486
|
-
colors(defs) {
|
|
3487
|
-
colorDefs = {
|
|
3488
|
-
...colorDefs,
|
|
3489
|
-
...defs
|
|
3490
|
-
};
|
|
3491
|
-
invalidate();
|
|
3492
|
-
},
|
|
3493
|
-
color(name, def) {
|
|
3494
|
-
if (def === void 0) return colorDefs[name];
|
|
3495
|
-
colorDefs[name] = def;
|
|
3496
|
-
invalidate();
|
|
3497
|
-
},
|
|
3498
|
-
remove(names) {
|
|
3499
|
-
const list = Array.isArray(names) ? names : [names];
|
|
3500
|
-
for (const name of list) delete colorDefs[name];
|
|
3501
|
-
invalidate();
|
|
3502
|
-
},
|
|
3503
|
-
has(name) {
|
|
3504
|
-
return name in colorDefs;
|
|
3505
|
-
},
|
|
3506
|
-
list() {
|
|
3507
|
-
return Object.keys(colorDefs);
|
|
3508
|
-
},
|
|
3509
|
-
reset() {
|
|
3510
|
-
colorDefs = {};
|
|
3511
|
-
invalidate();
|
|
3512
|
-
},
|
|
3513
|
-
export() {
|
|
3514
|
-
const out = {
|
|
3515
|
-
hue,
|
|
3516
|
-
saturation,
|
|
3517
|
-
colors: { ...colorDefs }
|
|
3518
|
-
};
|
|
3519
|
-
if (configOverride !== void 0) out.config = configOverride;
|
|
3520
|
-
return out;
|
|
3521
|
-
},
|
|
3522
|
-
extend(options) {
|
|
3523
|
-
const newHue = options.hue ?? hue;
|
|
3524
|
-
const newSat = options.saturation ?? saturation;
|
|
3525
|
-
const inheritedColors = {};
|
|
3526
|
-
for (const [name, def] of Object.entries(colorDefs)) if (def.inherit !== false) inheritedColors[name] = def;
|
|
3527
|
-
return createTheme(newHue, newSat, options.colors ? {
|
|
3528
|
-
...inheritedColors,
|
|
3529
|
-
...options.colors
|
|
3530
|
-
} : { ...inheritedColors }, configOverride || options.config ? {
|
|
3531
|
-
...configOverride ?? {},
|
|
3532
|
-
...options.config ?? {}
|
|
3533
|
-
} : void 0);
|
|
3534
|
-
},
|
|
3535
|
-
resolve() {
|
|
3536
|
-
return new Map(resolveCached());
|
|
3537
|
-
},
|
|
3538
|
-
tokens(options) {
|
|
3539
|
-
const format = options?.format ?? "oklch";
|
|
3540
|
-
assertNativeFormat(format, "tokens");
|
|
3541
|
-
const modes = resolveModes(options?.modes);
|
|
3542
|
-
return buildFlatTokenMap(resolveCached(), "", modes, format, getEffectiveConfig().pastel);
|
|
3543
|
-
},
|
|
3544
|
-
tasty(options) {
|
|
3545
|
-
const cfg = getEffectiveConfig();
|
|
3546
|
-
const states = {
|
|
3547
|
-
dark: options?.states?.dark ?? cfg.states.dark,
|
|
3548
|
-
highContrast: options?.states?.highContrast ?? cfg.states.highContrast
|
|
3549
|
-
};
|
|
3550
|
-
const modes = resolveModes(options?.modes);
|
|
3551
|
-
const format = options?.format ?? "oklch";
|
|
3552
|
-
const channelCtx = channelCtxFor(options, "oklch", "");
|
|
3553
|
-
return buildTokenMap(resolveCached(), "", states, modes, format, cfg.pastel, channelCtx);
|
|
3554
|
-
},
|
|
3555
|
-
json(options) {
|
|
3556
|
-
const format = options?.format ?? "oklch";
|
|
3557
|
-
assertNativeFormat(format, "json");
|
|
3558
|
-
const modes = resolveModes(options?.modes);
|
|
3559
|
-
return buildJsonMap(resolveCached(), modes, format, getEffectiveConfig().pastel);
|
|
3560
|
-
},
|
|
3561
|
-
css(options) {
|
|
3562
|
-
const format = options?.format ?? "oklch";
|
|
3563
|
-
assertNativeFormat(format, "css");
|
|
3564
|
-
const channelCtx = channelCtxFor(options, "oklch", "");
|
|
3565
|
-
return buildCssMap(resolveCached(), "", options?.suffix ?? "-color", format, getEffectiveConfig().pastel, channelCtx);
|
|
3566
|
-
},
|
|
3567
|
-
dtcg(options) {
|
|
3568
|
-
const modes = resolveModes(options?.modes);
|
|
3569
|
-
return buildDtcgMap(resolveCached(), "", modes, options?.colorSpace ?? "srgb", getEffectiveConfig().pastel);
|
|
3570
|
-
},
|
|
3571
|
-
dtcgResolver(options) {
|
|
3572
|
-
return buildDtcgResolver(buildDtcgMap(resolveCached(), "", resolveModes(options?.modes), options?.colorSpace ?? "srgb", getEffectiveConfig().pastel), options);
|
|
3573
|
-
},
|
|
3574
|
-
tailwind(options) {
|
|
3575
|
-
const format = options?.format ?? "oklch";
|
|
3576
|
-
assertNativeFormat(format, "tailwind");
|
|
3577
|
-
const modes = resolveModes(options?.modes);
|
|
3578
|
-
return buildTailwindMap(resolveCached(), "", options?.namespace ?? "color-", modes, format, options?.darkSelector ?? ".dark", options?.highContrastSelector ?? ".high-contrast", getEffectiveConfig().pastel);
|
|
3579
|
-
}
|
|
3580
|
-
};
|
|
3581
|
-
}
|
|
3582
|
-
|
|
3583
3722
|
//#endregion
|
|
3584
3723
|
//#region src/glaze.ts
|
|
3585
3724
|
/**
|
|
@@ -3593,6 +3732,7 @@ function createTheme(hue, saturation, initialColors, configOverride) {
|
|
|
3593
3732
|
* - `shadow.ts` — standalone shadow factory (`glaze.shadow`)
|
|
3594
3733
|
* - `formatters.ts` — variant → string (`glaze.format`)
|
|
3595
3734
|
* - `config.ts` — global config singleton
|
|
3735
|
+
* - `serialize.ts` — authoring export type guards / version checks
|
|
3596
3736
|
*/
|
|
3597
3737
|
/**
|
|
3598
3738
|
* Create a single-hue glaze theme.
|
|
@@ -3624,10 +3764,15 @@ glaze.configure = function configure$1(config) {
|
|
|
3624
3764
|
glaze.palette = function palette(themes, options) {
|
|
3625
3765
|
return createPalette(themes, options);
|
|
3626
3766
|
};
|
|
3627
|
-
/**
|
|
3628
|
-
|
|
3629
|
-
|
|
3767
|
+
/**
|
|
3768
|
+
* Create a theme from a serialized `theme.export()` snapshot.
|
|
3769
|
+
* Prefer this over the legacy `glaze.from` alias.
|
|
3770
|
+
*/
|
|
3771
|
+
glaze.themeFrom = function themeFrom(data) {
|
|
3772
|
+
return createThemeFromExport(data);
|
|
3630
3773
|
};
|
|
3774
|
+
/** Compat alias for `glaze.themeFrom`. */
|
|
3775
|
+
glaze.from = glaze.themeFrom;
|
|
3631
3776
|
/**
|
|
3632
3777
|
* Create a standalone single-color token.
|
|
3633
3778
|
*
|
|
@@ -3643,8 +3788,8 @@ glaze.from = function from(data) {
|
|
|
3643
3788
|
* **arg2 — config override** (optional, all shapes):
|
|
3644
3789
|
* Overrides the resolve-relevant global config fields for this token.
|
|
3645
3790
|
* Fields that are omitted fall through to the live global config at
|
|
3646
|
-
*
|
|
3647
|
-
*
|
|
3791
|
+
* resolve time. Pass `false` for a tone window to disable clamping
|
|
3792
|
+
* entirely. `pastel` is instance-only (not set via `configure()`).
|
|
3648
3793
|
*
|
|
3649
3794
|
* ```ts
|
|
3650
3795
|
* // Bare string — no overrides
|
|
@@ -3663,8 +3808,8 @@ glaze.from = function from(data) {
|
|
|
3663
3808
|
*
|
|
3664
3809
|
* Defaults: every form defaults to `mode: 'auto'`. Value-shorthand forms
|
|
3665
3810
|
* (bare strings and value objects) preserve light tone exactly
|
|
3666
|
-
* (`lightTone: false`
|
|
3667
|
-
* tone windows
|
|
3811
|
+
* (`lightTone: false` locally). Structured form falls through to the live
|
|
3812
|
+
* global tone windows for omitted fields.
|
|
3668
3813
|
*
|
|
3669
3814
|
* Relative `tone: '+N'` and `contrast` anchor to the literal seed by
|
|
3670
3815
|
* default; when `base` is set they anchor to the base's resolved variant
|
|
@@ -3742,8 +3887,8 @@ glaze.fromRgb = function fromRgb(r, g, b) {
|
|
|
3742
3887
|
*
|
|
3743
3888
|
* The snapshot is a plain JSON-safe object containing the original
|
|
3744
3889
|
* input value, overrides (with any `base` token recursively serialized),
|
|
3745
|
-
* and the effective config
|
|
3746
|
-
*
|
|
3890
|
+
* and the effective config freeze from export time. The reconstructed
|
|
3891
|
+
* token pins that freeze as its local override.
|
|
3747
3892
|
*
|
|
3748
3893
|
* @example
|
|
3749
3894
|
* ```ts
|
|
@@ -3757,6 +3902,18 @@ glaze.fromRgb = function fromRgb(r, g, b) {
|
|
|
3757
3902
|
glaze.colorFrom = function colorFrom(data) {
|
|
3758
3903
|
return colorFromExport(data);
|
|
3759
3904
|
};
|
|
3905
|
+
/**
|
|
3906
|
+
* Rehydrate a palette from a `palette.export()` snapshot.
|
|
3907
|
+
*/
|
|
3908
|
+
glaze.paletteFrom = function paletteFrom(data) {
|
|
3909
|
+
return createPaletteFromExport(data);
|
|
3910
|
+
};
|
|
3911
|
+
/** Type guard for theme authoring snapshots. */
|
|
3912
|
+
glaze.isThemeExport = isThemeExport;
|
|
3913
|
+
/** Type guard for color-token authoring snapshots. */
|
|
3914
|
+
glaze.isColorTokenExport = isColorTokenExport;
|
|
3915
|
+
/** Type guard for palette authoring snapshots. */
|
|
3916
|
+
glaze.isPaletteExport = isPaletteExport;
|
|
3760
3917
|
/** Get the current global configuration (for testing/debugging). */
|
|
3761
3918
|
glaze.getConfig = function getConfig() {
|
|
3762
3919
|
return snapshotConfig();
|
|
@@ -3767,5 +3924,5 @@ glaze.resetConfig = function resetConfig$1() {
|
|
|
3767
3924
|
};
|
|
3768
3925
|
|
|
3769
3926
|
//#endregion
|
|
3770
|
-
export { APCA_HC_ENHANCEMENT, APCA_MAX_LC, APCA_PRESETS, REF_EPS, apcaContrast, assertAllPastel, assertNativeFormat, contrastRatioFromLuminance, cuspLightness, findToneForContrast, findValueForMixContrast, formatHsl, formatOkhsl, formatOkhst, formatOklch, formatRgb, fromTone, gamutClampedLuminance, glaze, hslToSrgb, inferRoleFromName, normalizeRole, okhslToLinearSrgb, okhslToOkhst, okhslToOklab, okhslToOklch, okhslToSrgb, okhstToOkhsl, oklabToOkhsl, oppositeRole, parseHex, parseHexAlpha, relativeLuminanceFromLinearRgb, resolveApcaTarget, resolveContrastForMode, resolveMinContrast, roleToPolarity, srgbToHex, srgbToOkhsl, toTone, toneFromY, variantToOkhsl, yFromTone };
|
|
3927
|
+
export { APCA_HC_ENHANCEMENT, APCA_MAX_LC, APCA_PRESETS, GLAZE_EXPORT_VERSION, REF_EPS, apcaContrast, assertAllPastel, assertNativeFormat, contrastRatioFromLuminance, cuspLightness, findToneForContrast, findValueForMixContrast, formatHsl, formatOkhsl, formatOkhst, formatOklch, formatRgb, fromTone, gamutClampedLuminance, glaze, hslToSrgb, inferRoleFromName, isColorTokenExport, isPaletteExport, isThemeExport, normalizeRole, okhslToLinearSrgb, okhslToOkhst, okhslToOklab, okhslToOklch, okhslToSrgb, okhstToOkhsl, oklabToOkhsl, oppositeRole, parseHex, parseHexAlpha, relativeLuminanceFromLinearRgb, resolveApcaTarget, resolveContrastForMode, resolveMinContrast, roleToPolarity, srgbToHex, srgbToOkhsl, toTone, toneFromY, variantToOkhsl, yFromTone };
|
|
3771
3928
|
//# sourceMappingURL=index.mjs.map
|