-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
$ref()
rune for using directives on components
#14831
Comments
Essentially a duplicate of #9299. |
IMO they should all just be props. Look at the improvements to the class attribute for example, it now accepts an object on which you can specify conditions for your classnames. This makes the So I believe the same thing should to be done with the <button
class="card"
style:transform={flipped ? 'rotateY(0)' : ''}
style:--bg-1="palegoldenrod"
style:--bg-2="black"
style:--bg-3="goldenrod"
onclick={() => flipped = !flipped}
> becomes, <button
class="card"
style={{
transform: flipped ? 'rotateY(0)' : "",
"--bg-1": "palegoldenrod",
"--bg-2": "black",
"--bg-3": "goldenrod"
}}
onclick={() => flipped = !flipped}
> the latter will work on both elements and components. I imagine something similar will be done with the other directives |
@levibassey how do you envision the <div use={{
action: () => {}
}} /> feels very clunky. I guess <div transition={fly({ x: -100 })} /> |
Similar, sure. I'm not proposing that a Component with a |
honestly, I don't know, the Rich also said something about it a few months back |
Btw, there is a proposal to make I also think that actions and transitions should be passed in as basically props vs having to rely to
<!--Parent.svelte usage-->
<!--action / transition props could be anything that Child expects-->
<Child
action={{runner: (node, data) => {/*action body*/}, data: {}}}
transition={{animator: fly, options:{ y: 200, duration: 2000 }}} />
<!-- or nothing is passed in to the Child and svelte doesn't apply transitions / actions -->
<Child />
<!--Child.svelte-->
<script>
let { action, in, out, onintrostart, onintroend, onoutrostart, onoutrostart, otherProp } = $props();
</script>
// various example of possible usage:
// use the options for transitions provided by the parent
<div transition:{transition?.animator}={transition?.options} {onintrostart} {onintroend} {onoutrostart} {onoutrostart}>Something</div>
// customized usage to override transition options provided by the parent
<div transition:{transition?.animator}={{...transition?.options, duration: 1000}}>Something</div>
// in / out props
<div in:{in?.animator}={{...in?.options, duration: 500}} out:{out?.animator}={out?.options}>Something</div>
// use of action with parent provided params
<div use:{action?.runner}={action?.data}>Hello there</div>
// use of action with own params:
<div use:{action?.runner}={() => signal}>Hello there</div> |
Simplified and updated the example from yesterday for using transitions and actions as props. Here's the link to the previous comment: #14831 (comment) It would be just like using any regular props and would allow dynamically changing actions with data or transitions with options. Svelte can also easily account if the passed in props are |
Describe the problem
A commonly requested feature (#12229, #2870, #5236) is to have parity between native elements and svelte components for directives such as
class:
,style:
,use:
ortransition:
. This currently errors:Why is this bad? It breaks intuition for new developers who expect components to behave the same as elements. It makes wrapper components inherently more limited than native elements.
Several points of implementation difficulty have been brought up in the past:
Describe the proposed solution
The
$ref
rune would provide a way for components to determine which element receives the directives.Any component that does not explicitly use
$ref()
still throws an error when a directive is used on it.I believe this answers the main issues on this topic.
Right now, if you pass a
class
prop to a component, it uses the scoped css hash from that component (playground).class:
would behave the same way, i.e.<Comp class:foo />
would use the.foo
defined inComp.svelte
.This proposal leaves the choice to the component creator. They could specify which of the root elements receives the directives, or a non-root element, or a child component like this:
In this proposal, it would be impossible. However, here are some alternatives:
Alternatives
This doesn't allow using the bind:this for a local use, though.
Could also be
svelte:ref={ref}
or something.$ref()
s per componentIn this case, the directives would be duplicated and both elements would receive them.
I'm interested in knowing if there's some other barrier that makes this impossible, but I haven't found one while researching this issue!
Importance
would make my life easier
The text was updated successfully, but these errors were encountered: