/tailwind-ppx

Reason/OCaml PPX that validates your Tailwind classes at compile-time

Primary LanguageReasonMIT LicenseMIT

tailwind-ppx

Actions Status NPM Version

Reason/OCaml PPX for writing compile-time validated Tailwind CSS classes.

<Component className=[%tw "flex flex-ro"]> // ERROR: Class name not found: flex-ro
  ...
</Component>

Installation

The most likely use case for tailwind-ppx is inside ReasonReact projects (using BuckleScript). To get started, we recommend cloning our demo project.

With yarn or npm on Bucklescript projects

Install the PPX with yarn or npm

yarn add --dev @dylanirlbeck/tailwind-ppx
# Or
npm install --dev @dylanirlbeck/tailwind-ppx

And add the PPX in your bsconfig.json file:

{
  "ppx-flags": ["@dylanirlbeck/tailwind-ppx/tailwind-ppx"]
}

You can also use esy to install the PPX inside your BuckleScript project.

Create an esy.json file with the content:

{
  "name": "test_bs",
  "version": "0.0.0",
  "dependencies": {
    "@opam/tailwind-ppx": "*",
    "ocaml": "~4.6.1000"
  }
}

And add the PPX in your bsconfig.json file:

{
  "ppx-flags": ["esy x tailwind-ppx"]
}

Usage

tailwind_ppx implements a ppx that validates your Tailwind CSS classes at compile time.

For example, for the following (condensed) tailwind.css file:

.flex {
  display: flex;
}

.flex-row {
  flex-direction: row;
}

tailwind-ppx will provide validation for your desired class names. See these examples:

// Example 1
<Component className=[%tw "flex flex-row"] /> // This is ok!

// Example 2
<Component className=[%tw "flex flex-ro"] /> // ERROR: Class name not found: flex-ro

// Example 3
<Component className=[%tw "flex flex-row flex"] /> // ERROR: Duplicate class name: flex

Note that this PPX requires your generated tailwind.css file to exist somewhere in the project hierarchy. Though not required, it's recommended that you configure the path to your tailwind.css file (relative to your project root).

Moving or changing your tailwind.css file

If your tailwind.css file changes (or you move it) you'll need to rebuild your project - for example, bsb -clean-world and bsb -make-world if in BuckleScript. At this time, tailwind-ppx does not automatically watch for changes, though this is on the roadmap.

Alternatively, you can add the following rules to you bsconfig.json to re-trigger builds

{
  "sources": [
    {
      "dir": "src",
      "subdirs": true,
      "generators": [
        {
          "name": "gen-tailwind",
          "edge": ["tailwind.css", ":", "styles.css"]
        }
      ]
    }
  ],
  "generators": [
    {
      "name": "gen-tailwind",
      "command": "tailwindcss build $in -o $out"
    }
  ]
}

You might have to specify the path to tailwind.css

{
  "ppx-flags": [
    ["@dylanirlbeck/tailwind-ppx/tailwind-ppx", "-path ./src/tailwind.css"]
  ]
}

Features

Current

  • Invalid class names
  • Duplicate class names
  • Always in-sync with your tailwind.css file (just make sure to re-build!)

Upcoming

  • Redundant class names (like having both flex-row and flex-col)
  • Support for expressions inside the PPX (like [%tw Cn.make(...)]) to allow variables and function calls
  • Windows deployment
  • Suggestions for invalid class names (i.e. 'Did you mean X?')

Have feature requests? Feel free to open an issue!

Configuration

-path

By default, tailwind-ppx looks for your tailwind.css file in the root directory. If tailwind.css lives elsewhere (or the name of your generated CSS file is different), you'll need to specify the file path in your bsconfig.json.

"ppx-flags": [
  ["@dylanirlbeck/tailwind-ppx", "-path ../path/to/tailwind.css",]
],

Developing

Relevant commands

  • esy build -> Builds the project
  • esy watch -> Watches for changes to Reason/OCaml files in the entire project, including in the /test directory
  • esy test_native -> Runs the native tests (in test/native)
  • esy test_bs -> Runs the BuckleScript tests (in test/bucklescript)

Releasing

  1. Bump the version of the ppx in esy.json on master (we use semantic versioning)
  2. Create and push a new tag
$ git checkout master
$ git tag vx.y.z
$ git push origin vx.y.z
  1. Create detailed release notes for the new version, following the Added/Changed/Fixed/Removed format. Note that the new version of the PPX will automatically be pushed to NPM and a release will be created on GitHub.

Background/Sources