How can an external widget (say, Kendo UI grid, which is jquery based) be used with svelte? It probably needs an hook to be executed right after renderMainFragment, or can it be done currently with user code?
I suspect the best approach for this would be something akin to Ractive's decorators, which are essentially element-level lifecycle hooks. It would look something like this:
<div as:kendogrid='{foo:bar}'></div>
<script>
import kendogrid from 'svelte-decorator-kendogrid';
export default {
decorators: {
kendogrid
}
};
</script>
In Ractive, a decorator is a function that is called with a node (the <div> in this case, and returns an object with a teardown method (for when the element is removed) and an optional update method, which is called when the value of the argument ({foo:bar}) changes. I think we'd want to do something very similar.
You can also wrap it into a very thin Svelte component using the lifecycle hooks, right? It should only read the config, initialize the 3rd party widget on its own node, and later destroy it
Yep, on reflection I think I'll close this issue since components already allow you do everything you would use a decorator for, and they're cheap to create. We can revisit the decorator idea in future if it turns out there's a need for them that isn't met by components.
What should I do in the cases where I want to add behavior to an element, without prescribing anything else about the element?
I have two use cases in mind that I've run into with Ractive:
I can abuse custom events in Svelte to accomplish something similar, as per this example.
That may not be the most convincing example, since it's so close to just being appropriate to solve with straight events, but it is simple enough to serve as an example of how close Svelte's custom events are to what I want from decorators.
Both of those Ractive decorators would be inappropriate as components in my opinion. I don't want to add another layer of <ResponsiveImage> elements around the <img> itself, and I want the developer to be able to specify any other attributes on the <img> - all I care about is adding some specific behavior.
Is the "correct" thing to do to split apart the triggers into custom events, and the behaviors into custom methods? For the simple select-on-focus case that would look like this.
That's honestly pretty good, if so - but I would like to reduce the composition boilerplate.
What do you think about having a behavior/decorator that desugars to an event/method combination?
That is, have this:
<img decorate:lazyloadImg="'bigimage.jpg', 200" class="cool" src="placeholder.png">
<script>
import { changeSrc, nearViewport } from 'svelte-lazyload-img'
export default {
decorators: {
lazyloadImg: {
event: nearViewport,
method: changeSrc
}
}
}
</script>
be treated as equivalent to
<img on:nearViewport="changeSrc(this, event, 'bigimage.jpg', 200)" class="cool" src="placeholder.png">
<script>
import { changeSrc, nearViewport } from 'svelte-lazyload-img'
export default {
methods: {
changeSrc
},
events: {
nearViewport
}
}
</script>
The benefits are less thinking/work where you want to apply this behavior - all I have to do is
export default {
decorators: {
lazyload: require('svelte-lazyload-img')
}
}
Sorry for getting a bit rambly here, this post is half me thinking it through myself.
In conclusion: I believe combining events + methods gets the job done for me in all the cases I can think of, but I think it should require less boilerplate in the template and component where it is used.
Thanks for Svelte! It's really awesome.
One trick Svelte has that Ractive doesn't have is the ability to interact with the node inside event handlers, meaning that you can select an input on focus:
<input on:focus='this.select()'>
But yeah, lazy-loading images is a good use case for decorators. I actually think we could use the same approach Ractive uses, if we were to implement decorators, since updates aren't necessarily tied to events. (In fact Ractive decorator plugins might even work with Svelte components!)
That would be awesome. 馃憤
Should this issue be re-opened, or should there be a fresh issue for the "decorators" concept?
The fresh issue is here fyi https://github.com/sveltejs/svelte/issues/469
Most helpful comment
You can also wrap it into a very thin Svelte component using the lifecycle hooks, right? It should only read the config, initialize the 3rd party widget on its own node, and later destroy it