Skip to content

Forwarding class, style, transition, use (similar to on:eventname) #7244

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mekto opened this issue Feb 10, 2022 · 2 comments
Closed

Forwarding class, style, transition, use (similar to on:eventname) #7244

mekto opened this issue Feb 10, 2022 · 2 comments

Comments

@mekto
Copy link

mekto commented Feb 10, 2022

Describe the problem

If we have a regular DOM element we could write:

<button class="btn" style:color="red" out:fade use:tooltip={'Press me'} on:click={handleClick}>
  Press Me
</button>

But as soon as we move our button into a component (eg. <Button/>) (for extended functionality or just for styling), we loose a lot of Svelte superpowers. So by just replacing <button> with <Button> the Svelte compiler starts complaining:

  • Unused CSS selector ".btn"
  • Style directives cannot be used on components
  • Transitions can only be applied to DOM elements, not components
  • Actions can only be applied to DOM elements, not components

Only on:click can be used this way. What if we could forward other props as well?

Describe the proposed solution

// Button.svelte

<button class style transition use on:click>
  <slot>
</button>

Just taking the same approach as forwarding DOM events - directive without a value. Should be explicitly provided. In most cases it would be a root element of a component.

Alternatives considered

In most cases I just avoid wrapping DOM elements in components to not meet these limitations. But it often requires coping of styles and logic.

Exporting className and using :global(.btn) is another workaround, but not clean and obious.

For transitions and actions we could wrap with it another element.

I think forwarding 'class' directive would be most helpful from all the above, especially for UI library authors.

Importance

would make my life easier

@Conduitry
Copy link
Member

This would as written be a breaking change. class/style/transition/use/etc. as a bare attribute name already has a meaning: the attribute with no value.

You can solve part of this with <div {foo}>, which is shorthand for <div foo={foo}>, if foo is a prop in this component. Everything else is just syntactical sugar on top of sending a prop and then using that prop with the appropriate directive inside the component.

I don't think we want to expand the API for every single compiled component so that it can be passed any directive (including letting new values be passed in for any of those directives). I also don't think we want to worry about what happens when a directive is passed in that the child component is not set up to accept.

The "unused selector .btn" warning wouldn't be resolved with this sort of a feature, anyway. <Component class="btn"> doesn't mean an element with the btn class that would get matched against a certain selector - it just means a prop whose name happens to be class. The language shouldn't make any assumptions about what is meant by certain prop names just because they happen to match various attribute names. A parent component also can't selectively handle the class prop it's sending to a child component (i.e., selectively scoping it) depending on how the child component is using it.

@babichjacob
Copy link
Member

Also see sveltejs/rfcs#60

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants