UNPKG

@arminmajerie/dockview

Version:

Zero dependency layout manager supporting tabs, grids and splitviews (SolidJS only)

95 lines (94 loc) 3.2 kB
import { createEffect, onCleanup, onMount } from 'solid-js'; import { createPaneview, PROPERTY_KEYS_PANEVIEW } from 'dockview-core'; import { usePortalsLifecycle } from '../solid'; import { PanePanelSection } from './view'; function extractCoreOptions(props) { const coreOptions = PROPERTY_KEYS_PANEVIEW.reduce((obj, key) => { if (key in props) { obj[key] = props[key]; } return obj; }, {}); return coreOptions; } export function PaneviewSolid(props) { let domRef; let paneviewRef; const [portals, addPortal] = usePortalsLifecycle(); let prevProps = {}; // Handle options changes reactively createEffect(() => { const changes = {}; PROPERTY_KEYS_PANEVIEW.forEach((propKey) => { if (propKey in props) { // Only apply keys that exist in PaneviewOptions! changes[propKey] = props[propKey]; } }); if (paneviewRef) { paneviewRef.updateOptions(changes); } prevProps = { ...props }; }); // Initial mount: create Paneview instance and panels onMount(() => { if (!domRef) return; const headerComponents = props.headerComponents ?? {}; const frameworkOptions = { createComponent: (options) => { return new PanePanelSection(options.id, props.components[options.name], { addPortal }); }, createHeaderComponent: (options) => { return new PanePanelSection(options.id, headerComponents[options.name], { addPortal }); }, }; const api = createPaneview(domRef, { ...extractCoreOptions(props), ...frameworkOptions, }); api.layout(domRef.clientWidth, domRef.clientHeight); if (props.onReady) { props.onReady({ api }); } paneviewRef = api; onCleanup(() => { paneviewRef = undefined; api.dispose(); }); }); // Watch for components prop changes createEffect(() => { if (!paneviewRef) return; paneviewRef.updateOptions({ createComponent: (options) => { return new PanePanelSection(options.id, props.components[options.name], { addPortal }); }, }); }); // Watch for headerComponents prop changes createEffect(() => { if (!paneviewRef) return; const headerComponents = props.headerComponents ?? {}; paneviewRef.updateOptions({ createHeaderComponent: (options) => { return new PanePanelSection(options.id, headerComponents[options.name], { addPortal }); }, }); }); // Listen for onDidDrop event createEffect(() => { if (!paneviewRef) return; const disposable = paneviewRef.onDidDrop((event) => { if (props.onDidDrop) props.onDidDrop(event); }); onCleanup(() => disposable.dispose()); }); return (<div style={{ height: '100%', width: '100%' }} ref={el => domRef = el}> {/*{portals()}*/} </div>); }