Skip to content

hook for initializing external widgets #61

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
paulovieira opened this issue Nov 30, 2016 · 8 comments
Closed

hook for initializing external widgets #61

paulovieira opened this issue Nov 30, 2016 · 8 comments

Comments

@paulovieira
Copy link

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?

@Rich-Harris
Copy link
Member

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.

@emirotin
Copy link

emirotin commented Dec 2, 2016

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

@Rich-Harris
Copy link
Member

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.

@TehShrike
Copy link
Member

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.

@Rich-Harris
Copy link
Member

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!)

@TehShrike
Copy link
Member

That would be awesome. 👍

@TehShrike
Copy link
Member

Should this issue be re-opened, or should there be a fresh issue for the "decorators" concept?

@TehShrike
Copy link
Member

The fresh issue is here fyi #469

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

4 participants