Sebb

Sebb

Can we solve the tailwind-interpolation-problem with a macro?

tailwind will go through your files and find classes using a RE.
So you can’t interpolate tailwind classes.

<div class={"w-#{@foo}"}> <!-- DOES NOT WORK -->

You have to

<div class={[
  @foo==1 && "w-1",
  @foo==2 && "w-2",
  ...
  @foo==96 && "w-96"]}>

(or use @style)

How about a heex macro tailwind (and an accompanying attr type which gives all possible values)

attr :foo, :tailwind, range: [1, 2, 3, 4, 10, 24, 96]
...
<div class={[tailwind("w-#{@foo}"), "other classes ..."]}>

or maybe sth like this using a sigil

<div class={[~t"w-#{@foo}", "other classes ..."]}>

all tailwind macros could compile to an extra file (which is listed in tailwind.config to get parsed by the tailwind preprocessor)

# tailwind.lst
w-1, w-2, w-3, w-4, w-10, w-24, w-96 

Most Liked

zachdaniel

zachdaniel

Creator of Ash

I think my tails library could be a good place to put this solution: Tails - Tailwind & Tailwind Component Utilities

We can make classes into a macro instead of a function, and support something like this:

classes(["foo-#{x}", ...], x: [1, 2, 3, 4, 10, 24, 96])

Then it would yell if you interpolate a variable in your classes but don’t provide a list of possible values. Then it would write the file that you’ve mentioned.

zachdaniel

zachdaniel

Creator of Ash

Yep! We shouldn’t scan source code, we should provide a macro or sigil that does the validation. The tails library solves for class merging and conditional classes. Class merging is necessary for allowing components to have their classes overridden by parents passing down classes(my preferred way of overriding components) and tails will do a semantic merge based on what classes “conflict” in tailwind.

I’m already working on a macro version of classes as well as a sigil. The macro version will, for now, warn on interpolation unless possible values for the interpolated expression is provided.

D4no0

D4no0

Oh my god, just banged my head for a few hours to understand that this is happening.

The thing is that this is not only not consistent, if you use same classes elsewhere, it will work (this also includes cached builds), but it also doesn’t show any kind of errors or warnings.

Actually as it currently stands, it seems that the limitation is that the string should be known at compile-time, things such as this work:

<div class={[@badge_type]}>
</div>
badge_type = get_badge(type)
assign(socket, badge_type: badge_type)
defp badge_type (type) do
    case type do
      :success -> "badge-success"
      :warning -> "badge-warning"
      :error -> "badge-error"
      :inactive -> "badge-ghost"
      :not_found -> "badge-info"
    end
  end

I have both the cases where a separate .heex file is used and when render/1 from an .ex file is used, and both seem to be working when the strings are known at compile-time. Looking at this now, it seems that the configuration watches in .ex files too:

content = [
  ...
  "../lib/*_web/**/*.*ex"
]

Have you found any solutions so somebody else would not stumble onto this bug?

Where Next?

Popular in Discussions Top

Other popular topics Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 41454 115
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30840 112
New
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
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New

We're in Beta

About us Mission Statement