@uicraft/core 1.0.0 → 1.1.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/package.json +4 -2
- package/uicraft.js +882 -0
- package/uicraft.min.js +7 -0
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uicraft/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "uicraft — beautifully designed UI components built with semantic CSS utility classes",
|
|
5
|
-
"main": "uicraft.
|
|
5
|
+
"main": "uicraft.js",
|
|
6
6
|
"style": "uicraft.css",
|
|
7
7
|
"files": [
|
|
8
8
|
"uicraft.css",
|
|
9
9
|
"uicraft.min.css",
|
|
10
|
+
"uicraft.js",
|
|
11
|
+
"uicraft.min.js",
|
|
10
12
|
"theme-manifest.json",
|
|
11
13
|
"themes/"
|
|
12
14
|
],
|
package/uicraft.js
ADDED
|
@@ -0,0 +1,882 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* uicraft.js v1.1.0
|
|
3
|
+
* https://getuicraft.com
|
|
4
|
+
* MIT License
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// UCAccordion — expand/collapse with single and multi mode
|
|
8
|
+
var UCAccordion = {
|
|
9
|
+
init: function() {
|
|
10
|
+
var uid = 0;
|
|
11
|
+
document.querySelectorAll('[data-accordion-item]').forEach(function(item) {
|
|
12
|
+
uid++;
|
|
13
|
+
var trigger = item.querySelector('[data-accordion-trigger]');
|
|
14
|
+
var content = item.querySelector('[data-accordion-content]');
|
|
15
|
+
if (trigger && content) {
|
|
16
|
+
var tId = 'acc-trigger-' + uid;
|
|
17
|
+
var cId = 'acc-content-' + uid;
|
|
18
|
+
trigger.id = tId;
|
|
19
|
+
content.id = cId;
|
|
20
|
+
trigger.setAttribute('aria-controls', cId);
|
|
21
|
+
content.setAttribute('aria-labelledby', tId);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
function openContent(content) {
|
|
26
|
+
content.classList.remove('uc-hidden');
|
|
27
|
+
content.classList.add('open');
|
|
28
|
+
content.style.maxHeight = content.scrollHeight + 16 + 'px';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function closeContent(content) {
|
|
32
|
+
content.style.maxHeight = '0px';
|
|
33
|
+
content.classList.remove('open');
|
|
34
|
+
content.addEventListener('transitionend', function handler() {
|
|
35
|
+
if (content.style.maxHeight === '0px') {
|
|
36
|
+
content.classList.add('uc-hidden');
|
|
37
|
+
}
|
|
38
|
+
content.removeEventListener('transitionend', handler);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
document.querySelectorAll('[data-accordion-content]').forEach(function(content) {
|
|
43
|
+
if (!content.classList.contains('uc-hidden') && !content.classList.contains('hidden')) {
|
|
44
|
+
content.classList.add('open');
|
|
45
|
+
content.style.maxHeight = content.scrollHeight + 16 + 'px';
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
document.querySelectorAll('[data-accordion-trigger]').forEach(function(trigger) {
|
|
50
|
+
if (trigger.hasAttribute('data-accordion-init')) return;
|
|
51
|
+
trigger.setAttribute('data-accordion-init', 'true');
|
|
52
|
+
|
|
53
|
+
trigger.addEventListener('click', function() {
|
|
54
|
+
var item = trigger.closest('[data-accordion-item]');
|
|
55
|
+
var accordion = trigger.closest('[data-accordion]');
|
|
56
|
+
var mode = accordion.getAttribute('data-accordion');
|
|
57
|
+
var content = item.querySelector('[data-accordion-content]');
|
|
58
|
+
var icon = trigger.querySelector('[data-accordion-icon]');
|
|
59
|
+
var isOpen = !content.classList.contains('uc-hidden') && !content.classList.contains('hidden') && content.classList.contains('open');
|
|
60
|
+
|
|
61
|
+
if (mode === 'single') {
|
|
62
|
+
accordion.querySelectorAll('[data-accordion-item]').forEach(function(otherItem) {
|
|
63
|
+
var otherContent = otherItem.querySelector('[data-accordion-content]');
|
|
64
|
+
var otherTrigger = otherItem.querySelector('[data-accordion-trigger]');
|
|
65
|
+
var otherIcon = otherItem.querySelector('[data-accordion-trigger] [data-accordion-icon]');
|
|
66
|
+
if (otherItem !== item && !otherContent.classList.contains('uc-hidden') && !otherContent.classList.contains('hidden')) {
|
|
67
|
+
closeContent(otherContent);
|
|
68
|
+
if (otherIcon) otherIcon.classList.remove('uc-rotate-180');
|
|
69
|
+
if (otherTrigger) otherTrigger.setAttribute('aria-expanded', 'false');
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (isOpen) {
|
|
75
|
+
closeContent(content);
|
|
76
|
+
if (icon) icon.classList.remove('uc-rotate-180');
|
|
77
|
+
trigger.setAttribute('aria-expanded', 'false');
|
|
78
|
+
} else {
|
|
79
|
+
content.classList.remove('uc-hidden');
|
|
80
|
+
content.offsetHeight;
|
|
81
|
+
openContent(content);
|
|
82
|
+
if (icon) icon.classList.add('uc-rotate-180');
|
|
83
|
+
trigger.setAttribute('aria-expanded', 'true');
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// UCCollapsible — expand/collapse content with optional animation
|
|
91
|
+
var UCCollapsible = {
|
|
92
|
+
init: function() {
|
|
93
|
+
// Initialize open collapsibles
|
|
94
|
+
document.querySelectorAll('[data-collapsible][data-collapsible-open]').forEach(function(collapsible) {
|
|
95
|
+
var content = collapsible.querySelector('[data-collapsible-content]');
|
|
96
|
+
var icon = collapsible.querySelector('[data-collapsible-icon]');
|
|
97
|
+
if (content) {
|
|
98
|
+
content.classList.remove('uc-hidden');
|
|
99
|
+
if (collapsible.hasAttribute('data-collapsible-animated')) {
|
|
100
|
+
content.style.maxHeight = content.scrollHeight + 'px';
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (icon) {
|
|
104
|
+
icon.classList.add('uc-rotate-180');
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Bind triggers with guard
|
|
109
|
+
document.querySelectorAll('[data-collapsible-trigger]').forEach(function(trigger) {
|
|
110
|
+
if (trigger.hasAttribute('data-collapsible-bound')) return;
|
|
111
|
+
trigger.setAttribute('data-collapsible-bound', 'true');
|
|
112
|
+
|
|
113
|
+
trigger.addEventListener('click', function() {
|
|
114
|
+
var collapsible = trigger.closest('[data-collapsible]');
|
|
115
|
+
var content = collapsible.querySelector(':scope > [data-collapsible-content]');
|
|
116
|
+
if (!content) {
|
|
117
|
+
content = collapsible.querySelector('[data-collapsible-content]');
|
|
118
|
+
}
|
|
119
|
+
var icon = collapsible.querySelector(':scope > * [data-collapsible-icon]') || collapsible.querySelector('[data-collapsible-icon]');
|
|
120
|
+
var isAnimated = collapsible.hasAttribute('data-collapsible-animated');
|
|
121
|
+
var labelCollapse = trigger.querySelector('[data-collapsible-label-collapse]');
|
|
122
|
+
var labelExpand = trigger.querySelector('[data-collapsible-label-expand]');
|
|
123
|
+
var isOpen;
|
|
124
|
+
|
|
125
|
+
if (isAnimated) {
|
|
126
|
+
isOpen = parseInt(content.style.maxHeight) > 0;
|
|
127
|
+
} else {
|
|
128
|
+
isOpen = !content.classList.contains('uc-hidden');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (isOpen) {
|
|
132
|
+
if (isAnimated) {
|
|
133
|
+
content.style.maxHeight = '0';
|
|
134
|
+
} else {
|
|
135
|
+
content.classList.add('uc-hidden');
|
|
136
|
+
}
|
|
137
|
+
if (icon) icon.classList.remove('uc-rotate-180');
|
|
138
|
+
if (labelCollapse) labelCollapse.classList.add('uc-hidden');
|
|
139
|
+
if (labelExpand) labelExpand.classList.remove('uc-hidden');
|
|
140
|
+
collapsible.removeAttribute('data-collapsible-open');
|
|
141
|
+
} else {
|
|
142
|
+
if (isAnimated) {
|
|
143
|
+
content.style.maxHeight = content.scrollHeight + 'px';
|
|
144
|
+
} else {
|
|
145
|
+
content.classList.remove('uc-hidden');
|
|
146
|
+
}
|
|
147
|
+
if (icon) icon.classList.add('uc-rotate-180');
|
|
148
|
+
if (labelCollapse) labelCollapse.classList.remove('uc-hidden');
|
|
149
|
+
if (labelExpand) labelExpand.classList.add('uc-hidden');
|
|
150
|
+
collapsible.setAttribute('data-collapsible-open', '');
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// UCCombobox — searchable single/multi-select with tags
|
|
158
|
+
var UCCombobox = {
|
|
159
|
+
init: function() {
|
|
160
|
+
var checkSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="uc-w-4 uc-h-4 uc-shrink-0 uc-text-accents-blue uc-combobox-icon"><path d="M20 6 9 17l-5-5"/></svg>';
|
|
161
|
+
var emptySpacer = '<span class="uc-w-4 uc-h-4 uc-shrink-0 uc-combobox-icon"></span>';
|
|
162
|
+
var xTagSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="uc-w-3 uc-h-3"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>';
|
|
163
|
+
|
|
164
|
+
// Close on click outside
|
|
165
|
+
if (!document.body.hasAttribute('data-combobox-outside-init')) {
|
|
166
|
+
document.body.setAttribute('data-combobox-outside-init', 'true');
|
|
167
|
+
document.addEventListener('click', function(e) {
|
|
168
|
+
if (!e.target.closest('.uc-combobox-wrapper')) {
|
|
169
|
+
document.querySelectorAll('[data-combobox-content]').forEach(function(el) {
|
|
170
|
+
el.classList.remove('uc-open');
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Expose functions globally for inline onclick use
|
|
177
|
+
window.openCombobox = function(id) {
|
|
178
|
+
var el = document.getElementById(id);
|
|
179
|
+
if (el) el.classList.add('uc-open');
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
window.toggleCombobox = function(id) {
|
|
183
|
+
var el = document.getElementById(id);
|
|
184
|
+
if (el) el.classList.toggle('uc-open');
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
window.filterCombobox = function(input, id) {
|
|
188
|
+
var dropdown = document.getElementById(id);
|
|
189
|
+
var query = input.value.toLowerCase();
|
|
190
|
+
var items = dropdown.querySelectorAll('.uc-combobox-item');
|
|
191
|
+
var groups = dropdown.querySelectorAll('[data-combobox-group]');
|
|
192
|
+
var emptyEl = dropdown.querySelector('.uc-combobox-empty');
|
|
193
|
+
var totalVisible = 0;
|
|
194
|
+
|
|
195
|
+
if (groups.length > 0) {
|
|
196
|
+
groups.forEach(function(group) {
|
|
197
|
+
var groupItems = group.querySelectorAll('.uc-combobox-item');
|
|
198
|
+
var groupVisible = 0;
|
|
199
|
+
groupItems.forEach(function(item) {
|
|
200
|
+
if (item.textContent.toLowerCase().includes(query)) {
|
|
201
|
+
item.classList.remove('uc-hidden');
|
|
202
|
+
groupVisible++;
|
|
203
|
+
totalVisible++;
|
|
204
|
+
} else {
|
|
205
|
+
item.classList.add('uc-hidden');
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
group.style.display = groupVisible > 0 ? '' : 'none';
|
|
209
|
+
});
|
|
210
|
+
} else {
|
|
211
|
+
items.forEach(function(item) {
|
|
212
|
+
if (item.textContent.toLowerCase().includes(query)) {
|
|
213
|
+
item.classList.remove('uc-hidden');
|
|
214
|
+
totalVisible++;
|
|
215
|
+
} else {
|
|
216
|
+
item.classList.add('uc-hidden');
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (emptyEl) {
|
|
222
|
+
emptyEl.classList.toggle('uc-hidden', totalVisible > 0 || !query);
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
function setItemIcon(item, checked) {
|
|
227
|
+
var icon = item.querySelector('.uc-combobox-icon');
|
|
228
|
+
if (icon) icon.outerHTML = checked ? checkSvg : emptySpacer;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
window.selectComboboxItem = function(item) {
|
|
232
|
+
var text = item.textContent.trim();
|
|
233
|
+
var wrapper = item.closest('.uc-combobox-wrapper');
|
|
234
|
+
var keepIcons = wrapper.hasAttribute('data-keep-icons');
|
|
235
|
+
var input = wrapper.querySelector('input');
|
|
236
|
+
var dropdown = item.closest('[data-combobox-content]');
|
|
237
|
+
|
|
238
|
+
input.value = text;
|
|
239
|
+
|
|
240
|
+
dropdown.querySelectorAll('.uc-combobox-item').forEach(function(i) {
|
|
241
|
+
i.classList.remove('uc-selected');
|
|
242
|
+
if (!keepIcons) setItemIcon(i, false);
|
|
243
|
+
});
|
|
244
|
+
item.classList.add('uc-selected');
|
|
245
|
+
if (!keepIcons) setItemIcon(item, true);
|
|
246
|
+
|
|
247
|
+
dropdown.classList.remove('uc-open');
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
window.selectComboboxButton = function(item, dropdownId) {
|
|
251
|
+
var text = item.textContent.trim();
|
|
252
|
+
var wrapper = item.closest('.uc-combobox-wrapper');
|
|
253
|
+
var label = wrapper.querySelector('.uc-combobox-button-label');
|
|
254
|
+
var dropdown = document.getElementById(dropdownId);
|
|
255
|
+
|
|
256
|
+
label.textContent = text;
|
|
257
|
+
label.classList.remove('uc-text-fg-disabled');
|
|
258
|
+
|
|
259
|
+
dropdown.querySelectorAll('.uc-combobox-item').forEach(function(i) {
|
|
260
|
+
i.classList.remove('uc-selected');
|
|
261
|
+
setItemIcon(i, false);
|
|
262
|
+
});
|
|
263
|
+
item.classList.add('uc-selected');
|
|
264
|
+
setItemIcon(item, true);
|
|
265
|
+
|
|
266
|
+
dropdown.classList.remove('uc-open');
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
window.toggleMultiComboboxItem = function(item) {
|
|
270
|
+
var isSelected = item.classList.toggle('uc-selected');
|
|
271
|
+
setItemIcon(item, isSelected);
|
|
272
|
+
|
|
273
|
+
var wrapper = item.closest('.uc-combobox-wrapper');
|
|
274
|
+
var tagContainer = wrapper.querySelector('.uc-combobox-tags');
|
|
275
|
+
var text = item.textContent.trim();
|
|
276
|
+
|
|
277
|
+
if (isSelected) {
|
|
278
|
+
var tag = document.createElement('span');
|
|
279
|
+
tag.className = 'uc-combobox-tag uc-inline-flex uc-items-center uc-gap-1 uc-rounded uc-bg-neutrals-subtle uc-px-2 uc-py-0.5 uc-text-xs uc-font-medium';
|
|
280
|
+
tag.setAttribute('data-tag-value', text);
|
|
281
|
+
tag.innerHTML = text + '<button type="button" onclick="event.stopPropagation(); removeComboboxTag(this)" class="uc-ml-0.5 uc-rounded-sm uc-hover:bg-neutrals-muted uc-transition-colors">' + xTagSvg + '</button>';
|
|
282
|
+
tagContainer.insertBefore(tag, tagContainer.querySelector('input'));
|
|
283
|
+
} else {
|
|
284
|
+
var existing = tagContainer.querySelector('[data-tag-value="' + text + '"]');
|
|
285
|
+
if (existing) existing.remove();
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
UCCombobox._updateMultiPlaceholder(wrapper);
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
window.removeComboboxTag = function(btn) {
|
|
292
|
+
var tag = btn.closest('.uc-combobox-tag');
|
|
293
|
+
if (!tag) return;
|
|
294
|
+
var value = tag.getAttribute('data-tag-value');
|
|
295
|
+
var wrapper = tag.closest('.uc-combobox-wrapper');
|
|
296
|
+
tag.remove();
|
|
297
|
+
|
|
298
|
+
var dropdown = wrapper.querySelector('[data-combobox-content]');
|
|
299
|
+
if (dropdown) {
|
|
300
|
+
dropdown.querySelectorAll('.uc-combobox-item').forEach(function(item) {
|
|
301
|
+
if (item.textContent.trim() === value) {
|
|
302
|
+
item.classList.remove('uc-selected');
|
|
303
|
+
setItemIcon(item, false);
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
UCCombobox._updateMultiPlaceholder(wrapper);
|
|
309
|
+
};
|
|
310
|
+
},
|
|
311
|
+
|
|
312
|
+
_updateMultiPlaceholder: function(wrapper) {
|
|
313
|
+
var input = wrapper.querySelector('input');
|
|
314
|
+
var tags = wrapper.querySelectorAll('.uc-combobox-tag');
|
|
315
|
+
if (input) {
|
|
316
|
+
input.placeholder = tags.length > 0 ? '' : 'Add framework...';
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
// UCResizable — drag-to-resize panels horizontally or vertically
|
|
322
|
+
var UCResizable = {
|
|
323
|
+
init: function() {
|
|
324
|
+
document.querySelectorAll('[data-resizable]').forEach(function(container) {
|
|
325
|
+
if (container.hasAttribute('data-resizable-init')) return;
|
|
326
|
+
container.setAttribute('data-resizable-init', 'true');
|
|
327
|
+
|
|
328
|
+
var direction = container.dataset.resizable;
|
|
329
|
+
var isHorizontal = direction === 'horizontal';
|
|
330
|
+
var minPct = parseFloat(container.dataset.min || '10');
|
|
331
|
+
var maxPct = parseFloat(container.dataset.max || '90');
|
|
332
|
+
var handles = container.querySelectorAll(':scope > .uc-resize-handle');
|
|
333
|
+
|
|
334
|
+
handles.forEach(function(handle) {
|
|
335
|
+
var isDown = false;
|
|
336
|
+
var startPos = 0;
|
|
337
|
+
var prevPanel = null;
|
|
338
|
+
var nextPanel = null;
|
|
339
|
+
var containerSize = 0;
|
|
340
|
+
var prevStart = 0;
|
|
341
|
+
var nextStart = 0;
|
|
342
|
+
|
|
343
|
+
handle.addEventListener('mousedown', function(e) {
|
|
344
|
+
e.preventDefault();
|
|
345
|
+
isDown = true;
|
|
346
|
+
prevPanel = handle.previousElementSibling;
|
|
347
|
+
nextPanel = handle.nextElementSibling;
|
|
348
|
+
if (!prevPanel || !nextPanel) return;
|
|
349
|
+
|
|
350
|
+
containerSize = isHorizontal ? container.offsetWidth : container.offsetHeight;
|
|
351
|
+
prevStart = isHorizontal ? prevPanel.offsetWidth : prevPanel.offsetHeight;
|
|
352
|
+
nextStart = isHorizontal ? nextPanel.offsetWidth : nextPanel.offsetHeight;
|
|
353
|
+
startPos = isHorizontal ? e.clientX : e.clientY;
|
|
354
|
+
|
|
355
|
+
document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';
|
|
356
|
+
document.body.style.userSelect = 'none';
|
|
357
|
+
handle.style.background = 'hsl(var(--accents-blue) / 0.5)';
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
document.addEventListener('mousemove', function(e) {
|
|
361
|
+
if (!isDown || !prevPanel || !nextPanel) return;
|
|
362
|
+
var delta = (isHorizontal ? e.clientX : e.clientY) - startPos;
|
|
363
|
+
var newPrev = prevStart + delta;
|
|
364
|
+
var newNext = nextStart - delta;
|
|
365
|
+
|
|
366
|
+
var minSize = containerSize * (minPct / 100);
|
|
367
|
+
var maxSize = containerSize * (maxPct / 100);
|
|
368
|
+
|
|
369
|
+
if (newPrev < minSize) { newPrev = minSize; newNext = prevStart + nextStart - minSize; }
|
|
370
|
+
if (newNext < minSize) { newNext = minSize; newPrev = prevStart + nextStart - minSize; }
|
|
371
|
+
if (newPrev > maxSize) { newPrev = maxSize; newNext = prevStart + nextStart - maxSize; }
|
|
372
|
+
if (newNext > maxSize) { newNext = maxSize; newPrev = prevStart + nextStart - maxSize; }
|
|
373
|
+
|
|
374
|
+
var prevPct = (newPrev / containerSize * 100).toFixed(1);
|
|
375
|
+
var nextPct = (newNext / containerSize * 100).toFixed(1);
|
|
376
|
+
|
|
377
|
+
if (isHorizontal) {
|
|
378
|
+
prevPanel.style.width = prevPct + '%';
|
|
379
|
+
nextPanel.style.width = nextPct + '%';
|
|
380
|
+
} else {
|
|
381
|
+
prevPanel.style.height = prevPct + '%';
|
|
382
|
+
nextPanel.style.height = nextPct + '%';
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
prevPanel.style.flex = 'none';
|
|
386
|
+
nextPanel.style.flex = 'none';
|
|
387
|
+
|
|
388
|
+
var prevLabel = prevPanel.querySelector('.uc-size-label');
|
|
389
|
+
var nextLabel = nextPanel.querySelector('.uc-size-label');
|
|
390
|
+
if (prevLabel) prevLabel.textContent = Math.round(parseFloat(prevPct)) + '%';
|
|
391
|
+
if (nextLabel) nextLabel.textContent = Math.round(parseFloat(nextPct)) + '%';
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
document.addEventListener('mouseup', function() {
|
|
395
|
+
if (!isDown) return;
|
|
396
|
+
isDown = false;
|
|
397
|
+
document.body.style.cursor = '';
|
|
398
|
+
document.body.style.userSelect = '';
|
|
399
|
+
handle.style.background = '';
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
// UCCarousel — slide carousel with dots, prev/next navigation
|
|
407
|
+
var UCCarousel = {
|
|
408
|
+
init: function() {
|
|
409
|
+
document.querySelectorAll('[data-carousel]').forEach(function(el) {
|
|
410
|
+
if (el.hasAttribute('data-carousel-init')) return;
|
|
411
|
+
el.setAttribute('data-carousel-init', 'true');
|
|
412
|
+
|
|
413
|
+
var carousel = el;
|
|
414
|
+
var track = carousel.querySelector('[data-carousel-track]');
|
|
415
|
+
var prevBtn = carousel.querySelector('[data-carousel-prev]');
|
|
416
|
+
var nextBtn = carousel.querySelector('[data-carousel-next]');
|
|
417
|
+
var dotsContainer = carousel.querySelector('[data-carousel-dots]');
|
|
418
|
+
var total = parseInt(carousel.dataset.total || '0');
|
|
419
|
+
var visible = parseInt(carousel.dataset.visible || '1');
|
|
420
|
+
var maxIndex = total - visible;
|
|
421
|
+
var current = 0;
|
|
422
|
+
|
|
423
|
+
function update() {
|
|
424
|
+
if (visible === 1) {
|
|
425
|
+
track.style.transform = 'translateX(-' + (current * 100) + '%)';
|
|
426
|
+
} else {
|
|
427
|
+
var slide = track.children[0];
|
|
428
|
+
var gap = parseFloat(getComputedStyle(track).gap) || 0;
|
|
429
|
+
var offset = current * (slide.offsetWidth + gap);
|
|
430
|
+
track.style.transform = 'translateX(-' + offset + 'px)';
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (dotsContainer) {
|
|
434
|
+
dotsContainer.querySelectorAll('[data-dot]').forEach(function(dot) {
|
|
435
|
+
var idx = parseInt(dot.dataset.dot || '0');
|
|
436
|
+
dot.className = 'uc-w-2 uc-h-2 uc-rounded-full uc-transition-colors ' + (idx === current ? 'uc-bg-accents-blue' : 'uc-bg-neutrals-muted');
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
if (prevBtn) prevBtn.style.opacity = current === 0 ? '0.4' : '1';
|
|
441
|
+
if (nextBtn) nextBtn.style.opacity = current >= maxIndex ? '0.4' : '1';
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (prevBtn) {
|
|
445
|
+
prevBtn.addEventListener('click', function() {
|
|
446
|
+
if (current > 0) { current--; update(); }
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (nextBtn) {
|
|
451
|
+
nextBtn.addEventListener('click', function() {
|
|
452
|
+
if (current < maxIndex) { current++; update(); }
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
if (dotsContainer) {
|
|
457
|
+
dotsContainer.querySelectorAll('[data-dot]').forEach(function(dot) {
|
|
458
|
+
dot.addEventListener('click', function() {
|
|
459
|
+
current = Math.min(parseInt(dot.dataset.dot || '0'), maxIndex);
|
|
460
|
+
update();
|
|
461
|
+
});
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
update();
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
// UCDropdown — dropdown menu with checkbox and radio item support
|
|
471
|
+
var UCDropdown = {
|
|
472
|
+
init: function() {
|
|
473
|
+
if (document.body.hasAttribute('data-dropdowns-init')) return;
|
|
474
|
+
document.body.setAttribute('data-dropdowns-init', 'true');
|
|
475
|
+
|
|
476
|
+
document.addEventListener('click', function(e) {
|
|
477
|
+
if (!e.target.closest('[data-dropdown-trigger]') && !e.target.closest('.uc-dropdown-menu')) {
|
|
478
|
+
document.querySelectorAll('.uc-dropdown-menu').forEach(function(el) {
|
|
479
|
+
el.classList.remove('uc-open');
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
document.querySelectorAll('[data-dropdown-trigger]').forEach(function(trigger) {
|
|
485
|
+
if (trigger.hasAttribute('data-dropdown-bound')) return;
|
|
486
|
+
trigger.setAttribute('data-dropdown-bound', 'true');
|
|
487
|
+
trigger.addEventListener('click', function(e) {
|
|
488
|
+
e.stopPropagation();
|
|
489
|
+
var targetId = trigger.getAttribute('data-dropdown-trigger');
|
|
490
|
+
var content = document.getElementById(targetId);
|
|
491
|
+
if (!content) return;
|
|
492
|
+
|
|
493
|
+
document.querySelectorAll('.uc-dropdown-menu').forEach(function(el) {
|
|
494
|
+
if (el !== content) el.classList.remove('uc-open');
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
content.classList.toggle('uc-open');
|
|
498
|
+
});
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
// Checkbox toggle — called via onclick in HTML
|
|
504
|
+
function toggleCheckbox(el) {
|
|
505
|
+
var indicator = el.querySelector('.checkbox-indicator');
|
|
506
|
+
var isChecked = indicator.classList.contains('uc-bg-accents-blue');
|
|
507
|
+
|
|
508
|
+
if (isChecked) {
|
|
509
|
+
indicator.classList.remove('uc-bg-accents-blue', 'uc-text-constant-white', 'uc-border-transparent');
|
|
510
|
+
indicator.innerHTML = '';
|
|
511
|
+
} else {
|
|
512
|
+
indicator.classList.add('uc-bg-accents-blue', 'uc-text-constant-white', 'uc-border-transparent');
|
|
513
|
+
indicator.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="uc-w-3 uc-h-3"><path d="M20 6 9 17l-5-5"/></svg>';
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// Radio select — called via onclick in HTML
|
|
518
|
+
function selectRadio(el) {
|
|
519
|
+
var parent = el.closest('.uc-dropdown-menu');
|
|
520
|
+
parent.querySelectorAll('.radio-indicator').forEach(function(r) {
|
|
521
|
+
r.classList.remove('uc-border-accents-blue');
|
|
522
|
+
r.classList.add('uc-border-input');
|
|
523
|
+
r.innerHTML = '';
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
var indicator = el.querySelector('.radio-indicator');
|
|
527
|
+
indicator.classList.remove('uc-border-input');
|
|
528
|
+
indicator.classList.add('uc-border-accents-blue');
|
|
529
|
+
indicator.innerHTML = '<div class="uc-w-2 uc-h-2 uc-rounded-full uc-bg-accents-blue"></div>';
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// UCScrollView — drag-to-scroll and scroll indicators
|
|
533
|
+
var UCScrollView = {
|
|
534
|
+
init: function() {
|
|
535
|
+
// Drag-to-scroll for horizontal containers
|
|
536
|
+
document.querySelectorAll('.uc-drag-scroll').forEach(function(el) {
|
|
537
|
+
if (el.hasAttribute('data-drag-init')) return;
|
|
538
|
+
el.setAttribute('data-drag-init', 'true');
|
|
539
|
+
|
|
540
|
+
var isDown = false;
|
|
541
|
+
var startX = 0;
|
|
542
|
+
var scrollLeft = 0;
|
|
543
|
+
|
|
544
|
+
el.addEventListener('mousedown', function(e) {
|
|
545
|
+
isDown = true;
|
|
546
|
+
el.style.cursor = 'grabbing';
|
|
547
|
+
el.style.userSelect = 'none';
|
|
548
|
+
startX = e.pageX - el.offsetLeft;
|
|
549
|
+
scrollLeft = el.scrollLeft;
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
el.addEventListener('mouseleave', function() {
|
|
553
|
+
isDown = false;
|
|
554
|
+
el.style.cursor = 'grab';
|
|
555
|
+
el.style.userSelect = '';
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
el.addEventListener('mouseup', function() {
|
|
559
|
+
isDown = false;
|
|
560
|
+
el.style.cursor = 'grab';
|
|
561
|
+
el.style.userSelect = '';
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
el.addEventListener('mousemove', function(e) {
|
|
565
|
+
if (!isDown) return;
|
|
566
|
+
e.preventDefault();
|
|
567
|
+
var x = e.pageX - el.offsetLeft;
|
|
568
|
+
var walk = (x - startX) * 1.5;
|
|
569
|
+
el.scrollLeft = scrollLeft - walk;
|
|
570
|
+
});
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
// Scroll indicators — vertical
|
|
574
|
+
document.querySelectorAll('.uc-scroll-indicator').forEach(function(indicator) {
|
|
575
|
+
if (indicator.hasAttribute('data-indicator-init')) return;
|
|
576
|
+
indicator.setAttribute('data-indicator-init', 'true');
|
|
577
|
+
|
|
578
|
+
var scroll = indicator.querySelector('.uc-scroll, .uc-scroll-hidden, .uc-scroll-autohide');
|
|
579
|
+
if (!scroll) return;
|
|
580
|
+
|
|
581
|
+
scroll.addEventListener('scroll', function() {
|
|
582
|
+
var st = scroll.scrollTop;
|
|
583
|
+
var sh = scroll.scrollHeight;
|
|
584
|
+
var ch = scroll.clientHeight;
|
|
585
|
+
indicator.classList.toggle('uc-show-top', st > 8);
|
|
586
|
+
indicator.classList.toggle('uc-show-bottom', st < sh - ch - 8);
|
|
587
|
+
});
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
// Scroll indicators — horizontal
|
|
591
|
+
document.querySelectorAll('.uc-scroll-indicator-h').forEach(function(indicator) {
|
|
592
|
+
if (indicator.hasAttribute('data-indicator-h-init')) return;
|
|
593
|
+
indicator.setAttribute('data-indicator-h-init', 'true');
|
|
594
|
+
|
|
595
|
+
var scroll = indicator.querySelector('.uc-scroll, .uc-scroll-hidden, .uc-scroll-autohide, [class*="uc-overflow-x"]');
|
|
596
|
+
if (!scroll) return;
|
|
597
|
+
|
|
598
|
+
scroll.addEventListener('scroll', function() {
|
|
599
|
+
var sl = scroll.scrollLeft;
|
|
600
|
+
var sw = scroll.scrollWidth;
|
|
601
|
+
var cw = scroll.clientWidth;
|
|
602
|
+
indicator.classList.toggle('uc-show-left', sl > 8);
|
|
603
|
+
indicator.classList.toggle('uc-show-right', sl < sw - cw - 8);
|
|
604
|
+
});
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
// UCNumberInput — increment/decrement with min/max constraints
|
|
610
|
+
var UCNumberInput = {
|
|
611
|
+
init: function() {
|
|
612
|
+
document.querySelectorAll('[data-number-input]').forEach(function(wrapper) {
|
|
613
|
+
if (wrapper.hasAttribute('data-ni-bound')) return;
|
|
614
|
+
wrapper.setAttribute('data-ni-bound', 'true');
|
|
615
|
+
|
|
616
|
+
var input = wrapper.querySelector('[data-number-value]');
|
|
617
|
+
var decBtn = wrapper.querySelector('[data-action="decrement"]');
|
|
618
|
+
var incBtn = wrapper.querySelector('[data-action="increment"]');
|
|
619
|
+
if (!input) return;
|
|
620
|
+
|
|
621
|
+
function updateButtons() {
|
|
622
|
+
var val = parseInt(input.value) || 0;
|
|
623
|
+
var min = input.hasAttribute('min') ? parseInt(input.min) : -Infinity;
|
|
624
|
+
var max = input.hasAttribute('max') ? parseInt(input.max) : Infinity;
|
|
625
|
+
if (decBtn) decBtn.disabled = val <= min;
|
|
626
|
+
if (incBtn) incBtn.disabled = val >= max;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
function step(delta) {
|
|
630
|
+
var val = parseInt(input.value) || 0;
|
|
631
|
+
var min = input.hasAttribute('min') ? parseInt(input.min) : -Infinity;
|
|
632
|
+
var max = input.hasAttribute('max') ? parseInt(input.max) : Infinity;
|
|
633
|
+
var next = Math.min(Math.max(val + delta, min), max);
|
|
634
|
+
input.value = next;
|
|
635
|
+
updateButtons();
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
if (decBtn) decBtn.addEventListener('click', function() { step(-1); });
|
|
639
|
+
if (incBtn) incBtn.addEventListener('click', function() { step(1); });
|
|
640
|
+
|
|
641
|
+
input.addEventListener('change', function() {
|
|
642
|
+
var min = input.hasAttribute('min') ? parseInt(input.min) : -Infinity;
|
|
643
|
+
var max = input.hasAttribute('max') ? parseInt(input.max) : Infinity;
|
|
644
|
+
var val = parseInt(input.value) || min;
|
|
645
|
+
input.value = Math.min(Math.max(val, min), max);
|
|
646
|
+
updateButtons();
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
updateButtons();
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
};
|
|
653
|
+
|
|
654
|
+
// UCPopover — toggle popover panels with outside-click close
|
|
655
|
+
var UCPopover = {
|
|
656
|
+
init: function() {
|
|
657
|
+
document.querySelectorAll('[data-popover-trigger]').forEach(function(btn) {
|
|
658
|
+
btn.onclick = function(e) {
|
|
659
|
+
e.stopPropagation();
|
|
660
|
+
var id = btn.getAttribute('data-popover-trigger');
|
|
661
|
+
var el = id ? document.getElementById(id) : null;
|
|
662
|
+
if (!el) return;
|
|
663
|
+
|
|
664
|
+
var isOpen = el.classList.contains('uc-open');
|
|
665
|
+
|
|
666
|
+
document.querySelectorAll('.uc-popover-content').forEach(function(p) {
|
|
667
|
+
p.classList.remove('uc-open');
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
if (!isOpen) el.classList.add('uc-open');
|
|
671
|
+
};
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
if (!document.body.hasAttribute('data-popover-outside-init')) {
|
|
675
|
+
document.body.setAttribute('data-popover-outside-init', 'true');
|
|
676
|
+
document.addEventListener('click', function(e) {
|
|
677
|
+
var target = e.target;
|
|
678
|
+
if (!target.closest('.uc-popover-content') && !target.closest('[data-popover-trigger]')) {
|
|
679
|
+
document.querySelectorAll('.uc-popover-content').forEach(function(p) {
|
|
680
|
+
p.classList.remove('uc-open');
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
// UCSelect — custom select dropdown with single selection
|
|
689
|
+
var UCSelect = {
|
|
690
|
+
init: function() {
|
|
691
|
+
if (document.body.hasAttribute('data-select-init')) return;
|
|
692
|
+
document.body.setAttribute('data-select-init', 'true');
|
|
693
|
+
|
|
694
|
+
document.addEventListener('click', function(e) {
|
|
695
|
+
if (!e.target.closest('.uc-select-wrapper')) {
|
|
696
|
+
document.querySelectorAll('.uc-select-dropdown').forEach(function(d) {
|
|
697
|
+
d.classList.remove('open');
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
|
|
704
|
+
// toggleSelect — called via onclick in HTML
|
|
705
|
+
function toggleSelect(id) {
|
|
706
|
+
var dropdown = document.getElementById(id);
|
|
707
|
+
document.querySelectorAll('.uc-select-dropdown').forEach(function(d) {
|
|
708
|
+
if (d.id !== id) d.classList.remove('open');
|
|
709
|
+
});
|
|
710
|
+
dropdown.classList.toggle('open');
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
// selectItem — called via onclick in HTML
|
|
714
|
+
function selectItem(id, triggerId, value) {
|
|
715
|
+
document.getElementById(triggerId).querySelector('span').textContent = value;
|
|
716
|
+
document.getElementById(triggerId).querySelector('span').classList.remove('placeholder');
|
|
717
|
+
var dropdown = document.getElementById(id);
|
|
718
|
+
dropdown.querySelectorAll('.uc-select-item').forEach(function(i) {
|
|
719
|
+
i.classList.remove('selected');
|
|
720
|
+
});
|
|
721
|
+
dropdown.querySelectorAll('.uc-select-item').forEach(function(i) {
|
|
722
|
+
if (i.textContent.trim() === value) i.classList.add('selected');
|
|
723
|
+
});
|
|
724
|
+
dropdown.classList.remove('open');
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
// UCToast — programmatic toast notifications
|
|
728
|
+
var UCToast = {
|
|
729
|
+
_count: 0,
|
|
730
|
+
|
|
731
|
+
show: function(type) {
|
|
732
|
+
var container = document.getElementById('toast-container');
|
|
733
|
+
if (!container) return;
|
|
734
|
+
|
|
735
|
+
var id = 'toast-' + (++UCToast._count);
|
|
736
|
+
var configs = {
|
|
737
|
+
default: { title: 'Scheduled: Catch up', desc: 'Friday, February 14, 2026 at 5:57 PM', icon: '', btn: 'Undo' },
|
|
738
|
+
success: { title: 'Success', desc: 'Your changes have been saved.', icon: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="uc-w-5 uc-h-5 uc-text-accents-blue"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="M22 4 12 14.01l-3-3"/></svg>', btn: '' },
|
|
739
|
+
error: { title: 'Error', desc: 'Something went wrong. Please try again.', icon: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="uc-w-5 uc-h-5 uc-text-accents-red"><circle cx="12" cy="12" r="10"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/></svg>', btn: 'Retry' },
|
|
740
|
+
action: { title: 'Event created', desc: 'Sunday, December 03, 2023', icon: '', btn: 'Undo' }
|
|
741
|
+
};
|
|
742
|
+
|
|
743
|
+
var c = configs[type] || configs.default;
|
|
744
|
+
var toast = document.createElement('div');
|
|
745
|
+
toast.id = id;
|
|
746
|
+
toast.className = 'uc-flex uc-items-start uc-gap-3 uc-w-80 uc-p-4 uc-rounded-lg uc-border uc-border-border-default uc-bg-neutrals-surface uc-shadow-lg uc-mb-2';
|
|
747
|
+
toast.innerHTML =
|
|
748
|
+
(c.icon ? '<div class="uc-flex-shrink-0 uc-mt-0.5">' + c.icon + '</div>' : '') +
|
|
749
|
+
'<div class="uc-flex-1 uc-min-w-0">' +
|
|
750
|
+
'<p class="uc-text-sm uc-font-semibold">' + c.title + '</p>' +
|
|
751
|
+
'<p class="uc-text-xs uc-text-fg-disabled uc-mt-0.5">' + c.desc + '</p>' +
|
|
752
|
+
'</div>' +
|
|
753
|
+
(c.btn ? '<button onclick="this.parentElement.remove()" class="uc-flex-shrink-0 uc-inline-flex uc-items-center uc-justify-center uc-rounded-lg uc-text-xs uc-font-medium uc-h-7 uc-px-2 uc-border uc-border-border-strong uc-bg-neutrals-surface uc-hover:bg-neutrals-subtle uc-transition-colors">' + c.btn + '</button>' : '') +
|
|
754
|
+
'<button onclick="this.parentElement.remove()" class="uc-flex-shrink-0 uc-p-0.5 uc-text-fg-disabled uc-hover:text-fg-primary uc-transition-colors">' +
|
|
755
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="uc-w-3.5 uc-h-3.5"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>' +
|
|
756
|
+
'</button>';
|
|
757
|
+
|
|
758
|
+
container.appendChild(toast);
|
|
759
|
+
setTimeout(function() {
|
|
760
|
+
var el = document.getElementById(id);
|
|
761
|
+
if (el) el.remove();
|
|
762
|
+
}, 4000);
|
|
763
|
+
},
|
|
764
|
+
|
|
765
|
+
init: function() {
|
|
766
|
+
// Expose showToast globally for onclick use
|
|
767
|
+
window.showToast = function(type) { UCToast.show(type); };
|
|
768
|
+
}
|
|
769
|
+
};
|
|
770
|
+
|
|
771
|
+
// UCDialog — modal dialog with focus trap and keyboard support
|
|
772
|
+
var UCDialog = {
|
|
773
|
+
init: function() {
|
|
774
|
+
// Expose functions globally for onclick use
|
|
775
|
+
window.openDialog = function(id) {
|
|
776
|
+
var el = document.getElementById(id);
|
|
777
|
+
if (!el) return;
|
|
778
|
+
el.classList.add('uc-open');
|
|
779
|
+
el.removeAttribute('aria-hidden');
|
|
780
|
+
var focusable = el.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
|
|
781
|
+
if (focusable) focusable.focus();
|
|
782
|
+
el._keyHandler = function(e) {
|
|
783
|
+
if (e.key === 'Escape') { window.closeDialog(id); return; }
|
|
784
|
+
if (e.key !== 'Tab') return;
|
|
785
|
+
var all = el.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
|
|
786
|
+
var first = all[0];
|
|
787
|
+
var last = all[all.length - 1];
|
|
788
|
+
if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
|
|
789
|
+
else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
|
|
790
|
+
};
|
|
791
|
+
document.addEventListener('keydown', el._keyHandler);
|
|
792
|
+
};
|
|
793
|
+
|
|
794
|
+
window.closeDialog = function(id) {
|
|
795
|
+
var el = document.getElementById(id);
|
|
796
|
+
if (!el) return;
|
|
797
|
+
el.classList.remove('uc-open');
|
|
798
|
+
el.setAttribute('aria-hidden', 'true');
|
|
799
|
+
if (el._keyHandler) document.removeEventListener('keydown', el._keyHandler);
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
};
|
|
803
|
+
|
|
804
|
+
// UCTreeView — expandable/collapsible tree nodes
|
|
805
|
+
var UCTreeView = {
|
|
806
|
+
init: function() {
|
|
807
|
+
document.querySelectorAll('[data-tree]').forEach(function(tree) {
|
|
808
|
+
if (tree.hasAttribute('data-tree-bound')) return;
|
|
809
|
+
tree.setAttribute('data-tree-bound', 'true');
|
|
810
|
+
|
|
811
|
+
tree.querySelectorAll('[data-tree-branch]').forEach(function(branch) {
|
|
812
|
+
var toggle = branch.querySelector(':scope > .uc-tree-toggle');
|
|
813
|
+
if (!toggle) return;
|
|
814
|
+
toggle.addEventListener('click', function() {
|
|
815
|
+
branch.classList.toggle('open');
|
|
816
|
+
});
|
|
817
|
+
});
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
};
|
|
821
|
+
|
|
822
|
+
// UCSheet — slide-in panels from any edge
|
|
823
|
+
var UCSheet = {
|
|
824
|
+
init: function() {
|
|
825
|
+
// Expose functions globally for onclick use
|
|
826
|
+
window.openSheet = function(id) {
|
|
827
|
+
var overlay = document.getElementById('uc-sheet-overlay');
|
|
828
|
+
if (overlay) overlay.classList.add('uc-open');
|
|
829
|
+
var sheet = document.getElementById(id);
|
|
830
|
+
if (sheet) sheet.classList.add('uc-open');
|
|
831
|
+
};
|
|
832
|
+
|
|
833
|
+
window.closeSheet = function(id) {
|
|
834
|
+
var overlay = document.getElementById('uc-sheet-overlay');
|
|
835
|
+
if (overlay) overlay.classList.remove('uc-open');
|
|
836
|
+
var sheet = document.getElementById(id);
|
|
837
|
+
if (sheet) sheet.classList.remove('uc-open');
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
window.closeAllSheets = function() {
|
|
841
|
+
var overlay = document.getElementById('uc-sheet-overlay');
|
|
842
|
+
if (overlay) overlay.classList.remove('uc-open');
|
|
843
|
+
document.querySelectorAll('.uc-sheet-right,.uc-sheet-bottom,.uc-sheet-left').forEach(function(s) {
|
|
844
|
+
s.classList.remove('uc-open');
|
|
845
|
+
});
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
};
|
|
849
|
+
|
|
850
|
+
// Auto-initialize all components
|
|
851
|
+
(function() {
|
|
852
|
+
function initAll() {
|
|
853
|
+
UCAccordion.init();
|
|
854
|
+
UCCollapsible.init();
|
|
855
|
+
UCCombobox.init();
|
|
856
|
+
UCResizable.init();
|
|
857
|
+
UCCarousel.init();
|
|
858
|
+
UCDropdown.init();
|
|
859
|
+
UCScrollView.init();
|
|
860
|
+
UCNumberInput.init();
|
|
861
|
+
UCPopover.init();
|
|
862
|
+
UCSelect.init();
|
|
863
|
+
UCToast.init();
|
|
864
|
+
UCDialog.init();
|
|
865
|
+
UCTreeView.init();
|
|
866
|
+
UCSheet.init();
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
if (document.readyState === 'loading') {
|
|
870
|
+
document.addEventListener('DOMContentLoaded', initAll);
|
|
871
|
+
} else {
|
|
872
|
+
initAll();
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
document.addEventListener('astro:after-swap', function() {
|
|
876
|
+
document.body.removeAttribute('data-dropdowns-init');
|
|
877
|
+
document.body.removeAttribute('data-select-init');
|
|
878
|
+
document.body.removeAttribute('data-popover-outside-init');
|
|
879
|
+
document.body.removeAttribute('data-combobox-outside-init');
|
|
880
|
+
initAll();
|
|
881
|
+
});
|
|
882
|
+
})();
|
package/uicraft.min.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* uicraft.js v1.1.0
|
|
3
|
+
* https://getuicraft.com
|
|
4
|
+
* MIT License
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
var UCAccordion={init:function(){var uid=0;document.querySelectorAll('[data-accordion-item]').forEach(function(item){uid++;var trigger=item.querySelector('[data-accordion-trigger]');var content=item.querySelector('[data-accordion-content]');if(trigger&&content){var tId='acc-trigger-'+uid;var cId='acc-content-'+uid;trigger.id=tId;content.id=cId;trigger.setAttribute('aria-controls',cId);content.setAttribute('aria-labelledby',tId);}});function openContent(content){content.classList.remove('uc-hidden');content.classList.add('open');content.style.maxHeight=content.scrollHeight+16+'px';}function closeContent(content){content.style.maxHeight='0px';content.classList.remove('open');content.addEventListener('transitionend',function handler(){if(content.style.maxHeight==='0px'){content.classList.add('uc-hidden');}content.removeEventListener('transitionend',handler);});}document.querySelectorAll('[data-accordion-content]').forEach(function(content){if(!content.classList.contains('uc-hidden')&&!content.classList.contains('hidden')){content.classList.add('open');content.style.maxHeight=content.scrollHeight+16+'px';}});document.querySelectorAll('[data-accordion-trigger]').forEach(function(trigger){if(trigger.hasAttribute('data-accordion-init'))return;trigger.setAttribute('data-accordion-init','true');trigger.addEventListener('click',function(){var item=trigger.closest('[data-accordion-item]');var accordion=trigger.closest('[data-accordion]');var mode=accordion.getAttribute('data-accordion');var content=item.querySelector('[data-accordion-content]');var icon=trigger.querySelector('[data-accordion-icon]');var isOpen=!content.classList.contains('uc-hidden')&&!content.classList.contains('hidden')&&content.classList.contains('open');if(mode==='single'){accordion.querySelectorAll('[data-accordion-item]').forEach(function(otherItem){var otherContent=otherItem.querySelector('[data-accordion-content]');var otherTrigger=otherItem.querySelector('[data-accordion-trigger]');var otherIcon=otherItem.querySelector('[data-accordion-trigger][data-accordion-icon]');if(otherItem!==item&&!otherContent.classList.contains('uc-hidden')&&!otherContent.classList.contains('hidden')){closeContent(otherContent);if(otherIcon)otherIcon.classList.remove('uc-rotate-180');if(otherTrigger)otherTrigger.setAttribute('aria-expanded','false');}});}if(isOpen){closeContent(content);if(icon)icon.classList.remove('uc-rotate-180');trigger.setAttribute('aria-expanded','false');}else{content.classList.remove('uc-hidden');content.offsetHeight;openContent(content);if(icon)icon.classList.add('uc-rotate-180');trigger.setAttribute('aria-expanded','true');}});});}};var UCCollapsible={init:function(){document.querySelectorAll('[data-collapsible][data-collapsible-open]').forEach(function(collapsible){var content=collapsible.querySelector('[data-collapsible-content]');var icon=collapsible.querySelector('[data-collapsible-icon]');if(content){content.classList.remove('uc-hidden');if(collapsible.hasAttribute('data-collapsible-animated')){content.style.maxHeight=content.scrollHeight+'px';}}if(icon){icon.classList.add('uc-rotate-180');}});document.querySelectorAll('[data-collapsible-trigger]').forEach(function(trigger){if(trigger.hasAttribute('data-collapsible-bound'))return;trigger.setAttribute('data-collapsible-bound','true');trigger.addEventListener('click',function(){var collapsible=trigger.closest('[data-collapsible]');var content=collapsible.querySelector(':scope>[data-collapsible-content]');if(!content){content=collapsible.querySelector('[data-collapsible-content]');}var icon=collapsible.querySelector(':scope>*[data-collapsible-icon]')||collapsible.querySelector('[data-collapsible-icon]');var isAnimated=collapsible.hasAttribute('data-collapsible-animated');var labelCollapse=trigger.querySelector('[data-collapsible-label-collapse]');var labelExpand=trigger.querySelector('[data-collapsible-label-expand]');var isOpen;if(isAnimated){isOpen=parseInt(content.style.maxHeight)>0;}else{isOpen=!content.classList.contains('uc-hidden');}if(isOpen){if(isAnimated){content.style.maxHeight='0';}else{content.classList.add('uc-hidden');}if(icon)icon.classList.remove('uc-rotate-180');if(labelCollapse)labelCollapse.classList.add('uc-hidden');if(labelExpand)labelExpand.classList.remove('uc-hidden');collapsible.removeAttribute('data-collapsible-open');}else{if(isAnimated){content.style.maxHeight=content.scrollHeight+'px';}else{content.classList.remove('uc-hidden');}if(icon)icon.classList.add('uc-rotate-180');if(labelCollapse)labelCollapse.classList.remove('uc-hidden');if(labelExpand)labelExpand.classList.add('uc-hidden');collapsible.setAttribute('data-collapsible-open','');}});});}};var UCCombobox={init:function(){var checkSvg='<svg xmlns="http:var emptySpacer='<span class="uc-w-4 uc-h-4 uc-shrink-0 uc-combobox-icon"></span>';var xTagSvg='<svg xmlns="http:if(!document.body.hasAttribute('data-combobox-outside-init')){document.body.setAttribute('data-combobox-outside-init','true');document.addEventListener('click',function(e){if(!e.target.closest('.uc-combobox-wrapper')){document.querySelectorAll('[data-combobox-content]').forEach(function(el){el.classList.remove('uc-open');});}});}window.openCombobox=function(id){var el=document.getElementById(id);if(el)el.classList.add('uc-open');};window.toggleCombobox=function(id){var el=document.getElementById(id);if(el)el.classList.toggle('uc-open');};window.filterCombobox=function(input,id){var dropdown=document.getElementById(id);var query=input.value.toLowerCase();var items=dropdown.querySelectorAll('.uc-combobox-item');var groups=dropdown.querySelectorAll('[data-combobox-group]');var emptyEl=dropdown.querySelector('.uc-combobox-empty');var totalVisible=0;if(groups.length>0){groups.forEach(function(group){var groupItems=group.querySelectorAll('.uc-combobox-item');var groupVisible=0;groupItems.forEach(function(item){if(item.textContent.toLowerCase().includes(query)){item.classList.remove('uc-hidden');groupVisible++;totalVisible++;}else{item.classList.add('uc-hidden');}});group.style.display=groupVisible>0?'':'none';});}else{items.forEach(function(item){if(item.textContent.toLowerCase().includes(query)){item.classList.remove('uc-hidden');totalVisible++;}else{item.classList.add('uc-hidden');}});}if(emptyEl){emptyEl.classList.toggle('uc-hidden',totalVisible>0||!query);}};function setItemIcon(item,checked){var icon=item.querySelector('.uc-combobox-icon');if(icon)icon.outerHTML=checked?checkSvg:emptySpacer;}window.selectComboboxItem=function(item){var text=item.textContent.trim();var wrapper=item.closest('.uc-combobox-wrapper');var keepIcons=wrapper.hasAttribute('data-keep-icons');var input=wrapper.querySelector('input');var dropdown=item.closest('[data-combobox-content]');input.value=text;dropdown.querySelectorAll('.uc-combobox-item').forEach(function(i){i.classList.remove('uc-selected');if(!keepIcons)setItemIcon(i,false);});item.classList.add('uc-selected');if(!keepIcons)setItemIcon(item,true);dropdown.classList.remove('uc-open');};window.selectComboboxButton=function(item,dropdownId){var text=item.textContent.trim();var wrapper=item.closest('.uc-combobox-wrapper');var label=wrapper.querySelector('.uc-combobox-button-label');var dropdown=document.getElementById(dropdownId);label.textContent=text;label.classList.remove('uc-text-fg-disabled');dropdown.querySelectorAll('.uc-combobox-item').forEach(function(i){i.classList.remove('uc-selected');setItemIcon(i,false);});item.classList.add('uc-selected');setItemIcon(item,true);dropdown.classList.remove('uc-open');};window.toggleMultiComboboxItem=function(item){var isSelected=item.classList.toggle('uc-selected');setItemIcon(item,isSelected);var wrapper=item.closest('.uc-combobox-wrapper');var tagContainer=wrapper.querySelector('.uc-combobox-tags');var text=item.textContent.trim();if(isSelected){var tag=document.createElement('span');tag.className='uc-combobox-tag uc-inline-flex uc-items-center uc-gap-1 uc-rounded uc-bg-neutrals-subtle uc-px-2 uc-py-0.5 uc-text-xs uc-font-medium';tag.setAttribute('data-tag-value',text);tag.innerHTML=text+'<button type="button" onclick="event.stopPropagation();removeComboboxTag(this)" class="uc-ml-0.5 uc-rounded-sm uc-hover:bg-neutrals-muted uc-transition-colors">'+xTagSvg+'</button>';tagContainer.insertBefore(tag,tagContainer.querySelector('input'));}else{var existing=tagContainer.querySelector('[data-tag-value="'+text+'"]');if(existing)existing.remove();}UCCombobox._updateMultiPlaceholder(wrapper);};window.removeComboboxTag=function(btn){var tag=btn.closest('.uc-combobox-tag');if(!tag)return;var value=tag.getAttribute('data-tag-value');var wrapper=tag.closest('.uc-combobox-wrapper');tag.remove();var dropdown=wrapper.querySelector('[data-combobox-content]');if(dropdown){dropdown.querySelectorAll('.uc-combobox-item').forEach(function(item){if(item.textContent.trim()===value){item.classList.remove('uc-selected');setItemIcon(item,false);}});}UCCombobox._updateMultiPlaceholder(wrapper);};},_updateMultiPlaceholder:function(wrapper){var input=wrapper.querySelector('input');var tags=wrapper.querySelectorAll('.uc-combobox-tag');if(input){input.placeholder=tags.length>0?'':'Add framework...';}}};var UCResizable={init:function(){document.querySelectorAll('[data-resizable]').forEach(function(container){if(container.hasAttribute('data-resizable-init'))return;container.setAttribute('data-resizable-init','true');var direction=container.dataset.resizable;var isHorizontal=direction==='horizontal';var minPct=parseFloat(container.dataset.min||'10');var maxPct=parseFloat(container.dataset.max||'90');var handles=container.querySelectorAll(':scope>.uc-resize-handle');handles.forEach(function(handle){var isDown=false;var startPos=0;var prevPanel=null;var nextPanel=null;var containerSize=0;var prevStart=0;var nextStart=0;handle.addEventListener('mousedown',function(e){e.preventDefault();isDown=true;prevPanel=handle.previousElementSibling;nextPanel=handle.nextElementSibling;if(!prevPanel||!nextPanel)return;containerSize=isHorizontal?container.offsetWidth:container.offsetHeight;prevStart=isHorizontal?prevPanel.offsetWidth:prevPanel.offsetHeight;nextStart=isHorizontal?nextPanel.offsetWidth:nextPanel.offsetHeight;startPos=isHorizontal?e.clientX:e.clientY;document.body.style.cursor=isHorizontal?'col-resize':'row-resize';document.body.style.userSelect='none';handle.style.background='hsl(var(--accents-blue)/0.5)';});document.addEventListener('mousemove',function(e){if(!isDown||!prevPanel||!nextPanel)return;var delta=(isHorizontal?e.clientX:e.clientY)-startPos;var newPrev=prevStart+delta;var newNext=nextStart-delta;var minSize=containerSize*(minPct/100);var maxSize=containerSize*(maxPct/100);if(newPrev<minSize){newPrev=minSize;newNext=prevStart+nextStart-minSize;}if(newNext<minSize){newNext=minSize;newPrev=prevStart+nextStart-minSize;}if(newPrev>maxSize){newPrev=maxSize;newNext=prevStart+nextStart-maxSize;}if(newNext>maxSize){newNext=maxSize;newPrev=prevStart+nextStart-maxSize;}var prevPct=(newPrev/containerSize*100).toFixed(1);var nextPct=(newNext/containerSize*100).toFixed(1);if(isHorizontal){prevPanel.style.width=prevPct+'%';nextPanel.style.width=nextPct+'%';}else{prevPanel.style.height=prevPct+'%';nextPanel.style.height=nextPct+'%';}prevPanel.style.flex='none';nextPanel.style.flex='none';var prevLabel=prevPanel.querySelector('.uc-size-label');var nextLabel=nextPanel.querySelector('.uc-size-label');if(prevLabel)prevLabel.textContent=Math.round(parseFloat(prevPct))+'%';if(nextLabel)nextLabel.textContent=Math.round(parseFloat(nextPct))+'%';});document.addEventListener('mouseup',function(){if(!isDown)return;isDown=false;document.body.style.cursor='';document.body.style.userSelect='';handle.style.background='';});});});}};var UCCarousel={init:function(){document.querySelectorAll('[data-carousel]').forEach(function(el){if(el.hasAttribute('data-carousel-init'))return;el.setAttribute('data-carousel-init','true');var carousel=el;var track=carousel.querySelector('[data-carousel-track]');var prevBtn=carousel.querySelector('[data-carousel-prev]');var nextBtn=carousel.querySelector('[data-carousel-next]');var dotsContainer=carousel.querySelector('[data-carousel-dots]');var total=parseInt(carousel.dataset.total||'0');var visible=parseInt(carousel.dataset.visible||'1');var maxIndex=total-visible;var current=0;function update(){if(visible===1){track.style.transform='translateX(-'+(current*100)+'%)';}else{var slide=track.children[0];var gap=parseFloat(getComputedStyle(track).gap)||0;var offset=current*(slide.offsetWidth+gap);track.style.transform='translateX(-'+offset+'px)';}if(dotsContainer){dotsContainer.querySelectorAll('[data-dot]').forEach(function(dot){var idx=parseInt(dot.dataset.dot||'0');dot.className='uc-w-2 uc-h-2 uc-rounded-full uc-transition-colors '+(idx===current?'uc-bg-accents-blue':'uc-bg-neutrals-muted');});}if(prevBtn)prevBtn.style.opacity=current===0?'0.4':'1';if(nextBtn)nextBtn.style.opacity=current>=maxIndex?'0.4':'1';}if(prevBtn){prevBtn.addEventListener('click',function(){if(current>0){current--;update();}});}if(nextBtn){nextBtn.addEventListener('click',function(){if(current<maxIndex){current++;update();}});}if(dotsContainer){dotsContainer.querySelectorAll('[data-dot]').forEach(function(dot){dot.addEventListener('click',function(){current=Math.min(parseInt(dot.dataset.dot||'0'),maxIndex);update();});});}update();});}};var UCDropdown={init:function(){if(document.body.hasAttribute('data-dropdowns-init'))return;document.body.setAttribute('data-dropdowns-init','true');document.addEventListener('click',function(e){if(!e.target.closest('[data-dropdown-trigger]')&&!e.target.closest('.uc-dropdown-menu')){document.querySelectorAll('.uc-dropdown-menu').forEach(function(el){el.classList.remove('uc-open');});}});document.querySelectorAll('[data-dropdown-trigger]').forEach(function(trigger){if(trigger.hasAttribute('data-dropdown-bound'))return;trigger.setAttribute('data-dropdown-bound','true');trigger.addEventListener('click',function(e){e.stopPropagation();var targetId=trigger.getAttribute('data-dropdown-trigger');var content=document.getElementById(targetId);if(!content)return;document.querySelectorAll('.uc-dropdown-menu').forEach(function(el){if(el!==content)el.classList.remove('uc-open');});content.classList.toggle('uc-open');});});}};function toggleCheckbox(el){var indicator=el.querySelector('.checkbox-indicator');var isChecked=indicator.classList.contains('uc-bg-accents-blue');if(isChecked){indicator.classList.remove('uc-bg-accents-blue','uc-text-constant-white','uc-border-transparent');indicator.innerHTML='';}else{indicator.classList.add('uc-bg-accents-blue','uc-text-constant-white','uc-border-transparent');indicator.innerHTML='<svg xmlns="http:}}function selectRadio(el){var parent=el.closest('.uc-dropdown-menu');parent.querySelectorAll('.radio-indicator').forEach(function(r){r.classList.remove('uc-border-accents-blue');r.classList.add('uc-border-input');r.innerHTML='';});var indicator=el.querySelector('.radio-indicator');indicator.classList.remove('uc-border-input');indicator.classList.add('uc-border-accents-blue');indicator.innerHTML='<div class="uc-w-2 uc-h-2 uc-rounded-full uc-bg-accents-blue"></div>';}var UCScrollView={init:function(){document.querySelectorAll('.uc-drag-scroll').forEach(function(el){if(el.hasAttribute('data-drag-init'))return;el.setAttribute('data-drag-init','true');var isDown=false;var startX=0;var scrollLeft=0;el.addEventListener('mousedown',function(e){isDown=true;el.style.cursor='grabbing';el.style.userSelect='none';startX=e.pageX-el.offsetLeft;scrollLeft=el.scrollLeft;});el.addEventListener('mouseleave',function(){isDown=false;el.style.cursor='grab';el.style.userSelect='';});el.addEventListener('mouseup',function(){isDown=false;el.style.cursor='grab';el.style.userSelect='';});el.addEventListener('mousemove',function(e){if(!isDown)return;e.preventDefault();var x=e.pageX-el.offsetLeft;var walk=(x-startX)*1.5;el.scrollLeft=scrollLeft-walk;});});document.querySelectorAll('.uc-scroll-indicator').forEach(function(indicator){if(indicator.hasAttribute('data-indicator-init'))return;indicator.setAttribute('data-indicator-init','true');var scroll=indicator.querySelector('.uc-scroll,.uc-scroll-hidden,.uc-scroll-autohide');if(!scroll)return;scroll.addEventListener('scroll',function(){var st=scroll.scrollTop;var sh=scroll.scrollHeight;var ch=scroll.clientHeight;indicator.classList.toggle('uc-show-top',st>8);indicator.classList.toggle('uc-show-bottom',st<sh-ch-8);});});document.querySelectorAll('.uc-scroll-indicator-h').forEach(function(indicator){if(indicator.hasAttribute('data-indicator-h-init'))return;indicator.setAttribute('data-indicator-h-init','true');var scroll=indicator.querySelector('.uc-scroll,.uc-scroll-hidden,.uc-scroll-autohide,[class*="uc-overflow-x"]');if(!scroll)return;scroll.addEventListener('scroll',function(){var sl=scroll.scrollLeft;var sw=scroll.scrollWidth;var cw=scroll.clientWidth;indicator.classList.toggle('uc-show-left',sl>8);indicator.classList.toggle('uc-show-right',sl<sw-cw-8);});});}};var UCNumberInput={init:function(){document.querySelectorAll('[data-number-input]').forEach(function(wrapper){if(wrapper.hasAttribute('data-ni-bound'))return;wrapper.setAttribute('data-ni-bound','true');var input=wrapper.querySelector('[data-number-value]');var decBtn=wrapper.querySelector('[data-action="decrement"]');var incBtn=wrapper.querySelector('[data-action="increment"]');if(!input)return;function updateButtons(){var val=parseInt(input.value)||0;var min=input.hasAttribute('min')?parseInt(input.min):-Infinity;var max=input.hasAttribute('max')?parseInt(input.max):Infinity;if(decBtn)decBtn.disabled=val<=min;if(incBtn)incBtn.disabled=val>=max;}function step(delta){var val=parseInt(input.value)||0;var min=input.hasAttribute('min')?parseInt(input.min):-Infinity;var max=input.hasAttribute('max')?parseInt(input.max):Infinity;var next=Math.min(Math.max(val+delta,min),max);input.value=next;updateButtons();}if(decBtn)decBtn.addEventListener('click',function(){step(-1);});if(incBtn)incBtn.addEventListener('click',function(){step(1);});input.addEventListener('change',function(){var min=input.hasAttribute('min')?parseInt(input.min):-Infinity;var max=input.hasAttribute('max')?parseInt(input.max):Infinity;var val=parseInt(input.value)||min;input.value=Math.min(Math.max(val,min),max);updateButtons();});updateButtons();});}};var UCPopover={init:function(){document.querySelectorAll('[data-popover-trigger]').forEach(function(btn){btn.onclick=function(e){e.stopPropagation();var id=btn.getAttribute('data-popover-trigger');var el=id?document.getElementById(id):null;if(!el)return;var isOpen=el.classList.contains('uc-open');document.querySelectorAll('.uc-popover-content').forEach(function(p){p.classList.remove('uc-open');});if(!isOpen)el.classList.add('uc-open');};});if(!document.body.hasAttribute('data-popover-outside-init')){document.body.setAttribute('data-popover-outside-init','true');document.addEventListener('click',function(e){var target=e.target;if(!target.closest('.uc-popover-content')&&!target.closest('[data-popover-trigger]')){document.querySelectorAll('.uc-popover-content').forEach(function(p){p.classList.remove('uc-open');});}});}}};var UCSelect={init:function(){if(document.body.hasAttribute('data-select-init'))return;document.body.setAttribute('data-select-init','true');document.addEventListener('click',function(e){if(!e.target.closest('.uc-select-wrapper')){document.querySelectorAll('.uc-select-dropdown').forEach(function(d){d.classList.remove('open');});}});}};function toggleSelect(id){var dropdown=document.getElementById(id);document.querySelectorAll('.uc-select-dropdown').forEach(function(d){if(d.id!==id)d.classList.remove('open');});dropdown.classList.toggle('open');}function selectItem(id,triggerId,value){document.getElementById(triggerId).querySelector('span').textContent=value;document.getElementById(triggerId).querySelector('span').classList.remove('placeholder');var dropdown=document.getElementById(id);dropdown.querySelectorAll('.uc-select-item').forEach(function(i){i.classList.remove('selected');});dropdown.querySelectorAll('.uc-select-item').forEach(function(i){if(i.textContent.trim()===value)i.classList.add('selected');});dropdown.classList.remove('open');}var UCToast={_count:0,show:function(type){var container=document.getElementById('toast-container');if(!container)return;var id='toast-'+(++UCToast._count);var configs={default:{title:'Scheduled:Catch up',desc:'Friday,February 14,2026 at 5:57 PM',icon:'',btn:'Undo'},success:{title:'Success',desc:'Your changes have been saved.',icon:'<svg xmlns="http:error:{title:'Error',desc:'Something went wrong. Please try again.',icon:'<svg xmlns="http:action:{title:'Event created',desc:'Sunday,December 03,2023',icon:'',btn:'Undo'}};var c=configs[type]||configs.default;var toast=document.createElement('div');toast.id=id;toast.className='uc-flex uc-items-start uc-gap-3 uc-w-80 uc-p-4 uc-rounded-lg uc-border uc-border-border-default uc-bg-neutrals-surface uc-shadow-lg uc-mb-2';toast.innerHTML=(c.icon?'<div class="uc-flex-shrink-0 uc-mt-0.5">'+c.icon+'</div>':'')+'<div class="uc-flex-1 uc-min-w-0">'+'<p class="uc-text-sm uc-font-semibold">'+c.title+'</p>'+'<p class="uc-text-xs uc-text-fg-disabled uc-mt-0.5">'+c.desc+'</p>'+'</div>'+(c.btn?'<button onclick="this.parentElement.remove()" class="uc-flex-shrink-0 uc-inline-flex uc-items-center uc-justify-center uc-rounded-lg uc-text-xs uc-font-medium uc-h-7 uc-px-2 uc-border uc-border-border-strong uc-bg-neutrals-surface uc-hover:bg-neutrals-subtle uc-transition-colors">'+c.btn+'</button>':'')+'<button onclick="this.parentElement.remove()" class="uc-flex-shrink-0 uc-p-0.5 uc-text-fg-disabled uc-hover:text-fg-primary uc-transition-colors">'+'<svg xmlns="http:'</button>';container.appendChild(toast);setTimeout(function(){var el=document.getElementById(id);if(el)el.remove();},4000);},init:function(){window.showToast=function(type){UCToast.show(type);};}};var UCDialog={init:function(){window.openDialog=function(id){var el=document.getElementById(id);if(!el)return;el.classList.add('uc-open');el.removeAttribute('aria-hidden');var focusable=el.querySelector('button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"])');if(focusable)focusable.focus();el._keyHandler=function(e){if(e.key==='Escape'){window.closeDialog(id);return;}if(e.key!=='Tab')return;var all=el.querySelectorAll('button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"])');var first=all[0];var last=all[all.length-1];if(e.shiftKey&&document.activeElement===first){e.preventDefault();last.focus();}else if(!e.shiftKey&&document.activeElement===last){e.preventDefault();first.focus();}};document.addEventListener('keydown',el._keyHandler);};window.closeDialog=function(id){var el=document.getElementById(id);if(!el)return;el.classList.remove('uc-open');el.setAttribute('aria-hidden','true');if(el._keyHandler)document.removeEventListener('keydown',el._keyHandler);};}};var UCTreeView={init:function(){document.querySelectorAll('[data-tree]').forEach(function(tree){if(tree.hasAttribute('data-tree-bound'))return;tree.setAttribute('data-tree-bound','true');tree.querySelectorAll('[data-tree-branch]').forEach(function(branch){var toggle=branch.querySelector(':scope>.uc-tree-toggle');if(!toggle)return;toggle.addEventListener('click',function(){branch.classList.toggle('open');});});});}};var UCSheet={init:function(){window.openSheet=function(id){var overlay=document.getElementById('uc-sheet-overlay');if(overlay)overlay.classList.add('uc-open');var sheet=document.getElementById(id);if(sheet)sheet.classList.add('uc-open');};window.closeSheet=function(id){var overlay=document.getElementById('uc-sheet-overlay');if(overlay)overlay.classList.remove('uc-open');var sheet=document.getElementById(id);if(sheet)sheet.classList.remove('uc-open');};window.closeAllSheets=function(){var overlay=document.getElementById('uc-sheet-overlay');if(overlay)overlay.classList.remove('uc-open');document.querySelectorAll('.uc-sheet-right,.uc-sheet-bottom,.uc-sheet-left').forEach(function(s){s.classList.remove('uc-open');});};}};(function(){function initAll(){UCAccordion.init();UCCollapsible.init();UCCombobox.init();UCResizable.init();UCCarousel.init();UCDropdown.init();UCScrollView.init();UCNumberInput.init();UCPopover.init();UCSelect.init();UCToast.init();UCDialog.init();UCTreeView.init();UCSheet.init();}if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',initAll);}else{initAll();}document.addEventListener('astro:after-swap',function(){document.body.removeAttribute('data-dropdowns-init');document.body.removeAttribute('data-select-init');document.body.removeAttribute('data-popover-outside-init');document.body.removeAttribute('data-combobox-outside-init');initAll();});})();
|