class and class:list conflict
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=""container" 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.
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
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.
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>
`
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)