TailwindFormatter - Opinionated tailwind class sorter for HEEx templates

Here’s the repo link: GitHub - 100phlecs/tailwind_formatter: Formats tailwind classes within elixir projects

The idea is to have a consistent ordering of tailwind classes so it is easier to read through.
The solution uses Regex which, at times, feels a little brittle, but so far works in most cases.

It bails if it doesn’t have a clean selection to work with, so if you end up using it you may find sometimes the classes won’t sort. This usually happens due to too many inline elixir functions which I’ve yet to investigate.

Still, it’s ‘alpha’ at the moment, i.e. if there are a lot of inline elixir functions it may not sort.
Been using it in my private repositories without much issue though!

This is my first elixir library package, so feel free to critique/send PRs.
Still rather new to elixir :slight_smile:

If you’re curious on how I gathered all of the classes and variants, I pulled them out of the official tailwindcss library, with plugins attached. Here is the unorganized repo where I generate them: tailwindsort/index.js at d823656f1ffe26519f21fe4e458de482534121ee · 100phlecs/tailwindsort · GitHub

Hope you find it useful!

23 Likes

Nice work.


For guys don’t like extra deps, and want to sort classes and group classes manually, you can do something like this:

<body class={[
  "h-screen overflow-hidden",
  "bg-gray-300",
  "select-none"
]}>
  <%= @inner_content %>
</body>

A: Why do you group classes?
B: Because I want to seperate the concerns, like:

  1. Positioning
  2. Box model
  3. Typographic
  4. Visual
  5. Misc

This idea comes from Code Guide by @mdo.

7 Likes

New release!

TailwindFormatter now includes TailwindFormatter.MultiFormatter as a .formatter.exs plugin option, which will format your heex templates with Phoenix.Liveview.HTMLFormatter first, then with TailwindFormatter. This makes it so you no longer have to deal with scripts in order to use TailwindFormatter on a Phoenix project.

Also includes a bug fix on preserving original class order for user-defined classes.
Thanks to zachallaun the README is cleaned up!

Thank you to those who suggested these changes :slight_smile:

8 Likes

This separation of concerns could be a possible formatting option.

The main barrier would be labeling all the tailwind classes with each group. Another issue would be user-defined classes, they would probably just be filed under “Misc”

3 Likes

Awesome, than you :partying_face:

1 Like

New release.

  • Fixed a bug where class lists that had . or # in them were not sorted
  • Allow dynamic classes, i.e. grid-cols-#{@cols}, previously they were broken up
  • Validate any inline elixir with Code.string_to_quoted, raises an error otherwise

I’m using a new sort method by first “placeholding” any elixir functions with $#{num}, sorting, and then putting them back in. This makes the Regex easier, and also makes it easy to support dynamic classes.

Thank you to those who brought these issues up :slight_smile:

5 Likes

New release, thanks to those who raised issues & contributed!

Shoutout to @aptinio for ironing out the expression sorting, sorting multiple :class attributes & handling leading-trailing spacing issues between string fragments. :slightly_smiling_face:

I’ve added some highlights in the changelog.

A quick summary is that most if not all of the code fragments within a class={} are supported and sorted.

You can also now load in your custom TailwindCSS configuration instead of using the default ones I’ve generated awhile back.

Note: This release requires Elixir v1.15+. We’ve dropped MultiFormatter as Elixir v.1.15+ now supports multiple formatters.

10 Likes