@x1a0f3n9/dsh-client-ui-dockkit 0.1.5-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Interaction limits and dock geometry. The model itself is unbounded; these
3
+ * are the V1 rules the interaction layer enforces before it dispatches, kept
4
+ * pure so they can be asserted without a browser.
5
+ */
6
+ import type { DockZone, LayoutState, SplitAxis, SplitDirection } from '../contract/types.ts';
7
+ /** V1 caps the docked grid at four panes; floating panes do not count. */
8
+ export declare const MAX_DOCK_PANES = 4;
9
+ /** Smallest fraction a divider drag may leave a pane, as a share of its split. */
10
+ export declare const MIN_PANE_FRACTION = 0.12;
11
+ /** Size a tab takes when it first floats, in CSS pixels. */
12
+ export declare const FLOAT_DEFAULT_SIZE: {
13
+ readonly width: 380;
14
+ readonly height: 300;
15
+ };
16
+ /** Smallest size a floating panel may be resized to, in CSS pixels. */
17
+ export declare const FLOAT_MIN_SIZE: {
18
+ readonly width: 220;
19
+ readonly height: 140;
20
+ };
21
+ /** Fraction of a pane's width or height that counts as its dock edge. */
22
+ export declare const DOCK_EDGE_FRACTION = 0.25;
23
+ /**
24
+ * Number of docked panes.
25
+ * @param state - current layout.
26
+ * @returns how many panes the docked tree holds; floating panes do not count.
27
+ */
28
+ export declare function dockPaneCount(state: LayoutState): number;
29
+ /**
30
+ * Whether another docked pane is allowed.
31
+ * @param state - current layout.
32
+ * @returns whether the docked tree is under `MAX_DOCK_PANES`.
33
+ */
34
+ export declare function canSplit(state: LayoutState): boolean;
35
+ /** The five dock regions a tab can be dropped on. */
36
+ export declare const DOCK_ZONES: readonly DockZone[];
37
+ /**
38
+ * Which dock region a pointer sits in.
39
+ * @param x - pointer x as a fraction of pane width.
40
+ * @param y - pointer y as a fraction of pane height.
41
+ * @param edge - edge band width as a fraction; defaults to `DOCK_EDGE_FRACTION`.
42
+ * @returns the closest edge when the pointer is inside its band, else `'center'`.
43
+ */
44
+ export declare function zoneAt(x: number, y: number, edge?: number): DockZone;
45
+ /**
46
+ * How a dock region splits the pane it targets.
47
+ * @param zone - the region the pointer released in.
48
+ * @returns the split's axis and direction, or `undefined` for `'center'`, which moves the tab into the pane instead.
49
+ */
50
+ export declare function zoneSplit(zone: DockZone): {
51
+ axis: SplitAxis;
52
+ direction: SplitDirection;
53
+ } | undefined;
54
+ /**
55
+ * Clamp divider sizes so no pane falls under `MIN_PANE_FRACTION`.
56
+ * @param sizes - candidate fractions from the drag preview.
57
+ * @param minimum - smallest allowed share; defaults to the kit's pane fraction.
58
+ * @returns fractions summing to 1 with every entry at or above the minimum.
59
+ */
60
+ export declare function clampSizes(sizes: readonly number[], minimum?: number): number[];
61
+ //# sourceMappingURL=constraints.d.ts.map
@@ -0,0 +1,191 @@
1
+ /**
2
+ * The intent layer's stateful embedding: one controller per docking surface,
3
+ * React-free, and itself the observable source the UI subscribes to
4
+ * (`subscribe` + `getSnapshot`, whose reference only changes when the layout
5
+ * does).
6
+ *
7
+ * Every method here is a planner call plus recording plus one notification. The
8
+ * decisions live in `planner.ts` so an embedder holding its layout in an external
9
+ * store shares them rather than reimplementing them; a planner that returns no
10
+ * operations records nothing and notifies nobody.
11
+ *
12
+ * The controller holds no host concepts: what a seeded tab contains arrives as a
13
+ * factory, and a tab's `kind` is an opaque string.
14
+ */
15
+ import type { DockMode, DockZone, FloatRect, LayoutOp, LayoutState, PaneId, SplitId, TabId } from '../contract/types.ts';
16
+ import { type TabFactory } from './initial.ts';
17
+ import { type OpenContentInput } from './planner.ts';
18
+ export type { OpenContentInput } from './planner.ts';
19
+ /** Everything the rendering layer reads, in one immutable value. */
20
+ export interface DockSnapshot {
21
+ readonly state: LayoutState;
22
+ readonly canUndo: boolean;
23
+ readonly canRedo: boolean;
24
+ /** Whether the docked grid still has room for another pane. */
25
+ readonly canSplit: boolean;
26
+ /** Recorded operation count, redo branch included. */
27
+ readonly opCount: number;
28
+ /** How many recorded intents are applied. */
29
+ readonly cursor: number;
30
+ }
31
+ /** What the embedder seeds new panes with. */
32
+ export interface DockControllerOptions {
33
+ /** Builds the tab the starting pane holds; omit to start empty. */
34
+ readonly makeInitialTab?: TabFactory;
35
+ /** Builds the tab a pane created by `splitPane` holds; omit to leave it empty. */
36
+ readonly makePaneTab?: TabFactory;
37
+ /** Starting presentation; defaults to `push`. */
38
+ readonly mode?: DockMode;
39
+ }
40
+ /** One docking surface: history, interaction limits, and change notification. */
41
+ export declare class DockController {
42
+ private readonly minter;
43
+ private readonly sequencer;
44
+ private readonly listeners;
45
+ private readonly makePaneTab;
46
+ private snapshot;
47
+ /** @param options - the tab factories this surface seeds panes with. */
48
+ constructor(options?: DockControllerOptions);
49
+ /**
50
+ * Observe layout changes.
51
+ * @param listener - called after every committed change.
52
+ * @returns disposer removing the listener.
53
+ */
54
+ subscribe: (listener: () => void) => (() => void);
55
+ /** Current snapshot; the same reference until the layout changes. */
56
+ getSnapshot: () => DockSnapshot;
57
+ /** Recorded sequence, for tests and the operation readout. */
58
+ get ops(): readonly LayoutOp[];
59
+ private buildSnapshot;
60
+ private commit;
61
+ private get state();
62
+ private get mint();
63
+ /**
64
+ * Record a planned intent as one history entry.
65
+ * @param ops - the planner's operations; empty plans nothing.
66
+ * @returns whether anything was recorded.
67
+ */
68
+ private run;
69
+ /**
70
+ * Expand or collapse the docked area. Floating panels are unaffected.
71
+ * @param expanded - whether the docked area is shown.
72
+ */
73
+ setExpanded(expanded: boolean): void;
74
+ /** Flip the docked area between expanded and collapsed. */
75
+ toggleExpanded(): void;
76
+ /**
77
+ * Switch how the docked area is presented.
78
+ * @param mode - the presentation to record.
79
+ */
80
+ setMode(mode: DockMode): void;
81
+ /**
82
+ * Split a pane to its right and seat the embedder's pane tab in the new pane.
83
+ * @param paneId - pane to split; defaults to the active docked pane.
84
+ * @returns false when the docked grid is already at `MAX_DOCK_PANES`.
85
+ */
86
+ splitPane(paneId?: PaneId): boolean;
87
+ /**
88
+ * Seat the pane-tab factory's tab at the end of a pane's strip.
89
+ * @param paneId - the docked pane whose strip asked.
90
+ * @returns false when there is no factory or the pane is not docked.
91
+ */
92
+ addTab(paneId: PaneId): boolean;
93
+ /**
94
+ * Open content, or focus the tab already showing it.
95
+ * @param input - consistency id, copy, and optional target pane.
96
+ * @returns the tab now focused.
97
+ */
98
+ openContent(input: OpenContentInput): TabId;
99
+ /**
100
+ * Open a second, independent tab on the same content.
101
+ * @param tabId - tab to copy.
102
+ * @returns the new tab id.
103
+ */
104
+ duplicateTab(tabId: TabId): TabId;
105
+ /**
106
+ * Destroy a tab and its content state. A floating host panel goes with it.
107
+ * @param tabId - the tab to close.
108
+ */
109
+ closeTab(tabId: TabId): void;
110
+ /**
111
+ * Focus a tab, its pane, and raise that pane when it floats.
112
+ * @param tabId - the tab to focus.
113
+ */
114
+ focusTab(tabId: TabId): void;
115
+ /**
116
+ * Focus a pane, raising it when it floats.
117
+ * @param paneId - the pane to focus.
118
+ */
119
+ focusPane(paneId: PaneId): void;
120
+ /**
121
+ * Move a tab inside its own pane.
122
+ * @param tabId - the tab to move.
123
+ * @param index - its position in the strip without it.
124
+ */
125
+ reorderTab(tabId: TabId, index: number): void;
126
+ /**
127
+ * Put a tab at an explicit slot: a reorder inside its own pane, otherwise a
128
+ * move (or a return, when it currently floats).
129
+ * @param tabId - the tab being placed.
130
+ * @param toPaneId - destination docked pane.
131
+ * @param index - caret slot in the destination strip, counting the dragged chip when the strip is its own.
132
+ * @returns false when the placement changes nothing.
133
+ */
134
+ placeTab(tabId: TabId, toPaneId: PaneId, index: number): boolean;
135
+ /**
136
+ * Resolve a tab drop inside the docked area.
137
+ * @param tabId - the dragged tab.
138
+ * @param targetPaneId - pane under the pointer.
139
+ * @param zone - dock region the pointer released in.
140
+ * @returns false when the drop changes nothing or the grid is full.
141
+ */
142
+ dropTab(tabId: TabId, targetPaneId: PaneId, zone: DockZone): boolean;
143
+ /**
144
+ * Take a tab out into a floating panel.
145
+ * @param tabId - tab to float.
146
+ * @param rect - explicit rectangle; defaults to a cascade from the last panel.
147
+ * @returns the new floating pane id.
148
+ */
149
+ floatTab(tabId: TabId, rect?: FloatRect): PaneId;
150
+ /**
151
+ * Send a floating panel's tab back into the docked tree.
152
+ * @param paneId - the floating pane.
153
+ * @param toPaneId - destination docked pane; defaults to the active one.
154
+ */
155
+ unfloatPane(paneId: PaneId, toPaneId?: PaneId): void;
156
+ /**
157
+ * Record the net position of a floating-panel drag; the panel is focused and raised with it.
158
+ * @param paneId - the floating pane.
159
+ * @param x - its new left edge, in viewport pixels.
160
+ * @param y - its new top edge, in viewport pixels.
161
+ */
162
+ moveFloat(paneId: PaneId, x: number, y: number): void;
163
+ /**
164
+ * Record the net rectangle of a floating-panel resize; the panel is focused and raised with it.
165
+ * @param paneId - the floating pane.
166
+ * @param rect - its new rectangle.
167
+ */
168
+ resizeFloat(paneId: PaneId, rect: FloatRect): void;
169
+ /**
170
+ * Record the net sizes of a divider drag, clamped to the pane minimum.
171
+ * @param splitId - the split whose divider moved.
172
+ * @param sizes - the fractions the drag reached.
173
+ */
174
+ resizeSplit(splitId: SplitId, sizes: readonly number[]): void;
175
+ /**
176
+ * Step back one intent, or one run of consecutive focus-only intents.
177
+ * @returns false when there is nothing to undo.
178
+ */
179
+ undo(): boolean;
180
+ /**
181
+ * Step forward over what the matching undo stepped back.
182
+ * @returns false when there is nothing to redo.
183
+ */
184
+ redo(): boolean;
185
+ /**
186
+ * The pane a new tab lands in, for an embedder that needs to name it.
187
+ * @returns the active pane when docked, else the first docked pane.
188
+ */
189
+ activeDockPaneId(): PaneId;
190
+ }
191
+ //# sourceMappingURL=controller.d.ts.map
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Pure geometry for the drag interaction: point tests, dock-zone resolution
3
+ * against a real element rectangle, and tab-strip insertion slots. Kept free of
4
+ * React and DOM types so the drop rules can be asserted without a browser; the
5
+ * component layer measures rectangles and calls in.
6
+ */
7
+ import type { DockZone, FloatRect, PaneId } from '../contract/types.ts';
8
+ /** A measured rectangle in viewport coordinates. */
9
+ export interface Rect {
10
+ readonly x: number;
11
+ readonly y: number;
12
+ readonly width: number;
13
+ readonly height: number;
14
+ }
15
+ /** Where a drag would land if released now. */
16
+ export type DropTarget =
17
+ /** Into a tab strip at an explicit slot: a reorder or a cross-pane move. */
18
+ {
19
+ readonly kind: 'strip';
20
+ readonly paneId: PaneId;
21
+ readonly index: number;
22
+ }
23
+ /** Onto a pane body: the centre moves the tab in, an edge splits the pane. */
24
+ | {
25
+ readonly kind: 'zone';
26
+ readonly paneId: PaneId;
27
+ readonly zone: DockZone;
28
+ };
29
+ /**
30
+ * Whether a point is inside a rectangle, edges included.
31
+ * @param rect - the rectangle.
32
+ * @param x - point x in the same coordinates.
33
+ * @param y - point y in the same coordinates.
34
+ * @returns whether the point lies on or inside the rectangle.
35
+ */
36
+ export declare function containsPoint(rect: Rect, x: number, y: number): boolean;
37
+ /**
38
+ * Dock region a point falls in, relative to one pane's rectangle.
39
+ * @param rect - the pane's measured box.
40
+ * @param x - pointer x in the same coordinates.
41
+ * @param y - pointer y in the same coordinates.
42
+ * @param edge - edge band as a fraction; defaults to the model's value.
43
+ * @returns the region; `'center'` when the point is not in an edge band.
44
+ */
45
+ export declare function zoneInRect(rect: Rect, x: number, y: number, edge?: number): DockZone;
46
+ /**
47
+ * Slot a tab would take in a strip, by comparing the pointer with each tab's midpoint.
48
+ * @param tabRects - the strip's tab boxes in strip order.
49
+ * @param x - pointer x.
50
+ * @returns the insertion index, from 0 to `tabRects.length`.
51
+ */
52
+ export declare function insertionIndex(tabRects: readonly Rect[], x: number): number;
53
+ /** What one pane's strip measured, for the room rule. */
54
+ export interface PaneMeasure {
55
+ /** The pane's box, borders included. */
56
+ readonly pane: Rect;
57
+ /** The strip's box, inside the borders; its height is what a vertical half must carry. */
58
+ readonly strip: Rect;
59
+ /** Width of the chip box, the strip's one shrinking part. */
60
+ readonly chipsWidth: number;
61
+ /** Width of the fill: free space, not a control. */
62
+ readonly fillWidth: number;
63
+ /**
64
+ * Footprint of the rendered split control (its width plus the strip's gap)
65
+ * for embedders that hide blocked split controls: a half too narrow to
66
+ * split hides its own control, so the rule leaves the footprint out of the
67
+ * fixed part. Leaving it out is also what keeps the reading stable — the
68
+ * control hiding sheds the same footprint from the strip, and a reading
69
+ * that counted it would flip with the control's visibility and re-render
70
+ * forever. Absent or 0 keeps the control in the fixed part, for embedders
71
+ * that render a blocked control disabled.
72
+ */
73
+ readonly splitControlWidth?: number;
74
+ }
75
+ /** Pixel minimums the room rule holds each half to. */
76
+ export interface SplitMinimums {
77
+ /** The divider a split puts between the halves. */
78
+ readonly divider: number;
79
+ /** One chip at its minimum: the smallest strip that still names a tab. */
80
+ readonly chip: number;
81
+ /** The smallest body under a strip: one secondary text line inside 12px of the body's own insets. */
82
+ readonly body: number;
83
+ }
84
+ /**
85
+ * The minimums where no computed style can be read, mirroring
86
+ * `dockkit.module.css`: `.splitRow > .divider` takes no layout width (its
87
+ * hairline is painted over the seam); `.tab` is 80px of content plus
88
+ * 10px + 10px of padding (content-box), 100px; 12px above and below one 13px
89
+ * secondary line at 1.6 line-height — the inset a body draws for itself, as
90
+ * `.empty` does — is 45px, held to 48px.
91
+ */
92
+ export declare const SPLIT_MINIMUMS: SplitMinimums;
93
+ /** Whether a pane's two halves after an equal split would each still work. */
94
+ export interface HalvesFit {
95
+ /** A row split: each half holds the strip's fixed controls and one minimum chip. */
96
+ readonly row: boolean;
97
+ /** A column split: each half holds the strip and a minimum body. */
98
+ readonly column: boolean;
99
+ }
100
+ /**
101
+ * The room rule. After an equal split each half must hold what cannot shrink:
102
+ * horizontally the strip's fixed part — its width minus the chip box, the
103
+ * fill, and `splitControlWidth`, which is the padding, the gaps, and every
104
+ * control a half would still draw — plus one chip at its minimum; vertically
105
+ * the strip plus a minimum body. The
106
+ * borders are what the pane's box exceeds the strip's by. An unmeasured pane
107
+ * (no layout, as under jsdom) fits: the rule only blocks on a positive reading.
108
+ * @param measure - the pane's rectangles.
109
+ * @param minimums - the pixel minimums; defaults to the stylesheet's.
110
+ * @returns whether a row and a column split each leave two working halves.
111
+ */
112
+ export declare function halvesFit(measure: PaneMeasure, minimums?: SplitMinimums): HalvesFit;
113
+ /** How far a pointer must travel before a press becomes a drag, in pixels. */
114
+ export declare const DRAG_THRESHOLD = 4;
115
+ /**
116
+ * Whether a press has travelled far enough to be a drag.
117
+ * @param startX - press x.
118
+ * @param startY - press y.
119
+ * @param x - current pointer x.
120
+ * @param y - current pointer y.
121
+ * @returns whether either axis moved at least `DRAG_THRESHOLD`.
122
+ */
123
+ export declare function passedThreshold(startX: number, startY: number, x: number, y: number): boolean;
124
+ /**
125
+ * Split fractions after a divider drag.
126
+ * @param sizes - the split's current fractions.
127
+ * @param index - divider position: the boundary between `index` and `index + 1`.
128
+ * @param delta - pointer travel along the split axis, as a fraction of the split's extent.
129
+ * @returns new fractions; the two neighbours absorb the whole change.
130
+ */
131
+ export declare function dividerSizes(sizes: readonly number[], index: number, delta: number): number[];
132
+ /** A width/height pair used as a floating-panel bound. */
133
+ export interface Size {
134
+ readonly width: number;
135
+ readonly height: number;
136
+ }
137
+ /**
138
+ * A floating panel's rectangle after a drag.
139
+ * @param rect - the rectangle the gesture started from.
140
+ * @param dx - pointer travel on x.
141
+ * @param dy - pointer travel on y.
142
+ * @returns the moved rectangle; the size is unchanged.
143
+ */
144
+ export declare function movedRect(rect: FloatRect, dx: number, dy: number): FloatRect;
145
+ /**
146
+ * A floating panel's rectangle after a bottom-right resize.
147
+ * @param rect - the rectangle the gesture started from.
148
+ * @param dx - pointer travel on x.
149
+ * @param dy - pointer travel on y.
150
+ * @param min - smallest size the panel may take.
151
+ * @returns the resized rectangle; the origin is unchanged.
152
+ */
153
+ export declare function resizedRect(rect: FloatRect, dx: number, dy: number, min: Size): FloatRect;
154
+ /**
155
+ * Where a panel should appear when a tab is dropped outside the docked area.
156
+ * @param x - drop point x.
157
+ * @param y - drop point y.
158
+ * @param size - the panel's size.
159
+ * @returns a rectangle whose header sits under the drop point.
160
+ */
161
+ export declare function floatRectAt(x: number, y: number, size: Size): FloatRect;
162
+ //# sourceMappingURL=geometry.d.ts.map
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Initial state and the identity mint every operation draws its new ids from.
3
+ * Ids are minted outside `applyOp` so a recorded sequence replays to the exact
4
+ * same tree.
5
+ *
6
+ * What the first tab *is* belongs to the embedder: pass a factory and this
7
+ * module only decides where it sits.
8
+ */
9
+ import type { DockMode, LayoutState, TabId, TabRecord } from '../contract/types.ts';
10
+ import type { Mint } from './planner.ts';
11
+ /** Monotonic id source; one instance belongs to one surface's sequence. */
12
+ export interface IdMinter {
13
+ /** Next id under `prefix`, unique for the life of this minter; the prefix names the id's kind. */
14
+ readonly next: Mint;
15
+ }
16
+ /**
17
+ * Create an id source.
18
+ * @param seed - number the first id counts from; defaults to 0.
19
+ * @returns a minter producing `<prefix><n>` ids.
20
+ */
21
+ export declare function createIdMinter(seed?: number): IdMinter;
22
+ /** Builds the tab record a newly seeded pane should hold. */
23
+ export type TabFactory = (id: TabId) => TabRecord;
24
+ /**
25
+ * The state a surface starts in: collapsed, one docked pane, and whatever tab
26
+ * `makeInitialTab` supplies.
27
+ *
28
+ * The first tab belongs to the initial state rather than to an operation, so
29
+ * expanding and collapsing never accumulates copies of it.
30
+ * @param minter - id source this surface's sequence will keep using.
31
+ * @param makeInitialTab - builds the starting tab; omit for an empty pane.
32
+ * @param mode - starting presentation; the embedder's product default.
33
+ * @returns the collapsed single-pane starting state.
34
+ */
35
+ export declare function createInitialState(minter: IdMinter, makeInitialTab?: TabFactory, mode?: DockMode): LayoutState;
36
+ //# sourceMappingURL=initial.d.ts.map
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The operation engine: one pure `applyOp` that returns the next state plus the
3
+ * operations that undo it. No React, no DOM, no ambient state — replaying the
4
+ * same operations over the same initial state always yields the same result,
5
+ * because every id an operation creates travels inside the operation.
6
+ *
7
+ * Interaction limits (pane count, drag preview coalescing) are not enforced
8
+ * here; they belong to the interaction layer (`constraints.ts` and the UI).
9
+ */
10
+ import type { ApplyResult, LayoutOp, LayoutState } from '../contract/types.ts';
11
+ /**
12
+ * Apply one operation.
13
+ * @param state - state the operation reads; never mutated.
14
+ * @param op - the operation, carrying every id it creates.
15
+ * @returns the next state and the operations that undo it, applied in order.
16
+ * @throws when the operation addresses missing nodes or breaks a model rule.
17
+ */
18
+ export declare function applyOp(state: LayoutState, op: LayoutOp): ApplyResult;
19
+ /**
20
+ * Fold operations forward, discarding inverses.
21
+ * @param state - starting state.
22
+ * @param ops - operations in recorded order.
23
+ * @returns the state after every operation.
24
+ */
25
+ export declare function replay(state: LayoutState, ops: readonly LayoutOp[]): LayoutState;
26
+ //# sourceMappingURL=operations.d.ts.map
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Intent planning: each interaction, as a pure function from the current state to
3
+ * the operations that carry it out.
4
+ *
5
+ * Planners mint the ids their operations create and enforce the interaction
6
+ * limits, but they hold no state and apply nothing. That split is what lets the
7
+ * same intent vocabulary serve two embeddings — a `DockController` that keeps the
8
+ * state itself, and a host store that keeps it and only needs the operations —
9
+ * without either one reimplementing `openContent`'s identity lookup, `dropTab`'s
10
+ * region resolution, or the floating cascade.
11
+ *
12
+ * A planner returning no operations means the intent changes nothing; the caller
13
+ * records nothing and notifies nobody.
14
+ */
15
+ import type { DockMode, DockZone, FloatRect, LayoutOp, LayoutState, PaneId, SplitId, TabId } from '../contract/types.ts';
16
+ import type { TabFactory } from './initial.ts';
17
+ /** Mints ids for the operations a planner produces: the one place a string becomes an id. */
18
+ export interface Mint {
19
+ (prefix: 'tab'): TabId;
20
+ (prefix: 'pane' | 'float'): PaneId;
21
+ (prefix: 'split'): SplitId;
22
+ }
23
+ /** Where a new tab should go and what it should say. */
24
+ export interface OpenContentInput {
25
+ /** Consistency id: with `kind`, the identity opening twice focuses instead of adding to. */
26
+ readonly contentId: string;
27
+ readonly title: string;
28
+ readonly kind: string;
29
+ /** Target pane; defaults to the active docked pane. */
30
+ readonly paneId?: PaneId;
31
+ /** Strip slot in the target pane; defaults to its end. */
32
+ readonly index?: number;
33
+ /**
34
+ * Whether a tab already showing this (kind, contentId) is focused instead of
35
+ * a second one being opened. Defaults to `true`.
36
+ */
37
+ readonly revealIfOpened?: boolean;
38
+ }
39
+ /** An intent that both acts and names the tab it settled on. */
40
+ export interface PlannedTab {
41
+ readonly ops: readonly LayoutOp[];
42
+ /** The tab the intent focused or created. */
43
+ readonly tabId: TabId;
44
+ }
45
+ /**
46
+ * First tab in one pane carrying `contentId`, in strip order.
47
+ * @param state - current layout.
48
+ * @param paneId - the pane to search, docked or floating.
49
+ * @param contentId - the content identity.
50
+ * @param kind - restrict to tabs of this kind; omit to match any kind.
51
+ * @returns the tab, or `undefined` when that pane shows no such content.
52
+ */
53
+ export declare function findPaneContentTab(state: LayoutState, paneId: PaneId, contentId: string, kind?: string): TabId | undefined;
54
+ /**
55
+ * First tab carrying `contentId`, searched docked panes first, in visual order.
56
+ * @param state - current layout.
57
+ * @param contentId - the content identity.
58
+ * @param kind - restrict to tabs of this kind; omit to match any kind.
59
+ * @returns the tab, or `undefined` when nothing shows the content.
60
+ */
61
+ export declare function findContentTab(state: LayoutState, contentId: string, kind?: string): TabId | undefined;
62
+ /**
63
+ * The pane a new tab lands in.
64
+ * @param state - current layout.
65
+ * @returns the active pane when docked, else the first docked pane.
66
+ */
67
+ export declare function activeDockPaneId(state: LayoutState): PaneId;
68
+ /**
69
+ * Expand or collapse the docked area.
70
+ * @param state - current layout.
71
+ * @param expanded - whether the docked area is shown.
72
+ * @returns the operation, or none when the value is already current.
73
+ */
74
+ export declare function planSetExpanded(state: LayoutState, expanded: boolean): readonly LayoutOp[];
75
+ /**
76
+ * Switch the presentation.
77
+ * @param state - current layout.
78
+ * @param mode - the presentation to record.
79
+ * @returns the operation, or none when the value is already current.
80
+ */
81
+ export declare function planSetMode(state: LayoutState, mode: DockMode): readonly LayoutOp[];
82
+ /**
83
+ * Split a pane to its right and seed the new pane.
84
+ * @param state - current layout.
85
+ * @param mint - id source for the pane, split, and seeded tab.
86
+ * @param paneId - pane to split; defaults to the active docked pane.
87
+ * @param makePaneTab - builds the seeded tab; omit to leave the new pane empty.
88
+ * @returns the operations, or none when the pane budget is spent.
89
+ */
90
+ export declare function planSplitPane(state: LayoutState, mint: Mint, paneId?: PaneId, makePaneTab?: TabFactory): readonly LayoutOp[];
91
+ /**
92
+ * Seat the embedder's seeded tab at the end of a docked pane's strip.
93
+ * @param state - current layout.
94
+ * @param mint - id source for the new tab.
95
+ * @param paneId - the pane whose strip asked; must be docked.
96
+ * @param makeTab - builds the seeded tab; omit to plan nothing.
97
+ * @returns the operations, or none when there is nothing to seat.
98
+ */
99
+ export declare function planAddTab(state: LayoutState, mint: Mint, paneId: PaneId, makeTab?: TabFactory): readonly LayoutOp[];
100
+ /**
101
+ * Open content, or focus the tab already showing it.
102
+ * @param state - current layout.
103
+ * @param mint - id source for a newly opened tab.
104
+ * @param input - identity, copy, and optional placement.
105
+ * @returns the operations plus the tab they settle on.
106
+ */
107
+ export declare function planOpenContent(state: LayoutState, mint: Mint, input: OpenContentInput): PlannedTab;
108
+ /**
109
+ * Open a second, independent tab on the same content, beside the original.
110
+ * @param state - current layout.
111
+ * @param mint - id source for the copy.
112
+ * @param tabId - tab to copy.
113
+ * @returns the operations plus the new tab's id.
114
+ */
115
+ export declare function planDuplicateTab(state: LayoutState, mint: Mint, tabId: TabId): PlannedTab;
116
+ /**
117
+ * Put a tab at an explicit strip slot: a reorder inside its own pane, otherwise a
118
+ * move, or a return when it currently floats.
119
+ * @param state - current layout.
120
+ * @param tabId - the tab being placed.
121
+ * @param toPaneId - destination docked pane.
122
+ * @param index - caret slot in the destination strip, counted over the chips as
123
+ * drawn — the dragged chip included when the destination is its own pane, so
124
+ * the slot just before or just after it is where it already sits.
125
+ * @returns the operations, or none when the placement changes nothing.
126
+ */
127
+ export declare function planPlaceTab(state: LayoutState, tabId: TabId, toPaneId: PaneId, index: number): readonly LayoutOp[];
128
+ /**
129
+ * Resolve a tab release on a pane body: the centre moves the tab in, an edge
130
+ * splits the pane and seats the tab in the new half. A pane's only tab released
131
+ * on that pane's centre changes nothing; released on its edge it splits, and
132
+ * the factory's tab backfills the pane the drag would otherwise empty — without
133
+ * a factory that release also changes nothing, since the split would empty the
134
+ * pane and seat the tab beside where it already was.
135
+ * @param state - current layout.
136
+ * @param mint - id source for a pane an edge release creates.
137
+ * @param tabId - the dragged tab.
138
+ * @param targetPaneId - pane under the pointer.
139
+ * @param zone - dock region the pointer released in.
140
+ * @param makeTab - builds the tab that backfills a pane its only tab splits away from.
141
+ * @returns the operations, or none when the release changes nothing.
142
+ */
143
+ export declare function planDropTab(state: LayoutState, mint: Mint, tabId: TabId, targetPaneId: PaneId, zone: DockZone, makeTab?: TabFactory): readonly LayoutOp[];
144
+ /**
145
+ * Take a tab out into a floating panel.
146
+ * @param state - current layout.
147
+ * @param mint - id source for the floating pane.
148
+ * @param tabId - tab to float.
149
+ * @param rect - explicit rectangle; defaults to a cascade from the last panel.
150
+ * @returns the operations plus the floating pane's id.
151
+ */
152
+ export declare function planFloatTab(state: LayoutState, mint: Mint, tabId: TabId, rect?: FloatRect): {
153
+ readonly ops: readonly LayoutOp[];
154
+ readonly paneId: PaneId;
155
+ };
156
+ /**
157
+ * Send a floating panel's tab back into the docked tree.
158
+ * @param state - current layout.
159
+ * @param paneId - the floating pane.
160
+ * @param toPaneId - destination docked pane; defaults to the active one.
161
+ * @returns the operations.
162
+ */
163
+ export declare function planUnfloatPane(state: LayoutState, paneId: PaneId, toPaneId?: PaneId): readonly LayoutOp[];
164
+ /**
165
+ * Record the net sizes of a divider drag, clamped to the pane minimum.
166
+ * @param splitId - the split whose divider moved.
167
+ * @param sizes - the fractions the drag reached.
168
+ * @param minimum - smallest pane share; defaults to the kit's fraction.
169
+ * @returns the resize operation.
170
+ */
171
+ export declare function planResizeSplit(splitId: SplitId, sizes: readonly number[], minimum?: number): readonly LayoutOp[];
172
+ /**
173
+ * Keep the docked area populated after an intent: drop every docked pane the
174
+ * intent left empty, and when the surviving root pane is itself empty, seed it.
175
+ *
176
+ * A pane empties when its last tab is closed, moved out, or floated; each such
177
+ * pane is merged away, innermost first, until none remains. The root pane cannot
178
+ * be merged, so it is reseeded instead — with the factory's tab, or left empty
179
+ * when the embedder supplies none. The returned operations continue the intent
180
+ * they follow, so a caller records both as one entry.
181
+ * @param state - the layout after the intent's own operations.
182
+ * @param mint - id source for the reseeded tab.
183
+ * @param makeTab - builds the tab an emptied root pane is reseeded with.
184
+ * @returns the follow-up operations, or none when every docked pane holds a tab.
185
+ */
186
+ export declare function planSettle(state: LayoutState, mint: Mint, makeTab?: TabFactory): readonly LayoutOp[];
187
+ //# sourceMappingURL=planner.d.ts.map