@incursa/ui-kit 0.2.1

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.
@@ -0,0 +1,219 @@
1
+ (function () {
2
+ "use strict";
3
+
4
+ const selectors = {
5
+ menuToggle: '[data-inc-toggle="menu"]',
6
+ collapseToggle: '[data-inc-toggle="collapse"]',
7
+ tabToggle: '[data-inc-toggle="tab"]',
8
+ userMenu: ".inc-user-menu",
9
+ tabPane: ".inc-tab-pane",
10
+ };
11
+
12
+ function getTarget(trigger) {
13
+ const rawTarget = trigger.getAttribute("data-inc-target") || trigger.getAttribute("href");
14
+
15
+ if (!rawTarget || rawTarget === "#") {
16
+ return null;
17
+ }
18
+
19
+ try {
20
+ return document.querySelector(rawTarget);
21
+ } catch {
22
+ return null;
23
+ }
24
+ }
25
+
26
+ function closeMenu(toggle) {
27
+ const menu = getTarget(toggle);
28
+
29
+ if (!menu) {
30
+ return;
31
+ }
32
+
33
+ menu.classList.remove("show");
34
+ toggle.setAttribute("aria-expanded", "false");
35
+ }
36
+
37
+ function openMenu(toggle) {
38
+ const menu = getTarget(toggle);
39
+
40
+ if (!menu) {
41
+ return;
42
+ }
43
+
44
+ menu.classList.add("show");
45
+ toggle.setAttribute("aria-expanded", "true");
46
+ }
47
+
48
+ function closeAllMenus(exceptToggle) {
49
+ document.querySelectorAll(selectors.menuToggle).forEach((toggle) => {
50
+ if (exceptToggle && toggle === exceptToggle) {
51
+ return;
52
+ }
53
+
54
+ closeMenu(toggle);
55
+ });
56
+ }
57
+
58
+ function setCollapseState(trigger, target, expanded) {
59
+ trigger.setAttribute("aria-expanded", expanded ? "true" : "false");
60
+ trigger.classList.toggle("collapsed", !expanded);
61
+ target.classList.toggle("show", expanded);
62
+ }
63
+
64
+ function toggleCollapse(trigger) {
65
+ const target = getTarget(trigger);
66
+
67
+ if (!target) {
68
+ return;
69
+ }
70
+
71
+ const shouldExpand = !target.classList.contains("show");
72
+ const accordionRoot = trigger.closest("[data-inc-accordion]");
73
+
74
+ if (accordionRoot && shouldExpand) {
75
+ accordionRoot.querySelectorAll(selectors.collapseToggle).forEach((otherTrigger) => {
76
+ if (otherTrigger === trigger) {
77
+ return;
78
+ }
79
+
80
+ const otherTarget = getTarget(otherTrigger);
81
+
82
+ if (otherTarget) {
83
+ setCollapseState(otherTrigger, otherTarget, false);
84
+ }
85
+ });
86
+ }
87
+
88
+ setCollapseState(trigger, target, shouldExpand);
89
+ }
90
+
91
+ function activateTab(trigger) {
92
+ const listRoot = trigger.closest('[role="tablist"], .inc-tabs-nav');
93
+
94
+ if (!listRoot) {
95
+ return;
96
+ }
97
+
98
+ const tabs = Array.from(listRoot.querySelectorAll(selectors.tabToggle));
99
+ const targetPane = getTarget(trigger);
100
+
101
+ if (!targetPane) {
102
+ return;
103
+ }
104
+
105
+ tabs.forEach((tab) => {
106
+ const pane = getTarget(tab);
107
+ const isActive = tab === trigger;
108
+
109
+ tab.classList.toggle("active", isActive);
110
+ tab.setAttribute("aria-selected", isActive ? "true" : "false");
111
+ tab.tabIndex = isActive ? 0 : -1;
112
+
113
+ if (pane) {
114
+ pane.classList.toggle("active", isActive);
115
+ pane.classList.toggle("show", isActive);
116
+ pane.hidden = !isActive;
117
+ }
118
+ });
119
+ }
120
+
121
+ function initializeMenus() {
122
+ document.querySelectorAll(selectors.menuToggle).forEach((toggle) => {
123
+ toggle.setAttribute("aria-expanded", "false");
124
+ });
125
+ }
126
+
127
+ function initializeCollapses() {
128
+ document.querySelectorAll(selectors.collapseToggle).forEach((trigger) => {
129
+ const target = getTarget(trigger);
130
+
131
+ if (!target) {
132
+ return;
133
+ }
134
+
135
+ setCollapseState(trigger, target, target.classList.contains("show"));
136
+ });
137
+ }
138
+
139
+ function initializeTabs() {
140
+ document.querySelectorAll(selectors.tabToggle).forEach((tab) => {
141
+ const pane = getTarget(tab);
142
+ const isActive = tab.classList.contains("active");
143
+
144
+ tab.setAttribute("aria-selected", isActive ? "true" : "false");
145
+ tab.tabIndex = isActive ? 0 : -1;
146
+
147
+ if (pane) {
148
+ pane.hidden = !isActive;
149
+ pane.classList.toggle("show", isActive);
150
+ pane.classList.toggle("active", isActive);
151
+ }
152
+ });
153
+
154
+ document.querySelectorAll(selectors.tabPane).forEach((pane) => {
155
+ const hasActiveTab = document.querySelector(`${selectors.tabToggle}[href="#${pane.id}"].active, ${selectors.tabToggle}[data-inc-target="#${pane.id}"].active`);
156
+ pane.hidden = !hasActiveTab;
157
+ });
158
+ }
159
+
160
+ function attachEventHandlers() {
161
+ document.addEventListener("click", (event) => {
162
+ const menuToggle = event.target.closest(selectors.menuToggle);
163
+
164
+ if (menuToggle) {
165
+ event.preventDefault();
166
+
167
+ const menu = getTarget(menuToggle);
168
+ const isOpen = menu ? menu.classList.contains("show") : false;
169
+ closeAllMenus(menuToggle);
170
+
171
+ if (!isOpen) {
172
+ openMenu(menuToggle);
173
+ } else {
174
+ closeMenu(menuToggle);
175
+ }
176
+
177
+ return;
178
+ }
179
+
180
+ if (!event.target.closest(selectors.userMenu)) {
181
+ closeAllMenus();
182
+ }
183
+
184
+ const collapseToggle = event.target.closest(selectors.collapseToggle);
185
+
186
+ if (collapseToggle) {
187
+ event.preventDefault();
188
+ toggleCollapse(collapseToggle);
189
+ return;
190
+ }
191
+
192
+ const tabToggle = event.target.closest(selectors.tabToggle);
193
+
194
+ if (tabToggle) {
195
+ event.preventDefault();
196
+ activateTab(tabToggle);
197
+ }
198
+ });
199
+
200
+ document.addEventListener("keydown", (event) => {
201
+ if (event.key === "Escape") {
202
+ closeAllMenus();
203
+ }
204
+ });
205
+ }
206
+
207
+ function initialize() {
208
+ initializeMenus();
209
+ initializeCollapses();
210
+ initializeTabs();
211
+ attachEventHandlers();
212
+ }
213
+
214
+ if (document.readyState === "loading") {
215
+ document.addEventListener("DOMContentLoaded", initialize, { once: true });
216
+ } else {
217
+ initialize();
218
+ }
219
+ })();