Skip to content

Instantly share code, notes, and snippets.

@TehShrike
Last active July 24, 2023 17:39
Show Gist options
  • Save TehShrike/aea6bed1cd48c0780f5fba01d67e19b2 to your computer and use it in GitHub Desktop.
Save TehShrike/aea6bed1cd48c0780f5fba01d67e19b2 to your computer and use it in GitHub Desktop.
Svelte custom element wrapper
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>",
})
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