UNPKG

@prosekit/svelte

Version:

Svelte components and utilities for ProseKit

72 lines (59 loc) 2.35 kB
import type { AnyFunction } from '@prosekit/core' import type { EventHandler } from 'svelte/elements' import { useEditorContext } from '../contexts/editor-context' // For unknown reason, Svelte v4 cannot set properties on a web component // when I directly use `{...$$props}`. It seems that Svelte v4 recognizes // the properties as attributes. Here is a workaround to set the properties // on the element manually and only let Svelte set the attributes. export function useComponent( propNames: string[], eventNames: string[], ): (element: HTMLElement | undefined, $$props: Record<string, unknown>) => [Record<string, unknown>, Record<string, EventHandler>] { const hasEditor = propNames.includes('editor') const lowerCaseEventNameMap = new Map( eventNames.map((name) => [name.toLowerCase(), name]), ) const editorContext = useEditorContext() function handleChange( element: HTMLElement | undefined, $$props: Record<string, unknown>, ): [Record<string, unknown>, Record<string, EventHandler>] { const properties: Record<string, unknown> = {} const attributes: Record<string, unknown> = {} const eventHandlers: Record<string, EventHandler> = {} for (const [name, value] of Object.entries($$props)) { if (value === undefined || name.startsWith('$')) { continue } if (propNames.includes(name)) { properties[name] = value continue } if (name.startsWith('on')) { const lowerCaseEventName = name.slice(2).toLowerCase() const eventName = lowerCaseEventNameMap.get(lowerCaseEventName) if (eventName) { const extractDetail = eventName.endsWith('Change') eventHandlers[eventName] = (event: Event) => { const handler = value as AnyFunction | null if (typeof handler === 'function') { handler(extractDetail ? (event as CustomEvent).detail : event) } } continue } } attributes[name] = value } if (hasEditor && !properties.editor && editorContext) { properties.editor = editorContext } if (element) { for (const [key, value] of Object.entries(properties)) { ;(element as Record<string, any>)[key] = value } } return [attributes, eventHandlers] } return handleChange }