100phlecs / tailwind_formatter

Sorts tailwind classes within elixir projects
https://hexdocs.pm/tailwind_formatter
MIT License
111 stars 11 forks source link

Support project tailwind.config.js when sorting classes #27

Closed Neophen closed 12 months ago

Neophen commented 1 year ago

Hey, the prettier plugin takes into the consideration the current tailwind config applied and applies the sorting accordingly. At the moment tailwind formatter only takes into consideration the default config.

this means, that if you have a boxShadow: {shadow-1: ... } defined in your config, the formatter puts it in the front of the class list, rather than the location of boxShadows.

Is there possibility to support custom config?

100phlecs commented 1 year ago

Is there possibility to support custom config?

There is possibility. But it adds an order of complexity.

Naive Approach

A naive approach would be a computationally expensive algorithm, where -- if there is a mismatch in the map -- one then goes through all of the keys and see if there is a string substring match.

I.E.

sort_map = File.read!("priv/classes.txt") |> String.split("\n") |> Enum.with_index()

"shadow-1"
|> String.split("-", parts: 2)
|> then(fn [category] ->
  # Handle nil, pass position value to sorter if match
  Enum.find(sort_map, fn {default_class, position} ->
    String.contains?(default_class, category)
  end)
end)

The difficulty lies in how, with the above approach, there are variances to what a "category" of class looks like:

In addition, we would have no insight on whether a class exists or not. It may look like a tailwind class, but it isn't, or it doesn't even exist, yet it would be sorted as if it did exist. The current formatter works because all non-default classes are assumed to not exist, following the rule that all user-defined/unknown classes are sorted to the front.

Comprehensive, a tad over-engineered

Instead of playing a guessing game, one could instead derive the entire custom class list. And the only way to do that, would be to dynamically derive the tailwind sort positions from the library itself. [^1]

Thus, it would require creating a new repository that packages another array of binaries which can execute the JS required to derive the sort order. Call it tailwind_sort or something like that.

Then this library would run the above executable, dump the results to priv/ or somewhere accessible, and then use your custom classes in the sorting.

This approach is heavy handed, seeing as it would include another binary in the _build directory. I guess there could be an option to disable it.

Adding a watch-file to the tailwind.config.js would be a little much. I foresee a mix task mix twfmt.build that would have to be ran every-time the config is updated.

Conclusion

So yes, it is possible, it would just take some time to get it functioning. I don't know when I would work on it, but when I have some free time.

[^1]: That's what I did in order to find all of the default classes/variants for this library

100phlecs commented 1 year ago

I don't know when I would work on it, but when I have some free time.

I do not plan to work on this anytime soon. PRs welcomed.

BTW, it does not have to be binaries. Could be a build.js script added to the watchers: of a phoenix project, esbuild plugin as example