lumeland / lume

🔥 Static site generator for Deno 🦕
https://lume.land
MIT License
1.88k stars 86 forks source link

tailwindcss arbitrary variants are broken #498

Closed hesxenon closed 7 months ago

hesxenon commented 1 year ago

Version

1.19.1

Platform

linux

What steps will reproduce the bug?

Setup a new lume project with jsx + tailwind, then create jsx layout that makes use of arbitrary variants like [&:not(:focus)].

How often does it reproduce? Is there a required condition?

every time, it's not a heisenbug :)

What is the expected behavior?

Arbitrary variants should work

What do you see instead?

Arbitrary variants don't work

Additional information

I've traced this bug a bit and the reason is that when the tailwind plugin processes the page.content the string is already html escaped ([&:not(:focus)]) and thus the needed classes won't be generated.

While I can work around this by registering a processor before the tailwind plugin and just "un-escape" the content string it feels very brittle and hacky.

I'm not sure what the appropriate solution would be here but I think it would make more sense to only escape the generated HTML before saving instead of adapting the tailwind plugin for this use case as this would prevent further bugs like this for other future plugins.

oscarotero commented 1 year ago

Hi. I'm not a Tailwind expert. Do you mean something like this?

export default function () {
  return <div className="[&:not(:focus)]">
    Hello world
  </div>
}

As I can see, the output html code is this:

<!DOCTYPE html>
<div class="[&amp;:not(:focus)]">Hello world</div>

Lume doesn't escape HTML code, maybe it's JSX? I just tried this HTML code in nunjucks and the exported code is the same:

<!DOCTYPE html>
<div class="[&:not(:focus)]">Hello world</div>
hesxenon commented 1 year ago

damn, I wasn't sure who's responsible for escaping the generated html - so it seems the jsx plugin should be investigated? If that's not possible I guess the only fix is for the tailwind plugin to "un-escape" the content before passing it to tailwind, no?

oscarotero commented 1 year ago

I think it is an issue from Tailwind side. JSX does the correct thing, since in HTML the & must be always escaped.

hesxenon commented 1 year ago

well yes and no - on one side it's tailwinds fault for building on a syntax that contains dangerous characters, on the other side this syntax is inside a string where it needn't be escaped.

So no, I don't think that we can just say tailwind has to change their syntax.

hesxenon commented 1 year ago

okay, I tried getting around this by passing extensions: [".html", ".tsx"] to the tailwindcss plugin options, to no avail :/ the respective classes sadly still aren't generated.

oscarotero commented 1 year ago

You can use the following processor, just before tailwindcss to fix the classnames:

site.process([".html"], (page) => {
  page.content = page.content
    .replace(/class="([^"]+)"/, (match) => match.replace("&amp;", "&"));
})
hesxenon commented 1 year ago

yeah, I had that until yesterday when that solution stopped working 😅

maybe because I moved to mdx 🤔

On Fri, Oct 6, 2023, 11:26 Óscar Otero @.***> wrote:

You can use the following processor, just before tailwindcss to fix the classnames:

site.process([".html"], (page) => { page.content = page.content .replace(/class="([^"]+)"/, (match) => match.replace("&", "&"));})

— Reply to this email directly, view it on GitHub https://github.com/lumeland/lume/issues/498#issuecomment-1750274641, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACOHZTVBAUEBOUTOKSK33RDX57FFPAVCNFSM6AAAAAA5TJUV66VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONJQGI3TINRUGE . You are receiving this because you authored the thread.Message ID: @.***>