{"id":15681482,"url":"https://github.com/martinkavik/postcss-typed-css-classes","last_synced_at":"2025-05-07T08:44:15.828Z","repository":{"id":34636777,"uuid":"180000499","full_name":"MartinKavik/postcss-typed-css-classes","owner":"MartinKavik","description":"PostCSS plugin that generates typed entities from CSS classes for chosen programming language.","archived":false,"fork":false,"pushed_at":"2023-01-07T18:04:39.000Z","size":1077,"stargazers_count":11,"open_issues_count":7,"forks_count":12,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-20T11:18:13.506Z","etag":null,"topics":["classes","css","generator","postcss","postcss-plugin","rust","tailwindcss"],"latest_commit_sha":null,"homepage":null,"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/MartinKavik.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-04-07T17:37:32.000Z","updated_at":"2022-08-02T09:06:03.000Z","dependencies_parsed_at":"2023-01-15T08:13:37.740Z","dependency_job_id":null,"html_url":"https://github.com/MartinKavik/postcss-typed-css-classes","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/MartinKavik%2Fpostcss-typed-css-classes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MartinKavik%2Fpostcss-typed-css-classes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MartinKavik%2Fpostcss-typed-css-classes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MartinKavik%2Fpostcss-typed-css-classes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MartinKavik","download_url":"https://codeload.github.com/MartinKavik/postcss-typed-css-classes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252846105,"owners_count":21813378,"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":["classes","css","generator","postcss","postcss-plugin","rust","tailwindcss"],"created_at":"2024-10-03T16:55:24.086Z","updated_at":"2025-05-07T08:44:15.782Z","avatar_url":"https://github.com/MartinKavik.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PostCSS Typed Css Classes [![npm version](https://badge.fury.io/js/postcss-typed-css-classes.svg)](https://badge.fury.io/js/postcss-typed-css-classes)\n\n[PostCSS] plugin that **generates** typed entities from CSS classes for a chosen programming language.\nYou can also use it to **filter** CSS classes to reduce output size for faster application launch.\n\n[postcss]: https://github.com/postcss/postcss\n[ci-img]: https://travis-ci.org/MartinKavik/postcss-typed-css-classes.svg\n[ci]: https://travis-ci.org/MartinKavik/postcss-typed-css-classes\n\n## Why\n\nI like [atomic css](https://css-tricks.com/lets-define-exactly-atomic-css/) libraries like TailwindCSS or Tachyons. I also like statically typed languages like Rust or Elm where compiler is your best friend and teacher.\n\nSo this plugin is trying to solve these **problems**:\n\n1. How to force a compiler to check if used CSS class is valid (resp. given class exists in included stylesheet)?\n1. I don't remember all classes - autocomplete with a class description would be nice.\n1. How to reduce size of stylesheet?\n\n**Solutions**:\n\n1. Generate a file with source code in chosen language that mirrors your stylesheet and use it instead of plain `string` class names.\n1. Your IDE should autocomplete classes from generated file. You can use CSS attributes as a class description.\n1. Filter out classes from stylesheet that you didn't use. (Just search your source files for used classes.)\n\n## Used In Projects:\n\n_Do you use it? Create PR!_\n\n- Webpack template for Rust web-apps with TailwindCSS and Typescript\n  - https://github.com/seed-rs/seed-quickstart-webpack\n\n## Install\n\n```sh\nyarn add postcss-typed-css-classes --dev\n```\n\n## Basic Usage\n\n```js\npostcss([\n  require(\"postcss-typed-css-classes\")({\n    generator: \"rust\",\n  }),\n]);\n```\n\nSee [Seed Quickstart Webpack](https://github.com/MartinKavik/seed-quickstart-webpack) for using with Webpack.\n\nSee [PostCSS] docs for examples for your environment.\n\n## Options\n\n- ### generator\n\n  - can be:\n    - **a)** name of a built-in generator\n      - only valid values are `\"rust\"` and `\"json\"` at the time of writing\n        - see [rust_generator.js](/generators/rust_generator.js) and [json_generator.js](/generators/json_generator.js)\n    - **b)** function with one parameter `classes`\n      - it should return `string`\n      - generated file will not be created when function doesn't return `string`\n  - required\n  - examples:\n    - `\"rust\"`\n    - `function() {}`\n    - `` (classes) =\u003e `Classes: ${classes.length}` ``\n  - `classes` example:\n\n  ```json\n  [\n    {\n      \"name\": \"container\",\n      \"properties\": [\n        {\n          \"property\": \"max-width: 576px\",\n          \"mediaQuery\": \"@media (min-width: 576px)\"\n        }\n      ]\n    }\n  ]\n  ```\n\n- ### output_filepath\n\n  - a file path with filename and extension\n  - generated code will be saved into this location\n  - optional if generator does not provide a default otherwise it is required\n  - examples:\n    - `path.resolve(__dirname, 'css_classes.rs')`\n\n- ### purge\n\n  - boolean to indicate that the output should be filtered\n  - optional\n  - default is false\n\n- ### content\n\n  - Can be a path string pointing to the location of the files to be processed or an array of config objects\n  - optional\n\n  ### _content options_\n\n  - ### path\n    - a string path or an array of globs\n    - optional if generator has specified a default otherwise required\n  - ### regex\n    - valid regex\n    - optional if generator has specified a default otherwise required\n  - ### mapper\n    - map function\n    - transforms class output\n    - optional if generator has specified a default otherwise required\n  - ### escape\n    - boolean indicating that the output needs to be escaped to meet generator requirements\n    - optional\n    - default false\n\n_examples_\n\n```\n  require(\"postcss-typed-css-classes\")({\n    generator: \"rust\",\n    content: 'src/**/*.rs'\n  })\n```\n\n\n```\n  require(\"postcss-typed-css-classes\")({\n    generator: \"rust\",\n    purge: options.mode === \"production\",\n    content: [\n      { path: ['src/**/*.rs'] },\n      {\n        path: ['static/index.hbs', 'static/templates/**/*.hbs'],\n        regex: /class\\s*=\\s*[\"'|][^\"'|]+[\"'|]/g,\n        mapper: className =\u003e {\n          return (className.match(/class\\s*=\\s*[\"'|]([^\"'|]+)[\"'|]/)[1]).match(/\\S+/g)\n        },\n        escape: true\n      }\n    ],\n  })\n```\n\n- ### filter\n  - a function with one parameter `class_` that will be called when a CSS class is found in your stylesheet\n  - optional\n  - If a filter function is defined, it takes precedence over any of the content opts that may have been set\n  - examples:\n    - `function() { return true }`\n    - `(class_) =\u003e class_ !== \"not-this-class\"`\n\n- ### replace\n\t- object with key:value that is used to replace invalid characters in rust names where key is the regex and value is the replacement\n\t- allows adding new regex replacements as well as overriding defaults\n\n_default_\n```js\n{\n    '-': '_',\n    ':': '__',\n    '/': 'of',\n    '@': '_at_',\n    '\\\\.': '_p_',\n    '^(?=\\\\d)': '_'\n }\n```\n\n_example_\n```js\nrequire(\"postcss-typed-css-classes\")({\n    generator: \"rust\",\n    replace: {\n\t\t\"-\":\"_d_\"\n\t}\n  })\n```\n\n## Contributing - How To Add A New Built-In Generator\n\n\u003e NOTE:\n\u003e Plugin is based on official [postcss-plugin-boilerplate](https://github.com/postcss/postcss-plugin-boilerplate).\n\u003e So it uses old JS and very strict linter, but I think that code is clean enough and commented =\u003e it shouldn't be problem for a small project like this and we don't have to solve problems with building pipelines.\n\n1. Fork this repo\n1. Run `yarn` in project root\n1. Choose a name for a generator - we'll use `csharp` for this guide\n1. Duplicate file `/generators/json_generator.js` and rename it to `csharp_generator.js`\n1. Open `csharp_generator.js` and change:\n\n\u003c!-- prettier-ignore --\u003e\n```js\n// - pretty-print JSON with 4 spaces indentation\n// - with a new line at the end of a file\n// - see EXAMPLE CODE:\n//     `/tests/json_generator_test/json_generator.basic.expected_output`\nfunction generate (classes) {\n  return JSON.stringify(classes, undefined, 4) + os.EOL\n}\n```\n\nto\n\n\u003c!-- prettier-ignore --\u003e\n```js\n// - generate C# class\n// - see EXAMPLE CODE:\n//     `/tests/csharp_generator_test/csharp_generator.basic.expected_output`\nfunction generate (classes) {\n  return \"..I'm a c# class with \" + classes.length + ' fields..' + os.EOL\n}\n```\n\n7. Open `/index.js`\n1. Insert line\n\n\u003c!-- prettier-ignore --\u003e\n```js\nvar csharpGeneratorModule = require('./generators/csharp_generator')\n```\n\nbelow the line\n\n\u003c!-- prettier-ignore --\u003e\n```js\nvar jsonGeneratorModule = require('./generators/json_generator')\n```\n\n9. Insert case\n\n\u003c!-- prettier-ignore --\u003e\n```js\ncase 'csharp':\n    return csharpGeneratorModule.generate\n```\n\ninto function `getDefaultGenerator`\n\n10. Duplicate folder `/tests/json_generator_test` and rename it to `csharp_generator_test`\n1. Rename `/tests/csharp_generator_test/json_generator.basic.expected_output` to `csharp_generator.basic.expected_output`\n1. Change content of `csharp_generator.basic.expected_output` to\n   \u003c!-- prettier-ignore --\u003e\n\n```\n..I'm a c# class with 6 fields..\n\n```\n\n(new line at the end is necessary)\n\n13. Rename `/tests/csharp_generator_test/json_generator.test.js` to `csharp_generator.test.js`\n1. Open `csharp_generator.test.js` and change `GENERATOR_NAME` from `json` to `csharp`\n1. Run `yarn test` in the project root\n1. Update [README.md](/README.md) if necessary\n1. Update [CHANGELOG.md](CHANGELOG.md)\n1. Create pull request to this repo (squash commits and rebase if necessary)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartinkavik%2Fpostcss-typed-css-classes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmartinkavik%2Fpostcss-typed-css-classes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartinkavik%2Fpostcss-typed-css-classes/lists"}