import { DockviewGroupPanel, IPinnedTabsHost, IPinnedTabsService } from 'dockview'; /** * The pinned second row's window into its owner (the `PinnedTabsService`): the * component id a within-component drag payload carries, plus a way to flag a * drag as originating in the row so the pin-boundary resolver unpins a drag-out * regardless of the clamp/flip option. */ interface IPinnedRowDragHost { readonly viewId: string; beginRowDrag(panelId: string): void; endRowDrag(): void; } /** * Compute the strip index a dragged pinned tab should move to when reordered * within the pinned row. * * `tabMidpoints` are the horizontal midpoints of the row tabs in their current * order; the insertion slot is the number of midpoints the pointer has passed. * Because `moveTo` pulls the dragged tab out before re-inserting it, a slot to * the right of its current position shifts left by one. Pure (no DOM), so the * geometry-free index math is unit testable (jsdom has no layout). * * @param tabMidpoints midpoint x of each pinned row tab, in order * @param pointerX the drop pointer's x * @param fromIndex the dragged tab's current index in the row */ export declare function computePinnedRowDropIndex(tabMidpoints: number[], pointerX: number, fromIndex: number): number; /** * Compute the pinned-first tab order for a group. * * The invariant is: `[ pinned tabs (in pinned order) ][ unpinned tabs (in * their current relative order) ]`. Pinned tabs are ordered by their position * in `pinnedOrder` (the order they were pinned); a pinned id missing from * `pinnedOrder` sorts after the known ones while preserving its relative * position. Pure (no DOM, no side effects), so the ordering math is unit * testable in isolation from a live component. * * @param currentOrder panel ids in their current strip order * @param isPinned predicate: is this panel id pinned? * @param pinnedOrder canonical order of pinned ids */ export declare function computePinnedFirstOrder(currentOrder: string[], isPinned: (panelId: string) => boolean, pinnedOrder: string[]): string[]; /** * Enforces the pinned-first invariant on each group's tab strip. Pinned state * itself lives on the panel (`panel.api.isPinned`, mutated through the gated * `DockviewComponent.setPanelPinned`); this service only reacts to * pinned-state changes and reorders the strip; it never mutates pinned state * (except the deliberate cross-boundary-drag flip) or re-implements the tab * list. * * Owns: pinned-first ordering, overflow exclusion, the reorder guard, and (in * `separate-row` mode) the pinned second row. Compact rendering + serialization * live in core, keyed off the panel's pinned state. */ export declare class PinnedTabsService implements IPinnedTabsService, IPinnedRowDragHost { private readonly _host; private readonly _disposable; /** Panel id of an in-flight drag that originated in a pinned second row, so * the pin-boundary resolver treats a drop-out as an unpin (see * `resolveDropIndex`). `undefined` when no row drag is active. */ private _rowDragPanelId; /** Flat set of pinned panel ids: the overflow-exclusion lookup. Panel ids * are unique component-wide, so a single set serves every group. */ private readonly _pinnedIds; /** Live groups, tracked so a `fromJSON` restore can seed every strip. */ private readonly _groups; /** Per-group pinned second row (only in `separate-row` mode). */ private readonly _secondRows; /** Re-entrancy guard: reordering moves panels, which must not re-trigger. */ private _enforcing; private get _separateRow(); /** * Sticky-on-scroll is an inline-mode enhancement (the pinned second row is * always visible, so it needs no sticky). On by default; opt out with * `pinnedTabs.stickyScroll: false`. */ private get _inlineSticky(); /** The owning component's id: the `viewId` a row-originated `PanelTransfer` * carries so the main strip's drop targets accept a drag out of the row. */ get viewId(): string; beginRowDrag(panelId: string): void; endRowDrag(): void; constructor(host: IPinnedTabsHost); /** Re-apply the current pinned-tabs mode to an already-tracked group after * a runtime option change: create or tear down its separate row and set * inline sticky, then re-assert the pinned-first order and overflow so the * main strip stays consistent. Idempotent, so a no-op change costs nothing * visible. */ private _reapplyMode; /** Seed the pinned set from a restored group's panels (already in * pinned-first strip order) and re-assert the invariant + overflow. */ private _seedFromRestore; /** * Keep a panel's tab out of the overflow dropdown when it is pinned. A pure * `Set.has` lookup (no DOM reads) so it is safe to call from the overflow * filter, which re-fires on every resize. Returns `false` while the feature * is dormant. */ readonly isExcludedFromOverflow: (panelId: string) => boolean; /** * Keep a header drop on the correct side of the pin boundary. By default a * cross-boundary drop is **clamped** back (Chrome-style). Opt in to * flipping the dragged panel's pinned state with * `togglePinOnCrossBoundaryDrag: true` (VS-Code-style). The flip is * deferred to a microtask so it runs after the in-progress move settles, * then the pinned-change handler re-orders the strip. * * The boundary is the pinned count *excluding the dragged panel* (it is * removed and re-inserted during the move, so the index is post-removal). */ resolveDropIndex(group: DockviewGroupPanel, panelId: string, index: number): number; /** * Re-assert the pinned-first invariant on `group`'s tab strip by moving * panels into the computed order. A no-op while the feature is dormant * (`pinnedTabs.enabled` unset) or while a reorder is already in flight. */ enforceOrder(group: DockviewGroupPanel): void; dispose(): void; } export declare const PinnedTabsModule: import("dockview").DockviewModule; export {};