@alivecss/aliveui 1.1.0 → 1.3.0
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/README.md +52 -0
- package/dist/cli.js +2041 -0
- package/dist/index.js +2041 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2041 -0
- package/dist/index.mjs.map +1 -1
- package/dist/runtime.js +74 -0
- package/dist/runtime.js.map +1 -1
- package/dist/runtime.mjs +74 -0
- package/dist/runtime.mjs.map +1 -1
- package/dist/vite.js +2041 -0
- package/dist/vite.js.map +1 -1
- package/dist/vite.mjs +2041 -0
- package/dist/vite.mjs.map +1 -1
- package/package.json +1 -1
package/dist/runtime.js
CHANGED
|
@@ -268,6 +268,79 @@ function wireMagnetic(el, root) {
|
|
|
268
268
|
registerCleanup(root, moveCleanup);
|
|
269
269
|
registerCleanup(root, leaveCleanup);
|
|
270
270
|
}
|
|
271
|
+
function resetSceneAnimations(scene) {
|
|
272
|
+
const animated = scene.querySelectorAll(
|
|
273
|
+
'[class*="alive-enter"], [class*="alive-loop"], .alive-typewriter, .alive-typewriter-fast, .alive-typewriter-slow, .alive-word-reveal > *, .alive-kinetic-slam, .alive-metric-card, .alive-toast, .alive-badge-pulse, .alive-spotlight, .alive-code-block'
|
|
274
|
+
);
|
|
275
|
+
animated.forEach((el) => {
|
|
276
|
+
const saved = el.style.animationName;
|
|
277
|
+
el.style.animationName = "none";
|
|
278
|
+
void el.offsetHeight;
|
|
279
|
+
el.style.animationName = saved;
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
function wireVideoSequence(container, root) {
|
|
283
|
+
const scenes = [...container.querySelectorAll(":scope > [data-alive-scene]")];
|
|
284
|
+
if (scenes.length === 0) return;
|
|
285
|
+
const loop = container.hasAttribute("data-alive-loop");
|
|
286
|
+
let current = 0;
|
|
287
|
+
let timeoutId = null;
|
|
288
|
+
const containerEl = container;
|
|
289
|
+
if (getComputedStyle(containerEl).position === "static") {
|
|
290
|
+
containerEl.style.position = "relative";
|
|
291
|
+
}
|
|
292
|
+
containerEl.style.overflow = "hidden";
|
|
293
|
+
scenes.forEach((s) => {
|
|
294
|
+
s.style.position = "absolute";
|
|
295
|
+
s.style.inset = "0";
|
|
296
|
+
s.classList.remove("is-active");
|
|
297
|
+
});
|
|
298
|
+
function activate(index) {
|
|
299
|
+
const scene = scenes[index];
|
|
300
|
+
resetSceneAnimations(scene);
|
|
301
|
+
scene.classList.add("is-active");
|
|
302
|
+
scene.style.zIndex = "1";
|
|
303
|
+
}
|
|
304
|
+
function scheduleNext(fromIndex) {
|
|
305
|
+
const scene = scenes[fromIndex];
|
|
306
|
+
const duration = parseInt(scene.getAttribute("data-alive-duration") ?? "3000", 10);
|
|
307
|
+
timeoutId = setTimeout(() => {
|
|
308
|
+
const nextIndex = fromIndex + 1;
|
|
309
|
+
const toIndex = nextIndex >= scenes.length ? loop ? 0 : -1 : nextIndex;
|
|
310
|
+
if (toIndex === -1) return;
|
|
311
|
+
doTransition(fromIndex, toIndex);
|
|
312
|
+
}, duration);
|
|
313
|
+
}
|
|
314
|
+
function doTransition(fromIndex, toIndex) {
|
|
315
|
+
const outScene = scenes[fromIndex];
|
|
316
|
+
const inScene = scenes[toIndex];
|
|
317
|
+
const transType = outScene.getAttribute("data-alive-transition") ?? "fade";
|
|
318
|
+
const transDur = parseInt(outScene.getAttribute("data-alive-trans-duration") ?? "600", 10);
|
|
319
|
+
const outClass = `alive-transition-${transType}-out`;
|
|
320
|
+
const inClass = `alive-transition-${transType}-in`;
|
|
321
|
+
outScene.style.setProperty("--alive-tr-dur", `${transDur}ms`);
|
|
322
|
+
inScene.style.setProperty("--alive-tr-dur", `${transDur}ms`);
|
|
323
|
+
outScene.style.zIndex = "2";
|
|
324
|
+
outScene.classList.add(outClass);
|
|
325
|
+
inScene.style.zIndex = "1";
|
|
326
|
+
resetSceneAnimations(inScene);
|
|
327
|
+
inScene.classList.add("is-active", inClass);
|
|
328
|
+
timeoutId = setTimeout(() => {
|
|
329
|
+
outScene.classList.remove("is-active", outClass);
|
|
330
|
+
outScene.style.zIndex = "";
|
|
331
|
+
outScene.style.removeProperty("--alive-tr-dur");
|
|
332
|
+
inScene.classList.remove(inClass);
|
|
333
|
+
inScene.style.removeProperty("--alive-tr-dur");
|
|
334
|
+
current = toIndex;
|
|
335
|
+
scheduleNext(current);
|
|
336
|
+
}, transDur);
|
|
337
|
+
}
|
|
338
|
+
activate(current);
|
|
339
|
+
scheduleNext(current);
|
|
340
|
+
registerCleanup(root, () => {
|
|
341
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
342
|
+
});
|
|
343
|
+
}
|
|
271
344
|
function init(root = document.documentElement) {
|
|
272
345
|
root.querySelectorAll("[data-alive-accordion]").forEach((el) => wireAccordion(el, root));
|
|
273
346
|
root.querySelectorAll("[data-alive-modal]").forEach((el) => wireModal(el, root));
|
|
@@ -278,6 +351,7 @@ function init(root = document.documentElement) {
|
|
|
278
351
|
root.querySelectorAll("[data-alive-stagger]").forEach((el) => wireStagger(el));
|
|
279
352
|
root.querySelectorAll("[data-alive-tilt]").forEach((el) => wireTilt(el, root));
|
|
280
353
|
root.querySelectorAll("[data-alive-magnetic]").forEach((el) => wireMagnetic(el, root));
|
|
354
|
+
root.querySelectorAll("[data-alive-sequence]").forEach((el) => wireVideoSequence(el, root));
|
|
281
355
|
}
|
|
282
356
|
function destroy(root = document.documentElement) {
|
|
283
357
|
const cleanups = cleanupRegistry.get(root) ?? [];
|
package/dist/runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["/**\n * AliveUI Runtime\n *\n * Provides data-attribute-driven interactivity for accordion, modal, drawer,\n * dropdown, and tabs components — zero dependencies, ~2 KB.\n *\n * Usage:\n * import { init } from '@alivecss/aliveui/runtime'\n * init() // wire everything in document\n * init(myRootElement) // wire a subtree\n */\n\ntype Cleanup = () => void\n\nconst cleanupRegistry = new WeakMap<Element, Cleanup[]>()\n\nfunction registerCleanup(root: Element, fn: Cleanup): void {\n const existing = cleanupRegistry.get(root) ?? []\n existing.push(fn)\n cleanupRegistry.set(root, existing)\n}\n\nfunction addListener<K extends keyof HTMLElementEventMap>(\n el: EventTarget,\n type: K,\n handler: (e: HTMLElementEventMap[K]) => void,\n options?: AddEventListenerOptions,\n): Cleanup {\n el.addEventListener(type, handler as EventListener, options)\n return () => el.removeEventListener(type, handler as EventListener, options)\n}\n\n// ── Accordion ─────────────────────────────────────────────────────────────────\n\nfunction wireAccordion(container: Element, root: Element): void {\n const triggers = container.querySelectorAll<HTMLElement>('[data-alive-trigger]')\n triggers.forEach(trigger => {\n const item = trigger.closest('[data-alive-accordion-item]') ?? trigger.parentElement\n if (!item) return\n\n const cleanup = addListener(trigger, 'click', () => {\n const isOpen = item.classList.contains('is-open')\n // Close all items if not multi-open\n if (!container.hasAttribute('data-alive-multi')) {\n container.querySelectorAll('[data-alive-accordion-item]').forEach(i => {\n i.classList.remove('is-open')\n i.querySelector('[data-alive-trigger]')?.setAttribute('aria-expanded', 'false')\n })\n }\n if (!isOpen) {\n item.classList.add('is-open')\n trigger.setAttribute('aria-expanded', 'true')\n }\n })\n registerCleanup(root, cleanup)\n })\n}\n\n// ── Modal ─────────────────────────────────────────────────────────────────────\n\nfunction wireModal(modal: Element, root: Element): void {\n const id = modal.getAttribute('data-alive-modal')\n if (!id) return\n\n // Open triggers\n const openers = document.querySelectorAll<HTMLElement>(`[data-alive-open=\"${id}\"]`)\n openers.forEach(opener => {\n const cleanup = addListener(opener, 'click', () => openModal(id))\n registerCleanup(root, cleanup)\n })\n\n // Close triggers inside the modal\n modal.querySelectorAll<HTMLElement>('[data-alive-close]').forEach(closer => {\n const cleanup = addListener(closer, 'click', () => closeModal(id))\n registerCleanup(root, cleanup)\n })\n\n // Backdrop click to close (click on the modal wrapper, not the content)\n const cleanup = addListener(modal, 'click', (e) => {\n if (e.target === modal) closeModal(id)\n })\n registerCleanup(root, cleanup)\n\n // ESC key\n const escCleanup = addListener(document, 'keydown', (e) => {\n if (e.key === 'Escape' && modal.classList.contains('is-open')) closeModal(id)\n })\n registerCleanup(root, escCleanup)\n}\n\nexport function openModal(id: string): void {\n const modal = document.querySelector<HTMLElement>(`[data-alive-modal=\"${id}\"]`)\n if (!modal) return\n modal.classList.add('is-open')\n modal.setAttribute('aria-hidden', 'false')\n document.body.style.overflow = 'hidden'\n // Focus first focusable element\n const focusable = modal.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n )\n focusable?.focus()\n}\n\nexport function closeModal(id: string): void {\n const modal = document.querySelector<HTMLElement>(`[data-alive-modal=\"${id}\"]`)\n if (!modal) return\n modal.classList.remove('is-open')\n modal.setAttribute('aria-hidden', 'true')\n document.body.style.overflow = ''\n}\n\n// ── Drawer ────────────────────────────────────────────────────────────────────\n\nfunction wireDrawer(drawer: Element, root: Element): void {\n const id = drawer.getAttribute('data-alive-drawer')\n if (!id) return\n\n const openers = document.querySelectorAll<HTMLElement>(`[data-alive-open=\"${id}\"]`)\n openers.forEach(opener => {\n const cleanup = addListener(opener, 'click', () => openDrawer(id))\n registerCleanup(root, cleanup)\n })\n\n drawer.querySelectorAll<HTMLElement>('[data-alive-close]').forEach(closer => {\n const cleanup = addListener(closer, 'click', () => closeDrawer(id))\n registerCleanup(root, cleanup)\n })\n\n const backdropCleanup = addListener(drawer, 'click', (e) => {\n if (e.target === drawer) closeDrawer(id)\n })\n registerCleanup(root, backdropCleanup)\n\n const escCleanup = addListener(document, 'keydown', (e) => {\n if (e.key === 'Escape' && drawer.classList.contains('is-open')) closeDrawer(id)\n })\n registerCleanup(root, escCleanup)\n}\n\nexport function openDrawer(id: string): void {\n const drawer = document.querySelector<HTMLElement>(`[data-alive-drawer=\"${id}\"]`)\n if (!drawer) return\n drawer.classList.add('is-open')\n drawer.setAttribute('aria-hidden', 'false')\n document.body.style.overflow = 'hidden'\n}\n\nexport function closeDrawer(id: string): void {\n const drawer = document.querySelector<HTMLElement>(`[data-alive-drawer=\"${id}\"]`)\n if (!drawer) return\n drawer.classList.remove('is-open')\n drawer.setAttribute('aria-hidden', 'true')\n document.body.style.overflow = ''\n}\n\n// ── Dropdown ──────────────────────────────────────────────────────────────────\n\nfunction wireDropdown(container: Element, root: Element): void {\n const trigger = container.querySelector<HTMLElement>('[data-alive-trigger]')\n const menu = container.querySelector<HTMLElement>('[data-alive-dropdown-menu]')\n if (!trigger || !menu) return\n\n const toggleCleanup = addListener(trigger, 'click', (e) => {\n e.stopPropagation()\n toggleDropdown(container)\n })\n registerCleanup(root, toggleCleanup)\n\n // Close on outside click\n const outsideCleanup = addListener(document, 'click', (e) => {\n if (!container.contains(e.target as Node)) {\n menu.classList.remove('is-open')\n trigger.setAttribute('aria-expanded', 'false')\n }\n })\n registerCleanup(root, outsideCleanup)\n\n // Close on ESC\n const escCleanup = addListener(document, 'keydown', (e) => {\n if (e.key === 'Escape' && menu.classList.contains('is-open')) {\n menu.classList.remove('is-open')\n trigger.setAttribute('aria-expanded', 'false')\n trigger.focus()\n }\n })\n registerCleanup(root, escCleanup)\n}\n\nexport function toggleDropdown(container: Element): void {\n const trigger = container.querySelector<HTMLElement>('[data-alive-trigger]')\n const menu = container.querySelector<HTMLElement>('[data-alive-dropdown-menu]')\n if (!menu) return\n const isOpen = menu.classList.toggle('is-open')\n trigger?.setAttribute('aria-expanded', String(isOpen))\n if (isOpen) {\n // Focus first item\n menu.querySelector<HTMLElement>('[role=\"menuitem\"], button, a')?.focus()\n }\n}\n\n// ── Tabs ──────────────────────────────────────────────────────────────────────\n\nfunction wireTabs(container: Element, root: Element): void {\n const tabs = container.querySelectorAll<HTMLElement>('[data-alive-tab]')\n tabs.forEach(tab => {\n const cleanup = addListener(tab, 'click', () => {\n const panelId = tab.getAttribute('data-alive-tab')\n if (!panelId) return\n activateTab(container, panelId)\n })\n registerCleanup(root, cleanup)\n\n // Keyboard navigation\n const keyCleanup = addListener(tab, 'keydown', (e) => {\n const allTabs = [...container.querySelectorAll<HTMLElement>('[data-alive-tab]')]\n const idx = allTabs.indexOf(tab)\n if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {\n e.preventDefault()\n allTabs[(idx + 1) % allTabs.length]?.focus()\n } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {\n e.preventDefault()\n allTabs[(idx - 1 + allTabs.length) % allTabs.length]?.focus()\n }\n })\n registerCleanup(root, keyCleanup)\n })\n}\n\nfunction activateTab(container: Element, panelId: string): void {\n // Deactivate all tabs + panels within this tabs container\n container.querySelectorAll('[data-alive-tab]').forEach(t => {\n t.classList.remove('is-active')\n t.setAttribute('aria-selected', 'false')\n t.setAttribute('tabindex', '-1')\n })\n\n // Find panels — look in the container, then in the whole document\n const searchRoot = container.closest('[data-alive-tabs-panels]') ?? document\n searchRoot.querySelectorAll('[data-alive-panel]').forEach(p => {\n p.classList.remove('is-active')\n p.setAttribute('aria-hidden', 'true')\n })\n\n // Activate the selected tab\n const activeTab = container.querySelector<HTMLElement>(`[data-alive-tab=\"${panelId}\"]`)\n activeTab?.classList.add('is-active')\n activeTab?.setAttribute('aria-selected', 'true')\n activeTab?.setAttribute('tabindex', '0')\n\n // Activate the matching panel\n const activePanel = searchRoot.querySelector<HTMLElement>(`[data-alive-panel=\"${panelId}\"]`)\n activePanel?.classList.add('is-active')\n activePanel?.setAttribute('aria-hidden', 'false')\n}\n\n// ── Scroll Reveal ──────────────────────────────────────────────────────────────\n\nfunction wireScroll(el: Element, root: Element): void {\n const obs = new IntersectionObserver(\n (entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n entry.target.classList.add('is-visible')\n obs.unobserve(entry.target)\n }\n })\n },\n { threshold: 0.1, rootMargin: '0px 0px -40px 0px' },\n )\n obs.observe(el)\n registerCleanup(root, () => obs.disconnect())\n}\n\n// ── Auto-Stagger ───────────────────────────────────────────────────────────────\n\nfunction wireStagger(container: Element): void {\n const children = [...container.children] as HTMLElement[]\n children.forEach((child, i) => {\n child.style.setProperty('--alive-index', String(i))\n })\n}\n\n// ── 3D Tilt ────────────────────────────────────────────────────────────────────\n\nfunction wireTilt(el: Element, root: Element): void {\n const htmlEl = el as HTMLElement\n const STRENGTH = 8\n\n const moveCleanup = addListener(htmlEl, 'mousemove', (e) => {\n const rect = htmlEl.getBoundingClientRect()\n const x = (e.clientX - rect.left) / rect.width - 0.5\n const y = (e.clientY - rect.top) / rect.height - 0.5\n htmlEl.style.transform = `perspective(800px) rotateY(${x * STRENGTH}deg) rotateX(${-y * STRENGTH}deg) scale(1.01)`\n htmlEl.style.transition = 'transform 0.1s ease-out'\n })\n\n const leaveCleanup = addListener(htmlEl, 'mouseleave', () => {\n htmlEl.style.transform = ''\n htmlEl.style.transition = 'transform 0.4s cubic-bezier(0.16, 1, 0.3, 1)'\n })\n\n registerCleanup(root, moveCleanup)\n registerCleanup(root, leaveCleanup)\n}\n\n// ── Magnetic Follow ────────────────────────────────────────────────────────────\n\nfunction wireMagnetic(el: Element, root: Element): void {\n const htmlEl = el as HTMLElement\n const PULL = 0.35\n\n const moveCleanup = addListener(htmlEl, 'mousemove', (e) => {\n const rect = htmlEl.getBoundingClientRect()\n const cx = rect.left + rect.width / 2\n const cy = rect.top + rect.height / 2\n const dx = (e.clientX - cx) * PULL\n const dy = (e.clientY - cy) * PULL\n htmlEl.style.transform = `translate(${dx}px, ${dy}px)`\n htmlEl.style.transition = 'transform 0.2s cubic-bezier(0.16, 1, 0.3, 1)'\n })\n\n const leaveCleanup = addListener(htmlEl, 'mouseleave', () => {\n htmlEl.style.transform = ''\n htmlEl.style.transition = 'transform 0.5s cubic-bezier(0.16, 1, 0.3, 1)'\n })\n\n registerCleanup(root, moveCleanup)\n registerCleanup(root, leaveCleanup)\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Wire all data-alive-* components within `root` (defaults to document.documentElement).\n * Safe to call multiple times — existing listeners are tracked and replaced on `destroy()`.\n */\nexport function init(root: Element = document.documentElement): void {\n // Accordion\n root.querySelectorAll('[data-alive-accordion]').forEach(el => wireAccordion(el, root))\n\n // Modal\n root.querySelectorAll('[data-alive-modal]').forEach(el => wireModal(el, root))\n\n // Drawer\n root.querySelectorAll('[data-alive-drawer]').forEach(el => wireDrawer(el, root))\n\n // Dropdown\n root.querySelectorAll('[data-alive-dropdown]').forEach(el => wireDropdown(el, root))\n\n // Tabs\n root.querySelectorAll('[data-alive-tabs]').forEach(el => wireTabs(el, root))\n\n // Scroll reveal\n root.querySelectorAll('[data-alive-scroll]').forEach(el => wireScroll(el, root))\n\n // Auto-stagger children\n root.querySelectorAll('[data-alive-stagger]').forEach(el => wireStagger(el))\n\n // 3D tilt\n root.querySelectorAll('[data-alive-tilt]').forEach(el => wireTilt(el, root))\n\n // Magnetic follow\n root.querySelectorAll('[data-alive-magnetic]').forEach(el => wireMagnetic(el, root))\n}\n\n/**\n * Remove all event listeners registered by `init(root)`.\n */\nexport function destroy(root: Element = document.documentElement): void {\n const cleanups = cleanupRegistry.get(root) ?? []\n cleanups.forEach(fn => fn())\n cleanupRegistry.delete(root)\n}\n"],"mappings":"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","names":["cleanup"]}
|
|
1
|
+
{"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["/**\n * AliveUI Runtime\n *\n * Provides data-attribute-driven interactivity for accordion, modal, drawer,\n * dropdown, and tabs components — zero dependencies, ~2 KB.\n *\n * Usage:\n * import { init } from '@alivecss/aliveui/runtime'\n * init() // wire everything in document\n * init(myRootElement) // wire a subtree\n */\n\ntype Cleanup = () => void\n\nconst cleanupRegistry = new WeakMap<Element, Cleanup[]>()\n\nfunction registerCleanup(root: Element, fn: Cleanup): void {\n const existing = cleanupRegistry.get(root) ?? []\n existing.push(fn)\n cleanupRegistry.set(root, existing)\n}\n\nfunction addListener<K extends keyof HTMLElementEventMap>(\n el: EventTarget,\n type: K,\n handler: (e: HTMLElementEventMap[K]) => void,\n options?: AddEventListenerOptions,\n): Cleanup {\n el.addEventListener(type, handler as EventListener, options)\n return () => el.removeEventListener(type, handler as EventListener, options)\n}\n\n// ── Accordion ─────────────────────────────────────────────────────────────────\n\nfunction wireAccordion(container: Element, root: Element): void {\n const triggers = container.querySelectorAll<HTMLElement>('[data-alive-trigger]')\n triggers.forEach(trigger => {\n const item = trigger.closest('[data-alive-accordion-item]') ?? trigger.parentElement\n if (!item) return\n\n const cleanup = addListener(trigger, 'click', () => {\n const isOpen = item.classList.contains('is-open')\n // Close all items if not multi-open\n if (!container.hasAttribute('data-alive-multi')) {\n container.querySelectorAll('[data-alive-accordion-item]').forEach(i => {\n i.classList.remove('is-open')\n i.querySelector('[data-alive-trigger]')?.setAttribute('aria-expanded', 'false')\n })\n }\n if (!isOpen) {\n item.classList.add('is-open')\n trigger.setAttribute('aria-expanded', 'true')\n }\n })\n registerCleanup(root, cleanup)\n })\n}\n\n// ── Modal ─────────────────────────────────────────────────────────────────────\n\nfunction wireModal(modal: Element, root: Element): void {\n const id = modal.getAttribute('data-alive-modal')\n if (!id) return\n\n // Open triggers\n const openers = document.querySelectorAll<HTMLElement>(`[data-alive-open=\"${id}\"]`)\n openers.forEach(opener => {\n const cleanup = addListener(opener, 'click', () => openModal(id))\n registerCleanup(root, cleanup)\n })\n\n // Close triggers inside the modal\n modal.querySelectorAll<HTMLElement>('[data-alive-close]').forEach(closer => {\n const cleanup = addListener(closer, 'click', () => closeModal(id))\n registerCleanup(root, cleanup)\n })\n\n // Backdrop click to close (click on the modal wrapper, not the content)\n const cleanup = addListener(modal, 'click', (e) => {\n if (e.target === modal) closeModal(id)\n })\n registerCleanup(root, cleanup)\n\n // ESC key\n const escCleanup = addListener(document, 'keydown', (e) => {\n if (e.key === 'Escape' && modal.classList.contains('is-open')) closeModal(id)\n })\n registerCleanup(root, escCleanup)\n}\n\nexport function openModal(id: string): void {\n const modal = document.querySelector<HTMLElement>(`[data-alive-modal=\"${id}\"]`)\n if (!modal) return\n modal.classList.add('is-open')\n modal.setAttribute('aria-hidden', 'false')\n document.body.style.overflow = 'hidden'\n // Focus first focusable element\n const focusable = modal.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n )\n focusable?.focus()\n}\n\nexport function closeModal(id: string): void {\n const modal = document.querySelector<HTMLElement>(`[data-alive-modal=\"${id}\"]`)\n if (!modal) return\n modal.classList.remove('is-open')\n modal.setAttribute('aria-hidden', 'true')\n document.body.style.overflow = ''\n}\n\n// ── Drawer ────────────────────────────────────────────────────────────────────\n\nfunction wireDrawer(drawer: Element, root: Element): void {\n const id = drawer.getAttribute('data-alive-drawer')\n if (!id) return\n\n const openers = document.querySelectorAll<HTMLElement>(`[data-alive-open=\"${id}\"]`)\n openers.forEach(opener => {\n const cleanup = addListener(opener, 'click', () => openDrawer(id))\n registerCleanup(root, cleanup)\n })\n\n drawer.querySelectorAll<HTMLElement>('[data-alive-close]').forEach(closer => {\n const cleanup = addListener(closer, 'click', () => closeDrawer(id))\n registerCleanup(root, cleanup)\n })\n\n const backdropCleanup = addListener(drawer, 'click', (e) => {\n if (e.target === drawer) closeDrawer(id)\n })\n registerCleanup(root, backdropCleanup)\n\n const escCleanup = addListener(document, 'keydown', (e) => {\n if (e.key === 'Escape' && drawer.classList.contains('is-open')) closeDrawer(id)\n })\n registerCleanup(root, escCleanup)\n}\n\nexport function openDrawer(id: string): void {\n const drawer = document.querySelector<HTMLElement>(`[data-alive-drawer=\"${id}\"]`)\n if (!drawer) return\n drawer.classList.add('is-open')\n drawer.setAttribute('aria-hidden', 'false')\n document.body.style.overflow = 'hidden'\n}\n\nexport function closeDrawer(id: string): void {\n const drawer = document.querySelector<HTMLElement>(`[data-alive-drawer=\"${id}\"]`)\n if (!drawer) return\n drawer.classList.remove('is-open')\n drawer.setAttribute('aria-hidden', 'true')\n document.body.style.overflow = ''\n}\n\n// ── Dropdown ──────────────────────────────────────────────────────────────────\n\nfunction wireDropdown(container: Element, root: Element): void {\n const trigger = container.querySelector<HTMLElement>('[data-alive-trigger]')\n const menu = container.querySelector<HTMLElement>('[data-alive-dropdown-menu]')\n if (!trigger || !menu) return\n\n const toggleCleanup = addListener(trigger, 'click', (e) => {\n e.stopPropagation()\n toggleDropdown(container)\n })\n registerCleanup(root, toggleCleanup)\n\n // Close on outside click\n const outsideCleanup = addListener(document, 'click', (e) => {\n if (!container.contains(e.target as Node)) {\n menu.classList.remove('is-open')\n trigger.setAttribute('aria-expanded', 'false')\n }\n })\n registerCleanup(root, outsideCleanup)\n\n // Close on ESC\n const escCleanup = addListener(document, 'keydown', (e) => {\n if (e.key === 'Escape' && menu.classList.contains('is-open')) {\n menu.classList.remove('is-open')\n trigger.setAttribute('aria-expanded', 'false')\n trigger.focus()\n }\n })\n registerCleanup(root, escCleanup)\n}\n\nexport function toggleDropdown(container: Element): void {\n const trigger = container.querySelector<HTMLElement>('[data-alive-trigger]')\n const menu = container.querySelector<HTMLElement>('[data-alive-dropdown-menu]')\n if (!menu) return\n const isOpen = menu.classList.toggle('is-open')\n trigger?.setAttribute('aria-expanded', String(isOpen))\n if (isOpen) {\n // Focus first item\n menu.querySelector<HTMLElement>('[role=\"menuitem\"], button, a')?.focus()\n }\n}\n\n// ── Tabs ──────────────────────────────────────────────────────────────────────\n\nfunction wireTabs(container: Element, root: Element): void {\n const tabs = container.querySelectorAll<HTMLElement>('[data-alive-tab]')\n tabs.forEach(tab => {\n const cleanup = addListener(tab, 'click', () => {\n const panelId = tab.getAttribute('data-alive-tab')\n if (!panelId) return\n activateTab(container, panelId)\n })\n registerCleanup(root, cleanup)\n\n // Keyboard navigation\n const keyCleanup = addListener(tab, 'keydown', (e) => {\n const allTabs = [...container.querySelectorAll<HTMLElement>('[data-alive-tab]')]\n const idx = allTabs.indexOf(tab)\n if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {\n e.preventDefault()\n allTabs[(idx + 1) % allTabs.length]?.focus()\n } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {\n e.preventDefault()\n allTabs[(idx - 1 + allTabs.length) % allTabs.length]?.focus()\n }\n })\n registerCleanup(root, keyCleanup)\n })\n}\n\nfunction activateTab(container: Element, panelId: string): void {\n // Deactivate all tabs + panels within this tabs container\n container.querySelectorAll('[data-alive-tab]').forEach(t => {\n t.classList.remove('is-active')\n t.setAttribute('aria-selected', 'false')\n t.setAttribute('tabindex', '-1')\n })\n\n // Find panels — look in the container, then in the whole document\n const searchRoot = container.closest('[data-alive-tabs-panels]') ?? document\n searchRoot.querySelectorAll('[data-alive-panel]').forEach(p => {\n p.classList.remove('is-active')\n p.setAttribute('aria-hidden', 'true')\n })\n\n // Activate the selected tab\n const activeTab = container.querySelector<HTMLElement>(`[data-alive-tab=\"${panelId}\"]`)\n activeTab?.classList.add('is-active')\n activeTab?.setAttribute('aria-selected', 'true')\n activeTab?.setAttribute('tabindex', '0')\n\n // Activate the matching panel\n const activePanel = searchRoot.querySelector<HTMLElement>(`[data-alive-panel=\"${panelId}\"]`)\n activePanel?.classList.add('is-active')\n activePanel?.setAttribute('aria-hidden', 'false')\n}\n\n// ── Scroll Reveal ──────────────────────────────────────────────────────────────\n\nfunction wireScroll(el: Element, root: Element): void {\n const obs = new IntersectionObserver(\n (entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n entry.target.classList.add('is-visible')\n obs.unobserve(entry.target)\n }\n })\n },\n { threshold: 0.1, rootMargin: '0px 0px -40px 0px' },\n )\n obs.observe(el)\n registerCleanup(root, () => obs.disconnect())\n}\n\n// ── Auto-Stagger ───────────────────────────────────────────────────────────────\n\nfunction wireStagger(container: Element): void {\n const children = [...container.children] as HTMLElement[]\n children.forEach((child, i) => {\n child.style.setProperty('--alive-index', String(i))\n })\n}\n\n// ── 3D Tilt ────────────────────────────────────────────────────────────────────\n\nfunction wireTilt(el: Element, root: Element): void {\n const htmlEl = el as HTMLElement\n const STRENGTH = 8\n\n const moveCleanup = addListener(htmlEl, 'mousemove', (e) => {\n const rect = htmlEl.getBoundingClientRect()\n const x = (e.clientX - rect.left) / rect.width - 0.5\n const y = (e.clientY - rect.top) / rect.height - 0.5\n htmlEl.style.transform = `perspective(800px) rotateY(${x * STRENGTH}deg) rotateX(${-y * STRENGTH}deg) scale(1.01)`\n htmlEl.style.transition = 'transform 0.1s ease-out'\n })\n\n const leaveCleanup = addListener(htmlEl, 'mouseleave', () => {\n htmlEl.style.transform = ''\n htmlEl.style.transition = 'transform 0.4s cubic-bezier(0.16, 1, 0.3, 1)'\n })\n\n registerCleanup(root, moveCleanup)\n registerCleanup(root, leaveCleanup)\n}\n\n// ── Magnetic Follow ────────────────────────────────────────────────────────────\n\nfunction wireMagnetic(el: Element, root: Element): void {\n const htmlEl = el as HTMLElement\n const PULL = 0.35\n\n const moveCleanup = addListener(htmlEl, 'mousemove', (e) => {\n const rect = htmlEl.getBoundingClientRect()\n const cx = rect.left + rect.width / 2\n const cy = rect.top + rect.height / 2\n const dx = (e.clientX - cx) * PULL\n const dy = (e.clientY - cy) * PULL\n htmlEl.style.transform = `translate(${dx}px, ${dy}px)`\n htmlEl.style.transition = 'transform 0.2s cubic-bezier(0.16, 1, 0.3, 1)'\n })\n\n const leaveCleanup = addListener(htmlEl, 'mouseleave', () => {\n htmlEl.style.transform = ''\n htmlEl.style.transition = 'transform 0.5s cubic-bezier(0.16, 1, 0.3, 1)'\n })\n\n registerCleanup(root, moveCleanup)\n registerCleanup(root, leaveCleanup)\n}\n\n// ── Video Scene Sequencer ──────────────────────────────────────────────────────\n\n/**\n * Force-restart CSS animations on all animated children of a scene element.\n * This ensures stagger delays are relative to scene activation, not page load.\n */\nfunction resetSceneAnimations(scene: HTMLElement): void {\n const animated = scene.querySelectorAll<HTMLElement>(\n '[class*=\"alive-enter\"], [class*=\"alive-loop\"], ' +\n '.alive-typewriter, .alive-typewriter-fast, .alive-typewriter-slow, ' +\n '.alive-word-reveal > *, .alive-kinetic-slam, ' +\n '.alive-metric-card, .alive-toast, .alive-badge-pulse, ' +\n '.alive-spotlight, .alive-code-block',\n )\n animated.forEach(el => {\n const saved = el.style.animationName\n el.style.animationName = 'none'\n void el.offsetHeight // force reflow — restarts animation from t=0\n el.style.animationName = saved\n })\n}\n\n/**\n * Wire a [data-alive-sequence] container.\n *\n * Markup:\n * <div data-alive-sequence data-alive-loop style=\"position:relative; width:800px; height:500px;\">\n * <div data-alive-scene data-alive-duration=\"3000\" data-alive-transition=\"wipe-left\">…</div>\n * <div data-alive-scene data-alive-duration=\"2500\" data-alive-transition=\"fade\">…</div>\n * </div>\n *\n * Scene attributes:\n * data-alive-duration — how long to show the scene (ms, default 3000)\n * data-alive-transition — transition type (default \"fade\"; matches alive-transition-* classes)\n * data-alive-trans-duration — transition animation duration (ms, default 600)\n *\n * Sequence attributes:\n * data-alive-loop — loop back to the first scene after the last\n */\nfunction wireVideoSequence(container: Element, root: Element): void {\n const scenes = [...container.querySelectorAll<HTMLElement>(':scope > [data-alive-scene]')]\n if (scenes.length === 0) return\n\n const loop = container.hasAttribute('data-alive-loop')\n let current = 0\n let timeoutId: ReturnType<typeof setTimeout> | null = null\n\n const containerEl = container as HTMLElement\n if (getComputedStyle(containerEl).position === 'static') {\n containerEl.style.position = 'relative'\n }\n containerEl.style.overflow = 'hidden'\n\n scenes.forEach(s => {\n s.style.position = 'absolute'\n s.style.inset = '0'\n s.classList.remove('is-active')\n })\n\n function activate(index: number): void {\n const scene = scenes[index]\n resetSceneAnimations(scene)\n scene.classList.add('is-active')\n scene.style.zIndex = '1'\n }\n\n function scheduleNext(fromIndex: number): void {\n const scene = scenes[fromIndex]\n const duration = parseInt(scene.getAttribute('data-alive-duration') ?? '3000', 10)\n\n timeoutId = setTimeout(() => {\n const nextIndex = fromIndex + 1\n const toIndex = nextIndex >= scenes.length ? (loop ? 0 : -1) : nextIndex\n if (toIndex === -1) return\n doTransition(fromIndex, toIndex)\n }, duration)\n }\n\n function doTransition(fromIndex: number, toIndex: number): void {\n const outScene = scenes[fromIndex]\n const inScene = scenes[toIndex]\n const transType = outScene.getAttribute('data-alive-transition') ?? 'fade'\n const transDur = parseInt(outScene.getAttribute('data-alive-trans-duration') ?? '600', 10)\n\n const outClass = `alive-transition-${transType}-out`\n const inClass = `alive-transition-${transType}-in`\n\n // Sync CSS animation duration with the JS timer\n outScene.style.setProperty('--alive-tr-dur', `${transDur}ms`)\n inScene.style.setProperty('--alive-tr-dur', `${transDur}ms`)\n\n // Outgoing goes on top (required for wipe/clip-path transitions)\n outScene.style.zIndex = '2'\n outScene.classList.add(outClass)\n\n // Activate incoming beneath, reset its child animations\n inScene.style.zIndex = '1'\n resetSceneAnimations(inScene)\n inScene.classList.add('is-active', inClass)\n\n timeoutId = setTimeout(() => {\n outScene.classList.remove('is-active', outClass)\n outScene.style.zIndex = ''\n outScene.style.removeProperty('--alive-tr-dur')\n inScene.classList.remove(inClass)\n inScene.style.removeProperty('--alive-tr-dur')\n current = toIndex\n scheduleNext(current)\n }, transDur)\n }\n\n activate(current)\n scheduleNext(current)\n\n registerCleanup(root, () => {\n if (timeoutId) clearTimeout(timeoutId)\n })\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Wire all data-alive-* components within `root` (defaults to document.documentElement).\n * Safe to call multiple times — existing listeners are tracked and replaced on `destroy()`.\n */\nexport function init(root: Element = document.documentElement): void {\n // Accordion\n root.querySelectorAll('[data-alive-accordion]').forEach(el => wireAccordion(el, root))\n\n // Modal\n root.querySelectorAll('[data-alive-modal]').forEach(el => wireModal(el, root))\n\n // Drawer\n root.querySelectorAll('[data-alive-drawer]').forEach(el => wireDrawer(el, root))\n\n // Dropdown\n root.querySelectorAll('[data-alive-dropdown]').forEach(el => wireDropdown(el, root))\n\n // Tabs\n root.querySelectorAll('[data-alive-tabs]').forEach(el => wireTabs(el, root))\n\n // Scroll reveal\n root.querySelectorAll('[data-alive-scroll]').forEach(el => wireScroll(el, root))\n\n // Auto-stagger children\n root.querySelectorAll('[data-alive-stagger]').forEach(el => wireStagger(el))\n\n // 3D tilt\n root.querySelectorAll('[data-alive-tilt]').forEach(el => wireTilt(el, root))\n\n // Magnetic follow\n root.querySelectorAll('[data-alive-magnetic]').forEach(el => wireMagnetic(el, root))\n\n // Video scene sequencer\n root.querySelectorAll('[data-alive-sequence]').forEach(el => wireVideoSequence(el, root))\n}\n\n/**\n * Remove all event listeners registered by `init(root)`.\n */\nexport function destroy(root: Element = document.documentElement): void {\n const cleanups = cleanupRegistry.get(root) ?? []\n cleanups.forEach(fn => fn())\n cleanupRegistry.delete(root)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,IAAM,kBAAkB,oBAAI,QAA4B;AAExD,SAAS,gBAAgB,MAAe,IAAmB;AACzD,QAAM,WAAW,gBAAgB,IAAI,IAAI,KAAK,CAAC;AAC/C,WAAS,KAAK,EAAE;AAChB,kBAAgB,IAAI,MAAM,QAAQ;AACpC;AAEA,SAAS,YACP,IACA,MACA,SACA,SACS;AACT,KAAG,iBAAiB,MAAM,SAA0B,OAAO;AAC3D,SAAO,MAAM,GAAG,oBAAoB,MAAM,SAA0B,OAAO;AAC7E;AAIA,SAAS,cAAc,WAAoB,MAAqB;AAC9D,QAAM,WAAW,UAAU,iBAA8B,sBAAsB;AAC/E,WAAS,QAAQ,aAAW;AAC1B,UAAM,OAAO,QAAQ,QAAQ,6BAA6B,KAAK,QAAQ;AACvE,QAAI,CAAC,KAAM;AAEX,UAAM,UAAU,YAAY,SAAS,SAAS,MAAM;AAClD,YAAM,SAAS,KAAK,UAAU,SAAS,SAAS;AAEhD,UAAI,CAAC,UAAU,aAAa,kBAAkB,GAAG;AAC/C,kBAAU,iBAAiB,6BAA6B,EAAE,QAAQ,OAAK;AACrE,YAAE,UAAU,OAAO,SAAS;AAC5B,YAAE,cAAc,sBAAsB,GAAG,aAAa,iBAAiB,OAAO;AAAA,QAChF,CAAC;AAAA,MACH;AACA,UAAI,CAAC,QAAQ;AACX,aAAK,UAAU,IAAI,SAAS;AAC5B,gBAAQ,aAAa,iBAAiB,MAAM;AAAA,MAC9C;AAAA,IACF,CAAC;AACD,oBAAgB,MAAM,OAAO;AAAA,EAC/B,CAAC;AACH;AAIA,SAAS,UAAU,OAAgB,MAAqB;AACtD,QAAM,KAAK,MAAM,aAAa,kBAAkB;AAChD,MAAI,CAAC,GAAI;AAGT,QAAM,UAAU,SAAS,iBAA8B,qBAAqB,EAAE,IAAI;AAClF,UAAQ,QAAQ,YAAU;AACxB,UAAMA,WAAU,YAAY,QAAQ,SAAS,MAAM,UAAU,EAAE,CAAC;AAChE,oBAAgB,MAAMA,QAAO;AAAA,EAC/B,CAAC;AAGD,QAAM,iBAA8B,oBAAoB,EAAE,QAAQ,YAAU;AAC1E,UAAMA,WAAU,YAAY,QAAQ,SAAS,MAAM,WAAW,EAAE,CAAC;AACjE,oBAAgB,MAAMA,QAAO;AAAA,EAC/B,CAAC;AAGD,QAAM,UAAU,YAAY,OAAO,SAAS,CAAC,MAAM;AACjD,QAAI,EAAE,WAAW,MAAO,YAAW,EAAE;AAAA,EACvC,CAAC;AACD,kBAAgB,MAAM,OAAO;AAG7B,QAAM,aAAa,YAAY,UAAU,WAAW,CAAC,MAAM;AACzD,QAAI,EAAE,QAAQ,YAAY,MAAM,UAAU,SAAS,SAAS,EAAG,YAAW,EAAE;AAAA,EAC9E,CAAC;AACD,kBAAgB,MAAM,UAAU;AAClC;AAEO,SAAS,UAAU,IAAkB;AAC1C,QAAM,QAAQ,SAAS,cAA2B,sBAAsB,EAAE,IAAI;AAC9E,MAAI,CAAC,MAAO;AACZ,QAAM,UAAU,IAAI,SAAS;AAC7B,QAAM,aAAa,eAAe,OAAO;AACzC,WAAS,KAAK,MAAM,WAAW;AAE/B,QAAM,YAAY,MAAM;AAAA,IACtB;AAAA,EACF;AACA,aAAW,MAAM;AACnB;AAEO,SAAS,WAAW,IAAkB;AAC3C,QAAM,QAAQ,SAAS,cAA2B,sBAAsB,EAAE,IAAI;AAC9E,MAAI,CAAC,MAAO;AACZ,QAAM,UAAU,OAAO,SAAS;AAChC,QAAM,aAAa,eAAe,MAAM;AACxC,WAAS,KAAK,MAAM,WAAW;AACjC;AAIA,SAAS,WAAW,QAAiB,MAAqB;AACxD,QAAM,KAAK,OAAO,aAAa,mBAAmB;AAClD,MAAI,CAAC,GAAI;AAET,QAAM,UAAU,SAAS,iBAA8B,qBAAqB,EAAE,IAAI;AAClF,UAAQ,QAAQ,YAAU;AACxB,UAAM,UAAU,YAAY,QAAQ,SAAS,MAAM,WAAW,EAAE,CAAC;AACjE,oBAAgB,MAAM,OAAO;AAAA,EAC/B,CAAC;AAED,SAAO,iBAA8B,oBAAoB,EAAE,QAAQ,YAAU;AAC3E,UAAM,UAAU,YAAY,QAAQ,SAAS,MAAM,YAAY,EAAE,CAAC;AAClE,oBAAgB,MAAM,OAAO;AAAA,EAC/B,CAAC;AAED,QAAM,kBAAkB,YAAY,QAAQ,SAAS,CAAC,MAAM;AAC1D,QAAI,EAAE,WAAW,OAAQ,aAAY,EAAE;AAAA,EACzC,CAAC;AACD,kBAAgB,MAAM,eAAe;AAErC,QAAM,aAAa,YAAY,UAAU,WAAW,CAAC,MAAM;AACzD,QAAI,EAAE,QAAQ,YAAY,OAAO,UAAU,SAAS,SAAS,EAAG,aAAY,EAAE;AAAA,EAChF,CAAC;AACD,kBAAgB,MAAM,UAAU;AAClC;AAEO,SAAS,WAAW,IAAkB;AAC3C,QAAM,SAAS,SAAS,cAA2B,uBAAuB,EAAE,IAAI;AAChF,MAAI,CAAC,OAAQ;AACb,SAAO,UAAU,IAAI,SAAS;AAC9B,SAAO,aAAa,eAAe,OAAO;AAC1C,WAAS,KAAK,MAAM,WAAW;AACjC;AAEO,SAAS,YAAY,IAAkB;AAC5C,QAAM,SAAS,SAAS,cAA2B,uBAAuB,EAAE,IAAI;AAChF,MAAI,CAAC,OAAQ;AACb,SAAO,UAAU,OAAO,SAAS;AACjC,SAAO,aAAa,eAAe,MAAM;AACzC,WAAS,KAAK,MAAM,WAAW;AACjC;AAIA,SAAS,aAAa,WAAoB,MAAqB;AAC7D,QAAM,UAAU,UAAU,cAA2B,sBAAsB;AAC3E,QAAM,OAAO,UAAU,cAA2B,4BAA4B;AAC9E,MAAI,CAAC,WAAW,CAAC,KAAM;AAEvB,QAAM,gBAAgB,YAAY,SAAS,SAAS,CAAC,MAAM;AACzD,MAAE,gBAAgB;AAClB,mBAAe,SAAS;AAAA,EAC1B,CAAC;AACD,kBAAgB,MAAM,aAAa;AAGnC,QAAM,iBAAiB,YAAY,UAAU,SAAS,CAAC,MAAM;AAC3D,QAAI,CAAC,UAAU,SAAS,EAAE,MAAc,GAAG;AACzC,WAAK,UAAU,OAAO,SAAS;AAC/B,cAAQ,aAAa,iBAAiB,OAAO;AAAA,IAC/C;AAAA,EACF,CAAC;AACD,kBAAgB,MAAM,cAAc;AAGpC,QAAM,aAAa,YAAY,UAAU,WAAW,CAAC,MAAM;AACzD,QAAI,EAAE,QAAQ,YAAY,KAAK,UAAU,SAAS,SAAS,GAAG;AAC5D,WAAK,UAAU,OAAO,SAAS;AAC/B,cAAQ,aAAa,iBAAiB,OAAO;AAC7C,cAAQ,MAAM;AAAA,IAChB;AAAA,EACF,CAAC;AACD,kBAAgB,MAAM,UAAU;AAClC;AAEO,SAAS,eAAe,WAA0B;AACvD,QAAM,UAAU,UAAU,cAA2B,sBAAsB;AAC3E,QAAM,OAAO,UAAU,cAA2B,4BAA4B;AAC9E,MAAI,CAAC,KAAM;AACX,QAAM,SAAS,KAAK,UAAU,OAAO,SAAS;AAC9C,WAAS,aAAa,iBAAiB,OAAO,MAAM,CAAC;AACrD,MAAI,QAAQ;AAEV,SAAK,cAA2B,8BAA8B,GAAG,MAAM;AAAA,EACzE;AACF;AAIA,SAAS,SAAS,WAAoB,MAAqB;AACzD,QAAM,OAAO,UAAU,iBAA8B,kBAAkB;AACvE,OAAK,QAAQ,SAAO;AAClB,UAAM,UAAU,YAAY,KAAK,SAAS,MAAM;AAC9C,YAAM,UAAU,IAAI,aAAa,gBAAgB;AACjD,UAAI,CAAC,QAAS;AACd,kBAAY,WAAW,OAAO;AAAA,IAChC,CAAC;AACD,oBAAgB,MAAM,OAAO;AAG7B,UAAM,aAAa,YAAY,KAAK,WAAW,CAAC,MAAM;AACpD,YAAM,UAAU,CAAC,GAAG,UAAU,iBAA8B,kBAAkB,CAAC;AAC/E,YAAM,MAAM,QAAQ,QAAQ,GAAG;AAC/B,UAAI,EAAE,QAAQ,gBAAgB,EAAE,QAAQ,aAAa;AACnD,UAAE,eAAe;AACjB,iBAAS,MAAM,KAAK,QAAQ,MAAM,GAAG,MAAM;AAAA,MAC7C,WAAW,EAAE,QAAQ,eAAe,EAAE,QAAQ,WAAW;AACvD,UAAE,eAAe;AACjB,iBAAS,MAAM,IAAI,QAAQ,UAAU,QAAQ,MAAM,GAAG,MAAM;AAAA,MAC9D;AAAA,IACF,CAAC;AACD,oBAAgB,MAAM,UAAU;AAAA,EAClC,CAAC;AACH;AAEA,SAAS,YAAY,WAAoB,SAAuB;AAE9D,YAAU,iBAAiB,kBAAkB,EAAE,QAAQ,OAAK;AAC1D,MAAE,UAAU,OAAO,WAAW;AAC9B,MAAE,aAAa,iBAAiB,OAAO;AACvC,MAAE,aAAa,YAAY,IAAI;AAAA,EACjC,CAAC;AAGD,QAAM,aAAa,UAAU,QAAQ,0BAA0B,KAAK;AACpE,aAAW,iBAAiB,oBAAoB,EAAE,QAAQ,OAAK;AAC7D,MAAE,UAAU,OAAO,WAAW;AAC9B,MAAE,aAAa,eAAe,MAAM;AAAA,EACtC,CAAC;AAGD,QAAM,YAAY,UAAU,cAA2B,oBAAoB,OAAO,IAAI;AACtF,aAAW,UAAU,IAAI,WAAW;AACpC,aAAW,aAAa,iBAAiB,MAAM;AAC/C,aAAW,aAAa,YAAY,GAAG;AAGvC,QAAM,cAAc,WAAW,cAA2B,sBAAsB,OAAO,IAAI;AAC3F,eAAa,UAAU,IAAI,WAAW;AACtC,eAAa,aAAa,eAAe,OAAO;AAClD;AAIA,SAAS,WAAW,IAAa,MAAqB;AACpD,QAAM,MAAM,IAAI;AAAA,IACd,CAAC,YAAY;AACX,cAAQ,QAAQ,WAAS;AACvB,YAAI,MAAM,gBAAgB;AACxB,gBAAM,OAAO,UAAU,IAAI,YAAY;AACvC,cAAI,UAAU,MAAM,MAAM;AAAA,QAC5B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,EAAE,WAAW,KAAK,YAAY,oBAAoB;AAAA,EACpD;AACA,MAAI,QAAQ,EAAE;AACd,kBAAgB,MAAM,MAAM,IAAI,WAAW,CAAC;AAC9C;AAIA,SAAS,YAAY,WAA0B;AAC7C,QAAM,WAAW,CAAC,GAAG,UAAU,QAAQ;AACvC,WAAS,QAAQ,CAAC,OAAO,MAAM;AAC7B,UAAM,MAAM,YAAY,iBAAiB,OAAO,CAAC,CAAC;AAAA,EACpD,CAAC;AACH;AAIA,SAAS,SAAS,IAAa,MAAqB;AAClD,QAAM,SAAS;AACf,QAAM,WAAW;AAEjB,QAAM,cAAc,YAAY,QAAQ,aAAa,CAAC,MAAM;AAC1D,UAAM,OAAO,OAAO,sBAAsB;AAC1C,UAAM,KAAK,EAAE,UAAU,KAAK,QAAQ,KAAK,QAAQ;AACjD,UAAM,KAAK,EAAE,UAAU,KAAK,OAAO,KAAK,SAAS;AACjD,WAAO,MAAM,YAAY,8BAA8B,IAAI,QAAQ,gBAAgB,CAAC,IAAI,QAAQ;AAChG,WAAO,MAAM,aAAa;AAAA,EAC5B,CAAC;AAED,QAAM,eAAe,YAAY,QAAQ,cAAc,MAAM;AAC3D,WAAO,MAAM,YAAY;AACzB,WAAO,MAAM,aAAa;AAAA,EAC5B,CAAC;AAED,kBAAgB,MAAM,WAAW;AACjC,kBAAgB,MAAM,YAAY;AACpC;AAIA,SAAS,aAAa,IAAa,MAAqB;AACtD,QAAM,SAAS;AACf,QAAM,OAAO;AAEb,QAAM,cAAc,YAAY,QAAQ,aAAa,CAAC,MAAM;AAC1D,UAAM,OAAO,OAAO,sBAAsB;AAC1C,UAAM,KAAK,KAAK,OAAO,KAAK,QAAQ;AACpC,UAAM,KAAK,KAAK,MAAM,KAAK,SAAS;AACpC,UAAM,MAAM,EAAE,UAAU,MAAM;AAC9B,UAAM,MAAM,EAAE,UAAU,MAAM;AAC9B,WAAO,MAAM,YAAY,aAAa,EAAE,OAAO,EAAE;AACjD,WAAO,MAAM,aAAa;AAAA,EAC5B,CAAC;AAED,QAAM,eAAe,YAAY,QAAQ,cAAc,MAAM;AAC3D,WAAO,MAAM,YAAY;AACzB,WAAO,MAAM,aAAa;AAAA,EAC5B,CAAC;AAED,kBAAgB,MAAM,WAAW;AACjC,kBAAgB,MAAM,YAAY;AACpC;AAQA,SAAS,qBAAqB,OAA0B;AACtD,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,EAKF;AACA,WAAS,QAAQ,QAAM;AACrB,UAAM,QAAQ,GAAG,MAAM;AACvB,OAAG,MAAM,gBAAgB;AACzB,SAAK,GAAG;AACR,OAAG,MAAM,gBAAgB;AAAA,EAC3B,CAAC;AACH;AAmBA,SAAS,kBAAkB,WAAoB,MAAqB;AAClE,QAAM,SAAS,CAAC,GAAG,UAAU,iBAA8B,6BAA6B,CAAC;AACzF,MAAI,OAAO,WAAW,EAAG;AAEzB,QAAM,OAAO,UAAU,aAAa,iBAAiB;AACrD,MAAI,UAAU;AACd,MAAI,YAAkD;AAEtD,QAAM,cAAc;AACpB,MAAI,iBAAiB,WAAW,EAAE,aAAa,UAAU;AACvD,gBAAY,MAAM,WAAW;AAAA,EAC/B;AACA,cAAY,MAAM,WAAW;AAE7B,SAAO,QAAQ,OAAK;AAClB,MAAE,MAAM,WAAW;AACnB,MAAE,MAAM,QAAQ;AAChB,MAAE,UAAU,OAAO,WAAW;AAAA,EAChC,CAAC;AAED,WAAS,SAAS,OAAqB;AACrC,UAAM,QAAQ,OAAO,KAAK;AAC1B,yBAAqB,KAAK;AAC1B,UAAM,UAAU,IAAI,WAAW;AAC/B,UAAM,MAAM,SAAS;AAAA,EACvB;AAEA,WAAS,aAAa,WAAyB;AAC7C,UAAM,QAAQ,OAAO,SAAS;AAC9B,UAAM,WAAW,SAAS,MAAM,aAAa,qBAAqB,KAAK,QAAQ,EAAE;AAEjF,gBAAY,WAAW,MAAM;AAC3B,YAAM,YAAY,YAAY;AAC9B,YAAM,UAAU,aAAa,OAAO,SAAU,OAAO,IAAI,KAAM;AAC/D,UAAI,YAAY,GAAI;AACpB,mBAAa,WAAW,OAAO;AAAA,IACjC,GAAG,QAAQ;AAAA,EACb;AAEA,WAAS,aAAa,WAAmB,SAAuB;AAC9D,UAAM,WAAW,OAAO,SAAS;AACjC,UAAM,UAAU,OAAO,OAAO;AAC9B,UAAM,YAAY,SAAS,aAAa,uBAAuB,KAAK;AACpE,UAAM,WAAW,SAAS,SAAS,aAAa,2BAA2B,KAAK,OAAO,EAAE;AAEzF,UAAM,WAAW,oBAAoB,SAAS;AAC9C,UAAM,UAAU,oBAAoB,SAAS;AAG7C,aAAS,MAAM,YAAY,kBAAkB,GAAG,QAAQ,IAAI;AAC5D,YAAQ,MAAM,YAAY,kBAAkB,GAAG,QAAQ,IAAI;AAG3D,aAAS,MAAM,SAAS;AACxB,aAAS,UAAU,IAAI,QAAQ;AAG/B,YAAQ,MAAM,SAAS;AACvB,yBAAqB,OAAO;AAC5B,YAAQ,UAAU,IAAI,aAAa,OAAO;AAE1C,gBAAY,WAAW,MAAM;AAC3B,eAAS,UAAU,OAAO,aAAa,QAAQ;AAC/C,eAAS,MAAM,SAAS;AACxB,eAAS,MAAM,eAAe,gBAAgB;AAC9C,cAAQ,UAAU,OAAO,OAAO;AAChC,cAAQ,MAAM,eAAe,gBAAgB;AAC7C,gBAAU;AACV,mBAAa,OAAO;AAAA,IACtB,GAAG,QAAQ;AAAA,EACb;AAEA,WAAS,OAAO;AAChB,eAAa,OAAO;AAEpB,kBAAgB,MAAM,MAAM;AAC1B,QAAI,UAAW,cAAa,SAAS;AAAA,EACvC,CAAC;AACH;AAQO,SAAS,KAAK,OAAgB,SAAS,iBAAuB;AAEnE,OAAK,iBAAiB,wBAAwB,EAAE,QAAQ,QAAM,cAAc,IAAI,IAAI,CAAC;AAGrF,OAAK,iBAAiB,oBAAoB,EAAE,QAAQ,QAAM,UAAU,IAAI,IAAI,CAAC;AAG7E,OAAK,iBAAiB,qBAAqB,EAAE,QAAQ,QAAM,WAAW,IAAI,IAAI,CAAC;AAG/E,OAAK,iBAAiB,uBAAuB,EAAE,QAAQ,QAAM,aAAa,IAAI,IAAI,CAAC;AAGnF,OAAK,iBAAiB,mBAAmB,EAAE,QAAQ,QAAM,SAAS,IAAI,IAAI,CAAC;AAG3E,OAAK,iBAAiB,qBAAqB,EAAE,QAAQ,QAAM,WAAW,IAAI,IAAI,CAAC;AAG/E,OAAK,iBAAiB,sBAAsB,EAAE,QAAQ,QAAM,YAAY,EAAE,CAAC;AAG3E,OAAK,iBAAiB,mBAAmB,EAAE,QAAQ,QAAM,SAAS,IAAI,IAAI,CAAC;AAG3E,OAAK,iBAAiB,uBAAuB,EAAE,QAAQ,QAAM,aAAa,IAAI,IAAI,CAAC;AAGnF,OAAK,iBAAiB,uBAAuB,EAAE,QAAQ,QAAM,kBAAkB,IAAI,IAAI,CAAC;AAC1F;AAKO,SAAS,QAAQ,OAAgB,SAAS,iBAAuB;AACtE,QAAM,WAAW,gBAAgB,IAAI,IAAI,KAAK,CAAC;AAC/C,WAAS,QAAQ,QAAM,GAAG,CAAC;AAC3B,kBAAgB,OAAO,IAAI;AAC7B;","names":["cleanup"]}
|
package/dist/runtime.mjs
CHANGED
|
@@ -238,6 +238,79 @@ function wireMagnetic(el, root) {
|
|
|
238
238
|
registerCleanup(root, moveCleanup);
|
|
239
239
|
registerCleanup(root, leaveCleanup);
|
|
240
240
|
}
|
|
241
|
+
function resetSceneAnimations(scene) {
|
|
242
|
+
const animated = scene.querySelectorAll(
|
|
243
|
+
'[class*="alive-enter"], [class*="alive-loop"], .alive-typewriter, .alive-typewriter-fast, .alive-typewriter-slow, .alive-word-reveal > *, .alive-kinetic-slam, .alive-metric-card, .alive-toast, .alive-badge-pulse, .alive-spotlight, .alive-code-block'
|
|
244
|
+
);
|
|
245
|
+
animated.forEach((el) => {
|
|
246
|
+
const saved = el.style.animationName;
|
|
247
|
+
el.style.animationName = "none";
|
|
248
|
+
void el.offsetHeight;
|
|
249
|
+
el.style.animationName = saved;
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
function wireVideoSequence(container, root) {
|
|
253
|
+
const scenes = [...container.querySelectorAll(":scope > [data-alive-scene]")];
|
|
254
|
+
if (scenes.length === 0) return;
|
|
255
|
+
const loop = container.hasAttribute("data-alive-loop");
|
|
256
|
+
let current = 0;
|
|
257
|
+
let timeoutId = null;
|
|
258
|
+
const containerEl = container;
|
|
259
|
+
if (getComputedStyle(containerEl).position === "static") {
|
|
260
|
+
containerEl.style.position = "relative";
|
|
261
|
+
}
|
|
262
|
+
containerEl.style.overflow = "hidden";
|
|
263
|
+
scenes.forEach((s) => {
|
|
264
|
+
s.style.position = "absolute";
|
|
265
|
+
s.style.inset = "0";
|
|
266
|
+
s.classList.remove("is-active");
|
|
267
|
+
});
|
|
268
|
+
function activate(index) {
|
|
269
|
+
const scene = scenes[index];
|
|
270
|
+
resetSceneAnimations(scene);
|
|
271
|
+
scene.classList.add("is-active");
|
|
272
|
+
scene.style.zIndex = "1";
|
|
273
|
+
}
|
|
274
|
+
function scheduleNext(fromIndex) {
|
|
275
|
+
const scene = scenes[fromIndex];
|
|
276
|
+
const duration = parseInt(scene.getAttribute("data-alive-duration") ?? "3000", 10);
|
|
277
|
+
timeoutId = setTimeout(() => {
|
|
278
|
+
const nextIndex = fromIndex + 1;
|
|
279
|
+
const toIndex = nextIndex >= scenes.length ? loop ? 0 : -1 : nextIndex;
|
|
280
|
+
if (toIndex === -1) return;
|
|
281
|
+
doTransition(fromIndex, toIndex);
|
|
282
|
+
}, duration);
|
|
283
|
+
}
|
|
284
|
+
function doTransition(fromIndex, toIndex) {
|
|
285
|
+
const outScene = scenes[fromIndex];
|
|
286
|
+
const inScene = scenes[toIndex];
|
|
287
|
+
const transType = outScene.getAttribute("data-alive-transition") ?? "fade";
|
|
288
|
+
const transDur = parseInt(outScene.getAttribute("data-alive-trans-duration") ?? "600", 10);
|
|
289
|
+
const outClass = `alive-transition-${transType}-out`;
|
|
290
|
+
const inClass = `alive-transition-${transType}-in`;
|
|
291
|
+
outScene.style.setProperty("--alive-tr-dur", `${transDur}ms`);
|
|
292
|
+
inScene.style.setProperty("--alive-tr-dur", `${transDur}ms`);
|
|
293
|
+
outScene.style.zIndex = "2";
|
|
294
|
+
outScene.classList.add(outClass);
|
|
295
|
+
inScene.style.zIndex = "1";
|
|
296
|
+
resetSceneAnimations(inScene);
|
|
297
|
+
inScene.classList.add("is-active", inClass);
|
|
298
|
+
timeoutId = setTimeout(() => {
|
|
299
|
+
outScene.classList.remove("is-active", outClass);
|
|
300
|
+
outScene.style.zIndex = "";
|
|
301
|
+
outScene.style.removeProperty("--alive-tr-dur");
|
|
302
|
+
inScene.classList.remove(inClass);
|
|
303
|
+
inScene.style.removeProperty("--alive-tr-dur");
|
|
304
|
+
current = toIndex;
|
|
305
|
+
scheduleNext(current);
|
|
306
|
+
}, transDur);
|
|
307
|
+
}
|
|
308
|
+
activate(current);
|
|
309
|
+
scheduleNext(current);
|
|
310
|
+
registerCleanup(root, () => {
|
|
311
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
312
|
+
});
|
|
313
|
+
}
|
|
241
314
|
function init(root = document.documentElement) {
|
|
242
315
|
root.querySelectorAll("[data-alive-accordion]").forEach((el) => wireAccordion(el, root));
|
|
243
316
|
root.querySelectorAll("[data-alive-modal]").forEach((el) => wireModal(el, root));
|
|
@@ -248,6 +321,7 @@ function init(root = document.documentElement) {
|
|
|
248
321
|
root.querySelectorAll("[data-alive-stagger]").forEach((el) => wireStagger(el));
|
|
249
322
|
root.querySelectorAll("[data-alive-tilt]").forEach((el) => wireTilt(el, root));
|
|
250
323
|
root.querySelectorAll("[data-alive-magnetic]").forEach((el) => wireMagnetic(el, root));
|
|
324
|
+
root.querySelectorAll("[data-alive-sequence]").forEach((el) => wireVideoSequence(el, root));
|
|
251
325
|
}
|
|
252
326
|
function destroy(root = document.documentElement) {
|
|
253
327
|
const cleanups = cleanupRegistry.get(root) ?? [];
|
package/dist/runtime.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["/**\n * AliveUI Runtime\n *\n * Provides data-attribute-driven interactivity for accordion, modal, drawer,\n * dropdown, and tabs components — zero dependencies, ~2 KB.\n *\n * Usage:\n * import { init } from '@alivecss/aliveui/runtime'\n * init() // wire everything in document\n * init(myRootElement) // wire a subtree\n */\n\ntype Cleanup = () => void\n\nconst cleanupRegistry = new WeakMap<Element, Cleanup[]>()\n\nfunction registerCleanup(root: Element, fn: Cleanup): void {\n const existing = cleanupRegistry.get(root) ?? []\n existing.push(fn)\n cleanupRegistry.set(root, existing)\n}\n\nfunction addListener<K extends keyof HTMLElementEventMap>(\n el: EventTarget,\n type: K,\n handler: (e: HTMLElementEventMap[K]) => void,\n options?: AddEventListenerOptions,\n): Cleanup {\n el.addEventListener(type, handler as EventListener, options)\n return () => el.removeEventListener(type, handler as EventListener, options)\n}\n\n// ── Accordion ─────────────────────────────────────────────────────────────────\n\nfunction wireAccordion(container: Element, root: Element): void {\n const triggers = container.querySelectorAll<HTMLElement>('[data-alive-trigger]')\n triggers.forEach(trigger => {\n const item = trigger.closest('[data-alive-accordion-item]') ?? trigger.parentElement\n if (!item) return\n\n const cleanup = addListener(trigger, 'click', () => {\n const isOpen = item.classList.contains('is-open')\n // Close all items if not multi-open\n if (!container.hasAttribute('data-alive-multi')) {\n container.querySelectorAll('[data-alive-accordion-item]').forEach(i => {\n i.classList.remove('is-open')\n i.querySelector('[data-alive-trigger]')?.setAttribute('aria-expanded', 'false')\n })\n }\n if (!isOpen) {\n item.classList.add('is-open')\n trigger.setAttribute('aria-expanded', 'true')\n }\n })\n registerCleanup(root, cleanup)\n })\n}\n\n// ── Modal ─────────────────────────────────────────────────────────────────────\n\nfunction wireModal(modal: Element, root: Element): void {\n const id = modal.getAttribute('data-alive-modal')\n if (!id) return\n\n // Open triggers\n const openers = document.querySelectorAll<HTMLElement>(`[data-alive-open=\"${id}\"]`)\n openers.forEach(opener => {\n const cleanup = addListener(opener, 'click', () => openModal(id))\n registerCleanup(root, cleanup)\n })\n\n // Close triggers inside the modal\n modal.querySelectorAll<HTMLElement>('[data-alive-close]').forEach(closer => {\n const cleanup = addListener(closer, 'click', () => closeModal(id))\n registerCleanup(root, cleanup)\n })\n\n // Backdrop click to close (click on the modal wrapper, not the content)\n const cleanup = addListener(modal, 'click', (e) => {\n if (e.target === modal) closeModal(id)\n })\n registerCleanup(root, cleanup)\n\n // ESC key\n const escCleanup = addListener(document, 'keydown', (e) => {\n if (e.key === 'Escape' && modal.classList.contains('is-open')) closeModal(id)\n })\n registerCleanup(root, escCleanup)\n}\n\nexport function openModal(id: string): void {\n const modal = document.querySelector<HTMLElement>(`[data-alive-modal=\"${id}\"]`)\n if (!modal) return\n modal.classList.add('is-open')\n modal.setAttribute('aria-hidden', 'false')\n document.body.style.overflow = 'hidden'\n // Focus first focusable element\n const focusable = modal.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n )\n focusable?.focus()\n}\n\nexport function closeModal(id: string): void {\n const modal = document.querySelector<HTMLElement>(`[data-alive-modal=\"${id}\"]`)\n if (!modal) return\n modal.classList.remove('is-open')\n modal.setAttribute('aria-hidden', 'true')\n document.body.style.overflow = ''\n}\n\n// ── Drawer ────────────────────────────────────────────────────────────────────\n\nfunction wireDrawer(drawer: Element, root: Element): void {\n const id = drawer.getAttribute('data-alive-drawer')\n if (!id) return\n\n const openers = document.querySelectorAll<HTMLElement>(`[data-alive-open=\"${id}\"]`)\n openers.forEach(opener => {\n const cleanup = addListener(opener, 'click', () => openDrawer(id))\n registerCleanup(root, cleanup)\n })\n\n drawer.querySelectorAll<HTMLElement>('[data-alive-close]').forEach(closer => {\n const cleanup = addListener(closer, 'click', () => closeDrawer(id))\n registerCleanup(root, cleanup)\n })\n\n const backdropCleanup = addListener(drawer, 'click', (e) => {\n if (e.target === drawer) closeDrawer(id)\n })\n registerCleanup(root, backdropCleanup)\n\n const escCleanup = addListener(document, 'keydown', (e) => {\n if (e.key === 'Escape' && drawer.classList.contains('is-open')) closeDrawer(id)\n })\n registerCleanup(root, escCleanup)\n}\n\nexport function openDrawer(id: string): void {\n const drawer = document.querySelector<HTMLElement>(`[data-alive-drawer=\"${id}\"]`)\n if (!drawer) return\n drawer.classList.add('is-open')\n drawer.setAttribute('aria-hidden', 'false')\n document.body.style.overflow = 'hidden'\n}\n\nexport function closeDrawer(id: string): void {\n const drawer = document.querySelector<HTMLElement>(`[data-alive-drawer=\"${id}\"]`)\n if (!drawer) return\n drawer.classList.remove('is-open')\n drawer.setAttribute('aria-hidden', 'true')\n document.body.style.overflow = ''\n}\n\n// ── Dropdown ──────────────────────────────────────────────────────────────────\n\nfunction wireDropdown(container: Element, root: Element): void {\n const trigger = container.querySelector<HTMLElement>('[data-alive-trigger]')\n const menu = container.querySelector<HTMLElement>('[data-alive-dropdown-menu]')\n if (!trigger || !menu) return\n\n const toggleCleanup = addListener(trigger, 'click', (e) => {\n e.stopPropagation()\n toggleDropdown(container)\n })\n registerCleanup(root, toggleCleanup)\n\n // Close on outside click\n const outsideCleanup = addListener(document, 'click', (e) => {\n if (!container.contains(e.target as Node)) {\n menu.classList.remove('is-open')\n trigger.setAttribute('aria-expanded', 'false')\n }\n })\n registerCleanup(root, outsideCleanup)\n\n // Close on ESC\n const escCleanup = addListener(document, 'keydown', (e) => {\n if (e.key === 'Escape' && menu.classList.contains('is-open')) {\n menu.classList.remove('is-open')\n trigger.setAttribute('aria-expanded', 'false')\n trigger.focus()\n }\n })\n registerCleanup(root, escCleanup)\n}\n\nexport function toggleDropdown(container: Element): void {\n const trigger = container.querySelector<HTMLElement>('[data-alive-trigger]')\n const menu = container.querySelector<HTMLElement>('[data-alive-dropdown-menu]')\n if (!menu) return\n const isOpen = menu.classList.toggle('is-open')\n trigger?.setAttribute('aria-expanded', String(isOpen))\n if (isOpen) {\n // Focus first item\n menu.querySelector<HTMLElement>('[role=\"menuitem\"], button, a')?.focus()\n }\n}\n\n// ── Tabs ──────────────────────────────────────────────────────────────────────\n\nfunction wireTabs(container: Element, root: Element): void {\n const tabs = container.querySelectorAll<HTMLElement>('[data-alive-tab]')\n tabs.forEach(tab => {\n const cleanup = addListener(tab, 'click', () => {\n const panelId = tab.getAttribute('data-alive-tab')\n if (!panelId) return\n activateTab(container, panelId)\n })\n registerCleanup(root, cleanup)\n\n // Keyboard navigation\n const keyCleanup = addListener(tab, 'keydown', (e) => {\n const allTabs = [...container.querySelectorAll<HTMLElement>('[data-alive-tab]')]\n const idx = allTabs.indexOf(tab)\n if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {\n e.preventDefault()\n allTabs[(idx + 1) % allTabs.length]?.focus()\n } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {\n e.preventDefault()\n allTabs[(idx - 1 + allTabs.length) % allTabs.length]?.focus()\n }\n })\n registerCleanup(root, keyCleanup)\n })\n}\n\nfunction activateTab(container: Element, panelId: string): void {\n // Deactivate all tabs + panels within this tabs container\n container.querySelectorAll('[data-alive-tab]').forEach(t => {\n t.classList.remove('is-active')\n t.setAttribute('aria-selected', 'false')\n t.setAttribute('tabindex', '-1')\n })\n\n // Find panels — look in the container, then in the whole document\n const searchRoot = container.closest('[data-alive-tabs-panels]') ?? document\n searchRoot.querySelectorAll('[data-alive-panel]').forEach(p => {\n p.classList.remove('is-active')\n p.setAttribute('aria-hidden', 'true')\n })\n\n // Activate the selected tab\n const activeTab = container.querySelector<HTMLElement>(`[data-alive-tab=\"${panelId}\"]`)\n activeTab?.classList.add('is-active')\n activeTab?.setAttribute('aria-selected', 'true')\n activeTab?.setAttribute('tabindex', '0')\n\n // Activate the matching panel\n const activePanel = searchRoot.querySelector<HTMLElement>(`[data-alive-panel=\"${panelId}\"]`)\n activePanel?.classList.add('is-active')\n activePanel?.setAttribute('aria-hidden', 'false')\n}\n\n// ── Scroll Reveal ──────────────────────────────────────────────────────────────\n\nfunction wireScroll(el: Element, root: Element): void {\n const obs = new IntersectionObserver(\n (entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n entry.target.classList.add('is-visible')\n obs.unobserve(entry.target)\n }\n })\n },\n { threshold: 0.1, rootMargin: '0px 0px -40px 0px' },\n )\n obs.observe(el)\n registerCleanup(root, () => obs.disconnect())\n}\n\n// ── Auto-Stagger ───────────────────────────────────────────────────────────────\n\nfunction wireStagger(container: Element): void {\n const children = [...container.children] as HTMLElement[]\n children.forEach((child, i) => {\n child.style.setProperty('--alive-index', String(i))\n })\n}\n\n// ── 3D Tilt ────────────────────────────────────────────────────────────────────\n\nfunction wireTilt(el: Element, root: Element): void {\n const htmlEl = el as HTMLElement\n const STRENGTH = 8\n\n const moveCleanup = addListener(htmlEl, 'mousemove', (e) => {\n const rect = htmlEl.getBoundingClientRect()\n const x = (e.clientX - rect.left) / rect.width - 0.5\n const y = (e.clientY - rect.top) / rect.height - 0.5\n htmlEl.style.transform = `perspective(800px) rotateY(${x * STRENGTH}deg) rotateX(${-y * STRENGTH}deg) scale(1.01)`\n htmlEl.style.transition = 'transform 0.1s ease-out'\n })\n\n const leaveCleanup = addListener(htmlEl, 'mouseleave', () => {\n htmlEl.style.transform = ''\n htmlEl.style.transition = 'transform 0.4s cubic-bezier(0.16, 1, 0.3, 1)'\n })\n\n registerCleanup(root, moveCleanup)\n registerCleanup(root, leaveCleanup)\n}\n\n// ── Magnetic Follow ────────────────────────────────────────────────────────────\n\nfunction wireMagnetic(el: Element, root: Element): void {\n const htmlEl = el as HTMLElement\n const PULL = 0.35\n\n const moveCleanup = addListener(htmlEl, 'mousemove', (e) => {\n const rect = htmlEl.getBoundingClientRect()\n const cx = rect.left + rect.width / 2\n const cy = rect.top + rect.height / 2\n const dx = (e.clientX - cx) * PULL\n const dy = (e.clientY - cy) * PULL\n htmlEl.style.transform = `translate(${dx}px, ${dy}px)`\n htmlEl.style.transition = 'transform 0.2s cubic-bezier(0.16, 1, 0.3, 1)'\n })\n\n const leaveCleanup = addListener(htmlEl, 'mouseleave', () => {\n htmlEl.style.transform = ''\n htmlEl.style.transition = 'transform 0.5s cubic-bezier(0.16, 1, 0.3, 1)'\n })\n\n registerCleanup(root, moveCleanup)\n registerCleanup(root, leaveCleanup)\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Wire all data-alive-* components within `root` (defaults to document.documentElement).\n * Safe to call multiple times — existing listeners are tracked and replaced on `destroy()`.\n */\nexport function init(root: Element = document.documentElement): void {\n // Accordion\n root.querySelectorAll('[data-alive-accordion]').forEach(el => wireAccordion(el, root))\n\n // Modal\n root.querySelectorAll('[data-alive-modal]').forEach(el => wireModal(el, root))\n\n // Drawer\n root.querySelectorAll('[data-alive-drawer]').forEach(el => wireDrawer(el, root))\n\n // Dropdown\n root.querySelectorAll('[data-alive-dropdown]').forEach(el => wireDropdown(el, root))\n\n // Tabs\n root.querySelectorAll('[data-alive-tabs]').forEach(el => wireTabs(el, root))\n\n // Scroll reveal\n root.querySelectorAll('[data-alive-scroll]').forEach(el => wireScroll(el, root))\n\n // Auto-stagger children\n root.querySelectorAll('[data-alive-stagger]').forEach(el => wireStagger(el))\n\n // 3D tilt\n root.querySelectorAll('[data-alive-tilt]').forEach(el => wireTilt(el, root))\n\n // Magnetic follow\n root.querySelectorAll('[data-alive-magnetic]').forEach(el => wireMagnetic(el, root))\n}\n\n/**\n * Remove all event listeners registered by `init(root)`.\n */\nexport function destroy(root: Element = document.documentElement): void {\n const cleanups = cleanupRegistry.get(root) ?? []\n cleanups.forEach(fn => fn())\n cleanupRegistry.delete(root)\n}\n"],"mappings":"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","names":["cleanup"]}
|
|
1
|
+
{"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["/**\n * AliveUI Runtime\n *\n * Provides data-attribute-driven interactivity for accordion, modal, drawer,\n * dropdown, and tabs components — zero dependencies, ~2 KB.\n *\n * Usage:\n * import { init } from '@alivecss/aliveui/runtime'\n * init() // wire everything in document\n * init(myRootElement) // wire a subtree\n */\n\ntype Cleanup = () => void\n\nconst cleanupRegistry = new WeakMap<Element, Cleanup[]>()\n\nfunction registerCleanup(root: Element, fn: Cleanup): void {\n const existing = cleanupRegistry.get(root) ?? []\n existing.push(fn)\n cleanupRegistry.set(root, existing)\n}\n\nfunction addListener<K extends keyof HTMLElementEventMap>(\n el: EventTarget,\n type: K,\n handler: (e: HTMLElementEventMap[K]) => void,\n options?: AddEventListenerOptions,\n): Cleanup {\n el.addEventListener(type, handler as EventListener, options)\n return () => el.removeEventListener(type, handler as EventListener, options)\n}\n\n// ── Accordion ─────────────────────────────────────────────────────────────────\n\nfunction wireAccordion(container: Element, root: Element): void {\n const triggers = container.querySelectorAll<HTMLElement>('[data-alive-trigger]')\n triggers.forEach(trigger => {\n const item = trigger.closest('[data-alive-accordion-item]') ?? trigger.parentElement\n if (!item) return\n\n const cleanup = addListener(trigger, 'click', () => {\n const isOpen = item.classList.contains('is-open')\n // Close all items if not multi-open\n if (!container.hasAttribute('data-alive-multi')) {\n container.querySelectorAll('[data-alive-accordion-item]').forEach(i => {\n i.classList.remove('is-open')\n i.querySelector('[data-alive-trigger]')?.setAttribute('aria-expanded', 'false')\n })\n }\n if (!isOpen) {\n item.classList.add('is-open')\n trigger.setAttribute('aria-expanded', 'true')\n }\n })\n registerCleanup(root, cleanup)\n })\n}\n\n// ── Modal ─────────────────────────────────────────────────────────────────────\n\nfunction wireModal(modal: Element, root: Element): void {\n const id = modal.getAttribute('data-alive-modal')\n if (!id) return\n\n // Open triggers\n const openers = document.querySelectorAll<HTMLElement>(`[data-alive-open=\"${id}\"]`)\n openers.forEach(opener => {\n const cleanup = addListener(opener, 'click', () => openModal(id))\n registerCleanup(root, cleanup)\n })\n\n // Close triggers inside the modal\n modal.querySelectorAll<HTMLElement>('[data-alive-close]').forEach(closer => {\n const cleanup = addListener(closer, 'click', () => closeModal(id))\n registerCleanup(root, cleanup)\n })\n\n // Backdrop click to close (click on the modal wrapper, not the content)\n const cleanup = addListener(modal, 'click', (e) => {\n if (e.target === modal) closeModal(id)\n })\n registerCleanup(root, cleanup)\n\n // ESC key\n const escCleanup = addListener(document, 'keydown', (e) => {\n if (e.key === 'Escape' && modal.classList.contains('is-open')) closeModal(id)\n })\n registerCleanup(root, escCleanup)\n}\n\nexport function openModal(id: string): void {\n const modal = document.querySelector<HTMLElement>(`[data-alive-modal=\"${id}\"]`)\n if (!modal) return\n modal.classList.add('is-open')\n modal.setAttribute('aria-hidden', 'false')\n document.body.style.overflow = 'hidden'\n // Focus first focusable element\n const focusable = modal.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n )\n focusable?.focus()\n}\n\nexport function closeModal(id: string): void {\n const modal = document.querySelector<HTMLElement>(`[data-alive-modal=\"${id}\"]`)\n if (!modal) return\n modal.classList.remove('is-open')\n modal.setAttribute('aria-hidden', 'true')\n document.body.style.overflow = ''\n}\n\n// ── Drawer ────────────────────────────────────────────────────────────────────\n\nfunction wireDrawer(drawer: Element, root: Element): void {\n const id = drawer.getAttribute('data-alive-drawer')\n if (!id) return\n\n const openers = document.querySelectorAll<HTMLElement>(`[data-alive-open=\"${id}\"]`)\n openers.forEach(opener => {\n const cleanup = addListener(opener, 'click', () => openDrawer(id))\n registerCleanup(root, cleanup)\n })\n\n drawer.querySelectorAll<HTMLElement>('[data-alive-close]').forEach(closer => {\n const cleanup = addListener(closer, 'click', () => closeDrawer(id))\n registerCleanup(root, cleanup)\n })\n\n const backdropCleanup = addListener(drawer, 'click', (e) => {\n if (e.target === drawer) closeDrawer(id)\n })\n registerCleanup(root, backdropCleanup)\n\n const escCleanup = addListener(document, 'keydown', (e) => {\n if (e.key === 'Escape' && drawer.classList.contains('is-open')) closeDrawer(id)\n })\n registerCleanup(root, escCleanup)\n}\n\nexport function openDrawer(id: string): void {\n const drawer = document.querySelector<HTMLElement>(`[data-alive-drawer=\"${id}\"]`)\n if (!drawer) return\n drawer.classList.add('is-open')\n drawer.setAttribute('aria-hidden', 'false')\n document.body.style.overflow = 'hidden'\n}\n\nexport function closeDrawer(id: string): void {\n const drawer = document.querySelector<HTMLElement>(`[data-alive-drawer=\"${id}\"]`)\n if (!drawer) return\n drawer.classList.remove('is-open')\n drawer.setAttribute('aria-hidden', 'true')\n document.body.style.overflow = ''\n}\n\n// ── Dropdown ──────────────────────────────────────────────────────────────────\n\nfunction wireDropdown(container: Element, root: Element): void {\n const trigger = container.querySelector<HTMLElement>('[data-alive-trigger]')\n const menu = container.querySelector<HTMLElement>('[data-alive-dropdown-menu]')\n if (!trigger || !menu) return\n\n const toggleCleanup = addListener(trigger, 'click', (e) => {\n e.stopPropagation()\n toggleDropdown(container)\n })\n registerCleanup(root, toggleCleanup)\n\n // Close on outside click\n const outsideCleanup = addListener(document, 'click', (e) => {\n if (!container.contains(e.target as Node)) {\n menu.classList.remove('is-open')\n trigger.setAttribute('aria-expanded', 'false')\n }\n })\n registerCleanup(root, outsideCleanup)\n\n // Close on ESC\n const escCleanup = addListener(document, 'keydown', (e) => {\n if (e.key === 'Escape' && menu.classList.contains('is-open')) {\n menu.classList.remove('is-open')\n trigger.setAttribute('aria-expanded', 'false')\n trigger.focus()\n }\n })\n registerCleanup(root, escCleanup)\n}\n\nexport function toggleDropdown(container: Element): void {\n const trigger = container.querySelector<HTMLElement>('[data-alive-trigger]')\n const menu = container.querySelector<HTMLElement>('[data-alive-dropdown-menu]')\n if (!menu) return\n const isOpen = menu.classList.toggle('is-open')\n trigger?.setAttribute('aria-expanded', String(isOpen))\n if (isOpen) {\n // Focus first item\n menu.querySelector<HTMLElement>('[role=\"menuitem\"], button, a')?.focus()\n }\n}\n\n// ── Tabs ──────────────────────────────────────────────────────────────────────\n\nfunction wireTabs(container: Element, root: Element): void {\n const tabs = container.querySelectorAll<HTMLElement>('[data-alive-tab]')\n tabs.forEach(tab => {\n const cleanup = addListener(tab, 'click', () => {\n const panelId = tab.getAttribute('data-alive-tab')\n if (!panelId) return\n activateTab(container, panelId)\n })\n registerCleanup(root, cleanup)\n\n // Keyboard navigation\n const keyCleanup = addListener(tab, 'keydown', (e) => {\n const allTabs = [...container.querySelectorAll<HTMLElement>('[data-alive-tab]')]\n const idx = allTabs.indexOf(tab)\n if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {\n e.preventDefault()\n allTabs[(idx + 1) % allTabs.length]?.focus()\n } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {\n e.preventDefault()\n allTabs[(idx - 1 + allTabs.length) % allTabs.length]?.focus()\n }\n })\n registerCleanup(root, keyCleanup)\n })\n}\n\nfunction activateTab(container: Element, panelId: string): void {\n // Deactivate all tabs + panels within this tabs container\n container.querySelectorAll('[data-alive-tab]').forEach(t => {\n t.classList.remove('is-active')\n t.setAttribute('aria-selected', 'false')\n t.setAttribute('tabindex', '-1')\n })\n\n // Find panels — look in the container, then in the whole document\n const searchRoot = container.closest('[data-alive-tabs-panels]') ?? document\n searchRoot.querySelectorAll('[data-alive-panel]').forEach(p => {\n p.classList.remove('is-active')\n p.setAttribute('aria-hidden', 'true')\n })\n\n // Activate the selected tab\n const activeTab = container.querySelector<HTMLElement>(`[data-alive-tab=\"${panelId}\"]`)\n activeTab?.classList.add('is-active')\n activeTab?.setAttribute('aria-selected', 'true')\n activeTab?.setAttribute('tabindex', '0')\n\n // Activate the matching panel\n const activePanel = searchRoot.querySelector<HTMLElement>(`[data-alive-panel=\"${panelId}\"]`)\n activePanel?.classList.add('is-active')\n activePanel?.setAttribute('aria-hidden', 'false')\n}\n\n// ── Scroll Reveal ──────────────────────────────────────────────────────────────\n\nfunction wireScroll(el: Element, root: Element): void {\n const obs = new IntersectionObserver(\n (entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n entry.target.classList.add('is-visible')\n obs.unobserve(entry.target)\n }\n })\n },\n { threshold: 0.1, rootMargin: '0px 0px -40px 0px' },\n )\n obs.observe(el)\n registerCleanup(root, () => obs.disconnect())\n}\n\n// ── Auto-Stagger ───────────────────────────────────────────────────────────────\n\nfunction wireStagger(container: Element): void {\n const children = [...container.children] as HTMLElement[]\n children.forEach((child, i) => {\n child.style.setProperty('--alive-index', String(i))\n })\n}\n\n// ── 3D Tilt ────────────────────────────────────────────────────────────────────\n\nfunction wireTilt(el: Element, root: Element): void {\n const htmlEl = el as HTMLElement\n const STRENGTH = 8\n\n const moveCleanup = addListener(htmlEl, 'mousemove', (e) => {\n const rect = htmlEl.getBoundingClientRect()\n const x = (e.clientX - rect.left) / rect.width - 0.5\n const y = (e.clientY - rect.top) / rect.height - 0.5\n htmlEl.style.transform = `perspective(800px) rotateY(${x * STRENGTH}deg) rotateX(${-y * STRENGTH}deg) scale(1.01)`\n htmlEl.style.transition = 'transform 0.1s ease-out'\n })\n\n const leaveCleanup = addListener(htmlEl, 'mouseleave', () => {\n htmlEl.style.transform = ''\n htmlEl.style.transition = 'transform 0.4s cubic-bezier(0.16, 1, 0.3, 1)'\n })\n\n registerCleanup(root, moveCleanup)\n registerCleanup(root, leaveCleanup)\n}\n\n// ── Magnetic Follow ────────────────────────────────────────────────────────────\n\nfunction wireMagnetic(el: Element, root: Element): void {\n const htmlEl = el as HTMLElement\n const PULL = 0.35\n\n const moveCleanup = addListener(htmlEl, 'mousemove', (e) => {\n const rect = htmlEl.getBoundingClientRect()\n const cx = rect.left + rect.width / 2\n const cy = rect.top + rect.height / 2\n const dx = (e.clientX - cx) * PULL\n const dy = (e.clientY - cy) * PULL\n htmlEl.style.transform = `translate(${dx}px, ${dy}px)`\n htmlEl.style.transition = 'transform 0.2s cubic-bezier(0.16, 1, 0.3, 1)'\n })\n\n const leaveCleanup = addListener(htmlEl, 'mouseleave', () => {\n htmlEl.style.transform = ''\n htmlEl.style.transition = 'transform 0.5s cubic-bezier(0.16, 1, 0.3, 1)'\n })\n\n registerCleanup(root, moveCleanup)\n registerCleanup(root, leaveCleanup)\n}\n\n// ── Video Scene Sequencer ──────────────────────────────────────────────────────\n\n/**\n * Force-restart CSS animations on all animated children of a scene element.\n * This ensures stagger delays are relative to scene activation, not page load.\n */\nfunction resetSceneAnimations(scene: HTMLElement): void {\n const animated = scene.querySelectorAll<HTMLElement>(\n '[class*=\"alive-enter\"], [class*=\"alive-loop\"], ' +\n '.alive-typewriter, .alive-typewriter-fast, .alive-typewriter-slow, ' +\n '.alive-word-reveal > *, .alive-kinetic-slam, ' +\n '.alive-metric-card, .alive-toast, .alive-badge-pulse, ' +\n '.alive-spotlight, .alive-code-block',\n )\n animated.forEach(el => {\n const saved = el.style.animationName\n el.style.animationName = 'none'\n void el.offsetHeight // force reflow — restarts animation from t=0\n el.style.animationName = saved\n })\n}\n\n/**\n * Wire a [data-alive-sequence] container.\n *\n * Markup:\n * <div data-alive-sequence data-alive-loop style=\"position:relative; width:800px; height:500px;\">\n * <div data-alive-scene data-alive-duration=\"3000\" data-alive-transition=\"wipe-left\">…</div>\n * <div data-alive-scene data-alive-duration=\"2500\" data-alive-transition=\"fade\">…</div>\n * </div>\n *\n * Scene attributes:\n * data-alive-duration — how long to show the scene (ms, default 3000)\n * data-alive-transition — transition type (default \"fade\"; matches alive-transition-* classes)\n * data-alive-trans-duration — transition animation duration (ms, default 600)\n *\n * Sequence attributes:\n * data-alive-loop — loop back to the first scene after the last\n */\nfunction wireVideoSequence(container: Element, root: Element): void {\n const scenes = [...container.querySelectorAll<HTMLElement>(':scope > [data-alive-scene]')]\n if (scenes.length === 0) return\n\n const loop = container.hasAttribute('data-alive-loop')\n let current = 0\n let timeoutId: ReturnType<typeof setTimeout> | null = null\n\n const containerEl = container as HTMLElement\n if (getComputedStyle(containerEl).position === 'static') {\n containerEl.style.position = 'relative'\n }\n containerEl.style.overflow = 'hidden'\n\n scenes.forEach(s => {\n s.style.position = 'absolute'\n s.style.inset = '0'\n s.classList.remove('is-active')\n })\n\n function activate(index: number): void {\n const scene = scenes[index]\n resetSceneAnimations(scene)\n scene.classList.add('is-active')\n scene.style.zIndex = '1'\n }\n\n function scheduleNext(fromIndex: number): void {\n const scene = scenes[fromIndex]\n const duration = parseInt(scene.getAttribute('data-alive-duration') ?? '3000', 10)\n\n timeoutId = setTimeout(() => {\n const nextIndex = fromIndex + 1\n const toIndex = nextIndex >= scenes.length ? (loop ? 0 : -1) : nextIndex\n if (toIndex === -1) return\n doTransition(fromIndex, toIndex)\n }, duration)\n }\n\n function doTransition(fromIndex: number, toIndex: number): void {\n const outScene = scenes[fromIndex]\n const inScene = scenes[toIndex]\n const transType = outScene.getAttribute('data-alive-transition') ?? 'fade'\n const transDur = parseInt(outScene.getAttribute('data-alive-trans-duration') ?? '600', 10)\n\n const outClass = `alive-transition-${transType}-out`\n const inClass = `alive-transition-${transType}-in`\n\n // Sync CSS animation duration with the JS timer\n outScene.style.setProperty('--alive-tr-dur', `${transDur}ms`)\n inScene.style.setProperty('--alive-tr-dur', `${transDur}ms`)\n\n // Outgoing goes on top (required for wipe/clip-path transitions)\n outScene.style.zIndex = '2'\n outScene.classList.add(outClass)\n\n // Activate incoming beneath, reset its child animations\n inScene.style.zIndex = '1'\n resetSceneAnimations(inScene)\n inScene.classList.add('is-active', inClass)\n\n timeoutId = setTimeout(() => {\n outScene.classList.remove('is-active', outClass)\n outScene.style.zIndex = ''\n outScene.style.removeProperty('--alive-tr-dur')\n inScene.classList.remove(inClass)\n inScene.style.removeProperty('--alive-tr-dur')\n current = toIndex\n scheduleNext(current)\n }, transDur)\n }\n\n activate(current)\n scheduleNext(current)\n\n registerCleanup(root, () => {\n if (timeoutId) clearTimeout(timeoutId)\n })\n}\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Wire all data-alive-* components within `root` (defaults to document.documentElement).\n * Safe to call multiple times — existing listeners are tracked and replaced on `destroy()`.\n */\nexport function init(root: Element = document.documentElement): void {\n // Accordion\n root.querySelectorAll('[data-alive-accordion]').forEach(el => wireAccordion(el, root))\n\n // Modal\n root.querySelectorAll('[data-alive-modal]').forEach(el => wireModal(el, root))\n\n // Drawer\n root.querySelectorAll('[data-alive-drawer]').forEach(el => wireDrawer(el, root))\n\n // Dropdown\n root.querySelectorAll('[data-alive-dropdown]').forEach(el => wireDropdown(el, root))\n\n // Tabs\n root.querySelectorAll('[data-alive-tabs]').forEach(el => wireTabs(el, root))\n\n // Scroll reveal\n root.querySelectorAll('[data-alive-scroll]').forEach(el => wireScroll(el, root))\n\n // Auto-stagger children\n root.querySelectorAll('[data-alive-stagger]').forEach(el => wireStagger(el))\n\n // 3D tilt\n root.querySelectorAll('[data-alive-tilt]').forEach(el => wireTilt(el, root))\n\n // Magnetic follow\n root.querySelectorAll('[data-alive-magnetic]').forEach(el => wireMagnetic(el, root))\n\n // Video scene sequencer\n root.querySelectorAll('[data-alive-sequence]').forEach(el => wireVideoSequence(el, root))\n}\n\n/**\n * Remove all event listeners registered by `init(root)`.\n */\nexport function destroy(root: Element = document.documentElement): void {\n const cleanups = cleanupRegistry.get(root) ?? []\n cleanups.forEach(fn => fn())\n cleanupRegistry.delete(root)\n}\n"],"mappings":"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","names":["cleanup"]}
|