Skip to content

Commit 7cf6b2a

Browse files
committed
feat(styles): add theme .vars to access any variable
1 parent c81020e commit 7cf6b2a

File tree

3 files changed

+27
-5
lines changed

3 files changed

+27
-5
lines changed

packages/styles/src/makeTheme.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,23 @@ import { colors, HvThemeColors, type ColorTokens } from "./tokens/colors";
44
import type { HvCustomTheme, HvThemeStructure } from "./types";
55
import { mergeTheme } from "./utils";
66

7+
const getKey = (...keys: string[]) => keys.filter(Boolean).join("-");
8+
9+
/** Uses a Proxy to output the CSS Vars based on the `themeObject` */
10+
const makeVarsProxy = (themeObject: Record<string, any>, parentKey = "") => {
11+
return new Proxy(themeObject, {
12+
get(target, prop) {
13+
if (prop === "vars" || typeof prop !== "string") return null;
14+
15+
if (typeof target[prop] === "object" && target[prop] != null) {
16+
return makeVarsProxy(target[prop], getKey(parentKey, prop));
17+
}
18+
19+
return `var(--${getKey("uikit", parentKey, prop)})`;
20+
},
21+
});
22+
};
23+
724
/**
825
* Generate a theme base on the options received.
926
* Takes an incomplete theme object and adds the missing parts.
@@ -17,6 +34,9 @@ export const makeTheme = <Mode extends string = string>(
1734
const customTheme = typeof options === "function" ? options(theme) : options;
1835
const newTheme = mergeTheme(baseTheme, customTheme);
1936

37+
// @ts-expect-error type this correctly
38+
newTheme.vars = makeVarsProxy(newTheme);
39+
2040
return newTheme;
2141
};
2242

packages/styles/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ export interface HvThemeStructure<Mode extends string = string>
147147
colors: {
148148
modes: Record<Mode, HvThemeColorModeStructure>;
149149
};
150+
vars: HvThemeVars;
150151
}
151152

152153
// Custom theme

packages/styles/src/utils.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ export const getThemesList = (themes: Record<string, any>) => {
149149
};
150150

151151
export const getThemesVars = (themes: HvThemeStructure[]) => {
152-
const vars: Record<string, any> = {};
152+
const cssVars: Record<string, any> = {};
153153

154154
themes.forEach((theme) => {
155155
const colorModes = Object.keys(theme.colors.modes);
@@ -160,19 +160,20 @@ export const getThemesVars = (themes: HvThemeStructure[]) => {
160160

161161
// extract properties that shouldn't be mapped to CSS variables
162162
// @ts-expect-error align HvTheme <-> HvThemeStructure?
163-
const { base, components, name, colors, palette, icons, ...rest } = theme;
163+
const { base, components, name, colors, palette, icons, vars, ...rest } =
164+
theme;
164165

165-
vars[styleName] = toCSSVars({
166+
cssVars[styleName] = toCSSVars({
166167
colors: {
167168
...colors.modes[colorMode],
168169
},
169170
});
170171

171-
vars[themeName] = toCSSVars({
172+
cssVars[themeName] = toCSSVars({
172173
...rest,
173174
});
174175
});
175176
});
176177

177-
return vars;
178+
return cssVars;
178179
};

0 commit comments

Comments
 (0)