securityos/node_modules/postcss-styled-syntax/README.md

162 lines
3.9 KiB
Markdown
Raw Permalink Normal View History

2024-09-06 15:32:35 +00:00
# postcss-styled-syntax
PostCSS syntax for template literals CSS-in-JS (e. g. styled-components, Emotion). Built to be used as [Stylelint] custom syntax or with [PostCSS] plugins.
Syntax supports:
- Full spectrum of styled-components syntax
- Deeply nested interpolations
- Interpolations in selectors, property names and values
- JavaScript and TypeScript (including files with JSX)
- All functions:
- `styled.foo`
- `styled(Component)`
- `styled.foo.attrs({})`
- `styled(Component).attrs({})`
- `css`
- `createGlobalStyle`
```js
let Component = styled.p`
color: #bada55;
`;
```
## Install
```
npm install --save-dev postcss-styled-syntax
```
## Usage
### Stylelint
Install syntax and add to a Stylelint config:
```json
{
"customSyntax": "postcss-styled-syntax"
}
```
Stylelint [custom syntax documentation](https://stylelint.io/user-guide/usage/options#customsyntax).
### PostCSS
Install syntax and add to a PostCSS config:
```js
module.exports = {
syntax: 'postcss-styled-syntax',
plugins: [ /* ... */ ],
};
```
Example assumes using [PostCSS CLI](https://github.com/postcss/postcss-cli) or other PostCSS runner with config support.
## How it works
### Parsing
Syntax parser JavaScript/TypeScript code and find all supported components and functions (e. g. <code>css\`\`</code>). Then it go over them and builds a PostCSS AST, where all found components become `Root` nodes inside `Document` node.
All interpolations within found component CSS are end up in the AST. E. g. for a declaration `color: ${brand}` `Decl` node will look like:
```js
Decl {
prop: 'color',
value: '${brand}',
}
```
When interpolation is not part of any node it goes to the next node's `raws.before`. For example for the following code:
```js
let Component = styled.p`
${textStyles}
color: red;
`;
```
AST will look like:
```js
Decl {
prop: 'color',
value: 'red',
raws: {
before: '\n\t${textStyles}\n\n\t',
// ...
}
}
```
If there is not next node after interpolation, it will go to parents `raws.after`. For example for the following code:
```js
let Component = styled.p`
color: red;
${textStyles}
`;
```
AST will look like:
```js
Root {
nodes: [
Decl {
prop: 'color',
value: 'red',
},
],
raws: {
after: '\n\n\t${textStyles}\n'
// ...
},
}
```
### Stringifying
Mostly it works just as default PostCSS stringifyer. The main difference is `css` helper in interpolations within a styled component code. E. g. situatians like this:
```js
let Component = styled.p`
${(props) =>
props.isPrimary
? css`
background: green;
`
: css`
border: 1px solid blue;
`}
color: red;
`;
```
`css` helper inside an interpolation within `Component` code.
During parsing whole interpolation (`${(props) ... }`) is added as `raws.before` to `color: red` node. And it should not be modified. Each `css` helpers remember their original content (as a string).
When stringifyer reaches `raws.before` of a node it checks if it has interpolations with `css` helpers. If yes, then it searchs for `css` helper original content and replace it with stringified `css` helper. This way changes made to the AST of `css` helper will be stringified.
## Known issues
- Double slash comments (`//`) will result in parsing error. Use standard CSS comments instead (`/* */`). It is definitelly possible to add support for double slash comment, but let's use standard CSS as much as possible
- Source maps won't work or could not be trusted. I did not disable them on purpose. But did not test them at all. Because of the way we need handle `css` helpers within styled component, `source.end` positions on a node might change if `css` AST changes. See “How it works” section on stringifying for more info.
## Acknowledgements
[PostCSS] for tokenizer, parser, stringifier and tests for them.
[Prettier](https://prettier.io/) for styled-components detection function in an ESTree AST.
[Stylelint]: https://stylelint.io/
[PostCSS]: https://postcss.org/