stylex
stylex copied to clipboard
[Question] Do we have a solution for overriding any properties this with `stylex.createTheme`?
To customize themes, the customer can configure any variables (color, font, size...) in the Settings feature and save it to the local storage and init when app start. Do we have a solution for overriding properties with stylex.createTheme
?
Currently it will throw err if we use fn: theme.stylex.ts: Only static values are allowed inside of a stylex.create() call
const getOverrideColors = () => {
// Get from localStorage or api on app init
return {
//
};
};
const overrideColors = getOverrideColors();
export const darkTheme = stylex.createTheme(colors, {
...colorRepos,
...overrideColors,
});
You need to set dynamic values for variables. Please use stylex.create
and dynamic styles to achieve this.
Also, please don't define themes in the .stylex.ts
file. That file is only for defineVars
calls.
import * as stylex from '@stylexjs/stylex';
import {darkTheme} from './themes';
function Root({children}) {
const {color, font, size} = useOverrideColors();
return <div {...stylex.props(
// The default theme values
// the default values passed to `defineVars` might be sufficient
// and you may not need this at all.
darkTheme,
// The user-defined dynamic overrides whose values cannot be statically known.
color && styles.color(color),
font && styles.font(font),
size && styles.size(size),
)}>
{children}
</div>
}
const styles = stylex.create({
color: (color: string) => ({color}),
font: (fontFamily: string) => ({fontFamily}),
size: (fontSize: number | string) => ({fontFamily}),
});
@nmn, When we use color: (color: string) => ({color})
it will make text content color by the input color.
In my case, I want to override an value in colors (create by defineVars).
Example: colors.primary: blue
, then we can override colors.primary: newColor
by createTheme
.
Finally, we use the dynamic color in localStorage to override the value by createTheme
. It will change all component that use the colors.primary
to dynamic color.
You can use stylex.create
to override variables.
color: (color: string) => ({[colors.primary]: color})
@nmn This code color: (color: string) => ({[colors.primary]: color})
will override only one property but didn't work to override multiples properties.
const overrideStyles = stylex.create({
colors: (
newColors: {
primary: string;
secondary: string;
}
) => ({
// This trick is worked
[colors.primary.replace('var(', '').replace(')', '')]: newColors.primary,
[colors.secondary.replace('var(', '').replace(')', '')]: newColors.secondary,
// It would be convenient if this syntax worked too
// [colors.primary]: newColors.primary,
// [colors.secondary]: newColors.secondary,
}),
});
// It would be convenient if this syntax worked too
// [colors.primary]: newColors.primary,
// [colors.secondary]: newColors.secondary,
This should work. It's a bug if it's not. Reopened issue will investigate.
Seeing the same issue when attemping to set a token inside a dynamic style
const styles = stylex.create({
dragging: (position) => ({
[tokens.position]: `${position}px`,
}),
});
I see the following eslint error
Computed key cannot be resolved.eslint(@stylexjs/valid-styles)
The generated style attribute looks like:
style="--var\(--x3b528y\): 21.9375px;"
which I think is why the .replace('--var(', '').replace(')', '')
hack was suggested.
I'm using @^0.5.0-alpha.3
Thanks for the specific example to verify. Will fix.
#376 should fix this.
Fixed in 0.5.0