@n-uf/placement 26.11.9 → 26.11.11
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.
- package/CHANGELOG.md +47 -0
- package/README.md +104 -11
- package/dist/{chunk-XUV6MJ2P.js → chunk-2H3CSPEH.js} +38 -4
- package/dist/chunk-2H3CSPEH.js.map +1 -0
- package/dist/{chunk-PWQWD2CS.js → chunk-CJA6LRHN.js} +283 -34
- package/dist/chunk-CJA6LRHN.js.map +1 -0
- package/dist/desk.d.ts +12 -6
- package/dist/desk.js +35 -7
- package/dist/desk.js.map +1 -1
- package/dist/panels.d.ts +12 -3
- package/dist/panels.js +14 -2
- package/dist/{targets-DwOTs4UC.d.ts → targets-B_U2Zf7x.d.ts} +180 -27
- package/dist/targets.d.ts +1 -1
- package/dist/targets.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-PWQWD2CS.js.map +0 -1
- package/dist/chunk-XUV6MJ2P.js.map +0 -1
|
@@ -4,13 +4,32 @@ import { S as Size, R as Rect, P as Point } from './geometry-mL-GTRti.js';
|
|
|
4
4
|
* The panels model: plain data and the pure changes on it.
|
|
5
5
|
*
|
|
6
6
|
* Panels have string ids. Each side holds full-height columns (outer edge first), each column one or more panels
|
|
7
|
-
* top to bottom and its own width.
|
|
7
|
+
* top to bottom and its own width. Opt-in, the top and bottom edges hold a band each: its panels side by side, left to
|
|
8
|
+
* right, sharing its width, at its own height. A panel may instead float, in page space (it moves with the page) or pinned in
|
|
8
9
|
* view space (it stays put). A logical clock per panel (opened, used) is what give-way reads; every change here that
|
|
9
10
|
* counts as a use moves it on. Nothing here reads a host clock: the next tick is one past the latest in the state.
|
|
10
11
|
*/
|
|
11
12
|
|
|
12
13
|
type Side = "left" | "right";
|
|
13
14
|
declare const SIDES: readonly Side[];
|
|
15
|
+
/** A band's edge: a horizontal dock along the stage's top or bottom (opt-in, `PanelsOptions.bands`). */
|
|
16
|
+
type Edge = "top" | "bottom";
|
|
17
|
+
declare const EDGES: readonly Edge[];
|
|
18
|
+
/** Where a panel may dock: a side's columns or an edge's band. */
|
|
19
|
+
type Place = Side | Edge;
|
|
20
|
+
/** A band's height limits and natural height when a def gives none. */
|
|
21
|
+
declare const BAND_SIZE: {
|
|
22
|
+
readonly min: number;
|
|
23
|
+
readonly max: number;
|
|
24
|
+
readonly natural: number;
|
|
25
|
+
};
|
|
26
|
+
/** How an edge's band lies: "reserved" shortens the pages, "overlay" lies over them; between the columns, or full width. */
|
|
27
|
+
interface BandOption {
|
|
28
|
+
readonly mode: "reserved" | "overlay";
|
|
29
|
+
readonly span: "between" | "full";
|
|
30
|
+
}
|
|
31
|
+
/** Room kept clear along the pages' edges, px. */
|
|
32
|
+
type Reserve = Readonly<Partial<Record<"top" | "right" | "bottom" | "left", number>>>;
|
|
14
33
|
/**
|
|
15
34
|
* What a consumer says about a panel: its width limits docked, its size limits floating, and where it may go. No
|
|
16
35
|
* words: names and titles are the consumer's.
|
|
@@ -37,8 +56,14 @@ interface PanelDef {
|
|
|
37
56
|
readonly min: Size;
|
|
38
57
|
readonly natural: Size;
|
|
39
58
|
};
|
|
40
|
-
/** Where it may dock (default: both sides). */
|
|
41
|
-
readonly sides?: readonly
|
|
59
|
+
/** Where it may dock (default: both sides, and every edge that has a band). */
|
|
60
|
+
readonly sides?: readonly Place[];
|
|
61
|
+
/** A band's height limits and natural height (default `BAND_SIZE`: min 120, max 480, natural 200). */
|
|
62
|
+
readonly band?: {
|
|
63
|
+
readonly min: number;
|
|
64
|
+
readonly max: number;
|
|
65
|
+
readonly natural: number;
|
|
66
|
+
};
|
|
42
67
|
/** May it float (default: yes). */
|
|
43
68
|
readonly floats?: boolean;
|
|
44
69
|
}
|
|
@@ -59,6 +84,11 @@ interface FloatAt {
|
|
|
59
84
|
readonly rect: Rect;
|
|
60
85
|
readonly pinned?: boolean;
|
|
61
86
|
}
|
|
87
|
+
/** A band: its panels left to right, sharing its width, and its stored height (the layout clamps it to their limits). */
|
|
88
|
+
interface Band {
|
|
89
|
+
readonly panels: readonly string[];
|
|
90
|
+
readonly height: number;
|
|
91
|
+
}
|
|
62
92
|
/** Logical times: when a panel was last opened, and last used (opened, focused, moved or unfolded). */
|
|
63
93
|
interface Clock {
|
|
64
94
|
readonly opened: number;
|
|
@@ -76,6 +106,8 @@ interface PanelsState {
|
|
|
76
106
|
/** Not shown at all (they keep their place, for when they open again). */
|
|
77
107
|
readonly closed: readonly string[];
|
|
78
108
|
readonly clock: Readonly<Record<string, Clock>>;
|
|
109
|
+
/** Each edge's band (absent: no band panels). An emptied band goes from the state. */
|
|
110
|
+
readonly bands?: Readonly<Partial<Record<Edge, Band>>>;
|
|
79
111
|
}
|
|
80
112
|
/** The page's offset and scale in the view: a page point p shows at `x + p.x * scale`, `y + p.y * scale`. */
|
|
81
113
|
interface View {
|
|
@@ -117,16 +149,26 @@ interface PanelsOptions {
|
|
|
117
149
|
readonly railInset: number;
|
|
118
150
|
/** A tabbed column's strip height (default 28). */
|
|
119
151
|
readonly tabs: number;
|
|
152
|
+
/** Which edges have a band, and how it lies (default: none). */
|
|
153
|
+
readonly bands: Readonly<Partial<Record<Edge, BandOption>>>;
|
|
154
|
+
/** The pages' minimum height; only bands give way to it (default 240). */
|
|
155
|
+
readonly pagesMinHeight: number;
|
|
156
|
+
/** Room kept clear at the pages' edges for a toolbar the app draws, px (default: none). */
|
|
157
|
+
readonly reserve: Reserve;
|
|
120
158
|
}
|
|
121
159
|
declare const DEFAULT_PANELS_OPTIONS: PanelsOptions;
|
|
122
160
|
/** A float's size when its def gives none: this tall, and never smaller than FLOAT_MIN. */
|
|
123
161
|
declare const FLOAT_HEIGHT = 360;
|
|
124
162
|
declare const FLOAT_MIN: Size;
|
|
125
|
-
/** Where a panel is: a column (side and index), floating, or nowhere. */
|
|
163
|
+
/** Where a panel is: a column (side and index), a band (edge and index, left to right), floating, or nowhere. */
|
|
126
164
|
type Where = {
|
|
127
165
|
readonly kind: "column";
|
|
128
166
|
readonly side: Side;
|
|
129
167
|
readonly index: number;
|
|
168
|
+
} | {
|
|
169
|
+
readonly kind: "band";
|
|
170
|
+
readonly edge: Edge;
|
|
171
|
+
readonly index: number;
|
|
130
172
|
} | {
|
|
131
173
|
readonly kind: "float";
|
|
132
174
|
readonly float: FloatAt;
|
|
@@ -142,15 +184,26 @@ declare function floatSize(def: PanelDef | undefined): {
|
|
|
142
184
|
min: Size;
|
|
143
185
|
natural: Size;
|
|
144
186
|
};
|
|
187
|
+
/** A band's height limits and natural height from a def (`BAND_SIZE` when it gives none). */
|
|
188
|
+
declare const bandSize: (def: PanelDef | undefined) => {
|
|
189
|
+
min: number;
|
|
190
|
+
max: number;
|
|
191
|
+
natural: number;
|
|
192
|
+
};
|
|
193
|
+
/** A band's height as the layout takes it: its stored height clamped to its panels' limits (the largest min, the smallest max). */
|
|
194
|
+
declare function bandHeight(defs: readonly PanelDef[] | undefined, band: Band): number;
|
|
145
195
|
/**
|
|
146
196
|
* A panel's own width, for a new column made for it: the width of the column it is in, clamped to its own limits;
|
|
147
|
-
* floating or nowhere, its natural width.
|
|
197
|
+
* in a band, floating or nowhere, its natural width.
|
|
148
198
|
*/
|
|
149
199
|
declare function ownWidth(defs: readonly PanelDef[], state: PanelsState, id: string): number;
|
|
150
200
|
interface PanelsStart {
|
|
151
201
|
/** Each side's columns from the outer edge inward, each a list of panel ids top to bottom. */
|
|
152
202
|
readonly left?: readonly (readonly string[])[];
|
|
153
203
|
readonly right?: readonly (readonly string[])[];
|
|
204
|
+
/** Each edge's band, its panels left to right (it takes the tallest natural band height, within their limits). */
|
|
205
|
+
readonly top?: readonly string[];
|
|
206
|
+
readonly bottom?: readonly string[];
|
|
154
207
|
/** Floating panels: where (page space, or view space when pinned); the size defaults to the def's natural size. */
|
|
155
208
|
readonly floats?: readonly {
|
|
156
209
|
readonly id: string;
|
|
@@ -166,39 +219,65 @@ interface PanelsStart {
|
|
|
166
219
|
}
|
|
167
220
|
/**
|
|
168
221
|
* A state from a plain start: each column as wide as the widest natural width of its panels (within their limits),
|
|
169
|
-
* each float its natural size. The clock counts up in the order the panels are listed (left, right,
|
|
170
|
-
* last one listed is the newest.
|
|
222
|
+
* each float its natural size. The clock counts up in the order the panels are listed (left, right, top, bottom,
|
|
223
|
+
* floats), so the last one listed is the newest.
|
|
171
224
|
*/
|
|
172
225
|
declare function createPanels(defs: readonly PanelDef[], start: PanelsStart): PanelsState;
|
|
173
|
-
/**
|
|
226
|
+
/**
|
|
227
|
+
* The state with `id` taken out of its column (an emptied column goes), its band (an emptied band goes, and its height
|
|
228
|
+
* is forgotten) or the floats. Nothing else changes.
|
|
229
|
+
*/
|
|
174
230
|
declare function liftPanel(state: PanelsState, id: string): PanelsState;
|
|
175
231
|
/**
|
|
176
232
|
* Open a panel: it shows again where it was, and it is the newest opened and used. A panel placed nowhere goes into
|
|
177
|
-
* a new innermost column on `at.side`, `at.width` wide
|
|
178
|
-
*
|
|
233
|
+
* a new innermost column on `at.side`, `at.width` wide, or with `at.edge` at the right end of that edge's band (a new
|
|
234
|
+
* band is `at.height` tall, default `BAND_SIZE.natural`; the layout clamps it); without `at` it stays placed nowhere.
|
|
235
|
+
* In a tabbed column it becomes the tab that shows, as a drop into the column does.
|
|
179
236
|
*/
|
|
180
237
|
declare function open(state: PanelsState, id: string, at?: {
|
|
181
238
|
readonly side: Side;
|
|
182
239
|
readonly width: number;
|
|
240
|
+
} | {
|
|
241
|
+
readonly edge: Edge;
|
|
242
|
+
readonly height?: number;
|
|
183
243
|
}): PanelsState;
|
|
184
244
|
/** Close a panel: it isn't shown, keeps its place, and is no longer kept open. */
|
|
185
245
|
declare const close: (state: PanelsState, id: string) => PanelsState;
|
|
186
246
|
/** Focus a panel: it is the newest used; a float comes to the top. */
|
|
187
247
|
declare function focus(state: PanelsState, id: string): PanelsState;
|
|
188
|
-
/**
|
|
248
|
+
/**
|
|
249
|
+
* Fold a panel to its title bar by hand, or unfold it (unfolding is a use). A band folds as a whole: on a band panel
|
|
250
|
+
* all its panels go into `folded`, or (when every shown panel of the band is folded) all come out.
|
|
251
|
+
*/
|
|
189
252
|
declare function toggleFold(state: PanelsState, id: string): PanelsState;
|
|
190
|
-
/** Keep a docked panel open (its column gives way last), or stop keeping it. A floating panel isn't kept. */
|
|
253
|
+
/** Keep a docked panel open (its column or band gives way last), or stop keeping it. A floating panel isn't kept. */
|
|
191
254
|
declare function keep(state: PanelsState, id: string, on: boolean): PanelsState;
|
|
255
|
+
/**
|
|
256
|
+
* Dock a panel in the band on `edge`, at `index` (0 the leftmost; past the end, the rightmost). A new band takes the
|
|
257
|
+
* panel's natural band height (with `defs`; else `BAND_SIZE.natural`). It shows (a band folded by hand unfolds), it is
|
|
258
|
+
* the newest used, and it keeps whether it is kept open.
|
|
259
|
+
*/
|
|
260
|
+
declare function dockBand(state: PanelsState, id: string, edge: Edge, index: number, defs?: readonly PanelDef[]): PanelsState;
|
|
261
|
+
/** Store a band's height (the layout clamps it to its panels' limits). Resizing is a use, as for a column. */
|
|
262
|
+
declare function resizeBand(state: PanelsState, edge: Edge, height: number): PanelsState;
|
|
192
263
|
interface DockOptions {
|
|
193
264
|
/** Stack into the column at `index` (at its bottom) instead of making a new column there. */
|
|
194
265
|
readonly into?: boolean;
|
|
195
|
-
/**
|
|
266
|
+
/**
|
|
267
|
+
* With `into`: the panel goes before the column's member at this index (0 the top; past the end, or left out, the
|
|
268
|
+
* bottom), counted once the panel is lifted out.
|
|
269
|
+
*/
|
|
270
|
+
readonly at?: number;
|
|
271
|
+
/**
|
|
272
|
+
* A new column's width (default: the width of the column the panel leaves, else 0, which the layout clamps to the
|
|
273
|
+
* minimum; from a band, pass `ownWidth` for its natural width, as the drop targets do).
|
|
274
|
+
*/
|
|
196
275
|
readonly width?: number;
|
|
197
276
|
}
|
|
198
277
|
/**
|
|
199
|
-
* Dock a panel on `side`: a new column at `index` (0 the outer edge; past the end, innermost), or with `into`
|
|
200
|
-
*
|
|
201
|
-
* keeps whether it is kept open.
|
|
278
|
+
* Dock a panel on `side`: a new column at `index` (0 the outer edge; past the end, innermost), or with `into` in the
|
|
279
|
+
* column at `index` (counted once the panel is lifted out), at its bottom or before the member `at`. It shows, it is
|
|
280
|
+
* the newest used, and it keeps whether it is kept open.
|
|
202
281
|
*/
|
|
203
282
|
declare function dock(state: PanelsState, id: string, side: Side, index: number, options?: DockOptions): PanelsState;
|
|
204
283
|
/** Show a column's panels as tabs (one at a time under a strip), or as a stack again. */
|
|
@@ -265,15 +344,16 @@ declare function samePlaces(a: PanelsState, b: PanelsState, defs?: readonly Pane
|
|
|
265
344
|
*/
|
|
266
345
|
|
|
267
346
|
/**
|
|
268
|
-
* Where a panel is, structurally: an open part of a column, a folded title bar (in a column,
|
|
269
|
-
* folded float), a segment of a rail (the panel itself isn't laid out), or a
|
|
347
|
+
* Where a panel is, structurally: an open part of a column, an open part of a band, a folded title bar (in a column,
|
|
348
|
+
* riding on one, in a folded band, or a folded float), a segment of a rail (the panel itself isn't laid out), or a
|
|
349
|
+
* float.
|
|
270
350
|
*/
|
|
271
|
-
type PanelKind = "column" | "bar" | "segment" | "float";
|
|
351
|
+
type PanelKind = "column" | "band" | "bar" | "segment" | "float";
|
|
272
352
|
interface PlacedPanel {
|
|
273
353
|
/** Stage px; for a segment, the segment's rect in its rail. */
|
|
274
354
|
readonly rect: Rect;
|
|
275
355
|
readonly kind: PanelKind;
|
|
276
|
-
/** Columns and
|
|
356
|
+
/** Columns, rails and reserved bands 0, overlay bands 5, floats 10 and up (a later float on top). */
|
|
277
357
|
readonly layer: number;
|
|
278
358
|
/** Not drawn as a panel: in a rail (only its segment shows), or a tab that isn't showing (only its `tab`). */
|
|
279
359
|
readonly hidden: boolean;
|
|
@@ -294,7 +374,32 @@ interface PlacedPanel {
|
|
|
294
374
|
readonly tab?: Rect;
|
|
295
375
|
/** A float the clamp moved or resized. */
|
|
296
376
|
readonly clamped?: boolean;
|
|
377
|
+
/** In a band: its edge and its index in the state's band (left to right). */
|
|
378
|
+
readonly edge?: Edge;
|
|
379
|
+
readonly index?: number;
|
|
297
380
|
}
|
|
381
|
+
/** A band as laid out. */
|
|
382
|
+
interface PlacedBand {
|
|
383
|
+
readonly edge: Edge;
|
|
384
|
+
/** The band's rect (a bar when folded). */
|
|
385
|
+
readonly rect: Rect;
|
|
386
|
+
/** Its stored height clamped to its panels' limits, and those limits. */
|
|
387
|
+
readonly height: number;
|
|
388
|
+
readonly min: number;
|
|
389
|
+
readonly max: number;
|
|
390
|
+
/** null: open; "hand": its panels folded by hand; "auto": folded by give-way. */
|
|
391
|
+
readonly folded: null | "hand" | "auto";
|
|
392
|
+
/** Shrunk by give-way below its height. */
|
|
393
|
+
readonly shrunk: boolean;
|
|
394
|
+
/** It holds a kept panel. */
|
|
395
|
+
readonly kept: boolean;
|
|
396
|
+
readonly mode: "reserved" | "overlay";
|
|
397
|
+
readonly span: "between" | "full";
|
|
398
|
+
/** The shown panels, left to right. */
|
|
399
|
+
readonly panels: readonly string[];
|
|
400
|
+
}
|
|
401
|
+
/** A reserve's edge. */
|
|
402
|
+
type ReserveEdge = "top" | "right" | "bottom" | "left";
|
|
298
403
|
interface PlacedColumn {
|
|
299
404
|
readonly side: Side;
|
|
300
405
|
/** The column's index in the state. */
|
|
@@ -329,8 +434,8 @@ interface PlacedRail {
|
|
|
329
434
|
readonly rect: Rect;
|
|
330
435
|
}[];
|
|
331
436
|
}
|
|
332
|
-
type PanelsNoteCode = "column-shrunk" | "column-folded" | "kept-folded" | "section-folded" | "pages-under-min" | "float-clamped" | "float-resized";
|
|
333
|
-
/** One note on a layout: a code and its data. */
|
|
437
|
+
type PanelsNoteCode = "column-shrunk" | "column-folded" | "kept-folded" | "section-folded" | "pages-under-min" | "float-clamped" | "float-resized" | "band-shrunk" | "band-folded" | "band-off" | "pages-short";
|
|
438
|
+
/** One note on a layout: a code and its data. `kept-folded` carries `side` and `column` for a column, `edge` for a band. */
|
|
334
439
|
type PanelsNote = {
|
|
335
440
|
readonly code: "column-shrunk";
|
|
336
441
|
readonly side: Side;
|
|
@@ -350,6 +455,20 @@ type PanelsNote = {
|
|
|
350
455
|
} | {
|
|
351
456
|
readonly code: "float-clamped" | "float-resized";
|
|
352
457
|
readonly items: readonly string[];
|
|
458
|
+
} | {
|
|
459
|
+
readonly code: "band-shrunk";
|
|
460
|
+
readonly edge: Edge;
|
|
461
|
+
readonly items: readonly string[];
|
|
462
|
+
readonly from: number;
|
|
463
|
+
readonly to: number;
|
|
464
|
+
} | {
|
|
465
|
+
readonly code: "band-folded" | "kept-folded" | "band-off";
|
|
466
|
+
readonly edge: Edge;
|
|
467
|
+
readonly items: readonly string[];
|
|
468
|
+
} | {
|
|
469
|
+
readonly code: "pages-short";
|
|
470
|
+
readonly height: number;
|
|
471
|
+
readonly min: number;
|
|
353
472
|
};
|
|
354
473
|
interface PanelsLayout {
|
|
355
474
|
readonly items: Map<string, PlacedPanel>;
|
|
@@ -359,6 +478,10 @@ interface PanelsLayout {
|
|
|
359
478
|
readonly notes: readonly PanelsNote[];
|
|
360
479
|
/** What is left for the documents. */
|
|
361
480
|
readonly pages: Rect;
|
|
481
|
+
/** The bands laid out (an enabled edge with shown panels). */
|
|
482
|
+
readonly bands: Readonly<Partial<Record<Edge, PlacedBand>>>;
|
|
483
|
+
/** The room kept clear along the pages' edges (an edge with a reserve over 0). */
|
|
484
|
+
readonly reserved: Readonly<Partial<Record<ReserveEdge, Rect>>>;
|
|
362
485
|
}
|
|
363
486
|
/** The order columns give way in: unkept before kept, then the policy (oldest or newest), outer first, left first. */
|
|
364
487
|
declare function giveWayOrder<C extends {
|
|
@@ -390,14 +513,22 @@ interface Target {
|
|
|
390
513
|
* - `column:<side>:<i>` (priority 2): a band across the line between two columns (or a side's edge): a new column
|
|
391
514
|
* there, as wide as the panel's own width.
|
|
392
515
|
* - `into:<side>:<i>` (2): a column's area: the panel stacks at its bottom.
|
|
516
|
+
* - `into:<side>:<i>:<k>` (2), opt-in (`stackSlots`): before the stacked column's member k. The column's area is split
|
|
517
|
+
* at its members' middles: the top half of member k (and the lower half of the one above) goes before k, and
|
|
518
|
+
* `into:<side>:<i>` keeps only what lies below the last member's middle. `marker` is the line where the panel's top
|
|
519
|
+
* lands after the drop, for the app to draw. k counts closed members too (they keep their place in the column's
|
|
520
|
+
* list); only the members shown get slots. A tabbed column keeps its one `into` target.
|
|
393
521
|
* - `rail:<side>` (1): the side's rail, or its outer edge: the panel docks folded.
|
|
394
522
|
* - `float` (3, free): anywhere; it floats where it is let go, kept in the view as the float option says.
|
|
523
|
+
* - `band:<edge>:<i>` (2), for each edge with a band (`options.bands`): the slots between a band's panels and at both
|
|
524
|
+
* ends (the band's area split at its panels' middles). `band:<edge>` (2): an empty enabled edge, a strip `2 × bar`
|
|
525
|
+
* tall along it inside the pages' area.
|
|
395
526
|
*
|
|
396
527
|
* A place the panel may not take (its def's `sides` and `floats`, and `allows`) is no target, and neither is its own
|
|
397
528
|
* place (a drop there changes nothing). Targets carry a structured `place`, never words: the consumer names them.
|
|
398
529
|
*/
|
|
399
530
|
|
|
400
|
-
/** Where a drop puts a panel. `index` is a column index in the state with the panel lifted out. */
|
|
531
|
+
/** Where a drop puts a panel. `index` is a column (or band panel) index in the state with the panel lifted out. */
|
|
401
532
|
type PanelPlace = {
|
|
402
533
|
readonly kind: "column";
|
|
403
534
|
readonly side: Side;
|
|
@@ -406,9 +537,15 @@ type PanelPlace = {
|
|
|
406
537
|
readonly kind: "into";
|
|
407
538
|
readonly side: Side;
|
|
408
539
|
readonly index: number;
|
|
540
|
+
/** Before the column's member at this index (in the state with the panel lifted out); left out: at its bottom. */
|
|
541
|
+
readonly at?: number;
|
|
409
542
|
} | {
|
|
410
543
|
readonly kind: "rail";
|
|
411
544
|
readonly side: Side;
|
|
545
|
+
} | {
|
|
546
|
+
readonly kind: "band";
|
|
547
|
+
readonly edge: Edge;
|
|
548
|
+
readonly index: number;
|
|
412
549
|
} | {
|
|
413
550
|
readonly kind: "float";
|
|
414
551
|
};
|
|
@@ -420,6 +557,12 @@ interface PanelTarget extends Target {
|
|
|
420
557
|
readonly order: number;
|
|
421
558
|
/** The state a drop here makes, with the pointer at `p` holding the panel at `grab` from its top-left corner. */
|
|
422
559
|
readonly make: (p: Point, grab: Point) => PanelsState;
|
|
560
|
+
/**
|
|
561
|
+
* With `stackSlots`, on `into` targets of a stacked column: the line where the panel's top lands after the drop (the
|
|
562
|
+
* column re-shares its height, so this is the drop's layout, not today's gap), as a rect zero tall and as wide as
|
|
563
|
+
* the column. `panelDrop(...).slot` is the whole rect.
|
|
564
|
+
*/
|
|
565
|
+
readonly marker?: Rect;
|
|
423
566
|
}
|
|
424
567
|
interface PanelTargetInput {
|
|
425
568
|
readonly defs: readonly PanelDef[];
|
|
@@ -430,14 +573,24 @@ interface PanelTargetInput {
|
|
|
430
573
|
readonly options?: Partial<PanelsOptions>;
|
|
431
574
|
/** Places the panel may go beyond its def's rules (default: all of them). */
|
|
432
575
|
readonly allows?: (id: string, place: PanelPlace) => boolean;
|
|
576
|
+
/** Drops into a stacked column may go before any of its members (`into` targets with `at`); default: the bottom only. */
|
|
577
|
+
readonly stackSlots?: boolean;
|
|
433
578
|
}
|
|
434
579
|
/** How far a column band reaches on each side of its line, px; how wide a side's edge takes a rail drop when it has no rail. */
|
|
435
580
|
declare const COLUMN_REACH = 22;
|
|
436
581
|
declare const RAIL_EDGE = 10;
|
|
437
|
-
/**
|
|
582
|
+
/**
|
|
583
|
+
* A place's rank in reading order: the left side outer to inner, the right side inner to outer, then the top band and
|
|
584
|
+
* the bottom band left to right, floating last.
|
|
585
|
+
*/
|
|
438
586
|
declare function placeRank(place: PanelPlace): number;
|
|
439
|
-
/**
|
|
440
|
-
|
|
587
|
+
/**
|
|
588
|
+
* Where a panel is now, as a place (a float, a column of its own, or stacked in one); null when placed nowhere. With
|
|
589
|
+
* `stackSlots`, a panel stacked in a column says its position there as `at` (a tabbed column's panel never does).
|
|
590
|
+
*/
|
|
591
|
+
declare function homePlace(state: PanelsState, id: string, options?: {
|
|
592
|
+
readonly stackSlots?: boolean;
|
|
593
|
+
}): PanelPlace | null;
|
|
441
594
|
/** The targets for dragging `input.id`, in reading order. */
|
|
442
595
|
declare function panelTargets(input: PanelTargetInput): PanelTarget[];
|
|
443
596
|
/** A target's drop, laid out: where the panel lands. */
|
|
@@ -480,4 +633,4 @@ interface PanelStopsOptions {
|
|
|
480
633
|
/** The panel's places in reading order, for the arrow keys and a "Move to" menu (`keyboardStops` calls this). */
|
|
481
634
|
declare function panelStops(targets: readonly PanelTarget[], options?: PanelStopsOptions): PanelStop[];
|
|
482
635
|
|
|
483
|
-
export {
|
|
636
|
+
export { floatSize as $, type PlacedPanel as A, BAND_SIZE as B, type Clock as C, DEFAULT_PANELS_OPTIONS as D, type Edge as E, FLOAT_HEIGHT as F, type GiveWay as G, type PlacedRail as H, IDENTITY_VIEW as I, type Reserve as J, type ReserveEdge as K, SIDES as L, activate as M, bandHeight as N, bandSize as O, type PanelsOptions as P, close as Q, RAIL_EDGE as R, type Side as S, columnWidth as T, createPanels as U, type View as V, type Where as W, defOf as X, dock as Y, dockBand as Z, float as _, type PanelDef as a, focus as a0, giveWayOrder as a1, homePlace as a2, keep as a3, liftPanel as a4, open as a5, ownWidth as a6, panelStops as a7, panelTargets as a8, pin as a9, placeRank as aa, resizeBand as ab, resizeColumn as ac, resizeFloat as ad, samePlaces as ae, showTabs as af, tick as ag, toPage as ah, toView as ai, toggleFold as aj, whereIs as ak, type Target as al, type PanelsState as b, type PanelTargetInput as c, type PanelTarget as d, type PanelDrop as e, type PanelsLayout as f, type Band as g, type BandOption as h, COLUMN_REACH as i, type Column as j, type DockOptions as k, layoutPanels as l, EDGES as m, FLOAT_MIN as n, type FloatAt as o, panelDrop as p, type PanelKind as q, type PanelPlace as r, type PanelStop as s, type PanelStopsOptions as t, type PanelsNote as u, type PanelsNoteCode as v, type PanelsStart as w, type Place as x, type PlacedBand as y, type PlacedColumn as z };
|
package/dist/targets.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { al as Target, d as PanelTarget, t as PanelStopsOptions, s as PanelStop } from './targets-B_U2Zf7x.js';
|
|
2
2
|
import { R as Rect, P as Point, S as Size } from './geometry-mL-GTRti.js';
|
|
3
3
|
import { D as DeskState, g as Layout, a as Construction, O as Options } from './constructions-VDK_mwmz.js';
|
|
4
4
|
import { Place, Arrangement, HostId, HostSpec, GroupSize } from './toolbar.js';
|
package/dist/targets.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@n-uf/placement",
|
|
3
|
-
"version": "26.11.
|
|
3
|
+
"version": "26.11.11",
|
|
4
4
|
"description": "Where things go: desk docks, rails and palettes, panel columns, toolbar groups, and the drop targets for each. Pure state in, rects out. No DOM, no framework, no motion.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"layout",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/panels/model.ts","../src/panels/layout.ts","../src/panels/targets.ts"],"sourcesContent":["/**\n * The panels model: plain data and the pure changes on it.\n *\n * Panels have string ids. Each side holds full-height columns (outer edge first), each column one or more panels\n * top to bottom and its own width. A panel may instead float, in page space (it moves with the page) or pinned in\n * view space (it stays put). A logical clock per panel (opened, used) is what give-way reads; every change here that\n * counts as a use moves it on. Nothing here reads a host clock: the next tick is one past the latest in the state.\n */\nimport type { Rect, Size } from \"../geometry\";\n\nexport type Side = \"left\" | \"right\";\nexport const SIDES: readonly Side[] = [\"left\", \"right\"];\n\n/**\n * What a consumer says about a panel: its width limits docked, its size limits floating, and where it may go. No\n * words: names and titles are the consumer's.\n */\nexport interface PanelDef {\n readonly id: string;\n /** A docked column's width limits and its natural width. */\n readonly width: { readonly min: number; readonly max: number; readonly natural: number };\n /**\n * Its height as a section of a stack column (opt-in): it gets its natural height, the column's last open section\n * takes the rest, and when the column is short sections fold to bars by give-way. Without it a section shares the\n * column's height equally with the others, as before.\n */\n readonly height?: { readonly min: number; readonly natural: number };\n /** A float's size limits and natural size (default: its natural width, 360 px tall, no smaller than 160 × 120). */\n readonly float?: { readonly min: Size; readonly natural: Size };\n /** Where it may dock (default: both sides). */\n readonly sides?: readonly Side[];\n /** May it float (default: yes). */\n readonly floats?: boolean;\n}\n\n/**\n * A full-height column: its panels top to bottom, and its stored width (the layout clamps it to its panels' limits).\n * `show` \"tabs\" shows one panel at a time under a strip of tabs: `active` (default, or when `active` isn't one of\n * them: the first panel in the column that isn't closed).\n */\nexport interface Column {\n readonly panels: readonly string[];\n readonly width: number;\n readonly show?: \"stack\" | \"tabs\";\n readonly active?: string;\n}\n\n/** A floating panel: `rect` in page space, or in view space when `pinned`. */\nexport interface FloatAt {\n readonly id: string;\n readonly rect: Rect;\n readonly pinned?: boolean;\n}\n\n/** Logical times: when a panel was last opened, and last used (opened, focused, moved or unfolded). */\nexport interface Clock {\n readonly opened: number;\n readonly used: number;\n}\n\nexport interface PanelsState {\n /** Each side's columns, from the outer edge inward. */\n readonly sides: Readonly<Record<Side, readonly Column[]>>;\n /** Floating panels; a later one is on top. */\n readonly floats: readonly FloatAt[];\n /** Folded by hand (give-way never writes this). */\n readonly folded: readonly string[];\n /** Docked panels kept open: their columns give way last. */\n readonly kept: readonly string[];\n /** Not shown at all (they keep their place, for when they open again). */\n readonly closed: readonly string[];\n readonly clock: Readonly<Record<string, Clock>>;\n}\n\n/** The page's offset and scale in the view: a page point p shows at `x + p.x * scale`, `y + p.y * scale`. */\nexport interface View {\n readonly x: number;\n readonly y: number;\n readonly scale: number;\n}\nexport const IDENTITY_VIEW: View = { x: 0, y: 0, scale: 1 };\n\n/** Who gives way first: the oldest or the newest, by when they were last used or last opened. */\nexport interface GiveWay {\n readonly order: \"oldest\" | \"newest\";\n readonly by: \"used\" | \"opened\";\n}\n\nexport interface PanelsOptions {\n /** Default: `{ order: \"oldest\", by: \"used\" }`, so the panel used longest ago gives way first. */\n readonly giveWay: GiveWay;\n /** \"clamp\" keeps floats in the view at layout time; \"free\" never moves them. Default \"clamp\". */\n readonly floats: \"clamp\" | \"free\";\n /**\n * Where a column folded by hand goes (default \"rail\"): to its side's rail, or (\"ride\") as title bars on top of the\n * side's first open column, until every column on that side is folded. Give-way's folds always go to the rail.\n */\n readonly fold: \"rail\" | \"ride\";\n /** How much of a float wider than the view stays in it, px (default 48). */\n readonly floatVisible: number;\n /** The pages' minimum width (default 320). */\n readonly pagesMin: number;\n /** The page's offset and scale (default: identity). */\n readonly view: View;\n /**\n * A title bar's height: a panel folded in a column, a folded float, a riding column, and the part of a float the\n * clamp keeps in the view (default 28).\n */\n readonly bar: number;\n /** A rail's width (default 36). */\n readonly rail: number;\n /** A rail segment's height, and the gap above the first one (defaults 36 and 4). */\n readonly segment: number;\n readonly railInset: number;\n /** A tabbed column's strip height (default 28). */\n readonly tabs: number;\n}\n\nexport const DEFAULT_PANELS_OPTIONS: PanelsOptions = {\n giveWay: { order: \"oldest\", by: \"used\" },\n floats: \"clamp\",\n fold: \"rail\",\n floatVisible: 48,\n pagesMin: 320,\n view: IDENTITY_VIEW,\n bar: 28,\n rail: 36,\n segment: 36,\n railInset: 4,\n tabs: 28,\n};\n\n/** A float's size when its def gives none: this tall, and never smaller than FLOAT_MIN. */\nexport const FLOAT_HEIGHT = 360;\nexport const FLOAT_MIN: Size = { width: 160, height: 120 };\n\n// --- reading the state ---------------------------------------------------------------------------------------------\n\nconst without = <T>(list: readonly T[], x: T): T[] => list.filter((y) => y !== x);\nconst withOnce = <T>(list: readonly T[], x: T): T[] => (list.includes(x) ? [...list] : [...list, x]);\n\n/** Where a panel is: a column (side and index), floating, or nowhere. */\nexport type Where = { readonly kind: \"column\"; readonly side: Side; readonly index: number } | { readonly kind: \"float\"; readonly float: FloatAt } | { readonly kind: \"none\" };\n\nexport function whereIs(state: PanelsState, id: string): Where {\n for (const side of SIDES) {\n const index = state.sides[side].findIndex((c) => c.panels.includes(id));\n if (index >= 0) return { kind: \"column\", side, index };\n }\n const float = state.floats.find((f) => f.id === id);\n return float ? { kind: \"float\", float } : { kind: \"none\" };\n}\n\n/** One past the latest logical time in the state. */\nexport const tick = (state: PanelsState): number => Object.values(state.clock).reduce((m, c) => Math.max(m, c.opened, c.used), 0) + 1;\n\nconst bump = (state: PanelsState, id: string, opened: boolean): PanelsState => {\n const t = tick(state);\n const was = state.clock[id] ?? { opened: 0, used: 0 };\n return { ...state, clock: { ...state.clock, [id]: { opened: opened ? t : was.opened, used: t } } };\n};\n\nexport const defOf = (defs: readonly PanelDef[], id: string): PanelDef | undefined => defs.find((d) => d.id === id);\n\n/** A float's size limits and natural size from its def. */\nexport function floatSize(def: PanelDef | undefined): { min: Size; natural: Size } {\n if (def?.float) return { min: def.float.min, natural: def.float.natural };\n const width = Math.max(FLOAT_MIN.width, def?.width.natural ?? FLOAT_MIN.width);\n return { min: FLOAT_MIN, natural: { width, height: FLOAT_HEIGHT } };\n}\n\n/**\n * A panel's own width, for a new column made for it: the width of the column it is in, clamped to its own limits;\n * floating or nowhere, its natural width.\n */\nexport function ownWidth(defs: readonly PanelDef[], state: PanelsState, id: string): number {\n const def = defOf(defs, id);\n const w = whereIs(state, id);\n const lo = def?.width.min ?? 0;\n const hi = Math.max(lo, def?.width.max ?? Infinity);\n if (w.kind === \"column\") return Math.min(Math.max(state.sides[w.side][w.index]!.width, lo), hi);\n return def?.width.natural ?? lo;\n}\n\n// --- building one --------------------------------------------------------------------------------------------------\n\nexport interface PanelsStart {\n /** Each side's columns from the outer edge inward, each a list of panel ids top to bottom. */\n readonly left?: readonly (readonly string[])[];\n readonly right?: readonly (readonly string[])[];\n /** Floating panels: where (page space, or view space when pinned); the size defaults to the def's natural size. */\n readonly floats?: readonly { readonly id: string; readonly x: number; readonly y: number; readonly width?: number; readonly height?: number; readonly pinned?: boolean }[];\n readonly folded?: readonly string[];\n readonly kept?: readonly string[];\n readonly closed?: readonly string[];\n}\n\n/**\n * A state from a plain start: each column as wide as the widest natural width of its panels (within their limits),\n * each float its natural size. The clock counts up in the order the panels are listed (left, right, floats), so the\n * last one listed is the newest.\n */\nexport function createPanels(defs: readonly PanelDef[], start: PanelsStart): PanelsState {\n const column = (ids: readonly string[]): Column => {\n const ds = ids.map((id) => defOf(defs, id));\n const lo = Math.max(0, ...ds.map((d) => d?.width.min ?? 0));\n const hi = Math.max(lo, Math.min(...ds.map((d) => d?.width.max ?? Infinity)));\n const natural = Math.max(0, ...ds.map((d) => d?.width.natural ?? 0));\n return { panels: [...ids], width: Math.min(Math.max(natural, lo), hi) };\n };\n const floats = (start.floats ?? []).map((f): FloatAt => {\n const n = floatSize(defOf(defs, f.id)).natural;\n return { id: f.id, rect: { x: f.x, y: f.y, width: f.width ?? n.width, height: f.height ?? n.height }, ...(f.pinned ? { pinned: true } : {}) };\n });\n const sides = { left: (start.left ?? []).map(column), right: (start.right ?? []).map(column) };\n const order = [...sides.left, ...sides.right].flatMap((c) => c.panels).concat(floats.map((f) => f.id));\n const clock: Record<string, Clock> = {};\n order.forEach((id, i) => (clock[id] = { opened: i + 1, used: i + 1 }));\n return { sides, floats, folded: [...(start.folded ?? [])], kept: [...(start.kept ?? [])], closed: [...(start.closed ?? [])], clock };\n}\n\n// --- changes -------------------------------------------------------------------------------------------------------\n\n/** The state with `id` taken out of its column (an emptied column goes) or the floats. Nothing else changes. */\nexport function liftPanel(state: PanelsState, id: string): PanelsState {\n // A tabbed column whose active panel leaves shows its first panel again.\n const out = (c: Column): Column => {\n const { active: _a, ...rest } = c;\n return { ...(c.active === id ? rest : c), panels: without(c.panels, id) };\n };\n const lift = (cols: readonly Column[]): Column[] => cols.map(out).filter((c) => c.panels.length > 0);\n return { ...state, sides: { left: lift(state.sides.left), right: lift(state.sides.right) }, floats: state.floats.filter((f) => f.id !== id) };\n}\n\n/**\n * Open a panel: it shows again where it was, and it is the newest opened and used. A panel placed nowhere goes into\n * a new innermost column on `at.side`, `at.width` wide; without `at` it stays placed nowhere. In a tabbed column it\n * becomes the tab that shows, as a drop into the column does.\n */\nexport function open(state: PanelsState, id: string, at?: { readonly side: Side; readonly width: number }): PanelsState {\n let s: PanelsState = { ...state, closed: without(state.closed, id) };\n if (at && whereIs(s, id).kind === \"none\") s = { ...s, sides: { ...s.sides, [at.side]: [...s.sides[at.side], { panels: [id], width: at.width }] } };\n const w = whereIs(s, id);\n if (w.kind === \"column\" && s.sides[w.side][w.index]!.show === \"tabs\") s = { ...s, sides: { ...s.sides, [w.side]: s.sides[w.side].map((c, i) => (i === w.index ? { ...c, active: id } : c)) } };\n return bump(s, id, true);\n}\n\n/** Close a panel: it isn't shown, keeps its place, and is no longer kept open. */\nexport const close = (state: PanelsState, id: string): PanelsState => ({ ...state, closed: withOnce(state.closed, id), kept: without(state.kept, id) });\n\n/** Focus a panel: it is the newest used; a float comes to the top. */\nexport function focus(state: PanelsState, id: string): PanelsState {\n const f = state.floats.find((x) => x.id === id);\n const s = f ? { ...state, floats: [...state.floats.filter((x) => x !== f), f] } : state;\n return bump(s, id, false);\n}\n\n/** Fold a panel to its title bar by hand, or unfold it (unfolding is a use). */\nexport function toggleFold(state: PanelsState, id: string): PanelsState {\n if (state.folded.includes(id)) return bump({ ...state, folded: without(state.folded, id) }, id, false);\n return { ...state, folded: [...state.folded, id] };\n}\n\n/** Keep a docked panel open (its column gives way last), or stop keeping it. A floating panel isn't kept. */\nexport function keep(state: PanelsState, id: string, on: boolean): PanelsState {\n if (!on) return { ...state, kept: without(state.kept, id) };\n return whereIs(state, id).kind === \"column\" ? { ...state, kept: withOnce(state.kept, id) } : state;\n}\n\nexport interface DockOptions {\n /** Stack into the column at `index` (at its bottom) instead of making a new column there. */\n readonly into?: boolean;\n /** A new column's width (default: the width of the column the panel leaves, else 0, which the layout clamps to the minimum). */\n readonly width?: number;\n}\n\n/**\n * Dock a panel on `side`: a new column at `index` (0 the outer edge; past the end, innermost), or with `into` at the\n * bottom of the column at `index` (counted once the panel is lifted out). It shows, it is the newest used, and it\n * keeps whether it is kept open.\n */\nexport function dock(state: PanelsState, id: string, side: Side, index: number, options: DockOptions = {}): PanelsState {\n const w = whereIs(state, id);\n const from = w.kind === \"column\" ? state.sides[w.side][w.index]!.width : 0;\n const s = liftPanel(state, id);\n const cols = [...s.sides[side]];\n // Into a tabbed column: a tab at the end, and the one showing.\n if (options.into && cols[index]) cols[index] = { ...cols[index]!, panels: [...cols[index]!.panels, id], ...(cols[index]!.show === \"tabs\" ? { active: id } : {}) };\n else {\n const at = Math.max(0, Math.min(index, cols.length));\n cols.splice(at, 0, { panels: [id], width: options.width ?? from });\n }\n return bump({ ...s, sides: { ...s.sides, [side]: cols }, closed: without(s.closed, id) }, id, false);\n}\n\n/** Show a column's panels as tabs (one at a time under a strip), or as a stack again. */\nexport function showTabs(state: PanelsState, side: Side, index: number, on: boolean): PanelsState {\n const col = state.sides[side][index];\n if (!col) return state;\n const { show: _s, ...stack } = col;\n return { ...state, sides: { ...state.sides, [side]: state.sides[side].map((c, i) => (i === index ? (on ? { ...col, show: \"tabs\" as const } : stack) : c)) } };\n}\n\n/** Make a docked panel the one its column shows (its tab), and the newest used. */\nexport function activate(state: PanelsState, id: string): PanelsState {\n const w = whereIs(state, id);\n if (w.kind !== \"column\") return state;\n const sides = { ...state.sides, [w.side]: state.sides[w.side].map((c, i) => (i === w.index ? { ...c, active: id } : c)) };\n return bump({ ...state, sides }, id, false);\n}\n\n/**\n * Float a panel at `rect` (page space; view space when pinned). A float stays pinned or not unless `pinned` says;\n * a docked panel floats unpinned. It shows, it is the newest used and on top, and it is no longer kept open.\n */\nexport function float(state: PanelsState, id: string, rect: Rect, pinned?: boolean): PanelsState {\n const was = state.floats.find((f) => f.id === id);\n const on = pinned ?? !!was?.pinned;\n const s = liftPanel(state, id);\n const f: FloatAt = { id, rect: { ...rect }, ...(on ? { pinned: true } : {}) };\n return bump({ ...s, floats: [...s.floats, f], kept: without(s.kept, id), closed: without(s.closed, id) }, id, false);\n}\n\n/** A page-space rect in view space, and back. */\nexport const toView = (r: Rect, v: View): Rect => ({ ...r, x: v.x + r.x * v.scale, y: v.y + r.y * v.scale });\nexport const toPage = (r: Rect, v: View): Rect => ({ ...r, x: (r.x - v.x) / v.scale, y: (r.y - v.y) / v.scale });\n\n/**\n * Pin a float to the view, or unpin it to the page. `view` is where the page is now (default: identity): the float\n * doesn't jump, its rect is converted between the two spaces. A float's size is never scaled.\n *\n * `shown` is where the float shows now, in view space (the layout's placed rect for it). When given, its position is\n * converted instead of the stored one, so a float the clamp moved stays where it shows rather than jumping to its\n * stored place. The size stays the stored one: a float folded to a bar, or shrunk by the clamp, keeps its full size.\n */\nexport function pin(state: PanelsState, id: string, on: boolean, view: View = IDENTITY_VIEW, shown?: Rect): PanelsState {\n return {\n ...state,\n floats: state.floats.map((f): FloatAt => {\n if (f.id !== id || !!f.pinned === on) return f;\n // In view space: where it shows, else where it is stored; at its stored size.\n const seen = shown ? { ...f.rect, x: shown.x, y: shown.y } : f.pinned ? { ...f.rect } : toView(f.rect, view);\n return on ? { id, rect: seen, pinned: true } : { id, rect: toPage(seen, view) };\n }),\n };\n}\n\n/**\n * Store a column's width (the layout clamps it to its panels' limits). Resizing is a use: the column's panels are\n * the newest used, so give-way takes room from the other columns, not from the one being resized.\n */\nexport function resizeColumn(state: PanelsState, side: Side, index: number, width: number): PanelsState {\n const col = state.sides[side][index];\n if (!col || !Number.isFinite(width)) return state;\n const t = tick(state);\n const clock = { ...state.clock };\n for (const id of col.panels) clock[id] = { opened: clock[id]?.opened ?? 0, used: t };\n return { ...state, sides: { ...state.sides, [side]: state.sides[side].map((c, i) => (i === index ? { ...c, width: Math.max(0, width) } : c)) }, clock };\n}\n\n/** Store a float's rect (its own space). Resizing is a use. */\nexport function resizeFloat(state: PanelsState, id: string, rect: Rect): PanelsState {\n if (!state.floats.some((f) => f.id === id)) return state;\n return bump({ ...state, floats: state.floats.map((f) => (f.id === id ? { ...f, rect: { ...rect } } : f)) }, id, false);\n}\n\n/** A column's width as the layout takes it: its stored width clamped to its panels' limits (with `defs`). */\nexport function columnWidth(defs: readonly PanelDef[] | undefined, col: Column): number {\n if (!defs) return col.width;\n const ds = col.panels.map((id) => defOf(defs, id));\n const lo = Math.max(0, ...ds.map((d) => d?.width.min ?? 0));\n const hi = Math.max(lo, Math.min(...ds.map((d) => d?.width.max ?? Infinity)));\n return Math.min(Math.max(Number.isFinite(col.width) ? col.width : lo, lo), hi);\n}\n\n/**\n * Two states place the panels the same (columns, their panels and widths, floats and their rects; the clock aside).\n * With `defs`, widths compare as the layout takes them (clamped to the panels' limits), so a stored width past a\n * column's max is the same place as that max.\n */\nexport function samePlaces(a: PanelsState, b: PanelsState, defs?: readonly PanelDef[]): boolean {\n const cols = (s: PanelsState): string =>\n SIDES.map((side) =>\n s.sides[side]\n .map((c) => `${c.panels.join(\",\")}@${Math.round(columnWidth(defs, c))}${c.show === \"tabs\" ? `/tabs:${c.active ?? c.panels[0]}` : \"\"}`)\n .join(\"|\"),\n ).join(\"‖\");\n const fl = (s: PanelsState): string => s.floats.map((f) => `${f.id}@${Math.round(f.rect.x)},${Math.round(f.rect.y)},${Math.round(f.rect.width)},${Math.round(f.rect.height)}${f.pinned ? \"p\" : \"\"}`).join(\"|\");\n const set = (l: readonly string[]): string => [...l].sort().join(\",\");\n return cols(a) === cols(b) && fl(a) === fl(b) && set(a.folded) === set(b.folded) && set(a.kept) === set(b.kept) && set(a.closed) === set(b.closed);\n}\n","/**\n * `layoutPanels`: the panels' state, a stage and options in; geometry and structure out: every panel's rect, layer\n * and kind, the columns, the rails, the pages' rect, and coded notes on how it gave way. Pure: the same input always\n * lays out the same. How anything looks is the consumer's.\n *\n * - A column is full height and as wide as its stored width, clamped to its panels' limits. Inside it, a panel\n * folded by hand is a title bar (`options.bar` tall) and the open ones share the rest of the height equally.\n * - A column whose panels are all folded is railed: its panels become segments of its side's rail (one rail per\n * side, `options.rail` wide at the outer edge, segments in side order).\n * - With `options.fold` \"ride\", a column folded by hand on a side that still has an open column rides instead: its\n * panels become title bars stacked on top of the side's first open column (outer edge first), as wide as that\n * column, and its open panels share the rest of the height. The folded column keeps its stored place and width, and\n * the open columns lie as if it were gone. Only when every column on the side is folded does the side show its rail.\n * Give-way's folds always go to the rail.\n * - A float folded by hand is a title bar: its own x, y and width, `options.bar` tall, still a float (clamped as a\n * bar, `floating`); unfolding brings its full rect back, as the stored rect never changes.\n * - Give-way: when the open columns, the rails and `pagesMin` don't fit the stage width, columns shrink toward their\n * minimum, then whole columns fold to the rail, in the policy's order, until the pages fit. Columns holding a kept\n * panel come after every other column; if the pages still don't fit, they fold too (`kept-folded`). Folding by\n * give-way never writes `folded`, so a wider stage brings the column back.\n * - Floats: \"clamp\" keeps a float in the view at layout time (the state keeps the stored rect, so a larger view\n * brings it back where it was); \"free\" never moves one. A float's size is never scaled. A pinned float is in view\n * space and clamped against the view; an unpinned one has its position in page space, clamped so that its screen\n * rect at pan 0 fits the view, then moved by the view's offset and scale, so it scrolls with the page.\n */\n/*\n * Also (26.11.9):\n * - A tabbed column (`show` \"tabs\") draws a strip `options.tabs` tall on top (`PlacedColumn.strip`, each panel's\n * `tab` in it, panel order, equal widths); its active panel takes the rest and the others are hidden. With its\n * active panel folded it shows only the strip (the active panel is a \"bar\" there); with every panel folded it goes\n * to the rail (or rides) as a stack column does.\n * - Height give-way, opt-in by `PanelDef.height`: see `sectionHeights` in the layout (note `section-folded`).\n */\nimport { rect, type Rect, type Size } from \"../geometry\";\nimport { DEFAULT_PANELS_OPTIONS, SIDES, defOf, floatSize, toView, type PanelDef, type PanelsOptions, type PanelsState, type Side } from \"./model\";\n\n/**\n * Where a panel is, structurally: an open part of a column, a folded title bar (in a column, riding on one, or a\n * folded float), a segment of a rail (the panel itself isn't laid out), or a float.\n */\nexport type PanelKind = \"column\" | \"bar\" | \"segment\" | \"float\";\n\nexport interface PlacedPanel {\n /** Stage px; for a segment, the segment's rect in its rail. */\n readonly rect: Rect;\n readonly kind: PanelKind;\n /** Columns and rails 0, floats 10 and up (a later float on top). */\n readonly layer: number;\n /** Not drawn as a panel: in a rail (only its segment shows), or a tab that isn't showing (only its `tab`). */\n readonly hidden: boolean;\n /** Folded by hand (a bar, or a segment of a column folded by hand), or by give-way (a segment). */\n readonly folded: null | \"hand\" | \"auto\";\n /** Kept open. */\n readonly kept: boolean;\n /** A pinned float. */\n readonly pinned: boolean;\n /** It floats (open, or folded to a bar). */\n readonly floating: boolean;\n /** Docked: its side and column index (the state's). */\n readonly side?: Side;\n readonly column?: number;\n /** A riding bar: the index of the column it rides on (`options.fold` \"ride\"). */\n readonly rides?: number;\n /** In a tabbed column: its tab's rect in the strip (panel order, equal widths). */\n readonly tab?: Rect;\n /** A float the clamp moved or resized. */\n readonly clamped?: boolean;\n}\n\nexport interface PlacedColumn {\n readonly side: Side;\n /** The column's index in the state. */\n readonly index: number;\n /** Its rect (zero wide when railed). */\n readonly rect: Rect;\n /** Its stored width clamped to its panels' limits, and those limits. */\n readonly width: number;\n readonly min: number;\n readonly max: number;\n /** null: open; \"hand\": all its panels folded by hand; \"auto\": folded by give-way. */\n readonly folded: null | \"hand\" | \"auto\";\n /** Shrunk by give-way below its width. */\n readonly shrunk: boolean;\n /** It holds a kept panel. */\n readonly kept: boolean;\n /** The shown panels, top to bottom. */\n readonly panels: readonly string[];\n /** Riding: the index of the column its bars ride on; its rect is the bars'. */\n readonly rides?: number;\n /** How it shows its panels (default \"stack\"). */\n readonly show?: \"stack\" | \"tabs\";\n /** Tabbed and laid out: its strip of tabs, and the panel it shows. */\n readonly strip?: Rect;\n readonly active?: string;\n}\n\nexport interface PlacedRail {\n readonly side: Side;\n readonly rect: Rect;\n readonly segments: readonly { readonly id: string; readonly rect: Rect }[];\n}\n\nexport type PanelsNoteCode = \"column-shrunk\" | \"column-folded\" | \"kept-folded\" | \"section-folded\" | \"pages-under-min\" | \"float-clamped\" | \"float-resized\";\n\n/** One note on a layout: a code and its data. */\nexport type PanelsNote =\n | { readonly code: \"column-shrunk\"; readonly side: Side; readonly column: number; readonly items: readonly string[]; readonly from: number; readonly to: number }\n | { readonly code: \"column-folded\" | \"kept-folded\" | \"section-folded\"; readonly side: Side; readonly column: number; readonly items: readonly string[] }\n | { readonly code: \"pages-under-min\"; readonly width: number; readonly min: number }\n | { readonly code: \"float-clamped\" | \"float-resized\"; readonly items: readonly string[] };\n\nexport interface PanelsLayout {\n readonly items: Map<string, PlacedPanel>;\n /** The shown columns in side order (left outer → inner, then right outer → inner). */\n readonly columns: readonly PlacedColumn[];\n readonly rails: Partial<Record<Side, PlacedRail>>;\n readonly notes: readonly PanelsNote[];\n /** What is left for the documents. */\n readonly pages: Rect;\n}\n\ninterface Col {\n readonly side: Side;\n readonly index: number;\n readonly panels: readonly string[];\n readonly min: number;\n readonly max: number;\n readonly width: number;\n readonly hand: boolean;\n readonly kept: boolean;\n readonly age: number;\n readonly show?: \"stack\" | \"tabs\";\n /** Tabbed: the panel it shows (its stored one when shown, else its first). */\n readonly active?: string;\n}\n\nconst clamp = (v: number, lo: number, hi: number): number => Math.min(Math.max(v, lo), Math.max(lo, hi));\n\n/** The order columns give way in: unkept before kept, then the policy (oldest or newest), outer first, left first. */\nexport function giveWayOrder<C extends { readonly side: Side; readonly index: number; readonly kept: boolean; readonly age: number }>(cols: readonly C[], order: \"oldest\" | \"newest\"): C[] {\n return [...cols].sort((a, b) => Number(a.kept) - Number(b.kept) || (order === \"oldest\" ? a.age - b.age : b.age - a.age) || a.index - b.index || SIDES.indexOf(a.side) - SIDES.indexOf(b.side));\n}\n\nexport function layoutPanels(defs: readonly PanelDef[], state: PanelsState, stage: Size, options: Partial<PanelsOptions> = {}): PanelsLayout {\n const opt: PanelsOptions = { ...DEFAULT_PANELS_OPTIONS, ...options };\n const W = stage.width;\n const H = stage.height;\n const closed = new Set(state.closed);\n const folded = new Set(state.folded);\n const kept = new Set(state.kept);\n const by = opt.giveWay.by;\n const ride = opt.fold === \"ride\";\n\n // The shown columns.\n const cols: Col[] = [];\n for (const side of SIDES) {\n state.sides[side].forEach((c, index) => {\n const panels = c.panels.filter((id) => !closed.has(id));\n if (panels.length === 0) return;\n const ds = panels.map((id) => defOf(defs, id));\n const min = Math.max(0, ...ds.map((d) => d?.width.min ?? 0));\n const max = Math.max(min, Math.min(...ds.map((d) => d?.width.max ?? Infinity)));\n const width = clamp(Number.isFinite(c.width) ? c.width : min, min, max);\n const age = Math.max(...panels.map((id) => state.clock[id]?.[by] ?? 0));\n const tabs = c.show === \"tabs\" ? { show: \"tabs\" as const, active: c.active !== undefined && panels.includes(c.active) ? c.active : panels[0]! } : {};\n cols.push({ side, index, panels, min, max, width, hand: panels.every((id) => folded.has(id)), kept: panels.some((id) => kept.has(id)), age, ...tabs });\n });\n }\n\n /**\n * A stack column's sections, top to bottom, `room` px tall. Without a `height` def among its open sections they\n * share the room equally (bars `opt.bar` tall). With one: each gets its natural height and the last open one the rest\n * (never under its min; sections without a def share what is left). Short of room, open sections fold to bars by\n * give-way (policy order, kept last, never the last open one); their natural heights give way toward their mins\n * before the last one goes under its min.\n */\n const sectionHeights = (c: Col, room: number): Map<string, { height: number; folded: null | \"hand\" | \"auto\" }> => {\n const out = new Map<string, { height: number; folded: null | \"hand\" | \"auto\" }>();\n const open0 = c.panels.filter((id) => !folded.has(id));\n const hOf = (id: string) => defOf(defs, id)?.height;\n const auto = new Set<string>();\n if (open0.some((id) => hOf(id))) {\n const last = open0.at(-1)!;\n // A section without a def never goes under a bar's height: that is its min.\n const minOf = (id: string): number => hOf(id)?.min ?? opt.bar;\n const fits = (): boolean => (c.panels.length - open0.length + auto.size) * opt.bar + open0.filter((id) => !auto.has(id)).reduce((a, id) => a + minOf(id), 0) <= room;\n const rank = (ids: readonly string[]): string[] =>\n [...ids].sort((a, b) => {\n const age = (id: string): number => state.clock[id]?.[by] ?? 0;\n return Number(kept.has(a)) - Number(kept.has(b)) || (opt.giveWay.order === \"oldest\" ? age(a) - age(b) : age(b) - age(a)) || c.panels.indexOf(a) - c.panels.indexOf(b);\n });\n for (const id of rank(open0.filter((x) => x !== last))) {\n if (fits()) break;\n // Folding a section whose min is no more than a bar gains nothing: skip it.\n if (minOf(id) > opt.bar) auto.add(id);\n }\n const open = open0.filter((id) => !auto.has(id));\n const space = room - (c.panels.length - open.length) * opt.bar;\n const fixed = open.filter((id) => id !== last && hOf(id));\n const sharers = open.filter((id) => id === last || !hOf(id));\n const h = new Map(fixed.map((id) => [id, hOf(id)!.natural]));\n let rest = space - fixed.reduce((a, id) => a + h.get(id)!, 0);\n // The sharers (the last section and those without a def) need their mins: the fixed sections' natural heights\n // give way toward their mins first, in policy order.\n const need = sharers.reduce((a, id) => a + minOf(id), 0);\n for (const id of rank(fixed)) {\n if (rest >= need) break;\n const take = Math.min(need - rest, h.get(id)! - minOf(id));\n h.set(id, h.get(id)! - take);\n rest += take;\n }\n if (rest >= need) {\n // Equal shares, raised to each sharer's min where a share falls under it.\n let pool = [...sharers];\n let left = rest;\n for (;;) {\n const share = left / pool.length;\n const under = pool.filter((id) => minOf(id) > share);\n if (under.length === 0) {\n for (const id of pool) h.set(id, share);\n break;\n }\n for (const id of under) h.set(id, minOf(id));\n left -= under.reduce((a, id) => a + minOf(id), 0);\n pool = pool.filter((id) => !under.includes(id));\n }\n } else {\n // Short even for the mins: the last section first, the others share what is left.\n const lastH = Math.max(0, Math.min(minOf(last), rest));\n for (const id of sharers) h.set(id, id === last ? lastH : Math.max(0, rest - lastH) / (sharers.length - 1));\n }\n for (const id of c.panels) out.set(id, folded.has(id) ? { height: opt.bar, folded: \"hand\" } : auto.has(id) ? { height: opt.bar, folded: \"auto\" } : { height: Math.max(0, h.get(id)!), folded: null });\n return out;\n }\n const bars = c.panels.length - open0.length;\n const share = Math.max(0, (room - bars * opt.bar) / open0.length);\n for (const id of c.panels) out.set(id, folded.has(id) ? { height: opt.bar, folded: \"hand\" } : { height: share, folded: null });\n return out;\n };\n\n // Give-way: fold the fewest columns in order that let the pages fit, shrinking the rest in order toward their minimum.\n const order = giveWayOrder(\n cols.filter((c) => !c.hand),\n opt.giveWay.order,\n );\n const fit = (k: number): { auto: Set<Col>; widths: Map<Col, number>; excess: number } => {\n const auto = new Set(order.slice(0, k));\n // Riding, a side's hand-folded columns need no rail while one of its columns stays open.\n const open = (side: Side): boolean => cols.some((c) => c.side === side && !c.hand && !auto.has(c));\n const railed = (side: Side): boolean => cols.some((c) => c.side === side && (auto.has(c) || (c.hand && !(ride && open(side)))));\n const widths = new Map(order.filter((c) => !auto.has(c)).map((c) => [c, c.width]));\n let excess = [...widths.values()].reduce((a, b) => a + b, 0) + SIDES.filter(railed).length * opt.rail + opt.pagesMin - W;\n for (const c of order) {\n if (excess <= 0 || auto.has(c)) continue;\n const take = Math.min(excess, c.width - c.min);\n if (take > 0) {\n widths.set(c, c.width - take);\n excess -= take;\n }\n }\n return { auto, widths, excess };\n };\n let g = fit(0);\n for (let k = 1; g.excess > 0 && k <= order.length; k++) g = fit(k);\n\n const notes: PanelsNote[] = [];\n for (const c of order) {\n const w = g.widths.get(c);\n if (w !== undefined && w < c.width) notes.push({ code: \"column-shrunk\", side: c.side, column: c.index, items: c.panels, from: c.width, to: w });\n }\n for (const c of order) if (g.auto.has(c)) notes.push({ code: c.kept ? \"kept-folded\" : \"column-folded\", side: c.side, column: c.index, items: c.panels });\n\n // Positions: rails at the outer edges, open columns inward from them, the pages between.\n const items = new Map<string, PlacedPanel>();\n const placedCols: PlacedColumn[] = [];\n const rails: Partial<Record<Side, PlacedRail>> = {};\n let x0 = 0;\n let x1 = W;\n for (const side of SIDES) {\n const mine = cols.filter((c) => c.side === side);\n const open = mine.filter((c) => !c.hand && !g.auto.has(c));\n // Riding: the side's hand-folded columns, while it has an open column to ride on (the first, outer edge first).\n const host = ride ? open[0] : undefined;\n const riders = host ? mine.filter((c) => c.hand) : [];\n const inRail = mine.filter((c) => (c.hand && !riders.includes(c)) || g.auto.has(c));\n if (inRail.length) {\n const r = side === \"left\" ? rect(0, 0, opt.rail, H) : rect(W - opt.rail, 0, opt.rail, H);\n const segments = inRail.flatMap((c) => c.panels).map((id, i) => ({ id, rect: rect(r.x, opt.railInset + i * opt.segment, opt.rail, opt.segment) }));\n rails[side] = { side, rect: r, segments };\n for (const s of segments) {\n const c = inRail.find((x) => x.panels.includes(s.id))!;\n items.set(s.id, { rect: s.rect, kind: \"segment\", layer: 0, hidden: true, folded: c.hand ? \"hand\" : \"auto\", kept: kept.has(s.id), pinned: false, floating: false, side, column: c.index });\n }\n if (side === \"left\") x0 = opt.rail;\n else x1 = W - opt.rail;\n }\n // The open columns first (riding bars need their host's rect), then the folded ones in state order.\n const at = new Map<Col, Rect>();\n for (const c of mine) {\n const w = g.widths.get(c);\n if (w === undefined || riders.includes(c)) continue;\n if (side === \"left\") {\n at.set(c, rect(x0, 0, w, H));\n x0 += w;\n } else {\n x1 -= w;\n at.set(c, rect(x1, 0, w, H));\n }\n }\n const riding = riders.flatMap((c) => c.panels.map((id) => ({ id, c })));\n const top = riding.length * opt.bar;\n for (const c of mine) {\n const w = g.widths.get(c);\n const folded1 = c.hand ? \"hand\" : g.auto.has(c) ? \"auto\" : null;\n const base = { side, index: c.index, width: c.width, min: c.min, max: c.max, folded: folded1, kept: c.kept, panels: c.panels } as const;\n if (riders.includes(c)) {\n const hr = at.get(host!)!;\n const first = riding.findIndex((x) => x.c === c);\n c.panels.forEach((id, i) =>\n items.set(id, { rect: rect(hr.x, (first + i) * opt.bar, hr.width, opt.bar), kind: \"bar\", layer: 0, hidden: false, folded: \"hand\", kept: kept.has(id), pinned: false, floating: false, side, column: c.index, rides: host!.index }),\n );\n placedCols.push({ ...base, rect: rect(hr.x, first * opt.bar, hr.width, c.panels.length * opt.bar), shrunk: false, rides: host!.index });\n continue;\n }\n const r = at.get(c) ?? rect(side === \"left\" ? x0 : x1, 0, 0, H);\n // The host shares what the riding bars leave.\n const y0 = c === host ? top : 0;\n const tabbed = c.show === \"tabs\";\n const strip = rect(r.x, y0, r.width, opt.tabs);\n const shown = tabbed && w !== undefined ? { strip, active: c.active! } : {};\n placedCols.push({ ...base, rect: r, shrunk: w !== undefined && w < c.width, ...(tabbed ? { show: \"tabs\" as const } : {}), ...shown });\n if (w === undefined) continue;\n const panel = (id: string, to: Rect, kind: PanelKind, f: null | \"hand\" | \"auto\", more: { tab?: Rect; hidden?: boolean } = {}): void => {\n items.set(id, { rect: to, kind, layer: 0, hidden: more.hidden ?? false, folded: f, kept: kept.has(id), pinned: false, floating: false, side, column: c.index, ...(more.tab ? { tab: more.tab } : {}) });\n };\n if (tabbed) {\n // One panel shows under the strip; the others are its hidden tabs. Its active panel folded: only the strip.\n const body = rect(r.x, y0 + opt.tabs, r.width, Math.max(0, H - y0 - opt.tabs));\n const shade = folded.has(c.active!);\n const tw = r.width / c.panels.length;\n c.panels.forEach((id, i) => {\n const tab = rect(r.x + i * tw, y0, tw, opt.tabs);\n if (id === c.active) panel(id, shade ? strip : body, shade ? \"bar\" : \"column\", shade ? \"hand\" : null, { tab });\n else panel(id, body, \"column\", folded.has(id) ? \"hand\" : null, { tab, hidden: true });\n });\n continue;\n }\n const hs = sectionHeights(c, H - y0);\n let y = y0;\n for (const id of c.panels) {\n const s = hs.get(id)!;\n panel(id, rect(r.x, y, r.width, s.height), s.folded ? \"bar\" : \"column\", s.folded);\n y += s.height;\n }\n for (const id of c.panels) if (hs.get(id)!.folded === \"auto\") notes.push({ code: \"section-folded\", side, column: c.index, items: [id] });\n }\n }\n const pages = rect(x0, 0, Math.max(0, x1 - x0), H);\n if (pages.width < opt.pagesMin) notes.push({ code: \"pages-under-min\", width: pages.width, min: opt.pagesMin });\n\n // Floats, clamped unless free. A float's size is screen px in both spaces (never scaled); only an unpinned float's\n // position is in page space. The clamp keeps the SCREEN rect in the view: a pinned float where it is, an unpinned\n // one as it shows at pan 0, so it still scrolls with the page. In page units (k = the scale, 1 when pinned) a\n // screen interval [lo, hi] is [lo / k, hi / k].\n state.floats.forEach((f, i) => {\n if (closed.has(f.id)) return;\n // Folded by hand: a title bar at its own place and width (the stored rect keeps its height).\n const shaded = folded.has(f.id);\n const at = shaded ? { ...f.rect, height: opt.bar } : f.rect;\n const k = f.pinned ? 1 : opt.view.scale;\n const r = { ...at };\n if (opt.floats === \"clamp\") {\n const lim = floatSize(defOf(defs, f.id)).min;\n r.width = Math.max(lim.width, Math.min(r.width, W));\n if (!shaded) r.height = Math.max(lim.height, Math.min(r.height, H));\n if (r.width !== at.width || r.height !== at.height) notes.push({ code: \"float-resized\", items: [f.id] });\n // Fits: wholly in the view. Too big even at its minimum: its title bar stays in, and `floatVisible` px of its width.\n r.x = r.width <= W ? clamp(r.x, 0, (W - r.width) / k) : clamp(r.x, (opt.floatVisible - r.width) / k, (W - opt.floatVisible) / k);\n r.y = r.height <= H ? clamp(r.y, 0, (H - r.height) / k) : clamp(r.y, 0, (H - opt.bar) / k);\n if (r.x !== at.x || r.y !== at.y) notes.push({ code: \"float-clamped\", items: [f.id] });\n }\n const clamped = r.x !== at.x || r.y !== at.y || r.width !== at.width || r.height !== at.height;\n items.set(f.id, {\n rect: f.pinned ? r : toView(r, opt.view),\n kind: shaded ? \"bar\" : \"float\",\n layer: 10 + i,\n hidden: false,\n folded: shaded ? \"hand\" : null,\n kept: false,\n pinned: !!f.pinned,\n floating: true,\n ...(clamped ? { clamped: true } : {}),\n });\n });\n\n return { items, columns: placedCols, rails, notes, pages };\n}\n","/**\n * The drop targets for dragging a panel, in the shape @n-uf/motion/drag takes (`{ id, priority, hit, slot?, free? }`),\n * worked out from the state with the panel lifted out:\n *\n * - `column:<side>:<i>` (priority 2): a band across the line between two columns (or a side's edge): a new column\n * there, as wide as the panel's own width.\n * - `into:<side>:<i>` (2): a column's area: the panel stacks at its bottom.\n * - `rail:<side>` (1): the side's rail, or its outer edge: the panel docks folded.\n * - `float` (3, free): anywhere; it floats where it is let go, kept in the view as the float option says.\n *\n * A place the panel may not take (its def's `sides` and `floats`, and `allows`) is no target, and neither is its own\n * place (a drop there changes nothing). Targets carry a structured `place`, never words: the consumer names them.\n */\nimport { rect, type Point, type Rect, type Size } from \"../geometry\";\nimport type { Target } from \"../targets/target\";\nimport { layoutPanels, type PanelsLayout } from \"./layout\";\nimport { DEFAULT_PANELS_OPTIONS, SIDES, defOf, dock, float, floatSize, liftPanel, ownWidth, samePlaces, toPage, whereIs, type PanelDef, type PanelsOptions, type PanelsState, type Side } from \"./model\";\n\n/** Where a drop puts a panel. `index` is a column index in the state with the panel lifted out. */\nexport type PanelPlace =\n | { readonly kind: \"column\"; readonly side: Side; readonly index: number }\n | { readonly kind: \"into\"; readonly side: Side; readonly index: number }\n | { readonly kind: \"rail\"; readonly side: Side }\n | { readonly kind: \"float\" };\n\nexport interface PanelTarget extends Target {\n /** The panel dragged. */\n readonly panel: string;\n readonly place: PanelPlace;\n /** Its rank in reading order (left to right across the stage, floating last). */\n readonly order: number;\n /** The state a drop here makes, with the pointer at `p` holding the panel at `grab` from its top-left corner. */\n readonly make: (p: Point, grab: Point) => PanelsState;\n}\n\nexport interface PanelTargetInput {\n readonly defs: readonly PanelDef[];\n /** The state as it is, the panel still in its place. */\n readonly state: PanelsState;\n readonly id: string;\n readonly stage: Size;\n readonly options?: Partial<PanelsOptions>;\n /** Places the panel may go beyond its def's rules (default: all of them). */\n readonly allows?: (id: string, place: PanelPlace) => boolean;\n}\n\n/** How far a column band reaches on each side of its line, px; how wide a side's edge takes a rail drop when it has no rail. */\nexport const COLUMN_REACH = 22;\nexport const RAIL_EDGE = 10;\n\n/** A place's rank in reading order: the left side outer to inner, the right side inner to outer, floating last. */\nexport function placeRank(place: PanelPlace): number {\n switch (place.kind) {\n case \"float\":\n return 3000;\n case \"rail\":\n return place.side === \"left\" ? 0 : 1999;\n case \"column\":\n return place.side === \"left\" ? 1 + 2 * place.index : 1998 - 2 * place.index;\n case \"into\":\n return place.side === \"left\" ? 2 + 2 * place.index : 1997 - 2 * place.index;\n }\n}\n\n/** Where a panel is now, as a place (a float, a column of its own, or stacked in one); null when placed nowhere. */\nexport function homePlace(state: PanelsState, id: string): PanelPlace | null {\n const w = whereIs(state, id);\n if (w.kind === \"float\") return { kind: \"float\" };\n if (w.kind === \"none\") return null;\n return state.sides[w.side][w.index]!.panels.length === 1 ? { kind: \"column\", side: w.side, index: w.index } : { kind: \"into\", side: w.side, index: w.index };\n}\n\nconst cut = (x0: number, x1: number, lo: number, hi: number): [number, number] => [Math.max(x0, lo), Math.min(x1, hi)];\n\n/** The targets for dragging `input.id`, in reading order. */\nexport function panelTargets(input: PanelTargetInput): PanelTarget[] {\n const { defs, state, id, stage } = input;\n const opt: PanelsOptions = { ...DEFAULT_PANELS_OPTIONS, ...input.options };\n const def = defOf(defs, id);\n const s0 = liftPanel(state, id);\n const l0 = layoutPanels(defs, s0, stage, opt);\n const width = ownWidth(defs, state, id);\n const W = stage.width;\n const H = stage.height;\n const R = COLUMN_REACH;\n const out: PanelTarget[] = [];\n const add = (place: PanelPlace, priority: 1 | 2 | 3, hit: Rect, make: PanelTarget[\"make\"], free = false): void => {\n if (hit.width <= 0 || hit.height <= 0) return;\n if (input.allows && !input.allows(id, place)) return;\n // Its own place: a drop there changes nothing, so it is no target (the drag's home covers it).\n // Widths compare as laid out: a stored width past the column's limits is the same place as the limit.\n if (place.kind !== \"float\" && samePlaces(make({ x: 0, y: 0 }, { x: 0, y: 0 }), state, defs)) return;\n out.push({ id: place.kind === \"float\" ? \"float\" : place.kind === \"rail\" ? `rail:${place.side}` : `${place.kind}:${place.side}:${place.index}`, priority, hit, panel: id, place, order: placeRank(place), make, ...(free ? { free: true } : {}) });\n };\n\n for (const side of SIDES) {\n if (def?.sides && !def.sides.includes(side)) continue;\n const left = side === \"left\";\n const rail = l0.rails[side];\n const edge = rail ? rail.rect.width : RAIL_EDGE;\n // The rail (or the bare edge): dock folded, as the outermost column.\n const railHit = rail ? rail.rect : left ? rect(0, 0, RAIL_EDGE, H) : rect(W - RAIL_EDGE, 0, RAIL_EDGE, H);\n add({ kind: \"rail\", side }, 1, railHit, () => {\n const s = dock(state, id, side, 0, { width });\n return { ...s, folded: [...s.folded.filter((x) => x !== id), id] };\n });\n // The lines between the open columns, outer to inner, and each column's area.\n const open = l0.columns.filter((c) => c.side === side && c.folded === null);\n const lo = left ? edge : 0;\n const hi = left ? W : W - edge;\n const band = (x: number, outer: boolean, i: number): void => {\n // The outermost line reaches inward only: outward is the rail's.\n const [a, b] = outer ? (left ? cut(x, x + 2 * R, lo, hi) : cut(x - 2 * R, x, lo, hi)) : cut(x - R, x + R, lo, hi);\n add({ kind: \"column\", side, index: i }, 2, rect(a, 0, b - a, H), () => dock(state, id, side, i, { width }));\n };\n if (open.length === 0) band(left ? l0.pages.x : l0.pages.x + l0.pages.width, true, s0.sides[side].length);\n open.forEach((c, k) => {\n band(left ? c.rect.x : c.rect.x + c.rect.width, k === 0, c.index);\n add({ kind: \"into\", side, index: c.index }, 2, c.rect, () => dock(state, id, side, c.index, { into: true }));\n });\n const last = open.at(-1);\n if (last) band(left ? last.rect.x + last.rect.width : last.rect.x, false, last.index + 1);\n }\n\n if (def?.floats !== false) {\n const was = state.floats.find((f) => f.id === id);\n const size = was ? { width: was.rect.width, height: was.rect.height } : floatSize(def).natural;\n const pinned = !!was?.pinned;\n add(\n { kind: \"float\" },\n 3,\n rect(0, 0, W, H),\n (p, grab) => {\n // Let go at p (view space); stored where it shows once the float option has had its say.\n const at = rect(p.x - grab.x, p.y - grab.y, size.width, size.height);\n const s = float(state, id, pinned ? at : toPage(at, opt.view), pinned);\n const laid = layoutPanels(defs, s, stage, opt).items.get(id)!.rect;\n // A folded float shows as a bar: it moves to where the bar shows and keeps its full size for unfolding.\n const shown = s.folded.includes(id) ? { ...laid, width: at.width, height: at.height } : laid;\n return float(state, id, pinned ? shown : toPage(shown, opt.view), pinned);\n },\n true,\n );\n }\n return out.sort((a, b) => a.order - b.order);\n}\n\n/** A target's drop, laid out: where the panel lands. */\nexport interface PanelDrop {\n readonly target: string;\n readonly place: PanelPlace;\n /** Same key, same place (a float's key carries where it lands). */\n readonly key: string;\n readonly state: PanelsState;\n readonly layout: PanelsLayout;\n /** Where the panel lands (its rail segment when it docks folded). */\n readonly slot: Rect;\n /** It lands in a rail. */\n readonly hidden: boolean;\n /** It floats where it is let go: no room is made for it. */\n readonly free: boolean;\n}\n\n/** The drop on `target` with the pointer at `p` holding the panel at `grab`, laid out. */\nexport function panelDrop(input: PanelTargetInput, target: PanelTarget, p: Point, grab: Point): PanelDrop {\n const opt: PanelsOptions = { ...DEFAULT_PANELS_OPTIONS, ...input.options };\n const state = target.make(p, grab);\n const layout = layoutPanels(input.defs, state, input.stage, opt);\n const placed = layout.items.get(input.id)!;\n const key = target.free ? `float:${Math.round(placed.rect.x)},${Math.round(placed.rect.y)}` : target.id;\n return { target: target.id, place: target.place, key, state, layout, slot: placed.rect, hidden: placed.hidden, free: !!target.free };\n}\n\n// --- keyboard stops ------------------------------------------------------------------------------------------------\n\nexport interface PanelStop {\n /** The target's id (\"home\" for the panel's own place). */\n readonly id: string;\n readonly place: PanelPlace;\n /** The state a move here makes (the current one for home). */\n readonly state: PanelsState;\n readonly home: boolean;\n}\n\nexport interface PanelStopsOptions {\n /** The panel's own place (`homePlace`) and the state as it is: a stop of its own in its reading-order position. */\n readonly home?: { readonly place: PanelPlace; readonly state: PanelsState };\n /** Floating as a stop at the end (default: left out); `at` and `grab` as for a drop (default: the stage's middle, the corner). */\n readonly floats?: boolean | { readonly at: Point; readonly grab?: Point };\n}\n\n/** The panel's places in reading order, for the arrow keys and a \"Move to\" menu (`keyboardStops` calls this). */\nexport function panelStops(targets: readonly PanelTarget[], options: PanelStopsOptions = {}): PanelStop[] {\n const stops: (PanelStop & { order: number })[] = [];\n for (const t of targets) {\n if (t.place.kind === \"float\") {\n if (!options.floats) continue;\n const at = options.floats === true ? { x: t.hit.x + t.hit.width / 2, y: t.hit.y + t.hit.height / 2 } : options.floats.at;\n const grab = options.floats === true ? { x: 0, y: 0 } : (options.floats.grab ?? { x: 0, y: 0 });\n stops.push({ id: t.id, place: t.place, state: t.make(at, grab), home: false, order: t.order });\n continue;\n }\n stops.push({ id: t.id, place: t.place, state: t.make({ x: 0, y: 0 }, { x: 0, y: 0 }), home: false, order: t.order });\n }\n const h = options.home;\n // A float's home sits with the floats: last, after any float stop.\n if (h) stops.push({ id: \"home\", place: h.place, state: h.state, home: true, order: placeRank(h.place) + (h.place.kind === \"float\" ? 1 : 0.5) });\n return stops.sort((a, b) => a.order - b.order).map(({ order: _order, ...s }) => s);\n}\n"],"mappings":"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","names":["float","rect","f","open","share","open"]}
|