solidjs / solid

A declarative, efficient, and flexible JavaScript library for building user interfaces.
https://solidjs.com
MIT License
32.13k stars 915 forks source link

use:directive doesn't work in HTML literal templates #1666

Closed chvelkov closed 1 year ago

chvelkov commented 1 year ago

Describe the bug

When use:funcName is used in HTML templates, it sets an HTML attribute with that name, instead of calling funcName. Check the demo to see this in action.

Your Example Website or App

https://playground.solidjs.com/anonymous/423708dc-5d7c-4539-b110-4933ce95e4f0

Steps to Reproduce the Bug or Issue

Run the demo. Inspect the generated HTML in the dev console - funcName is set as attribute in CompHTML

Expected behavior

use:directive should have the same behavior as in JSX templates

Screenshots or Videos

No response

Platform

Additional context

No response

ryansolid commented 1 year ago

In JSX use the key to turn it into an in-scope variable. In tagged template literals the compiled scope doesn't have access outside of the interpolated expressions ${}. I had concluded directives wouldn't work here and it is better to just use them as refs.

I suppose we could consider if the following is fine. This would require some more parser code to get this pattern to match.

html`<div use:${directive}=${() => "text"} />` 

But where we are right now it is a yet to be implemented feature.

chvelkov commented 1 year ago

I think the example you gave is fine, although not having use in template literals is not that big of a deal, as long as there's an alternative. When you say "use them as refs", I guess you mean something like this, right?

html`<div ref=${(e) => directive(e, "text")}/>`
ryansolid commented 1 year ago

Yes exactly. I think you need to wrap the argument in a function to match the API but yeah.

html`<div ref=${(e) => directive(e, () => "text")}/>`