Enforce a class
attribute order within markup using TailwindCSS.
this is a mix format
plugin.
Note: The Tailwind Formatter requires Elixir v1.13.4 or later
Add tailwind_formatter
to your list of dependencies in mix.exs
:
def deps do
[
{:tailwind_formatter, "~> 0.3.0"}
# alternatively, keep track with the latest release:
{:tailwind_formatter, github: "100phlecs/tailwind_formatter"}
]
end
Add it as a plugin to your project's .formatter.exs
.
Make sure to put in the heex
extension to the possible inputs.
[
plugins: [TailwindFormatter],
inputs: [
"*.{heex,ex,exs}",
"{config,lib,test}/**/*.{heex,ex,exs}"
],
]
Then run mix deps.get
and also mix compile
to load in the plugin.
After that, run the formatter with mix format
.
Note: If you're using multiple formatters and you're running an Elixir
version that supports multiple format plugins, keep in mind that the
order by which the plugins are defined in the plugins: []
array are
the order in which they are ran.
If you plan to use this with another formatter, you may run into issues.
Thie is because mix format
, depending on your version, may not support multiple
plugins (just yet)!
There are two options to work around this. The first option is, if you
are formatting with Phoenix.LiveView.HTMLFormatter
, to use the
MultiFormatter
shipped with this library instead of
TailwindFormatter
.
The MultiFormatter
will first format with HTMLFormatter
and then
follow up with TailwindFormatter
.
The other option is to set up two .formatter.exs
files and a script
within your base directory, i.e. format.sh
which runs both.
In format.sh
:
#!/usr/bin/env bash
mix format --dot-formatter .tailwind_formatter.exs
mix format # this runs the default .formatter.exs
And then chmod +x format.sh
.
The formatter aims to follow a bundle of rules outlined in the blog post that introduces the official Tailwind sorter plugin.
- Order them the same way classes are imported in the CSS file. Base, Components, Utilities.
- Classes that override other classes appear later in the list
- Classes that impact layout take precedence over classes that decorate
- Plain classes come first before variants (i.e.
focus:
) - Unknown classes are sorted to the front
There are some differences in order to simplify the algorithm and to support Elixir use cases.
With elixir templating one may add an #{inline_elixir_function}
to the class list.
The formatter supports this and sorts these toward the front.
i.e. sm:unknown-class
will still be grouped with the other sm:
variants, even if Tailwind doesn't recognize the class.
In the original spec, 'variants' i.e. sm:hover:
are sorted as though it is one block.
Thus, the order in which they're specified does not matter.
So, for example, a chain of dark:sm:hover:text-gray-600
would be placed toward the end.
In this algorithm, classes are sorted by "layers".
All sm:
variants are grouped together, even if it's a chain of 4 variants.
So for example, dark:sm:hover:text-gray-600
will be placed before any sm:
and hover:
variants, because dark:
has precedence over sm:
and hover:
.
Thus in order to achieve more consistency, the variant chain is ordered.
So, dark:sm:hover:text-gray-600
transforms to sm:dark:hover:text-gray-600
.
As a bonus this plugin supports the Phoenix variants that ship with new applications.
Otherwise custom classes are not supported at this time. It may be supported in the future.
As this is quite new there may be some Tailwind classes missing.
This project builds heavily off of rustywind and HTMLFormatter.