compiler icon indicating copy to clipboard operation
compiler copied to clipboard

class and class:list conflict

Open FrancoJavierGadea opened this issue 1 year ago • 4 comments

Astro Info

Astro                    v4.5.16
Node                     v20.11.0
System                   Windows (x64)
Package Manager          npm
Output                   static
Adapter                  none
Integrations             @astrojs/react

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

Attribute class with template string not work with class:list directive

---
const name = 'work'
const classString = `container ${name}`
---

<!-- Work -->
<div class={`container ${name}`} />

<!-- Not work -->
<div class={`container ${name}`} class:list={{'active': true}} />

<div class={classString} class:list={{'active': true}} />

<div class={"container"} class:list={{'active': true}} />

<!-- Very bad -->
<!-- <div class={'container'} class:list={{'active': true}} /> -->

render

<div class="container work"></div>

<div class="`container ${name}` active"></div>

<div class="classString active"></div>

<div class="&quot;container&quot; active"></div>

What's the expected result?

---
const name = 'work'
const classString = `container ${name}`
---

<div class={`container ${name}`} class:list={{'active': true}} />

render

<div class="container work active"  />

Link to Minimal Reproducible Example

https://stackblitz.com/edit/withastro-astro-6vn7fi?file=src%2Fpages%2Findex.astro

Participation

  • [ ] I am willing to submit a pull request for this issue.

FrancoJavierGadea avatar Apr 07 '24 22:04 FrancoJavierGadea

I don't know if this is actually a bug or not, but you can pass name to class:list instead, and it will work

ematipico avatar Apr 08 '24 10:04 ematipico

You can use https://live-astro-compiler.vercel.app to inspect how Astro compiles the code, and I think it revealed some issues here. It seems like the compiler is not correctly constructing the array passed to $addAttribute class:list.

bluwy avatar Apr 08 '24 15:04 bluwy

I try the compiler and yep

---
const name = 'work'
---

<!-- Work fine -->
<div class={`container ${work}`}></div>

<div class="container" class:list={}></div>

<div class='container' class:list={}></div>

<!-- Not work -->
<div class={`container ${work}`} class:list={}></div>

<div class={name} class:list={}></div>

<div class={"container " + name} class:list={}></div>

<div class={"container"} class:list={}></div>


<!-- Crash -->
<div class={'container'} class:list={}></div>

<div class={'container ' + name} class:list={}></div>

Output


//Work Fine
`
<div${$$addAttribute(`container ${work}`, "class")}></div>

<div${$$addAttribute(['container', ], "class:list")}></div>

<div${$$addAttribute(['container', ], "class:list")}></div>
`

//Not Work
`
<div${$$addAttribute(['`container ${work}`', ], "class:list")}></div>

<div${$$addAttribute(['name', ], "class:list")}></div>

<div${$$addAttribute(['"container " + name', ], "class:list")}></div>

<div${$$addAttribute(['"container"', ], "class:list")}></div>
`

//Crash 
`
<div${$$addAttribute([''container'', ], "class:list")}></div>

<div${$$addAttribute([''container ' + name', ], "class:list")}></div>
`

show

FrancoJavierGadea avatar Apr 08 '24 20:04 FrancoJavierGadea

If someone wants work on this, I believe the issue is happening here https://github.com/withastro/compiler/blob/main/internal/transform/transform.go#L618

The quotes should be set according to the class attribute's type, for example it should be template literals (`) for elements which class attribute is a template literal one (attr.Type == TemplateLiteralAttribute)

MoustaphaDev avatar Apr 10 '24 22:04 MoustaphaDev