Possible limitation
jpmaga opened this issue · 10 comments
Hello all, I am currenlty evaluating astroturf and linaria to see which one fits our needs the best. So far astroturf is in the lead, but I think i found a possible limitation that would make it unusable for us. Or maybe I'm just missing some configuration flag or workaround.
I'm trying to assign different classes to an object, but I am greeted with the following error message:
There are multiple css tags with the same inferred identifier. Differentiate each tag by assigning the output to a unique identifier
and here is a sample code:
const styles = {
App: css`text-align: center;`,
header: css`background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;`,
link: css`color: #b318f0;`,
logo: css`
animation: logo-spin infinite 20s linear;
height: 40vmin;
pointer-events: none;
@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
`
}
Wouldn't it make sense to include the object key in the identifier in this case? Or what am I missing here?
Cheers.
does this not work already? I can totally make it work if it doesn't yeah
also you don't need to declare each class separately like this, stylesheet
produces the same object with properties
Cool, thanks for the quick fix. Already tested and it is working just fine.
I hit another road block in the meantime. I feel this one might be by design, but just in case it isn't... It seems i can't interpolate strings (derived from functions). here is an example:
const interpolationFn = () => "tomato"
const color = interpolationFn()
const b_class = css`
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: ${color};
`
And this is the error message:
The following expression could not be evaluated during compilation. Dynamic expressions can only be used in the context of a component, in a `css` prop, or styled() component helper
118 | justify-content: center;
119 | font-size: calc(10px + 2vmin);
> 120 | color: ${color};
| ^^^^^
Linaria handles this without issues, so it might have put my expectations a bit higher than they should. To our use case this is now the only thing failing our test suite. If you could let me know if this is by design or just an overlooked feature, that would be great. Many thanks! 🙏
yeah this isn't supported in astroturf, because the value of the interpolation isn't statically determinable. Linaria handles this by actually running your code to get the value of the fn, which has it's own downsides (its much slower and can create an uncanny valley around where code runs).
Astroturf supports dynamic values in the context of a component, where it can't replace the value with a CSS property, e.g.
function ({ color }) {
return <div css={css`
color: ${color}
`} />
}
yeah this isn't supported in astroturf, because the value of the interpolation isn't statically determinable. Linaria handles this by actually running your code to get the value of the fn, which has it's own downsides (its much slower and can create an uncanny valley around where code runs).
Astroturf supports dynamic values in the context of a component, where it can't replace the value with a CSS property, e.g.
function ({ color }) { return <div css={css` color: ${color} `} /> }
Thanks for the quick reply. Yes, I saw that, it is and interesting approach, but for our use case doesn't work. We're not even using react and this is required to run a function kinda like vanilla extract's sprinkle. In any case, I understand the design decision, and thank you for your time. Cheers.
also you don't need to declare each class separately like this,
stylesheet
produces the same object with properties
Hello. I am still trying to use astroturf instead of Linaria. :) Using this approach works alright, but, i don't seem to get any type inference.
const styles = stylesheet`
.root {
color: red;
}
`
console.log(styles.root) // no ts validation
console.log(styles.something) // no ts error
Don't really know how to handle this, if you could shed some light on the matter that would be great.
this is just a hard limitation of ts, you'd need a type plugin for this to work and TS doesn't allow that (if something else is doing this let me know i will see how they manage it).
The simplest way to avoid is like you tried originally with css
to declare individual classes on an object, There are some differences between that and the stylesheet
approach but should be the same feature-wise.
this is just a hard limitation of ts, you'd need a type plugin for this to work and TS doesn't allow that (if something else is doing this let me know i will see how they manage it).
The simplest way to avoid is like you tried originally with
css
to declare individual classes on an object, There are some differences between that and thestylesheet
approach but should be the same feature-wise.
I've been using this with plain css modules: https://github.com/mrmckeb/typescript-plugin-css-modules and it works great. Even parses sass and postcss plugins. But have no idea if you can adapt to to the inner workings of astroturf.
you definitely could get that to work, astroturf is just css-modules, so all you'd need to do is tell it which template tags are actually css-modules. (the author might even add support if we ask) but that's not the same as TS errors, e.g. tsc -p .
wouldn't give you type errors, but I agree the intellisense is nice...there is already an astroturf vscode extension we could add this too as well...
Well, I suggested it in here: mrmckeb/typescript-plugin-css-modules#220 So... 🤞