Noriller / easy-tailwind

An easier way of writing Tailwind classes.
https://www.npmjs.com/package/easy-tailwind
MIT License
173 stars 2 forks source link

Any ways to combine `e()` with `cn()` or`clsx()` ? #4

Open hoangnhan2ka3 opened 5 days ago

hoangnhan2ka3 commented 5 days ago

First, thanks for creating this plugin! It's nearly 90% perfect for me. ✨

Why 90%:

className={cn(
    fonts.Gilroy_Sans.variable,
    fonts.Sf_Mono.variable,
    "relative h-fit !scroll-smooth bg-mega-background",
    e({
        all: "focus:outline-none",
        selection: "bg-zinc-400/40 text-mega-secondary text-shadow-none"
    })
)}

I use cn() because although the results of fonts.Gilroy_Sans.variable and fonts.Sf_Mono.variable are "string" (see below), but in the TW transform time, it's a variable, so e() will be failed when parsing the object with those two (I mean just the object's styles was not created, the string and fonts are ok), when delete 2 font variables, it works like normal.

Infact, this is enough for me, but I want to try to ask if we can do something like:

import * as fonts from "@/app/fonts"

import { clsx as cn } from "clsx"
import { e } from "easy-tailwind"

function etwind(...args) {
    const cnArgs = []
    const eArgs = []

    args.forEach(arg => {
        if (typeof arg !== "string") {
            eArgs.push(arg)
        } else {
            cnArgs.push(arg)
        }
    })

    return cn(...cnArgs, e(...eArgs))
}

// then the biggest problem of this plugin may be solved
<html className={etwind(
    fonts.Gilroy_Sans.variable, // this go to cn()
    fonts.Sf_Mono.variable, // this go to cn()
    "relative h-fit !scroll-smooth bg-mega-background", // this go to cn()
    { // but this go to e()
        all: "opacity-50",
        selection: "bg-zinc-400/40 text-mega-secondary text-shadow-none"
    }
)}>
</html>

But, what e() scanned is ...eArgs; yes, actually the string ..eArgs, not the object. Although the result when I inspect <html /> seems right, no loss classes:

class="gilroy_sans_2a70e61c-module__96ixaa__variable sf_mono_e07e9971-module__91Mg3a__variable relative h-fit !scroll-smooth bg-mega-background all:opacity-50 selection:bg-zinc-400/40 selection:text-mega-secondary selection:text-shadow-none"

Of course the style from the object, which is all:* and selection:* are not applied

I'm using Nextjs 15 with --turbo, not Webpack but I think that's not the problem. Do you have any ideas or some possible thoughts? @Noriller

Noriller commented 2 days ago

Hi, I tried playing around with some ideas I had some experience with. In some limited capacity I might make it work, but even then, it might end breaking hard on unexpected inputs.

Unfortunately a proper solution would be an AST traversing.

EDIT: this won't help much in this case, but you can use: https://github.com/Noriller/easy-tailwind?tab=readme-ov-file#renaming-the-exports

To make it accept other function names.

hoangnhan2ka3 commented 2 days ago

The most annoying thing that TW content.transform need a "signal", like /e\(./, like u say above if I add etwind to the customNameReplacer(), then it will scan also fonts.Gilroy_Sans.variable, which is a variable, then the object won't works.

I've tried edit the regex to only match object in the nameReplacer like /etwind\(.?\{./gis, but it never work :D.

Anyways, if there are some workaround for this, it will increase the tailwind's DX to be better. Thank you for your reply 💕

Noriller commented 2 days ago

If you're good enough with Regex, then there would be ways around it... even if it were like saying to start at a comment like /*e*/

Improving that is something on my list, unfortunately, I seem to never find the time to do it.