Last active
July 24, 2023 17:39
-
-
Save TehShrike/aea6bed1cd48c0780f5fba01d67e19b2 to your computer and use it in GitHub Desktop.
Svelte custom element wrapper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import DateRangeInput from "@equipmentshare/date-range-input" | |
import makeCeFromSvelte from "common/svelte-ce" | |
export default makeCeFromSvelte(DateRangeInput, { | |
mirrorProps: [ "start", "end", "visibleStartMonth", "visibleEndMonth" ], | |
requiredToInstantiate: [ "start", "end" ], | |
mirrorEvents: [ "change" ], | |
// Shouldn't be necessary now that https://github.com/sveltejs/svelte/issues/3940 is fixed | |
initialHtml: "<style>@import './date-range-input/component.css';</style>", | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Options = { | |
mirrorProps?: string[], | |
requiredToInstantiate?: string[], | |
mirrorEvents?: string[], | |
initialHtml?: string, | |
} | |
export default (Component, { mirrorProps, requiredToInstantiate, mirrorEvents, initialHtml }: Options = {}) => class extends HTMLElement{ | |
constructor(){ | |
super() | |
const initialProps = {} | |
const shadow = this.attachShadow({ mode: "closed" }) | |
if(initialHtml){ | |
shadow.innerHTML = initialHtml | |
} | |
const instantiateLater = requiredToInstantiate && requiredToInstantiate.length > 0 | |
let component: any = null | |
const instantiate = () => { | |
component = new Component({ | |
target: shadow, | |
props: initialProps, | |
}) | |
mirrorEvents && mirrorEvents.forEach(event => { | |
component.$on(event, ({ detail }) => { | |
this.dispatchEvent( | |
new CustomEvent(event, { | |
detail, | |
}) | |
) | |
}) | |
}) | |
} | |
instantiateLater || instantiate() | |
if(mirrorProps){ | |
mirrorProps.forEach(prop => { | |
Object.defineProperty(this, prop, { | |
set(newValue){ | |
if(component){ | |
component.$set({ | |
[prop]: newValue, | |
}) | |
} else if(instantiateLater){ | |
initialProps[prop] = newValue | |
// @ts-ignore | |
if(requiredToInstantiate.every(key => key in initialProps)){ | |
instantiate() | |
} | |
} | |
}, | |
}) | |
}) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment