Remove evaluation of styled wrapped component
- Dominant language
- TypeScript
- Stars
- 12.4k
- Forks
- 413
- PR merge metrics
- No merged PRs in 30d
Description
## Describe the enhancement
## Motivation
There are some issues caused by evaluating the styled wrapped component.
```js
import {Link} from 'routing-library'
const styled = myLink = styled(Link)``
```
See https://github.com/silvenon/gatsby-plugin-linaria/issues/19 or https://github.com/callstack/linaria/issues/447
It happens because we treat `Link` as a lazy dependency, that has to be evaluated.
We need to evaluate Link, to get it's generated className (in case it will be a linaria styled component).
We want to later produce more specific class names if styled components are composed together. For example given components
```js
// produces selector: '.a'
const A = styled.div`
background-color: red;
`
// produces selector: '.b.a'
const B = styled(A)`
background-color: green;
`
// produces selector: '.c.b.a'
const C = styled(B)`
background-color: blue;
`
```
it generates the following CSS
```css
.a {
background-color: red;
}
.b.a {
background-color: green;
}
.c.b.a {
background-color: blue;
}
```
Which eventually prevents from situation, where rules in CSS are saved in different order than we produced them.
If we skip mentioned evaluation and will not have information about classNames from previous components, it will produce selectors with just class names
```js
const A = styled.div`` // produces selector: '.a'
const B = styled(A)`` // produces selector: '.b'
const C = styled(B)`` // produces selector: '.c'
```
and will generate following CSS
```css
.a {
background-color: red;
}
.b {
background-color: green;
}
.c {
background-color: blue;
}
```
The actual styled component will have these class names regardless the generated CSS
```js
```
So if order of rules in CSS file will not be changed, it will work the same as more specific selectors.
The only place that we do not control in terms of CSS ordering us custom preprocessors or how CSS files are bundled by the bundler. I think with both cases we are safe, because preprocessor cannot break CSS, it has follow its rules, and bundlers should follow files resolution order the same we use to evaluate reps.
@satya164 suggested, we need to check if style loaders also persist the order.
## Possible implementations
We can remove the following condition
https://github.com/callstack/linaria/blob/fb65ee41bf569baa78affbdb2fb74d6bc8784b60/src/babel/visitors/TaggedTemplateExpression.ts#L224-L232
And code responsible for merging the class names
https://github.com/callstack/linaria/blob/fb65ee41bf569baa78affbdb2fb74d6bc8784b60/src/babel/evaluators/templateProcessor.ts#L205-L211
## Related Issues
https://github.com/silvenon/gatsby-plugin-linaria/issues/19
https://github.com/callstack/linaria/issues/447
https://github.com/callstack/linaria/issues/454
and maybe this https://github.com/callstack/linaria/issues/399
https://github.com/zeit/next.js/issues/7769
Contributor guide
Assessment
This issue has not been assessed yet.