crisward / svelte-tag

MIT License
52 stars 8 forks source link

get context of next customElement ancestor #8

Open Vanillabacke opened 2 years ago

Vanillabacke commented 2 years ago

Just wanna share a quick and dirty solution of getting the context kinda working.

Needs a new method in the wrapper class:

getAncestorContext( node = false )  {
    while ( node.parentNode ) {
        if ( node._root?.elem?.$$?.context  ) {
            return node._root?.elem?.$$?.context
        }
        node = node.parentNode
    }
    return false
}

And then adopt the context in the opts.component constructor:

connectedCallback(){
    let props = opts.defaults ? opts.defaults : {};

    // ...

    props.$$slots = createSlots(slots)
    this.elem = new opts.component({
        target: this._root,
        context: this.getAncestorContext(this?._root), // add the context to the component
        props
    });
}

Usage for example with a writable: Parent:

<script>
import { setContext} from 'svelte';
import {writable} from 'svelte/store';

const yourName= writable('default name');
setContext('yourName',yourName);
</script>

<div>{$yourName}<div>

Child:

<script>
import { getContext } from 'svelte';
let yourName= getContext('yourName')

updateName(){
    $yourName = 'your new name';
}
</script>

<div>{$yourName}<div>
<button on:click={updateName}>Update the Name</button>
patricknelson commented 11 months ago

Hi @Vanillabacke! Thanks for making this suggestion.

Just wanted to let you know that context support is now available for custom elements in Svelte! Thanks to svelte-retag starting in version 1.3.0 :slightly_smiling_face: See demo @ https://svelte-retag.vercel.app/ and implemented in https://github.com/patricknelson/svelte-retag/pull/18

IMHO, this is a huge leap toward bridging the gap between legacy apps (like my site which is a PHP based website) and modern JS component-based front-ends by utilizing a hybrid approach with web components. You keep things composable and continue to populate the data into your front-end by taking a tag-based approach like you might already be doing in other server-side languages like PHP, Ruby, Python, Java and etc. It includes support for light DOM as well as support for slots (something Svelte itself notably doesn't yet support!). I'm so pumped about this last feature because we're going to be using it very heavily in the redesign of our homepage, which will be implemented using Svelte, particularly with the carousels we will be building.

Edit: Accidentally included the actual site copy/pasted from my Slack message 😅 Edited that out since it isn't necessary here.

Vanillabacke commented 11 months ago

Hi @patricknelson finally I had some time for testing it. In short I love it! 😅

As far as I've tested it, this gives a huge advantage. Thanks a lot for implementing it! I can see a lot of usecases, especially for small projects, where you just simple reuse alle the stuff easily without heavy scripts ❤️

patricknelson commented 11 months ago

Cool! I'm using it heavily in production myself, so I plan on supporting it long term. If you encounter any issues, you know what to do.