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