@dodlhuat/basix 1.3.1 → 1.3.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 +14 -8
- package/css/accordion.scss +0 -5
- package/css/badge.scss +1 -6
- package/css/bottom-sheet.scss +3 -8
- package/css/breadcrumb.scss +6 -15
- package/css/button.scss +2 -1
- package/css/calendar.scss +0 -67
- package/css/card.scss +0 -5
- package/css/carousel.scss +0 -3
- package/css/chart.scss +0 -25
- package/css/chat-bubbles.scss +0 -15
- package/css/checkbox.scss +3 -2
- package/css/chips.scss +3 -7
- package/css/code-viewer.scss +1 -5
- package/css/context-menu.scss +5 -21
- package/css/datepicker.scss +6 -9
- package/css/docs.scss +0 -4
- package/css/dropdown.scss +1 -1
- package/css/editor.scss +1 -23
- package/css/file-uploader.scss +2 -2
- package/css/flyout-menu.scss +65 -58
- package/css/form.scss +0 -28
- package/css/gallery.scss +2 -3
- package/css/group-picker.scss +5 -35
- package/css/icons.scss +0 -3
- package/css/lightbox.scss +2 -4
- package/css/mixins.scss +8 -0
- package/css/modal.scss +3 -3
- package/css/parameters.scss +6 -1
- package/css/popover.scss +3 -15
- package/css/progress.scss +0 -6
- package/css/push-menu.scss +3 -28
- package/css/radiobutton.scss +2 -1
- package/css/range-slider.scss +1 -7
- package/css/scrollbar.scss +9 -16
- package/css/sidebar-nav.scss +0 -12
- package/css/stepper.scss +0 -4
- package/css/style.css +108 -116
- package/css/style.css.map +1 -1
- package/css/style.min.css +1 -1
- package/css/style.min.css.map +1 -1
- package/css/style.scss +1 -1
- package/css/table.scss +0 -4
- package/css/tabs.scss +0 -2
- package/css/timeline.scss +1 -13
- package/css/timepicker.scss +55 -39
- package/css/toast.scss +1 -1
- package/css/tooltip.scss +1 -5
- package/css/tree.scss +1 -1
- package/css/typography.scss +3 -3
- package/css/virtual-dropdown.scss +3 -28
- package/js/bottom-sheet.d.ts +3 -1
- package/js/bottom-sheet.js +26 -27
- package/js/calendar.d.ts +7 -0
- package/js/calendar.js +14 -33
- package/js/carousel.d.ts +2 -0
- package/js/carousel.js +13 -5
- package/js/chart.d.ts +4 -0
- package/js/chart.js +13 -31
- package/js/code-viewer.d.ts +1 -0
- package/js/code-viewer.js +4 -0
- package/js/context-menu.d.ts +9 -2
- package/js/context-menu.js +17 -14
- package/js/datepicker.d.ts +4 -0
- package/js/datepicker.js +26 -11
- package/js/dropdown.d.ts +3 -3
- package/js/dropdown.js +6 -9
- package/js/editor.d.ts +1 -1
- package/js/editor.js +14 -20
- package/js/file-uploader.d.ts +4 -0
- package/js/file-uploader.js +52 -43
- package/js/flyout-menu.d.ts +5 -3
- package/js/flyout-menu.js +23 -46
- package/js/gallery.d.ts +4 -0
- package/js/gallery.js +39 -50
- package/js/group-picker.d.ts +5 -0
- package/js/group-picker.js +12 -17
- package/js/lightbox.d.ts +3 -0
- package/js/lightbox.js +12 -6
- package/js/modal.d.ts +3 -1
- package/js/modal.js +14 -11
- package/js/popover.d.ts +2 -0
- package/js/popover.js +26 -30
- package/js/position.d.ts +2 -0
- package/js/position.js +1 -5
- package/js/push-menu.d.ts +2 -1
- package/js/push-menu.js +25 -48
- package/js/range-slider.d.ts +1 -0
- package/js/range-slider.js +5 -3
- package/js/scroll.d.ts +2 -0
- package/js/scroll.js +1 -0
- package/js/scrollbar.d.ts +2 -0
- package/js/scrollbar.js +24 -36
- package/js/select.d.ts +1 -0
- package/js/select.js +5 -10
- package/js/sidebar-nav.d.ts +2 -0
- package/js/sidebar-nav.js +8 -0
- package/js/stepper.d.ts +2 -0
- package/js/stepper.js +7 -1
- package/js/table.d.ts +4 -0
- package/js/table.js +15 -22
- package/js/tabs.d.ts +2 -0
- package/js/tabs.js +6 -14
- package/js/theme.d.ts +1 -0
- package/js/theme.js +5 -13
- package/js/timepicker.d.ts +22 -5
- package/js/timepicker.js +160 -57
- package/js/toast.d.ts +3 -1
- package/js/toast.js +25 -22
- package/js/tooltip.d.ts +2 -0
- package/js/tooltip.js +21 -19
- package/js/tree.d.ts +3 -0
- package/js/tree.js +13 -0
- package/js/utils.d.ts +1 -3
- package/js/utils.js +0 -3
- package/js/virtual-dropdown.d.ts +3 -0
- package/js/virtual-dropdown.js +25 -0
- package/package.json +2 -2
package/js/table.js
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import { Select } from "./select.js";
|
|
2
|
+
/** Dynamic data table with sorting, filtering, and pagination. */
|
|
2
3
|
class Table {
|
|
4
|
+
container;
|
|
5
|
+
data;
|
|
6
|
+
columns;
|
|
7
|
+
pageSize;
|
|
8
|
+
currentPage;
|
|
9
|
+
sortColumn;
|
|
10
|
+
sortDirection;
|
|
11
|
+
filterText;
|
|
12
|
+
tableBody;
|
|
13
|
+
tableHeader;
|
|
14
|
+
paginationContainer;
|
|
15
|
+
abortController = new AbortController();
|
|
3
16
|
constructor(elementOrSelector, options = {}) {
|
|
4
|
-
this.abortController = new AbortController();
|
|
5
17
|
const element = typeof elementOrSelector === 'string'
|
|
6
18
|
? document.querySelector(elementOrSelector)
|
|
7
19
|
: elementOrSelector;
|
|
@@ -32,14 +44,12 @@ class Table {
|
|
|
32
44
|
const tbody = table.querySelector('tbody');
|
|
33
45
|
if (!thead || !tbody)
|
|
34
46
|
return;
|
|
35
|
-
// Parse columns from header
|
|
36
47
|
const ths = thead.querySelectorAll('th');
|
|
37
48
|
this.columns = Array.from(ths).map((th, index) => ({
|
|
38
49
|
key: `col${index}`,
|
|
39
50
|
label: th.textContent?.trim() || '',
|
|
40
51
|
sortable: true
|
|
41
52
|
}));
|
|
42
|
-
// Parse data from body rows
|
|
43
53
|
const trs = tbody.querySelectorAll('tr');
|
|
44
54
|
this.data = Array.from(trs).map(tr => {
|
|
45
55
|
const row = {};
|
|
@@ -51,7 +61,6 @@ class Table {
|
|
|
51
61
|
});
|
|
52
62
|
return row;
|
|
53
63
|
});
|
|
54
|
-
// Clear the existing static table
|
|
55
64
|
this.container.innerHTML = '';
|
|
56
65
|
}
|
|
57
66
|
/**
|
|
@@ -68,7 +77,6 @@ class Table {
|
|
|
68
77
|
renderControls() {
|
|
69
78
|
const controlsDiv = document.createElement('div');
|
|
70
79
|
controlsDiv.className = 'table-controls';
|
|
71
|
-
// Search input
|
|
72
80
|
const searchInput = document.createElement('input');
|
|
73
81
|
searchInput.type = 'text';
|
|
74
82
|
searchInput.placeholder = 'Search...';
|
|
@@ -77,7 +85,6 @@ class Table {
|
|
|
77
85
|
this.handleSearch(e.target.value);
|
|
78
86
|
}, { signal: this.abortController.signal });
|
|
79
87
|
controlsDiv.appendChild(searchInput);
|
|
80
|
-
// Page size selector
|
|
81
88
|
const selectGroup = document.createElement('div');
|
|
82
89
|
selectGroup.className = 'select-group';
|
|
83
90
|
const label = document.createElement('label');
|
|
@@ -110,7 +117,6 @@ class Table {
|
|
|
110
117
|
const table = document.createElement('table');
|
|
111
118
|
const thead = document.createElement('thead');
|
|
112
119
|
const tbody = document.createElement('tbody');
|
|
113
|
-
// Create header row
|
|
114
120
|
const tr = document.createElement('tr');
|
|
115
121
|
this.columns.forEach(col => {
|
|
116
122
|
const th = document.createElement('th');
|
|
@@ -127,7 +133,6 @@ class Table {
|
|
|
127
133
|
table.appendChild(tbody);
|
|
128
134
|
wrapper.appendChild(table);
|
|
129
135
|
this.container.appendChild(wrapper);
|
|
130
|
-
// Create pagination container
|
|
131
136
|
const paginationDiv = document.createElement('div');
|
|
132
137
|
paginationDiv.className = 'pagination';
|
|
133
138
|
this.container.appendChild(paginationDiv);
|
|
@@ -140,7 +145,6 @@ class Table {
|
|
|
140
145
|
*/
|
|
141
146
|
getFilteredAndSortedData() {
|
|
142
147
|
let processedData = [...this.data];
|
|
143
|
-
// Apply filter
|
|
144
148
|
if (this.filterText) {
|
|
145
149
|
const lowerFilter = this.filterText.toLowerCase();
|
|
146
150
|
processedData = processedData.filter(row => {
|
|
@@ -150,12 +154,10 @@ class Table {
|
|
|
150
154
|
});
|
|
151
155
|
});
|
|
152
156
|
}
|
|
153
|
-
// Apply sort
|
|
154
157
|
if (this.sortColumn) {
|
|
155
158
|
processedData.sort((a, b) => {
|
|
156
159
|
const valA = a[this.sortColumn];
|
|
157
160
|
const valB = b[this.sortColumn];
|
|
158
|
-
// Handle null/undefined values
|
|
159
161
|
if (valA == null && valB == null)
|
|
160
162
|
return 0;
|
|
161
163
|
if (valA == null)
|
|
@@ -178,7 +180,6 @@ class Table {
|
|
|
178
180
|
const processedData = this.getFilteredAndSortedData();
|
|
179
181
|
const totalItems = processedData.length;
|
|
180
182
|
const totalPages = Math.ceil(totalItems / this.pageSize);
|
|
181
|
-
// Ensure current page is valid
|
|
182
183
|
if (this.currentPage > totalPages && totalPages > 0) {
|
|
183
184
|
this.currentPage = totalPages;
|
|
184
185
|
}
|
|
@@ -212,7 +213,7 @@ class Table {
|
|
|
212
213
|
this.columns.forEach(col => {
|
|
213
214
|
const td = document.createElement('td');
|
|
214
215
|
td.textContent = String(row[col.key] ?? '');
|
|
215
|
-
td.setAttribute('data-label', col.label);
|
|
216
|
+
td.setAttribute('data-label', col.label);
|
|
216
217
|
tr.appendChild(td);
|
|
217
218
|
});
|
|
218
219
|
this.tableBody.appendChild(tr);
|
|
@@ -237,28 +238,23 @@ class Table {
|
|
|
237
238
|
this.paginationContainer.innerHTML = '';
|
|
238
239
|
if (totalItems === 0)
|
|
239
240
|
return;
|
|
240
|
-
// Info text
|
|
241
241
|
const info = document.createElement('div');
|
|
242
242
|
info.className = 'pagination-info';
|
|
243
243
|
info.textContent = `Showing ${startIndex + 1} to ${endIndex} of ${totalItems} entries`;
|
|
244
244
|
this.paginationContainer.appendChild(info);
|
|
245
|
-
// Pagination buttons
|
|
246
245
|
const buttonsDiv = document.createElement('div');
|
|
247
246
|
buttonsDiv.className = 'pagination-buttons';
|
|
248
|
-
// Previous button
|
|
249
247
|
const prevBtn = document.createElement('button');
|
|
250
248
|
prevBtn.className = 'page-btn';
|
|
251
249
|
prevBtn.textContent = 'Previous';
|
|
252
250
|
prevBtn.disabled = this.currentPage === 1;
|
|
253
251
|
prevBtn.addEventListener('click', () => this.setPage(this.currentPage - 1));
|
|
254
252
|
buttonsDiv.appendChild(prevBtn);
|
|
255
|
-
// Calculate page range to display (max 5 pages)
|
|
256
253
|
let startPage = Math.max(1, this.currentPage - 2);
|
|
257
254
|
let endPage = Math.min(totalPages, startPage + 4);
|
|
258
255
|
if (endPage - startPage < 4) {
|
|
259
256
|
startPage = Math.max(1, endPage - 4);
|
|
260
257
|
}
|
|
261
|
-
// Page number buttons
|
|
262
258
|
for (let i = startPage; i <= endPage; i++) {
|
|
263
259
|
const btn = document.createElement('button');
|
|
264
260
|
btn.className = `page-btn ${i === this.currentPage ? 'active' : ''}`;
|
|
@@ -266,7 +262,6 @@ class Table {
|
|
|
266
262
|
btn.addEventListener('click', () => this.setPage(i));
|
|
267
263
|
buttonsDiv.appendChild(btn);
|
|
268
264
|
}
|
|
269
|
-
// Next button
|
|
270
265
|
const nextBtn = document.createElement('button');
|
|
271
266
|
nextBtn.className = 'page-btn';
|
|
272
267
|
nextBtn.textContent = 'Next';
|
|
@@ -280,7 +275,7 @@ class Table {
|
|
|
280
275
|
*/
|
|
281
276
|
handleSearch(text) {
|
|
282
277
|
this.filterText = text;
|
|
283
|
-
this.currentPage = 1;
|
|
278
|
+
this.currentPage = 1;
|
|
284
279
|
this.render();
|
|
285
280
|
}
|
|
286
281
|
/**
|
|
@@ -288,7 +283,6 @@ class Table {
|
|
|
288
283
|
*/
|
|
289
284
|
handleSort(key) {
|
|
290
285
|
if (this.sortColumn === key) {
|
|
291
|
-
// Toggle sort direction
|
|
292
286
|
this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
|
|
293
287
|
}
|
|
294
288
|
else {
|
|
@@ -320,7 +314,6 @@ class Table {
|
|
|
320
314
|
return null;
|
|
321
315
|
let id = baseId;
|
|
322
316
|
let counter = 1;
|
|
323
|
-
// If baseId already ends with a number, extract it
|
|
324
317
|
const match = baseId.match(/^(.*?)(\d+)$/);
|
|
325
318
|
if (match) {
|
|
326
319
|
id = match[1];
|
package/js/tabs.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
type TabLayout = 'horizontal' | 'vertical';
|
|
2
2
|
type MenuPosition = 'top' | 'bottom' | 'left' | 'right';
|
|
3
|
+
/** Configuration options for a Tabs instance. */
|
|
3
4
|
interface TabsOptions {
|
|
4
5
|
layout?: TabLayout;
|
|
5
6
|
defaultTab?: number;
|
|
6
7
|
menuPos?: MenuPosition;
|
|
7
8
|
onChange?: (index: number) => void;
|
|
8
9
|
}
|
|
10
|
+
/** Tabbed content component with horizontal/vertical layouts and keyboard navigation. */
|
|
9
11
|
declare class Tabs {
|
|
10
12
|
private container;
|
|
11
13
|
private options;
|
package/js/tabs.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
/** Tabbed content component with horizontal/vertical layouts and keyboard navigation. */
|
|
1
2
|
class Tabs {
|
|
3
|
+
container;
|
|
4
|
+
options;
|
|
5
|
+
tabItems;
|
|
6
|
+
tabPanels;
|
|
7
|
+
currentTab;
|
|
2
8
|
constructor(elementOrSelector, options = {}) {
|
|
3
9
|
const element = typeof elementOrSelector === 'string'
|
|
4
10
|
? document.querySelector(elementOrSelector)
|
|
@@ -7,7 +13,6 @@ class Tabs {
|
|
|
7
13
|
throw new Error(`Tabs: Element not found for selector "${elementOrSelector}"`);
|
|
8
14
|
}
|
|
9
15
|
this.container = element;
|
|
10
|
-
// Set default options
|
|
11
16
|
const layout = options.layout || 'horizontal';
|
|
12
17
|
this.options = {
|
|
13
18
|
layout,
|
|
@@ -24,13 +29,11 @@ class Tabs {
|
|
|
24
29
|
* Initializes the tabs component
|
|
25
30
|
*/
|
|
26
31
|
init() {
|
|
27
|
-
// Apply layout class
|
|
28
32
|
if (this.options.layout === 'vertical') {
|
|
29
33
|
this.container.classList.add('tabs-vertical');
|
|
30
34
|
}
|
|
31
35
|
this.tabItems = this.container.querySelectorAll('.tab-item');
|
|
32
36
|
this.tabPanels = this.container.querySelectorAll('.tab-panel');
|
|
33
|
-
// Validate that we have tabs and panels
|
|
34
37
|
if (this.tabItems.length === 0) {
|
|
35
38
|
console.warn('No tab items found in container');
|
|
36
39
|
return;
|
|
@@ -54,17 +57,14 @@ class Tabs {
|
|
|
54
57
|
e.preventDefault();
|
|
55
58
|
this.activateTab(index);
|
|
56
59
|
});
|
|
57
|
-
// Add keyboard navigation for accessibility
|
|
58
60
|
item.addEventListener('keydown', (e) => {
|
|
59
61
|
const keyEvent = e;
|
|
60
62
|
this.handleKeyboardNavigation(keyEvent, index);
|
|
61
63
|
});
|
|
62
|
-
// Set ARIA attributes
|
|
63
64
|
item.setAttribute('role', 'tab');
|
|
64
65
|
item.setAttribute('tabindex', index === this.options.defaultTab ? '0' : '-1');
|
|
65
66
|
item.setAttribute('aria-selected', index === this.options.defaultTab ? 'true' : 'false');
|
|
66
67
|
});
|
|
67
|
-
// Set ARIA attributes for panels
|
|
68
68
|
this.tabPanels.forEach((panel, index) => {
|
|
69
69
|
panel.setAttribute('role', 'tabpanel');
|
|
70
70
|
panel.setAttribute('aria-hidden', index === this.options.defaultTab ? 'false' : 'true');
|
|
@@ -125,7 +125,6 @@ class Tabs {
|
|
|
125
125
|
console.warn(`Invalid tab index: ${index}`);
|
|
126
126
|
return;
|
|
127
127
|
}
|
|
128
|
-
// Remove active class from all
|
|
129
128
|
this.tabItems.forEach((item, i) => {
|
|
130
129
|
item.classList.remove('active');
|
|
131
130
|
item.setAttribute('tabindex', '-1');
|
|
@@ -135,7 +134,6 @@ class Tabs {
|
|
|
135
134
|
panel.classList.remove('active');
|
|
136
135
|
panel.setAttribute('aria-hidden', 'true');
|
|
137
136
|
});
|
|
138
|
-
// Add active class to selected
|
|
139
137
|
this.tabItems[index].classList.add('active');
|
|
140
138
|
this.tabItems[index].setAttribute('tabindex', '0');
|
|
141
139
|
this.tabItems[index].setAttribute('aria-selected', 'true');
|
|
@@ -143,7 +141,6 @@ class Tabs {
|
|
|
143
141
|
this.tabPanels[index].setAttribute('aria-hidden', 'false');
|
|
144
142
|
const previousTab = this.currentTab;
|
|
145
143
|
this.currentTab = index;
|
|
146
|
-
// Call onChange callback if provided
|
|
147
144
|
if (this.options.onChange && previousTab !== index) {
|
|
148
145
|
this.options.onChange(index);
|
|
149
146
|
}
|
|
@@ -153,7 +150,6 @@ class Tabs {
|
|
|
153
150
|
*/
|
|
154
151
|
goToTab(index) {
|
|
155
152
|
this.activateTab(index);
|
|
156
|
-
// Focus the tab for keyboard users
|
|
157
153
|
if (this.tabItems[index]) {
|
|
158
154
|
this.tabItems[index].focus();
|
|
159
155
|
}
|
|
@@ -191,7 +187,6 @@ class Tabs {
|
|
|
191
187
|
tab.classList.add('disabled');
|
|
192
188
|
tab.setAttribute('aria-disabled', 'true');
|
|
193
189
|
tab.style.pointerEvents = 'none';
|
|
194
|
-
// If disabling the current tab, switch to the first enabled tab
|
|
195
190
|
if (index === this.currentTab) {
|
|
196
191
|
const firstEnabled = Array.from(this.tabItems).findIndex((item) => !item.classList.contains('disabled'));
|
|
197
192
|
if (firstEnabled !== -1) {
|
|
@@ -203,14 +198,11 @@ class Tabs {
|
|
|
203
198
|
* Public API: Destroy the tabs instance and clean up
|
|
204
199
|
*/
|
|
205
200
|
destroy() {
|
|
206
|
-
// Remove event listeners by cloning and replacing nodes
|
|
207
201
|
this.tabItems.forEach((item) => {
|
|
208
202
|
const newItem = item.cloneNode(true);
|
|
209
203
|
item.parentNode?.replaceChild(newItem, item);
|
|
210
204
|
});
|
|
211
|
-
// Remove classes
|
|
212
205
|
this.container.classList.remove('tabs-vertical');
|
|
213
|
-
// Remove ARIA attributes
|
|
214
206
|
this.tabItems.forEach((item) => {
|
|
215
207
|
item.removeAttribute('role');
|
|
216
208
|
item.removeAttribute('tabindex');
|
package/js/theme.d.ts
CHANGED
package/js/theme.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
+
/** Static class for managing light/dark theme switching with system preference and localStorage persistence. */
|
|
1
2
|
class Theme {
|
|
3
|
+
static STORAGE_KEY = 'theme';
|
|
4
|
+
static root;
|
|
5
|
+
static elements = null;
|
|
6
|
+
static mediaQuery = null;
|
|
2
7
|
/**
|
|
3
8
|
* Initializes the theme system with toggle functionality and system preference detection
|
|
4
9
|
*/
|
|
5
10
|
static init() {
|
|
6
11
|
this.root = document.documentElement;
|
|
7
|
-
// Get DOM elements
|
|
8
12
|
const toggleBtn = document.getElementById('theme-toggle');
|
|
9
13
|
const icon = document.getElementById('theme-icon');
|
|
10
14
|
const status = document.getElementById('status');
|
|
11
|
-
// Validate required elements
|
|
12
15
|
if (!toggleBtn || !icon) {
|
|
13
16
|
console.error('Theme toggle: missing DOM elements', { toggleBtn, icon });
|
|
14
17
|
if (status) {
|
|
@@ -17,16 +20,13 @@ class Theme {
|
|
|
17
20
|
return;
|
|
18
21
|
}
|
|
19
22
|
this.elements = { toggleBtn, icon, status };
|
|
20
|
-
// Initialize media query
|
|
21
23
|
if (window.matchMedia) {
|
|
22
24
|
this.mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
23
25
|
}
|
|
24
|
-
// Apply initial theme
|
|
25
26
|
const savedTheme = this.getSavedTheme();
|
|
26
27
|
const systemTheme = this.getSystemTheme();
|
|
27
28
|
const initialTheme = savedTheme || systemTheme;
|
|
28
29
|
this.applyTheme(initialTheme);
|
|
29
|
-
// Bind event listeners
|
|
30
30
|
this.bindToggleClick();
|
|
31
31
|
this.bindKeyboardShortcut();
|
|
32
32
|
this.bindSystemThemeChange();
|
|
@@ -77,10 +77,8 @@ class Theme {
|
|
|
77
77
|
this.root.setAttribute('data-theme', theme);
|
|
78
78
|
const isDark = theme === 'dark';
|
|
79
79
|
const { toggleBtn, icon } = this.elements;
|
|
80
|
-
// Update button state
|
|
81
80
|
toggleBtn.setAttribute('aria-pressed', String(isDark));
|
|
82
81
|
toggleBtn.setAttribute('aria-label', `Switch to ${isDark ? 'light' : 'dark'} mode`);
|
|
83
|
-
// Update icon — SVG sprite via <use> or font icon via class
|
|
84
82
|
const useEl = icon.querySelector('use');
|
|
85
83
|
if (useEl) {
|
|
86
84
|
const iconName = isDark ? icon.dataset.iconDark : icon.dataset.iconLight;
|
|
@@ -151,17 +149,14 @@ class Theme {
|
|
|
151
149
|
if (!this.mediaQuery)
|
|
152
150
|
return;
|
|
153
151
|
const handler = (e) => {
|
|
154
|
-
// Only apply system theme if user hasn't saved a preference
|
|
155
152
|
if (!this.getSavedTheme()) {
|
|
156
153
|
const matches = 'matches' in e ? e.matches : e.matches;
|
|
157
154
|
this.applyTheme(matches ? 'dark' : 'light');
|
|
158
155
|
}
|
|
159
156
|
};
|
|
160
|
-
// Modern API
|
|
161
157
|
if ('addEventListener' in this.mediaQuery) {
|
|
162
158
|
this.mediaQuery.addEventListener('change', handler);
|
|
163
159
|
}
|
|
164
|
-
// Legacy API (deprecated but still supported in older browsers)
|
|
165
160
|
else if ('addListener' in this.mediaQuery) {
|
|
166
161
|
this.mediaQuery.addListener(handler);
|
|
167
162
|
}
|
|
@@ -199,7 +194,4 @@ class Theme {
|
|
|
199
194
|
return this.getSavedTheme() !== null;
|
|
200
195
|
}
|
|
201
196
|
}
|
|
202
|
-
Theme.STORAGE_KEY = 'theme';
|
|
203
|
-
Theme.elements = null;
|
|
204
|
-
Theme.mediaQuery = null;
|
|
205
197
|
export { Theme };
|
package/js/timepicker.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
/** A start/end time pair as HH:MM strings. */
|
|
1
2
|
interface TimeSpan {
|
|
2
3
|
start: string;
|
|
3
4
|
end: string;
|
|
4
5
|
}
|
|
6
|
+
/** Configuration options for a TimeSpanPicker instance. */
|
|
5
7
|
interface TimeSpanPickerOptions {
|
|
6
8
|
onChange?: (start: string, end: string) => void;
|
|
7
9
|
defaultStart?: string;
|
|
@@ -9,6 +11,7 @@ interface TimeSpanPickerOptions {
|
|
|
9
11
|
fromString?: string;
|
|
10
12
|
toString?: string;
|
|
11
13
|
}
|
|
14
|
+
/** Interactive time-range picker with a draggable bar and dual time inputs. */
|
|
12
15
|
declare class TimeSpanPicker {
|
|
13
16
|
private container;
|
|
14
17
|
private startTimeInput;
|
|
@@ -16,17 +19,31 @@ declare class TimeSpanPicker {
|
|
|
16
19
|
private onChange?;
|
|
17
20
|
private readonly uid;
|
|
18
21
|
private fromString;
|
|
19
|
-
private
|
|
22
|
+
private toLabel;
|
|
23
|
+
private pickerEl;
|
|
24
|
+
private durationEl;
|
|
25
|
+
private barEl;
|
|
26
|
+
private barFillEl;
|
|
27
|
+
private startHandleEl;
|
|
28
|
+
private endHandleEl;
|
|
29
|
+
private dragState;
|
|
20
30
|
constructor(elementOrSelector: string | HTMLElement, options?: TimeSpanPickerOptions);
|
|
21
|
-
private
|
|
31
|
+
private queryEl;
|
|
22
32
|
private render;
|
|
23
|
-
private readonly
|
|
24
|
-
private readonly handleEndChange;
|
|
33
|
+
private readonly handleChange;
|
|
25
34
|
private attachEventListeners;
|
|
35
|
+
private attachBarListeners;
|
|
36
|
+
private beginDrag;
|
|
37
|
+
private readonly onStartHandleDown;
|
|
38
|
+
private readonly onEndHandleDown;
|
|
39
|
+
private readonly onFillDown;
|
|
40
|
+
private readonly onPointerMove;
|
|
41
|
+
private readonly onPointerUp;
|
|
26
42
|
private toMinutes;
|
|
43
|
+
private minutesToTime;
|
|
44
|
+
private snap;
|
|
27
45
|
private formatDuration;
|
|
28
46
|
private updateUI;
|
|
29
|
-
private handleChange;
|
|
30
47
|
getValue(): TimeSpan;
|
|
31
48
|
setValue(start: string, end: string): void;
|
|
32
49
|
reset(): void;
|