-
Notifications
You must be signed in to change notification settings - Fork 82
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
Declarative Actions #41
base: master
Are you sure you want to change the base?
Conversation
It seems like this is already possible by wrapping the element with a component and slot props -- maybe use:Component is just syntactical sugar for wrapping an element with a component? |
How would slot props solve the problem? And a component can't really assume its slot only has one child. |
How would they not? What would this make possible that would not otherwise be possible by wrapping an element with a component? I mention slot props because To your point about a slot containing multiple child nodes, perhaps in the context of |
Check out the "More on styling" section of the RFC. How would you do that with a wrapper component and slot props? I have an example with a wrapper Component. Applying styles to the parent is not the same as applying styles to the Element itself. How would you solve the problem I propose there? Could you spin up an example on the REPL? Regarding this:
Then it wouldn't be an action anymore. That is in no way possible with current actions either. If you truly wanted that you could apply the action individually to all the elements you wanted I guess. |
The use of
True. |
Ah, I see. One of my intentions with this RFC was to avoid But apart from styling I still do think Declarative Actions are a generally better way to write Actions. |
I can certainly see the appeal, I was just thinking it might be possible to deliver the reactivity you seek without introducing the |
There might be other ways. Introducing a new Element (or using EDIT: |
One thing that is not clear to me is how well the proposed type of actions will be composable. A big strength of the current actions (and a reason to keep the "old" way in, even if this RFC would be implemented) is that they are just functions and can easily be mixed and matched with other functions or even actions. |
Hi,
If you go with this please do it in addition and not instead the existing API. |
Yes. If you currently For me one open question is if this should have a different extension (e.g. Edit: The big issue with DX/teaching is that from the import statement you cannot distinguish between action and component, but both are used very differently. However, now that I think about it, that's true for literally every Edt2: We can also attach a |
What about actions without a script at all? Declarative actions would allow for actions that only apply styling or that only wrap the |
This could just come down to a naming convention. |
Good point, maybe the existence of I realized that declarative actions would change my mental model for actions.;
Once I had this new mental model three things came to my mind:
Regarding the parameters: I think we stick with the current approach, because declarative actions have the current action spec as compile target (they need to be compiled to something anyway). So the parameters become If the maintainers could signal if this is something they can see happening I'll go ahead an review the whole rfc. I still haven't read it in it's entirety. |
We shall wait. And I don't think I understood this:
What's stopping us from allowing multiple props, like in a Component, and then compiling them into a single function parameter? This could be less intuitive then just forcing actions to have a single prop and letting the user handle that themselves I guess, but it would sure be more ergonomic. |
So what you're suggesting is that actions compiled from declarative action always require the argument to be an object? Because right now I have actions that get a single function as argument. You could always do this if you want to: <script>
export let parameters;
$: {foo, bar} = parameters;
</script> This would be 100% backwards compatible. If you you want this: <script>
export let foo;
export let bar;
</script> Then you need to change actions that currently don't use an object if you want to migrate to declarative actions. But there could also be a magic |
Such a loose thought: Isn't Declarative Actions more of a component + svelte:element + additional goodies?
<!-- action.svelte -->
<script>
</script>
<target on:click={_=>{}} /> <!-- App.svelte -->
<script>
import { action } from './action.svelte';
</script>
<div use:action {...individualPropsdiv> vs
<!-- action.svelte -->
<script>
export tag;
</script>
<svelte:element tag={tag} on:click={_=>{}} {...$$restProps}><slot/></svelte:element> <!-- App.svelte -->
<script>
import { action } from './action.svelte';
</script>
<action tag="div" {...individualProps}></action> What difference? So actually, you need to set
<!-- action.svelte -->
<script>
export tag;
</script>
<svelte:element tag={tag} on:click={_=>{}} {...$$restProps} special-props={$$specialProps}><slot/></svelte:element> <!-- App.svelte -->
<script>
import { action } from './action.svelte';
</script>
<action tag="div" {...individualProps} on:click={_=>} class:name bind:val></action> Attributes Summary: |
Ah... I was completely disregarding actions with a single parameter. I guess we could force having an object as a parameter. Maybe leaving it as it is, is better though. I would personally prefer the "forcing object as parameter" option. This may not be a popular opinion though. |
It seems like this syntax implicates dynamic injection of any directive at runtime. I feel like this will be both confusing and abused. |
UPDATE 2A separate RFCS for this - #68 An alternative syntax that gives more possibilities, using slots, but also less graceful: <!-- App.svelte -->
<script>
import Com from "./Com.svelte";
</script>
<Com>
<svelte:element slot="button" class="class1"></svelte:element>
</Com>
<style>
.class1 {}
</style> <!-- Com.svelte -->
<script>
let target;
</script>
<slot name="button" targeted this="button" bind:this={target} class="class2" on:click={_=>{}}/>
<style>
.class2 {}
</style> Description:
I would very much appreciate your feedback, do you like it? UPDATE 1I noticed one mistake.
Solution
The same example in a new way: <!-- App.svelte -->
<script>
import Com from "./Com.svelte";
</script>
<Com>
<svelte:element slot="button" class="class1"></svelte:element>
</Com>
<style>
.class1 {}
</style> <!-- Com.svelte -->
<script>
let target;
</script>
<slot targeted:button this="button" bind:this={target} class="class2" on:click={_=>{}}/>
<style>
.class2 {}
</style> Where And you can something like this: <svelte:element slot="button" class="class1" let:val>{val}</svelte:element>
...
<slot targeted:button={{ val: "string" }}
this="button" bind:this={target} class="class2" on:click={_=>{}} name="name1"
/> Where the This is a compromise to release the attributes of the slot, and be able to use them as attributes of a dynamic element. DISCLAIMER: If one believes that "slots should be left alone", one could call it different. But it would literally work as upgraded slots. |
A minor note - Using Declarative Actions is a bit like using the This I don't know, maybe this will encourage someone to pursue Declarative Actions. :) |
I don’t know what the is syntax has to do with this proposal, the is=“el” was also abandoned from the web components spec because safari wouldn’t implement it |
@madeleineostoja Topic appears to be unfinished - https://bugs.webkit.org/show_bug.cgi?id=182671#c18 As for the lack of similarity - maybe I have more imagination.... I don't want the topic to be closed by a drawn out side discussion. In a nutshell: Both the Declarative Action and the
A regular Extension, use:DeclarativeAction vs the Wrapper, putting Element in Svelte Component slot(or inside Component) vs putting Element in slot(or inside Custom Element): Summary: |
Not going to get wrapped up in this, just wanted to mention that I was quite involved in spec discussions during the early days of web components, and I can assure you that customised built ins ( I don't understand what you're trying to get across, and there's no need for comments like "maybe I have more imagination" |
I meant that maybe I associate things that don't fit together as I think they do. All in all, I feel bad that almost anything I write is received negatively. |
This is great. If I'm not forgetting anything this would be fantastic. I think I've alluded to a solution like this in a comment to an issue that I'm not finding right now xd. This might even be easier to teach since you could drop the notion of "Declarative Actions" completely. It's just a |
I've been really busy lately. If you want to you'd be welcome to open a pull request for my RFC, introducing this as an alternative. I'd happily review it. @lukaszpolowczyk |
@Prinzhorn redirected me here after I posted a similar issue. A couple thoughts, as I'm getting caught up and have been pondering this more:
<!-- Given a composable named `dropZone` -->
<div with:dropZone />
<div compose:dropZone />
<div also:dropZone /> |
It's funny you mention the material ripple. That was the first time I felt the need for something like Declarative Actions adn then I generalized from there. And I don't think you would need to add an element to implement the material ripple. I think adding elements would make this RFC more convoluted than it needs to be and we would lose the differentiation between vertical and horizontal that @Prinzhorn conjectured in an earlier comment. You're right that using the current action infrastructure maybe wouldn't play nice with SSR. But I don't see why that couldn't be changed. Idk if handling SSR would make it different enough from Imperative Actions to warrant a different notation like There's a new RFC where your input would be greatly appreciated, you seem to have some nice thoughts on the matter. I honestly think it almost supersedes this one, but there's some discussion about it on that RFC. The biggest drawback I see is: With declarative actions you can do: <div use:action1 use:action1 use:action2 use:action3>Hi!</div> With targeted slots this doesn't really work. I do have some thoughts that could make this work with targeted slots but I'll brew them for some more time xD. I'll post them over there when I can formalize my thoughts. EDIT: Ok... I completely overlooked that you (@mimbrown) had already read @lukaszpolowczyk's RFC. I won't change the comment though, just keep in mind I hadn't noticed xD |
@Zizico2 I'm waiting for your solution to this problem, as I myself don't have any good idea about it yet. |
It is interesting we had the same use case in mind! I think there are inevitably going to be use cases where adding child elements through a declarative action will be helpful/necessary, but I agree that it complicates the proposal. I would be in favor of a V1 where children are disallowed and continuing this discussion for future versions.
About SSR, I don't think there's a scenario where the current
Haha np. It goes without saying that I agree with my comments over there :) |
Rendered