UNPKG

claritykit-svelte

Version:

A comprehensive Svelte component library focused on accessibility, ADHD-optimized design, developer experience, and full SSR compatibility

78 lines (77 loc) 2.68 kB
/** * Create a TipTap 3 compatible node view that renders a Svelte component */ export function createSvelteNodeView(options) { const { component: Component, as = 'div', className, tag = 'div' } = options; return ({ node, editor, getPos, decorations, selected }) => { // Create container element const container = document.createElement(tag); if (className) { container.className = className; } let svelteComponent = null; const updateAttributes = (attributes) => { const pos = getPos(); if (pos !== undefined) { const transaction = editor.view.state.tr.setNodeMarkup(pos, undefined, { ...node.attrs, ...attributes, }); editor.view.dispatch(transaction); } }; // Mount the Svelte component const mount = () => { try { svelteComponent = new Component({ target: container, props: { node, editor, getPos, decorations, selected, updateAttributes, }, }); } catch (error) { console.error('Failed to mount Svelte component in node view:', error); container.innerHTML = '<div class="error">Failed to load component</div>'; } }; const update = (updatedNode, updatedDecorations, updatedSelected) => { if (updatedNode.type !== node.type) { return false; } // Update the component props if (svelteComponent && svelteComponent.$set) { svelteComponent.$set({ node: updatedNode, decorations: updatedDecorations, selected: updatedSelected, updateAttributes, }); } return true; }; const destroy = () => { if (svelteComponent) { svelteComponent.$destroy(); svelteComponent = null; } }; // Initial mount mount(); return { dom: container, update, destroy, ignoreMutation: (mutation) => { // Allow Svelte to handle its own mutations return !container.contains(mutation.target) || container === mutation.target; }, }; }; }