arekui 1.0.0 → 2.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.
Files changed (99) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/LICENSE +21 -21
  3. package/README.md +26 -198
  4. package/arekui.css +5930 -3279
  5. package/arekui.d.ts +328 -328
  6. package/arekui.js +817 -450
  7. package/assets/img/grunge-wall-texture-freepick-kues1.webp +0 -0
  8. package/assets/img/logo.png +0 -0
  9. package/dist/css/arekui.base.min.css +1 -0
  10. package/dist/css/arekui.broadsheet.min.css +1 -0
  11. package/dist/css/arekui.brutalist.min.css +1 -0
  12. package/dist/css/arekui.default.min.css +1 -0
  13. package/dist/css/arekui.full.min.css +1 -0
  14. package/dist/css/arekui.min.css +1 -0
  15. package/dist/css/arekui.neo.min.css +1 -0
  16. package/dist/css/arekui.pixel.min.css +1 -0
  17. package/dist/js/arekui.min.js +2 -0
  18. package/package.json +64 -57
  19. package/scripts/build-css.js +95 -0
  20. package/scripts/build-custom.js +287 -318
  21. package/scripts/build-js.js +68 -0
  22. package/scripts/clean.js +13 -0
  23. package/scripts/dev.js +97 -0
  24. package/scripts/imports.js +18 -0
  25. package/scripts/split.js +256 -0
  26. package/src/arekui.base.css +63 -0
  27. package/src/arekui.broadsheet.css +6 -0
  28. package/src/arekui.brutalist.css +8 -0
  29. package/src/arekui.core.css +64 -0
  30. package/src/arekui.css +22 -5
  31. package/src/arekui.default.css +6 -0
  32. package/src/arekui.neo.css +8 -0
  33. package/src/arekui.pixel.css +8 -0
  34. package/src/base/brutalist-overrides.css +254 -0
  35. package/src/base/neo-overrides.css +330 -315
  36. package/src/base/pixel-overrides.css +336 -0
  37. package/src/base/reset.css +179 -65
  38. package/src/base/theme-brutalist.css +111 -0
  39. package/src/base/theme-default.css +184 -0
  40. package/src/base/theme-neo.css +108 -0
  41. package/src/base/theme-pixel.css +111 -0
  42. package/src/base/tokens.css +59 -302
  43. package/src/components/accordion.css +32 -33
  44. package/src/components/alert.css +24 -25
  45. package/src/components/badge.css +31 -32
  46. package/src/components/breadcrumb.css +31 -32
  47. package/src/components/broadsheet.css +264 -0
  48. package/src/components/button.css +102 -101
  49. package/src/components/card.css +22 -23
  50. package/src/components/carousel.css +49 -13
  51. package/src/components/chat.css +77 -76
  52. package/src/components/description-list.css +34 -0
  53. package/src/components/docs.css +252 -0
  54. package/src/components/empty.css +36 -0
  55. package/src/components/file-upload.css +49 -50
  56. package/src/components/footer.css +40 -25
  57. package/src/components/forms.css +67 -68
  58. package/src/components/heading.css +27 -0
  59. package/src/components/hero.css +20 -21
  60. package/src/components/join.css +12 -13
  61. package/src/components/kbd.css +15 -0
  62. package/src/components/link.css +22 -23
  63. package/src/components/loading.css +109 -0
  64. package/src/components/menu.css +104 -54
  65. package/src/components/misc.css +94 -55
  66. package/src/components/modal.css +30 -31
  67. package/src/components/navbar.css +166 -36
  68. package/src/components/pagination.css +50 -45
  69. package/src/components/popover.css +68 -69
  70. package/src/components/progress.css +17 -18
  71. package/src/components/prose.css +78 -78
  72. package/src/components/rating.css +35 -36
  73. package/src/components/scroll-top.css +34 -34
  74. package/src/components/segmented.css +44 -0
  75. package/src/components/sidebar.css +377 -0
  76. package/src/components/skeleton.css +52 -52
  77. package/src/components/spinner.css +36 -0
  78. package/src/components/swap.css +43 -43
  79. package/src/components/table.css +20 -21
  80. package/src/components/tabs.css +22 -23
  81. package/src/components/tag.css +99 -99
  82. package/src/components/textured.css +52 -32
  83. package/src/components/timeline.css +32 -33
  84. package/src/components/toast.css +132 -132
  85. package/src/components/tooltip.css +22 -23
  86. package/src/utilities/borders.css +150 -150
  87. package/src/utilities/brutalist-utilities.css +49 -0
  88. package/src/utilities/colors.css +79 -71
  89. package/src/utilities/hover.css +31 -31
  90. package/src/utilities/layout.css +98 -98
  91. package/src/utilities/neo-utilities.css +86 -93
  92. package/src/utilities/pixel-utilities.css +88 -0
  93. package/src/utilities/responsive.css +131 -126
  94. package/src/utilities/sizing.css +98 -89
  95. package/src/utilities/spacing.css +132 -129
  96. package/src/utilities/typography.css +95 -92
  97. package/dist/arekui.min.css +0 -1
  98. package/dist/arekui.min.js +0 -2
  99. package/src/components/drawer.css +0 -53
package/arekui.js CHANGED
@@ -1,450 +1,817 @@
1
- /*!
2
- * Arekui v1.0.0 — optional vanilla JS (no dependencies).
3
- * data-ar-* driven behaviors: theme toggle, modal, drawer, tabs, dropdown, accordion, toast, rating, popover, file upload, scroll-to-top.
4
- */
5
- (() => {
6
- var STORAGE_KEY = "arekui-theme";
7
-
8
- var THEMES_LIGHT_DARK = ["light", "dark"];
9
- var THEMES_DEFAULT_NEO = ["light", "neo"];
10
-
11
- function getTheme() {
12
- return document.documentElement.getAttribute("data-theme");
13
- }
14
-
15
- function setTheme(theme) {
16
- document.documentElement.setAttribute("data-theme", theme);
17
- document.documentElement.classList.toggle("dark", theme === "dark");
18
- }
19
-
20
- function initTheme() {
21
- var stored = localStorage.getItem(STORAGE_KEY);
22
- var allThemes = THEMES_LIGHT_DARK.concat(THEMES_DEFAULT_NEO);
23
- if (stored && allThemes.indexOf(stored) !== -1) {
24
- setTheme(stored);
25
- } else {
26
- var prefersDark = window.matchMedia(
27
- "(prefers-color-scheme: dark)",
28
- ).matches;
29
- setTheme(prefersDark ? "dark" : "light");
30
- }
31
- }
32
-
33
- function syncToggles() {
34
- var current = getTheme();
35
- document.querySelectorAll("[data-ar-theme-toggle]").forEach((el) => {
36
- if (el.matches('input[type="checkbox"]')) {
37
- el.checked = current === "dark";
38
- } else {
39
- el.setAttribute("aria-pressed", String(current === "dark"));
40
- }
41
- });
42
- document.querySelectorAll("[data-ar-neo-toggle]").forEach((el) => {
43
- var isNeo = current === "neo";
44
- if (el.matches('input[type="checkbox"]')) {
45
- el.checked = isNeo;
46
- } else {
47
- el.setAttribute("aria-pressed", String(isNeo));
48
- el.textContent = isNeo ? "Default" : "Neo";
49
- }
50
- });
51
- }
52
-
53
- function initThemeToggle() {
54
- document.addEventListener("click", (e) => {
55
- var toggle = e.target.closest("[data-ar-theme-toggle]");
56
- if (!toggle) return;
57
- var current = getTheme() || "light";
58
- var idx = THEMES_LIGHT_DARK.indexOf(current);
59
- var next = THEMES_LIGHT_DARK[(idx + 1) % THEMES_LIGHT_DARK.length];
60
- setTheme(next);
61
- localStorage.setItem(STORAGE_KEY, next);
62
- syncToggles();
63
- });
64
- }
65
-
66
- function initNeoToggle() {
67
- document.addEventListener("click", (e) => {
68
- var toggle = e.target.closest("[data-ar-neo-toggle]");
69
- if (!toggle) return;
70
- var current = getTheme() || "light";
71
- var idx = THEMES_DEFAULT_NEO.indexOf(current);
72
- var next = THEMES_DEFAULT_NEO[(idx + 1) % THEMES_DEFAULT_NEO.length];
73
- setTheme(next);
74
- localStorage.setItem(STORAGE_KEY, next);
75
- syncToggles();
76
- });
77
- }
78
-
79
- function initModals() {
80
- document.querySelectorAll("[data-ar-open]").forEach((opener) => {
81
- opener.addEventListener("click", (e) => {
82
- e.preventDefault();
83
- var target = document.getElementById(
84
- opener.getAttribute("data-ar-open"),
85
- );
86
- if (target && typeof target.showModal === "function")
87
- target.showModal();
88
- });
89
- });
90
- document.querySelectorAll("[data-ar-close]").forEach((closer) => {
91
- closer.addEventListener("click", () => {
92
- var modal = closer.closest("dialog");
93
- if (modal && typeof modal.close === "function") modal.close();
94
- });
95
- });
96
- document
97
- .querySelectorAll("dialog[data-ar-backdrop-close]")
98
- .forEach((modal) => {
99
- modal.addEventListener("click", (e) => {
100
- if (e.target === modal) modal.close();
101
- });
102
- });
103
- }
104
-
105
- function initDrawers() {
106
- document.querySelectorAll("[data-ar-drawer-toggle]").forEach((btn) => {
107
- btn.addEventListener("click", () => {
108
- var id = btn.getAttribute("data-ar-drawer-toggle");
109
- var checkbox = document.getElementById(id);
110
- if (checkbox) checkbox.checked = !checkbox.checked;
111
- });
112
- });
113
- }
114
-
115
- function initTabs() {
116
- document.querySelectorAll("[data-ar-tab]").forEach((tab) => {
117
- tab.addEventListener("click", () => {
118
- var group = tab.closest(".ar-tabs");
119
- if (!group) return;
120
- group.querySelectorAll("[data-ar-tab]").forEach((t) => {
121
- t.classList.remove("ar-tab-active");
122
- });
123
- tab.classList.add("ar-tab-active");
124
- var panelId = tab.getAttribute("data-ar-tab");
125
- var groupPanel = group.getAttribute("data-ar-tabs-panel");
126
- if (groupPanel) {
127
- document.querySelectorAll("[" + groupPanel + "]").forEach((p) => {
128
- p.style.display = p.id === panelId ? "" : "none";
129
- });
130
- }
131
- });
132
- });
133
- }
134
-
135
- function closeDropdown(dropdown) {
136
- dropdown.classList.remove("ar-dropdown-open");
137
- var trigger = dropdown.querySelector(":scope > button, :scope > a");
138
- if (trigger) trigger.blur();
139
- }
140
-
141
- function initDropdowns() {
142
- document.querySelectorAll(".ar-dropdown").forEach((dropdown) => {
143
- var content = dropdown.querySelector(".ar-dropdown-content");
144
- if (!content) return;
145
-
146
- dropdown.addEventListener("click", (e) => {
147
- if (content.contains(e.target)) {
148
- closeDropdown(dropdown);
149
- return;
150
- }
151
- if (dropdown.classList.contains("ar-dropdown-open")) {
152
- closeDropdown(dropdown);
153
- } else {
154
- dropdown.classList.add("ar-dropdown-open");
155
- }
156
- });
157
- });
158
-
159
- document.addEventListener("click", (e) => {
160
- document
161
- .querySelectorAll(".ar-dropdown.ar-dropdown-open")
162
- .forEach((dd) => {
163
- if (!dd.contains(e.target)) dd.classList.remove("ar-dropdown-open");
164
- });
165
- });
166
-
167
- document.addEventListener("keydown", (e) => {
168
- if (e.key === "Escape") {
169
- document
170
- .querySelectorAll(".ar-dropdown.ar-dropdown-open")
171
- .forEach(closeDropdown);
172
- }
173
- });
174
- }
175
-
176
- function initAccordion() {
177
- document.querySelectorAll(".ar-accordion details").forEach((d) => {
178
- var first = d.querySelector("summary");
179
- if (first)
180
- first.addEventListener("click", () => {
181
- if (d.getAttribute("data-ar-exclusive") !== null) return;
182
- var parent = d.closest(".ar-accordion");
183
- if (!parent) return;
184
- parent.querySelectorAll("details[open]").forEach((other) => {
185
- if (other !== d) other.removeAttribute("open");
186
- });
187
- });
188
- });
189
- }
190
-
191
- var toastContainers = {};
192
-
193
- function getToastContainer(position) {
194
- if (toastContainers[position]) return toastContainers[position];
195
- var container = document.createElement("div");
196
- container.className = "ar-toast-container";
197
- container.setAttribute("data-ar-toast-position", position);
198
- document.body.appendChild(container);
199
- toastContainers[position] = container;
200
- return container;
201
- }
202
-
203
- function toast(message, options) {
204
- var opts = options || {};
205
- var type = opts.type || "";
206
- var duration = typeof opts.duration === "number" ? opts.duration : 4000;
207
- var position = opts.position || "top-right";
208
- var closable = opts.closable !== false;
209
- var icon = opts.icon || null;
210
-
211
- var container = getToastContainer(position);
212
- var el = document.createElement("div");
213
- el.className = "ar-toast" + (type ? " ar-toast-" + type : "");
214
- el.style.position = "relative";
215
-
216
- if (icon) {
217
- var iconEl = document.createElement("span");
218
- iconEl.className = "ar-toast-icon";
219
- iconEl.textContent = icon;
220
- el.appendChild(iconEl);
221
- }
222
-
223
- var msgEl = document.createElement("span");
224
- msgEl.className = "ar-toast-message";
225
- msgEl.textContent = message;
226
- el.appendChild(msgEl);
227
-
228
- if (closable) {
229
- var closeBtn = document.createElement("button");
230
- closeBtn.className = "ar-toast-close";
231
- closeBtn.textContent = "\u2715";
232
- closeBtn.setAttribute("aria-label", "Close");
233
- closeBtn.addEventListener("click", () => {
234
- dismissToast(el);
235
- });
236
- el.appendChild(closeBtn);
237
- }
238
-
239
- if (duration > 0) {
240
- var progress = document.createElement("div");
241
- progress.className = "ar-toast-progress";
242
- progress.style.animationDuration = duration + "ms";
243
- el.appendChild(progress);
244
- }
245
-
246
- container.appendChild(el);
247
-
248
- var timer;
249
- if (duration > 0) {
250
- timer = setTimeout(() => {
251
- dismissToast(el);
252
- }, duration);
253
- }
254
-
255
- el.addEventListener("mouseenter", () => {
256
- if (timer) clearTimeout(timer);
257
- if (el.querySelector(".ar-toast-progress")) {
258
- el.querySelector(".ar-toast-progress").style.animationPlayState =
259
- "paused";
260
- }
261
- });
262
- el.addEventListener("mouseleave", () => {
263
- if (duration > 0) {
264
- var remaining = duration * 0.3;
265
- timer = setTimeout(() => {
266
- dismissToast(el);
267
- }, remaining);
268
- if (el.querySelector(".ar-toast-progress")) {
269
- el.querySelector(".ar-toast-progress").style.animationPlayState =
270
- "running";
271
- }
272
- }
273
- });
274
-
275
- return el;
276
- }
277
-
278
- function dismissToast(el) {
279
- if (el.classList.contains("ar-toast-out")) return;
280
- el.classList.add("ar-toast-out");
281
- el.addEventListener("animationend", () => {
282
- el.remove();
283
- });
284
- }
285
-
286
- function initRatings() {
287
- document.querySelectorAll("[data-ar-rating]").forEach((group) => {
288
- var inputs = group.querySelectorAll("input");
289
- inputs.forEach((input) => {
290
- input.addEventListener("change", () => {
291
- var event = new CustomEvent("ar-rating-change", {
292
- detail: { value: Number(input.value) },
293
- bubbles: true,
294
- });
295
- group.dispatchEvent(event);
296
- });
297
- });
298
- });
299
- }
300
-
301
- function getRating(container) {
302
- var checked = container.querySelector("input:checked");
303
- return checked ? Number(checked.value) : 0;
304
- }
305
-
306
- function setRating(container, value) {
307
- var input = container.querySelector('input[value="' + value + '"]');
308
- if (input) {
309
- input.checked = true;
310
- input.dispatchEvent(new Event("change"));
311
- }
312
- }
313
-
314
- function initPopovers() {
315
- // Click toggle
316
- document.addEventListener("click", (e) => {
317
- var trigger = e.target.closest("[data-ar-popover]");
318
- if (trigger) {
319
- e.preventDefault();
320
- var id = trigger.getAttribute("data-ar-popover");
321
- var popover = id
322
- ? document.getElementById(id)
323
- : trigger.querySelector(".ar-popover-content");
324
- if (!popover) return;
325
- var wrapper =
326
- popover.closest(".ar-popover") || trigger.closest(".ar-popover");
327
- if (!wrapper) return;
328
- document.querySelectorAll(".ar-popover-open").forEach((p) => {
329
- if (p !== wrapper) p.classList.remove("ar-popover-open");
330
- });
331
- wrapper.classList.toggle("ar-popover-open");
332
- return;
333
- }
334
- if (!e.target.closest(".ar-popover")) {
335
- document.querySelectorAll(".ar-popover-open").forEach((p) => {
336
- p.classList.remove("ar-popover-open");
337
- });
338
- }
339
- });
340
- document.addEventListener("keydown", (e) => {
341
- if (e.key === "Escape") {
342
- document.querySelectorAll(".ar-popover-open").forEach((p) => {
343
- p.classList.remove("ar-popover-open");
344
- });
345
- }
346
- });
347
- }
348
-
349
- function openPopover(id) {
350
- var el = document.getElementById(id);
351
- if (el) {
352
- var wrapper = el.closest(".ar-popover");
353
- if (wrapper) wrapper.classList.add("ar-popover-open");
354
- }
355
- }
356
-
357
- function closePopover(id) {
358
- var el = document.getElementById(id);
359
- if (el) {
360
- var wrapper = el.closest(".ar-popover");
361
- if (wrapper) wrapper.classList.remove("ar-popover-open");
362
- }
363
- }
364
-
365
- function initFileUploads() {
366
- document.querySelectorAll(".ar-file-upload").forEach((zone) => {
367
- var input = zone.querySelector('input[type="file"]');
368
- if (!input) return;
369
- ["dragenter", "dragover"].forEach((evt) => {
370
- zone.addEventListener(evt, (e) => {
371
- e.preventDefault();
372
- zone.classList.add("ar-file-upload-dragover");
373
- });
374
- });
375
- ["dragleave", "drop"].forEach((evt) => {
376
- zone.addEventListener(evt, (e) => {
377
- e.preventDefault();
378
- zone.classList.remove("ar-file-upload-dragover");
379
- });
380
- });
381
- input.addEventListener("change", () => {
382
- var event = new CustomEvent("ar-file-change", {
383
- detail: { files: input.files },
384
- bubbles: true,
385
- });
386
- zone.dispatchEvent(event);
387
- });
388
- });
389
- }
390
-
391
- function initScrollTop() {
392
- var btns = document.querySelectorAll("[data-ar-scroll-top]");
393
- if (!btns.length) return;
394
-
395
- function toggle() {
396
- var show = window.scrollY > 300;
397
- btns.forEach((btn) => {
398
- btn.classList.toggle("ar-scroll-top-visible", show);
399
- });
400
- }
401
-
402
- window.addEventListener("scroll", toggle, { passive: true });
403
- toggle();
404
-
405
- btns.forEach((btn) => {
406
- btn.addEventListener("click", () => {
407
- window.scrollTo({ top: 0, behavior: "smooth" });
408
- });
409
- });
410
- }
411
-
412
- function init() {
413
- if (document.readyState === "loading") {
414
- document.addEventListener("DOMContentLoaded", ready);
415
- } else {
416
- ready();
417
- }
418
- }
419
-
420
- function ready() {
421
- if (!getTheme()) initTheme();
422
- syncToggles();
423
- initThemeToggle();
424
- initNeoToggle();
425
- initModals();
426
- initDrawers();
427
- initTabs();
428
- initDropdowns();
429
- initAccordion();
430
- initRatings();
431
- initPopovers();
432
- initFileUploads();
433
- initScrollTop();
434
- }
435
-
436
- window.ARStyle = {
437
- setTheme: setTheme,
438
- getTheme: getTheme,
439
- initTheme: initTheme,
440
- init: init,
441
- toast: toast,
442
- dismissToast: dismissToast,
443
- getRating: getRating,
444
- setRating: setRating,
445
- openPopover: openPopover,
446
- closePopover: closePopover,
447
- };
448
-
449
- init();
450
- })();
1
+ /*!
2
+ * ArekUI v2.0.0 — optional vanilla JS (no browser runtime dependencies).
3
+ * data-ar-* driven behaviors: theme toggle, modal, sidebar, tabs, dropdown, accordion, toast, rating, popover, file upload, scroll-to-top, carousel controls.
4
+ */
5
+ (() => {
6
+ var STORAGE_KEY = "arekui-theme";
7
+
8
+ var KNOWN_THEMES = ["light", "dark", "neo", "pixel", "brutalist"];
9
+ var THEME_LABELS = {
10
+ light: "Default",
11
+ dark: "Dark",
12
+ neo: "Neo",
13
+ pixel: "Pixel",
14
+ brutalist: "Brutalist",
15
+ };
16
+
17
+ function getTheme() {
18
+ return document.documentElement.getAttribute("data-theme");
19
+ }
20
+
21
+ function setTheme(theme) {
22
+ document.documentElement.setAttribute("data-theme", theme);
23
+ document.documentElement.classList.toggle("dark", theme === "dark");
24
+ document.dispatchEvent(
25
+ new CustomEvent("ar-themechange", { detail: { theme: theme } }),
26
+ );
27
+ syncToggles();
28
+ }
29
+
30
+ function initTheme() {
31
+ var stored = localStorage.getItem(STORAGE_KEY);
32
+ if (stored && KNOWN_THEMES.indexOf(stored) !== -1) {
33
+ setTheme(stored);
34
+ } else {
35
+ var prefersDark = window.matchMedia(
36
+ "(prefers-color-scheme: dark)",
37
+ ).matches;
38
+ setTheme(prefersDark ? "dark" : "light");
39
+ }
40
+ }
41
+
42
+ function setToggleLabel(el, whenOn, whenOff, isOn) {
43
+ if (el.children.length > 0) return;
44
+ var current = (el.textContent || "").trim();
45
+ if (current !== whenOn && current !== whenOff) return;
46
+ el.textContent = isOn ? whenOn : whenOff;
47
+ }
48
+
49
+ function toggleCycle(el, attr, own) {
50
+ var other = (el.getAttribute(attr) || "").trim();
51
+ if (!THEME_LABELS[other] || other === own) other = "light";
52
+ return [other, own];
53
+ }
54
+
55
+ function nextTheme(cycle, current) {
56
+ var idx = cycle.indexOf(current);
57
+ return idx === -1 ? cycle[cycle.length - 1] : cycle[(idx + 1) % cycle.length];
58
+ }
59
+
60
+ function syncToggles() {
61
+ var current = getTheme();
62
+ document.querySelectorAll("[data-ar-theme-toggle]").forEach((el) => {
63
+ if (el.matches('input[type="checkbox"]')) {
64
+ el.checked = current === "dark";
65
+ } else {
66
+ el.setAttribute("aria-pressed", String(current === "dark"));
67
+ }
68
+ });
69
+ document.querySelectorAll("[data-ar-neo-toggle]").forEach((el) => {
70
+ var isNeo = current === "neo";
71
+ if (el.matches('input[type="checkbox"]')) {
72
+ el.checked = isNeo;
73
+ } else {
74
+ el.setAttribute("aria-pressed", String(isNeo));
75
+ var cycle = toggleCycle(el, "data-ar-neo-toggle", "neo");
76
+ setToggleLabel(el, THEME_LABELS[cycle[0]], THEME_LABELS[cycle[1]], isNeo);
77
+ }
78
+ });
79
+ document.querySelectorAll("[data-ar-pixel-toggle]").forEach((el) => {
80
+ var isPixel = current === "pixel";
81
+ if (el.matches('input[type="checkbox"]')) {
82
+ el.checked = isPixel;
83
+ } else {
84
+ el.setAttribute("aria-pressed", String(isPixel));
85
+ var cycle = toggleCycle(el, "data-ar-pixel-toggle", "pixel");
86
+ setToggleLabel(el, THEME_LABELS[cycle[0]], THEME_LABELS[cycle[1]], isPixel);
87
+ }
88
+ });
89
+ document.querySelectorAll("[data-ar-brutalist-toggle]").forEach((el) => {
90
+ var isBrutalist = current === "brutalist";
91
+ if (el.matches('input[type="checkbox"]')) {
92
+ el.checked = isBrutalist;
93
+ } else {
94
+ el.setAttribute("aria-pressed", String(isBrutalist));
95
+ var cycle = toggleCycle(el, "data-ar-brutalist-toggle", "brutalist");
96
+ setToggleLabel(el, THEME_LABELS[cycle[0]], THEME_LABELS[cycle[1]], isBrutalist);
97
+ }
98
+ });
99
+ }
100
+
101
+ function initThemeToggle() {
102
+ document.addEventListener("click", (e) => {
103
+ var toggle = e.target.closest("[data-ar-theme-toggle]");
104
+ if (!toggle) return;
105
+ var current = getTheme() || "light";
106
+ var next = nextTheme(toggleCycle(toggle, "data-ar-theme-toggle", "dark"), current);
107
+ setTheme(next);
108
+ localStorage.setItem(STORAGE_KEY, next);
109
+ syncToggles();
110
+ });
111
+ }
112
+
113
+ function initNeoToggle() {
114
+ document.addEventListener("click", (e) => {
115
+ var toggle = e.target.closest("[data-ar-neo-toggle]");
116
+ if (!toggle) return;
117
+ var current = getTheme() || "light";
118
+ var next = nextTheme(toggleCycle(toggle, "data-ar-neo-toggle", "neo"), current);
119
+ setTheme(next);
120
+ localStorage.setItem(STORAGE_KEY, next);
121
+ syncToggles();
122
+ });
123
+ }
124
+
125
+ function initPixelToggle() {
126
+ document.addEventListener("click", (e) => {
127
+ var toggle = e.target.closest("[data-ar-pixel-toggle]");
128
+ if (!toggle) return;
129
+ var current = getTheme() || "light";
130
+ var next = nextTheme(toggleCycle(toggle, "data-ar-pixel-toggle", "pixel"), current);
131
+ setTheme(next);
132
+ localStorage.setItem(STORAGE_KEY, next);
133
+ syncToggles();
134
+ });
135
+ }
136
+
137
+ function initBrutalistToggle() {
138
+ document.addEventListener("click", (e) => {
139
+ var toggle = e.target.closest("[data-ar-brutalist-toggle]");
140
+ if (!toggle) return;
141
+ var current = getTheme() || "light";
142
+ var next = nextTheme(toggleCycle(toggle, "data-ar-brutalist-toggle", "brutalist"), current);
143
+ setTheme(next);
144
+ localStorage.setItem(STORAGE_KEY, next);
145
+ syncToggles();
146
+ });
147
+ }
148
+
149
+ function initModals() {
150
+ document.querySelectorAll("[data-ar-open]").forEach((opener) => {
151
+ opener.addEventListener("click", (e) => {
152
+ e.preventDefault();
153
+ var target = document.getElementById(
154
+ opener.getAttribute("data-ar-open"),
155
+ );
156
+ if (target && typeof target.showModal === "function")
157
+ target.showModal();
158
+ });
159
+ });
160
+ document.querySelectorAll("[data-ar-close]").forEach((closer) => {
161
+ closer.addEventListener("click", () => {
162
+ var modal = closer.closest("dialog");
163
+ if (modal && typeof modal.close === "function") modal.close();
164
+ });
165
+ });
166
+ document
167
+ .querySelectorAll("dialog[data-ar-backdrop-close]")
168
+ .forEach((modal) => {
169
+ modal.addEventListener("click", (e) => {
170
+ if (e.target === modal) modal.close();
171
+ });
172
+ });
173
+ }
174
+
175
+ var SIDEBAR_FOCUSABLE =
176
+ 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]),' +
177
+ ' textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
178
+
179
+ var SIDEBAR_BREAKPOINTS = { "ar-sidebar-bp-md": 768 };
180
+ var SIDEBAR_DEFAULT_BP = 1024;
181
+ var SIDEBAR_MEDIA = {};
182
+ function sidebarMedia(px) {
183
+ if (!SIDEBAR_MEDIA[px]) {
184
+ SIDEBAR_MEDIA[px] = window.matchMedia("(min-width: " + px + "px)");
185
+ }
186
+ return SIDEBAR_MEDIA[px];
187
+ }
188
+ function sidebarBreakpoint(sidebar) {
189
+ var px = SIDEBAR_DEFAULT_BP;
190
+ if (sidebar) {
191
+ Object.keys(SIDEBAR_BREAKPOINTS).forEach(function (name) {
192
+ if (sidebar.classList.contains(name)) px = SIDEBAR_BREAKPOINTS[name];
193
+ });
194
+ }
195
+ return px;
196
+ }
197
+ function isPersistentSidebar(sidebar) {
198
+ if (!sidebar || !sidebarMedia(sidebarBreakpoint(sidebar)).matches)
199
+ return false;
200
+ return (
201
+ sidebar.classList.contains("ar-sidebar-responsive") ||
202
+ sidebar.classList.contains("ar-sidebar-compact") ||
203
+ sidebar.classList.contains("ar-sidebar-nav")
204
+ );
205
+ }
206
+ function sidebarMediaAll() {
207
+ return [SIDEBAR_DEFAULT_BP]
208
+ .concat(
209
+ Object.keys(SIDEBAR_BREAKPOINTS).map(function (name) {
210
+ return SIDEBAR_BREAKPOINTS[name];
211
+ }),
212
+ )
213
+ .map(sidebarMedia);
214
+ }
215
+
216
+ function setSidebarState(sidebar, open) {
217
+ if (!sidebar) return;
218
+ sidebar.classList.toggle("ar-sidebar-is-open", !!open);
219
+ sidebar.classList.toggle("ar-sidebar-is-close", !open);
220
+ }
221
+
222
+ function trapFocus(panel, e) {
223
+ if (e.key !== "Tab") return;
224
+ var items = Array.prototype.filter.call(
225
+ panel.querySelectorAll(SIDEBAR_FOCUSABLE),
226
+ (el) => el.getClientRects().length > 0,
227
+ );
228
+ if (!items.length) {
229
+ e.preventDefault();
230
+ return;
231
+ }
232
+ var first = items[0];
233
+ var last = items[items.length - 1];
234
+ if (!panel.contains(document.activeElement)) {
235
+ e.preventDefault();
236
+ first.focus();
237
+ return;
238
+ }
239
+ if (e.shiftKey && document.activeElement === first) {
240
+ e.preventDefault();
241
+ last.focus();
242
+ return;
243
+ }
244
+ if (!e.shiftKey && document.activeElement === last) {
245
+ e.preventDefault();
246
+ first.focus();
247
+ }
248
+ }
249
+
250
+ function syncSidebar(cb) {
251
+ if (!cb) return;
252
+ var sidebar = cb.closest(".ar-sidebar");
253
+ if (!sidebar) return;
254
+ var panel = sidebar.querySelector(".ar-sidebar-panel");
255
+ var persistent = isPersistentSidebar(sidebar);
256
+ setSidebarState(sidebar, cb.checked || persistent);
257
+ if (persistent) {
258
+ cb.checked = false;
259
+ cb._arOpener = null;
260
+ if (panel) {
261
+ panel.removeAttribute("role");
262
+ panel.removeAttribute("aria-modal");
263
+ }
264
+ document.body.style.overflow = "";
265
+ document
266
+ .querySelectorAll('[data-ar-sidebar-toggle="' + cb.id + '"]')
267
+ .forEach((btn) => btn.setAttribute("aria-expanded", "false"));
268
+ return;
269
+ }
270
+ if (cb.checked && !cb._arOpener) {
271
+ var active = document.activeElement;
272
+ if (active && active !== document.body && !sidebar.contains(active))
273
+ cb._arOpener = active;
274
+ }
275
+ if (panel) {
276
+ if (cb.checked) {
277
+ panel.setAttribute("role", "dialog");
278
+ panel.setAttribute("aria-modal", "true");
279
+ panel.focus();
280
+ } else {
281
+ panel.removeAttribute("role");
282
+ panel.removeAttribute("aria-modal");
283
+ }
284
+ }
285
+ document.body.style.overflow = cb.checked ? "hidden" : "";
286
+ document
287
+ .querySelectorAll('[data-ar-sidebar-toggle="' + cb.id + '"]')
288
+ .forEach((btn) => {
289
+ btn.setAttribute("aria-expanded", cb.checked ? "true" : "false");
290
+ });
291
+ if (!cb.checked) {
292
+ var restore = cb._arOpener;
293
+ cb._arOpener = null;
294
+ if (restore && document.contains(restore)) restore.focus();
295
+ }
296
+ }
297
+
298
+ function initSidebars() {
299
+ document.querySelectorAll(".ar-sidebar-toggle").forEach((cb) => {
300
+ var sidebar = cb.closest(".ar-sidebar");
301
+ if (!sidebar) return;
302
+ var panel = sidebar.querySelector(".ar-sidebar-panel");
303
+ if (!panel) return;
304
+ panel.setAttribute("tabindex", "-1");
305
+ setSidebarState(sidebar, cb.checked || isPersistentSidebar(sidebar));
306
+ cb.addEventListener("change", () => syncSidebar(cb));
307
+ panel.addEventListener("keydown", (e) => {
308
+ if (e.key === "Escape" && cb.checked) {
309
+ cb.checked = false;
310
+ syncSidebar(cb);
311
+ return;
312
+ }
313
+ if (isPersistentSidebar(sidebar)) return;
314
+ trapFocus(panel, e);
315
+ });
316
+ panel.querySelectorAll("a[href]").forEach((link) => {
317
+ link.addEventListener("click", () => {
318
+ if (!cb.checked) return;
319
+ cb.checked = false;
320
+ syncSidebar(cb);
321
+ });
322
+ });
323
+ document
324
+ .querySelectorAll('[data-ar-sidebar-toggle="' + cb.id + '"]')
325
+ .forEach((btn) => {
326
+ btn.setAttribute("aria-controls", cb.id);
327
+ btn.setAttribute("aria-expanded", cb.checked ? "true" : "false");
328
+ });
329
+ });
330
+
331
+ document.querySelectorAll("[data-ar-sidebar-toggle]").forEach((btn) => {
332
+ btn.addEventListener("click", () => {
333
+ var id = btn.getAttribute("data-ar-sidebar-toggle");
334
+ var cb = document.getElementById(id);
335
+ if (!cb) {
336
+ console.error(
337
+ '[ArekUI] data-ar-sidebar-toggle="' + id + '" matched no element',
338
+ );
339
+ return;
340
+ }
341
+ cb._arOpener = btn;
342
+ cb.checked = !cb.checked;
343
+ syncSidebar(cb);
344
+ });
345
+ });
346
+
347
+ document.querySelectorAll("[data-ar-sidebar-close]").forEach((closer) => {
348
+ closer.addEventListener("click", () => {
349
+ var sidebar = closer.closest(".ar-sidebar");
350
+ var cb = sidebar && sidebar.querySelector(".ar-sidebar-toggle");
351
+ if (!cb) return;
352
+ cb.checked = false;
353
+ syncSidebar(cb);
354
+ });
355
+ });
356
+
357
+ var onBreakpoint = () => {
358
+ document.querySelectorAll(".ar-sidebar-toggle").forEach((cb) => {
359
+ var sidebar = cb.closest(".ar-sidebar");
360
+ if (!sidebar) return;
361
+ setSidebarState(sidebar, cb.checked || isPersistentSidebar(sidebar));
362
+ if (cb.checked) syncSidebar(cb);
363
+ });
364
+ };
365
+ sidebarMediaAll().forEach((mql) => {
366
+ if (mql.addEventListener) mql.addEventListener("change", onBreakpoint);
367
+ else if (mql.addListener) mql.addListener(onBreakpoint);
368
+ });
369
+ }
370
+
371
+ function activateTab(tab, group) {
372
+ var panelId = tab.getAttribute("data-ar-tab");
373
+ group.querySelectorAll("[data-ar-tab]").forEach((t) => {
374
+ var isOn = t === tab;
375
+ t.classList.toggle("ar-tab-active", isOn);
376
+ t.setAttribute("aria-selected", String(isOn));
377
+ t.setAttribute("tabindex", isOn ? "0" : "-1");
378
+ });
379
+ var groupPanel = group.getAttribute("data-ar-tabs-panel");
380
+ if (groupPanel) {
381
+ var scope = group.parentElement || document;
382
+ var scoped = scope.querySelectorAll("[" + groupPanel + "]");
383
+ (scoped.length ? scoped : document.querySelectorAll("[" + groupPanel + "]")).forEach((p) => {
384
+ p.style.display = p.id === panelId ? "" : "none";
385
+ });
386
+ }
387
+ }
388
+
389
+ function initTabs() {
390
+ document.querySelectorAll(".ar-tabs").forEach((group) => {
391
+ group.setAttribute("role", "tablist");
392
+ });
393
+ document.querySelectorAll("[data-ar-tab]").forEach((tab) => {
394
+ var panelId = tab.getAttribute("data-ar-tab");
395
+ var panel = document.getElementById(panelId);
396
+ if (panel && !tab.id) tab.id = panelId + "-tab";
397
+ tab.setAttribute("role", "tab");
398
+ if (panel) {
399
+ tab.setAttribute("aria-controls", panelId);
400
+ panel.setAttribute("role", "tabpanel");
401
+ panel.setAttribute("aria-labelledby", tab.id);
402
+ }
403
+ var isActive = tab.classList.contains("ar-tab-active");
404
+ tab.setAttribute("aria-selected", String(isActive));
405
+ tab.setAttribute("tabindex", isActive ? "0" : "-1");
406
+
407
+ tab.addEventListener("click", () => {
408
+ var group = tab.closest(".ar-tabs");
409
+ if (group) activateTab(tab, group);
410
+ });
411
+
412
+ tab.addEventListener("keydown", (e) => {
413
+ var group = tab.closest(".ar-tabs");
414
+ if (!group) return;
415
+ var tabs = Array.from(group.querySelectorAll("[data-ar-tab]"));
416
+ if (!tabs.length) return;
417
+ var i = tabs.indexOf(tab);
418
+ var target;
419
+ if (e.key === "ArrowRight") target = (i + 1) % tabs.length;
420
+ else if (e.key === "ArrowLeft")
421
+ target = (i - 1 + tabs.length) % tabs.length;
422
+ else if (e.key === "Home") target = 0;
423
+ else if (e.key === "End") target = tabs.length - 1;
424
+ else return;
425
+ e.preventDefault();
426
+ var next = tabs[target];
427
+ activateTab(next, group);
428
+ next.focus();
429
+ });
430
+ });
431
+ }
432
+
433
+ function closeDropdown(dropdown) {
434
+ dropdown.classList.remove("ar-dropdown-open");
435
+ var trigger = dropdown.querySelector(":scope > button, :scope > a");
436
+ if (trigger) {
437
+ trigger.setAttribute("aria-expanded", "false");
438
+ trigger.blur();
439
+ }
440
+ }
441
+
442
+ function openDropdown(dropdown) {
443
+ dropdown.classList.add("ar-dropdown-open");
444
+ var trigger = dropdown.querySelector(":scope > button, :scope > a");
445
+ if (trigger) trigger.setAttribute("aria-expanded", "true");
446
+ }
447
+
448
+ function initDropdowns() {
449
+ document.querySelectorAll(".ar-dropdown").forEach((dropdown) => {
450
+ var content = dropdown.querySelector(".ar-dropdown-content");
451
+ if (!content) return;
452
+ var trigger = dropdown.querySelector(":scope > button, :scope > a");
453
+ if (trigger) trigger.setAttribute("aria-expanded", "false");
454
+
455
+ dropdown.addEventListener("click", (e) => {
456
+ if (content.contains(e.target)) {
457
+ closeDropdown(dropdown);
458
+ return;
459
+ }
460
+ if (dropdown.classList.contains("ar-dropdown-open")) {
461
+ closeDropdown(dropdown);
462
+ } else {
463
+ openDropdown(dropdown);
464
+ }
465
+ });
466
+ });
467
+
468
+ document.addEventListener("click", (e) => {
469
+ document
470
+ .querySelectorAll(".ar-dropdown.ar-dropdown-open")
471
+ .forEach((dd) => {
472
+ if (!dd.contains(e.target)) closeDropdown(dd);
473
+ });
474
+ });
475
+
476
+ document.addEventListener("keydown", (e) => {
477
+ if (e.key === "Escape") {
478
+ document
479
+ .querySelectorAll(".ar-dropdown.ar-dropdown-open")
480
+ .forEach(closeDropdown);
481
+ }
482
+ });
483
+ }
484
+
485
+ function initAccordion() {
486
+ document.querySelectorAll(".ar-accordion details").forEach((d) => {
487
+ var first = d.querySelector("summary");
488
+ if (first)
489
+ first.addEventListener("click", () => {
490
+ var parent = d.closest(".ar-accordion");
491
+ if (!parent) return;
492
+ if (parent.getAttribute("data-ar-exclusive") === null) return;
493
+ parent.querySelectorAll("details[open]").forEach((other) => {
494
+ if (other !== d) other.removeAttribute("open");
495
+ });
496
+ });
497
+ });
498
+ }
499
+
500
+ function scrollCarousel(carousel, direction) {
501
+ if (!carousel) return;
502
+ var amount = carousel.clientWidth || 300;
503
+ var reduce =
504
+ window.matchMedia &&
505
+ window.matchMedia("(prefers-reduced-motion: reduce)").matches;
506
+ carousel.scrollBy({
507
+ left: direction * amount,
508
+ behavior: reduce ? "auto" : "smooth",
509
+ });
510
+ }
511
+
512
+ function findCarousel(btn, attrName) {
513
+ var id = btn.getAttribute(attrName);
514
+ if (id) return document.getElementById(id);
515
+ var frame = btn.closest(".ar-carousel-frame") || btn.parentElement;
516
+ return frame ? frame.querySelector(".ar-carousel") : null;
517
+ }
518
+
519
+ function initCarouselControls() {
520
+ document.querySelectorAll("[data-ar-carousel-prev]").forEach((btn) => {
521
+ btn.addEventListener("click", () => {
522
+ scrollCarousel(findCarousel(btn, "data-ar-carousel-prev"), -1);
523
+ });
524
+ });
525
+ document.querySelectorAll("[data-ar-carousel-next]").forEach((btn) => {
526
+ btn.addEventListener("click", () => {
527
+ scrollCarousel(findCarousel(btn, "data-ar-carousel-next"), 1);
528
+ });
529
+ });
530
+ }
531
+
532
+ var toastContainers = {};
533
+
534
+ function getToastContainer(position) {
535
+ if (toastContainers[position]) return toastContainers[position];
536
+ var container = document.createElement("div");
537
+ container.className = "ar-toast-container";
538
+ container.setAttribute("data-ar-toast-position", position);
539
+ document.body.appendChild(container);
540
+ toastContainers[position] = container;
541
+ return container;
542
+ }
543
+
544
+ function toast(message, options) {
545
+ var opts = options || {};
546
+ var type = opts.type || "info";
547
+ var duration = typeof opts.duration === "number" ? opts.duration : 4000;
548
+ var position = opts.position || "top-right";
549
+ var closable = opts.closable !== false;
550
+ var icon = opts.icon || null;
551
+
552
+ var container = getToastContainer(position);
553
+ var el = document.createElement("div");
554
+ el.className = "ar-toast" + (type ? " ar-toast-" + type : "");
555
+ el.style.position = "relative";
556
+
557
+ if (icon) {
558
+ var iconEl = document.createElement("span");
559
+ iconEl.className = "ar-toast-icon";
560
+ iconEl.textContent = icon;
561
+ el.appendChild(iconEl);
562
+ }
563
+
564
+ var msgEl = document.createElement("span");
565
+ msgEl.className = "ar-toast-message";
566
+ msgEl.textContent = message;
567
+ el.appendChild(msgEl);
568
+
569
+ if (closable) {
570
+ var closeBtn = document.createElement("button");
571
+ closeBtn.className = "ar-toast-close";
572
+ closeBtn.textContent = "\u2715";
573
+ closeBtn.setAttribute("aria-label", "Close");
574
+ closeBtn.addEventListener("click", () => {
575
+ dismissToast(el);
576
+ });
577
+ el.appendChild(closeBtn);
578
+ }
579
+
580
+ if (duration > 0) {
581
+ var progress = document.createElement("div");
582
+ progress.className = "ar-toast-progress";
583
+ progress.style.animationDuration = duration + "ms";
584
+ el.appendChild(progress);
585
+ }
586
+
587
+ container.appendChild(el);
588
+
589
+ var timer;
590
+ if (duration > 0) {
591
+ timer = setTimeout(() => {
592
+ dismissToast(el);
593
+ }, duration);
594
+ }
595
+
596
+ el.addEventListener("mouseenter", () => {
597
+ if (timer) clearTimeout(timer);
598
+ if (el.querySelector(".ar-toast-progress")) {
599
+ el.querySelector(".ar-toast-progress").style.animationPlayState =
600
+ "paused";
601
+ }
602
+ });
603
+ el.addEventListener("mouseleave", () => {
604
+ if (duration > 0) {
605
+ var remaining = duration * 0.3;
606
+ timer = setTimeout(() => {
607
+ dismissToast(el);
608
+ }, remaining);
609
+ if (el.querySelector(".ar-toast-progress")) {
610
+ el.querySelector(".ar-toast-progress").style.animationPlayState =
611
+ "running";
612
+ }
613
+ }
614
+ });
615
+
616
+ return el;
617
+ }
618
+
619
+ function dismissToast(el) {
620
+ if (el.classList.contains("ar-toast-out")) return;
621
+ el.classList.add("ar-toast-out");
622
+ el.addEventListener("animationend", () => {
623
+ el.remove();
624
+ });
625
+ }
626
+
627
+ function initRatings() {
628
+ document.querySelectorAll("[data-ar-rating]").forEach((group) => {
629
+ var inputs = group.querySelectorAll("input");
630
+ inputs.forEach((input) => {
631
+ input.addEventListener("change", () => {
632
+ var event = new CustomEvent("ar-rating-change", {
633
+ detail: { value: Number(input.value) },
634
+ bubbles: true,
635
+ });
636
+ group.dispatchEvent(event);
637
+ });
638
+ });
639
+ });
640
+ }
641
+
642
+ function getRating(container) {
643
+ var checked = container.querySelector("input:checked");
644
+ return checked ? Number(checked.value) : 0;
645
+ }
646
+
647
+ function setRating(container, value) {
648
+ var input = container.querySelector('input[value="' + value + '"]');
649
+ if (input) {
650
+ input.checked = true;
651
+ input.dispatchEvent(new Event("change"));
652
+ }
653
+ }
654
+
655
+ function initPopovers() {
656
+ document.addEventListener("click", (e) => {
657
+ var trigger = e.target.closest("[data-ar-popover]");
658
+ if (trigger) {
659
+ e.preventDefault();
660
+ var id = trigger.getAttribute("data-ar-popover");
661
+ var popover = id
662
+ ? document.getElementById(id)
663
+ : trigger.querySelector(".ar-popover-content");
664
+ if (!popover) return;
665
+ var wrapper =
666
+ popover.closest(".ar-popover") || trigger.closest(".ar-popover");
667
+ if (!wrapper) return;
668
+ document.querySelectorAll(".ar-popover-open").forEach((p) => {
669
+ if (p !== wrapper) p.classList.remove("ar-popover-open");
670
+ });
671
+ wrapper.classList.toggle("ar-popover-open");
672
+ return;
673
+ }
674
+ if (!e.target.closest(".ar-popover")) {
675
+ document.querySelectorAll(".ar-popover-open").forEach((p) => {
676
+ p.classList.remove("ar-popover-open");
677
+ });
678
+ }
679
+ });
680
+ document.addEventListener("keydown", (e) => {
681
+ if (e.key === "Escape") {
682
+ document.querySelectorAll(".ar-popover-open").forEach((p) => {
683
+ p.classList.remove("ar-popover-open");
684
+ });
685
+ }
686
+ });
687
+ }
688
+
689
+ function openPopover(id) {
690
+ var el = document.getElementById(id);
691
+ if (el) {
692
+ var wrapper = el.closest(".ar-popover");
693
+ if (wrapper) wrapper.classList.add("ar-popover-open");
694
+ }
695
+ }
696
+
697
+ function closePopover(id) {
698
+ var el = document.getElementById(id);
699
+ if (el) {
700
+ var wrapper = el.closest(".ar-popover");
701
+ if (wrapper) wrapper.classList.remove("ar-popover-open");
702
+ }
703
+ }
704
+
705
+ function initFileUploads() {
706
+ document.querySelectorAll(".ar-file-upload").forEach((zone) => {
707
+ var input = zone.querySelector('input[type="file"]');
708
+ if (!input) return;
709
+ ["dragenter", "dragover"].forEach((evt) => {
710
+ zone.addEventListener(evt, (e) => {
711
+ e.preventDefault();
712
+ zone.classList.add("ar-file-upload-dragover");
713
+ });
714
+ });
715
+ ["dragleave", "drop"].forEach((evt) => {
716
+ zone.addEventListener(evt, (e) => {
717
+ e.preventDefault();
718
+ zone.classList.remove("ar-file-upload-dragover");
719
+ });
720
+ });
721
+ input.addEventListener("change", () => {
722
+ var event = new CustomEvent("ar-file-change", {
723
+ detail: { files: input.files },
724
+ bubbles: true,
725
+ });
726
+ zone.dispatchEvent(event);
727
+ });
728
+ });
729
+ }
730
+
731
+ function initScrollTop() {
732
+ var btns = document.querySelectorAll("[data-ar-scroll-top]");
733
+ if (!btns.length) return;
734
+
735
+ function toggle() {
736
+ var show = window.scrollY > 300;
737
+ btns.forEach((btn) => {
738
+ btn.classList.toggle("ar-scroll-top-visible", show);
739
+ });
740
+ }
741
+
742
+ window.addEventListener("scroll", toggle, { passive: true });
743
+ toggle();
744
+
745
+ btns.forEach((btn) => {
746
+ btn.addEventListener("click", () => {
747
+ window.scrollTo({ top: 0, behavior: "smooth" });
748
+ });
749
+ });
750
+ }
751
+
752
+ function initReveal() {
753
+ var els = document.querySelectorAll("[data-ar-reveal]");
754
+ if (!els.length) return;
755
+ if (!("IntersectionObserver" in window)) {
756
+ els.forEach((el) => el.classList.add("ar-reveal", "ar-reveal-in"));
757
+ return;
758
+ }
759
+ var io = new IntersectionObserver(
760
+ (entries) => {
761
+ entries.forEach((entry) => {
762
+ if (!entry.isIntersecting) return;
763
+ entry.target.classList.add("ar-reveal-in");
764
+ io.unobserve(entry.target);
765
+ });
766
+ },
767
+ { rootMargin: "0px 0px -10% 0px", threshold: 0 },
768
+ );
769
+ els.forEach((el) => {
770
+ el.classList.add("ar-reveal");
771
+ io.observe(el);
772
+ });
773
+ }
774
+
775
+ function init() {
776
+ if (document.readyState === "loading") {
777
+ document.addEventListener("DOMContentLoaded", ready);
778
+ } else {
779
+ ready();
780
+ }
781
+ }
782
+
783
+ function ready() {
784
+ if (!getTheme()) initTheme();
785
+ syncToggles();
786
+ initThemeToggle();
787
+ initNeoToggle();
788
+ initPixelToggle();
789
+ initBrutalistToggle();
790
+ initModals();
791
+ initSidebars();
792
+ initTabs();
793
+ initDropdowns();
794
+ initAccordion();
795
+ initRatings();
796
+ initPopovers();
797
+ initFileUploads();
798
+ initScrollTop();
799
+ initCarouselControls();
800
+ initReveal();
801
+ }
802
+
803
+ window.ArekUI = {
804
+ setTheme: setTheme,
805
+ getTheme: getTheme,
806
+ initTheme: initTheme,
807
+ init: init,
808
+ toast: toast,
809
+ dismissToast: dismissToast,
810
+ getRating: getRating,
811
+ setRating: setRating,
812
+ openPopover: openPopover,
813
+ closePopover: closePopover,
814
+ };
815
+
816
+ init();
817
+ })();