@sentropic/design-system-angular 0.36.60 → 0.36.63
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/PanelSection.d.ts +69 -0
- package/dist/PanelSection.d.ts.map +1 -0
- package/dist/PanelSection.js +191 -0
- package/dist/PanelSection.js.map +1 -0
- package/dist/PanelStack.d.ts +270 -0
- package/dist/PanelStack.d.ts.map +1 -0
- package/dist/PanelStack.js +584 -0
- package/dist/PanelStack.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/styles.css +158 -0
- package/package.json +3 -1
|
@@ -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
|
@@ -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
|