zachdaniel

zachdaniel

Creator of Ash

Tails - Tailwind & Tailwind Component Utilities

Making components take tailwind classes is a dicey proposition at best. You can’t just put a set of tailwind classes after another set and expect them to do the right thing, because later classes in the class string don’t override earlier ones, its all based on how “specific” the CSS that class applies. In looking for an example, I found a similar package for js that illustrates the need for it: https://www.npmjs.com/package/tailwind-merge.

I’m (slowly) building a set of utilities to help make more “tailwind-y” components, and also to be able to leverage tailwind in other ways. This library isn’t published to hex yet because it will need some more love, specifically it needs a lot more merge logic. It currently only handles some basic things.

Eventually, I could also see it supporting other kinds of directives to help overriding what a component does. For example, if a component sets something like bg-blue-500 hover:bg-blue-600, but you want it to use bg-red-500 always we could support something like <Component class="all_directives:bg-red-500" />. Or if you wanted to remove a class that the component adds, you could do so with <Component class="remove_class:bg-blue-500" />.

The ideas above are dubious, not sure if they are a good idea, but the point is that the potential for them is there :slight_smile: The part I am sure of is that having a class merger will allow us to write better components that can take tailwind classes and use them as overrides for their own classes.

It also handles merging a list, as well as conditional classes and nested lists, so in the end you might have something like this:

class={classes([
  "inline-flex items-center justify-center gap-2 text-sm font-medium font-sans transition-colors duration-300 disabled:cursor-not-allowed flex-grow-0",
  handle_button_hierarchy(@hierarchy), 
  handle_button_size(@size, @show_label),
  [
    "flex-row-reverse": slot_position == "trailing",
    "w-full": @expanded
  ],
  @class
])}

The other thing it currently does is defines functions that map to your tailwind colors, if configured with a tailwind.colors.json file to use. For those trying out LiveViewNative, this means you can reuse any custom tailwind colors, i.e <text color={primary_light_600()}>{@text}</text>. We could perhaps find other ways to make tailwind the “source of truth” that can be shared between web and LiveViewNative?

Curious to hear your thoughts! If we can get a few more people interested to help build out the class merging rules, and especially if we can make it more integrated with the tailwind config, that kind of thing.

https://github.com/zachdaniel/tails

Most Liked

trisolaran

trisolaran

Sounds definitely like something that could be useful. By the way, some of your ideas reminded me of this library: GitHub - cblavier/phx_component_helpers: Extensible Phoenix liveview components, without boilerplate · GitHub
which comes with utilities to manipulate CSS classes. Don’t know how similar they are to what you have in mind.

zachdaniel

zachdaniel

Creator of Ash

That does look very similar! My only qualm that I can see is that its just doing “prefix replacements”, which won’t work for things like block and hidden, and other tailwind specific things. But I do wonder if perhaps tails should just live inside of a tool like that :slight_smile: So they could say extend_class(..., tailwind: true)?

Where Next?

Popular in Announcing Top

sasajuric
I’d like to announce a small library called boundaries. This is an experimental project which explores the idea of enforcing boundaries ...
New
tfwright
After working on it for a couple of months and using it in production for most of that time, today I’ve released LiveAdmin, a LiveView ba...
New
alisinabh
Hey everyone i’ve developed a library for Jalaali calendar for elixir which supports converting Gregorian dates to Jalaali and vice vers...
New
bluzky
You may know https://ui.shadcn.com/, a UI component library for React. I really love it’s design style and components. I’ve built some co...
384 13736 119
New
kip
ex_cldr provides localisation and internationalisation support based upon the data from the Unicode CLDR project. Unicode released CLDR ...
407 12840 120
New
tmbb
I’ve been working on two packages (not on hex.pm yet) to build admin interfaces for phoenix apps: bureaucrat - which contains a bunch ...
New
Crowdhailer
Raxx is an alternative to Plug and is inspired by projects such as Rack(Ruby) and Ring(Clojure). 1.0-rc.1 is now available. To use it re...
New
mindok
What is ContEx? A pure Elixir server-side data plotting/charting library outputting SVG. It has nice barcharts in particular and works g...
New
achempion
Hi, I would like to tell about my initiative to further maintain and develop Waffle project which is the fork of Arc library. The progre...
New
trisolaran
Hi! :waving_hand: I would like to present LiveSelect, a little library that I wrote to easily add a dynamic selection input to your LV f...
198 10858 107
New

Other popular topics Top

albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement