panelset 0.5.3 → 0.5.4

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/panelset.js CHANGED
@@ -11,17 +11,22 @@ const h = class h {
11
11
  return console.warn("PanelSet: Element already initialized, returning existing instance"), t.panelSet;
12
12
  t.panelSet = this;
13
13
  const i = h._getDataConfig(t);
14
- this.config = h._mergeConfig(
14
+ if (this.config = h._mergeConfig(
15
15
  h.defaults,
16
16
  i,
17
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();
18
+ ), this.panels = Array.from(t.querySelectorAll('[role="tabpanel"]')), this.panels.length === 0) {
19
+ const a = `<${t.tagName.toLowerCase()}${t.id ? ` id="${t.id}"` : ""}${t.className ? ` class="${t.className}"` : ""}>`;
20
+ console.error(`PanelSet: No panels with [role="tabpanel"] found inside ${a}. Make sure panel elements are children of the [data-panelset] element.`), this.panels = [], this.activePanel = null, this.panelWrapper = null, this.pendingPanel = null;
21
+ return;
22
+ }
23
+ 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.element.dataset.panelset = "true", this._log(`Initialized (${this.panels.length} panels)`), this._dispatch("ps:ready", { container: this.element, instance: this }), this._internalInit();
19
24
  let n;
20
25
  window.addEventListener("resize", () => {
21
26
  clearTimeout(n), n = setTimeout(() => {
22
27
  this._updateHighestPanel();
23
28
  }, 250);
24
- }), this.element.dataset.panelset = "true", this._log(`Initialized (${this.panels.length} panels)`), this._dispatch("ps:ready", { container: this.element, instance: this });
29
+ });
25
30
  }
26
31
  // Parse data attributes from element
27
32
  static _getDataConfig(e) {
@@ -143,7 +148,7 @@ const h = class h {
143
148
  }), t.hidden = !1, t.classList.add("active"), t.style.visibility = "hidden", this.element.offsetHeight;
144
149
  const a = this.element.offsetHeight;
145
150
  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) => {
151
+ }), this.activePanel && (this.activePanel.hidden = !1, this.activePanel.classList.add("active")), this.panels.forEach((t) => {
147
152
  t !== this.activePanel && (t.hidden = !0, t.classList.remove("active"));
148
153
  }), e.style.setProperty("--ps-max-height", `${s}px`), this._log(`Max container height: ${s}px (set on tracking parent)`);
149
154
  }
@@ -272,12 +277,12 @@ const h = class h {
272
277
  outgoingPanel: n,
273
278
  signal: l.signal,
274
279
  promise: null
275
- }, P = new CustomEvent("ps:beforeactivate", {
280
+ }, y = new CustomEvent("ps:beforeactivate", {
276
281
  detail: c,
277
282
  bubbles: !0,
278
283
  cancelable: !1
279
284
  });
280
- this.element.dispatchEvent(P);
285
+ this.element.dispatchEvent(y);
281
286
  const _ = c.promise;
282
287
  if (_) {
283
288
  this._isLoadingAsync = !0, this._log("Waiting for content...");
@@ -347,9 +352,9 @@ h.defaults = {
347
352
  loadingDelay: 300,
348
353
  debug: !1
349
354
  };
350
- let y = h;
355
+ let P = h;
351
356
  export {
352
- y as PanelSet,
353
- y as default
357
+ P as PanelSet,
358
+ P as default
354
359
  };
355
360
  //# sourceMappingURL=panelset.js.map
@@ -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\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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"}
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\n\t\tif (this.panels.length === 0) {\n\t\t\tconst elementDesc = `<${element.tagName.toLowerCase()}${element.id ? ` id=\"${element.id}\"` : ''}${element.className ? ` class=\"${element.className}\"` : ''}>`;\n\t\t\tconsole.error(`PanelSet: No panels with [role=\"tabpanel\"] found inside ${elementDesc}. Make sure panel elements are children of the [data-panelset] element.`);\n\t\t\t// Set safe defaults and bail\n\t\t\tthis.panels = [];\n\t\t\tthis.activePanel = null as any;\n\t\t\tthis.panelWrapper = null as any;\n\t\t\tthis.pendingPanel = null as any;\n\t\t\treturn;\n\t\t}\n\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\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\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\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\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\n\t\tif (this.activePanel) {\n\t\t\tthis.activePanel.hidden = false;\n\t\t\tthis.activePanel.classList.add('active');\n\t\t}\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","elementDesc","p","resizeTimeout","data","config","attrs","key","type","value","defaults","selectorOrOptions","selector","elements","instances","el","error","instance","message","id","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":"AA8DO,MAAMA,IAAN,MAAMA,EAAS;AAAA,EA2HrB,YAAYC,GAAyCC,IAA0B,IAAI;AAzGnF,SAAQ,uBAA+B,GACvC,KAAQ,kBAA2B;AA0GlC,QAAIC;AACJ,QAAI,OAAOF,KAAsB;AAEhC,UADAE,IAAU,SAAS,cAA2BF,CAAiB,GAC3D,CAACE;AACJ,cAAM,IAAI,MAAM,4CAA4CF,CAAiB,GAAG;AAAA;AAGjF,MAAAE,IAAUF;AASX,QANA,KAAK,UAAUE,GAGfH,EAAS,iBAAiBG,CAAO,GAG7BA,EAAQ,YAAYA,EAAQ,QAAQ,aAAa;AACpD,qBAAQ,KAAK,oEAAoE,GAC1EA,EAAQ;AAIhB,IAAAA,EAAQ,WAAW;AAEnB,UAAMC,IAAaJ,EAAS,eAAeG,CAAO;AASlD,QARA,KAAK,SAASH,EAAS;AAAA,MACtBA,EAAS;AAAA,MACTI;AAAA,MACAF;AAAA,IAAA,GAGD,KAAK,SAAS,MAAM,KAAKC,EAAQ,iBAA8B,mBAAmB,CAAC,GAE/E,KAAK,OAAO,WAAW,GAAG;AAC7B,YAAME,IAAc,IAAIF,EAAQ,QAAQ,aAAa,GAAGA,EAAQ,KAAK,QAAQA,EAAQ,EAAE,MAAM,EAAE,GAAGA,EAAQ,YAAY,WAAWA,EAAQ,SAAS,MAAM,EAAE;AAC1J,cAAQ,MAAM,2DAA2DE,CAAW,yEAAyE,GAE7J,KAAK,SAAS,CAAA,GACd,KAAK,cAAc,MACnB,KAAK,eAAe,MACpB,KAAK,eAAe;AACpB;AAAA,IACD;AAEA,SAAK,cACJ,KAAK,OAAO,KAAK,CAAAC,MAAKA,EAAE,UAAU,SAAS,QAAQ,CAAC,KAAK,KAAK,OAAO,CAAC,GACvE,KAAK,eACJ,KAAK,QAAQ,cAA2B,gBAAgB,KAAK,KAAK,gBAAA,GAEnE,KAAK,eAAe,KAAK,aAKzB,KAAK,QAAQ,QAAQ,WAAW,QAEhC,KAAK,KAAK,gBAAgB,KAAK,OAAO,MAAM,UAAU,GACtD,KAAK,UAA4B,YAAY,EAAE,WAAW,KAAK,SAAS,UAAU,MAAM,GAExF,KAAK,cAAA;AAEL,QAAIC;AACJ,WAAO,iBAAiB,UAAU,MAAM;AACvC,mBAAaA,CAAa,GAC1BA,IAAgB,WAAW,MAAM;AAChC,aAAK,oBAAA;AAAA,MACN,GAAG,GAAG;AAAA,IACP,CAAC;AAAA,EAEF;AAAA;AAAA,EA3KA,OAAO,eAAeJ,GAA+C;AACpE,UAAMK,IAAOL,EAAQ,SACfM,IAAkC,CAAA,GAGlCC,IAAuD;AAAA,MAC5D,aAAa;AAAA,MACb,UAAU;AAAA,MACV,kBAAkB;AAAA,MAClB,cAAc;AAAA,MACd,OAAO;AAAA,IAAA;AAIR,eAAW,CAACC,GAAKC,CAAI,KAAK,OAAO,QAAQF,CAAK,GAAG;AAChD,UAAI,EAAEC,KAAOH,GAAO;AAEpB,YAAMK,IAAQL,EAAKG,CAAG;AACtB,UAAIE,MAAU;AAEd,gBAAQD,GAAA;AAAA,UACP,KAAK;AACH,YAAAH,EAAeE,CAAG,IAAIE,MAAU;AACjC;AAAA,UACD,KAAK;AACH,YAAAJ,EAAeE,CAAG,IAAI,SAASE,GAAO,EAAE;AACzC;AAAA,UACD,KAAK;AACJ,gBAAI;AACF,cAAAJ,EAAeE,CAAG,IAAI,KAAK,MAAME,CAAK;AAAA,YACxC,QAAQ;AAEN,cAAAJ,EAAeE,CAAG,IAAIE,MAAU;AAAA,YAClC;AACA;AAAA,QAAA;AAAA,IAEH;AAEA,WAAOJ;AAAA,EACR;AAAA;AAAA,EAGA,OAAO,aACNK,GACAV,GACAF,GAC6C;AAC7C,WAAO;AAAA,MACN,GAAGY;AAAA,MACH,GAAGV;AAAA,MACH,GAAGF;AAAA,IAAA;AAAA,EAEL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,KAAKa,IAA6C,IAAIb,IAA0B,CAAA,GAAgB;AAEtG,QAAIc,GACAP;AAEJ,IAAI,OAAOM,KAAsB,YAEhCC,IAAWD,GACXN,IAASP,MAGTO,IAASM,GACTC,IAAWP,EAAO,YAAY;AAG/B,UAAMQ,IAAW,SAAS,iBAA8BD,CAAQ,GAC1DE,IAAwB,CAAA;AAE9B,WAAAD,EAAS,QAAQ,CAAAE,MAAM;AAEtB,UAAI;AACH,QAAAnB,EAAS,iBAAiBmB,CAAE;AAAA,MAC7B,SAASC,GAAO;AACf,gBAAQ,MAAOA,EAAgB,OAAO;AACtC;AAAA,MACD;AAGA,UAAID,EAAG,YAAYA,EAAG,QAAQ,aAAa,QAAQ;AAClD,QAAIA,EAAG,YAAUD,EAAU,KAAKC,EAAG,QAAQ;AAC3C;AAAA,MACD;AAEA,YAAME,IAAW,IAAIrB,EAASmB,GAAIV,CAAM;AACxC,MAAAS,EAAU,KAAKG,CAAQ;AAAA,IACxB,CAAC,GAEMH;AAAA,EACR;AAAA;AAAA,EA4EQ,KAAKI,GAAuB;AACnC,QAAI,CAAC,KAAK,OAAO,MAAO;AACxB,UAAMC,IAAK,KAAK,QAAQ,MAAM;AAC9B,YAAQ,IAAI,iBAAiBA,CAAE,OAAOD,CAAO;AAAA,EAC9C;AAAA,EAEA,OAAe,iBAAiBnB,GAA4B;AAC3D,QAAI,CAACA,EAAQ,aAAa,eAAe,GAAG;AAC3C,YAAME,IAAc,IAAIF,EAAQ,QAAQ,aAAa,GAAGA,EAAQ,KAAK,QAAQA,EAAQ,EAAE,MAAM,EAAE,GAAGA,EAAQ,YAAY,WAAWA,EAAQ,SAAS,MAAM,EAAE;AAC1J,YAAM,IAAI,MAAM,2EAA2EE,CAAW,EAAE;AAAA,IACzG;AAAA,EACD;AAAA,EAEQ,kBAA+B;AACtC,UAAMmB,IAAU,SAAS,cAAc,KAAK;AAC5C,WAAAA,EAAQ,YAAY,iBACpB,KAAK,OAAO,QAAQ,CAAAC,MAASD,EAAQ,YAAYC,CAAK,CAAC,GACvD,KAAK,QAAQ,YAAYD,CAAO,GACzBA;AAAA,EACR;AAAA,EAEQ,gBAAsB;AAC7B,SAAK,OAAO,QAAQ,CAAAC,MAAS;AAC5B,MAAAA,EAAM,UAAU,OAAO,QAAQ,UAAU,GACrCA,MAAU,KAAK,eAClBA,EAAM,SAAS,IACfA,EAAM,UAAU,OAAO,QAAQ,MAE/BA,EAAM,SAAS,IACfA,EAAM,UAAU,IAAI,QAAQ;AAAA,IAE9B,CAAC,GACD,KAAK,QAAQ,MAAM,SAAS,IAC5B,KAAK,oBAAA;AAAA,EACN;AAAA;AAAA,EAGQ,UAAuBC,GAAmBC,GAAiB;AAClE,SAAK,QAAQ;AAAA,MACZ,IAAI,YAAYD,GAAW;AAAA,QAC1B,QAAAC;AAAA,QACA,SAAS;AAAA,QACT,YAAY;AAAA,MAAA,CACZ;AAAA,IAAA;AAAA,EAEH;AAAA;AAAA,EAIQ,oBAAoBR,GAAgC;AAC3D,QAAI,CAACA,EAAI,QAAO;AAChB,UAAM,IAAI,iBAAiBA,CAAE;AAC7B,WAAO,CAAC,cAAc,iBAAiB,kBAAkB,mBAAmB,EAC1E,OAAO,CAACS,GAAKC,MAASD,KAAO,WAAW,EAAEC,CAAiC,CAAW,KAAK,IAAI,CAAC;AAAA,EACnG;AAAA,EAEQ,eAAeJ,GAA4B;AAClD,QAAIK,IAAQL,EAAM;AAClB,WAAAK,KAAS,KAAK,oBAAoB,KAAK,YAAY,GACnDA,KAAS,KAAK,oBAAoB,KAAK,OAAO,GACvCA;AAAA,EACR;AAAA,EAEQ,sBAA4B;AAGnC,QAAI,KAAK,QAAQ,aAAa,sBAAsB,GAAG;AACtD,cAAQ,KAAK,8HAA8H;AAC3I;AAAA,IACD;AAGA,UAAMC,IAAiB,KAAK,QAAQ,QAAQ,wBAAwB;AACpE,QAAI,CAACA,EAAgB;AAErB,QAAIC,IAAqB;AAGzB,SAAK,OAAO,QAAQ,CAAAP,MAAS;AAE5B,YAAMQ,IAAYR,EAAM,QAClBS,IAAYT,EAAM,UAAU,SAAS,QAAQ;AAGnD,WAAK,OAAO,QAAQ,CAAAnB,MAAK;AACxB,QAAAA,EAAE,SAAS,IACXA,EAAE,UAAU,OAAO,QAAQ;AAAA,MAC5B,CAAC,GAEDmB,EAAM,SAAS,IACfA,EAAM,UAAU,IAAI,QAAQ,GAC5BA,EAAM,MAAM,aAAa,UAGzB,KAAK,QAAQ;AAGb,YAAMU,IAAkB,KAAK,QAAQ;AACrC,MAAIA,IAAkBH,MACrBA,IAAqBG,IAItBV,EAAM,SAASQ,GACVC,KAAWT,EAAM,UAAU,OAAO,QAAQ,GAC/CA,EAAM,MAAM,aAAa;AAAA,IAC1B,CAAC,GAEG,KAAK,gBACR,KAAK,YAAY,SAAS,IAC1B,KAAK,YAAY,UAAU,IAAI,QAAQ,IAExC,KAAK,OAAO,QAAQ,CAAAnB,MAAK;AACxB,MAAIA,MAAM,KAAK,gBACdA,EAAE,SAAS,IACXA,EAAE,UAAU,OAAO,QAAQ;AAAA,IAE7B,CAAC,GAGAyB,EAA+B,MAAM,YAAY,mBAAmB,GAAGC,CAAkB,IAAI,GAC9F,KAAK,KAAK,yBAAyBA,CAAkB,6BAA6B;AAAA,EACnF;AAAA,EAEQ,eAAeI,GAA6B;AACnD,SAAK,OAAO,QAAQ,CAAAX,MAAS;AAC5B,MAAAA,EAAM,UAAU,OAAO,QAAQ,UAAU,GACrCA,MAAUW,KACbX,EAAM,UAAU,OAAO,QAAQ,GAC/BA,EAAM,SAAS,OAEfA,EAAM,UAAU,IAAI,QAAQ,GAC5BA,EAAM,SAAS;AAAA,IAEjB,CAAC,GACD,KAAK,QAAQ,MAAM,SAAS,IAC5B,KAAK,QAAQ,UAAU,OAAO,kBAAkB,GAChD,KAAK,cAAcW;AAAA,EACpB;AAAA,EAEQ,mBAAmBjC,GAAqC;AAC/D,WAAO,IAAI,QAAQ,CAAAkC,MAAW;AAC7B,YAAMC,IAAS,iBAAiBnC,CAAO,GACjCoC,IAAW,WAAWD,EAAO,kBAAkB,KAAK,GACpDE,IAAQ,WAAWF,EAAO,eAAe,KAAK;AACpD,UAAIC,IAAWC,MAAU,GAAG;AAC3B,QAAAH,EAAA;AACA;AAAA,MACD;AACA,YAAMI,IAAU,CAACC,MAAuB;AACvC,QAAIA,EAAE,WAAWvC,MACjBA,EAAQ,oBAAoB,iBAAiBsC,CAAO,GACpDJ,EAAA;AAAA,MACD;AACA,MAAAlC,EAAQ,iBAAiB,iBAAiBsC,CAAO;AAAA,IAClD,CAAC;AAAA,EACF;AAAA;AAAA,EAGQ,kBAAkBE,GAAoBC,GAA+B;AAC5E,UAAMC,IAASF,IAAY,YAAY,WAEjCG,IAAgB,MADCH,IAAY,YAAY,SACL,IACpCI,IAAc,MAAMF,CAAM;AAEhC,SAAK,KAAKF,IAAY,YAAY,SAAS,GAE3C,KAAK;AACL,UAAMK,IAAe,KAAK;AAG1B,IAAI,KAAK,QAAQ,UAAU,SAASF,CAAa,KAChD,KAAK,QAAQ,UAAU,OAAOA,CAAa;AAG5C,UAAMG,IAAeN,IAAY,KAAK,eAAe,KAAK,YAAY,IAAI;AAE1E,QAAIC,KAAkB,KAAK,OAAO,aAAa;AAC9C,WAAK,QAAQ,UAAU,IAAIG,CAAW;AAEtC,YAAMG,IAAgB,KAAK,QAAQ;AACnC,WAAK,QAAQ,MAAM,SAAS,GAAGA,CAAa,MAExCP,KAAW,KAAK,QAAQ,UAAU,OAAO,WAAW,GAExD,sBAAsB,MAAM;AAC3B,aAAK,QAAQ,MAAM,SAAS,GAAGM,CAAY,MAE3C,KAAK,mBAAmB,KAAK,OAAO,EAAE,KAAK,MAAM;AAChD,UAAI,KAAK,yBAAyBD,MACjC,KAAK,QAAQ,MAAM,SAAS,IAC5B,KAAK,QAAQ,UAAU,OAAOD,CAAW,GACpCJ,KAAW,KAAK,QAAQ,UAAU,IAAI,WAAW;AAAA,QAExD,CAAC;AAAA,MACF,CAAC;AAAA,IACF;AACC,MAAIA,IACH,KAAK,QAAQ,UAAU,OAAO,WAAW,IAEzC,KAAK,QAAQ,UAAU,IAAI,WAAW,GAEvC,KAAK,QAAQ,MAAM,SAAS;AAAA,EAE9B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAA2B;AAC1B,WAAO,KAAK,cAAc,MAAM;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAKC,IAA0B,IAAY;AAC1C,QAAI,CAAC,KAAK,OAAO,UAAU;AAC1B,WAAK,KAAK,gCAAgC;AAC1C;AAAA,IACD;AAEA,UAAMO,IAAW,KAAK,QAAQ,UAAU,SAAS,WAAW,GACtDC,IAAY,KAAK,QAAQ,UAAU,SAAS,YAAY;AAE9D,IAAI,CAACD,KAAY,CAACC,KAElB,KAAK,kBAAkB,IAAMR,CAAc;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAMA,IAA0B,IAAY;AAC3C,QAAI,CAAC,KAAK,OAAO,UAAU;AAC1B,WAAK,KAAK,iCAAiC;AAC3C;AAAA,IACD;AAEA,UAAMO,IAAW,KAAK,QAAQ,UAAU,SAAS,WAAW,GACtDR,IAAY,KAAK,QAAQ,UAAU,SAAS,YAAY;AAE9D,IAAIQ,KAAY,CAACR,KAEjB,KAAK,kBAAkB,IAAOC,CAAc;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAOA,IAA0B,IAAY;AAC5C,UAAMO,IAAW,KAAK,QAAQ,UAAU,SAAS,WAAW,GACtDC,IAAY,KAAK,QAAQ,UAAU,SAAS,YAAY;AAG9D,IAAID,KAAYC,IACf,KAAK,KAAKR,CAAc,IAExB,KAAK,MAAMA,CAAc;AAAA,EAE3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,iBAAiBH,GAA8BvC,IAA0B,IAAU;AAClF,UAAMmD,IAAOnD,EAAQ,SAAS;AAE9B,SAAK,QAAQ,iBAAiB,qBAAqB,CAACwC,MAAM;AACzD,YAAMY,IAAQZ,GACR,EAAE,aAAAa,GAAa,QAAAC,EAAA,IAAWF,EAAM;AAGtC,UAAID,KAAQE,EAAY,QAAQ,WAAW,QAAQ;AAClD,QAAI,KAAK,OAAO,SACf,KAAK,KAAK,YAAYA,EAAY,EAAE,mBAAmB;AAExD;AAAA,MACD;AAGA,YAAME,IAAShB,EAAQc,GAAaC,CAAM;AAG1C,MAAIC,KAAU,OAAOA,EAAO,QAAS,eACpCH,EAAM,OAAO,UAAUG,EACrB,KAAK,MAAM;AAEX,QAAIJ,MACHE,EAAY,QAAQ,SAAS;AAAA,MAE/B,CAAC,EACA,MAAM,CAAAnC,MAAS;AACf,cAAIA,EAAM,SAAS,gBACd,KAAK,OAAO,SACf,KAAK,KAAK,iBAAiBmC,EAAY,EAAE,EAAE,GAEtCnC,MAEN,KAAK,KAAK,gBAAgBA,EAAM,OAAO,EAAE,GACnCA;AAAA,MAER,CAAC;AAAA,IAEJ,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,KAAKsC,GAAiBd,IAA0B,IAAM1C,IAAuB,CAAA,GAAmB;AACrG,UAAMkC,IAAW,KAAK,OAAO,KAAK,CAAA9B,MAAKA,EAAE,OAAOoD,CAAO;AAEvD,QAAI,CAACtB,GAAU;AACd,WAAK,KAAK,oBAAoBsB,CAAO,EAAE;AACvC;AAAA,IACD;AAEA,QAAItB,MAAa,KAAK,aAAc;AAEpC,UAAMuB,IAAY,KAAK,cACjBC,IAAcD,GAAW;AAC/B,SAAK,eAAevB,GAEpB,KAAK,QAAQ,UAAU,OAAO,YAAY,GAEtCuB,KAAaA,MAAc,KAAK,eAAeA,MAAcvB,MAChEuB,EAAU,UAAU,OAAO,UAAU,GACjCA,EAAU,UAGbA,EAAU,UAAU,OAAO,QAAQ;AAIrC,UAAME,IAAkB,KAAK;AAE7B,IAAI,KAAK,4BACR,KAAK,wBAAwB,MAAA,GAGzBA,KAAmBD,KAAeA,MAAgBF,KACrD,KAAK,UAAwC,wBAAwB;AAAA,MACpE,SAASE;AAAA,MACT,SAAS;AAAA,IAAA,CACT;AAIH,UAAME,IAAkB,IAAI,gBAAA;AAC5B,SAAK,0BAA0BA,GAC/B,KAAK,kBAAkB,IAEvB,KAAK,KAAK,GAAGH,GAAW,MAAM,MAAM,MAAMD,CAAO,EAAE;AAEnD,UAAMK,IAAkD;AAAA,MACvD,SAAAL;AAAA,MACA,aAAatB;AAAA,MACb,eAAeuB;AAAA,MACf,QAAQG,EAAgB;AAAA,MACxB,SAAS;AAAA,IAAA,GAGJE,IAAsB,IAAI,YAAY,qBAAqB;AAAA,MAChE,QAAQD;AAAA,MACR,SAAS;AAAA,MACT,YAAY;AAAA,IAAA,CACZ;AAED,SAAK,QAAQ,cAAcC,CAAmB;AAE9C,UAAMC,IAAcF,EAAqB;AAEzC,QAAIE,GAAa;AAChB,WAAK,kBAAkB,IACvB,KAAK,KAAK,wBAAwB;AAElC,UAAIC,GACAC,IAAe;AAcnB,UAZI,KAAK,OAAO,eAAe,IAC9BD,IAAiB,WAAW,MAAM;AACjC,aAAK,QAAQ,UAAU,IAAI,YAAY,GACvCC,IAAe;AAAA,MAChB,GAAG,KAAK,OAAO,YAAY,KAE3B,KAAK,QAAQ,UAAU,IAAI,YAAY,GACvCA,IAAe,KAKZ,EAFqB,KAAK,eAAe,KAAK,gBAAgB/B,IAE3C;AACtB,cAAMgC,IAAmBxB,MAAmB,MAAS,KAAK,OAAO,gBAAgB;AACjF,YAAIyB,IAAmBD;AAKvB,YAJI,OAAO,KAAK,OAAO,eAAgB,aACtCC,IAAmBD,KAAoB,KAAK,OAAO,YAAY,WAAW,KAGvEC,GAAkB;AACrB,gBAAMnB,IAAgB,KAAK,QAAQ;AACnC,eAAK,QAAQ,MAAM,SAAS,GAAGA,CAAa,MAE5C,sBAAsB,MAAM;AAC3B,iBAAK,QAAQ,MAAM,SAAS,GAAG,KAAK,OAAO,gBAAgB;AAAA,UAC5D,CAAC;AAAA,QACF;AAAA,MACD;AAEA,UAAI;AAKH,YAJA,MAAMe,GAEFC,kBAA6BA,CAAc,GAE3CJ,EAAgB,OAAO,SAAS;AACnC,eAAK,KAAK,wBAAwBJ,CAAO,EAAE,GACvCS,KAAc,KAAK,QAAQ,UAAU,OAAO,YAAY;AAC5D;AAAA,QACD;AAEA,aAAK,KAAK,gBAAgB,GAEtB/B,EAAS,QAAQ,WAAW,UAC/B,KAAK,oBAAA;AAAA,MAIP,SAAShB,GAAO;AACf,QAAI8C,kBAA6BA,CAAc;AAE/C,cAAMI,IAAMlD;AACZ,aAAK,KAAK,gBAAgBkD,EAAI,OAAO,EAAE,GACnCH,KAAc,KAAK,QAAQ,UAAU,OAAO,YAAY,GAExDG,EAAI,SAAS,gBAChB,QAAQ,MAAM,qBAAqBlD,CAAK;AAGzC;AAAA,MACD;AAEA,MAAI+C,KAAc,KAAK,QAAQ,UAAU,OAAO,YAAY;AAAA,IAC7D;AAEA,QAAIL,EAAgB,OAAO,SAAS;AACnC,WAAK,KAAK,YAAYJ,CAAO,EAAE;AAC/B;AAAA,IACD;AAEA,SAAK,UAAiC,sBAAsB;AAAA,MAC3D,SAAAA;AAAA,MACA,SAASxD,EAAQ,WAAW;AAAA,IAAA,CAC5B;AAED,UAAMkE,IAAmBxB,MAAmB,MAAS,KAAK,OAAO,gBAAgB;AAEjF,QAAI2B,IAAkBH,GAClBC,IAAmBD;AAGvB,IAAI,OAAO,KAAK,OAAO,eAAgB,aACtCG,IAAkBH,KAAoB,KAAK,OAAO,YAAY,WAAW,IACzEC,IAAmBD,KAAoB,KAAK,OAAO,YAAY,WAAW,KAG3E,KAAK,OAAO,QAAQ,CAAA3C,MAASA,EAAM,UAAU,OAAO,QAAQ8C,CAAe,CAAC;AAE5E,UAAMC,IAAc,KAAK,QAAQ;AACjC,IAAIH,MACH,KAAK,QAAQ,MAAM,SAAS,GAAGG,CAAW;AAG3C,UAAMC,IAAgB,KAAK;AAE3B,IAAArC,EAAS,SAAS,IAClBA,EAAS,UAAU,IAAI,UAAU,GAC7BmC,KAEH,KAAK,QAAQ,UAAU,IAAI,kBAAkB,GAE1CE,KAAiBA,MAAkBrC,MACtCqC,EAAc,UAAU,OAAO,UAAU,UAAU,GACnDA,EAAc,SAAS,KAGxB,sBAAsB,MAAM;AAC3B,MAAArC,EAAS,UAAU,IAAI,QAAQ,GAC3BqC,KAAiBA,MAAkBrC,KACtCqC,EAAc,UAAU,OAAO,UAAU;AAG1C,YAAMxB,IAAe,KAAK,eAAeb,CAAQ,GAC3CsC,IAAgBF,MAAgBvB;AAEtC,MAAIoB,MACH,KAAK,QAAQ,MAAM,SAAS,GAAGpB,CAAY;AAG5C,YAAM0B,IAA4B,CAAA;AAClC,MAAIJ,KACHI,EAAS,KAAK,KAAK,mBAAmBvC,CAAQ,CAAC,GAE5CiC,KAAoBK,KACvBC,EAAS,KAAK,KAAK,mBAAmB,KAAK,OAAO,CAAC,GAE/CA,EAAS,YAAiB,KAAK,QAAQ,SAAS,GAErD,QAAQ,IAAIA,CAAQ,EAAE,KAAK,MAAM;AAEhC,YAAI,KAAK,iBAAiBvC,GAAU;AACnC,eAAK,KAAK,gBAAgBsB,CAAO,EAAE;AACnC;AAAA,QACD;AAEA,aAAK,eAAetB,CAAQ,GAC5B,KAAK,KAAK,KAAKsB,CAAO,EAAE,GACxB,KAAK,UAAiC,yBAAyB;AAAA,UAC9D,SAAAA;AAAA,UACA,SAASxD,EAAQ,WAAW;AAAA,QAAA,CAC5B;AAAA,MACF,CAAC;AAAA,IACF,CAAC;AAAA,EACF;AACD;AAztBCF,EAAO,WAAuD;AAAA,EAC7D,aAAa;AAAA,EACb,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,OAAO;AAAA;AAPF,IAAM4E,IAAN5E;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "panelset",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "Flexible panel management with smooth transitions",
5
5
  "type": "module",
6
6
  "main": "./dist/panelset.js",