Palettes API
PaletteApi manages the hue+chroma palettes that semantic color tokens draw their tones from. It sits between the Context (which provides sourceColor) and ColorApi (which resolves tones into hex values).
PaletteCallback
type PaletteCallback = (
context: Context,
base?: { hue: number; chroma: number },
) => { hue: number; chroma: number };The callback receives the current Context, whose sourceColor is a Color. It is evaluated once and then again when one of the context properties it read changes. For an override, base is the active variant’s palette recipe for the same context. Return the palette’s hue and chroma; its tone is not part of a palette, which spans every tone.
// `rotate` normalises the hue over 360°.
const capped: PaletteCallback = ({ sourceColor }) => ({
hue: sourceColor.hue + 30,
chroma: Math.min(sourceColor.chroma, 60),
});To change only one coordinate of an existing standard palette, transform the inherited base. It is recomputed when the source color or variant changes, so the hue does not need to be duplicated:
const moreTertiaryChroma: PaletteCallback = (_context, base) => {
if (!base) throw new Error('This callback requires an inherited palette');
return { ...base, chroma: base.chroma + 10 };
};api.palettes.get(key)
Returns a Palette instance for the given key. Available after the first api.load().
const api = await loader(config);
const primary = api.palettes.get('primary');
console.log(primary.hue); // e.g. 270.4
console.log(primary.chroma); // e.g. 36.0
// Compute a specific tone (returns ARGB integer)
const argb = primary.tone(50);Standard keys: 'primary', 'secondary', 'tertiary', 'neutral', 'error'.
Custom palette keys are accessible too, if you added them via palettes in config.
api.palettes.getAll()
Returns a read-only map of all current palettes:
const palettes = api.palettes.getAll();
for (const [key, palette] of Object.entries(palettes)) {
console.log(key, palette.hue, palette.chroma);
}api.palettes.override(args)
Overrides specific palettes without removing others. Existing palettes not included in args stay unchanged.
api.palettes.override({
primary: (_context, base) => {
if (!base) throw new Error('This callback requires an inherited palette');
return { ...base, chroma: 80 };
},
});
await api.load();Hex strings are accepted as shorthand:
api.palettes.override({ primary: '#FF5722' });api.palettes.sync(args)
Replaces the entire palette set atomically — palettes not present in args are removed:
api.palettes.sync({
primary: () => ({ hue: 270, chroma: 40 }),
brand: () => ({ hue: 15, chroma: 80 }),
});
await api.load();sync() replaces the custom palettes previously registered through the API. The palettes supplied by the active variant remain available; entries in args can override them or add new custom palettes.
api.palettes.add(args)
Adds custom palettes without touching existing ones. Used internally when customPalettes keys are present in config:
api.palettes.add({
highlight: '#FFAB40',
});api.palettes.getSerializableState()
Returns a plain Record<string, { hue, chroma }> safe for JSON.stringify or postMessage:
const state = api.palettes.getSerializableState();
worker.postMessage({ palettes: state });Example: palette inspection build script
import { loader } from '@udixio/theme';
import { Variants } from '@udixio/theme';
const api = await loader({
sourceColor: '#6750A4',
variant: Variants.Udixio,
});
const all = api.palettes.getAll();
for (const [key, palette] of Object.entries(all)) {
console.log(
`${key}: hue=${palette.hue.toFixed(1)}°, chroma=${palette.chroma.toFixed(1)}`,
);
}
// primary: hue=270.4°, chroma=36.0
// secondary: hue=270.4°, chroma=16.0
// …