Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/martinkavik/postcss-typed-css-classes
PostCSS plugin that generates typed entities from CSS classes for chosen programming language.
https://github.com/martinkavik/postcss-typed-css-classes
classes css generator postcss postcss-plugin rust tailwindcss
Last synced: 13 days ago
JSON representation
PostCSS plugin that generates typed entities from CSS classes for chosen programming language.
- Host: GitHub
- URL: https://github.com/martinkavik/postcss-typed-css-classes
- Owner: MartinKavik
- License: mit
- Created: 2019-04-07T17:37:32.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-01-07T18:04:39.000Z (almost 2 years ago)
- Last Synced: 2024-10-23T15:15:58.964Z (22 days ago)
- Topics: classes, css, generator, postcss, postcss-plugin, rust, tailwindcss
- Language: JavaScript
- Size: 1.03 MB
- Stars: 11
- Watchers: 2
- Forks: 12
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
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)
[PostCSS] plugin that **generates** typed entities from CSS classes for a chosen programming language.
You can also use it to **filter** CSS classes to reduce output size for faster application launch.[postcss]: https://github.com/postcss/postcss
[ci-img]: https://travis-ci.org/MartinKavik/postcss-typed-css-classes.svg
[ci]: https://travis-ci.org/MartinKavik/postcss-typed-css-classes## Why
I 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.
So this plugin is trying to solve these **problems**:
1. How to force a compiler to check if used CSS class is valid (resp. given class exists in included stylesheet)?
1. I don't remember all classes - autocomplete with a class description would be nice.
1. How to reduce size of stylesheet?**Solutions**:
1. Generate a file with source code in chosen language that mirrors your stylesheet and use it instead of plain `string` class names.
1. Your IDE should autocomplete classes from generated file. You can use CSS attributes as a class description.
1. Filter out classes from stylesheet that you didn't use. (Just search your source files for used classes.)## Used In Projects:
_Do you use it? Create PR!_
- Webpack template for Rust web-apps with TailwindCSS and Typescript
- https://github.com/seed-rs/seed-quickstart-webpack## Install
```sh
yarn add postcss-typed-css-classes --dev
```## Basic Usage
```js
postcss([
require("postcss-typed-css-classes")({
generator: "rust",
}),
]);
```See [Seed Quickstart Webpack](https://github.com/MartinKavik/seed-quickstart-webpack) for using with Webpack.
See [PostCSS] docs for examples for your environment.
## Options
- ### generator
- can be:
- **a)** name of a built-in generator
- only valid values are `"rust"` and `"json"` at the time of writing
- see [rust_generator.js](/generators/rust_generator.js) and [json_generator.js](/generators/json_generator.js)
- **b)** function with one parameter `classes`
- it should return `string`
- generated file will not be created when function doesn't return `string`
- required
- examples:
- `"rust"`
- `function() {}`
- `` (classes) => `Classes: ${classes.length}` ``
- `classes` example:```json
[
{
"name": "container",
"properties": [
{
"property": "max-width: 576px",
"mediaQuery": "@media (min-width: 576px)"
}
]
}
]
```- ### output_filepath
- a file path with filename and extension
- generated code will be saved into this location
- optional if generator does not provide a default otherwise it is required
- examples:
- `path.resolve(__dirname, 'css_classes.rs')`- ### purge
- boolean to indicate that the output should be filtered
- optional
- default is false- ### content
- Can be a path string pointing to the location of the files to be processed or an array of config objects
- optional### _content options_
- ### path
- a string path or an array of globs
- optional if generator has specified a default otherwise required
- ### regex
- valid regex
- optional if generator has specified a default otherwise required
- ### mapper
- map function
- transforms class output
- optional if generator has specified a default otherwise required
- ### escape
- boolean indicating that the output needs to be escaped to meet generator requirements
- optional
- default false_examples_
```
require("postcss-typed-css-classes")({
generator: "rust",
content: 'src/**/*.rs'
})
``````
require("postcss-typed-css-classes")({
generator: "rust",
purge: options.mode === "production",
content: [
{ path: ['src/**/*.rs'] },
{
path: ['static/index.hbs', 'static/templates/**/*.hbs'],
regex: /class\s*=\s*["'|][^"'|]+["'|]/g,
mapper: className => {
return (className.match(/class\s*=\s*["'|]([^"'|]+)["'|]/)[1]).match(/\S+/g)
},
escape: true
}
],
})
```- ### filter
- a function with one parameter `class_` that will be called when a CSS class is found in your stylesheet
- optional
- If a filter function is defined, it takes precedence over any of the content opts that may have been set
- examples:
- `function() { return true }`
- `(class_) => class_ !== "not-this-class"`- ### replace
- object with key:value that is used to replace invalid characters in rust names where key is the regex and value is the replacement
- allows adding new regex replacements as well as overriding defaults_default_
```js
{
'-': '_',
':': '__',
'/': 'of',
'@': '_at_',
'\\.': '_p_',
'^(?=\\d)': '_'
}
```_example_
```js
require("postcss-typed-css-classes")({
generator: "rust",
replace: {
"-":"_d_"
}
})
```## Contributing - How To Add A New Built-In Generator
> NOTE:
> Plugin is based on official [postcss-plugin-boilerplate](https://github.com/postcss/postcss-plugin-boilerplate).
> So it uses old JS and very strict linter, but I think that code is clean enough and commented => it shouldn't be problem for a small project like this and we don't have to solve problems with building pipelines.1. Fork this repo
1. Run `yarn` in project root
1. Choose a name for a generator - we'll use `csharp` for this guide
1. Duplicate file `/generators/json_generator.js` and rename it to `csharp_generator.js`
1. Open `csharp_generator.js` and change:```js
// - pretty-print JSON with 4 spaces indentation
// - with a new line at the end of a file
// - see EXAMPLE CODE:
// `/tests/json_generator_test/json_generator.basic.expected_output`
function generate (classes) {
return JSON.stringify(classes, undefined, 4) + os.EOL
}
```to
```js
// - generate C# class
// - see EXAMPLE CODE:
// `/tests/csharp_generator_test/csharp_generator.basic.expected_output`
function generate (classes) {
return "..I'm a c# class with " + classes.length + ' fields..' + os.EOL
}
```7. Open `/index.js`
1. Insert line```js
var csharpGeneratorModule = require('./generators/csharp_generator')
```below the line
```js
var jsonGeneratorModule = require('./generators/json_generator')
```9. Insert case
```js
case 'csharp':
return csharpGeneratorModule.generate
```into function `getDefaultGenerator`
10. Duplicate folder `/tests/json_generator_test` and rename it to `csharp_generator_test`
1. Rename `/tests/csharp_generator_test/json_generator.basic.expected_output` to `csharp_generator.basic.expected_output`
1. Change content of `csharp_generator.basic.expected_output` to
```
..I'm a c# class with 6 fields..```
(new line at the end is necessary)
13. Rename `/tests/csharp_generator_test/json_generator.test.js` to `csharp_generator.test.js`
1. Open `csharp_generator.test.js` and change `GENERATOR_NAME` from `json` to `csharp`
1. Run `yarn test` in the project root
1. Update [README.md](/README.md) if necessary
1. Update [CHANGELOG.md](CHANGELOG.md)
1. Create pull request to this repo (squash commits and rebase if necessary)