-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Are there plans to support dynamic parameters #90
Comments
Hey, there is no plans to do this currently or near future. It's our intentional decision. Let me explain it a bit. makeStyles({
root: { fontColor: "red" }
});
// => .hash { font-color: red }
// ⚠️ not real code
makeStyles(color => {
fontColor: color;
});
// => .??hash?? { font-color: ??? }
Another issue with dynamic params that nothing prevents following: // ⚠️ not real code, not something that we want to support
const useClasses = makeStyles(isFoo => ({
color: "red",
...(isFoo & { color: "blue" })
})); In this case static evaluation will be impossible at all. Our current solution for these cases is to use inline styles or combination with CSS variables: function App(props) {
return <div style={{ color: props.color }} />;
} const useClasses = makeStyles({
root: { color: 'var(--color)',
})
function App(props) {
const classes = useClasses()
return <div className={classes.root} style={{ '--color': props.color }} />
} P.S. We can reconsider this later based on consumers feedback, but currently we don't have enough data to turn it into usable API. |
@layershifter I do not think that this is a solution that is maintainable in the long run. I tested this on a small scale project and it was wonky at best. On one hand, it requires a lot of additional work from the user which can be faulty and can lead to mixing style with logic. On the other hand it is not possible to typecheck which makes early detection of mistakes during development even harder. If I could choose an API, it would probably look something like this: const useClasses = makeStyles((props) => {
root: { color: props.color }
}, { color: "#aabbcc" }) // type of props is the same as the second parameter
function App(props) {
const classes = useClasses({}, { color: "red" }) // same second argument types as props
return <div className={classes.root} />
} Then the makeStyles function injects some hashes into the parameters and the useClasses function handles provision of the variables via those hashes. This effectively reduces the amount of work needed to be done for an update while still allowing for changing props to influence the style. However, the work for the creation and injection of the hashes could be a bit more involved, since it would be useful to be able to pass deep objects. But since this work can be done on load it might not be as bad. |
There are two problems with that, read below. CSS variables generationTo support SSR and build time optimisations we need a deterministic way to generate CSS variables in Browser & Node environments to avoid collisions: const useClasses = makeStyles((props) => ({
root: { color: variables.color }
}))
To summarise: currently I don't know a predictable way to generate CSS variables that would scale. API changesWell, let's assume that we can generate CSS variables, but how they will be passed? const useClasses = makeStyles((props) => ({
root: { color: variables.color }
}))
function Foo() {
// Where to pass variables?
const classes = useClasses({ color: 'foo' })
} Something like that could work: function Foo() {
// Where to pass variables?
const [classes, styles] = useClasses({ color: 'foo' })
return <div className={classes.root} style={styles} />
} But I don't see this intuitive and scaling to other JS frameworks/libraries rather than React. I prototyped a solution that should be typesafe: https://codesandbox.io/s/clever-sunset-5ju2bq?file=/src/App.tsx |
Looking at the simpler Problem first, does anything speak against injecting in into a style bucket sheet with It seems to me that the hash could be generated from the encoded style object by injecting placeholder into the variables. However, in corner cases this would create collisions. |
Well, if it's global then it brings few more interesting questions:
|
sorry for coming back to you so late. Corona got me. Now assuming there is a good solution for creating a hash one could create a helper class with each call of useClasses that is passed around with the classes. This helper class then gets all the variables for the instance of useClasses. function Foo() {
const classes1 = useClasses({ color: 'red' }) // produces something like { root: ["abc123", "h3lp3r"], helpers: ["h3lp3r"] }
const classes2 = useClasses({ color: 'blue }) // produces something like { root: ["abc123", "r3pl3h"], helpers: ["r3pl3h"] }
return (
<>
<div className={classes1.root} />
<div className={classes2.root} />
</>
)
} where the previous still holds true that the helper classes get updated when the props object is updated. However this looks like it would make the problem of finding hashes even worse. |
Creating styles that are more real-time can feel incongruous! It is not known if Griffel has any plans to support dynamic parameters. Similar to:
`
const useClasses= makeStyles((color)=>({fontColor:{color}}))
const classes = useClasses('red')
`
The text was updated successfully, but these errors were encountered: