🧑💻(tokens) add getThemesFromGlobals utils
Export a new util method `getThemesFromGlobals` to easily generate theme with its variant only by providing a partial globals object. By default it returns both available theme variants (light & dark). Through options you can prefix variant property keys, only generate theme with a subset of variant and also overrides/extend theme.
This commit is contained in:
committed by
Jean-Baptiste PENRATH
parent
fe8eb4b802
commit
db26e21b88
33
packages/tokens/src/lib/utils/buildRefs.ts
Normal file
33
packages/tokens/src/lib/utils/buildRefs.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Transform such object:
|
||||
* {
|
||||
* theme: {
|
||||
* colors: {
|
||||
* "primary-500": "blue"
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* to:
|
||||
* {
|
||||
* theme: {
|
||||
* colors: {
|
||||
* "primary-500": "ref(theme.colors.primary-500)"
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* @param tokens_
|
||||
*/
|
||||
export const buildRefs = <T extends Object>(tokens_: T): T => {
|
||||
const buildRefsAux = (upperKey: string, subTokens: any) => {
|
||||
if (typeof subTokens === "object") {
|
||||
const obj: any = {};
|
||||
Object.entries(subTokens).forEach(([key, value]) => {
|
||||
obj[key] = buildRefsAux((upperKey ? upperKey + "." : "") + key, value);
|
||||
});
|
||||
return obj;
|
||||
}
|
||||
return "ref(" + upperKey + ")";
|
||||
};
|
||||
return buildRefsAux("", tokens_);
|
||||
};
|
||||
61
packages/tokens/src/lib/utils/getThemesFromGlobals.ts
Normal file
61
packages/tokens/src/lib/utils/getThemesFromGlobals.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
// deepmerge is not available as a module, so we need to import it as a commonjs module...
|
||||
import deepmerge = require("deepmerge");
|
||||
import {
|
||||
contextualDefaultTokens,
|
||||
contextualDarkTokens,
|
||||
globals as defaultGlobals,
|
||||
} from "../cunningham";
|
||||
|
||||
type GlobalTokens = typeof defaultGlobals;
|
||||
type PartialExtendableNested<T> = {
|
||||
[K in keyof T]?: T[K] extends object ? PartialExtendableNested<T[K]> : T[K];
|
||||
} & Record<PropertyKey, any>;
|
||||
|
||||
const THEME_VARIANTS = ["light", "dark"] as const;
|
||||
type ThemeVariant = (typeof THEME_VARIANTS)[number];
|
||||
const CONTEXTUAL_TOKENS_MAP = {
|
||||
light: contextualDefaultTokens,
|
||||
dark: contextualDarkTokens,
|
||||
};
|
||||
|
||||
interface Options {
|
||||
prefix?: string;
|
||||
variants?: readonly ThemeVariant[];
|
||||
overrides?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates theme objects from global tokens and optional overrides.
|
||||
*
|
||||
* @param globals - A partial global tokens object.
|
||||
* @param options - Additional options for generating themes.
|
||||
* @param options.prefix - Optional prefix for the theme keys.
|
||||
* @param options.variants - Theme variants to generate (e.g., ['light', 'dark']).
|
||||
* @param options.overrides - Optional overrides/extensions to apply to the generated themes.
|
||||
* @returns An object mapping each theme variant (with optional prefix) to its corresponding tokens.
|
||||
*/
|
||||
export const getThemesFromGlobals = (
|
||||
globals: PartialExtendableNested<GlobalTokens> = {},
|
||||
options: Options = {},
|
||||
) => {
|
||||
const variants = options.variants || THEME_VARIANTS;
|
||||
|
||||
return variants.reduce(
|
||||
(themes, variant) => {
|
||||
const variantKey = options.prefix
|
||||
? `${options.prefix}-${variant}`
|
||||
: variant;
|
||||
|
||||
themes[variantKey] = deepmerge(
|
||||
{
|
||||
globals,
|
||||
contextuals: CONTEXTUAL_TOKENS_MAP[variant],
|
||||
},
|
||||
options.overrides || {},
|
||||
);
|
||||
|
||||
return themes;
|
||||
},
|
||||
{} as Record<string, any>,
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user