@sentropic/design-system-angular 0.36.59 → 0.36.61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,584 @@
1
+ import { Component, ContentChildren, ElementRef, EventEmitter, Input as NgInput, Output, QueryList } from "@angular/core";
2
+ import { classNames } from "./classNames.js";
3
+ import { PanelSection } from "./PanelSection.js";
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * Bound ratified by the chat consumer lane: beyond 4 sections, stacking
7
+ * collapsible regions in a pane capped at 640px makes scrolling unmanageable
8
+ * and the single-owner rule becomes untenable. Enforced as a dev-time
9
+ * `console.warn` in `register()` (this package's established convention —
10
+ * see NavActionStack/WaterfallChart — is to warn and degrade, never throw or
11
+ * silently truncate); exported here so the bound is also visible through
12
+ * types/docs to a consumer reading `PanelStackProps`. Mirrors
13
+ * `PanelStack.svelte`'s constant of the same name/value 1:1.
14
+ */
15
+ export const PANEL_STACK_MAX_SECTIONS = 4;
16
+ /**
17
+ * Default for the `primaryMinHeight` input below. The INPUT — not this
18
+ * constant — is the single source of truth for both the JS auto-collapse
19
+ * threshold (`resolvedPrimaryMinHeight`, fed into
20
+ * `computePanelStackAutoCollapse`'s `floorPx`) and the CSS floor: the host
21
+ * emits it as an inline `--st-component-panelStack-primaryMinBlockSize`
22
+ * custom property (see the `@Component` `host` binding), which styles.css's
23
+ * `.st-panelSection__body--scrollOwner` rule reads via `var(...)` — kept in
24
+ * sync with that stylesheet's `160px` var() fallback for the case where
25
+ * nothing sets the inline property. Not read back via `getComputedStyle`:
26
+ * this package's Node test environment has no DOM at all, which would make
27
+ * the threshold untestable; a hardcoded, documented, kept-in-sync numeric
28
+ * mirror of the CSS default is this codebase's existing pattern (see
29
+ * MenuPopover's `MIN_HEIGHT`/`GAP`). Mirrors `PanelStack.svelte`'s local
30
+ * `PRIMARY_MIN_BLOCK_SIZE_PX`.
31
+ */
32
+ const PRIMARY_MIN_BLOCK_SIZE_PX = 160;
33
+ /**
34
+ * Pure fallback-chain resolver for split-primary's scroll owner — mirrors
35
+ * `PanelStack.svelte`'s `effectivePrimary` derivation so it is unit-testable
36
+ * without any component/DOM machinery (see MenuPopover's
37
+ * `computeMenuPopoverPosition` for the established pattern).
38
+ *
39
+ * Tier 1: a `designatedPrimary` that matches a currently-registered id always
40
+ * wins. Tier 2: otherwise the first EXPANDED id in `orderedIds` (registration
41
+ * order is the tiebreak, never click order). Tier 3 (last resort): the first
42
+ * registered id, so the stack never degrades to zero scroll owners.
43
+ */
44
+ export function resolvePanelStackPrimary(designatedPrimary, orderedIds, openIds) {
45
+ if (designatedPrimary !== undefined && orderedIds.includes(designatedPrimary)) {
46
+ return designatedPrimary;
47
+ }
48
+ const firstExpanded = orderedIds.find((id) => openIds.has(id));
49
+ if (firstExpanded !== undefined)
50
+ return firstExpanded;
51
+ return orderedIds[0] ?? null;
52
+ }
53
+ /**
54
+ * Pure resolver for sticky-item's effective expanded/scroll-owner id — a
55
+ * SINGLE resolved value deliberately reused by the class for both
56
+ * `isExpanded` and `isScrollOwner` in that shape (see `effectiveExpandedId`).
57
+ * Splitting these into two different values would let a section render as
58
+ * the (visible, `overflow:auto`) scroll owner while its trigger reports
59
+ * `aria-expanded="false"` — a screen reader announcing "collapsed" for
60
+ * on-screen, scrolling content. sticky-item's contract is that "expanded"
61
+ * and "owns the scroll" are the same fact about the same section by
62
+ * definition, so this resolver is the one place that fact is decided, for
63
+ * both.
64
+ *
65
+ * The controlled counterpart to `effectiveExpandedId`'s uncontrolled
66
+ * fallback (which already resolves to the first registered id on its own).
67
+ * Mirrors `resolvePanelStackPrimary`'s last-resort tier so this package's
68
+ * Node test environment can exercise the decision without any
69
+ * component/DOM machinery.
70
+ *
71
+ * Ratified cross-framework rule: a controlled `expanded` is NEVER silently
72
+ * corrected — the caller must still expose the raw, possibly-invalid value
73
+ * back to the consumer (never rewritten, never fed through
74
+ * `onExpandedChange`) — that is about the PROP, not about what gets
75
+ * rendered: ARIA still has to describe the actual DOM, so the resolved
76
+ * (possibly healed) value below is what both `isExpanded` and
77
+ * `isScrollOwner` read. Two distinct controlled inputs are told apart here:
78
+ *
79
+ * - `expandedId` is a non-null id that names NO id in `orderedIds`: this is
80
+ * a MISTAKE (a stale/typo'd controlled value) — the consumer intended a
81
+ * section open and silently got none, which is exactly the "content
82
+ * unreachable by the wheel" state the stack must never reach. Falls back
83
+ * to the first registered id, identically to `resolvePanelStackPrimary`'s
84
+ * own tier 3.
85
+ * - `expandedId` is explicitly `null`: this is a DELIBERATE "everything
86
+ * collapsed" — honoured as-is, no fallback. An all-collapsed stack shows
87
+ * no content at all, so nothing is unreachable; zero scroll owners is the
88
+ * correct, legitimate outcome here.
89
+ */
90
+ export function resolvePanelStackExpanded(expandedId, orderedIds) {
91
+ if (expandedId === null)
92
+ return null;
93
+ if (orderedIds.includes(expandedId))
94
+ return expandedId;
95
+ return orderedIds[0] ?? null;
96
+ }
97
+ /**
98
+ * THE auto-collapse decision, factored out as a pure function (per
99
+ * MenuPopover's `computeMenuPopoverPosition` precedent) so it is testable
100
+ * without ResizeObserver/DOM: this package's Node test environment has
101
+ * neither. Mirrors `PanelStack.svelte`'s decision `$effect` body exactly.
102
+ *
103
+ * Returns the id of AT MOST ONE new secondary to auto-collapse this pass, or
104
+ * `null` if nothing needs to (either it already fits, or nothing is left to
105
+ * collapse — the degenerate "pane too small even fully collapsed" case).
106
+ *
107
+ * Convergence / no-avalanche contract: this function is a pure read of the
108
+ * measurements and state PASSED IN — it never reads or writes any component
109
+ * field itself, and it never returns more than one id per call. A caller
110
+ * that re-invokes it once per REAL measurement update (the pattern used by
111
+ * `PanelStack`'s ResizeObserver callback and `toggle()`) therefore collapses
112
+ * at most one NEW secondary per pass, using measurements that are always
113
+ * either accurate (untouched by this pass) or correctly reflect an EARLIER
114
+ * pass once the observer catches up — never a same-tick avalanche. Calling
115
+ * it again with IDENTICAL inputs (e.g. a duplicate/no-op resize delivery)
116
+ * always returns `null` once the fixed point is reached: `autoCollapsed`
117
+ * already contains every viable candidate, so the `.find()` below yields
118
+ * nothing new — no oscillation.
119
+ */
120
+ export function computePanelStackAutoCollapse(measurements, floorPx = PRIMARY_MIN_BLOCK_SIZE_PX) {
121
+ const { primaryId, stackHeight, primaryHeaderHeight, secondaryIds, rootHeights, openSecondary, autoCollapsed, expansionOrder } = measurements;
122
+ if (stackHeight === 0)
123
+ return null; // not measured yet — nothing to decide.
124
+ let secondaryTotal = 0;
125
+ for (const id of secondaryIds) {
126
+ secondaryTotal += rootHeights.get(id) ?? 0;
127
+ }
128
+ const available = stackHeight - primaryHeaderHeight - secondaryTotal;
129
+ if (available >= floorPx)
130
+ return null;
131
+ const candidate = expansionOrder.find((id) => id !== primaryId && openSecondary.has(id) && !autoCollapsed.has(id));
132
+ return candidate ?? null;
133
+ }
134
+ /**
135
+ * Stacks several `PanelSection` contents inside ONE panel so a docked chat
136
+ * can share a pane with other content. The invariant is the whole point:
137
+ * exactly one section's body has `overflow: auto` at any moment, and the
138
+ * stack itself NEVER scrolls — see `PanelSection.ts` for the single scrolling
139
+ * declaration in this component pair.
140
+ *
141
+ * Faithful Angular port of `PanelStack.svelte`. See that file for the
142
+ * ratified contract this mirrors; the notable Angular-specific departures,
143
+ * all forced by this platform (documented in depth at each site below):
144
+ *
145
+ * - Coordination with `PanelSection` children is NOT Svelte-style context
146
+ * (`setContext`/`getContext`). Angular constructor DI would be the direct
147
+ * analog, but it needs `@Optional()`/`@Inject()` PARAMETER decorators,
148
+ * which this package's tsconfig cannot compile (no `experimentalDecorators`
149
+ * — the whole package already relies on standard/Ivy decorators for
150
+ * class/property positions only). Instead `PanelStack` discovers its
151
+ * sections via `@ContentChildren` and pushes `isPrimary`/`expanded`/
152
+ * `scrollOwner` directly onto each instance — the SAME "parent owns
153
+ * projected children's state" idiom `SelectableList` already established
154
+ * for its `SelectableRow` children in this exact package.
155
+ * - Registration order substitutes for Svelte's DOM-order-via-
156
+ * `compareDocumentPosition` fallback: `@ContentChildren` (and this
157
+ * package's Node test environment, which has no DOM at all) both already
158
+ * hand entries over in call/DOM order, so no separate re-sort is needed.
159
+ * - No `ChangeDetectorRef`/`markForCheck` — matching this package's existing
160
+ * idiom of relying on zone.js's default full-tree change detection (same
161
+ * as `MenuPopover`'s window-listener-driven position updates).
162
+ */
163
+ export class PanelStack {
164
+ host;
165
+ static stComponentName = "PanelStack";
166
+ componentName = "PanelStack";
167
+ shape = "sticky-item";
168
+ label;
169
+ /** sticky-item, controlled: id of the expanded section. Presence (including
170
+ * an explicit `null`) is what makes the stack controlled — same
171
+ * undefined-vs-set idiom as `AppShell.panelWidths`. */
172
+ expanded;
173
+ defaultExpanded = null;
174
+ /** Svelte-canonical callback. */
175
+ onExpandedChange;
176
+ /** Angular-idiom addition (not in the Svelte contract): enables
177
+ * `[(expanded)]` two-way binding alongside `onExpandedChange`. */
178
+ expandedChange = new EventEmitter();
179
+ primary;
180
+ primaryMinHeight;
181
+ classInput;
182
+ sectionsQuery;
183
+ // --- Registration -----------------------------------------------------
184
+ entries = [];
185
+ internalExpanded = null;
186
+ openSecondary = new Set();
187
+ autoCollapsed = new Set();
188
+ expansionOrder = [];
189
+ rootHeights = new Map();
190
+ stackHeight = 0;
191
+ primaryHeaderHeight = 0;
192
+ resizeObserver = null;
193
+ observedPrimaryHeaderEl = null;
194
+ /** Dev-time "warned once" latch for a controlled `expanded` naming no
195
+ * registered section — see `effectiveExpandedId`. Guards the
196
+ * `console.warn` only, never the fallback resolution itself (which must
197
+ * always resolve a scroll owner). Never reset: the contract is "a
198
+ * console.warn once" (per instance), not "once per distinct bad id". */
199
+ warnedInvalidExpanded = false;
200
+ // --- @ContentChildren glue: reconcile the discovered PanelSection
201
+ // instances against `entries`/subscriptions, and push state back onto
202
+ // them. All of THIS is Angular wiring; the actual decisions it calls into
203
+ // (`register`, `toggle`, `isPrimary`, ...) are plain, DOM/Angular-agnostic
204
+ // methods below, directly callable (and tested) on a bare `new PanelStack()`.
205
+ childUnregister = new Map();
206
+ childToggleSub = new Map();
207
+ sectionsChangesSub = null;
208
+ constructor(host) {
209
+ this.host = host;
210
+ }
211
+ ngOnInit() {
212
+ // One-time SEED, not a live binding to `defaultExpanded` — same idiom as
213
+ // RangeSlider's `defaultValue` (Svelte: `untrack(() => defaultExpanded)`).
214
+ this.internalExpanded = this.defaultExpanded;
215
+ }
216
+ ngAfterContentInit() {
217
+ this.syncSections();
218
+ this.sectionsChangesSub = this.sectionsQuery?.changes.subscribe(() => this.syncSections()) ?? null;
219
+ }
220
+ ngAfterViewInit() {
221
+ const observer = this.ensureResizeObserver();
222
+ observer?.observe(this.host.nativeElement);
223
+ }
224
+ ngOnChanges(changes) {
225
+ if (changes["primary"] || changes["shape"] || changes["primaryMinHeight"]) {
226
+ this.syncPrimaryHeaderObserver();
227
+ this.runAutoCollapseDecision();
228
+ }
229
+ if (changes["primary"] ||
230
+ changes["shape"] ||
231
+ changes["expanded"] ||
232
+ changes["defaultExpanded"] ||
233
+ changes["primaryMinHeight"]) {
234
+ this.applyStateToChildren();
235
+ }
236
+ }
237
+ ngOnDestroy() {
238
+ this.sectionsChangesSub?.unsubscribe();
239
+ this.sectionsChangesSub = null;
240
+ for (const sub of this.childToggleSub.values())
241
+ sub.unsubscribe();
242
+ this.childToggleSub.clear();
243
+ for (const unregister of this.childUnregister.values())
244
+ unregister();
245
+ this.childUnregister.clear();
246
+ // Release every observation (stack, primary header, every entry) in one
247
+ // shot — a leaked observer is a real bug.
248
+ this.resizeObserver?.disconnect();
249
+ this.resizeObserver = null;
250
+ this.observedPrimaryHeaderEl = null;
251
+ }
252
+ get hostClass() {
253
+ return classNames("st-panelStack", this.classInput);
254
+ }
255
+ get controlled() {
256
+ return this.expanded !== undefined;
257
+ }
258
+ /**
259
+ * sticky-item: the controlled branch NEVER rewrites `this.expanded` (the
260
+ * controlled contract is absolute — no self-correction, no synthetic
261
+ * `onExpandedChange`/`expandedChange` call), but it DOES resolve through
262
+ * `resolvePanelStackExpanded` so every DERIVED read (`isExpanded`,
263
+ * `isScrollOwner`) sees a healed value: a non-null `expanded` naming no
264
+ * registered section falls back to the first registered id (with a
265
+ * one-time dev warning below); an explicit `null` is a deliberate
266
+ * "everything collapsed" and is returned as-is. Guarded by
267
+ * `this.entries.length > 0` so a controlled value isn't flagged as
268
+ * "invalid" before any `PanelSection` has had a chance to register yet.
269
+ */
270
+ get effectiveExpandedId() {
271
+ if (this.controlled) {
272
+ const rawExpanded = this.expanded ?? null;
273
+ // Explicit null: deliberate "everything collapsed" — honoured as-is,
274
+ // never escalated to the fallback below (see resolvePanelStackExpanded's
275
+ // doc). No sections registered yet: defer judgment entirely — a
276
+ // controlled value isn't "invalid" before any `PanelSection` has had a
277
+ // chance to register, so return it untouched rather than resolving
278
+ // against an empty list (which would otherwise heal it to `null`).
279
+ if (rawExpanded === null)
280
+ return null;
281
+ const orderedIds = this.entries.map((e) => e.id);
282
+ if (orderedIds.length === 0)
283
+ return rawExpanded;
284
+ const resolved = resolvePanelStackExpanded(rawExpanded, orderedIds);
285
+ if (resolved !== rawExpanded && !this.warnedInvalidExpanded) {
286
+ this.warnedInvalidExpanded = true;
287
+ console.warn(`[PanelStack] expanded="${rawExpanded}" does not match any registered section — the controlled value is left untouched, but "${resolved}" is resolved internally as the scroll owner so the stack never has zero.`);
288
+ }
289
+ return resolved;
290
+ }
291
+ if (this.internalExpanded !== null && this.entries.some((e) => e.id === this.internalExpanded)) {
292
+ return this.internalExpanded;
293
+ }
294
+ return this.entries[0]?.id ?? null;
295
+ }
296
+ get effectivePrimary() {
297
+ if (this.shape !== "split-primary")
298
+ return null;
299
+ return resolvePanelStackPrimary(this.primary, this.entries.map((e) => e.id), this.openSecondary);
300
+ }
301
+ /** Resolved floor fed to `computePanelStackAutoCollapse`'s `floorPx` —
302
+ * falls back to `PRIMARY_MIN_BLOCK_SIZE_PX` (the same value as the CSS
303
+ * fallback) when `primaryMinHeight` is unset. */
304
+ get resolvedPrimaryMinHeight() {
305
+ return this.primaryMinHeight ?? PRIMARY_MIN_BLOCK_SIZE_PX;
306
+ }
307
+ /** Inline value for the host's `--st-component-panelStack-primaryMinBlockSize`
308
+ * custom property — see the `host` binding in the `@Component` decorator.
309
+ * `resolvedPrimaryMinHeight` is the single source of truth this is
310
+ * derived from, so the JS threshold and the CSS floor can never drift
311
+ * apart. */
312
+ get primaryMinHeightStyle() {
313
+ return `${this.resolvedPrimaryMinHeight}px`;
314
+ }
315
+ isPrimary(id) {
316
+ return this.shape === "split-primary" && id === this.effectivePrimary;
317
+ }
318
+ isExpanded(id) {
319
+ if (this.shape === "split-primary") {
320
+ if (id === this.effectivePrimary)
321
+ return true;
322
+ return this.openSecondary.has(id) && !this.autoCollapsed.has(id);
323
+ }
324
+ return id === this.effectiveExpandedId;
325
+ }
326
+ isScrollOwner(id) {
327
+ return this.shape === "split-primary" ? id === this.effectivePrimary : id === this.effectiveExpandedId;
328
+ }
329
+ toggle(id) {
330
+ if (this.shape === "split-primary") {
331
+ if (id === this.effectivePrimary)
332
+ return; // primary has no disclosure button; guard anyway.
333
+ const primaryBefore = this.effectivePrimary;
334
+ // Toggle acts on what's currently RENDERED (isExpanded), not the raw
335
+ // openSecondary flag, so a click on an auto-collapsed (visually
336
+ // closed) section always reads as "open it", never a confusing
337
+ // second "close" of a section the user already sees as closed.
338
+ if (this.isExpanded(id)) {
339
+ this.openSecondary.delete(id);
340
+ this.expansionOrder = this.expansionOrder.filter((x) => x !== id);
341
+ }
342
+ else {
343
+ this.openSecondary.add(id);
344
+ this.autoCollapsed.delete(id);
345
+ // Move to the most-recently-expanded end — an explicit re-open
346
+ // always makes this section the LAST one the algorithm would
347
+ // collapse again.
348
+ this.expansionOrder = [...this.expansionOrder.filter((x) => x !== id), id];
349
+ }
350
+ // Deliberately do NOT re-run the auto-collapse decision unconditionally
351
+ // here: `openSecondary`/`autoCollapsed`/`expansionOrder` are exactly
352
+ // the state this decision WRITES (mirrors PanelStack.svelte's `untrack`
353
+ // of those three inside its decision effect) — re-deciding off them
354
+ // synchronously, before the browser has actually re-laid-out and a
355
+ // real ResizeObserver measurement has landed, would judge the toggle's
356
+ // visual consequence using STALE sizes and could collapse the wrong
357
+ // section. Only re-decide here in the one case a toggle can change a
358
+ // TRACKED dependency: `effectivePrimary` itself shifting (split-primary
359
+ // tier 2/3, `primary` unset — opening/closing a secondary can change
360
+ // which one is "first expanded"). Every other case waits for the next
361
+ // real ResizeObserver delivery, exactly like Svelte's effect does.
362
+ if (this.effectivePrimary !== primaryBefore) {
363
+ this.syncPrimaryHeaderObserver();
364
+ this.runAutoCollapseDecision();
365
+ }
366
+ return;
367
+ }
368
+ // sticky-item: radio semantics — clicking the already-expanded header
369
+ // (including the first-section fallback) is a no-op, there is no
370
+ // "collapse to zero" gesture.
371
+ if (this.effectiveExpandedId === id)
372
+ return;
373
+ this.setExpanded(id);
374
+ }
375
+ /** Register a section's root AND header element, in registration order;
376
+ * returns an unregister callback. NOT just bookkeeping — the stack falls
377
+ * back to the first registered section as the scroll owner whenever
378
+ * nothing else designates one (unset/stale `expanded` or `primary`), so
379
+ * the invariant "exactly one scroll owner whenever the stack has >=1
380
+ * section" holds even for a misconfigured or dynamically-changing stack.
381
+ * Plain, DOM-agnostic bookkeeping — safe to call directly from tests with
382
+ * fake element objects (no real DOM required: `el`/`headerEl` are only
383
+ * ever compared by identity or handed to `ResizeObserver.observe`, which
384
+ * is itself guarded for absence below). */
385
+ register(id, el, headerEl) {
386
+ this.entries = [...this.entries.filter((e) => e.el !== el), { id, el, headerEl }];
387
+ // Dev-time visibility only — see PANEL_STACK_MAX_SECTIONS' doc comment.
388
+ // Never truncated/hidden: every registered section still renders and
389
+ // participates normally, this is a nudge, not an enforcement mechanism.
390
+ if (this.entries.length > PANEL_STACK_MAX_SECTIONS) {
391
+ console.warn(`[PanelStack] ${this.entries.length} sections registered — the stack is designed for at most ${PANEL_STACK_MAX_SECTIONS}. Beyond that, stacked collapsible regions in a capped pane become unmanageable to scroll and the single-scroll-owner contract gets hard to reason about. Consider splitting into multiple panes.`);
392
+ }
393
+ const observer = this.ensureResizeObserver();
394
+ observer?.observe(el);
395
+ this.syncPrimaryHeaderObserver();
396
+ this.runAutoCollapseDecision();
397
+ return () => {
398
+ observer?.unobserve(el);
399
+ this.entries = this.entries.filter((e) => e.el !== el);
400
+ // Drop any stale open/closed/measurement record for a section that no
401
+ // longer exists, so a LATER section re-registered under the same id
402
+ // doesn't silently inherit a dead instance's state.
403
+ this.openSecondary.delete(id);
404
+ this.autoCollapsed.delete(id);
405
+ this.expansionOrder = this.expansionOrder.filter((x) => x !== id);
406
+ this.rootHeights.delete(id);
407
+ this.syncPrimaryHeaderObserver();
408
+ this.runAutoCollapseDecision();
409
+ };
410
+ }
411
+ setExpanded(id) {
412
+ if (!this.controlled)
413
+ this.internalExpanded = id;
414
+ this.onExpandedChange?.(id);
415
+ this.expandedChange.emit(id);
416
+ this.applyStateToChildren();
417
+ }
418
+ // --- @ContentChildren reconciliation -----------------------------------
419
+ syncSections() {
420
+ const list = this.sectionsQuery?.toArray() ?? [];
421
+ const live = new Set(list);
422
+ for (const [section, unregister] of [...this.childUnregister]) {
423
+ if (!live.has(section)) {
424
+ unregister();
425
+ this.childUnregister.delete(section);
426
+ this.childToggleSub.get(section)?.unsubscribe();
427
+ this.childToggleSub.delete(section);
428
+ }
429
+ }
430
+ for (const section of list) {
431
+ if (this.childUnregister.has(section))
432
+ continue;
433
+ const headerEl = section.headerElement;
434
+ if (!headerEl)
435
+ continue;
436
+ this.childUnregister.set(section, this.register(section.id, section.rootElement, headerEl));
437
+ this.childToggleSub.set(section, section.toggleRequested.subscribe((id) => {
438
+ this.toggle(id);
439
+ this.applyStateToChildren();
440
+ }));
441
+ }
442
+ this.applyStateToChildren();
443
+ }
444
+ applyStateToChildren() {
445
+ for (const section of this.sectionsQuery?.toArray() ?? []) {
446
+ section.isPrimary = this.isPrimary(section.id);
447
+ section.expanded = this.isExpanded(section.id);
448
+ section.scrollOwner = this.isScrollOwner(section.id);
449
+ }
450
+ }
451
+ // --- Measurement (split-primary auto-collapse) -------------------------
452
+ ensureResizeObserver() {
453
+ if (this.resizeObserver)
454
+ return this.resizeObserver;
455
+ // Guard: this package's Node test environment (and some SSR/older
456
+ // environments) has no ResizeObserver at all. Auto-collapse simply never
457
+ // engages there — `stackHeight` stays 0, `computePanelStackAutoCollapse`
458
+ // is a permanent no-op — rather than throwing.
459
+ if (typeof ResizeObserver === "undefined")
460
+ return null;
461
+ this.resizeObserver = new ResizeObserver((observedEntries) => {
462
+ for (const entry of observedEntries) {
463
+ const height = entry.contentRect.height;
464
+ if (entry.target === this.host.nativeElement) {
465
+ this.stackHeight = height;
466
+ }
467
+ else if (entry.target === this.observedPrimaryHeaderEl) {
468
+ this.primaryHeaderHeight = height;
469
+ }
470
+ else {
471
+ const found = this.entries.find((e) => e.el === entry.target);
472
+ if (found)
473
+ this.rootHeights.set(found.id, height);
474
+ }
475
+ }
476
+ // One decision pass per DELIVERY (which may batch several targets),
477
+ // never per-target — matches the pure function's one-collapse-per-call
478
+ // contract and avoids a same-tick avalanche.
479
+ this.runAutoCollapseDecision();
480
+ this.applyStateToChildren();
481
+ });
482
+ return this.resizeObserver;
483
+ }
484
+ /** Retarget the header observer whenever the primary changes (designation,
485
+ * fallback resolution, or a section registering/unregistering). */
486
+ syncPrimaryHeaderObserver() {
487
+ const primaryId = this.effectivePrimary;
488
+ const nextHeaderEl = primaryId ? (this.entries.find((e) => e.id === primaryId)?.headerEl ?? null) : null;
489
+ const observer = this.ensureResizeObserver();
490
+ if (!observer) {
491
+ this.observedPrimaryHeaderEl = nextHeaderEl;
492
+ return;
493
+ }
494
+ if (this.observedPrimaryHeaderEl && this.observedPrimaryHeaderEl !== nextHeaderEl) {
495
+ observer.unobserve(this.observedPrimaryHeaderEl);
496
+ }
497
+ if (nextHeaderEl && nextHeaderEl !== this.observedPrimaryHeaderEl) {
498
+ observer.observe(nextHeaderEl);
499
+ }
500
+ this.observedPrimaryHeaderEl = nextHeaderEl;
501
+ }
502
+ /** THE decision, driven off whatever measurements are CURRENTLY known.
503
+ * Called after every event that could change what "fits" means (a fresh
504
+ * ResizeObserver delivery, a toggle, a register/unregister, a `primary`/
505
+ * `shape` input change) — safe to over-call: `computePanelStackAutoCollapse`
506
+ * is a pure, idempotent read that returns `null` once nothing more needs
507
+ * to collapse, so redundant calls are no-ops. */
508
+ runAutoCollapseDecision() {
509
+ if (this.shape !== "split-primary")
510
+ return;
511
+ const primaryId = this.effectivePrimary;
512
+ if (primaryId === null)
513
+ return;
514
+ const secondaryIds = this.entries.filter((e) => e.id !== primaryId).map((e) => e.id);
515
+ const candidate = computePanelStackAutoCollapse({
516
+ primaryId,
517
+ stackHeight: this.stackHeight,
518
+ primaryHeaderHeight: this.primaryHeaderHeight,
519
+ secondaryIds,
520
+ rootHeights: this.rootHeights,
521
+ openSecondary: this.openSecondary,
522
+ autoCollapsed: this.autoCollapsed,
523
+ expansionOrder: this.expansionOrder,
524
+ }, this.resolvedPrimaryMinHeight);
525
+ if (candidate !== null)
526
+ this.autoCollapsed.add(candidate);
527
+ }
528
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: PanelStack, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
529
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.17", type: PanelStack, isStandalone: true, selector: "st-panel-stack", inputs: { shape: "shape", label: "label", expanded: "expanded", defaultExpanded: "defaultExpanded", onExpandedChange: "onExpandedChange", primary: "primary", primaryMinHeight: "primaryMinHeight", classInput: ["class", "classInput"] }, outputs: { expandedChange: "expandedChange" }, host: { attributes: { "role": "group" }, properties: { "attr.data-st-component": "componentName", "class": "hostClass", "attr.aria-label": "label ?? null", "style.--st-component-panelStack-primaryMinBlockSize": "primaryMinHeightStyle" } }, queries: [{ propertyName: "sectionsQuery", predicate: PanelSection, descendants: true }], usesOnChanges: true, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true });
530
+ }
531
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: PanelStack, decorators: [{
532
+ type: Component,
533
+ args: [{
534
+ selector: "st-panel-stack",
535
+ standalone: true,
536
+ // The host tag itself carries `.st-panelStack` (no inner wrapper div): the
537
+ // shared stylesheet's `.st-panelStack > .st-panelSection + .st-panelSection`
538
+ // separator rule is a direct-child/sibling combinator, which only matches
539
+ // the real DOM tree — `:host{display:contents}` (this package's usual
540
+ // "host + inner wrapper div" pattern, see MenuPopover/Icon) would still
541
+ // leave the projected `<st-panel-section>` elements one level too deep for
542
+ // that selector, since `display:contents` unboxes for LAYOUT, not for
543
+ // selector matching. Binding the class straight onto the host, with no
544
+ // wrapper, sidesteps that entirely and matches `PanelStack.svelte`'s flat
545
+ // (one box) structure even more closely than the wrapper pattern would.
546
+ host: {
547
+ "[attr.data-st-component]": "componentName",
548
+ "[class]": "hostClass",
549
+ role: "group",
550
+ "[attr.aria-label]": "label ?? null",
551
+ // `primaryMinHeight` is the single source of truth for BOTH the JS
552
+ // auto-collapse threshold (`resolvedPrimaryMinHeight`, read below) and
553
+ // the CSS floor: styles.css's `.st-panelSection__body--scrollOwner` rule
554
+ // reads this same inherited custom property via
555
+ // `var(--st-component-panelStack-primaryMinBlockSize, 160px)`, so the
556
+ // two can never drift apart again.
557
+ "[style.--st-component-panelStack-primaryMinBlockSize]": "primaryMinHeightStyle",
558
+ },
559
+ template: `<ng-content></ng-content>`,
560
+ }]
561
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { shape: [{
562
+ type: NgInput
563
+ }], label: [{
564
+ type: NgInput
565
+ }], expanded: [{
566
+ type: NgInput
567
+ }], defaultExpanded: [{
568
+ type: NgInput
569
+ }], onExpandedChange: [{
570
+ type: NgInput
571
+ }], expandedChange: [{
572
+ type: Output
573
+ }], primary: [{
574
+ type: NgInput
575
+ }], primaryMinHeight: [{
576
+ type: NgInput
577
+ }], classInput: [{
578
+ type: NgInput,
579
+ args: ["class"]
580
+ }], sectionsQuery: [{
581
+ type: ContentChildren,
582
+ args: [PanelSection, { descendants: true }]
583
+ }] } });
584
+ //# sourceMappingURL=PanelStack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelStack.js","sourceRoot":"","sources":["../src/PanelStack.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ export type { AppHeaderProps } from "./AppHeader.js";
5
5
  export { AppChrome } from "./AppChrome.js";
6
6
  export type { AppChromeNavItem, AppChromeThemeOption, AppChromeColorMode, AppChromeLocale, AppChromeProps } from "./AppChrome.js";
7
7
  export { AppShell } from "./AppShell.js";
8
- export type { AppShellPanelCollapse, AppShellProps, AppShellUtilityMode, AppShellUtilitySide, AppShellVariant } from "./AppShell.js";
8
+ export type { AppShellPanelCollapse, AppShellPanelKey, AppShellProps, AppShellUtilityMode, AppShellUtilitySide, AppShellVariant, } from "./AppShell.js";
9
9
  export { NavShell } from "./NavShell.js";
10
10
  export type { NavShellProps, NavShellSide, NavShellVariant } from "./NavShell.js";
11
11
  export { NavRail } from "./NavRail.js";
@@ -283,7 +283,7 @@ export type { LoadingStateVariant, LoadingStateProps } from "./LoadingState.js";
283
283
  export { Menu } from "./Menu.js";
284
284
  export type { MenuActionItem, MenuDividerItem, MenuGroupItem, MenuItem, MenuProps } from "./Menu.js";
285
285
  export { MenuPopover } from "./MenuPopover.js";
286
- export type { MenuPopoverPlacement, MenuPopoverProps } from "./MenuPopover.js";
286
+ export type { MenuPopoverPlacement, MenuPopoverAlign, MenuPopoverProps } from "./MenuPopover.js";
287
287
  export { MenuTriggerButton } from "./MenuTriggerButton.js";
288
288
  export type { MenuTriggerButtonSize, MenuTriggerButtonVariant, MenuTriggerButtonProps } from "./MenuTriggerButton.js";
289
289
  export { Modal } from "./Modal.js";
@@ -447,4 +447,8 @@ export { Dashboard } from "./Dashboard.js";
447
447
  export type { DashboardProps, DashboardNavItem, DashboardKpi } from "./Dashboard.js";
448
448
  export { Wizard } from "./Wizard.js";
449
449
  export type { WizardProps, WizardStep } from "./Wizard.js";
450
+ export { PanelStack, PANEL_STACK_MAX_SECTIONS, resolvePanelStackPrimary, computePanelStackAutoCollapse } from "./PanelStack.js";
451
+ export type { PanelStackShape, PanelStackProps, PanelStackAutoCollapseMeasurements } from "./PanelStack.js";
452
+ export { PanelSection } from "./PanelSection.js";
453
+ export type { PanelSectionProps } from "./PanelSection.js";
450
454
  //# sourceMappingURL=index.d.ts.map