/** * `` — React renderer for a layout-as-data tree. * * Pure function of the current model snapshot (+ registry + the two host * callbacks). It owns NO layout state: it subscribes to the `LayoutModel`, * keeps the latest tree in component state, and re-renders on every emission. * All structural targeting is via STABLE `data-*` attributes — see the * contract doc-block in `dock-view.test.tsx`. * * This file lives under `src/dock-react/` (NOT `src/layout/`), so importing * react here does not violate the pure-TS layout boundary. The stateful child * views (`SplitView`, `GroupView`) and the body renderer live in sibling * modules; this file owns the orchestration (`renderNode`) + the shared * `RenderContext`. */ import { type ReactNode } from 'react'; import type { LayoutModel, LayoutNode, PanelRegistry } from '../layout/index.js'; import { type DropZone } from './drag-redock.js'; export interface DockViewProps { model: LayoutModel; registry: PanelRegistry; /** * Render a DOM panel's body. `opts.active` is `true` iff `panelId` is its tab * group's currently-active panel. Under DOM-panel keepalive every DOM panel in * a group is rendered (the inactive ones hidden), so this callback is invoked * for ALL of them and `opts.active` is RE-EVALUATED on every activation change * WITHOUT remounting the kept-alive subtree — letting a host run on-activation * side effects (e.g. data refresh) off the false→true `active` edge. */ renderDomPanel: (panelId: string, opts: { active: boolean; }) => ReactNode; bindNativeSlot: (panelId: string, el: HTMLElement | null) => void; /** * Opt-in: while a `dropPolicy:'reorder-only'` panel is dragged, paint NO drop * indicator over a group body (its own edges or any other group) — those are * no-op targets, so the highlight is misleading. Default `false` keeps the * geometry-only indicator (it paints where the pointer is; the capability * gate still rejects the drop). Hosts that want the cleaner "no misleading * highlight" UX pass `true`. */ suppressReorderOnlyDropIndicator?: boolean; /** * Fires when the user clicks a tab that is ALREADY active. The host can use * this to toggle the panel's visibility (e.g. collapse the debug group). * When absent, clicking an active tab is a no-op (the existing behaviour). */ onActiveTabClick?: (panelId: string) => void; } /** * Read the current dock layout epoch (the model revision). Re-renders the caller * whenever a layout mutation commits. Keyed into a panel's effect deps, it lets * a native-overlay host re-measure on a reorder that fires no geometry event. * Returns 0 when used outside a ``. */ export declare function useDockLayoutEpoch(): number; export declare function DockView(props: DockViewProps): ReactNode; /** The shared per-render context threaded from `DockView` down through * `renderNode` into every `SplitView`/`GroupView`. Exported so the sibling view * modules type their `ctx` against the single source. */ export interface RenderContext { registry: PanelRegistry; renderDomPanel: (panelId: string, opts: { active: boolean; }) => ReactNode; bindNativeSlot: (panelId: string, el: HTMLElement | null) => void; onActivate: (groupId: string, panelId: string) => void; onActiveTabClick: ((panelId: string) => void) | undefined; onApplyLayout: (splitId: string, weights: number[]) => void; onRedock: (groupId: string, activePanelId: string, draggedPanelId: string, zone: DropZone, /** Pointer-derived insertion index for a within-group reorder * (`dropPolicy:'reorder-only'`). Omitted by the imperative seam, which * falls back to the active anchor's current index. */ reorderIndex?: number) => void; onClose: (panelId: string) => void; /** False when the whole tree has a single panel — suppresses every close * button so the layout can't be emptied (closePanel would no-op anyway). */ canClose: boolean; /** True iff `panelId` is present in the CURRENT layout tree (M2). Registry * membership is NOT enough: a panel can be registered but absent from the tree * (closed out / never docked), and driving a re-dock on it makes the mutation * layer throw `panel not found`. A drop carrying such an id must be a no-op. */ isPanelInTree: (panelId: string) => boolean; /** See {@link DockViewProps.suppressReorderOnlyDropIndicator}. */ suppressReorderOnlyDropIndicator: boolean; /** The in-flight tab-drag panel id, INSTANCE-scoped to the owning DockView * (set on `dragstart`, cleared on `dragend`/`drop`). The drop-indicator path * reads it during `dragover`, where the DataTransfer value is unreadable. */ activeDragPanelId: { current: string | null; }; } declare function renderNode(node: LayoutNode, ctx: RenderContext): ReactNode; export { renderNode }; //# sourceMappingURL=dock-view.d.ts.map