@lanrenbang/basecoat-ultra 0.1.2

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 (55) hide show
  1. package/CHANGELOG-cn.md +54 -0
  2. package/CHANGELOG.md +54 -0
  3. package/LICENSE +21 -0
  4. package/README-cn.md +186 -0
  5. package/README.md +173 -0
  6. package/dist/css/basecoat.cdn.css +7389 -0
  7. package/dist/css/basecoat.cdn.min.css +2 -0
  8. package/dist/css/basecoat.css +1797 -0
  9. package/dist/css/datepicker.css +382 -0
  10. package/dist/css/datepicker.min.css +1 -0
  11. package/dist/css/resizable.css +96 -0
  12. package/dist/css/resizable.min.css +1 -0
  13. package/dist/js/accordion.js +20 -0
  14. package/dist/js/accordion.min.js +13 -0
  15. package/dist/js/all.js +17 -0
  16. package/dist/js/all.min.js +17 -0
  17. package/dist/js/basecoat.js +75 -0
  18. package/dist/js/basecoat.min.js +56 -0
  19. package/dist/js/carousel.js +104 -0
  20. package/dist/js/carousel.min.js +41 -0
  21. package/dist/js/catppuccin-theme-switcher.js +136 -0
  22. package/dist/js/catppuccin-theme-switcher.min.js +73 -0
  23. package/dist/js/command.js +132 -0
  24. package/dist/js/command.min.js +76 -0
  25. package/dist/js/datepicker.js +2367 -0
  26. package/dist/js/datepicker.min.js +1422 -0
  27. package/dist/js/dialog.js +20 -0
  28. package/dist/js/dialog.min.js +11 -0
  29. package/dist/js/dropdown-menu.js +148 -0
  30. package/dist/js/dropdown-menu.min.js +75 -0
  31. package/dist/js/input-otp.js +94 -0
  32. package/dist/js/input-otp.min.js +38 -0
  33. package/dist/js/lighting.js +80 -0
  34. package/dist/js/lighting.min.js +44 -0
  35. package/dist/js/popover.js +72 -0
  36. package/dist/js/popover.min.js +34 -0
  37. package/dist/js/resizable.js +534 -0
  38. package/dist/js/resizable.min.js +284 -0
  39. package/dist/js/select.js +246 -0
  40. package/dist/js/select.min.js +131 -0
  41. package/dist/js/sheet.js +85 -0
  42. package/dist/js/sheet.min.js +40 -0
  43. package/dist/js/sidebar.js +87 -0
  44. package/dist/js/sidebar.min.js +53 -0
  45. package/dist/js/slider.js +18 -0
  46. package/dist/js/slider.min.js +10 -0
  47. package/dist/js/tabs.js +53 -0
  48. package/dist/js/tabs.min.js +40 -0
  49. package/dist/js/toast.js +137 -0
  50. package/dist/js/toast.min.js +83 -0
  51. package/dist/js/toggle.js +36 -0
  52. package/dist/js/toggle.min.js +20 -0
  53. package/dist/theme/catppuccin/index.css +448 -0
  54. package/dist/theme/catppuccin/index.min.css +1 -0
  55. package/package.json +46 -0
@@ -0,0 +1,85 @@
1
+ (() => {
2
+ const toggleSheet = (trigger) => {
3
+ const targetId = trigger.getAttribute("aria-controls") || trigger.dataset.target;
4
+ if (!targetId) return;
5
+ const sheet = document.getElementById(targetId);
6
+ if (!sheet) return;
7
+ const isOpen = sheet.getAttribute("aria-hidden") === "false";
8
+ sheet.querySelector(".sheet-content, .drawer-content");
9
+ if (isOpen) {
10
+ closeSheet(sheet);
11
+ } else {
12
+ openSheet(sheet, trigger);
13
+ }
14
+ };
15
+ const openSheet = (sheet, trigger) => {
16
+ sheet.setAttribute("aria-hidden", "false");
17
+ sheet.offsetHeight;
18
+ const content = sheet.querySelector(".sheet-content, .drawer-content");
19
+ if (content) {
20
+ content.dataset.state = "open";
21
+ }
22
+ if (trigger) {
23
+ trigger.setAttribute("aria-expanded", "true");
24
+ sheet.dataset.triggerId = trigger.id || "";
25
+ }
26
+ document.body.style.overflow = "hidden";
27
+ };
28
+ const closeSheet = (sheet) => {
29
+ const content = sheet.querySelector(".sheet-content, .drawer-content");
30
+ if (content) {
31
+ content.dataset.state = "closed";
32
+ const transitionDuration = parseFloat(window.getComputedStyle(content).transitionDuration) * 1e3 || 300;
33
+ setTimeout(() => {
34
+ if (content.dataset.state === "closed") {
35
+ sheet.setAttribute("aria-hidden", "true");
36
+ document.body.style.overflow = "";
37
+ if (sheet.dataset.triggerId) {
38
+ const trigger = document.getElementById(sheet.dataset.triggerId);
39
+ trigger?.focus();
40
+ }
41
+ }
42
+ }, transitionDuration);
43
+ } else {
44
+ sheet.setAttribute("aria-hidden", "true");
45
+ document.body.style.overflow = "";
46
+ }
47
+ const triggerId = sheet.dataset.triggerId;
48
+ if (triggerId) {
49
+ const trigger = document.getElementById(triggerId);
50
+ trigger?.setAttribute("aria-expanded", "false");
51
+ }
52
+ };
53
+ document.addEventListener("click", (e) => {
54
+ const trigger = e.target.closest('[data-toggle="sheet"], [data-toggle="drawer"]');
55
+ if (trigger) {
56
+ e.preventDefault();
57
+ if (!trigger.id) {
58
+ trigger.id = "trigger-" + Math.random().toString(36).substr(2, 9);
59
+ }
60
+ toggleSheet(trigger);
61
+ }
62
+ });
63
+ document.addEventListener("click", (e) => {
64
+ if (e.target.matches(".sheet, .drawer")) {
65
+ closeSheet(e.target);
66
+ }
67
+ });
68
+ document.addEventListener("keydown", (e) => {
69
+ if (e.key === "Escape") {
70
+ const openSheets = document.querySelectorAll('.sheet[aria-hidden="false"], .drawer[aria-hidden="false"]');
71
+ openSheets.forEach(closeSheet);
72
+ }
73
+ });
74
+ document.addEventListener("click", (e) => {
75
+ const closeBtn = e.target.closest("[data-close]");
76
+ if (closeBtn) {
77
+ const sheet = closeBtn.closest(".sheet, .drawer");
78
+ if (sheet) {
79
+ closeSheet(sheet);
80
+ }
81
+ }
82
+ });
83
+ if (!window.basecoat) window.basecoat = {};
84
+ window.basecoat.sheet = { open: openSheet, close: closeSheet };
85
+ })();
@@ -0,0 +1,40 @@
1
+ (() => {
2
+ const d = (t) => {
3
+ const e = t.getAttribute("aria-controls") || t.dataset.target;
4
+ if (!e) return;
5
+ const n = document.getElementById(e);
6
+ if (!n) return;
7
+ const a = n.getAttribute("aria-hidden") === "false";
8
+ n.querySelector(".sheet-content, .drawer-content"), a ? o(n) : r(n, t);
9
+ }, r = (t, e) => {
10
+ t.setAttribute("aria-hidden", "false"), t.offsetHeight;
11
+ const n = t.querySelector(".sheet-content, .drawer-content");
12
+ n && (n.dataset.state = "open"), e && (e.setAttribute("aria-expanded", "true"), t.dataset.triggerId = e.id || ""), document.body.style.overflow = "hidden";
13
+ }, o = (t) => {
14
+ const e = t.querySelector(".sheet-content, .drawer-content");
15
+ if (e) {
16
+ e.dataset.state = "closed";
17
+ const a = parseFloat(window.getComputedStyle(e).transitionDuration) * 1e3 || 300;
18
+ setTimeout(() => {
19
+ e.dataset.state === "closed" && (t.setAttribute("aria-hidden", "true"), document.body.style.overflow = "", t.dataset.triggerId && document.getElementById(t.dataset.triggerId)?.focus());
20
+ }, a);
21
+ } else
22
+ t.setAttribute("aria-hidden", "true"), document.body.style.overflow = "";
23
+ const n = t.dataset.triggerId;
24
+ n && document.getElementById(n)?.setAttribute("aria-expanded", "false");
25
+ };
26
+ document.addEventListener("click", (t) => {
27
+ const e = t.target.closest('[data-toggle="sheet"], [data-toggle="drawer"]');
28
+ e && (t.preventDefault(), e.id || (e.id = "trigger-" + Math.random().toString(36).substr(2, 9)), d(e));
29
+ }), document.addEventListener("click", (t) => {
30
+ t.target.matches(".sheet, .drawer") && o(t.target);
31
+ }), document.addEventListener("keydown", (t) => {
32
+ t.key === "Escape" && document.querySelectorAll('.sheet[aria-hidden="false"], .drawer[aria-hidden="false"]').forEach(o);
33
+ }), document.addEventListener("click", (t) => {
34
+ const e = t.target.closest("[data-close]");
35
+ if (e) {
36
+ const n = e.closest(".sheet, .drawer");
37
+ n && o(n);
38
+ }
39
+ }), window.basecoat || (window.basecoat = {}), window.basecoat.sheet = { open: r, close: o };
40
+ })();
@@ -0,0 +1,87 @@
1
+ (() => {
2
+ if (!window.history.__basecoatPatched) {
3
+ const originalPushState = window.history.pushState;
4
+ window.history.pushState = function(...args) {
5
+ originalPushState.apply(this, args);
6
+ window.dispatchEvent(new Event("basecoat:locationchange"));
7
+ };
8
+ const originalReplaceState = window.history.replaceState;
9
+ window.history.replaceState = function(...args) {
10
+ originalReplaceState.apply(this, args);
11
+ window.dispatchEvent(new Event("basecoat:locationchange"));
12
+ };
13
+ window.history.__basecoatPatched = true;
14
+ }
15
+ const initSidebar = (sidebarComponent) => {
16
+ const initialOpen = sidebarComponent.dataset.initialOpen !== "false";
17
+ const initialMobileOpen = sidebarComponent.dataset.initialMobileOpen === "true";
18
+ const breakpoint = parseInt(sidebarComponent.dataset.breakpoint) || 768;
19
+ let open = breakpoint > 0 ? window.innerWidth >= breakpoint ? initialOpen : initialMobileOpen : initialOpen;
20
+ const updateCurrentPageLinks = () => {
21
+ const currentPath = window.location.pathname.replace(/\/$/, "");
22
+ sidebarComponent.querySelectorAll("a").forEach((link) => {
23
+ if (link.hasAttribute("data-ignore-current")) return;
24
+ if (link.getAttribute("href") === "#") {
25
+ link.removeAttribute("aria-current");
26
+ return;
27
+ }
28
+ const linkPath = new URL(link.href).pathname.replace(/\/$/, "");
29
+ if (linkPath === currentPath) {
30
+ link.setAttribute("aria-current", "page");
31
+ } else {
32
+ link.removeAttribute("aria-current");
33
+ }
34
+ });
35
+ };
36
+ const updateState = () => {
37
+ sidebarComponent.setAttribute("aria-hidden", !open);
38
+ if (open) {
39
+ sidebarComponent.removeAttribute("inert");
40
+ } else {
41
+ sidebarComponent.setAttribute("inert", "");
42
+ }
43
+ };
44
+ const setState = (state) => {
45
+ open = state;
46
+ updateState();
47
+ };
48
+ const sidebarId = sidebarComponent.id;
49
+ document.addEventListener("basecoat:sidebar", (event) => {
50
+ if (event.detail?.id && event.detail.id !== sidebarId) return;
51
+ switch (event.detail?.action) {
52
+ case "open":
53
+ setState(true);
54
+ break;
55
+ case "close":
56
+ setState(false);
57
+ break;
58
+ default:
59
+ setState(!open);
60
+ break;
61
+ }
62
+ });
63
+ sidebarComponent.addEventListener("click", (event) => {
64
+ const target = event.target;
65
+ const nav = sidebarComponent.querySelector("nav");
66
+ const isMobile = window.innerWidth < breakpoint;
67
+ if (isMobile && (target.closest("a, button") && !target.closest("[data-keep-mobile-sidebar-open]"))) {
68
+ if (document.activeElement) document.activeElement.blur();
69
+ setState(false);
70
+ return;
71
+ }
72
+ if (target === sidebarComponent || nav && !nav.contains(target)) {
73
+ if (document.activeElement) document.activeElement.blur();
74
+ setState(false);
75
+ }
76
+ });
77
+ window.addEventListener("popstate", updateCurrentPageLinks);
78
+ window.addEventListener("basecoat:locationchange", updateCurrentPageLinks);
79
+ updateState();
80
+ updateCurrentPageLinks();
81
+ sidebarComponent.dataset.sidebarInitialized = true;
82
+ sidebarComponent.dispatchEvent(new CustomEvent("basecoat:initialized"));
83
+ };
84
+ if (window.basecoat) {
85
+ window.basecoat.register("sidebar", ".sidebar:not([data-sidebar-initialized])", initSidebar);
86
+ }
87
+ })();
@@ -0,0 +1,53 @@
1
+ (() => {
2
+ if (!window.history.__basecoatPatched) {
3
+ const t = window.history.pushState;
4
+ window.history.pushState = function(...i) {
5
+ t.apply(this, i), window.dispatchEvent(new Event("basecoat:locationchange"));
6
+ };
7
+ const r = window.history.replaceState;
8
+ window.history.replaceState = function(...i) {
9
+ r.apply(this, i), window.dispatchEvent(new Event("basecoat:locationchange"));
10
+ }, window.history.__basecoatPatched = !0;
11
+ }
12
+ const u = (t) => {
13
+ const r = t.dataset.initialOpen !== "false", i = t.dataset.initialMobileOpen === "true", s = parseInt(t.dataset.breakpoint) || 768;
14
+ let c = s > 0 ? window.innerWidth >= s ? r : i : r;
15
+ const o = () => {
16
+ const a = window.location.pathname.replace(/\/$/, "");
17
+ t.querySelectorAll("a").forEach((e) => {
18
+ if (e.hasAttribute("data-ignore-current")) return;
19
+ if (e.getAttribute("href") === "#") {
20
+ e.removeAttribute("aria-current");
21
+ return;
22
+ }
23
+ new URL(e.href).pathname.replace(/\/$/, "") === a ? e.setAttribute("aria-current", "page") : e.removeAttribute("aria-current");
24
+ });
25
+ }, l = () => {
26
+ t.setAttribute("aria-hidden", !c), c ? t.removeAttribute("inert") : t.setAttribute("inert", "");
27
+ }, n = (a) => {
28
+ c = a, l();
29
+ }, w = t.id;
30
+ document.addEventListener("basecoat:sidebar", (a) => {
31
+ if (!(a.detail?.id && a.detail.id !== w))
32
+ switch (a.detail?.action) {
33
+ case "open":
34
+ n(!0);
35
+ break;
36
+ case "close":
37
+ n(!1);
38
+ break;
39
+ default:
40
+ n(!c);
41
+ break;
42
+ }
43
+ }), t.addEventListener("click", (a) => {
44
+ const e = a.target, d = t.querySelector("nav");
45
+ if (window.innerWidth < s && e.closest("a, button") && !e.closest("[data-keep-mobile-sidebar-open]")) {
46
+ document.activeElement && document.activeElement.blur(), n(!1);
47
+ return;
48
+ }
49
+ (e === t || d && !d.contains(e)) && (document.activeElement && document.activeElement.blur(), n(!1));
50
+ }), window.addEventListener("popstate", o), window.addEventListener("basecoat:locationchange", o), l(), o(), t.dataset.sidebarInitialized = !0, t.dispatchEvent(new CustomEvent("basecoat:initialized"));
51
+ };
52
+ window.basecoat && window.basecoat.register("sidebar", ".sidebar:not([data-sidebar-initialized])", u);
53
+ })();
@@ -0,0 +1,18 @@
1
+ (() => {
2
+ const initSlider = (slider) => {
3
+ const update = () => {
4
+ const value = slider.value;
5
+ const min = slider.min ? parseFloat(slider.min) : 0;
6
+ const max = slider.max ? parseFloat(slider.max) : 100;
7
+ const percentage = (value - min) / (max - min) * 100;
8
+ slider.style.setProperty("--slider-value", `${percentage}%`);
9
+ };
10
+ slider.addEventListener("input", update);
11
+ update();
12
+ slider.dataset.sliderInitialized = true;
13
+ slider.dispatchEvent(new CustomEvent("basecoat:initialized"));
14
+ };
15
+ if (window.basecoat) {
16
+ window.basecoat.register("slider", 'input[type="range"].slider:not([data-slider-initialized]), input[type="range"].input:not([data-slider-initialized])', initSlider);
17
+ }
18
+ })();
@@ -0,0 +1,10 @@
1
+ (() => {
2
+ const n = (t) => {
3
+ const a = () => {
4
+ const i = t.value, e = t.min ? parseFloat(t.min) : 0, o = t.max ? parseFloat(t.max) : 100, s = (i - e) / (o - e) * 100;
5
+ t.style.setProperty("--slider-value", `${s}%`);
6
+ };
7
+ t.addEventListener("input", a), a(), t.dataset.sliderInitialized = !0, t.dispatchEvent(new CustomEvent("basecoat:initialized"));
8
+ };
9
+ window.basecoat && window.basecoat.register("slider", 'input[type="range"].slider:not([data-slider-initialized]), input[type="range"].input:not([data-slider-initialized])', n);
10
+ })();
@@ -0,0 +1,53 @@
1
+ (() => {
2
+ const initTabs = (tabsComponent) => {
3
+ const tablist = tabsComponent.querySelector('[role="tablist"]');
4
+ if (!tablist) return;
5
+ const tabs = Array.from(tablist.querySelectorAll('[role="tab"]'));
6
+ const panels = tabs.map((tab) => document.getElementById(tab.getAttribute("aria-controls"))).filter(Boolean);
7
+ const selectTab = (tabToSelect) => {
8
+ tabs.forEach((tab, index) => {
9
+ tab.setAttribute("aria-selected", "false");
10
+ tab.setAttribute("tabindex", "-1");
11
+ if (panels[index]) panels[index].hidden = true;
12
+ });
13
+ tabToSelect.setAttribute("aria-selected", "true");
14
+ tabToSelect.setAttribute("tabindex", "0");
15
+ const activePanel = document.getElementById(tabToSelect.getAttribute("aria-controls"));
16
+ if (activePanel) activePanel.hidden = false;
17
+ };
18
+ tablist.addEventListener("click", (event) => {
19
+ const clickedTab = event.target.closest('[role="tab"]');
20
+ if (clickedTab) selectTab(clickedTab);
21
+ });
22
+ tablist.addEventListener("keydown", (event) => {
23
+ const currentTab = event.target;
24
+ if (!tabs.includes(currentTab)) return;
25
+ let nextTab;
26
+ const currentIndex = tabs.indexOf(currentTab);
27
+ switch (event.key) {
28
+ case "ArrowRight":
29
+ nextTab = tabs[(currentIndex + 1) % tabs.length];
30
+ break;
31
+ case "ArrowLeft":
32
+ nextTab = tabs[(currentIndex - 1 + tabs.length) % tabs.length];
33
+ break;
34
+ case "Home":
35
+ nextTab = tabs[0];
36
+ break;
37
+ case "End":
38
+ nextTab = tabs[tabs.length - 1];
39
+ break;
40
+ default:
41
+ return;
42
+ }
43
+ event.preventDefault();
44
+ selectTab(nextTab);
45
+ nextTab.focus();
46
+ });
47
+ tabsComponent.dataset.tabsInitialized = true;
48
+ tabsComponent.dispatchEvent(new CustomEvent("basecoat:initialized"));
49
+ };
50
+ if (window.basecoat) {
51
+ window.basecoat.register("tabs", ".tabs:not([data-tabs-initialized])", initTabs);
52
+ }
53
+ })();
@@ -0,0 +1,40 @@
1
+ (() => {
2
+ const o = (s) => {
3
+ const n = s.querySelector('[role="tablist"]');
4
+ if (!n) return;
5
+ const t = Array.from(n.querySelectorAll('[role="tab"]')), c = t.map((e) => document.getElementById(e.getAttribute("aria-controls"))).filter(Boolean), l = (e) => {
6
+ t.forEach((a, i) => {
7
+ a.setAttribute("aria-selected", "false"), a.setAttribute("tabindex", "-1"), c[i] && (c[i].hidden = !0);
8
+ }), e.setAttribute("aria-selected", "true"), e.setAttribute("tabindex", "0");
9
+ const r = document.getElementById(e.getAttribute("aria-controls"));
10
+ r && (r.hidden = !1);
11
+ };
12
+ n.addEventListener("click", (e) => {
13
+ const r = e.target.closest('[role="tab"]');
14
+ r && l(r);
15
+ }), n.addEventListener("keydown", (e) => {
16
+ const r = e.target;
17
+ if (!t.includes(r)) return;
18
+ let a;
19
+ const i = t.indexOf(r);
20
+ switch (e.key) {
21
+ case "ArrowRight":
22
+ a = t[(i + 1) % t.length];
23
+ break;
24
+ case "ArrowLeft":
25
+ a = t[(i - 1 + t.length) % t.length];
26
+ break;
27
+ case "Home":
28
+ a = t[0];
29
+ break;
30
+ case "End":
31
+ a = t[t.length - 1];
32
+ break;
33
+ default:
34
+ return;
35
+ }
36
+ e.preventDefault(), l(a), a.focus();
37
+ }), s.dataset.tabsInitialized = !0, s.dispatchEvent(new CustomEvent("basecoat:initialized"));
38
+ };
39
+ window.basecoat && window.basecoat.register("tabs", ".tabs:not([data-tabs-initialized])", o);
40
+ })();
@@ -0,0 +1,137 @@
1
+ (() => {
2
+ let toaster;
3
+ const toasts = /* @__PURE__ */ new WeakMap();
4
+ let isPaused = false;
5
+ const ICONS = {
6
+ success: '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></svg>',
7
+ error: '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></svg>',
8
+ info: '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>',
9
+ warning: '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>'
10
+ };
11
+ function initToaster(toasterElement) {
12
+ if (toasterElement.dataset.toasterInitialized) return;
13
+ toaster = toasterElement;
14
+ toaster.addEventListener("mouseenter", pauseAllTimeouts);
15
+ toaster.addEventListener("mouseleave", resumeAllTimeouts);
16
+ toaster.addEventListener("click", (event) => {
17
+ const actionLink = event.target.closest(".toast footer a");
18
+ const actionButton = event.target.closest(".toast footer button");
19
+ if (actionLink || actionButton) {
20
+ closeToast(event.target.closest(".toast"));
21
+ }
22
+ });
23
+ toaster.querySelectorAll(".toast:not([data-toast-initialized])").forEach(initToast);
24
+ toaster.dataset.toasterInitialized = "true";
25
+ toaster.dispatchEvent(new CustomEvent("basecoat:initialized"));
26
+ }
27
+ function initToast(element) {
28
+ if (element.dataset.toastInitialized) return;
29
+ const duration = parseInt(element.dataset.duration);
30
+ const timeoutDuration = duration !== -1 ? duration || (element.dataset.category === "error" ? 5e3 : 3e3) : -1;
31
+ const state = {
32
+ remainingTime: timeoutDuration,
33
+ timeoutId: null,
34
+ startTime: null
35
+ };
36
+ if (timeoutDuration !== -1) {
37
+ if (isPaused) {
38
+ state.timeoutId = null;
39
+ } else {
40
+ state.startTime = Date.now();
41
+ state.timeoutId = setTimeout(() => closeToast(element), timeoutDuration);
42
+ }
43
+ }
44
+ toasts.set(element, state);
45
+ element.dataset.toastInitialized = "true";
46
+ }
47
+ function pauseAllTimeouts() {
48
+ if (isPaused) return;
49
+ isPaused = true;
50
+ toaster.querySelectorAll('.toast:not([aria-hidden="true"])').forEach((element) => {
51
+ if (!toasts.has(element)) return;
52
+ const state = toasts.get(element);
53
+ if (state.timeoutId) {
54
+ clearTimeout(state.timeoutId);
55
+ state.timeoutId = null;
56
+ state.remainingTime -= Date.now() - state.startTime;
57
+ }
58
+ });
59
+ }
60
+ function resumeAllTimeouts() {
61
+ if (!isPaused) return;
62
+ isPaused = false;
63
+ toaster.querySelectorAll('.toast:not([aria-hidden="true"])').forEach((element) => {
64
+ if (!toasts.has(element)) return;
65
+ const state = toasts.get(element);
66
+ if (state.remainingTime !== -1 && !state.timeoutId) {
67
+ if (state.remainingTime > 0) {
68
+ state.startTime = Date.now();
69
+ state.timeoutId = setTimeout(() => closeToast(element), state.remainingTime);
70
+ } else {
71
+ closeToast(element);
72
+ }
73
+ }
74
+ });
75
+ }
76
+ function closeToast(element) {
77
+ if (!toasts.has(element)) return;
78
+ const state = toasts.get(element);
79
+ clearTimeout(state.timeoutId);
80
+ toasts.delete(element);
81
+ if (element.contains(document.activeElement)) document.activeElement.blur();
82
+ element.setAttribute("aria-hidden", "true");
83
+ element.addEventListener("transitionend", () => element.remove(), { once: true });
84
+ }
85
+ function createToast(config) {
86
+ const {
87
+ category = "info",
88
+ title,
89
+ description,
90
+ action,
91
+ cancel,
92
+ duration,
93
+ icon
94
+ } = config;
95
+ const iconHtml = icon || category && ICONS[category] || "";
96
+ const titleHtml = title ? `<h2>${title}</h2>` : "";
97
+ const descriptionHtml = description ? `<p>${description}</p>` : "";
98
+ const actionHtml = action?.href ? `<a href="${action.href}" class="btn" data-toast-action>${action.label}</a>` : action?.onclick ? `<button type="button" class="btn" data-toast-action onclick="${action.onclick}">${action.label}</button>` : "";
99
+ const cancelHtml = cancel ? `<button type="button" class="btn-outline h-6 text-xs px-2.5 rounded-sm" data-toast-cancel onclick="${cancel?.onclick}">${cancel.label}</button>` : "";
100
+ const footerHtml = actionHtml || cancelHtml ? `<footer>${actionHtml}${cancelHtml}</footer>` : "";
101
+ const html = `
102
+ <div
103
+ class="toast"
104
+ role="${category === "error" ? "alert" : "status"}"
105
+ aria-atomic="true"
106
+ ${category ? `data-category="${category}"` : ""}
107
+ ${duration !== void 0 ? `data-duration="${duration}"` : ""}
108
+ >
109
+ <div class="toast-content">
110
+ ${iconHtml}
111
+ <section>
112
+ ${titleHtml}
113
+ ${descriptionHtml}
114
+ </section>
115
+ ${footerHtml}
116
+ </div>
117
+ </div>
118
+ </div>
119
+ `;
120
+ const template = document.createElement("template");
121
+ template.innerHTML = html.trim();
122
+ return template.content.firstChild;
123
+ }
124
+ document.addEventListener("basecoat:toast", (event) => {
125
+ if (!toaster) {
126
+ console.error("Cannot create toast: toaster container not found on page.");
127
+ return;
128
+ }
129
+ const config = event.detail?.config || {};
130
+ const toastElement = createToast(config);
131
+ toaster.appendChild(toastElement);
132
+ });
133
+ if (window.basecoat) {
134
+ window.basecoat.register("toaster", "#toaster:not([data-toaster-initialized])", initToaster);
135
+ window.basecoat.register("toast", ".toast:not([data-toast-initialized])", initToast);
136
+ }
137
+ })();
@@ -0,0 +1,83 @@
1
+ (() => {
2
+ let o;
3
+ const n = /* @__PURE__ */ new WeakMap();
4
+ let s = !1;
5
+ const g = {
6
+ success: '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></svg>',
7
+ error: '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></svg>',
8
+ info: '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>',
9
+ warning: '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>'
10
+ };
11
+ function w(t) {
12
+ t.dataset.toasterInitialized || (o = t, o.addEventListener("mouseenter", p), o.addEventListener("mouseleave", v), o.addEventListener("click", (e) => {
13
+ const i = e.target.closest(".toast footer a"), a = e.target.closest(".toast footer button");
14
+ (i || a) && c(e.target.closest(".toast"));
15
+ }), o.querySelectorAll(".toast:not([data-toast-initialized])").forEach(l), o.dataset.toasterInitialized = "true", o.dispatchEvent(new CustomEvent("basecoat:initialized")));
16
+ }
17
+ function l(t) {
18
+ if (t.dataset.toastInitialized) return;
19
+ const e = parseInt(t.dataset.duration), i = e !== -1 ? e || (t.dataset.category === "error" ? 5e3 : 3e3) : -1, a = {
20
+ remainingTime: i,
21
+ timeoutId: null,
22
+ startTime: null
23
+ };
24
+ i !== -1 && (s ? a.timeoutId = null : (a.startTime = Date.now(), a.timeoutId = setTimeout(() => c(t), i))), n.set(t, a), t.dataset.toastInitialized = "true";
25
+ }
26
+ function p() {
27
+ s || (s = !0, o.querySelectorAll('.toast:not([aria-hidden="true"])').forEach((t) => {
28
+ if (!n.has(t)) return;
29
+ const e = n.get(t);
30
+ e.timeoutId && (clearTimeout(e.timeoutId), e.timeoutId = null, e.remainingTime -= Date.now() - e.startTime);
31
+ }));
32
+ }
33
+ function v() {
34
+ s && (s = !1, o.querySelectorAll('.toast:not([aria-hidden="true"])').forEach((t) => {
35
+ if (!n.has(t)) return;
36
+ const e = n.get(t);
37
+ e.remainingTime !== -1 && !e.timeoutId && (e.remainingTime > 0 ? (e.startTime = Date.now(), e.timeoutId = setTimeout(() => c(t), e.remainingTime)) : c(t));
38
+ }));
39
+ }
40
+ function c(t) {
41
+ if (!n.has(t)) return;
42
+ const e = n.get(t);
43
+ clearTimeout(e.timeoutId), n.delete(t), t.contains(document.activeElement) && document.activeElement.blur(), t.setAttribute("aria-hidden", "true"), t.addEventListener("transitionend", () => t.remove(), { once: !0 });
44
+ }
45
+ function k(t) {
46
+ const {
47
+ category: e = "info",
48
+ title: i,
49
+ description: a,
50
+ action: r,
51
+ cancel: d,
52
+ duration: u,
53
+ icon: b
54
+ } = t, T = b || e && g[e] || "", $ = i ? `<h2>${i}</h2>` : "", I = a ? `<p>${a}</p>` : "", h = r?.href ? `<a href="${r.href}" class="btn" data-toast-action>${r.label}</a>` : r?.onclick ? `<button type="button" class="btn" data-toast-action onclick="${r.onclick}">${r.label}</button>` : "", m = d ? `<button type="button" class="btn-outline h-6 text-xs px-2.5 rounded-sm" data-toast-cancel onclick="${d?.onclick}">${d.label}</button>` : "", x = h || m ? `<footer>${h}${m}</footer>` : "", E = `
55
+ <div
56
+ class="toast"
57
+ role="${e === "error" ? "alert" : "status"}"
58
+ aria-atomic="true"
59
+ ${e ? `data-category="${e}"` : ""}
60
+ ${u !== void 0 ? `data-duration="${u}"` : ""}
61
+ >
62
+ <div class="toast-content">
63
+ ${T}
64
+ <section>
65
+ ${$}
66
+ ${I}
67
+ </section>
68
+ ${x}
69
+ </div>
70
+ </div>
71
+ </div>
72
+ `, f = document.createElement("template");
73
+ return f.innerHTML = E.trim(), f.content.firstChild;
74
+ }
75
+ document.addEventListener("basecoat:toast", (t) => {
76
+ if (!o) {
77
+ console.error("Cannot create toast: toaster container not found on page.");
78
+ return;
79
+ }
80
+ const e = t.detail?.config || {}, i = k(e);
81
+ o.appendChild(i);
82
+ }), window.basecoat && (window.basecoat.register("toaster", "#toaster:not([data-toaster-initialized])", w), window.basecoat.register("toast", ".toast:not([data-toast-initialized])", l));
83
+ })();
@@ -0,0 +1,36 @@
1
+ (() => {
2
+ const initToggle = (toggle) => {
3
+ toggle.addEventListener("click", (e) => {
4
+ if (toggle.disabled || toggle.getAttribute("aria-disabled") === "true") return;
5
+ const isPressed = toggle.getAttribute("aria-pressed") === "true";
6
+ toggle.setAttribute("aria-pressed", !isPressed);
7
+ });
8
+ toggle.dataset.toggleInitialized = true;
9
+ };
10
+ const initToggleGroup = (group) => {
11
+ const type = group.dataset.type || "single";
12
+ group.addEventListener("click", (event) => {
13
+ const toggle = event.target.closest(".toggle");
14
+ if (!toggle || !group.contains(toggle)) return;
15
+ if (toggle.disabled || toggle.getAttribute("aria-disabled") === "true") return;
16
+ const isPressed = toggle.getAttribute("aria-pressed") === "true";
17
+ if (type === "single") {
18
+ if (!isPressed) {
19
+ group.querySelectorAll(".toggle").forEach((t) => {
20
+ if (t !== toggle) t.setAttribute("aria-pressed", "false");
21
+ });
22
+ toggle.setAttribute("aria-pressed", "true");
23
+ } else {
24
+ toggle.setAttribute("aria-pressed", "false");
25
+ }
26
+ } else {
27
+ toggle.setAttribute("aria-pressed", !isPressed);
28
+ }
29
+ });
30
+ group.dataset.toggleGroupInitialized = true;
31
+ };
32
+ if (window.basecoat) {
33
+ window.basecoat.register("toggle", ".toggle:not(.toggle-group .toggle):not([data-toggle-initialized])", initToggle);
34
+ window.basecoat.register("toggle-group", ".toggle-group:not([data-toggle-group-initialized])", initToggleGroup);
35
+ }
36
+ })();