I am looking for a Svelte "Delegating Lazy Loading" component to another "real" component. This component should be transparent to the user who shouldn't know there is this "proxy" :
I don't think it's possible now because no api is exposed for slots forwarding or events forwarding. Maybe a hack by implementing in js the same internal interface has a svelte component ?
Edit
I am looking for this kind of magic method:
I have an Heavy component, which I want to load asynchronously
Heavy.svelte:
<div on:click>
<slot {secret}/>
<slot name="footer"/>
</div>
<script>
let secret = 'huhu';
</script>
I want to be able to export this component like this :
module.js
import { lazy } from './lazy.js'; // magic method
export let Heavy = lazy(async () => (await import('./Heavy.svelte')).default)
a consumer can then use Heavy without knowing it has been wrapped in this "high order" lazy component. this consumer doesn't have to handle/knowing anything about the asynchronous behavior of this wrapper :
Consumer.svelte
<Heavy on:click={() => console.log("clicked")} let:secret>
<div>{secret}</div>
<div slot="footer">Footer</div>
</Heavy>
<script>
import { Heavy } from './module.js';
</script>
I have a "working" solution, which doesn't support "let", doesn't support named slots, and doesn't support events..
The best I can do. bind:* doesn't work, slots and events seem to work.
Wrapper.svelte
<svelte:component this={cpn} {...slotsProps} {...$$restProps} bind:this={instance}/>
<script>
import { get_current_component } from 'svelte/internal';
export let provider;
const slotsProps = {"$$slots":$$props.$$slots, "$$scope":$$props.$$scope};
const self = get_current_component();
let cpn;
let instance;
provider().then(result => cpn = result);
$: if (instance) {
for (let [type, listeners] of Object.entries(self.$$.callbacks)) {
instance.$on(type, (e) => {
listeners.forEach(l => l(e));
});
}
}
</script>
lazy.js
import Wrapper from './Wrapper.svelte';
export function lazy(provider) {
return function(opts) {
opts.props = {...opts.props, provider };
return new Wrapper(opts)
}
}
module.js (usecase example)
import { lazy } from './lazy.js';
export let Heavy = lazy(async () => (await import("./Heavy.svelte")).Heavy);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With