@n-uf/placement 26.11.8 → 26.11.10

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/dist/panels.js CHANGED
@@ -1,16 +1,26 @@
1
1
  import {
2
+ readPanels,
3
+ storePanels
4
+ } from "./chunk-7R5H2ABL.js";
5
+ import {
6
+ BAND_SIZE,
2
7
  COLUMN_REACH,
3
8
  DEFAULT_PANELS_OPTIONS,
9
+ EDGES,
4
10
  FLOAT_HEIGHT,
5
11
  FLOAT_MIN,
6
12
  IDENTITY_VIEW,
7
13
  RAIL_EDGE,
8
14
  SIDES,
15
+ activate,
16
+ bandHeight,
17
+ bandSize,
9
18
  close,
10
19
  columnWidth,
11
20
  createPanels,
12
21
  defOf,
13
22
  dock,
23
+ dockBand,
14
24
  float,
15
25
  floatSize,
16
26
  focus,
@@ -26,146 +36,37 @@ import {
26
36
  panelTargets,
27
37
  pin,
28
38
  placeRank,
39
+ resizeBand,
29
40
  resizeColumn,
30
41
  resizeFloat,
31
42
  samePlaces,
43
+ showTabs,
32
44
  tick,
33
45
  toPage,
34
46
  toView,
35
47
  toggleFold,
36
48
  whereIs
37
- } from "./chunk-QR7MGDX6.js";
49
+ } from "./chunk-PJD5HKYX.js";
38
50
  import "./chunk-QMTNB2C3.js";
39
-
40
- // src/panels/store.ts
41
- function storePanels(state) {
42
- const sides = Object.fromEntries(SIDES.map((s) => [s, state.sides[s].map((c) => ({ panels: [...c.panels], width: c.width }))]));
43
- return {
44
- v: 1,
45
- sides,
46
- floats: state.floats.map((f) => ({ id: f.id, rect: { x: f.rect.x, y: f.rect.y, width: f.rect.width, height: f.rect.height }, pinned: !!f.pinned })),
47
- folded: [...state.folded],
48
- kept: [...state.kept],
49
- closed: [...state.closed],
50
- clock: Object.fromEntries(Object.entries(state.clock).map(([k, c]) => [k, { opened: c.opened, used: c.used }]))
51
- };
52
- }
53
- var isObject = (x) => typeof x === "object" && x !== null && !Array.isArray(x);
54
- var finite = (x) => typeof x === "number" && Number.isFinite(x);
55
- function readPanels(data, defs) {
56
- try {
57
- return read(data, defs);
58
- } catch (e) {
59
- return { ok: false, error: `unreadable: ${e instanceof Error ? e.message : typeof e}` };
60
- }
61
- }
62
- function read(data, defs) {
63
- if (!isObject(data)) return { ok: false, error: "not an object" };
64
- if (data.v !== 1) return { ok: false, error: `unknown version ${typeof data.v === "number" || typeof data.v === "string" ? String(data.v) : typeof data.v} (this reads version 1)` };
65
- if (!isObject(data.sides)) return { ok: false, error: "sides is missing" };
66
- const dropped = [];
67
- const drop = (what) => {
68
- if (!dropped.includes(what)) dropped.push(what);
69
- };
70
- const seen = /* @__PURE__ */ new Set();
71
- const take = (x) => {
72
- if (typeof x !== "string") {
73
- drop(`a ${typeof x} where an id goes`);
74
- return null;
75
- }
76
- if (defs && !defOf(defs, x) || seen.has(x)) {
77
- drop(x);
78
- return null;
79
- }
80
- seen.add(x);
81
- return x;
82
- };
83
- const extra = (o, known, prefix) => {
84
- for (const k of Object.keys(o)) if (!known.includes(k)) drop(`${prefix}${k}`);
85
- };
86
- extra(data, ["v", "sides", "floats", "folded", "kept", "closed", "clock"], "");
87
- extra(data.sides, SIDES, "sides.");
88
- const sides = { left: [], right: [] };
89
- for (const side of SIDES) {
90
- const cols = data.sides[side];
91
- if (cols === void 0) continue;
92
- if (!Array.isArray(cols)) {
93
- drop(`sides.${side}`);
94
- continue;
95
- }
96
- for (const c of cols) {
97
- if (!isObject(c) || !Array.isArray(c.panels)) {
98
- drop(`a column on the ${side}`);
99
- continue;
100
- }
101
- extra(c, ["panels", "width"], "column.");
102
- const panels = c.panels.map(take).filter((x) => x !== null);
103
- if (panels.length === 0) continue;
104
- const ds = defs ? panels.map((id) => defOf(defs, id)) : [];
105
- const lo = Math.max(0, ...ds.map((d) => d.width.min));
106
- const hi = Math.max(lo, Math.min(...ds.map((d) => d.width.max)));
107
- const natural = ds.length ? Math.max(...ds.map((d) => d.width.natural)) : 0;
108
- const width = finite(c.width) ? c.width : natural;
109
- sides[side].push({ panels, width: defs ? Math.min(Math.max(width, lo), hi) : Math.max(0, width) });
110
- }
111
- }
112
- const floats = [];
113
- for (const f of Array.isArray(data.floats) ? data.floats : []) {
114
- const r = isObject(f) ? f.rect : void 0;
115
- if (!isObject(f) || !isObject(r) || !finite(r.x) || !finite(r.y) || !finite(r.width) || !finite(r.height)) {
116
- drop(isObject(f) && typeof f.id === "string" ? f.id : "a float");
117
- continue;
118
- }
119
- extra(f, ["id", "rect", "pinned"], "float.");
120
- const id = take(f.id);
121
- if (id === null) continue;
122
- const min = defs ? floatSize(defOf(defs, id)).min : { width: 0, height: 0 };
123
- floats.push({ id, rect: { x: r.x, y: r.y, width: Math.max(min.width, r.width), height: Math.max(min.height, r.height) }, ...f.pinned === true ? { pinned: true } : {} });
124
- }
125
- if (data.floats !== void 0 && !Array.isArray(data.floats)) drop("floats");
126
- const placed = (key) => {
127
- const x = data[key];
128
- if (x === void 0) return [];
129
- if (!Array.isArray(x)) {
130
- drop(key);
131
- return [];
132
- }
133
- const out = [];
134
- for (const id of x) {
135
- if (typeof id === "string" && seen.has(id)) {
136
- if (!out.includes(id)) out.push(id);
137
- } else drop(typeof id === "string" ? id : `a ${typeof id} in ${key}`);
138
- }
139
- return out;
140
- };
141
- const floating = new Set(floats.map((f) => f.id));
142
- const kept = placed("kept").filter((id) => {
143
- if (floating.has(id)) drop(id);
144
- return !floating.has(id);
145
- });
146
- const clock = {};
147
- if (isObject(data.clock)) {
148
- for (const id of Object.keys(data.clock)) if (!seen.has(id)) drop(`clock.${id}`);
149
- for (const id of seen) {
150
- const c = data.clock[id];
151
- clock[id] = isObject(c) && finite(c.opened) && finite(c.used) ? { opened: c.opened, used: c.used } : { opened: 0, used: 0 };
152
- }
153
- }
154
- return { ok: true, state: { sides, floats, folded: placed("folded"), kept, closed: placed("closed"), clock }, dropped };
155
- }
156
51
  export {
52
+ BAND_SIZE,
157
53
  COLUMN_REACH,
158
54
  DEFAULT_PANELS_OPTIONS,
55
+ EDGES,
159
56
  FLOAT_HEIGHT,
160
57
  FLOAT_MIN,
161
58
  IDENTITY_VIEW,
162
59
  RAIL_EDGE,
163
60
  SIDES,
61
+ activate,
62
+ bandHeight,
63
+ bandSize,
164
64
  close,
165
65
  columnWidth,
166
66
  createPanels,
167
67
  defOf,
168
68
  dock,
69
+ dockBand,
169
70
  float,
170
71
  floatSize,
171
72
  focus,
@@ -182,9 +83,11 @@ export {
182
83
  pin,
183
84
  placeRank,
184
85
  readPanels,
86
+ resizeBand,
185
87
  resizeColumn,
186
88
  resizeFloat,
187
89
  samePlaces,
90
+ showTabs,
188
91
  storePanels,
189
92
  tick,
190
93
  toPage,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/panels/store.ts"],"sourcesContent":["/**\n * The panels' stored form: `storePanels(state)` gives plain JSON-safe data (`{ v: 1, … }`); `readPanels(data, defs?)`\n * reads parsed data back and never throws. As with the toolbar's `readArrangement`: anything but an object of\n * version 1 is `{ ok: false, error }`. Inside one, it is lenient: an unknown id (with `defs`), a repeated one or a\n * malformed entry is dropped and listed in `dropped`; widths and float sizes are clamped to the defs. A panel the\n * consumer has but the stored state lacks is no error: the consumer places it (`open` with a place, say).\n *\n * Version 1 only gains optional fields. A field this reader doesn't know (a newer writer's, say) is no error either:\n * it is skipped and reported in `dropped` (`\"<field>\"` at the top, `\"sides.<key>\"`, `\"column.<field>\"`,\n * `\"float.<field>\"`; a clock entry for a panel that isn't placed as `\"clock.<id>\"`), so a consumer can tell that\n * something was left out.\n */\nimport type { Rect } from \"../geometry\";\nimport { SIDES, defOf, floatSize, type Clock, type Column, type FloatAt, type PanelDef, type PanelsState, type Side } from \"./model\";\n\nexport interface StoredPanels {\n readonly v: 1;\n readonly sides: Record<Side, { panels: string[]; width: number }[]>;\n readonly floats: { id: string; rect: Rect; pinned: boolean }[];\n readonly folded: string[];\n readonly kept: string[];\n readonly closed: string[];\n readonly clock: Record<string, Clock>;\n}\n\nexport type PanelsRead = { readonly ok: true; readonly state: PanelsState; readonly dropped: readonly string[] } | { readonly ok: false; readonly error: string };\n\nexport function storePanels(state: PanelsState): StoredPanels {\n const sides = Object.fromEntries(SIDES.map((s) => [s, state.sides[s].map((c) => ({ panels: [...c.panels], width: c.width }))])) as StoredPanels[\"sides\"];\n return {\n v: 1,\n sides,\n floats: state.floats.map((f) => ({ id: f.id, rect: { x: f.rect.x, y: f.rect.y, width: f.rect.width, height: f.rect.height }, pinned: !!f.pinned })),\n folded: [...state.folded],\n kept: [...state.kept],\n closed: [...state.closed],\n clock: Object.fromEntries(Object.entries(state.clock).map(([k, c]) => [k, { opened: c.opened, used: c.used }])),\n };\n}\n\nconst isObject = (x: unknown): x is Record<string, unknown> => typeof x === \"object\" && x !== null && !Array.isArray(x);\nconst finite = (x: unknown): x is number => typeof x === \"number\" && Number.isFinite(x);\n\nexport function readPanels(data: unknown, defs?: readonly PanelDef[]): PanelsRead {\n try {\n return read(data, defs);\n } catch (e) {\n // A getter that throws, a proxy: still no throw.\n return { ok: false, error: `unreadable: ${e instanceof Error ? e.message : typeof e}` };\n }\n}\n\nfunction read(data: unknown, defs?: readonly PanelDef[]): PanelsRead {\n if (!isObject(data)) return { ok: false, error: \"not an object\" };\n // Named without serialising it: a BigInt or a circular value must not throw.\n if (data.v !== 1) return { ok: false, error: `unknown version ${typeof data.v === \"number\" || typeof data.v === \"string\" ? String(data.v) : typeof data.v} (this reads version 1)` };\n if (!isObject(data.sides)) return { ok: false, error: \"sides is missing\" };\n const dropped: string[] = [];\n const drop = (what: string): void => {\n if (!dropped.includes(what)) dropped.push(what);\n };\n const seen = new Set<string>();\n // An id the consumer has, not placed yet.\n const take = (x: unknown): string | null => {\n if (typeof x !== \"string\") {\n drop(`a ${typeof x} where an id goes`);\n return null;\n }\n if ((defs && !defOf(defs, x)) || seen.has(x)) {\n drop(x);\n return null;\n }\n seen.add(x);\n return x;\n };\n // Fields this version doesn't know: skipped, and reported.\n const extra = (o: Record<string, unknown>, known: readonly string[], prefix: string): void => {\n for (const k of Object.keys(o)) if (!known.includes(k)) drop(`${prefix}${k}`);\n };\n extra(data, [\"v\", \"sides\", \"floats\", \"folded\", \"kept\", \"closed\", \"clock\"], \"\");\n extra(data.sides, SIDES, \"sides.\");\n const sides = { left: [] as Column[], right: [] as Column[] };\n for (const side of SIDES) {\n const cols = data.sides[side];\n if (cols === undefined) continue;\n if (!Array.isArray(cols)) {\n drop(`sides.${side}`);\n continue;\n }\n for (const c of cols as unknown[]) {\n if (!isObject(c) || !Array.isArray(c.panels)) {\n drop(`a column on the ${side}`);\n continue;\n }\n extra(c, [\"panels\", \"width\"], \"column.\");\n const panels = (c.panels as unknown[]).map(take).filter((x): x is string => x !== null);\n if (panels.length === 0) continue;\n const ds = defs ? panels.map((id) => defOf(defs, id)!) : [];\n const lo = Math.max(0, ...ds.map((d) => d.width.min));\n const hi = Math.max(lo, Math.min(...ds.map((d) => d.width.max)));\n const natural = ds.length ? Math.max(...ds.map((d) => d.width.natural)) : 0;\n const width = finite(c.width) ? c.width : natural;\n sides[side].push({ panels, width: defs ? Math.min(Math.max(width, lo), hi) : Math.max(0, width) });\n }\n }\n const floats: FloatAt[] = [];\n for (const f of Array.isArray(data.floats) ? (data.floats as unknown[]) : []) {\n const r = isObject(f) ? f.rect : undefined;\n if (!isObject(f) || !isObject(r) || !finite(r.x) || !finite(r.y) || !finite(r.width) || !finite(r.height)) {\n drop(isObject(f) && typeof f.id === \"string\" ? f.id : \"a float\");\n continue;\n }\n extra(f, [\"id\", \"rect\", \"pinned\"], \"float.\");\n const id = take(f.id);\n if (id === null) continue;\n const min = defs ? floatSize(defOf(defs, id)).min : { width: 0, height: 0 };\n floats.push({ id, rect: { x: r.x, y: r.y, width: Math.max(min.width, r.width), height: Math.max(min.height, r.height) }, ...(f.pinned === true ? { pinned: true } : {}) });\n }\n if (data.floats !== undefined && !Array.isArray(data.floats)) drop(\"floats\");\n // The lists keep only ids that are placed (a closed panel keeps its place).\n const placed = (key: \"folded\" | \"kept\" | \"closed\"): string[] => {\n const x = data[key];\n if (x === undefined) return [];\n if (!Array.isArray(x)) {\n drop(key);\n return [];\n }\n const out: string[] = [];\n for (const id of x as unknown[]) {\n if (typeof id === \"string\" && seen.has(id)) {\n if (!out.includes(id)) out.push(id);\n } else drop(typeof id === \"string\" ? id : `a ${typeof id} in ${key}`);\n }\n return out;\n };\n const floating = new Set(floats.map((f) => f.id));\n // Only a docked panel is kept open.\n const kept = placed(\"kept\").filter((id) => {\n if (floating.has(id)) drop(id);\n return !floating.has(id);\n });\n const clock: Record<string, Clock> = {};\n if (isObject(data.clock)) {\n for (const id of Object.keys(data.clock)) if (!seen.has(id)) drop(`clock.${id}`);\n for (const id of seen) {\n const c = data.clock[id];\n clock[id] = isObject(c) && finite(c.opened) && finite(c.used) ? { opened: c.opened, used: c.used } : { opened: 0, used: 0 };\n }\n }\n return { ok: true, state: { sides, floats, folded: placed(\"folded\"), kept, closed: placed(\"closed\"), clock }, dropped };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -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. A panel may instead float, in page space (it moves with the page) or pinned in
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.
@@ -23,20 +42,41 @@ interface PanelDef {
23
42
  readonly max: number;
24
43
  readonly natural: number;
25
44
  };
45
+ /**
46
+ * Its height as a section of a stack column (opt-in): it gets its natural height, the column's last open section
47
+ * takes the rest, and when the column is short sections fold to bars by give-way. Without it a section shares the
48
+ * column's height equally with the others, as before.
49
+ */
50
+ readonly height?: {
51
+ readonly min: number;
52
+ readonly natural: number;
53
+ };
26
54
  /** A float's size limits and natural size (default: its natural width, 360 px tall, no smaller than 160 × 120). */
27
55
  readonly float?: {
28
56
  readonly min: Size;
29
57
  readonly natural: Size;
30
58
  };
31
- /** Where it may dock (default: both sides). */
32
- readonly sides?: readonly Side[];
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
+ };
33
67
  /** May it float (default: yes). */
34
68
  readonly floats?: boolean;
35
69
  }
36
- /** A full-height column: its panels top to bottom, and its stored width (the layout clamps it to its panels' limits). */
70
+ /**
71
+ * A full-height column: its panels top to bottom, and its stored width (the layout clamps it to its panels' limits).
72
+ * `show` "tabs" shows one panel at a time under a strip of tabs: `active` (default, or when `active` isn't one of
73
+ * them: the first panel in the column that isn't closed).
74
+ */
37
75
  interface Column {
38
76
  readonly panels: readonly string[];
39
77
  readonly width: number;
78
+ readonly show?: "stack" | "tabs";
79
+ readonly active?: string;
40
80
  }
41
81
  /** A floating panel: `rect` in page space, or in view space when `pinned`. */
42
82
  interface FloatAt {
@@ -44,6 +84,11 @@ interface FloatAt {
44
84
  readonly rect: Rect;
45
85
  readonly pinned?: boolean;
46
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
+ }
47
92
  /** Logical times: when a panel was last opened, and last used (opened, focused, moved or unfolded). */
48
93
  interface Clock {
49
94
  readonly opened: number;
@@ -61,6 +106,8 @@ interface PanelsState {
61
106
  /** Not shown at all (they keep their place, for when they open again). */
62
107
  readonly closed: readonly string[];
63
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>>>;
64
111
  }
65
112
  /** The page's offset and scale in the view: a page point p shows at `x + p.x * scale`, `y + p.y * scale`. */
66
113
  interface View {
@@ -100,16 +147,28 @@ interface PanelsOptions {
100
147
  /** A rail segment's height, and the gap above the first one (defaults 36 and 4). */
101
148
  readonly segment: number;
102
149
  readonly railInset: number;
150
+ /** A tabbed column's strip height (default 28). */
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;
103
158
  }
104
159
  declare const DEFAULT_PANELS_OPTIONS: PanelsOptions;
105
160
  /** A float's size when its def gives none: this tall, and never smaller than FLOAT_MIN. */
106
161
  declare const FLOAT_HEIGHT = 360;
107
162
  declare const FLOAT_MIN: Size;
108
- /** 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. */
109
164
  type Where = {
110
165
  readonly kind: "column";
111
166
  readonly side: Side;
112
167
  readonly index: number;
168
+ } | {
169
+ readonly kind: "band";
170
+ readonly edge: Edge;
171
+ readonly index: number;
113
172
  } | {
114
173
  readonly kind: "float";
115
174
  readonly float: FloatAt;
@@ -125,15 +184,26 @@ declare function floatSize(def: PanelDef | undefined): {
125
184
  min: Size;
126
185
  natural: Size;
127
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;
128
195
  /**
129
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;
130
- * floating or nowhere, its natural width.
197
+ * in a band, floating or nowhere, its natural width.
131
198
  */
132
199
  declare function ownWidth(defs: readonly PanelDef[], state: PanelsState, id: string): number;
133
200
  interface PanelsStart {
134
201
  /** Each side's columns from the outer edge inward, each a list of panel ids top to bottom. */
135
202
  readonly left?: readonly (readonly string[])[];
136
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[];
137
207
  /** Floating panels: where (page space, or view space when pinned); the size defaults to the def's natural size. */
138
208
  readonly floats?: readonly {
139
209
  readonly id: string;
@@ -149,32 +219,54 @@ interface PanelsStart {
149
219
  }
150
220
  /**
151
221
  * A state from a plain start: each column as wide as the widest natural width of its panels (within their limits),
152
- * each float its natural size. The clock counts up in the order the panels are listed (left, right, floats), so the
153
- * 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.
154
224
  */
155
225
  declare function createPanels(defs: readonly PanelDef[], start: PanelsStart): PanelsState;
156
- /** The state with `id` taken out of its column (an emptied column goes) or the floats. Nothing else changes. */
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
+ */
157
230
  declare function liftPanel(state: PanelsState, id: string): PanelsState;
158
231
  /**
159
232
  * Open a panel: it shows again where it was, and it is the newest opened and used. A panel placed nowhere goes into
160
- * a new innermost column on `at.side`, `at.width` wide; without `at` it stays placed nowhere.
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.
161
236
  */
162
237
  declare function open(state: PanelsState, id: string, at?: {
163
238
  readonly side: Side;
164
239
  readonly width: number;
240
+ } | {
241
+ readonly edge: Edge;
242
+ readonly height?: number;
165
243
  }): PanelsState;
166
244
  /** Close a panel: it isn't shown, keeps its place, and is no longer kept open. */
167
245
  declare const close: (state: PanelsState, id: string) => PanelsState;
168
246
  /** Focus a panel: it is the newest used; a float comes to the top. */
169
247
  declare function focus(state: PanelsState, id: string): PanelsState;
170
- /** Fold a panel to its title bar by hand, or unfold it (unfolding is a use). */
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
+ */
171
252
  declare function toggleFold(state: PanelsState, id: string): PanelsState;
172
- /** 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. */
173
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;
174
263
  interface DockOptions {
175
264
  /** Stack into the column at `index` (at its bottom) instead of making a new column there. */
176
265
  readonly into?: boolean;
177
- /** A new column's width (default: the width of the column the panel leaves, else 0, which the layout clamps to the minimum). */
266
+ /**
267
+ * A new column's width (default: the width of the column the panel leaves, else 0, which the layout clamps to the
268
+ * minimum; from a band, pass `ownWidth` for its natural width, as the drop targets do).
269
+ */
178
270
  readonly width?: number;
179
271
  }
180
272
  /**
@@ -183,6 +275,10 @@ interface DockOptions {
183
275
  * keeps whether it is kept open.
184
276
  */
185
277
  declare function dock(state: PanelsState, id: string, side: Side, index: number, options?: DockOptions): PanelsState;
278
+ /** Show a column's panels as tabs (one at a time under a strip), or as a stack again. */
279
+ declare function showTabs(state: PanelsState, side: Side, index: number, on: boolean): PanelsState;
280
+ /** Make a docked panel the one its column shows (its tab), and the newest used. */
281
+ declare function activate(state: PanelsState, id: string): PanelsState;
186
282
  /**
187
283
  * Float a panel at `rect` (page space; view space when pinned). A float stays pinned or not unless `pinned` says;
188
284
  * a docked panel floats unpinned. It shows, it is the newest used and on top, and it is no longer kept open.
@@ -243,17 +339,18 @@ declare function samePlaces(a: PanelsState, b: PanelsState, defs?: readonly Pane
243
339
  */
244
340
 
245
341
  /**
246
- * Where a panel is, structurally: an open part of a column, a folded title bar (in a column, riding on one, or a
247
- * folded float), a segment of a rail (the panel itself isn't laid out), or a float.
342
+ * Where a panel is, structurally: an open part of a column, an open part of a band, a folded title bar (in a column,
343
+ * 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
344
+ * float.
248
345
  */
249
- type PanelKind = "column" | "bar" | "segment" | "float";
346
+ type PanelKind = "column" | "band" | "bar" | "segment" | "float";
250
347
  interface PlacedPanel {
251
348
  /** Stage px; for a segment, the segment's rect in its rail. */
252
349
  readonly rect: Rect;
253
350
  readonly kind: PanelKind;
254
- /** Columns and rails 0, floats 10 and up (a later float on top). */
351
+ /** Columns, rails and reserved bands 0, overlay bands 5, floats 10 and up (a later float on top). */
255
352
  readonly layer: number;
256
- /** In a rail: there is no panel to lay out, only its segment. */
353
+ /** Not drawn as a panel: in a rail (only its segment shows), or a tab that isn't showing (only its `tab`). */
257
354
  readonly hidden: boolean;
258
355
  /** Folded by hand (a bar, or a segment of a column folded by hand), or by give-way (a segment). */
259
356
  readonly folded: null | "hand" | "auto";
@@ -268,9 +365,36 @@ interface PlacedPanel {
268
365
  readonly column?: number;
269
366
  /** A riding bar: the index of the column it rides on (`options.fold` "ride"). */
270
367
  readonly rides?: number;
368
+ /** In a tabbed column: its tab's rect in the strip (panel order, equal widths). */
369
+ readonly tab?: Rect;
271
370
  /** A float the clamp moved or resized. */
272
371
  readonly clamped?: boolean;
372
+ /** In a band: its edge and its index in the state's band (left to right). */
373
+ readonly edge?: Edge;
374
+ readonly index?: number;
375
+ }
376
+ /** A band as laid out. */
377
+ interface PlacedBand {
378
+ readonly edge: Edge;
379
+ /** The band's rect (a bar when folded). */
380
+ readonly rect: Rect;
381
+ /** Its stored height clamped to its panels' limits, and those limits. */
382
+ readonly height: number;
383
+ readonly min: number;
384
+ readonly max: number;
385
+ /** null: open; "hand": its panels folded by hand; "auto": folded by give-way. */
386
+ readonly folded: null | "hand" | "auto";
387
+ /** Shrunk by give-way below its height. */
388
+ readonly shrunk: boolean;
389
+ /** It holds a kept panel. */
390
+ readonly kept: boolean;
391
+ readonly mode: "reserved" | "overlay";
392
+ readonly span: "between" | "full";
393
+ /** The shown panels, left to right. */
394
+ readonly panels: readonly string[];
273
395
  }
396
+ /** A reserve's edge. */
397
+ type ReserveEdge = "top" | "right" | "bottom" | "left";
274
398
  interface PlacedColumn {
275
399
  readonly side: Side;
276
400
  /** The column's index in the state. */
@@ -291,6 +415,11 @@ interface PlacedColumn {
291
415
  readonly panels: readonly string[];
292
416
  /** Riding: the index of the column its bars ride on; its rect is the bars'. */
293
417
  readonly rides?: number;
418
+ /** How it shows its panels (default "stack"). */
419
+ readonly show?: "stack" | "tabs";
420
+ /** Tabbed and laid out: its strip of tabs, and the panel it shows. */
421
+ readonly strip?: Rect;
422
+ readonly active?: string;
294
423
  }
295
424
  interface PlacedRail {
296
425
  readonly side: Side;
@@ -300,8 +429,8 @@ interface PlacedRail {
300
429
  readonly rect: Rect;
301
430
  }[];
302
431
  }
303
- type PanelsNoteCode = "column-shrunk" | "column-folded" | "kept-folded" | "pages-under-min" | "float-clamped" | "float-resized";
304
- /** One note on a layout: a code and its data. */
432
+ 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";
433
+ /** One note on a layout: a code and its data. `kept-folded` carries `side` and `column` for a column, `edge` for a band. */
305
434
  type PanelsNote = {
306
435
  readonly code: "column-shrunk";
307
436
  readonly side: Side;
@@ -310,7 +439,7 @@ type PanelsNote = {
310
439
  readonly from: number;
311
440
  readonly to: number;
312
441
  } | {
313
- readonly code: "column-folded" | "kept-folded";
442
+ readonly code: "column-folded" | "kept-folded" | "section-folded";
314
443
  readonly side: Side;
315
444
  readonly column: number;
316
445
  readonly items: readonly string[];
@@ -321,6 +450,20 @@ type PanelsNote = {
321
450
  } | {
322
451
  readonly code: "float-clamped" | "float-resized";
323
452
  readonly items: readonly string[];
453
+ } | {
454
+ readonly code: "band-shrunk";
455
+ readonly edge: Edge;
456
+ readonly items: readonly string[];
457
+ readonly from: number;
458
+ readonly to: number;
459
+ } | {
460
+ readonly code: "band-folded" | "kept-folded" | "band-off";
461
+ readonly edge: Edge;
462
+ readonly items: readonly string[];
463
+ } | {
464
+ readonly code: "pages-short";
465
+ readonly height: number;
466
+ readonly min: number;
324
467
  };
325
468
  interface PanelsLayout {
326
469
  readonly items: Map<string, PlacedPanel>;
@@ -330,6 +473,10 @@ interface PanelsLayout {
330
473
  readonly notes: readonly PanelsNote[];
331
474
  /** What is left for the documents. */
332
475
  readonly pages: Rect;
476
+ /** The bands laid out (an enabled edge with shown panels). */
477
+ readonly bands: Readonly<Partial<Record<Edge, PlacedBand>>>;
478
+ /** The room kept clear along the pages' edges (an edge with a reserve over 0). */
479
+ readonly reserved: Readonly<Partial<Record<ReserveEdge, Rect>>>;
333
480
  }
334
481
  /** The order columns give way in: unkept before kept, then the policy (oldest or newest), outer first, left first. */
335
482
  declare function giveWayOrder<C extends {
@@ -363,12 +510,15 @@ interface Target {
363
510
  * - `into:<side>:<i>` (2): a column's area: the panel stacks at its bottom.
364
511
  * - `rail:<side>` (1): the side's rail, or its outer edge: the panel docks folded.
365
512
  * - `float` (3, free): anywhere; it floats where it is let go, kept in the view as the float option says.
513
+ * - `band:<edge>:<i>` (2), for each edge with a band (`options.bands`): the slots between a band's panels and at both
514
+ * ends (the band's area split at its panels' middles). `band:<edge>` (2): an empty enabled edge, a strip `2 × bar`
515
+ * tall along it inside the pages' area.
366
516
  *
367
517
  * A place the panel may not take (its def's `sides` and `floats`, and `allows`) is no target, and neither is its own
368
518
  * place (a drop there changes nothing). Targets carry a structured `place`, never words: the consumer names them.
369
519
  */
370
520
 
371
- /** Where a drop puts a panel. `index` is a column index in the state with the panel lifted out. */
521
+ /** Where a drop puts a panel. `index` is a column (or band panel) index in the state with the panel lifted out. */
372
522
  type PanelPlace = {
373
523
  readonly kind: "column";
374
524
  readonly side: Side;
@@ -380,6 +530,10 @@ type PanelPlace = {
380
530
  } | {
381
531
  readonly kind: "rail";
382
532
  readonly side: Side;
533
+ } | {
534
+ readonly kind: "band";
535
+ readonly edge: Edge;
536
+ readonly index: number;
383
537
  } | {
384
538
  readonly kind: "float";
385
539
  };
@@ -405,7 +559,10 @@ interface PanelTargetInput {
405
559
  /** 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. */
406
560
  declare const COLUMN_REACH = 22;
407
561
  declare const RAIL_EDGE = 10;
408
- /** A place's rank in reading order: the left side outer to inner, the right side inner to outer, floating last. */
562
+ /**
563
+ * A place's rank in reading order: the left side outer to inner, the right side inner to outer, then the top band and
564
+ * the bottom band left to right, floating last.
565
+ */
409
566
  declare function placeRank(place: PanelPlace): number;
410
567
  /** Where a panel is now, as a place (a float, a column of its own, or stacked in one); null when placed nowhere. */
411
568
  declare function homePlace(state: PanelsState, id: string): PanelPlace | null;
@@ -451,4 +608,4 @@ interface PanelStopsOptions {
451
608
  /** The panel's places in reading order, for the arrow keys and a "Move to" menu (`keyboardStops` calls this). */
452
609
  declare function panelStops(targets: readonly PanelTarget[], options?: PanelStopsOptions): PanelStop[];
453
610
 
454
- export { resizeFloat as $, dock as A, float as B, type Clock as C, DEFAULT_PANELS_OPTIONS as D, floatSize as E, FLOAT_HEIGHT as F, type GiveWay as G, focus as H, IDENTITY_VIEW as I, giveWayOrder as J, homePlace as K, keep as L, layoutPanels as M, liftPanel as N, open as O, type PanelsState as P, ownWidth as Q, RAIL_EDGE as R, type Side as S, panelDrop as T, panelStops as U, type View as V, type Where as W, panelTargets as X, pin as Y, placeRank as Z, resizeColumn as _, type PanelDef as a, samePlaces as a0, tick as a1, toPage as a2, toView as a3, toggleFold as a4, whereIs as a5, type Target as a6, COLUMN_REACH as b, type Column as c, type DockOptions as d, FLOAT_MIN as e, type FloatAt as f, type PanelDrop as g, type PanelKind as h, type PanelPlace as i, type PanelStop as j, type PanelStopsOptions as k, type PanelTarget as l, type PanelTargetInput as m, type PanelsLayout as n, type PanelsNote as o, type PanelsNoteCode as p, type PanelsOptions as q, type PanelsStart as r, type PlacedColumn as s, type PlacedPanel as t, type PlacedRail as u, SIDES as v, close as w, columnWidth as x, createPanels as y, defOf as z };
611
+ 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 { a6 as Target, l as PanelTarget, k as PanelStopsOptions, j as PanelStop } from './targets-DqhZf3XZ.js';
1
+ import { al as Target, d as PanelTarget, t as PanelStopsOptions, s as PanelStop } from './targets-CLV69zMw.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
@@ -38,7 +38,7 @@ import {
38
38
  } from "./chunk-WLMJ6JGO.js";
39
39
  import {
40
40
  panelStops
41
- } from "./chunk-QR7MGDX6.js";
41
+ } from "./chunk-PJD5HKYX.js";
42
42
  import {
43
43
  centre,
44
44
  overlap,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@n-uf/placement",
3
- "version": "26.11.8",
3
+ "version": "26.11.10",
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",
@@ -48,6 +48,10 @@
48
48
  "types": "./dist/panels.d.ts",
49
49
  "default": "./dist/panels.js"
50
50
  },
51
+ "./desk": {
52
+ "types": "./dist/desk.d.ts",
53
+ "default": "./dist/desk.js"
54
+ },
51
55
  "./package.json": "./package.json"
52
56
  },
53
57
  "publishConfig": {