panelset 0.5.2 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -50,6 +50,7 @@ declare class PanelSet {
50
50
  private _dispatch;
51
51
  private _getVerticalMetrics;
52
52
  private _measureHeight;
53
+ private _updateHighestPanel;
53
54
  private _cleanupPanels;
54
55
  private _waitForTransition;
55
56
  private _animateOpenClose;
package/dist/panelset.js CHANGED
@@ -1,25 +1,31 @@
1
1
  const h = class h {
2
- constructor(e, t = {}) {
2
+ constructor(e, s = {}) {
3
3
  this._openCloseGeneration = 0, this._isLoadingAsync = !1;
4
- let s;
4
+ let t;
5
5
  if (typeof e == "string") {
6
- if (s = document.querySelector(e), !s)
6
+ if (t = document.querySelector(e), !t)
7
7
  throw new Error(`PanelSet: No element found for selector "${e}"`);
8
8
  } else
9
- s = e;
10
- if (this.element = s, h._validateElement(s), s.panelSet || s.dataset.panelset === "true")
11
- return console.warn("PanelSet: Element already initialized, returning existing instance"), s.panelSet;
12
- s.panelSet = this;
13
- const i = h._getDataConfig(s);
9
+ t = e;
10
+ if (this.element = t, h._validateElement(t), t.panelSet || t.dataset.panelset === "true")
11
+ return console.warn("PanelSet: Element already initialized, returning existing instance"), t.panelSet;
12
+ t.panelSet = this;
13
+ const i = h._getDataConfig(t);
14
14
  this.config = h._mergeConfig(
15
15
  h.defaults,
16
16
  i,
17
- t
18
- ), this.panels = Array.from(s.querySelectorAll('[role="tabpanel"]')), this.activePanel = this.panels.find((n) => n.classList.contains("active")) || this.panels[0], this.panelWrapper = this.element.querySelector(".panel-wrapper") || this._autoWrapPanels(), this.pendingPanel = this.activePanel, this._internalInit(), this.element.dataset.panelset = "true", this._log(`Initialized (${this.panels.length} panels)`), this._dispatch("ps:ready", { container: this.element, instance: this });
17
+ s
18
+ ), this.panels = Array.from(t.querySelectorAll('[role="tabpanel"]')), this.activePanel = this.panels.find((a) => a.classList.contains("active")) || this.panels[0], this.panelWrapper = this.element.querySelector(".panel-wrapper") || this._autoWrapPanels(), this.pendingPanel = this.activePanel, this._internalInit();
19
+ let n;
20
+ window.addEventListener("resize", () => {
21
+ clearTimeout(n), n = setTimeout(() => {
22
+ this._updateHighestPanel();
23
+ }, 250);
24
+ }), this.element.dataset.panelset = "true", this._log(`Initialized (${this.panels.length} panels)`), this._dispatch("ps:ready", { container: this.element, instance: this });
19
25
  }
20
26
  // Parse data attributes from element
21
27
  static _getDataConfig(e) {
22
- const t = e.dataset, s = {}, i = {
28
+ const s = e.dataset, t = {}, i = {
23
29
  transitions: "json",
24
30
  closable: "boolean",
25
31
  emptyPanelHeight: "number",
@@ -27,33 +33,33 @@ const h = class h {
27
33
  debug: "boolean"
28
34
  };
29
35
  for (const [n, a] of Object.entries(i)) {
30
- if (!(n in t)) continue;
31
- const o = t[n];
36
+ if (!(n in s)) continue;
37
+ const o = s[n];
32
38
  if (o !== void 0)
33
39
  switch (a) {
34
40
  case "boolean":
35
- s[n] = o !== "false";
41
+ t[n] = o !== "false";
36
42
  break;
37
43
  case "number":
38
- s[n] = parseInt(o, 10);
44
+ t[n] = parseInt(o, 10);
39
45
  break;
40
46
  case "json":
41
47
  try {
42
- s[n] = JSON.parse(o);
48
+ t[n] = JSON.parse(o);
43
49
  } catch {
44
- s[n] = o !== "false";
50
+ t[n] = o !== "false";
45
51
  }
46
52
  break;
47
53
  }
48
54
  }
49
- return s;
55
+ return t;
50
56
  }
51
57
  // Merge configurations
52
- static _mergeConfig(e, t, s) {
58
+ static _mergeConfig(e, s, t) {
53
59
  return {
54
60
  ...e,
55
- ...t,
56
- ...s
61
+ ...s,
62
+ ...t
57
63
  };
58
64
  }
59
65
  /**
@@ -62,10 +68,10 @@ const h = class h {
62
68
  * @param options - Additional config options (when first param is selector)
63
69
  * @returns Array of PanelSet instances
64
70
  */
65
- static init(e = {}, t = {}) {
66
- let s, i;
67
- typeof e == "string" ? (s = e, i = t) : (i = e, s = i.selector || "[data-panelset]");
68
- const n = document.querySelectorAll(s), a = [];
71
+ static init(e = {}, s = {}) {
72
+ let t, i;
73
+ typeof e == "string" ? (t = e, i = s) : (i = e, t = i.selector || "[data-panelset]");
74
+ const n = document.querySelectorAll(t), a = [];
69
75
  return n.forEach((o) => {
70
76
  try {
71
77
  h._validateElement(o);
@@ -84,29 +90,29 @@ const h = class h {
84
90
  // Debug logging helper
85
91
  _log(e) {
86
92
  if (!this.config.debug) return;
87
- const t = this.element.id || "no id";
88
- console.log(`[PanelSet] - "${t}" -`, e);
93
+ const s = this.element.id || "no id";
94
+ console.log(`[PanelSet] - "${s}" -`, e);
89
95
  }
90
96
  static _validateElement(e) {
91
97
  if (!e.hasAttribute("data-panelset")) {
92
- const t = `<${e.tagName.toLowerCase()}${e.id ? ` id="${e.id}"` : ""}${e.className ? ` class="${e.className}"` : ""}>`;
93
- throw new Error(`PanelSet: Element is missing required data-panelset attribute. Element: ${t}`);
98
+ const s = `<${e.tagName.toLowerCase()}${e.id ? ` id="${e.id}"` : ""}${e.className ? ` class="${e.className}"` : ""}>`;
99
+ throw new Error(`PanelSet: Element is missing required data-panelset attribute. Element: ${s}`);
94
100
  }
95
101
  }
96
102
  _autoWrapPanels() {
97
103
  const e = document.createElement("div");
98
- return e.className = "panel-wrapper", this.panels.forEach((t) => e.appendChild(t)), this.element.appendChild(e), e;
104
+ return e.className = "panel-wrapper", this.panels.forEach((s) => e.appendChild(s)), this.element.appendChild(e), e;
99
105
  }
100
106
  _internalInit() {
101
107
  this.panels.forEach((e) => {
102
108
  e.classList.remove("fade", "incoming"), e !== this.activePanel ? (e.hidden = !0, e.classList.remove("active")) : (e.hidden = !1, e.classList.add("active"));
103
- }), this.element.style.height = "";
109
+ }), this.element.style.height = "", this._updateHighestPanel();
104
110
  }
105
111
  // Dispatch custom event helper
106
- _dispatch(e, t) {
112
+ _dispatch(e, s) {
107
113
  this.element.dispatchEvent(
108
114
  new CustomEvent(e, {
109
- detail: t,
115
+ detail: s,
110
116
  bubbles: !0,
111
117
  cancelable: !1
112
118
  })
@@ -115,39 +121,58 @@ const h = class h {
115
121
  /* --- Modular helpers --- */
116
122
  _getVerticalMetrics(e) {
117
123
  if (!e) return 0;
118
- const t = getComputedStyle(e);
119
- return ["paddingTop", "paddingBottom", "borderTopWidth", "borderBottomWidth"].reduce((s, i) => s + (parseFloat(t[i]) || 0), 0);
124
+ const s = getComputedStyle(e);
125
+ return ["paddingTop", "paddingBottom", "borderTopWidth", "borderBottomWidth"].reduce((t, i) => t + (parseFloat(s[i]) || 0), 0);
120
126
  }
121
127
  _measureHeight(e) {
122
- let t = e.offsetHeight;
123
- return t += this._getVerticalMetrics(this.panelWrapper), t += this._getVerticalMetrics(this.element), t;
128
+ let s = e.offsetHeight;
129
+ return s += this._getVerticalMetrics(this.panelWrapper), s += this._getVerticalMetrics(this.element), s;
124
130
  }
125
- _cleanupPanels(e) {
131
+ _updateHighestPanel() {
132
+ if (this.element.hasAttribute("data-ps-track-height")) {
133
+ console.warn("PanelSet: data-ps-track-height should be placed on a parent element, not on [data-panelset] itself. Height tracking skipped.");
134
+ return;
135
+ }
136
+ const e = this.element.closest("[data-ps-track-height]");
137
+ if (!e) return;
138
+ let s = 0;
126
139
  this.panels.forEach((t) => {
127
- t.classList.remove("fade", "incoming"), t !== e ? (t.classList.remove("active"), t.hidden = !0) : (t.classList.add("active"), t.hidden = !1);
140
+ const i = t.hidden, n = t.classList.contains("active");
141
+ this.panels.forEach((o) => {
142
+ o.hidden = !0, o.classList.remove("active");
143
+ }), t.hidden = !1, t.classList.add("active"), t.style.visibility = "hidden", this.element.offsetHeight;
144
+ const a = this.element.offsetHeight;
145
+ a > s && (s = a), t.hidden = i, n || t.classList.remove("active"), t.style.visibility = "";
146
+ }), this.activePanel.hidden = !1, this.activePanel.classList.add("active"), this.panels.forEach((t) => {
147
+ t !== this.activePanel && (t.hidden = !0, t.classList.remove("active"));
148
+ }), e.style.setProperty("--ps-max-height", `${s}px`), this._log(`Max container height: ${s}px (set on tracking parent)`);
149
+ }
150
+ _cleanupPanels(e) {
151
+ this.panels.forEach((s) => {
152
+ s.classList.remove("fade", "incoming"), s !== e ? (s.classList.remove("active"), s.hidden = !0) : (s.classList.add("active"), s.hidden = !1);
128
153
  }), this.element.style.height = "", this.element.classList.remove("is-transitioning"), this.activePanel = e;
129
154
  }
130
155
  _waitForTransition(e) {
131
- return new Promise((t) => {
132
- const s = getComputedStyle(e), i = parseFloat(s.transitionDuration) || 0, n = parseFloat(s.transitionDelay) || 0;
156
+ return new Promise((s) => {
157
+ const t = getComputedStyle(e), i = parseFloat(t.transitionDuration) || 0, n = parseFloat(t.transitionDelay) || 0;
133
158
  if (i + n === 0) {
134
- t();
159
+ s();
135
160
  return;
136
161
  }
137
162
  const a = (o) => {
138
- o.target === e && (e.removeEventListener("transitionend", a), t());
163
+ o.target === e && (e.removeEventListener("transitionend", a), s());
139
164
  };
140
165
  e.addEventListener("transitionend", a);
141
166
  });
142
167
  }
143
168
  // Shared helper for open/close
144
- _animateOpenClose(e, t) {
145
- const s = e ? "opening" : "closing", n = `is-${e ? "closing" : "opening"}`, a = `is-${s}`;
169
+ _animateOpenClose(e, s) {
170
+ const t = e ? "opening" : "closing", n = `is-${e ? "closing" : "opening"}`, a = `is-${t}`;
146
171
  this._log(e ? "Opening" : "Closing"), this._openCloseGeneration++;
147
172
  const o = this._openCloseGeneration;
148
173
  this.element.classList.contains(n) && this.element.classList.remove(n);
149
174
  const l = e ? this._measureHeight(this.pendingPanel) : 0;
150
- if (t && this.config.transitions) {
175
+ if (s && this.config.transitions) {
151
176
  this.element.classList.add(a);
152
177
  const c = this.element.offsetHeight;
153
178
  this.element.style.height = `${c}px`, e && this.element.classList.remove("is-closed"), requestAnimationFrame(() => {
@@ -174,8 +199,8 @@ const h = class h {
174
199
  this._log("Cannot open: closable is false");
175
200
  return;
176
201
  }
177
- const t = this.element.classList.contains("is-closed"), s = this.element.classList.contains("is-closing");
178
- !t && !s || this._animateOpenClose(!0, e);
202
+ const s = this.element.classList.contains("is-closed"), t = this.element.classList.contains("is-closing");
203
+ !s && !t || this._animateOpenClose(!0, e);
179
204
  }
180
205
  /**
181
206
  * Close a closable panelset
@@ -186,33 +211,33 @@ const h = class h {
186
211
  this._log("Cannot close: closable is false");
187
212
  return;
188
213
  }
189
- const t = this.element.classList.contains("is-closed"), s = this.element.classList.contains("is-opening");
190
- t && !s || this._animateOpenClose(!1, e);
214
+ const s = this.element.classList.contains("is-closed"), t = this.element.classList.contains("is-opening");
215
+ s && !t || this._animateOpenClose(!1, e);
191
216
  }
192
217
  /**
193
218
  * Toggle a closable panelset between open and closed
194
219
  * @param withTransition - Whether to animate
195
220
  */
196
221
  toggle(e = !0) {
197
- const t = this.element.classList.contains("is-closed"), s = this.element.classList.contains("is-closing");
198
- t || s ? this.open(e) : this.close(e);
222
+ const s = this.element.classList.contains("is-closed"), t = this.element.classList.contains("is-closing");
223
+ s || t ? this.open(e) : this.close(e);
199
224
  }
200
225
  /**
201
226
  * Register a handler for async content loading
202
227
  * @param handler - Async content handler function
203
228
  * @param options - Handler options (once: whether to load only once)
204
229
  */
205
- onBeforeActivate(e, t = {}) {
206
- const s = t.once === !0;
230
+ onBeforeActivate(e, s = {}) {
231
+ const t = s.once === !0;
207
232
  this.element.addEventListener("ps:beforeactivate", (i) => {
208
233
  const n = i, { targetPanel: a, signal: o } = n.detail;
209
- if (s && a.dataset.loaded === "true") {
234
+ if (t && a.dataset.loaded === "true") {
210
235
  this.config.debug && this._log(`Skipping ${a.id} (already loaded)`);
211
236
  return;
212
237
  }
213
238
  const l = e(a, o);
214
239
  l && typeof l.then == "function" && (n.detail.promise = l.then(() => {
215
- s && (a.dataset.loaded = "true");
240
+ t && (a.dataset.loaded = "true");
216
241
  }).catch((c) => {
217
242
  throw c.name === "AbortError" ? (this.config.debug && this._log(`Load aborted: ${a.id}`), c) : (this._log(`Load failed: ${c.message}`), c);
218
243
  }));
@@ -225,7 +250,7 @@ const h = class h {
225
250
  * @param withTransition - Whether to animate the transition
226
251
  * @param options - Additional options (trigger name)
227
252
  */
228
- async show(e, t = !0, s = {}) {
253
+ async show(e, s = !0, t = {}) {
229
254
  const i = this.panels.find((r) => r.id === e);
230
255
  if (!i) {
231
256
  this._log(`Panel not found: ${e}`);
@@ -260,7 +285,7 @@ const h = class h {
260
285
  if (this.config.loadingDelay > 0 ? r = setTimeout(() => {
261
286
  this.element.classList.add("is-loading"), g = !0;
262
287
  }, this.config.loadingDelay) : (this.element.classList.add("is-loading"), g = !0), !(this.activePanel && this.activePanel !== i)) {
263
- const m = t !== !1 && this.config.transitions !== !1;
288
+ const m = s !== !1 && this.config.transitions !== !1;
264
289
  let u = m;
265
290
  if (typeof this.config.transitions == "object" && (u = m && this.config.transitions.height !== !1), u) {
266
291
  const C = this.element.offsetHeight;
@@ -274,7 +299,7 @@ const h = class h {
274
299
  this._log(`Aborted during load: ${e}`), g && this.element.classList.remove("is-loading");
275
300
  return;
276
301
  }
277
- this._log("Content loaded");
302
+ this._log("Content loaded"), i.dataset.loaded === "true" && this._updateHighestPanel();
278
303
  } catch (m) {
279
304
  r && clearTimeout(r);
280
305
  const u = m;
@@ -289,9 +314,9 @@ const h = class h {
289
314
  }
290
315
  this._dispatch("ps:activationstart", {
291
316
  panelId: e,
292
- trigger: s.trigger || null
317
+ trigger: t.trigger || null
293
318
  });
294
- const p = t !== !1 && this.config.transitions !== !1;
319
+ const p = s !== !1 && this.config.transitions !== !1;
295
320
  let v = p, b = p;
296
321
  typeof this.config.transitions == "object" && (v = p && this.config.transitions.panels !== !1, b = p && this.config.transitions.height !== !1), this.panels.forEach((r) => r.classList.toggle("fade", v));
297
322
  const L = this.element.offsetHeight;
@@ -309,7 +334,7 @@ const h = class h {
309
334
  }
310
335
  this._cleanupPanels(i), this._log(`✓ ${e}`), this._dispatch("ps:activationcomplete", {
311
336
  panelId: e,
312
- trigger: s.trigger || null
337
+ trigger: t.trigger || null
313
338
  });
314
339
  });
315
340
  });
@@ -1 +1 @@
1
- {"version":3,"file":"panelset.js","sources":["../src/lib/index.ts"],"sourcesContent":["import './styles/panelset.scss';\n\n// Configuration types\nexport interface PanelSetConfig {\n\ttransitions?: boolean | {\n\t\tpanels?: boolean;\n\t\theight?: boolean;\n\t};\n\tclosable?: boolean;\n\temptyPanelHeight?: number;\n\tloadingDelay?: number;\n\tdebug?: boolean;\n\tselector?: string;\n}\n\n// Event detail types\nexport interface ReadyEventDetail {\n\tcontainer: HTMLElement;\n\tinstance: PanelSet;\n}\n\nexport interface BeforeActivateEventDetail {\n\tpanelId: string;\n\ttargetPanel: HTMLElement;\n\toutgoingPanel: HTMLElement | null;\n\tsignal: AbortSignal;\n\tpromise: Promise<void> | null;\n}\n\nexport interface ActivationEventDetail {\n\tpanelId: string;\n\ttrigger: string | null;\n}\n\nexport interface ActivationAbortedEventDetail {\n\tpanelId: string;\n\ttrigger: string | null;\n}\n\n// Handler options\nexport interface HandlerOptions {\n\tonce?: boolean;\n}\n\n// Show options\nexport interface ShowOptions {\n\ttrigger?: string;\n}\n\n// Async content handler type\nexport type AsyncContentHandler = (\n\ttargetPanel: HTMLElement,\n\tsignal: AbortSignal\n) => Promise<void> | void;\n\n// Extend HTMLElement to include panelSet property\ndeclare global {\n\tinterface HTMLElement {\n\t\tpanelSet?: PanelSet;\n\t}\n}\n\nexport class PanelSet {\n\t// Default configuration\n\tstatic defaults: Required<Omit<PanelSetConfig, 'selector'>> = {\n\t\ttransitions: true,\n\t\tclosable: false,\n\t\temptyPanelHeight: 200,\n\t\tloadingDelay: 300,\n\t\tdebug: false\n\t};\n\n\t// Instance properties\n\telement!: HTMLElement;\n\tconfig!: Required<Omit<PanelSetConfig, 'selector'>>;\n\tpanels!: HTMLElement[];\n\tactivePanel!: HTMLElement;\n\tpanelWrapper!: HTMLElement;\n\tpendingPanel!: HTMLElement;\n\n\tprivate _openCloseGeneration: number = 0;\n\tprivate _isLoadingAsync: boolean = false;\n\t// private _isTransitioning: boolean = false;\n\tprivate _currentAbortController?: AbortController;\n\n\t// Parse data attributes from element\n\tstatic _getDataConfig(element: HTMLElement): Partial<PanelSetConfig> {\n\t\tconst data = element.dataset;\n\t\tconst config: Partial<PanelSetConfig> = {};\n\n\t\t// Define attribute types\n\t\tconst attrs: Record<string, 'json' | 'boolean' | 'number'> = {\n\t\t\ttransitions: 'json',\n\t\t\tclosable: 'boolean',\n\t\t\temptyPanelHeight: 'number',\n\t\t\tloadingDelay: 'number',\n\t\t\tdebug: 'boolean'\n\t\t};\n\n\t\t// Parse each attribute\n\t\tfor (const [key, type] of Object.entries(attrs)) {\n\t\t\tif (!(key in data)) continue;\n\n\t\t\tconst value = data[key];\n\t\t\tif (value === undefined) continue;\n\n\t\t\tswitch (type) {\n\t\t\t\tcase 'boolean':\n\t\t\t\t\t(config as any)[key] = value !== 'false';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'number':\n\t\t\t\t\t(config as any)[key] = parseInt(value, 10);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'json':\n\t\t\t\t\ttry {\n\t\t\t\t\t\t(config as any)[key] = JSON.parse(value);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Fall back to boolean parsing\n\t\t\t\t\t\t(config as any)[key] = value !== 'false';\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn config;\n\t}\n\n\t// Merge configurations\n\tstatic _mergeConfig(\n\t\tdefaults: Required<Omit<PanelSetConfig, 'selector'>>,\n\t\tdataConfig: Partial<PanelSetConfig>,\n\t\toptions: Partial<PanelSetConfig>\n\t): Required<Omit<PanelSetConfig, 'selector'>> {\n\t\treturn {\n\t\t\t...defaults,\n\t\t\t...dataConfig,\n\t\t\t...options\n\t\t} as Required<Omit<PanelSetConfig, 'selector'>>;\n\t}\n\n\t/**\n\t * Initialize PanelSet instances\n\t * @param selectorOrOptions - CSS selector string or config object\n\t * @param options - Additional config options (when first param is selector)\n\t * @returns Array of PanelSet instances\n\t */\n\tstatic init(selectorOrOptions: string | PanelSetConfig = {}, options: PanelSetConfig = {}): PanelSet[] {\n\t\t// Handle different call signatures\n\t\tlet selector: string;\n\t\tlet config: PanelSetConfig;\n\n\t\tif (typeof selectorOrOptions === 'string') {\n\t\t\t// init('#demo') or init('#demo', {debug: true})\n\t\t\tselector = selectorOrOptions;\n\t\t\tconfig = options;\n\t\t} else {\n\t\t\t// init() or init({selector: '#demo', debug: true})\n\t\t\tconfig = selectorOrOptions;\n\t\t\tselector = config.selector || '[data-panelset]';\n\t\t}\n\n\t\tconst elements = document.querySelectorAll<HTMLElement>(selector);\n\t\tconst instances: PanelSet[] = [];\n\n\t\telements.forEach(el => {\n\n\t\t\ttry {\n\t\t\t\tPanelSet._validateElement(el);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error((error as Error).message);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Skip if already initialized\n\t\t\tif (el.panelSet || el.dataset.panelset === 'true') {\n\t\t\t\tif (el.panelSet) instances.push(el.panelSet);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst instance = new PanelSet(el, config);\n\t\t\tinstances.push(instance);\n\t\t});\n\n\t\treturn instances;\n\t}\n\n\tconstructor(elementOrSelector: HTMLElement | string, options: PanelSetConfig = {}) {\n\t\t// Handle both element and selector\n\t\tlet element: HTMLElement | null;\n\t\tif (typeof elementOrSelector === 'string') {\n\t\t\telement = document.querySelector<HTMLElement>(elementOrSelector);\n\t\t\tif (!element) {\n\t\t\t\tthrow new Error(`PanelSet: No element found for selector \"${elementOrSelector}\"`);\n\t\t\t}\n\t\t} else {\n\t\t\telement = elementOrSelector;\n\t\t}\n\n\t\tthis.element = element;\n\n\t\t// Validate element\n\t\tPanelSet._validateElement(element);\n\n\t\t// Check if already initialized\n\t\tif (element.panelSet || element.dataset.panelset === 'true') {\n\t\t\tconsole.warn('PanelSet: Element already initialized, returning existing instance');\n\t\t\treturn element.panelSet!;\n\t\t}\n\n\t\t// Store instance on element\n\t\telement.panelSet = this;\n\n\t\tconst dataConfig = PanelSet._getDataConfig(element);\n\t\tthis.config = PanelSet._mergeConfig(\n\t\t\tPanelSet.defaults,\n\t\t\tdataConfig,\n\t\t\toptions\n\t\t);\n\n\t\tthis.panels = Array.from(element.querySelectorAll<HTMLElement>('[role=\"tabpanel\"]'));\n\t\tthis.activePanel =\n\t\t\tthis.panels.find(p => p.classList.contains('active')) || this.panels[0];\n\t\tthis.panelWrapper =\n\t\t\tthis.element.querySelector<HTMLElement>('.panel-wrapper') || this._autoWrapPanels();\n\n\t\tthis.pendingPanel = this.activePanel;\n\n\t\tthis._internalInit();\n\n\t\t// Mark as initialized, can be used in CSS selectors for visual confirmation\n\t\tthis.element.dataset.panelset = 'true';\n\n\t\tthis._log(`Initialized (${this.panels.length} panels)`);\n\t\tthis._dispatch<ReadyEventDetail>('ps:ready', { container: this.element, instance: this });\n\t}\n\n\t// Debug logging helper\n\tprivate _log(message: string): void {\n\t\tif (!this.config.debug) return;\n\t\tconst id = this.element.id || 'no id';\n\t\tconsole.log(`[PanelSet] - \"${id}\" -`, message);\n\t}\n\n\tprivate static _validateElement(element: HTMLElement): void {\n\t\tif (!element.hasAttribute('data-panelset')) {\n\t\t\tconst elementDesc = `<${element.tagName.toLowerCase()}${element.id ? ` id=\"${element.id}\"` : ''}${element.className ? ` class=\"${element.className}\"` : ''}>`;\n\t\t\tthrow new Error(`PanelSet: Element is missing required data-panelset attribute. Element: ${elementDesc}`);\n\t\t}\n\t}\n\n\tprivate _autoWrapPanels(): HTMLElement {\n\t\tconst wrapper = document.createElement('div');\n\t\twrapper.className = 'panel-wrapper';\n\t\tthis.panels.forEach(panel => wrapper.appendChild(panel));\n\t\tthis.element.appendChild(wrapper);\n\t\treturn wrapper;\n\t}\n\n\tprivate _internalInit(): void {\n\t\tthis.panels.forEach(panel => {\n\t\t\tpanel.classList.remove('fade', 'incoming');\n\t\t\tif (panel !== this.activePanel) {\n\t\t\t\tpanel.hidden = true;\n\t\t\t\tpanel.classList.remove('active');\n\t\t\t} else {\n\t\t\t\tpanel.hidden = false;\n\t\t\t\tpanel.classList.add('active');\n\t\t\t}\n\t\t});\n\t\tthis.element.style.height = '';\n\t}\n\n\t// Dispatch custom event helper\n\tprivate _dispatch<T = unknown>(eventName: string, detail: T): void {\n\t\tthis.element.dispatchEvent(\n\t\t\tnew CustomEvent(eventName, {\n\t\t\t\tdetail,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: false\n\t\t\t})\n\t\t);\n\t}\n\n\t/* --- Modular helpers --- */\n\n\tprivate _getVerticalMetrics(el: HTMLElement | null): number {\n\t\tif (!el) return 0;\n\t\tconst s = getComputedStyle(el);\n\t\treturn ['paddingTop', 'paddingBottom', 'borderTopWidth', 'borderBottomWidth']\n\t\t\t.reduce((sum, prop) => sum + (parseFloat(s[prop as keyof CSSStyleDeclaration] as string) || 0), 0);\n\t}\n\n\tprivate _measureHeight(panel: HTMLElement): number {\n\t\tlet total = panel.offsetHeight;\n\t\ttotal += this._getVerticalMetrics(this.panelWrapper);\n\t\ttotal += this._getVerticalMetrics(this.element);\n\t\treturn total;\n\t}\n\n\tprivate _cleanupPanels(newPanel: HTMLElement): void {\n\t\tthis.panels.forEach(panel => {\n\t\t\tpanel.classList.remove('fade', 'incoming');\n\t\t\tif (panel !== newPanel) {\n\t\t\t\tpanel.classList.remove('active');\n\t\t\t\tpanel.hidden = true;\n\t\t\t} else {\n\t\t\t\tpanel.classList.add('active');\n\t\t\t\tpanel.hidden = false;\n\t\t\t}\n\t\t});\n\t\tthis.element.style.height = '';\n\t\tthis.element.classList.remove('is-transitioning');\n\t\tthis.activePanel = newPanel;\n\t}\n\n\tprivate _waitForTransition(element: HTMLElement): Promise<void> {\n\t\treturn new Promise(resolve => {\n\t\t\tconst styles = getComputedStyle(element);\n\t\t\tconst duration = parseFloat(styles.transitionDuration) || 0;\n\t\t\tconst delay = parseFloat(styles.transitionDelay) || 0;\n\t\t\tif (duration + delay === 0) {\n\t\t\t\tresolve();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst handler = (e: TransitionEvent) => {\n\t\t\t\tif (e.target !== element) return;\n\t\t\t\telement.removeEventListener('transitionend', handler);\n\t\t\t\tresolve();\n\t\t\t};\n\t\t\telement.addEventListener('transitionend', handler);\n\t\t});\n\t}\n\n\t// Shared helper for open/close\n\tprivate _animateOpenClose(isOpening: boolean, withTransition: boolean): void {\n\t\tconst action = isOpening ? 'opening' : 'closing';\n\t\tconst oppositeAction = isOpening ? 'closing' : 'opening';\n\t\tconst oppositeClass = `is-${oppositeAction}`;\n\t\tconst actionClass = `is-${action}`;\n\n\t\tthis._log(isOpening ? 'Opening' : 'Closing');\n\n\t\tthis._openCloseGeneration++;\n\t\tconst myGeneration = this._openCloseGeneration;\n\n\t\t// Remove opposite state if interrupting\n\t\tif (this.element.classList.contains(oppositeClass)) {\n\t\t\tthis.element.classList.remove(oppositeClass);\n\t\t}\n\n\t\tconst targetHeight = isOpening ? this._measureHeight(this.pendingPanel) : 0;\n\n\t\tif (withTransition && this.config.transitions) {\n\t\t\tthis.element.classList.add(actionClass);\n\n\t\t\tconst currentHeight = this.element.offsetHeight;\n\t\t\tthis.element.style.height = `${currentHeight}px`;\n\n\t\t\tif (isOpening) this.element.classList.remove('is-closed');\n\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tthis.element.style.height = `${targetHeight}px`;\n\n\t\t\t\tthis._waitForTransition(this.element).then(() => {\n\t\t\t\t\tif (this._openCloseGeneration === myGeneration) {\n\t\t\t\t\t\tthis.element.style.height = '';\n\t\t\t\t\t\tthis.element.classList.remove(actionClass);\n\t\t\t\t\t\tif (!isOpening) this.element.classList.add('is-closed');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t} else {\n\t\t\tif (isOpening) {\n\t\t\t\tthis.element.classList.remove('is-closed');\n\t\t\t} else {\n\t\t\t\tthis.element.classList.add('is-closed');\n\t\t\t}\n\t\t\tthis.element.style.height = '';\n\t\t}\n\t}\n\n\t/**\n\t * Get the ID of the currently active panel\n\t * @returns Panel ID or null if no panel is active\n\t */\n\tgetActive(): string | null {\n\t\treturn this.pendingPanel?.id || null;\n\t}\n\n\t/**\n\t * Open a closable panelset\n\t * @param withTransition - Whether to animate\n\t */\n\topen(withTransition: boolean = true): void {\n\t\tif (!this.config.closable) {\n\t\t\tthis._log('Cannot open: closable is false');\n\t\t\treturn;\n\t\t}\n\n\t\tconst isClosed = this.element.classList.contains('is-closed');\n\t\tconst isClosing = this.element.classList.contains('is-closing');\n\n\t\tif (!isClosed && !isClosing) return;\n\n\t\tthis._animateOpenClose(true, withTransition);\n\t}\n\n\t/**\n\t * Close a closable panelset\n\t * @param withTransition - Whether to animate\n\t */\n\tclose(withTransition: boolean = true): void {\n\t\tif (!this.config.closable) {\n\t\t\tthis._log('Cannot close: closable is false');\n\t\t\treturn;\n\t\t}\n\n\t\tconst isClosed = this.element.classList.contains('is-closed');\n\t\tconst isOpening = this.element.classList.contains('is-opening');\n\n\t\tif (isClosed && !isOpening) return;\n\n\t\tthis._animateOpenClose(false, withTransition);\n\t}\n\n\t/**\n\t * Toggle a closable panelset between open and closed\n\t * @param withTransition - Whether to animate\n\t */\n\ttoggle(withTransition: boolean = true): void {\n\t\tconst isClosed = this.element.classList.contains('is-closed');\n\t\tconst isClosing = this.element.classList.contains('is-closing');\n\n\t\t// If closed or closing, open it\n\t\tif (isClosed || isClosing) {\n\t\t\tthis.open(withTransition);\n\t\t} else {\n\t\t\tthis.close(withTransition);\n\t\t}\n\t}\n\n\t/**\n\t * Register a handler for async content loading\n\t * @param handler - Async content handler function\n\t * @param options - Handler options (once: whether to load only once)\n\t */\n\tonBeforeActivate(handler: AsyncContentHandler, options: HandlerOptions = {}): void {\n\t\tconst once = options.once === true; // Default: false (always reload)\n\n\t\tthis.element.addEventListener('ps:beforeactivate', (e) => {\n\t\t\tconst event = e as CustomEvent<BeforeActivateEventDetail>;\n\t\t\tconst { targetPanel, signal } = event.detail;\n\n\t\t\t// Skip if already loaded and once=true\n\t\t\tif (once && targetPanel.dataset.loaded === 'true') {\n\t\t\t\tif (this.config.debug) {\n\t\t\t\t\tthis._log(`Skipping ${targetPanel.id} (already loaded)`);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Call user handler\n\t\t\tconst result = handler(targetPanel, signal);\n\n\t\t\t// If handler returns a promise, attach it to the event\n\t\t\tif (result && typeof result.then === 'function') {\n\t\t\t\tevent.detail.promise = result\n\t\t\t\t\t.then(() => {\n\t\t\t\t\t\t// Auto-mark as loaded on success if once=true\n\t\t\t\t\t\tif (once) {\n\t\t\t\t\t\t\ttargetPanel.dataset.loaded = 'true';\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\t.catch(error => {\n\t\t\t\t\t\tif (error.name === 'AbortError') {\n\t\t\t\t\t\t\tif (this.config.debug) {\n\t\t\t\t\t\t\t\tthis._log(`Load aborted: ${targetPanel.id}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis._log(`Load failed: ${error.message}`);\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\n\t/* --- Main logic --- */\n\n\t/**\n\t * Show a panel by ID\n\t * @param panelId - ID of the panel to show\n\t * @param withTransition - Whether to animate the transition\n\t * @param options - Additional options (trigger name)\n\t */\n\tasync show(panelId: string, withTransition: boolean = true, options: ShowOptions = {}): Promise<void> {\n\t\tconst newPanel = this.panels.find(p => p.id === panelId);\n\n\t\tif (!newPanel) {\n\t\t\tthis._log(`Panel not found: ${panelId}`);\n\t\t\treturn;\n\t\t}\n\n\t\tif (newPanel === this.pendingPanel) return;\n\n\t\tconst prevPanel = this.pendingPanel;\n\t\tconst prevPanelId = prevPanel?.id;\n\t\tthis.pendingPanel = newPanel;\n\n\t\tthis.element.classList.remove('is-loading');\n\n\t\tif (prevPanel && prevPanel !== this.activePanel && prevPanel !== newPanel) {\n\t\t\tprevPanel.classList.remove('incoming');\n\t\t\tif (prevPanel.hidden) {\n\t\t\t\t// Was never visible, keep hidden\n\t\t\t} else {\n\t\t\t\tprevPanel.classList.remove('active');\n\t\t\t}\n\t\t}\n\n\t\tconst wasLoadingAsync = this._isLoadingAsync;\n\n\t\tif (this._currentAbortController) {\n\t\t\tthis._currentAbortController.abort();\n\n\t\t\t// Only fire abort if we're cancelling an async operation\n\t\t\tif (wasLoadingAsync && prevPanelId && prevPanelId !== panelId) {\n\t\t\t\tthis._dispatch<ActivationAbortedEventDetail>('ps:activationaborted', {\n\t\t\t\t\tpanelId: prevPanelId,\n\t\t\t\t\ttrigger: null\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tconst abortController = new AbortController();\n\t\tthis._currentAbortController = abortController;\n\t\tthis._isLoadingAsync = false;\n\n\t\tthis._log(`${prevPanel?.id || 'none'} → ${panelId}`);\n\n\t\tconst beforeActivateDetail: BeforeActivateEventDetail = {\n\t\t\tpanelId,\n\t\t\ttargetPanel: newPanel,\n\t\t\toutgoingPanel: prevPanel,\n\t\t\tsignal: abortController.signal,\n\t\t\tpromise: null\n\t\t};\n\n\t\tconst beforeActivateEvent = new CustomEvent('ps:beforeactivate', {\n\t\t\tdetail: beforeActivateDetail,\n\t\t\tbubbles: true,\n\t\t\tcancelable: false\n\t\t});\n\n\t\tthis.element.dispatchEvent(beforeActivateEvent);\n\n\t\tconst userPromise = beforeActivateDetail.promise;\n\n\t\tif (userPromise) {\n\t\t\tthis._isLoadingAsync = true;\n\t\t\tthis._log('Waiting for content...');\n\n\t\t\tlet spinnerTimeout: ReturnType<typeof setTimeout> | undefined;\n\t\t\tlet loadingShown = false;\n\n\t\t\tif (this.config.loadingDelay > 0) {\n\t\t\t\tspinnerTimeout = setTimeout(() => {\n\t\t\t\t\tthis.element.classList.add('is-loading');\n\t\t\t\t\tloadingShown = true;\n\t\t\t\t}, this.config.loadingDelay);\n\t\t\t} else {\n\t\t\t\tthis.element.classList.add('is-loading');\n\t\t\t\tloadingShown = true;\n\t\t\t}\n\n\t\t\tconst hasPreviousPanel = this.activePanel && this.activePanel !== newPanel;\n\n\t\t\tif (!hasPreviousPanel) {\n\t\t\t\tconst shouldTransition = withTransition !== false && this.config.transitions !== false;\n\t\t\t\tlet heightTransition = shouldTransition;\n\t\t\t\tif (typeof this.config.transitions === 'object') {\n\t\t\t\t\theightTransition = shouldTransition && this.config.transitions.height !== false;\n\t\t\t\t}\n\n\t\t\t\tif (heightTransition) {\n\t\t\t\t\tconst currentHeight = this.element.offsetHeight;\n\t\t\t\t\tthis.element.style.height = `${currentHeight}px`;\n\n\t\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\t\tthis.element.style.height = `${this.config.emptyPanelHeight}px`;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tawait userPromise;\n\n\t\t\t\tif (spinnerTimeout) clearTimeout(spinnerTimeout);\n\n\t\t\t\tif (abortController.signal.aborted) {\n\t\t\t\t\tthis._log(`Aborted during load: ${panelId}`);\n\t\t\t\t\tif (loadingShown) this.element.classList.remove('is-loading');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis._log('Content loaded');\n\t\t\t} catch (error) {\n\t\t\t\tif (spinnerTimeout) clearTimeout(spinnerTimeout);\n\n\t\t\t\tconst err = error as Error;\n\t\t\t\tthis._log(`Load failed: ${err.message}`);\n\t\t\t\tif (loadingShown) this.element.classList.remove('is-loading');\n\n\t\t\t\tif (err.name !== 'AbortError') {\n\t\t\t\t\tconsole.error('Panel load error:', error);\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (loadingShown) this.element.classList.remove('is-loading');\n\t\t}\n\n\t\tif (abortController.signal.aborted) {\n\t\t\tthis._log(`Aborted: ${panelId}`);\n\t\t\treturn;\n\t\t}\n\n\t\tthis._dispatch<ActivationEventDetail>('ps:activationstart', {\n\t\t\tpanelId,\n\t\t\ttrigger: options.trigger || null\n\t\t});\n\n\t\tconst shouldTransition = withTransition !== false && this.config.transitions !== false;\n\n\t\tlet panelTransition = shouldTransition;\n\t\tlet heightTransition = shouldTransition;\n\n\t\tif (typeof this.config.transitions === 'object') {\n\t\t\tpanelTransition = shouldTransition && this.config.transitions.panels !== false;\n\t\t\theightTransition = shouldTransition && this.config.transitions.height !== false;\n\t\t}\n\n\t\tthis.panels.forEach(panel => panel.classList.toggle('fade', panelTransition));\n\n\t\tconst startHeight = this.element.offsetHeight;\n\t\tif (heightTransition) {\n\t\t\tthis.element.style.height = `${startHeight}px`;\n\t\t}\n\n\t\tconst outgoingPanel = this.activePanel;\n\n\t\tnewPanel.hidden = false;\n\t\tnewPanel.classList.add('incoming');\n\t\tif (panelTransition) {\n\t\t\t// Apply general transitioning class for overflow: hidden\n\t\t\tthis.element.classList.add('is-transitioning');\n\t\t}\n\t\tif (outgoingPanel && outgoingPanel !== newPanel) {\n\t\t\toutgoingPanel.classList.remove('active', 'incoming');\n\t\t\toutgoingPanel.hidden = false;\n\t\t}\n\n\t\trequestAnimationFrame(() => {\n\t\t\tnewPanel.classList.add('active');\n\t\t\tif (outgoingPanel && outgoingPanel !== newPanel) {\n\t\t\t\toutgoingPanel.classList.remove('incoming');\n\t\t\t}\n\n\t\t\tconst targetHeight = this._measureHeight(newPanel);\n\t\t\tconst heightChanged = startHeight !== targetHeight;\n\n\t\t\tif (heightTransition) {\n\t\t\t\tthis.element.style.height = `${targetHeight}px`;\n\t\t\t}\n\n\t\t\tconst promises: Promise<void>[] = [];\n\t\t\tif (panelTransition) {\n\t\t\t\tpromises.push(this._waitForTransition(newPanel));\n\t\t\t}\n\t\t\tif (heightTransition && heightChanged) {\n\t\t\t\tpromises.push(this._waitForTransition(this.element));\n\t\t\t}\n\t\t\tif (!promises.length) promises.push(Promise.resolve());\n\n\t\t\tPromise.all(promises).then(() => {\n\t\t\t\t// Check if interrupted by another activation\n\t\t\t\tif (this.pendingPanel !== newPanel) {\n\t\t\t\t\tthis._log(`Interrupted: ${panelId}`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis._cleanupPanels(newPanel);\n\t\t\t\tthis._log(`✓ ${panelId}`);\n\t\t\t\tthis._dispatch<ActivationEventDetail>('ps:activationcomplete', {\n\t\t\t\t\tpanelId,\n\t\t\t\t\ttrigger: options.trigger || null\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t}\n}\n\nexport default PanelSet;"],"names":["_PanelSet","elementOrSelector","options","element","dataConfig","p","data","config","attrs","key","type","value","defaults","selectorOrOptions","selector","elements","instances","el","error","instance","message","id","elementDesc","wrapper","panel","eventName","detail","s","sum","prop","total","newPanel","resolve","styles","duration","delay","handler","e","isOpening","withTransition","action","oppositeClass","actionClass","myGeneration","targetHeight","currentHeight","isClosed","isClosing","once","event","targetPanel","signal","result","panelId","prevPanel","prevPanelId","wasLoadingAsync","abortController","beforeActivateDetail","beforeActivateEvent","userPromise","spinnerTimeout","loadingShown","shouldTransition","heightTransition","err","panelTransition","startHeight","outgoingPanel","heightChanged","promises","PanelSet"],"mappings":"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"}
1
+ {"version":3,"file":"panelset.js","sources":["../src/lib/index.ts"],"sourcesContent":["import './styles/panelset.scss';\n\n// Configuration types\nexport interface PanelSetConfig {\n\ttransitions?: boolean | {\n\t\tpanels?: boolean;\n\t\theight?: boolean;\n\t};\n\tclosable?: boolean;\n\temptyPanelHeight?: number;\n\tloadingDelay?: number;\n\tdebug?: boolean;\n\tselector?: string;\n}\n\n// Event detail types\nexport interface ReadyEventDetail {\n\tcontainer: HTMLElement;\n\tinstance: PanelSet;\n}\n\nexport interface BeforeActivateEventDetail {\n\tpanelId: string;\n\ttargetPanel: HTMLElement;\n\toutgoingPanel: HTMLElement | null;\n\tsignal: AbortSignal;\n\tpromise: Promise<void> | null;\n}\n\nexport interface ActivationEventDetail {\n\tpanelId: string;\n\ttrigger: string | null;\n}\n\nexport interface ActivationAbortedEventDetail {\n\tpanelId: string;\n\ttrigger: string | null;\n}\n\n// Handler options\nexport interface HandlerOptions {\n\tonce?: boolean;\n}\n\n// Show options\nexport interface ShowOptions {\n\ttrigger?: string;\n}\n\n// Async content handler type\nexport type AsyncContentHandler = (\n\ttargetPanel: HTMLElement,\n\tsignal: AbortSignal\n) => Promise<void> | void;\n\n// Extend HTMLElement to include panelSet property\ndeclare global {\n\tinterface HTMLElement {\n\t\tpanelSet?: PanelSet;\n\t}\n}\n\nexport class PanelSet {\n\t// Default configuration\n\tstatic defaults: Required<Omit<PanelSetConfig, 'selector'>> = {\n\t\ttransitions: true,\n\t\tclosable: false,\n\t\temptyPanelHeight: 200,\n\t\tloadingDelay: 300,\n\t\tdebug: false\n\t};\n\n\t// Instance properties\n\telement!: HTMLElement;\n\tconfig!: Required<Omit<PanelSetConfig, 'selector'>>;\n\tpanels!: HTMLElement[];\n\tactivePanel!: HTMLElement;\n\tpanelWrapper!: HTMLElement;\n\tpendingPanel!: HTMLElement;\n\n\tprivate _openCloseGeneration: number = 0;\n\tprivate _isLoadingAsync: boolean = false;\n\tprivate _currentAbortController?: AbortController;\n\n\t// Parse data attributes from element\n\tstatic _getDataConfig(element: HTMLElement): Partial<PanelSetConfig> {\n\t\tconst data = element.dataset;\n\t\tconst config: Partial<PanelSetConfig> = {};\n\n\t\t// Define attribute types\n\t\tconst attrs: Record<string, 'json' | 'boolean' | 'number'> = {\n\t\t\ttransitions: 'json',\n\t\t\tclosable: 'boolean',\n\t\t\temptyPanelHeight: 'number',\n\t\t\tloadingDelay: 'number',\n\t\t\tdebug: 'boolean'\n\t\t};\n\n\t\t// Parse each attribute\n\t\tfor (const [key, type] of Object.entries(attrs)) {\n\t\t\tif (!(key in data)) continue;\n\n\t\t\tconst value = data[key];\n\t\t\tif (value === undefined) continue;\n\n\t\t\tswitch (type) {\n\t\t\t\tcase 'boolean':\n\t\t\t\t\t(config as any)[key] = value !== 'false';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'number':\n\t\t\t\t\t(config as any)[key] = parseInt(value, 10);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'json':\n\t\t\t\t\ttry {\n\t\t\t\t\t\t(config as any)[key] = JSON.parse(value);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Fall back to boolean parsing\n\t\t\t\t\t\t(config as any)[key] = value !== 'false';\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn config;\n\t}\n\n\t// Merge configurations\n\tstatic _mergeConfig(\n\t\tdefaults: Required<Omit<PanelSetConfig, 'selector'>>,\n\t\tdataConfig: Partial<PanelSetConfig>,\n\t\toptions: Partial<PanelSetConfig>\n\t): Required<Omit<PanelSetConfig, 'selector'>> {\n\t\treturn {\n\t\t\t...defaults,\n\t\t\t...dataConfig,\n\t\t\t...options\n\t\t} as Required<Omit<PanelSetConfig, 'selector'>>;\n\t}\n\n\t/**\n\t * Initialize PanelSet instances\n\t * @param selectorOrOptions - CSS selector string or config object\n\t * @param options - Additional config options (when first param is selector)\n\t * @returns Array of PanelSet instances\n\t */\n\tstatic init(selectorOrOptions: string | PanelSetConfig = {}, options: PanelSetConfig = {}): PanelSet[] {\n\t\t// Handle different call signatures\n\t\tlet selector: string;\n\t\tlet config: PanelSetConfig;\n\n\t\tif (typeof selectorOrOptions === 'string') {\n\t\t\t// init('#demo') or init('#demo', {debug: true})\n\t\t\tselector = selectorOrOptions;\n\t\t\tconfig = options;\n\t\t} else {\n\t\t\t// init() or init({selector: '#demo', debug: true})\n\t\t\tconfig = selectorOrOptions;\n\t\t\tselector = config.selector || '[data-panelset]';\n\t\t}\n\n\t\tconst elements = document.querySelectorAll<HTMLElement>(selector);\n\t\tconst instances: PanelSet[] = [];\n\n\t\telements.forEach(el => {\n\n\t\t\ttry {\n\t\t\t\tPanelSet._validateElement(el);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error((error as Error).message);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Skip if already initialized\n\t\t\tif (el.panelSet || el.dataset.panelset === 'true') {\n\t\t\t\tif (el.panelSet) instances.push(el.panelSet);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst instance = new PanelSet(el, config);\n\t\t\tinstances.push(instance);\n\t\t});\n\n\t\treturn instances;\n\t}\n\n\tconstructor(elementOrSelector: HTMLElement | string, options: PanelSetConfig = {}) {\n\t\t// Handle both element and selector\n\t\tlet element: HTMLElement | null;\n\t\tif (typeof elementOrSelector === 'string') {\n\t\t\telement = document.querySelector<HTMLElement>(elementOrSelector);\n\t\t\tif (!element) {\n\t\t\t\tthrow new Error(`PanelSet: No element found for selector \"${elementOrSelector}\"`);\n\t\t\t}\n\t\t} else {\n\t\t\telement = elementOrSelector;\n\t\t}\n\n\t\tthis.element = element;\n\n\t\t// Validate element\n\t\tPanelSet._validateElement(element);\n\n\t\t// Check if already initialized\n\t\tif (element.panelSet || element.dataset.panelset === 'true') {\n\t\t\tconsole.warn('PanelSet: Element already initialized, returning existing instance');\n\t\t\treturn element.panelSet!;\n\t\t}\n\n\t\t// Store instance on element\n\t\telement.panelSet = this;\n\n\t\tconst dataConfig = PanelSet._getDataConfig(element);\n\t\tthis.config = PanelSet._mergeConfig(\n\t\t\tPanelSet.defaults,\n\t\t\tdataConfig,\n\t\t\toptions\n\t\t);\n\n\t\tthis.panels = Array.from(element.querySelectorAll<HTMLElement>('[role=\"tabpanel\"]'));\n\t\tthis.activePanel =\n\t\t\tthis.panels.find(p => p.classList.contains('active')) || this.panels[0];\n\t\tthis.panelWrapper =\n\t\t\tthis.element.querySelector<HTMLElement>('.panel-wrapper') || this._autoWrapPanels();\n\n\t\tthis.pendingPanel = this.activePanel;\n\n\t\tthis._internalInit();\n\n\t\tlet resizeTimeout: ReturnType<typeof setTimeout>;\n\t\twindow.addEventListener('resize', () => {\n\t\t\tclearTimeout(resizeTimeout);\n\t\t\tresizeTimeout = setTimeout(() => {\n\t\t\t\tthis._updateHighestPanel();\n\t\t\t}, 250);\n\t\t});\n\n\n\t\tthis.element.dataset.panelset = 'true';\n\n\t\tthis._log(`Initialized (${this.panels.length} panels)`);\n\t\tthis._dispatch<ReadyEventDetail>('ps:ready', { container: this.element, instance: this });\n\t}\n\n\t// Debug logging helper\n\tprivate _log(message: string): void {\n\t\tif (!this.config.debug) return;\n\t\tconst id = this.element.id || 'no id';\n\t\tconsole.log(`[PanelSet] - \"${id}\" -`, message);\n\t}\n\n\tprivate static _validateElement(element: HTMLElement): void {\n\t\tif (!element.hasAttribute('data-panelset')) {\n\t\t\tconst elementDesc = `<${element.tagName.toLowerCase()}${element.id ? ` id=\"${element.id}\"` : ''}${element.className ? ` class=\"${element.className}\"` : ''}>`;\n\t\t\tthrow new Error(`PanelSet: Element is missing required data-panelset attribute. Element: ${elementDesc}`);\n\t\t}\n\t}\n\n\tprivate _autoWrapPanels(): HTMLElement {\n\t\tconst wrapper = document.createElement('div');\n\t\twrapper.className = 'panel-wrapper';\n\t\tthis.panels.forEach(panel => wrapper.appendChild(panel));\n\t\tthis.element.appendChild(wrapper);\n\t\treturn wrapper;\n\t}\n\n\tprivate _internalInit(): void {\n\t\tthis.panels.forEach(panel => {\n\t\t\tpanel.classList.remove('fade', 'incoming');\n\t\t\tif (panel !== this.activePanel) {\n\t\t\t\tpanel.hidden = true;\n\t\t\t\tpanel.classList.remove('active');\n\t\t\t} else {\n\t\t\t\tpanel.hidden = false;\n\t\t\t\tpanel.classList.add('active');\n\t\t\t}\n\t\t});\n\t\tthis.element.style.height = '';\n\t\tthis._updateHighestPanel();\n\t}\n\n\t// Dispatch custom event helper\n\tprivate _dispatch<T = unknown>(eventName: string, detail: T): void {\n\t\tthis.element.dispatchEvent(\n\t\t\tnew CustomEvent(eventName, {\n\t\t\t\tdetail,\n\t\t\t\tbubbles: true,\n\t\t\t\tcancelable: false\n\t\t\t})\n\t\t);\n\t}\n\n\t/* --- Modular helpers --- */\n\n\tprivate _getVerticalMetrics(el: HTMLElement | null): number {\n\t\tif (!el) return 0;\n\t\tconst s = getComputedStyle(el);\n\t\treturn ['paddingTop', 'paddingBottom', 'borderTopWidth', 'borderBottomWidth']\n\t\t\t.reduce((sum, prop) => sum + (parseFloat(s[prop as keyof CSSStyleDeclaration] as string) || 0), 0);\n\t}\n\n\tprivate _measureHeight(panel: HTMLElement): number {\n\t\tlet total = panel.offsetHeight;\n\t\ttotal += this._getVerticalMetrics(this.panelWrapper);\n\t\ttotal += this._getVerticalMetrics(this.element);\n\t\treturn total;\n\t}\n\n\tprivate _updateHighestPanel(): void {\n\t\t// Warn if user tries self-tracking\n\t\tif (this.element.hasAttribute('data-ps-track-height')) {\n\t\t\tconsole.warn('PanelSet: data-ps-track-height should be placed on a parent element, not on [data-panelset] itself. Height tracking skipped.');\n\t\t\treturn;\n\t\t}\n\t\t\n\t\t// Look for parent with tracking attribute\n\t\tconst trackingParent = this.element.closest('[data-ps-track-height]');\n\t\tif (!trackingParent) return; // Skip if no tracking parent found\n\t\t\n\t\tlet maxContainerHeight = 0;\n\t\t\n\t\t// Measure each panel as if it were active\n\t\tthis.panels.forEach(panel => {\n\t\t\t// Save state\n\t\t\tconst wasHidden = panel.hidden;\n\t\t\tconst wasActive = panel.classList.contains('active');\n\t\t\t\n\t\t\t// Make this panel active temporarily\n\t\t\tthis.panels.forEach(p => {\n\t\t\t\tp.hidden = true;\n\t\t\t\tp.classList.remove('active');\n\t\t\t});\n\t\t\t\n\t\t\tpanel.hidden = false;\n\t\t\tpanel.classList.add('active');\n\t\t\tpanel.style.visibility = 'hidden';\n\t\t\t\n\t\t\t// Force reflow\n\t\t\tthis.element.offsetHeight;\n\t\t\t\n\t\t\t// Measure the CONTAINER height (includes padding and borders)\n\t\t\tconst containerHeight = this.element.offsetHeight;\n\t\t\tif (containerHeight > maxContainerHeight) {\n\t\t\t\tmaxContainerHeight = containerHeight;\n\t\t\t}\n\t\t\t\n\t\t\t// Restore state\n\t\t\tpanel.hidden = wasHidden;\n\t\t\tif (!wasActive) panel.classList.remove('active');\n\t\t\tpanel.style.visibility = '';\n\t\t});\n\t\t\n\t\t// Restore original active panel\n\t\tthis.activePanel.hidden = false;\n\t\tthis.activePanel.classList.add('active');\n\t\tthis.panels.forEach(p => {\n\t\t\tif (p !== this.activePanel) {\n\t\t\t\tp.hidden = true;\n\t\t\t\tp.classList.remove('active');\n\t\t\t}\n\t\t});\n\t\t\n\t\t// Set CSS variable on the tracking parent\n\t\t(trackingParent as HTMLElement).style.setProperty('--ps-max-height', `${maxContainerHeight}px`);\n\t\tthis._log(`Max container height: ${maxContainerHeight}px (set on tracking parent)`);\n\t}\n\n\tprivate _cleanupPanels(newPanel: HTMLElement): void {\n\t\tthis.panels.forEach(panel => {\n\t\t\tpanel.classList.remove('fade', 'incoming');\n\t\t\tif (panel !== newPanel) {\n\t\t\t\tpanel.classList.remove('active');\n\t\t\t\tpanel.hidden = true;\n\t\t\t} else {\n\t\t\t\tpanel.classList.add('active');\n\t\t\t\tpanel.hidden = false;\n\t\t\t}\n\t\t});\n\t\tthis.element.style.height = '';\n\t\tthis.element.classList.remove('is-transitioning');\n\t\tthis.activePanel = newPanel;\n\t}\n\n\tprivate _waitForTransition(element: HTMLElement): Promise<void> {\n\t\treturn new Promise(resolve => {\n\t\t\tconst styles = getComputedStyle(element);\n\t\t\tconst duration = parseFloat(styles.transitionDuration) || 0;\n\t\t\tconst delay = parseFloat(styles.transitionDelay) || 0;\n\t\t\tif (duration + delay === 0) {\n\t\t\t\tresolve();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst handler = (e: TransitionEvent) => {\n\t\t\t\tif (e.target !== element) return;\n\t\t\t\telement.removeEventListener('transitionend', handler);\n\t\t\t\tresolve();\n\t\t\t};\n\t\t\telement.addEventListener('transitionend', handler);\n\t\t});\n\t}\n\n\t// Shared helper for open/close\n\tprivate _animateOpenClose(isOpening: boolean, withTransition: boolean): void {\n\t\tconst action = isOpening ? 'opening' : 'closing';\n\t\tconst oppositeAction = isOpening ? 'closing' : 'opening';\n\t\tconst oppositeClass = `is-${oppositeAction}`;\n\t\tconst actionClass = `is-${action}`;\n\n\t\tthis._log(isOpening ? 'Opening' : 'Closing');\n\n\t\tthis._openCloseGeneration++;\n\t\tconst myGeneration = this._openCloseGeneration;\n\n\t\t// Remove opposite state if interrupting\n\t\tif (this.element.classList.contains(oppositeClass)) {\n\t\t\tthis.element.classList.remove(oppositeClass);\n\t\t}\n\n\t\tconst targetHeight = isOpening ? this._measureHeight(this.pendingPanel) : 0;\n\n\t\tif (withTransition && this.config.transitions) {\n\t\t\tthis.element.classList.add(actionClass);\n\n\t\t\tconst currentHeight = this.element.offsetHeight;\n\t\t\tthis.element.style.height = `${currentHeight}px`;\n\n\t\t\tif (isOpening) this.element.classList.remove('is-closed');\n\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tthis.element.style.height = `${targetHeight}px`;\n\n\t\t\t\tthis._waitForTransition(this.element).then(() => {\n\t\t\t\t\tif (this._openCloseGeneration === myGeneration) {\n\t\t\t\t\t\tthis.element.style.height = '';\n\t\t\t\t\t\tthis.element.classList.remove(actionClass);\n\t\t\t\t\t\tif (!isOpening) this.element.classList.add('is-closed');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t} else {\n\t\t\tif (isOpening) {\n\t\t\t\tthis.element.classList.remove('is-closed');\n\t\t\t} else {\n\t\t\t\tthis.element.classList.add('is-closed');\n\t\t\t}\n\t\t\tthis.element.style.height = '';\n\t\t}\n\t}\n\n\t/**\n\t * Get the ID of the currently active panel\n\t * @returns Panel ID or null if no panel is active\n\t */\n\tgetActive(): string | null {\n\t\treturn this.pendingPanel?.id || null;\n\t}\n\n\t/**\n\t * Open a closable panelset\n\t * @param withTransition - Whether to animate\n\t */\n\topen(withTransition: boolean = true): void {\n\t\tif (!this.config.closable) {\n\t\t\tthis._log('Cannot open: closable is false');\n\t\t\treturn;\n\t\t}\n\n\t\tconst isClosed = this.element.classList.contains('is-closed');\n\t\tconst isClosing = this.element.classList.contains('is-closing');\n\n\t\tif (!isClosed && !isClosing) return;\n\n\t\tthis._animateOpenClose(true, withTransition);\n\t}\n\n\t/**\n\t * Close a closable panelset\n\t * @param withTransition - Whether to animate\n\t */\n\tclose(withTransition: boolean = true): void {\n\t\tif (!this.config.closable) {\n\t\t\tthis._log('Cannot close: closable is false');\n\t\t\treturn;\n\t\t}\n\n\t\tconst isClosed = this.element.classList.contains('is-closed');\n\t\tconst isOpening = this.element.classList.contains('is-opening');\n\n\t\tif (isClosed && !isOpening) return;\n\n\t\tthis._animateOpenClose(false, withTransition);\n\t}\n\n\t/**\n\t * Toggle a closable panelset between open and closed\n\t * @param withTransition - Whether to animate\n\t */\n\ttoggle(withTransition: boolean = true): void {\n\t\tconst isClosed = this.element.classList.contains('is-closed');\n\t\tconst isClosing = this.element.classList.contains('is-closing');\n\n\t\t// If closed or closing, open it\n\t\tif (isClosed || isClosing) {\n\t\t\tthis.open(withTransition);\n\t\t} else {\n\t\t\tthis.close(withTransition);\n\t\t}\n\t}\n\n\t/**\n\t * Register a handler for async content loading\n\t * @param handler - Async content handler function\n\t * @param options - Handler options (once: whether to load only once)\n\t */\n\tonBeforeActivate(handler: AsyncContentHandler, options: HandlerOptions = {}): void {\n\t\tconst once = options.once === true; // Default: false (always reload)\n\n\t\tthis.element.addEventListener('ps:beforeactivate', (e) => {\n\t\t\tconst event = e as CustomEvent<BeforeActivateEventDetail>;\n\t\t\tconst { targetPanel, signal } = event.detail;\n\n\t\t\t// Skip if already loaded and once=true\n\t\t\tif (once && targetPanel.dataset.loaded === 'true') {\n\t\t\t\tif (this.config.debug) {\n\t\t\t\t\tthis._log(`Skipping ${targetPanel.id} (already loaded)`);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Call user handler\n\t\t\tconst result = handler(targetPanel, signal);\n\n\t\t\t// If handler returns a promise, attach it to the event\n\t\t\tif (result && typeof result.then === 'function') {\n\t\t\t\tevent.detail.promise = result\n\t\t\t\t\t.then(() => {\n\t\t\t\t\t\t// Auto-mark as loaded on success if once=true\n\t\t\t\t\t\tif (once) {\n\t\t\t\t\t\t\ttargetPanel.dataset.loaded = 'true';\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\t.catch(error => {\n\t\t\t\t\t\tif (error.name === 'AbortError') {\n\t\t\t\t\t\t\tif (this.config.debug) {\n\t\t\t\t\t\t\t\tthis._log(`Load aborted: ${targetPanel.id}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis._log(`Load failed: ${error.message}`);\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\n\t/* --- Main logic --- */\n\n\t/**\n\t * Show a panel by ID\n\t * @param panelId - ID of the panel to show\n\t * @param withTransition - Whether to animate the transition\n\t * @param options - Additional options (trigger name)\n\t */\n\tasync show(panelId: string, withTransition: boolean = true, options: ShowOptions = {}): Promise<void> {\n\t\tconst newPanel = this.panels.find(p => p.id === panelId);\n\n\t\tif (!newPanel) {\n\t\t\tthis._log(`Panel not found: ${panelId}`);\n\t\t\treturn;\n\t\t}\n\n\t\tif (newPanel === this.pendingPanel) return;\n\n\t\tconst prevPanel = this.pendingPanel;\n\t\tconst prevPanelId = prevPanel?.id;\n\t\tthis.pendingPanel = newPanel;\n\n\t\tthis.element.classList.remove('is-loading');\n\n\t\tif (prevPanel && prevPanel !== this.activePanel && prevPanel !== newPanel) {\n\t\t\tprevPanel.classList.remove('incoming');\n\t\t\tif (prevPanel.hidden) {\n\t\t\t\t// Was never visible, keep hidden\n\t\t\t} else {\n\t\t\t\tprevPanel.classList.remove('active');\n\t\t\t}\n\t\t}\n\n\t\tconst wasLoadingAsync = this._isLoadingAsync;\n\n\t\tif (this._currentAbortController) {\n\t\t\tthis._currentAbortController.abort();\n\n\t\t\t// Only fire abort if we're cancelling an async operation\n\t\t\tif (wasLoadingAsync && prevPanelId && prevPanelId !== panelId) {\n\t\t\t\tthis._dispatch<ActivationAbortedEventDetail>('ps:activationaborted', {\n\t\t\t\t\tpanelId: prevPanelId,\n\t\t\t\t\ttrigger: null\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tconst abortController = new AbortController();\n\t\tthis._currentAbortController = abortController;\n\t\tthis._isLoadingAsync = false;\n\n\t\tthis._log(`${prevPanel?.id || 'none'} → ${panelId}`);\n\n\t\tconst beforeActivateDetail: BeforeActivateEventDetail = {\n\t\t\tpanelId,\n\t\t\ttargetPanel: newPanel,\n\t\t\toutgoingPanel: prevPanel,\n\t\t\tsignal: abortController.signal,\n\t\t\tpromise: null\n\t\t};\n\n\t\tconst beforeActivateEvent = new CustomEvent('ps:beforeactivate', {\n\t\t\tdetail: beforeActivateDetail,\n\t\t\tbubbles: true,\n\t\t\tcancelable: false\n\t\t});\n\n\t\tthis.element.dispatchEvent(beforeActivateEvent);\n\n\t\tconst userPromise = beforeActivateDetail.promise;\n\n\t\tif (userPromise) {\n\t\t\tthis._isLoadingAsync = true;\n\t\t\tthis._log('Waiting for content...');\n\n\t\t\tlet spinnerTimeout: ReturnType<typeof setTimeout> | undefined;\n\t\t\tlet loadingShown = false;\n\n\t\t\tif (this.config.loadingDelay > 0) {\n\t\t\t\tspinnerTimeout = setTimeout(() => {\n\t\t\t\t\tthis.element.classList.add('is-loading');\n\t\t\t\t\tloadingShown = true;\n\t\t\t\t}, this.config.loadingDelay);\n\t\t\t} else {\n\t\t\t\tthis.element.classList.add('is-loading');\n\t\t\t\tloadingShown = true;\n\t\t\t}\n\n\t\t\tconst hasPreviousPanel = this.activePanel && this.activePanel !== newPanel;\n\n\t\t\tif (!hasPreviousPanel) {\n\t\t\t\tconst shouldTransition = withTransition !== false && this.config.transitions !== false;\n\t\t\t\tlet heightTransition = shouldTransition;\n\t\t\t\tif (typeof this.config.transitions === 'object') {\n\t\t\t\t\theightTransition = shouldTransition && this.config.transitions.height !== false;\n\t\t\t\t}\n\n\t\t\t\tif (heightTransition) {\n\t\t\t\t\tconst currentHeight = this.element.offsetHeight;\n\t\t\t\t\tthis.element.style.height = `${currentHeight}px`;\n\n\t\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\t\tthis.element.style.height = `${this.config.emptyPanelHeight}px`;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tawait userPromise;\n\n\t\t\t\tif (spinnerTimeout) clearTimeout(spinnerTimeout);\n\n\t\t\t\tif (abortController.signal.aborted) {\n\t\t\t\t\tthis._log(`Aborted during load: ${panelId}`);\n\t\t\t\t\tif (loadingShown) this.element.classList.remove('is-loading');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis._log('Content loaded');\n\n\t\t\t\tif (newPanel.dataset.loaded === 'true') {\n\t\t\t\t\tthis._updateHighestPanel();\n\t\t\t\t}\n\n\n\t\t\t} catch (error) {\n\t\t\t\tif (spinnerTimeout) clearTimeout(spinnerTimeout);\n\n\t\t\t\tconst err = error as Error;\n\t\t\t\tthis._log(`Load failed: ${err.message}`);\n\t\t\t\tif (loadingShown) this.element.classList.remove('is-loading');\n\n\t\t\t\tif (err.name !== 'AbortError') {\n\t\t\t\t\tconsole.error('Panel load error:', error);\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (loadingShown) this.element.classList.remove('is-loading');\n\t\t}\n\n\t\tif (abortController.signal.aborted) {\n\t\t\tthis._log(`Aborted: ${panelId}`);\n\t\t\treturn;\n\t\t}\n\n\t\tthis._dispatch<ActivationEventDetail>('ps:activationstart', {\n\t\t\tpanelId,\n\t\t\ttrigger: options.trigger || null\n\t\t});\n\n\t\tconst shouldTransition = withTransition !== false && this.config.transitions !== false;\n\n\t\tlet panelTransition = shouldTransition;\n\t\tlet heightTransition = shouldTransition;\n\n\n\t\tif (typeof this.config.transitions === 'object') {\n\t\t\tpanelTransition = shouldTransition && this.config.transitions.panels !== false;\n\t\t\theightTransition = shouldTransition && this.config.transitions.height !== false;\n\t\t}\n\n\t\tthis.panels.forEach(panel => panel.classList.toggle('fade', panelTransition));\n\n\t\tconst startHeight = this.element.offsetHeight;\n\t\tif (heightTransition) {\n\t\t\tthis.element.style.height = `${startHeight}px`;\n\t\t}\n\n\t\tconst outgoingPanel = this.activePanel;\n\n\t\tnewPanel.hidden = false;\n\t\tnewPanel.classList.add('incoming');\n\t\tif (panelTransition) {\n\t\t\t// Apply general transitioning class for overflow: hidden\n\t\t\tthis.element.classList.add('is-transitioning');\n\t\t}\n\t\tif (outgoingPanel && outgoingPanel !== newPanel) {\n\t\t\toutgoingPanel.classList.remove('active', 'incoming');\n\t\t\toutgoingPanel.hidden = false;\n\t\t}\n\n\t\trequestAnimationFrame(() => {\n\t\t\tnewPanel.classList.add('active');\n\t\t\tif (outgoingPanel && outgoingPanel !== newPanel) {\n\t\t\t\toutgoingPanel.classList.remove('incoming');\n\t\t\t}\n\n\t\t\tconst targetHeight = this._measureHeight(newPanel);\n\t\t\tconst heightChanged = startHeight !== targetHeight;\n\n\t\t\tif (heightTransition) {\n\t\t\t\tthis.element.style.height = `${targetHeight}px`;\n\t\t\t}\n\n\t\t\tconst promises: Promise<void>[] = [];\n\t\t\tif (panelTransition) {\n\t\t\t\tpromises.push(this._waitForTransition(newPanel));\n\t\t\t}\n\t\t\tif (heightTransition && heightChanged) {\n\t\t\t\tpromises.push(this._waitForTransition(this.element));\n\t\t\t}\n\t\t\tif (!promises.length) promises.push(Promise.resolve());\n\n\t\t\tPromise.all(promises).then(() => {\n\t\t\t\t// Check if interrupted by another activation\n\t\t\t\tif (this.pendingPanel !== newPanel) {\n\t\t\t\t\tthis._log(`Interrupted: ${panelId}`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis._cleanupPanels(newPanel);\n\t\t\t\tthis._log(`✓ ${panelId}`);\n\t\t\t\tthis._dispatch<ActivationEventDetail>('ps:activationcomplete', {\n\t\t\t\t\tpanelId,\n\t\t\t\t\ttrigger: options.trigger || null\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t}\n}\n\nexport default PanelSet;"],"names":["_PanelSet","elementOrSelector","options","element","dataConfig","p","resizeTimeout","data","config","attrs","key","type","value","defaults","selectorOrOptions","selector","elements","instances","el","error","instance","message","id","elementDesc","wrapper","panel","eventName","detail","sum","prop","total","trackingParent","maxContainerHeight","wasHidden","wasActive","containerHeight","newPanel","resolve","styles","duration","delay","handler","e","isOpening","withTransition","action","oppositeClass","actionClass","myGeneration","targetHeight","currentHeight","isClosed","isClosing","once","event","targetPanel","signal","result","panelId","prevPanel","prevPanelId","wasLoadingAsync","abortController","beforeActivateDetail","beforeActivateEvent","userPromise","spinnerTimeout","loadingShown","shouldTransition","heightTransition","err","panelTransition","startHeight","outgoingPanel","heightChanged","promises","PanelSet"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "panelset",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Flexible panel management with smooth transitions",
5
5
  "type": "module",
6
6
  "main": "./dist/panelset.js",
@@ -24,6 +24,7 @@
24
24
  "build:docs": "vite build --config vite.config.docs.js",
25
25
  "copy-lib": "mkdir -p docs/lib && cp -r dist/* docs/lib/",
26
26
  "preview:docs": "npm run build && vite preview --config vite.config.docs.js",
27
+ "prepublishOnly": "npm run build",
27
28
  "clean": "rm -rf dist docs"
28
29
  },
29
30
  "keywords": [