@alivecss/aliveui 1.0.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 +317 -0
- package/dist/cli.js +3811 -0
- package/dist/index.d.mts +42 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +3757 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3717 -0
- package/dist/index.mjs.map +1 -0
- package/dist/runtime.d.mts +27 -0
- package/dist/runtime.d.ts +27 -0
- package/dist/runtime.js +236 -0
- package/dist/runtime.js.map +1 -0
- package/dist/runtime.mjs +205 -0
- package/dist/runtime.mjs.map +1 -0
- package/dist/vite.d.mts +43 -0
- package/dist/vite.d.ts +43 -0
- package/dist/vite.js +3872 -0
- package/dist/vite.js.map +1 -0
- package/dist/vite.mjs +3855 -0
- package/dist/vite.mjs.map +1 -0
- package/package.json +67 -0
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/runtime.ts
|
|
21
|
+
var runtime_exports = {};
|
|
22
|
+
__export(runtime_exports, {
|
|
23
|
+
closeDrawer: () => closeDrawer,
|
|
24
|
+
closeModal: () => closeModal,
|
|
25
|
+
destroy: () => destroy,
|
|
26
|
+
init: () => init,
|
|
27
|
+
openDrawer: () => openDrawer,
|
|
28
|
+
openModal: () => openModal,
|
|
29
|
+
toggleDropdown: () => toggleDropdown
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(runtime_exports);
|
|
32
|
+
var cleanupRegistry = /* @__PURE__ */ new WeakMap();
|
|
33
|
+
function registerCleanup(root, fn) {
|
|
34
|
+
const existing = cleanupRegistry.get(root) ?? [];
|
|
35
|
+
existing.push(fn);
|
|
36
|
+
cleanupRegistry.set(root, existing);
|
|
37
|
+
}
|
|
38
|
+
function addListener(el, type, handler, options) {
|
|
39
|
+
el.addEventListener(type, handler, options);
|
|
40
|
+
return () => el.removeEventListener(type, handler, options);
|
|
41
|
+
}
|
|
42
|
+
function wireAccordion(container, root) {
|
|
43
|
+
const triggers = container.querySelectorAll("[data-alive-trigger]");
|
|
44
|
+
triggers.forEach((trigger) => {
|
|
45
|
+
const item = trigger.closest("[data-alive-accordion-item]") ?? trigger.parentElement;
|
|
46
|
+
if (!item) return;
|
|
47
|
+
const cleanup = addListener(trigger, "click", () => {
|
|
48
|
+
const isOpen = item.classList.contains("is-open");
|
|
49
|
+
if (!container.hasAttribute("data-alive-multi")) {
|
|
50
|
+
container.querySelectorAll("[data-alive-accordion-item]").forEach((i) => {
|
|
51
|
+
i.classList.remove("is-open");
|
|
52
|
+
i.querySelector("[data-alive-trigger]")?.setAttribute("aria-expanded", "false");
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (!isOpen) {
|
|
56
|
+
item.classList.add("is-open");
|
|
57
|
+
trigger.setAttribute("aria-expanded", "true");
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
registerCleanup(root, cleanup);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
function wireModal(modal, root) {
|
|
64
|
+
const id = modal.getAttribute("data-alive-modal");
|
|
65
|
+
if (!id) return;
|
|
66
|
+
const openers = document.querySelectorAll(`[data-alive-open="${id}"]`);
|
|
67
|
+
openers.forEach((opener) => {
|
|
68
|
+
const cleanup2 = addListener(opener, "click", () => openModal(id));
|
|
69
|
+
registerCleanup(root, cleanup2);
|
|
70
|
+
});
|
|
71
|
+
modal.querySelectorAll("[data-alive-close]").forEach((closer) => {
|
|
72
|
+
const cleanup2 = addListener(closer, "click", () => closeModal(id));
|
|
73
|
+
registerCleanup(root, cleanup2);
|
|
74
|
+
});
|
|
75
|
+
const cleanup = addListener(modal, "click", (e) => {
|
|
76
|
+
if (e.target === modal) closeModal(id);
|
|
77
|
+
});
|
|
78
|
+
registerCleanup(root, cleanup);
|
|
79
|
+
const escCleanup = addListener(document, "keydown", (e) => {
|
|
80
|
+
if (e.key === "Escape" && modal.classList.contains("is-open")) closeModal(id);
|
|
81
|
+
});
|
|
82
|
+
registerCleanup(root, escCleanup);
|
|
83
|
+
}
|
|
84
|
+
function openModal(id) {
|
|
85
|
+
const modal = document.querySelector(`[data-alive-modal="${id}"]`);
|
|
86
|
+
if (!modal) return;
|
|
87
|
+
modal.classList.add("is-open");
|
|
88
|
+
modal.setAttribute("aria-hidden", "false");
|
|
89
|
+
document.body.style.overflow = "hidden";
|
|
90
|
+
const focusable = modal.querySelector(
|
|
91
|
+
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
92
|
+
);
|
|
93
|
+
focusable?.focus();
|
|
94
|
+
}
|
|
95
|
+
function closeModal(id) {
|
|
96
|
+
const modal = document.querySelector(`[data-alive-modal="${id}"]`);
|
|
97
|
+
if (!modal) return;
|
|
98
|
+
modal.classList.remove("is-open");
|
|
99
|
+
modal.setAttribute("aria-hidden", "true");
|
|
100
|
+
document.body.style.overflow = "";
|
|
101
|
+
}
|
|
102
|
+
function wireDrawer(drawer, root) {
|
|
103
|
+
const id = drawer.getAttribute("data-alive-drawer");
|
|
104
|
+
if (!id) return;
|
|
105
|
+
const openers = document.querySelectorAll(`[data-alive-open="${id}"]`);
|
|
106
|
+
openers.forEach((opener) => {
|
|
107
|
+
const cleanup = addListener(opener, "click", () => openDrawer(id));
|
|
108
|
+
registerCleanup(root, cleanup);
|
|
109
|
+
});
|
|
110
|
+
drawer.querySelectorAll("[data-alive-close]").forEach((closer) => {
|
|
111
|
+
const cleanup = addListener(closer, "click", () => closeDrawer(id));
|
|
112
|
+
registerCleanup(root, cleanup);
|
|
113
|
+
});
|
|
114
|
+
const backdropCleanup = addListener(drawer, "click", (e) => {
|
|
115
|
+
if (e.target === drawer) closeDrawer(id);
|
|
116
|
+
});
|
|
117
|
+
registerCleanup(root, backdropCleanup);
|
|
118
|
+
const escCleanup = addListener(document, "keydown", (e) => {
|
|
119
|
+
if (e.key === "Escape" && drawer.classList.contains("is-open")) closeDrawer(id);
|
|
120
|
+
});
|
|
121
|
+
registerCleanup(root, escCleanup);
|
|
122
|
+
}
|
|
123
|
+
function openDrawer(id) {
|
|
124
|
+
const drawer = document.querySelector(`[data-alive-drawer="${id}"]`);
|
|
125
|
+
if (!drawer) return;
|
|
126
|
+
drawer.classList.add("is-open");
|
|
127
|
+
drawer.setAttribute("aria-hidden", "false");
|
|
128
|
+
document.body.style.overflow = "hidden";
|
|
129
|
+
}
|
|
130
|
+
function closeDrawer(id) {
|
|
131
|
+
const drawer = document.querySelector(`[data-alive-drawer="${id}"]`);
|
|
132
|
+
if (!drawer) return;
|
|
133
|
+
drawer.classList.remove("is-open");
|
|
134
|
+
drawer.setAttribute("aria-hidden", "true");
|
|
135
|
+
document.body.style.overflow = "";
|
|
136
|
+
}
|
|
137
|
+
function wireDropdown(container, root) {
|
|
138
|
+
const trigger = container.querySelector("[data-alive-trigger]");
|
|
139
|
+
const menu = container.querySelector("[data-alive-dropdown-menu]");
|
|
140
|
+
if (!trigger || !menu) return;
|
|
141
|
+
const toggleCleanup = addListener(trigger, "click", (e) => {
|
|
142
|
+
e.stopPropagation();
|
|
143
|
+
toggleDropdown(container);
|
|
144
|
+
});
|
|
145
|
+
registerCleanup(root, toggleCleanup);
|
|
146
|
+
const outsideCleanup = addListener(document, "click", (e) => {
|
|
147
|
+
if (!container.contains(e.target)) {
|
|
148
|
+
menu.classList.remove("is-open");
|
|
149
|
+
trigger.setAttribute("aria-expanded", "false");
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
registerCleanup(root, outsideCleanup);
|
|
153
|
+
const escCleanup = addListener(document, "keydown", (e) => {
|
|
154
|
+
if (e.key === "Escape" && menu.classList.contains("is-open")) {
|
|
155
|
+
menu.classList.remove("is-open");
|
|
156
|
+
trigger.setAttribute("aria-expanded", "false");
|
|
157
|
+
trigger.focus();
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
registerCleanup(root, escCleanup);
|
|
161
|
+
}
|
|
162
|
+
function toggleDropdown(container) {
|
|
163
|
+
const trigger = container.querySelector("[data-alive-trigger]");
|
|
164
|
+
const menu = container.querySelector("[data-alive-dropdown-menu]");
|
|
165
|
+
if (!menu) return;
|
|
166
|
+
const isOpen = menu.classList.toggle("is-open");
|
|
167
|
+
trigger?.setAttribute("aria-expanded", String(isOpen));
|
|
168
|
+
if (isOpen) {
|
|
169
|
+
menu.querySelector('[role="menuitem"], button, a')?.focus();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function wireTabs(container, root) {
|
|
173
|
+
const tabs = container.querySelectorAll("[data-alive-tab]");
|
|
174
|
+
tabs.forEach((tab) => {
|
|
175
|
+
const cleanup = addListener(tab, "click", () => {
|
|
176
|
+
const panelId = tab.getAttribute("data-alive-tab");
|
|
177
|
+
if (!panelId) return;
|
|
178
|
+
activateTab(container, panelId);
|
|
179
|
+
});
|
|
180
|
+
registerCleanup(root, cleanup);
|
|
181
|
+
const keyCleanup = addListener(tab, "keydown", (e) => {
|
|
182
|
+
const allTabs = [...container.querySelectorAll("[data-alive-tab]")];
|
|
183
|
+
const idx = allTabs.indexOf(tab);
|
|
184
|
+
if (e.key === "ArrowRight" || e.key === "ArrowDown") {
|
|
185
|
+
e.preventDefault();
|
|
186
|
+
allTabs[(idx + 1) % allTabs.length]?.focus();
|
|
187
|
+
} else if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
|
|
188
|
+
e.preventDefault();
|
|
189
|
+
allTabs[(idx - 1 + allTabs.length) % allTabs.length]?.focus();
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
registerCleanup(root, keyCleanup);
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
function activateTab(container, panelId) {
|
|
196
|
+
container.querySelectorAll("[data-alive-tab]").forEach((t) => {
|
|
197
|
+
t.classList.remove("is-active");
|
|
198
|
+
t.setAttribute("aria-selected", "false");
|
|
199
|
+
t.setAttribute("tabindex", "-1");
|
|
200
|
+
});
|
|
201
|
+
const searchRoot = container.closest("[data-alive-tabs-panels]") ?? document;
|
|
202
|
+
searchRoot.querySelectorAll("[data-alive-panel]").forEach((p) => {
|
|
203
|
+
p.classList.remove("is-active");
|
|
204
|
+
p.setAttribute("aria-hidden", "true");
|
|
205
|
+
});
|
|
206
|
+
const activeTab = container.querySelector(`[data-alive-tab="${panelId}"]`);
|
|
207
|
+
activeTab?.classList.add("is-active");
|
|
208
|
+
activeTab?.setAttribute("aria-selected", "true");
|
|
209
|
+
activeTab?.setAttribute("tabindex", "0");
|
|
210
|
+
const activePanel = searchRoot.querySelector(`[data-alive-panel="${panelId}"]`);
|
|
211
|
+
activePanel?.classList.add("is-active");
|
|
212
|
+
activePanel?.setAttribute("aria-hidden", "false");
|
|
213
|
+
}
|
|
214
|
+
function init(root = document.documentElement) {
|
|
215
|
+
root.querySelectorAll("[data-alive-accordion]").forEach((el) => wireAccordion(el, root));
|
|
216
|
+
root.querySelectorAll("[data-alive-modal]").forEach((el) => wireModal(el, root));
|
|
217
|
+
root.querySelectorAll("[data-alive-drawer]").forEach((el) => wireDrawer(el, root));
|
|
218
|
+
root.querySelectorAll("[data-alive-dropdown]").forEach((el) => wireDropdown(el, root));
|
|
219
|
+
root.querySelectorAll("[data-alive-tabs]").forEach((el) => wireTabs(el, root));
|
|
220
|
+
}
|
|
221
|
+
function destroy(root = document.documentElement) {
|
|
222
|
+
const cleanups = cleanupRegistry.get(root) ?? [];
|
|
223
|
+
cleanups.forEach((fn) => fn());
|
|
224
|
+
cleanupRegistry.delete(root);
|
|
225
|
+
}
|
|
226
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
227
|
+
0 && (module.exports = {
|
|
228
|
+
closeDrawer,
|
|
229
|
+
closeModal,
|
|
230
|
+
destroy,
|
|
231
|
+
init,
|
|
232
|
+
openDrawer,
|
|
233
|
+
openModal,
|
|
234
|
+
toggleDropdown
|
|
235
|
+
});
|
|
236
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +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 '@pratikshadake/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// ── 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\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"]}
|
package/dist/runtime.mjs
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
// src/runtime.ts
|
|
2
|
+
var cleanupRegistry = /* @__PURE__ */ new WeakMap();
|
|
3
|
+
function registerCleanup(root, fn) {
|
|
4
|
+
const existing = cleanupRegistry.get(root) ?? [];
|
|
5
|
+
existing.push(fn);
|
|
6
|
+
cleanupRegistry.set(root, existing);
|
|
7
|
+
}
|
|
8
|
+
function addListener(el, type, handler, options) {
|
|
9
|
+
el.addEventListener(type, handler, options);
|
|
10
|
+
return () => el.removeEventListener(type, handler, options);
|
|
11
|
+
}
|
|
12
|
+
function wireAccordion(container, root) {
|
|
13
|
+
const triggers = container.querySelectorAll("[data-alive-trigger]");
|
|
14
|
+
triggers.forEach((trigger) => {
|
|
15
|
+
const item = trigger.closest("[data-alive-accordion-item]") ?? trigger.parentElement;
|
|
16
|
+
if (!item) return;
|
|
17
|
+
const cleanup = addListener(trigger, "click", () => {
|
|
18
|
+
const isOpen = item.classList.contains("is-open");
|
|
19
|
+
if (!container.hasAttribute("data-alive-multi")) {
|
|
20
|
+
container.querySelectorAll("[data-alive-accordion-item]").forEach((i) => {
|
|
21
|
+
i.classList.remove("is-open");
|
|
22
|
+
i.querySelector("[data-alive-trigger]")?.setAttribute("aria-expanded", "false");
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
if (!isOpen) {
|
|
26
|
+
item.classList.add("is-open");
|
|
27
|
+
trigger.setAttribute("aria-expanded", "true");
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
registerCleanup(root, cleanup);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function wireModal(modal, root) {
|
|
34
|
+
const id = modal.getAttribute("data-alive-modal");
|
|
35
|
+
if (!id) return;
|
|
36
|
+
const openers = document.querySelectorAll(`[data-alive-open="${id}"]`);
|
|
37
|
+
openers.forEach((opener) => {
|
|
38
|
+
const cleanup2 = addListener(opener, "click", () => openModal(id));
|
|
39
|
+
registerCleanup(root, cleanup2);
|
|
40
|
+
});
|
|
41
|
+
modal.querySelectorAll("[data-alive-close]").forEach((closer) => {
|
|
42
|
+
const cleanup2 = addListener(closer, "click", () => closeModal(id));
|
|
43
|
+
registerCleanup(root, cleanup2);
|
|
44
|
+
});
|
|
45
|
+
const cleanup = addListener(modal, "click", (e) => {
|
|
46
|
+
if (e.target === modal) closeModal(id);
|
|
47
|
+
});
|
|
48
|
+
registerCleanup(root, cleanup);
|
|
49
|
+
const escCleanup = addListener(document, "keydown", (e) => {
|
|
50
|
+
if (e.key === "Escape" && modal.classList.contains("is-open")) closeModal(id);
|
|
51
|
+
});
|
|
52
|
+
registerCleanup(root, escCleanup);
|
|
53
|
+
}
|
|
54
|
+
function openModal(id) {
|
|
55
|
+
const modal = document.querySelector(`[data-alive-modal="${id}"]`);
|
|
56
|
+
if (!modal) return;
|
|
57
|
+
modal.classList.add("is-open");
|
|
58
|
+
modal.setAttribute("aria-hidden", "false");
|
|
59
|
+
document.body.style.overflow = "hidden";
|
|
60
|
+
const focusable = modal.querySelector(
|
|
61
|
+
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
62
|
+
);
|
|
63
|
+
focusable?.focus();
|
|
64
|
+
}
|
|
65
|
+
function closeModal(id) {
|
|
66
|
+
const modal = document.querySelector(`[data-alive-modal="${id}"]`);
|
|
67
|
+
if (!modal) return;
|
|
68
|
+
modal.classList.remove("is-open");
|
|
69
|
+
modal.setAttribute("aria-hidden", "true");
|
|
70
|
+
document.body.style.overflow = "";
|
|
71
|
+
}
|
|
72
|
+
function wireDrawer(drawer, root) {
|
|
73
|
+
const id = drawer.getAttribute("data-alive-drawer");
|
|
74
|
+
if (!id) return;
|
|
75
|
+
const openers = document.querySelectorAll(`[data-alive-open="${id}"]`);
|
|
76
|
+
openers.forEach((opener) => {
|
|
77
|
+
const cleanup = addListener(opener, "click", () => openDrawer(id));
|
|
78
|
+
registerCleanup(root, cleanup);
|
|
79
|
+
});
|
|
80
|
+
drawer.querySelectorAll("[data-alive-close]").forEach((closer) => {
|
|
81
|
+
const cleanup = addListener(closer, "click", () => closeDrawer(id));
|
|
82
|
+
registerCleanup(root, cleanup);
|
|
83
|
+
});
|
|
84
|
+
const backdropCleanup = addListener(drawer, "click", (e) => {
|
|
85
|
+
if (e.target === drawer) closeDrawer(id);
|
|
86
|
+
});
|
|
87
|
+
registerCleanup(root, backdropCleanup);
|
|
88
|
+
const escCleanup = addListener(document, "keydown", (e) => {
|
|
89
|
+
if (e.key === "Escape" && drawer.classList.contains("is-open")) closeDrawer(id);
|
|
90
|
+
});
|
|
91
|
+
registerCleanup(root, escCleanup);
|
|
92
|
+
}
|
|
93
|
+
function openDrawer(id) {
|
|
94
|
+
const drawer = document.querySelector(`[data-alive-drawer="${id}"]`);
|
|
95
|
+
if (!drawer) return;
|
|
96
|
+
drawer.classList.add("is-open");
|
|
97
|
+
drawer.setAttribute("aria-hidden", "false");
|
|
98
|
+
document.body.style.overflow = "hidden";
|
|
99
|
+
}
|
|
100
|
+
function closeDrawer(id) {
|
|
101
|
+
const drawer = document.querySelector(`[data-alive-drawer="${id}"]`);
|
|
102
|
+
if (!drawer) return;
|
|
103
|
+
drawer.classList.remove("is-open");
|
|
104
|
+
drawer.setAttribute("aria-hidden", "true");
|
|
105
|
+
document.body.style.overflow = "";
|
|
106
|
+
}
|
|
107
|
+
function wireDropdown(container, root) {
|
|
108
|
+
const trigger = container.querySelector("[data-alive-trigger]");
|
|
109
|
+
const menu = container.querySelector("[data-alive-dropdown-menu]");
|
|
110
|
+
if (!trigger || !menu) return;
|
|
111
|
+
const toggleCleanup = addListener(trigger, "click", (e) => {
|
|
112
|
+
e.stopPropagation();
|
|
113
|
+
toggleDropdown(container);
|
|
114
|
+
});
|
|
115
|
+
registerCleanup(root, toggleCleanup);
|
|
116
|
+
const outsideCleanup = addListener(document, "click", (e) => {
|
|
117
|
+
if (!container.contains(e.target)) {
|
|
118
|
+
menu.classList.remove("is-open");
|
|
119
|
+
trigger.setAttribute("aria-expanded", "false");
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
registerCleanup(root, outsideCleanup);
|
|
123
|
+
const escCleanup = addListener(document, "keydown", (e) => {
|
|
124
|
+
if (e.key === "Escape" && menu.classList.contains("is-open")) {
|
|
125
|
+
menu.classList.remove("is-open");
|
|
126
|
+
trigger.setAttribute("aria-expanded", "false");
|
|
127
|
+
trigger.focus();
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
registerCleanup(root, escCleanup);
|
|
131
|
+
}
|
|
132
|
+
function toggleDropdown(container) {
|
|
133
|
+
const trigger = container.querySelector("[data-alive-trigger]");
|
|
134
|
+
const menu = container.querySelector("[data-alive-dropdown-menu]");
|
|
135
|
+
if (!menu) return;
|
|
136
|
+
const isOpen = menu.classList.toggle("is-open");
|
|
137
|
+
trigger?.setAttribute("aria-expanded", String(isOpen));
|
|
138
|
+
if (isOpen) {
|
|
139
|
+
menu.querySelector('[role="menuitem"], button, a')?.focus();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function wireTabs(container, root) {
|
|
143
|
+
const tabs = container.querySelectorAll("[data-alive-tab]");
|
|
144
|
+
tabs.forEach((tab) => {
|
|
145
|
+
const cleanup = addListener(tab, "click", () => {
|
|
146
|
+
const panelId = tab.getAttribute("data-alive-tab");
|
|
147
|
+
if (!panelId) return;
|
|
148
|
+
activateTab(container, panelId);
|
|
149
|
+
});
|
|
150
|
+
registerCleanup(root, cleanup);
|
|
151
|
+
const keyCleanup = addListener(tab, "keydown", (e) => {
|
|
152
|
+
const allTabs = [...container.querySelectorAll("[data-alive-tab]")];
|
|
153
|
+
const idx = allTabs.indexOf(tab);
|
|
154
|
+
if (e.key === "ArrowRight" || e.key === "ArrowDown") {
|
|
155
|
+
e.preventDefault();
|
|
156
|
+
allTabs[(idx + 1) % allTabs.length]?.focus();
|
|
157
|
+
} else if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
|
|
158
|
+
e.preventDefault();
|
|
159
|
+
allTabs[(idx - 1 + allTabs.length) % allTabs.length]?.focus();
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
registerCleanup(root, keyCleanup);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
function activateTab(container, panelId) {
|
|
166
|
+
container.querySelectorAll("[data-alive-tab]").forEach((t) => {
|
|
167
|
+
t.classList.remove("is-active");
|
|
168
|
+
t.setAttribute("aria-selected", "false");
|
|
169
|
+
t.setAttribute("tabindex", "-1");
|
|
170
|
+
});
|
|
171
|
+
const searchRoot = container.closest("[data-alive-tabs-panels]") ?? document;
|
|
172
|
+
searchRoot.querySelectorAll("[data-alive-panel]").forEach((p) => {
|
|
173
|
+
p.classList.remove("is-active");
|
|
174
|
+
p.setAttribute("aria-hidden", "true");
|
|
175
|
+
});
|
|
176
|
+
const activeTab = container.querySelector(`[data-alive-tab="${panelId}"]`);
|
|
177
|
+
activeTab?.classList.add("is-active");
|
|
178
|
+
activeTab?.setAttribute("aria-selected", "true");
|
|
179
|
+
activeTab?.setAttribute("tabindex", "0");
|
|
180
|
+
const activePanel = searchRoot.querySelector(`[data-alive-panel="${panelId}"]`);
|
|
181
|
+
activePanel?.classList.add("is-active");
|
|
182
|
+
activePanel?.setAttribute("aria-hidden", "false");
|
|
183
|
+
}
|
|
184
|
+
function init(root = document.documentElement) {
|
|
185
|
+
root.querySelectorAll("[data-alive-accordion]").forEach((el) => wireAccordion(el, root));
|
|
186
|
+
root.querySelectorAll("[data-alive-modal]").forEach((el) => wireModal(el, root));
|
|
187
|
+
root.querySelectorAll("[data-alive-drawer]").forEach((el) => wireDrawer(el, root));
|
|
188
|
+
root.querySelectorAll("[data-alive-dropdown]").forEach((el) => wireDropdown(el, root));
|
|
189
|
+
root.querySelectorAll("[data-alive-tabs]").forEach((el) => wireTabs(el, root));
|
|
190
|
+
}
|
|
191
|
+
function destroy(root = document.documentElement) {
|
|
192
|
+
const cleanups = cleanupRegistry.get(root) ?? [];
|
|
193
|
+
cleanups.forEach((fn) => fn());
|
|
194
|
+
cleanupRegistry.delete(root);
|
|
195
|
+
}
|
|
196
|
+
export {
|
|
197
|
+
closeDrawer,
|
|
198
|
+
closeModal,
|
|
199
|
+
destroy,
|
|
200
|
+
init,
|
|
201
|
+
openDrawer,
|
|
202
|
+
openModal,
|
|
203
|
+
toggleDropdown
|
|
204
|
+
};
|
|
205
|
+
//# sourceMappingURL=runtime.mjs.map
|
|
@@ -0,0 +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 '@pratikshadake/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// ── 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\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"]}
|
package/dist/vite.d.mts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
type ColorShades = Record<string, string>;
|
|
4
|
+
type ColorScale = Record<string, string | ColorShades>;
|
|
5
|
+
interface AliveUITheme {
|
|
6
|
+
colors: ColorScale;
|
|
7
|
+
spacing: Record<string, string>;
|
|
8
|
+
borderRadius: Record<string, string>;
|
|
9
|
+
fontSize: Record<string, [string, string]>;
|
|
10
|
+
fontWeight: Record<string, string>;
|
|
11
|
+
lineHeight: Record<string, string>;
|
|
12
|
+
screens: Record<string, string>;
|
|
13
|
+
opacity: Record<string, string>;
|
|
14
|
+
zIndex: Record<string, string>;
|
|
15
|
+
boxShadow: Record<string, string>;
|
|
16
|
+
darkMode: 'media' | 'class';
|
|
17
|
+
}
|
|
18
|
+
interface AliveUIConfig {
|
|
19
|
+
content: string[];
|
|
20
|
+
output?: string;
|
|
21
|
+
theme?: DeepPartial<AliveUITheme>;
|
|
22
|
+
}
|
|
23
|
+
type DeepPartial<T> = {
|
|
24
|
+
[K in keyof T]?: T[K] extends Record<string, unknown> ? DeepPartial<T[K]> : T[K];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* AliveUI Vite Plugin
|
|
29
|
+
*
|
|
30
|
+
* Injects the AliveUI PostCSS plugin into Vite's CSS pipeline so that
|
|
31
|
+
* `@aliveui` directives in your CSS are processed automatically.
|
|
32
|
+
*
|
|
33
|
+
* Usage in vite.config.ts:
|
|
34
|
+
* import { aliveUIVite } from '@pratikshadake/aliveui/vite'
|
|
35
|
+
*
|
|
36
|
+
* export default defineConfig({
|
|
37
|
+
* plugins: [aliveUIVite({ content: ['./src/**\/*.{ts,tsx,html}'] })],
|
|
38
|
+
* })
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
declare function aliveUIVite(config?: Partial<AliveUIConfig>): Plugin;
|
|
42
|
+
|
|
43
|
+
export { aliveUIVite, aliveUIVite as default };
|
package/dist/vite.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
type ColorShades = Record<string, string>;
|
|
4
|
+
type ColorScale = Record<string, string | ColorShades>;
|
|
5
|
+
interface AliveUITheme {
|
|
6
|
+
colors: ColorScale;
|
|
7
|
+
spacing: Record<string, string>;
|
|
8
|
+
borderRadius: Record<string, string>;
|
|
9
|
+
fontSize: Record<string, [string, string]>;
|
|
10
|
+
fontWeight: Record<string, string>;
|
|
11
|
+
lineHeight: Record<string, string>;
|
|
12
|
+
screens: Record<string, string>;
|
|
13
|
+
opacity: Record<string, string>;
|
|
14
|
+
zIndex: Record<string, string>;
|
|
15
|
+
boxShadow: Record<string, string>;
|
|
16
|
+
darkMode: 'media' | 'class';
|
|
17
|
+
}
|
|
18
|
+
interface AliveUIConfig {
|
|
19
|
+
content: string[];
|
|
20
|
+
output?: string;
|
|
21
|
+
theme?: DeepPartial<AliveUITheme>;
|
|
22
|
+
}
|
|
23
|
+
type DeepPartial<T> = {
|
|
24
|
+
[K in keyof T]?: T[K] extends Record<string, unknown> ? DeepPartial<T[K]> : T[K];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* AliveUI Vite Plugin
|
|
29
|
+
*
|
|
30
|
+
* Injects the AliveUI PostCSS plugin into Vite's CSS pipeline so that
|
|
31
|
+
* `@aliveui` directives in your CSS are processed automatically.
|
|
32
|
+
*
|
|
33
|
+
* Usage in vite.config.ts:
|
|
34
|
+
* import { aliveUIVite } from '@pratikshadake/aliveui/vite'
|
|
35
|
+
*
|
|
36
|
+
* export default defineConfig({
|
|
37
|
+
* plugins: [aliveUIVite({ content: ['./src/**\/*.{ts,tsx,html}'] })],
|
|
38
|
+
* })
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
declare function aliveUIVite(config?: Partial<AliveUIConfig>): Plugin;
|
|
42
|
+
|
|
43
|
+
export { aliveUIVite, aliveUIVite as default };
|