{"id":17460966,"url":"https://github.com/hudochenkov/postcss-styled-syntax","last_synced_at":"2025-05-16T14:08:37.801Z","repository":{"id":65177481,"uuid":"383282815","full_name":"hudochenkov/postcss-styled-syntax","owner":"hudochenkov","description":"PostCSS syntax for CSS-in-JS like styled-components","archived":false,"fork":false,"pushed_at":"2025-01-16T21:37:42.000Z","size":329,"stargazers_count":78,"open_issues_count":4,"forks_count":4,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-14T03:44:35.242Z","etag":null,"topics":["css-in-js","postcss","postcss-syntax","styled-components"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hudochenkov.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-05T23:00:51.000Z","updated_at":"2025-03-25T15:42:26.000Z","dependencies_parsed_at":"2024-01-02T19:29:24.328Z","dependency_job_id":"36998557-2808-4c6d-9184-7efb986e7119","html_url":"https://github.com/hudochenkov/postcss-styled-syntax","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hudochenkov%2Fpostcss-styled-syntax","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hudochenkov%2Fpostcss-styled-syntax/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hudochenkov%2Fpostcss-styled-syntax/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hudochenkov%2Fpostcss-styled-syntax/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hudochenkov","download_url":"https://codeload.github.com/hudochenkov/postcss-styled-syntax/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254544146,"owners_count":22088807,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["css-in-js","postcss","postcss-syntax","styled-components"],"created_at":"2024-10-18T06:24:17.110Z","updated_at":"2025-05-16T14:08:37.734Z","avatar_url":"https://github.com/hudochenkov.png","language":"JavaScript","readme":"# postcss-styled-syntax\n\nPostCSS syntax for template literals CSS-in-JS (e. g. styled-components, Emotion). It was built to be used as [Stylelint] custom syntax or with [PostCSS] plugins.\n\nSyntax supports:\n\n- Full spectrum of styled-components syntax\n- Deeply nested interpolations\n- Interpolations in selectors, property names, and values\n- JavaScript and TypeScript (including files with JSX)\n- All functions:\n\t- \u003ccode\u003estyled.foo``\u003c/code\u003e\n\t- \u003ccode\u003estyled(Component)``\u003c/code\u003e\n\t- \u003ccode\u003estyled.foo.attrs({})``\u003c/code\u003e\n\t- \u003ccode\u003estyled(Component).attrs({})``\u003c/code\u003e\n\t- \u003ccode\u003estyled.foo(props =\u003e ``)\u003c/code\u003e\n\t- \u003ccode\u003estyled(Component)(props =\u003e ``)\u003c/code\u003e\n\t- \u003ccode\u003ecss``\u003c/code\u003e\n\t- \u003ccode\u003ecreateGlobalStyle``\u003c/code\u003e\n\n```js\nlet Component = styled.p`\n\tcolor: #bada55;\n`;\n```\n\n## Install\n\n```\nnpm install --save-dev postcss-styled-syntax\n```\n\n## Usage\n\n### Stylelint\n\nInstall syntax and add to a Stylelint config:\n\n```json\n{\n\t\"customSyntax\": \"postcss-styled-syntax\"\n}\n```\n\nStylelint [custom syntax documentation](https://stylelint.io/user-guide/usage/options#customsyntax).\n\n### PostCSS\n\nInstall syntax and add to a PostCSS config:\n\n```js\nmodule.exports = {\n\tsyntax: 'postcss-styled-syntax',\n\tplugins: [ /* ... */ ],\n};\n```\n\nAn example assumes using [PostCSS CLI](https://github.com/postcss/postcss-cli) or another PostCSS runner with config support.\n\n## How it works\n\n### Parsing\n\nSyntax parser JavaScript/TypeScript code and find all supported components and functions (e.g., \u003ccode\u003ecss\\`\\`\u003c/code\u003e). Then, it goes over them and builds a PostCSS AST, where all found components become `Root` nodes inside the `Document` node.\n\nAll interpolations within the found component CSS end up in the AST. E. g. for a declaration `color: ${brand}` `Decl` node will look like this:\n\n```js\nDecl {\n\tprop: 'color',\n\tvalue: '${brand}',\n}\n```\n\nWhen interpolation is not part of any node, it goes to the next node's `raws.before`. For example, for the following code:\n\n```js\nlet Component = styled.p`\n\t${textStyles}\n\n\tcolor: red;\n`;\n```\n\nAST will look like:\n\n```js\nDecl {\n\tprop: 'color',\n\tvalue: 'red',\n\traws: {\n\t\tbefore: '\\n\\t${textStyles}\\n\\n\\t',\n\t\t// ...\n\t}\n}\n```\n\nIf there is no next node after interpolation, it will go to parents `raws.after`. For example, for the following code:\n\n```js\nlet Component = styled.p`\n\tcolor: red;\n\n\t${textStyles}\n`;\n```\n\nAST will look like:\n\n```js\nRoot {\n\tnodes: [\n\t\tDecl {\n\t\t\tprop: 'color',\n\t\t\tvalue: 'red',\n\t\t},\n\t],\n\traws: {\n\t\tafter: '\\n\\n\\t${textStyles}\\n'\n\t\t// ...\n\t},\n}\n```\n\n### Stringifying\n\nMostly, it works just as the default PostCSS stringifyer. The main difference is the `css` helper in interpolations within a styled component code. E. g. situations like this:\n\n```js\nlet Component = styled.p`\n\t${(props) =\u003e\n\t\tprops.isPrimary\n\t\t\t? css`\n\t\t\t\t\tbackground: green;\n\t\t\t  `\n\t\t\t: css`\n\t\t\t\t\tborder: 1px solid blue;\n\t\t\t  `}\n\n\tcolor: red;\n`;\n```\n\n`css` helper inside an interpolation within `Component` code.\n\nDuring parsing, the whole interpolation (`${(props) ... }`) is added as `raws.before` to `color: red` node. And it should not be modified. Each `css` helper remembers their original content (as a string).\n\nWhen stringifyer reaches a node's `raws.before`, it checks if it has interpolations with `css` helpers. If yes, it searches for the original content of `css` helper and replaces it with a stringified `css` helper. This way, changes to the AST of the `css` helper will be stringified.\n\n## Known issues\n\n- Double-slash comments (`//`) will result in a parsing error. Use standard CSS comments instead (`/* */`). It is definitely possible to add support for double-slash comments, but let's use standard CSS as much as possible\n\n- Source maps won't work or cannot be trusted. I did not disable them on purpose. But did not test them at all. Because of the way we need to handle `css` helpers within a styled component, `source.end` positions on a node might change if `css` AST changes. See the “How it works” section on stringifying for more info.\n\n## Acknowledgements\n\n[PostCSS] for tokenizer, parser, stringifier, and tests for them.\n\n[Prettier](https://prettier.io/) for styled-components detection function in an ESTree AST.\n\n[Stylelint]: https://stylelint.io/\n[PostCSS]: https://postcss.org/\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhudochenkov%2Fpostcss-styled-syntax","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhudochenkov%2Fpostcss-styled-syntax","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhudochenkov%2Fpostcss-styled-syntax/lists"}