Skip to content

Commit 5627b68

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

File tree

5 files changed

+65
-10
lines changed

5 files changed

+65
-10
lines changed

packages/core/src/Typography/Typography.tsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ import {
1818

1919
export { staticClasses as typographyClasses };
2020

21+
/** extend this interface with your custom typography variants */
22+
export interface HvCustomTypographyVariants {}
23+
2124
export type HvTypographyClasses = ExtractNames<typeof useClasses>;
2225

2326
const HvTypographyMap = {
@@ -62,7 +65,11 @@ export type HvTypographyProps<C extends React.ElementType = "p"> =
6265
C,
6366
{
6467
/** Use the variant prop to change the visual style of the Typography. */
65-
variant?: HvTypographyVariants | HvTypographyLegacyVariants;
68+
variant?:
69+
| HvTypographyVariants
70+
| HvTypographyLegacyVariants
71+
| keyof HvCustomTypographyVariants
72+
| (string & {});
6673
/** If `true` the typography will display the look of a link. */
6774
link?: boolean;
6875
/** If `true` the typography will display the look of a disabled state. */
@@ -95,10 +102,10 @@ export const HvTypography = fixedForwardRef(function HvTypography<
95102
component: ComponentProp,
96103
classes: classesProp,
97104
variant: variantProp = "body",
98-
link = false,
99-
noWrap = false,
100-
paragraph = false,
101-
disabled = false,
105+
link,
106+
noWrap,
107+
paragraph,
108+
disabled,
102109
...others
103110
} = useDefaultProps("HvTypography", props);
104111
const { classes, css, cx } = useClasses(classesProp);

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/themes/pentahoPlus.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ import {
1616

1717
const pentahoPlus = makeTheme((theme) => ({
1818
name: "pentahoPlus",
19+
otherColors: {
20+
gray: {
21+
strong: "lightgray",
22+
subtle: "gainsboro",
23+
dimmed: "darkgray",
24+
},
25+
},
1926
colors: makeColors({
2027
brand: blue[600],
2128
catastrophic: [rose[800], pink[600]],
@@ -27,6 +34,8 @@ const pentahoPlus = makeTheme((theme) => ({
2734
shadow: `0px 2px 4px -1px ${theme.alpha(slate[700], 0.08)}`,
2835
shad1: theme.alpha(slate[700], 0.08),
2936

37+
veryPurple: "rebeccapurple",
38+
3039
primary: [blue[600], blue[500]],
3140
primaryStrong: [blue[700], blue[600]],
3241
primaryDeep: [blue[800], blue[700]],
@@ -95,6 +104,15 @@ const pentahoPlus = makeTheme((theme) => ({
95104
fontSize: theme.fontSizes.xl3,
96105
lineHeight: theme.lineHeights.xl3,
97106
letterSpacing: "0.00384em",
107+
backgroundColor: "red",
108+
},
109+
title1Label: {
110+
color: "white",
111+
fontWeight: theme.fontWeights.bold,
112+
fontSize: theme.fontSizes.xl3,
113+
lineHeight: theme.lineHeights.xl3,
114+
letterSpacing: "0.00384em",
115+
backgroundColor: "red",
98116
},
99117
title2: {
100118
color: theme.colors.secondary,
@@ -103,6 +121,14 @@ const pentahoPlus = makeTheme((theme) => ({
103121
lineHeight: theme.lineHeights.xl2,
104122
letterSpacing: "0.00288em",
105123
},
124+
title2Label: {
125+
color: "white",
126+
fontWeight: theme.fontWeights.bold,
127+
fontSize: theme.fontSizes.xl2,
128+
lineHeight: theme.lineHeights.xl2,
129+
letterSpacing: "0.00288em",
130+
backgroundColor: "red",
131+
},
106132
title3: {
107133
color: theme.colors.secondary,
108134
fontWeight: theme.fontWeights.semibold,

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)