@dodlhuat/basix 1.4.2 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -1
- package/css/calendar.scss +4 -3
- package/css/code-viewer.scss +1 -1
- package/css/datepicker.scss +83 -70
- package/css/editor.scss +2 -1
- package/css/flyout-menu.scss +2 -1
- package/css/form.scss +11 -32
- package/css/mixins.scss +25 -0
- package/css/range-slider.scss +7 -6
- package/css/stepper.scss +2 -1
- package/css/style.css +84 -71
- package/css/style.css.map +1 -1
- package/css/style.min.css +1 -1
- package/css/style.min.css.map +1 -1
- package/css/timepicker.scss +1 -1
- package/css/virtual-dropdown.scss +6 -16
- package/js/bottom-sheet.d.ts +3 -5
- package/js/bottom-sheet.js +39 -58
- package/js/calendar.d.ts +1 -2
- package/js/calendar.js +77 -84
- package/js/carousel.d.ts +1 -1
- package/js/carousel.js +22 -14
- package/js/chart.d.ts +1 -1
- package/js/chart.js +104 -65
- package/js/code-viewer.d.ts +1 -1
- package/js/code-viewer.js +7 -18
- package/js/color-picker.d.ts +2 -2
- package/js/color-picker.js +20 -22
- package/js/context-menu.d.ts +1 -1
- package/js/context-menu.js +10 -12
- package/js/datepicker.d.ts +14 -3
- package/js/datepicker.js +180 -99
- package/js/dropdown.d.ts +1 -1
- package/js/dropdown.js +4 -5
- package/js/editor.d.ts +1 -1
- package/js/editor.js +30 -34
- package/js/file-uploader.d.ts +2 -9
- package/js/file-uploader.js +57 -86
- package/js/flyout-menu.d.ts +3 -3
- package/js/flyout-menu.js +20 -22
- package/js/gallery.d.ts +1 -2
- package/js/gallery.js +14 -20
- package/js/group-picker.d.ts +1 -1
- package/js/group-picker.js +22 -29
- package/js/lightbox.d.ts +2 -2
- package/js/lightbox.js +28 -27
- package/js/listeners.d.ts +7 -0
- package/js/listeners.js +14 -0
- package/js/modal.d.ts +2 -1
- package/js/modal.js +13 -20
- package/js/popover.d.ts +2 -2
- package/js/popover.js +42 -37
- package/js/position.js +3 -5
- package/js/push-menu.d.ts +2 -0
- package/js/push-menu.js +21 -15
- package/js/range-slider.d.ts +2 -2
- package/js/range-slider.js +7 -6
- package/js/scroll.js +4 -7
- package/js/scrollbar.d.ts +3 -3
- package/js/scrollbar.js +39 -42
- package/js/select.d.ts +1 -1
- package/js/select.js +19 -23
- package/js/sidebar-nav.d.ts +1 -1
- package/js/sidebar-nav.js +13 -9
- package/js/stepper.d.ts +1 -1
- package/js/stepper.js +9 -11
- package/js/table.d.ts +1 -1
- package/js/table.js +24 -23
- package/js/tabs.d.ts +1 -1
- package/js/tabs.js +10 -17
- package/js/theme.d.ts +1 -0
- package/js/theme.js +6 -15
- package/js/timepicker.d.ts +8 -6
- package/js/timepicker.js +36 -36
- package/js/toast.d.ts +2 -1
- package/js/toast.js +8 -4
- package/js/tooltip.d.ts +1 -4
- package/js/tooltip.js +14 -23
- package/js/tree.d.ts +0 -1
- package/js/tree.js +6 -11
- package/js/utils.js +7 -8
- package/js/virtual-dropdown.d.ts +1 -1
- package/js/virtual-dropdown.js +26 -28
- package/package.json +1 -1
- package/css/calendar.css +0 -928
- package/css/guitar-chords.css +0 -251
- package/js/form-builder.js +0 -107
- package/js/guitar-chords.js +0 -268
- package/js/lazy-loader.js +0 -121
- package/js/request.js +0 -51
package/js/scrollbar.d.ts
CHANGED
|
@@ -9,19 +9,19 @@ declare class Scrollbar {
|
|
|
9
9
|
private static activeInstance;
|
|
10
10
|
private static globalListenersInstalled;
|
|
11
11
|
private static instanceCount;
|
|
12
|
-
private static
|
|
12
|
+
private static globalListeners;
|
|
13
13
|
private readonly container;
|
|
14
14
|
private readonly viewport;
|
|
15
15
|
private readonly content;
|
|
16
16
|
private readonly track;
|
|
17
17
|
private readonly thumb;
|
|
18
18
|
private readonly MIN_THUMB_HEIGHT;
|
|
19
|
-
private readonly
|
|
19
|
+
private readonly resizeObserver;
|
|
20
20
|
private dragging;
|
|
21
21
|
private activePointerId;
|
|
22
22
|
private startPointerY;
|
|
23
23
|
private startThumbTop;
|
|
24
|
-
private
|
|
24
|
+
private listeners;
|
|
25
25
|
private constructor();
|
|
26
26
|
private getRequiredElements;
|
|
27
27
|
private getMinThumbHeight;
|
package/js/scrollbar.js
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
|
+
import { ListenerGroup } from './listeners.js';
|
|
1
2
|
class Scrollbar {
|
|
2
3
|
static instances = new WeakMap();
|
|
3
4
|
static activeInstance = null;
|
|
4
5
|
static globalListenersInstalled = false;
|
|
5
6
|
static instanceCount = 0;
|
|
6
|
-
static
|
|
7
|
+
static globalListeners = null;
|
|
7
8
|
container;
|
|
8
9
|
viewport;
|
|
9
10
|
content;
|
|
10
11
|
track;
|
|
11
12
|
thumb;
|
|
12
13
|
MIN_THUMB_HEIGHT;
|
|
13
|
-
|
|
14
|
+
resizeObserver;
|
|
14
15
|
dragging = false;
|
|
15
16
|
activePointerId = null;
|
|
16
17
|
startPointerY = 0;
|
|
17
18
|
startThumbTop = 0;
|
|
18
|
-
|
|
19
|
+
listeners = new ListenerGroup();
|
|
19
20
|
constructor(container) {
|
|
20
21
|
this.container = container;
|
|
21
22
|
const elements = this.getRequiredElements(container);
|
|
@@ -24,14 +25,14 @@ class Scrollbar {
|
|
|
24
25
|
this.track = elements.track;
|
|
25
26
|
this.thumb = elements.thumb;
|
|
26
27
|
this.MIN_THUMB_HEIGHT = this.getMinThumbHeight();
|
|
27
|
-
this.
|
|
28
|
+
this.resizeObserver = new ResizeObserver(() => this.updateThumb());
|
|
28
29
|
this.attachEventListeners();
|
|
29
30
|
Scrollbar.instances.set(container, this);
|
|
30
31
|
Scrollbar.instanceCount++;
|
|
31
32
|
if (!Scrollbar.globalListenersInstalled) {
|
|
32
33
|
Scrollbar.installGlobalListeners();
|
|
33
34
|
}
|
|
34
|
-
requestAnimationFrame(this.updateThumb);
|
|
35
|
+
requestAnimationFrame(() => this.updateThumb());
|
|
35
36
|
}
|
|
36
37
|
getRequiredElements(container) {
|
|
37
38
|
const viewport = container.querySelector('.viewport');
|
|
@@ -44,39 +45,37 @@ class Scrollbar {
|
|
|
44
45
|
return { viewport, content, track, thumb };
|
|
45
46
|
}
|
|
46
47
|
getMinThumbHeight() {
|
|
47
|
-
const cssValue = getComputedStyle(document.documentElement)
|
|
48
|
-
.getPropertyValue('--thumb-min')
|
|
49
|
-
.trim();
|
|
48
|
+
const cssValue = getComputedStyle(document.documentElement).getPropertyValue('--thumb-min').trim();
|
|
50
49
|
const parsed = parseInt(cssValue, 10);
|
|
51
50
|
const defaultMin = 28;
|
|
52
51
|
const absoluteMin = 16;
|
|
53
52
|
return Math.max(absoluteMin, parsed || defaultMin);
|
|
54
53
|
}
|
|
55
54
|
static installGlobalListeners() {
|
|
56
|
-
const
|
|
57
|
-
Scrollbar.
|
|
55
|
+
const listeners = new ListenerGroup();
|
|
56
|
+
Scrollbar.globalListeners = listeners;
|
|
58
57
|
document.addEventListener('pointermove', (e) => {
|
|
59
58
|
Scrollbar.activeInstance?.handlePointerMove(e);
|
|
60
|
-
}, { passive: false, signal:
|
|
59
|
+
}, { passive: false, signal: listeners.signal });
|
|
61
60
|
document.addEventListener('pointerup', (e) => {
|
|
62
61
|
Scrollbar.activeInstance?.handlePointerUp(e);
|
|
63
|
-
}, { signal:
|
|
62
|
+
}, { signal: listeners.signal });
|
|
64
63
|
document.addEventListener('pointercancel', (e) => {
|
|
65
64
|
Scrollbar.activeInstance?.handlePointerUp(e);
|
|
66
|
-
}, { signal:
|
|
65
|
+
}, { signal: listeners.signal });
|
|
67
66
|
Scrollbar.globalListenersInstalled = true;
|
|
68
67
|
}
|
|
69
68
|
attachEventListeners() {
|
|
70
|
-
const sig = { signal: this.
|
|
71
|
-
this.viewport.addEventListener('scroll', this.updateThumb, { passive: true
|
|
72
|
-
this.thumb.addEventListener('pointerdown', this.handleThumbPointerDown, sig);
|
|
73
|
-
this.track.addEventListener('click', this.handleTrackClick, sig);
|
|
74
|
-
this.container.addEventListener('wheel', this.handleContainerWheel, { passive: false
|
|
75
|
-
window.addEventListener('resize', this.updateThumb, sig);
|
|
76
|
-
this.
|
|
77
|
-
this.
|
|
78
|
-
}
|
|
79
|
-
updateThumb
|
|
69
|
+
const sig = { signal: this.listeners.signal };
|
|
70
|
+
this.viewport.addEventListener('scroll', () => this.updateThumb(), { ...sig, passive: true });
|
|
71
|
+
this.thumb.addEventListener('pointerdown', (e) => this.handleThumbPointerDown(e), sig);
|
|
72
|
+
this.track.addEventListener('click', (e) => this.handleTrackClick(e), sig);
|
|
73
|
+
this.container.addEventListener('wheel', (e) => this.handleContainerWheel(e), { ...sig, passive: false });
|
|
74
|
+
window.addEventListener('resize', () => this.updateThumb(), sig);
|
|
75
|
+
this.resizeObserver.observe(this.viewport);
|
|
76
|
+
this.resizeObserver.observe(this.content);
|
|
77
|
+
}
|
|
78
|
+
updateThumb() {
|
|
80
79
|
const viewportHeight = this.viewport.clientHeight;
|
|
81
80
|
const contentHeight = this.content.scrollHeight;
|
|
82
81
|
const trackHeight = this.track.clientHeight;
|
|
@@ -93,8 +92,8 @@ class Scrollbar {
|
|
|
93
92
|
const scrollRatio = this.viewport.scrollTop / (maxScroll || 1);
|
|
94
93
|
const thumbTop = scrollRatio * (maxThumbTop || 0);
|
|
95
94
|
this.thumb.style.top = `${thumbTop}px`;
|
|
96
|
-
}
|
|
97
|
-
handleThumbPointerDown
|
|
95
|
+
}
|
|
96
|
+
handleThumbPointerDown(e) {
|
|
98
97
|
e.preventDefault();
|
|
99
98
|
this.dragging = true;
|
|
100
99
|
this.activePointerId = e.pointerId;
|
|
@@ -110,8 +109,8 @@ class Scrollbar {
|
|
|
110
109
|
const trackRect = this.track.getBoundingClientRect();
|
|
111
110
|
this.startThumbTop = thumbRect.top - trackRect.top;
|
|
112
111
|
document.body.style.userSelect = 'none';
|
|
113
|
-
}
|
|
114
|
-
handlePointerMove
|
|
112
|
+
}
|
|
113
|
+
handlePointerMove(e) {
|
|
115
114
|
if (!this.dragging || this.activePointerId !== e.pointerId) {
|
|
116
115
|
return;
|
|
117
116
|
}
|
|
@@ -127,8 +126,8 @@ class Scrollbar {
|
|
|
127
126
|
const maxScroll = contentHeight - viewportHeight;
|
|
128
127
|
const scrollRatio = newThumbTop / (maxThumbTop || 1);
|
|
129
128
|
this.viewport.scrollTop = scrollRatio * (maxScroll || 0);
|
|
130
|
-
}
|
|
131
|
-
handlePointerUp
|
|
129
|
+
}
|
|
130
|
+
handlePointerUp(e) {
|
|
132
131
|
if (!this.dragging || this.activePointerId !== e.pointerId) {
|
|
133
132
|
return;
|
|
134
133
|
}
|
|
@@ -142,8 +141,8 @@ class Scrollbar {
|
|
|
142
141
|
this.activePointerId = null;
|
|
143
142
|
Scrollbar.activeInstance = null;
|
|
144
143
|
document.body.style.userSelect = '';
|
|
145
|
-
}
|
|
146
|
-
handleTrackClick
|
|
144
|
+
}
|
|
145
|
+
handleTrackClick(e) {
|
|
147
146
|
if (e.target === this.thumb) {
|
|
148
147
|
return;
|
|
149
148
|
}
|
|
@@ -160,8 +159,8 @@ class Scrollbar {
|
|
|
160
159
|
const scrollRatio = clampedThumbTop / (maxThumbTop || 1);
|
|
161
160
|
const scrollTop = scrollRatio * (maxScroll || 0);
|
|
162
161
|
this.viewport.scrollTo({ top: scrollTop, behavior: 'smooth' });
|
|
163
|
-
}
|
|
164
|
-
handleContainerWheel
|
|
162
|
+
}
|
|
163
|
+
handleContainerWheel(e) {
|
|
165
164
|
const { scrollTop, scrollHeight, clientHeight } = this.viewport;
|
|
166
165
|
const scrollable = scrollHeight > clientHeight;
|
|
167
166
|
const atTop = scrollTop === 0 && e.deltaY < 0;
|
|
@@ -170,25 +169,23 @@ class Scrollbar {
|
|
|
170
169
|
e.preventDefault();
|
|
171
170
|
}
|
|
172
171
|
this.viewport.scrollTop += e.deltaY;
|
|
173
|
-
}
|
|
172
|
+
}
|
|
174
173
|
destroy() {
|
|
175
|
-
this.
|
|
176
|
-
this.
|
|
174
|
+
this.listeners.destroy();
|
|
175
|
+
this.resizeObserver.disconnect();
|
|
177
176
|
Scrollbar.instances.delete(this.container);
|
|
178
177
|
if (Scrollbar.activeInstance === this) {
|
|
179
178
|
Scrollbar.activeInstance = null;
|
|
180
179
|
}
|
|
181
180
|
Scrollbar.instanceCount--;
|
|
182
181
|
if (Scrollbar.instanceCount === 0) {
|
|
183
|
-
Scrollbar.
|
|
184
|
-
Scrollbar.
|
|
182
|
+
Scrollbar.globalListeners?.destroy();
|
|
183
|
+
Scrollbar.globalListeners = null;
|
|
185
184
|
Scrollbar.globalListenersInstalled = false;
|
|
186
185
|
}
|
|
187
186
|
}
|
|
188
187
|
static create(elementOrSelector) {
|
|
189
|
-
const container = typeof elementOrSelector === 'string'
|
|
190
|
-
? document.querySelector(elementOrSelector)
|
|
191
|
-
: elementOrSelector;
|
|
188
|
+
const container = typeof elementOrSelector === 'string' ? document.querySelector(elementOrSelector) : elementOrSelector;
|
|
192
189
|
if (!container) {
|
|
193
190
|
throw new Error(`Scrollbar: Element not found for selector "${elementOrSelector}"`);
|
|
194
191
|
}
|
|
@@ -199,7 +196,7 @@ class Scrollbar {
|
|
|
199
196
|
}
|
|
200
197
|
static initAll(selector) {
|
|
201
198
|
const containers = document.querySelectorAll(selector);
|
|
202
|
-
return Array.from(containers).map(container => Scrollbar.create(container));
|
|
199
|
+
return Array.from(containers).map((container) => Scrollbar.create(container));
|
|
203
200
|
}
|
|
204
201
|
static initOne(elementOrSelector) {
|
|
205
202
|
return Scrollbar.create(elementOrSelector);
|
package/js/select.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ declare class Select {
|
|
|
2
2
|
private readonly element;
|
|
3
3
|
private readonly isMultiselect;
|
|
4
4
|
private readonly dropdown;
|
|
5
|
-
private
|
|
5
|
+
private listeners;
|
|
6
6
|
constructor(elementOrSelector: string | HTMLSelectElement);
|
|
7
7
|
destroy(): void;
|
|
8
8
|
value(): string | string[];
|
package/js/select.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
+
import { ListenerGroup } from './listeners.js';
|
|
1
2
|
class Select {
|
|
2
3
|
element;
|
|
3
4
|
isMultiselect;
|
|
4
5
|
dropdown;
|
|
5
|
-
|
|
6
|
+
listeners = new ListenerGroup();
|
|
6
7
|
constructor(elementOrSelector) {
|
|
7
|
-
const element = typeof elementOrSelector === 'string'
|
|
8
|
-
? document.querySelector(elementOrSelector)
|
|
9
|
-
: elementOrSelector;
|
|
8
|
+
const element = typeof elementOrSelector === 'string' ? document.querySelector(elementOrSelector) : elementOrSelector;
|
|
10
9
|
if (!element) {
|
|
11
10
|
throw new Error(`Select: Element not found for selector "${elementOrSelector}"`);
|
|
12
11
|
}
|
|
@@ -17,39 +16,36 @@ class Select {
|
|
|
17
16
|
}
|
|
18
17
|
this.isMultiselect = result.isMulti;
|
|
19
18
|
this.dropdown = result.dropdown;
|
|
20
|
-
|
|
19
|
+
document.addEventListener('click', (e) => {
|
|
21
20
|
if (this.dropdown && !this.dropdown.contains(e.target)) {
|
|
22
21
|
this.dropdown.classList.remove('open');
|
|
23
22
|
}
|
|
24
|
-
};
|
|
25
|
-
document.addEventListener('click', this.documentClickHandler);
|
|
23
|
+
}, { signal: this.listeners.signal });
|
|
26
24
|
}
|
|
27
25
|
destroy() {
|
|
28
|
-
|
|
26
|
+
this.listeners.destroy();
|
|
29
27
|
this.dropdown?.classList.remove('open');
|
|
30
28
|
}
|
|
31
29
|
value() {
|
|
32
30
|
const selectedValues = Array.from(this.element.options)
|
|
33
|
-
.filter(option => option.selected)
|
|
34
|
-
.map(option => option.value);
|
|
31
|
+
.filter((option) => option.selected)
|
|
32
|
+
.map((option) => option.value);
|
|
35
33
|
return this.isMultiselect ? selectedValues : selectedValues[0];
|
|
36
34
|
}
|
|
37
35
|
static init(elementOrSelector) {
|
|
38
|
-
const element = typeof elementOrSelector === 'string'
|
|
39
|
-
? document.querySelector(elementOrSelector)
|
|
40
|
-
: elementOrSelector;
|
|
36
|
+
const element = typeof elementOrSelector === 'string' ? document.querySelector(elementOrSelector) : elementOrSelector;
|
|
41
37
|
if (!element)
|
|
42
38
|
return null;
|
|
43
39
|
const result = Select.initElement(element);
|
|
44
40
|
if (!result)
|
|
45
41
|
return null;
|
|
46
|
-
const
|
|
42
|
+
const listeners = new ListenerGroup();
|
|
43
|
+
document.addEventListener('click', (e) => {
|
|
47
44
|
if (!result.dropdown.contains(e.target)) {
|
|
48
45
|
result.dropdown.classList.remove('open');
|
|
49
46
|
}
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
return () => document.removeEventListener('click', handler);
|
|
47
|
+
}, { signal: listeners.signal });
|
|
48
|
+
return () => listeners.destroy();
|
|
53
49
|
}
|
|
54
50
|
static initElement(element) {
|
|
55
51
|
if (!Select.transformSelect(element)) {
|
|
@@ -94,7 +90,7 @@ class Select {
|
|
|
94
90
|
return { isMulti, dropdown };
|
|
95
91
|
}
|
|
96
92
|
static closeAllDropdowns(exceptDropdown) {
|
|
97
|
-
document.querySelectorAll('.dropdown').forEach(dropdown => {
|
|
93
|
+
document.querySelectorAll('.dropdown').forEach((dropdown) => {
|
|
98
94
|
if (dropdown !== exceptDropdown) {
|
|
99
95
|
dropdown.classList.remove('open');
|
|
100
96
|
}
|
|
@@ -103,15 +99,15 @@ class Select {
|
|
|
103
99
|
static handleMultiSelect(option, optionsContainer, selected, selectElement) {
|
|
104
100
|
option.classList.toggle('selected');
|
|
105
101
|
const selectedOptions = Array.from(optionsContainer.querySelectorAll('.dropdown-option.selected'));
|
|
106
|
-
const values = selectedOptions.map(opt => opt.textContent?.trim() || '');
|
|
102
|
+
const values = selectedOptions.map((opt) => opt.textContent?.trim() || '');
|
|
107
103
|
selected.textContent = values.length ? values.join(', ') : 'Select options';
|
|
108
|
-
const selectedValues = selectedOptions.map(opt => opt.dataset.value || '');
|
|
109
|
-
Array.from(selectElement.options).forEach(opt => {
|
|
104
|
+
const selectedValues = selectedOptions.map((opt) => opt.dataset.value || '');
|
|
105
|
+
Array.from(selectElement.options).forEach((opt) => {
|
|
110
106
|
opt.selected = selectedValues.includes(opt.value);
|
|
111
107
|
});
|
|
112
108
|
}
|
|
113
109
|
static handleSingleSelect(option, optionsContainer, selected, dropdown, selectElement) {
|
|
114
|
-
optionsContainer.querySelectorAll('.dropdown-option').forEach(opt => {
|
|
110
|
+
optionsContainer.querySelectorAll('.dropdown-option').forEach((opt) => {
|
|
115
111
|
opt.classList.remove('selected');
|
|
116
112
|
});
|
|
117
113
|
option.classList.add('selected');
|
|
@@ -146,7 +142,7 @@ class Select {
|
|
|
146
142
|
optionsMenu.className = 'dropdown-options-menu hidden';
|
|
147
143
|
optionsMenu.innerHTML = 'Select options<span class="dropdown-options-icon icon icon-close"></span>';
|
|
148
144
|
dropdownOptions.appendChild(optionsMenu);
|
|
149
|
-
Array.from(select.options).forEach(opt => {
|
|
145
|
+
Array.from(select.options).forEach((opt) => {
|
|
150
146
|
const optDiv = document.createElement('div');
|
|
151
147
|
optDiv.className = 'dropdown-option';
|
|
152
148
|
optDiv.dataset.value = opt.value;
|
package/js/sidebar-nav.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ declare class SidebarNav {
|
|
|
12
12
|
private opts;
|
|
13
13
|
private touchStartX;
|
|
14
14
|
private touchStartY;
|
|
15
|
-
private
|
|
15
|
+
private listeners;
|
|
16
16
|
constructor(containerOrSelector: string | HTMLElement, options?: SidebarNavOptions);
|
|
17
17
|
open(): void;
|
|
18
18
|
close(): void;
|
package/js/sidebar-nav.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ListenerGroup } from './listeners.js';
|
|
1
2
|
class SidebarNav {
|
|
2
3
|
nav;
|
|
3
4
|
backdrop;
|
|
@@ -6,11 +7,9 @@ class SidebarNav {
|
|
|
6
7
|
opts;
|
|
7
8
|
touchStartX = 0;
|
|
8
9
|
touchStartY = 0;
|
|
9
|
-
|
|
10
|
+
listeners = new ListenerGroup();
|
|
10
11
|
constructor(containerOrSelector, options = {}) {
|
|
11
|
-
const container = typeof containerOrSelector === 'string'
|
|
12
|
-
? document.querySelector(containerOrSelector)
|
|
13
|
-
: containerOrSelector;
|
|
12
|
+
const container = typeof containerOrSelector === 'string' ? document.querySelector(containerOrSelector) : containerOrSelector;
|
|
14
13
|
this.opts = {
|
|
15
14
|
toggleSelector: options.toggleSelector ?? '.sidebar-toggle',
|
|
16
15
|
breakpoint: options.breakpoint ?? 768,
|
|
@@ -20,7 +19,7 @@ class SidebarNav {
|
|
|
20
19
|
this.nav = container?.querySelector('.sidebar-nav') ?? null;
|
|
21
20
|
this.backdrop = container?.querySelector('.sidebar-backdrop') ?? null;
|
|
22
21
|
this.toggleBtn = document.querySelector(this.opts.toggleSelector);
|
|
23
|
-
const sig = { signal: this.
|
|
22
|
+
const sig = { signal: this.listeners.signal };
|
|
24
23
|
this.toggleBtn?.addEventListener('click', () => this.toggle(), sig);
|
|
25
24
|
this.backdrop?.addEventListener('click', () => this.close(), sig);
|
|
26
25
|
window.addEventListener('resize', () => {
|
|
@@ -30,7 +29,7 @@ class SidebarNav {
|
|
|
30
29
|
document.addEventListener('touchstart', (e) => {
|
|
31
30
|
this.touchStartX = e.touches[0].clientX;
|
|
32
31
|
this.touchStartY = e.touches[0].clientY;
|
|
33
|
-
}, { passive: true
|
|
32
|
+
}, { ...sig, passive: true });
|
|
34
33
|
document.addEventListener('touchend', (e) => {
|
|
35
34
|
if (window.innerWidth > this.opts.breakpoint)
|
|
36
35
|
return;
|
|
@@ -44,7 +43,7 @@ class SidebarNav {
|
|
|
44
43
|
else if (this.isOpen() && dx <= -this.opts.swipeThreshold) {
|
|
45
44
|
this.close();
|
|
46
45
|
}
|
|
47
|
-
}, { passive: true
|
|
46
|
+
}, { ...sig, passive: true });
|
|
48
47
|
this.closeBtn = document.createElement('button');
|
|
49
48
|
this.closeBtn.className = 'sidebar-close';
|
|
50
49
|
this.closeBtn.setAttribute('aria-label', 'Close navigation');
|
|
@@ -61,13 +60,18 @@ class SidebarNav {
|
|
|
61
60
|
this.backdrop?.classList.remove('is-visible');
|
|
62
61
|
}
|
|
63
62
|
toggle() {
|
|
64
|
-
this.nav?.classList.contains('is-open')
|
|
63
|
+
if (this.nav?.classList.contains('is-open')) {
|
|
64
|
+
this.close();
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
this.open();
|
|
68
|
+
}
|
|
65
69
|
}
|
|
66
70
|
isOpen() {
|
|
67
71
|
return this.nav?.classList.contains('is-open') ?? false;
|
|
68
72
|
}
|
|
69
73
|
destroy() {
|
|
70
|
-
this.
|
|
74
|
+
this.listeners.destroy();
|
|
71
75
|
this.closeBtn?.remove();
|
|
72
76
|
}
|
|
73
77
|
}
|
package/js/stepper.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ declare class Stepper {
|
|
|
11
11
|
private current;
|
|
12
12
|
private readonly onChange?;
|
|
13
13
|
private readonly iconBasePath;
|
|
14
|
-
private
|
|
14
|
+
private listeners;
|
|
15
15
|
private injectedConnectors;
|
|
16
16
|
constructor(elementOrSelector: string | HTMLElement, options?: StepperOptions);
|
|
17
17
|
private injectConnectors;
|
package/js/stepper.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ListenerGroup } from './listeners.js';
|
|
1
2
|
class Stepper {
|
|
2
3
|
container;
|
|
3
4
|
steps;
|
|
@@ -5,12 +6,10 @@ class Stepper {
|
|
|
5
6
|
current;
|
|
6
7
|
onChange;
|
|
7
8
|
iconBasePath;
|
|
8
|
-
|
|
9
|
+
listeners = new ListenerGroup();
|
|
9
10
|
injectedConnectors = false;
|
|
10
11
|
constructor(elementOrSelector, options = {}) {
|
|
11
|
-
const element = typeof elementOrSelector === 'string'
|
|
12
|
-
? document.querySelector(elementOrSelector)
|
|
13
|
-
: elementOrSelector;
|
|
12
|
+
const element = typeof elementOrSelector === 'string' ? document.querySelector(elementOrSelector) : elementOrSelector;
|
|
14
13
|
if (!element)
|
|
15
14
|
throw new Error('Stepper: element not found');
|
|
16
15
|
this.container = element;
|
|
@@ -27,7 +26,7 @@ class Stepper {
|
|
|
27
26
|
if (options.clickable) {
|
|
28
27
|
this.container.classList.add('stepper-clickable');
|
|
29
28
|
this.steps.forEach((step, i) => {
|
|
30
|
-
step.addEventListener('click', () => this.goTo(i), { signal: this.
|
|
29
|
+
step.addEventListener('click', () => this.goTo(i), { signal: this.listeners.signal });
|
|
31
30
|
});
|
|
32
31
|
}
|
|
33
32
|
this.render();
|
|
@@ -88,9 +87,8 @@ class Stepper {
|
|
|
88
87
|
const previous = this.current;
|
|
89
88
|
this.current = index;
|
|
90
89
|
this.render();
|
|
91
|
-
if (
|
|
92
|
-
this.onChange(index, previous);
|
|
93
|
-
}
|
|
90
|
+
if (previous !== index)
|
|
91
|
+
this.onChange?.(index, previous);
|
|
94
92
|
}
|
|
95
93
|
setError(index) {
|
|
96
94
|
if (index < 0 || index >= this.steps.length)
|
|
@@ -115,12 +113,12 @@ class Stepper {
|
|
|
115
113
|
return this.current === this.steps.length - 1;
|
|
116
114
|
}
|
|
117
115
|
destroy() {
|
|
118
|
-
this.
|
|
116
|
+
this.listeners.destroy();
|
|
119
117
|
if (this.injectedConnectors) {
|
|
120
|
-
this.connectors.forEach(c => c.remove());
|
|
118
|
+
this.connectors.forEach((c) => c.remove());
|
|
121
119
|
this.connectors = [];
|
|
122
120
|
}
|
|
123
|
-
this.steps.forEach(step => step.removeAttribute('aria-current'));
|
|
121
|
+
this.steps.forEach((step) => step.removeAttribute('aria-current'));
|
|
124
122
|
}
|
|
125
123
|
}
|
|
126
124
|
export { Stepper };
|
package/js/table.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ declare class Table {
|
|
|
23
23
|
private tableBody;
|
|
24
24
|
private tableHeader;
|
|
25
25
|
private paginationContainer;
|
|
26
|
-
private
|
|
26
|
+
private listeners;
|
|
27
27
|
constructor(elementOrSelector: string | HTMLElement, options?: TableOptions);
|
|
28
28
|
private parseTableFromDOM;
|
|
29
29
|
private init;
|
package/js/table.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Select } from './select.js';
|
|
2
|
+
import { ListenerGroup } from './listeners.js';
|
|
2
3
|
class Table {
|
|
3
4
|
container;
|
|
4
5
|
data;
|
|
@@ -11,11 +12,9 @@ class Table {
|
|
|
11
12
|
tableBody;
|
|
12
13
|
tableHeader;
|
|
13
14
|
paginationContainer;
|
|
14
|
-
|
|
15
|
+
listeners = new ListenerGroup();
|
|
15
16
|
constructor(elementOrSelector, options = {}) {
|
|
16
|
-
const element = typeof elementOrSelector === 'string'
|
|
17
|
-
? document.querySelector(elementOrSelector)
|
|
18
|
-
: elementOrSelector;
|
|
17
|
+
const element = typeof elementOrSelector === 'string' ? document.querySelector(elementOrSelector) : elementOrSelector;
|
|
19
18
|
if (!element) {
|
|
20
19
|
throw new Error(`Table: Element not found for selector "${elementOrSelector}"`);
|
|
21
20
|
}
|
|
@@ -44,10 +43,10 @@ class Table {
|
|
|
44
43
|
this.columns = Array.from(ths).map((th, index) => ({
|
|
45
44
|
key: `col${index}`,
|
|
46
45
|
label: th.textContent?.trim() || '',
|
|
47
|
-
sortable: true
|
|
46
|
+
sortable: true,
|
|
48
47
|
}));
|
|
49
48
|
const trs = tbody.querySelectorAll('tr');
|
|
50
|
-
this.data = Array.from(trs).map(tr => {
|
|
49
|
+
this.data = Array.from(trs).map((tr) => {
|
|
51
50
|
const row = {};
|
|
52
51
|
const tds = tr.querySelectorAll('td');
|
|
53
52
|
tds.forEach((td, index) => {
|
|
@@ -73,7 +72,7 @@ class Table {
|
|
|
73
72
|
searchInput.className = 'search-input';
|
|
74
73
|
searchInput.addEventListener('input', (e) => {
|
|
75
74
|
this.handleSearch(e.target.value);
|
|
76
|
-
}, { signal: this.
|
|
75
|
+
}, { signal: this.listeners.signal });
|
|
77
76
|
controlsDiv.appendChild(searchInput);
|
|
78
77
|
const selectGroup = document.createElement('div');
|
|
79
78
|
selectGroup.className = 'select-group';
|
|
@@ -82,7 +81,7 @@ class Table {
|
|
|
82
81
|
selectGroup.appendChild(label);
|
|
83
82
|
const pageSizeSelect = document.createElement('select');
|
|
84
83
|
pageSizeSelect.className = 'page-size-select';
|
|
85
|
-
[5, 10, 20, 50].forEach(size => {
|
|
84
|
+
[5, 10, 20, 50].forEach((size) => {
|
|
86
85
|
const option = document.createElement('option');
|
|
87
86
|
option.value = String(size);
|
|
88
87
|
option.textContent = `${size} per page`;
|
|
@@ -91,7 +90,7 @@ class Table {
|
|
|
91
90
|
});
|
|
92
91
|
pageSizeSelect.addEventListener('change', (e) => {
|
|
93
92
|
this.handlePageSizeChange(parseInt(e.target.value, 10));
|
|
94
|
-
}, { signal: this.
|
|
93
|
+
}, { signal: this.listeners.signal });
|
|
95
94
|
this.assignUniqueId(pageSizeSelect, 'page-size-select-0');
|
|
96
95
|
selectGroup.appendChild(pageSizeSelect);
|
|
97
96
|
controlsDiv.appendChild(selectGroup);
|
|
@@ -105,13 +104,13 @@ class Table {
|
|
|
105
104
|
const thead = document.createElement('thead');
|
|
106
105
|
const tbody = document.createElement('tbody');
|
|
107
106
|
const tr = document.createElement('tr');
|
|
108
|
-
this.columns.forEach(col => {
|
|
107
|
+
this.columns.forEach((col) => {
|
|
109
108
|
const th = document.createElement('th');
|
|
110
109
|
th.textContent = col.label;
|
|
111
110
|
th.dataset.key = col.key;
|
|
112
111
|
if (col.sortable !== false) {
|
|
113
112
|
th.classList.add('sortable');
|
|
114
|
-
th.addEventListener('click', () => this.handleSort(col.key), { signal: this.
|
|
113
|
+
th.addEventListener('click', () => this.handleSort(col.key), { signal: this.listeners.signal });
|
|
115
114
|
}
|
|
116
115
|
tr.appendChild(th);
|
|
117
116
|
});
|
|
@@ -131,17 +130,18 @@ class Table {
|
|
|
131
130
|
let processedData = [...this.data];
|
|
132
131
|
if (this.filterText) {
|
|
133
132
|
const lowerFilter = this.filterText.toLowerCase();
|
|
134
|
-
processedData = processedData.filter(row => {
|
|
135
|
-
return this.columns.some(col => {
|
|
133
|
+
processedData = processedData.filter((row) => {
|
|
134
|
+
return this.columns.some((col) => {
|
|
136
135
|
const val = String(row[col.key] ?? '').toLowerCase();
|
|
137
136
|
return val.includes(lowerFilter);
|
|
138
137
|
});
|
|
139
138
|
});
|
|
140
139
|
}
|
|
141
140
|
if (this.sortColumn) {
|
|
141
|
+
const col = this.sortColumn;
|
|
142
142
|
processedData.sort((a, b) => {
|
|
143
|
-
const valA = a[
|
|
144
|
-
const valB = b[
|
|
143
|
+
const valA = a[col];
|
|
144
|
+
const valB = b[col];
|
|
145
145
|
if (valA == null && valB == null)
|
|
146
146
|
return 0;
|
|
147
147
|
if (valA == null)
|
|
@@ -186,9 +186,9 @@ class Table {
|
|
|
186
186
|
this.tableBody.appendChild(tr);
|
|
187
187
|
return;
|
|
188
188
|
}
|
|
189
|
-
data.forEach(row => {
|
|
189
|
+
data.forEach((row) => {
|
|
190
190
|
const tr = document.createElement('tr');
|
|
191
|
-
this.columns.forEach(col => {
|
|
191
|
+
this.columns.forEach((col) => {
|
|
192
192
|
const td = document.createElement('td');
|
|
193
193
|
td.textContent = String(row[col.key] ?? '');
|
|
194
194
|
td.setAttribute('data-label', col.label);
|
|
@@ -199,7 +199,7 @@ class Table {
|
|
|
199
199
|
}
|
|
200
200
|
updateHeaderSortIcons() {
|
|
201
201
|
const ths = this.tableHeader.querySelectorAll('th');
|
|
202
|
-
ths.forEach(th => {
|
|
202
|
+
ths.forEach((th) => {
|
|
203
203
|
th.classList.remove('sort-asc', 'sort-desc');
|
|
204
204
|
if (th.dataset.key === this.sortColumn) {
|
|
205
205
|
th.classList.add(this.sortDirection === 'asc' ? 'sort-asc' : 'sort-desc');
|
|
@@ -216,14 +216,15 @@ class Table {
|
|
|
216
216
|
this.paginationContainer.appendChild(info);
|
|
217
217
|
const buttonsDiv = document.createElement('div');
|
|
218
218
|
buttonsDiv.className = 'pagination-buttons';
|
|
219
|
+
const sig = { signal: this.listeners.signal };
|
|
219
220
|
const prevBtn = document.createElement('button');
|
|
220
221
|
prevBtn.className = 'page-btn';
|
|
221
222
|
prevBtn.textContent = 'Previous';
|
|
222
223
|
prevBtn.disabled = this.currentPage === 1;
|
|
223
|
-
prevBtn.addEventListener('click', () => this.setPage(this.currentPage - 1));
|
|
224
|
+
prevBtn.addEventListener('click', () => this.setPage(this.currentPage - 1), sig);
|
|
224
225
|
buttonsDiv.appendChild(prevBtn);
|
|
225
226
|
let startPage = Math.max(1, this.currentPage - 2);
|
|
226
|
-
|
|
227
|
+
const endPage = Math.min(totalPages, startPage + 4);
|
|
227
228
|
if (endPage - startPage < 4) {
|
|
228
229
|
startPage = Math.max(1, endPage - 4);
|
|
229
230
|
}
|
|
@@ -231,14 +232,14 @@ class Table {
|
|
|
231
232
|
const btn = document.createElement('button');
|
|
232
233
|
btn.className = `page-btn ${i === this.currentPage ? 'active' : ''}`;
|
|
233
234
|
btn.textContent = String(i);
|
|
234
|
-
btn.addEventListener('click', () => this.setPage(i));
|
|
235
|
+
btn.addEventListener('click', () => this.setPage(i), sig);
|
|
235
236
|
buttonsDiv.appendChild(btn);
|
|
236
237
|
}
|
|
237
238
|
const nextBtn = document.createElement('button');
|
|
238
239
|
nextBtn.className = 'page-btn';
|
|
239
240
|
nextBtn.textContent = 'Next';
|
|
240
241
|
nextBtn.disabled = this.currentPage === totalPages;
|
|
241
|
-
nextBtn.addEventListener('click', () => this.setPage(this.currentPage + 1));
|
|
242
|
+
nextBtn.addEventListener('click', () => this.setPage(this.currentPage + 1), sig);
|
|
242
243
|
buttonsDiv.appendChild(nextBtn);
|
|
243
244
|
this.paginationContainer.appendChild(buttonsDiv);
|
|
244
245
|
}
|
|
@@ -298,7 +299,7 @@ class Table {
|
|
|
298
299
|
return this.getFilteredAndSortedData();
|
|
299
300
|
}
|
|
300
301
|
destroy() {
|
|
301
|
-
this.
|
|
302
|
+
this.listeners.destroy();
|
|
302
303
|
this.container.innerHTML = '';
|
|
303
304
|
}
|
|
304
305
|
}
|
package/js/tabs.d.ts
CHANGED