import { register, ComponentType as mComponentType, ICustomElement, FunctionComponent, ComponentOptions, PropsDefinitionInput } from "component-register"; export { hot, getCurrentElement, noShadowDOM } from "component-register"; export type ComponentType = mComponentType; import { createRoot, createSignal } from "solid-js"; import { insert } from "solid-js/web"; function createProps(raw: T) { const keys = Object.keys(raw) as (keyof T)[]; const props = {}; for (let i = 0; i < keys.length; i++) { const [get, set] = createSignal(raw[keys[i]]); Object.defineProperty(props, keys[i], { get, set(v) { set(() => v); } }); } return props as T; } function lookupContext(el: ICustomElement & { _$owner?: any }) { if (el.assignedSlot && el.assignedSlot._$owner) return el.assignedSlot._$owner; let next: Element & { _$owner?: any } = el.parentNode; while ( next && !next._$owner && !(next.assignedSlot && (next.assignedSlot as Element & { _$owner?: any })._$owner) ) next = next.parentNode as Element; return next && next.assignedSlot ? (next.assignedSlot as Element & { _$owner?: any })._$owner : el._$owner; } function withSolid(ComponentType: ComponentType): ComponentType { return (rawProps: T, options: ComponentOptions) => { const { element } = options as { element: ICustomElement & { _$owner?: any }; }; return createRoot((dispose: Function) => { const props = createProps(rawProps); element.addPropertyChangedCallback((key: string, val: any) => (props[key as keyof T] = val)); element.addReleaseCallback(() => { element.renderRoot.textContent = ""; dispose(); }); const comp = (ComponentType as FunctionComponent)(props as T, options); return insert(element.renderRoot, comp); }, lookupContext(element)); }; } function customElement( tag: string, ComponentType: ComponentType ): (ComponentType: ComponentType) => any; function customElement( tag: string, props: PropsDefinitionInput, ComponentType: ComponentType ): (ComponentType: ComponentType) => any; function customElement( tag: string, props: PropsDefinitionInput | ComponentType, ComponentType?: ComponentType ): (ComponentType: ComponentType) => any { if (arguments.length === 2) { ComponentType = props as ComponentType; props = {} as PropsDefinitionInput; } return register(tag, props as PropsDefinitionInput)(withSolid(ComponentType!)); } export { withSolid, customElement };