"use client"; import type { AddPanelOptions, DockviewApi, DockviewReadyEvent, IDockviewPanelHeaderProps, IDockviewPanelProps, } from "dockview"; import "@/styles/dockview.css"; import * as Icons from "lucide-react"; import { useEffect, useState } from "react"; import type { LucideIcon } from "lucide-react"; import { DockviewReact, themeAbyssSpaced } from "dockview"; interface DockviewProps { storageKey: string; options: AddPanelOptions[]; components: Record>; tabComponents?: Record>; onApiReady?: (api: DockviewApi) => void; } const DefaultTab = ( props: IDockviewPanelHeaderProps<{ icon?: string }> ) => { const { icon } = props.params; const Icon = icon && icon in Icons ? (Icons[icon as keyof typeof Icons] as LucideIcon) : null; return (
{Icon && (
); }; export default function DockView({ storageKey, options, components, tabComponents, onApiReady, }: DockviewProps) { const [api, setApi] = useState(); useEffect(() => { if (!api) return; const disposable = api.onDidLayoutChange(() => { const layout = api.toJSON(); localStorage.setItem(storageKey, JSON.stringify(layout)); }); return () => disposable.dispose(); }, [api, storageKey]); const onReady = (event: DockviewReadyEvent) => { setApi(event.api); onApiReady?.(event.api); let success = false; const serializedLayout = localStorage.getItem(storageKey); if (serializedLayout) { try { const layout = JSON.parse(serializedLayout); event.api.fromJSON(layout); success = true; } catch (error) { console.error("Failed to load layout:", error); localStorage.removeItem(storageKey); } } if (!success) { options.forEach((option) => { event.api.addPanel({ ...option }); }); } }; return ( ); }