@dodlhuat/basix 1.2.7 → 1.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +1 -1
  2. package/js/bottom-sheet.d.ts +37 -0
  3. package/js/calendar.d.ts +115 -0
  4. package/js/carousel.d.ts +34 -0
  5. package/js/chart.d.ts +73 -0
  6. package/js/code-viewer.d.ts +16 -0
  7. package/js/context-menu.d.ts +31 -0
  8. package/js/datepicker.d.ts +55 -0
  9. package/js/dropdown.d.ts +30 -0
  10. package/js/editor.d.ts +41 -0
  11. package/js/file-uploader.d.ts +48 -0
  12. package/js/flyout-menu.d.ts +37 -0
  13. package/js/gallery.d.ts +35 -0
  14. package/js/group-picker.d.ts +59 -0
  15. package/js/lightbox.d.ts +46 -0
  16. package/js/modal.d.ts +28 -0
  17. package/js/popover.d.ts +46 -0
  18. package/js/position.d.ts +31 -0
  19. package/js/push-menu.d.ts +31 -0
  20. package/js/range-slider.d.ts +9 -0
  21. package/js/scroll.d.ts +15 -0
  22. package/js/scrollbar.d.ts +48 -0
  23. package/js/select.d.ts +16 -0
  24. package/js/sidebar-nav.d.ts +22 -0
  25. package/js/stepper.d.ts +26 -0
  26. package/js/table.d.ts +98 -0
  27. package/js/tabs.d.ts +57 -0
  28. package/js/theme.d.ts +65 -0
  29. package/js/timepicker.d.ts +37 -0
  30. package/js/toast.d.ts +26 -0
  31. package/js/tooltip.d.ts +34 -0
  32. package/js/tree.d.ts +40 -0
  33. package/js/utils.d.ts +24 -0
  34. package/js/virtual-dropdown.d.ts +55 -0
  35. package/package.json +1 -1
  36. package/js/bottom-sheet.ts +0 -224
  37. package/js/calendar.ts +0 -774
  38. package/js/carousel.ts +0 -222
  39. package/js/chart.ts +0 -694
  40. package/js/code-viewer.ts +0 -188
  41. package/js/context-menu.ts +0 -252
  42. package/js/datepicker.ts +0 -640
  43. package/js/dropdown.ts +0 -180
  44. package/js/editor.ts +0 -492
  45. package/js/file-uploader.ts +0 -361
  46. package/js/flyout-menu.ts +0 -255
  47. package/js/gallery.ts +0 -237
  48. package/js/group-picker.ts +0 -451
  49. package/js/lightbox.ts +0 -333
  50. package/js/modal.ts +0 -171
  51. package/js/popover.ts +0 -221
  52. package/js/position.ts +0 -111
  53. package/js/push-menu.ts +0 -286
  54. package/js/range-slider.ts +0 -33
  55. package/js/scroll.ts +0 -47
  56. package/js/scrollbar.ts +0 -335
  57. package/js/select.ts +0 -235
  58. package/js/sidebar-nav.ts +0 -66
  59. package/js/stepper.ts +0 -109
  60. package/js/table.ts +0 -459
  61. package/js/tabs.ts +0 -280
  62. package/js/theme.ts +0 -235
  63. package/js/timepicker.ts +0 -202
  64. package/js/toast.ts +0 -134
  65. package/js/tooltip.ts +0 -196
  66. package/js/tree.ts +0 -244
  67. package/js/tsconfig.json +0 -18
  68. package/js/utils.ts +0 -119
  69. package/js/virtual-dropdown.ts +0 -396
package/js/stepper.ts DELETED
@@ -1,109 +0,0 @@
1
- interface StepperOptions {
2
- defaultStep?: number;
3
- clickable?: boolean;
4
- onChange?: (current: number, previous: number) => void;
5
- }
6
-
7
- class Stepper {
8
- private container: HTMLElement;
9
- private steps: HTMLElement[];
10
- private connectors: HTMLElement[];
11
- private current: number;
12
- private readonly onChange?: (current: number, previous: number) => void;
13
- private abortController = new AbortController();
14
-
15
- constructor(elementOrSelector: string | HTMLElement, options: StepperOptions = {}) {
16
- const element = typeof elementOrSelector === 'string'
17
- ? document.querySelector<HTMLElement>(elementOrSelector)
18
- : elementOrSelector;
19
-
20
- if (!element) throw new Error(`Stepper: element not found`);
21
-
22
- this.container = element;
23
- this.steps = Array.from(this.container.querySelectorAll<HTMLElement>('.stepper-step'));
24
- this.connectors = Array.from(this.container.querySelectorAll<HTMLElement>('.stepper-connector'));
25
- this.onChange = options.onChange;
26
- this.current = options.defaultStep ?? 0;
27
-
28
- if (this.steps.length === 0) {
29
- console.warn('Stepper: no .stepper-step elements found');
30
- return;
31
- }
32
-
33
- if (options.clickable) {
34
- this.container.classList.add('stepper-clickable');
35
- this.steps.forEach((step, i) => {
36
- step.addEventListener('click', () => this.goTo(i), { signal: this.abortController.signal });
37
- });
38
- }
39
-
40
- this.render();
41
- }
42
-
43
- private render(): void {
44
- this.steps.forEach((step, i) => {
45
- step.classList.remove('active', 'completed');
46
-
47
- if (i < this.current) step.classList.add('completed');
48
- else if (i === this.current) step.classList.add('active');
49
- });
50
-
51
- this.connectors.forEach((connector, i) => {
52
- connector.classList.toggle('completed', i < this.current);
53
- });
54
- }
55
-
56
- public next(): void {
57
- if (this.current < this.steps.length - 1) {
58
- this.goTo(this.current + 1);
59
- }
60
- }
61
-
62
- public prev(): void {
63
- if (this.current > 0) {
64
- this.goTo(this.current - 1);
65
- }
66
- }
67
-
68
- public goTo(index: number): void {
69
- if (index < 0 || index >= this.steps.length) return;
70
- const previous = this.current;
71
- this.current = index;
72
- this.render();
73
- if (this.onChange && previous !== index) {
74
- this.onChange(index, previous);
75
- }
76
- }
77
-
78
- public setError(index: number): void {
79
- if (index < 0 || index >= this.steps.length) return;
80
- this.steps[index].classList.add('error');
81
- }
82
-
83
- public clearError(index: number): void {
84
- if (index < 0 || index >= this.steps.length) return;
85
- this.steps[index].classList.remove('error');
86
- }
87
-
88
- public getStep(): number {
89
- return this.current;
90
- }
91
-
92
- public getStepCount(): number {
93
- return this.steps.length;
94
- }
95
-
96
- public isFirst(): boolean {
97
- return this.current === 0;
98
- }
99
-
100
- public isLast(): boolean {
101
- return this.current === this.steps.length - 1;
102
- }
103
-
104
- public destroy(): void {
105
- this.abortController.abort();
106
- }
107
- }
108
-
109
- export { Stepper, type StepperOptions };
package/js/table.ts DELETED
@@ -1,459 +0,0 @@
1
- import { Select } from "./select.js";
2
-
3
- interface TableColumn {
4
- key: string;
5
- label: string;
6
- sortable?: boolean;
7
- }
8
-
9
- interface TableRow {
10
- [key: string]: string | number | boolean;
11
- }
12
-
13
- interface TableOptions {
14
- data?: TableRow[];
15
- columns?: TableColumn[];
16
- pageSize?: number;
17
- }
18
-
19
- type SortDirection = 'asc' | 'desc';
20
-
21
- class Table {
22
- private container: HTMLElement;
23
- private data: TableRow[];
24
- private columns: TableColumn[];
25
- private pageSize: number;
26
- private currentPage: number;
27
- private sortColumn: string | null;
28
- private sortDirection: SortDirection;
29
- private filterText: string;
30
- private tableBody!: HTMLTableSectionElement;
31
- private tableHeader!: HTMLTableSectionElement;
32
- private paginationContainer!: HTMLDivElement;
33
- private abortController = new AbortController();
34
-
35
- constructor(elementOrSelector: string | HTMLElement, options: TableOptions = {}) {
36
- const element = typeof elementOrSelector === 'string'
37
- ? document.querySelector<HTMLElement>(elementOrSelector)
38
- : elementOrSelector;
39
-
40
- if (!element) {
41
- throw new Error(`Table: Element not found for selector "${elementOrSelector}"`);
42
- }
43
-
44
- this.container = element;
45
- this.data = options.data || [];
46
- this.columns = options.columns || [];
47
- this.pageSize = options.pageSize || 10;
48
- this.currentPage = 1;
49
- this.sortColumn = null;
50
- this.sortDirection = 'asc';
51
- this.filterText = '';
52
-
53
- if (this.data.length === 0 && this.container.querySelector('table')) {
54
- this.parseTableFromDOM();
55
- }
56
-
57
- this.init();
58
- }
59
-
60
- /**
61
- * Parses an existing HTML table in the DOM to extract data and columns
62
- */
63
- private parseTableFromDOM(): void {
64
- const table = this.container.querySelector('table');
65
- if (!table) return;
66
-
67
- const thead = table.querySelector('thead');
68
- const tbody = table.querySelector('tbody');
69
-
70
- if (!thead || !tbody) return;
71
-
72
- // Parse columns from header
73
- const ths = thead.querySelectorAll('th');
74
- this.columns = Array.from(ths).map((th, index) => ({
75
- key: `col${index}`,
76
- label: th.textContent?.trim() || '',
77
- sortable: true
78
- }));
79
-
80
- // Parse data from body rows
81
- const trs = tbody.querySelectorAll('tr');
82
- this.data = Array.from(trs).map(tr => {
83
- const row: TableRow = {};
84
- const tds = tr.querySelectorAll('td');
85
-
86
- tds.forEach((td, index) => {
87
- if (this.columns[index]) {
88
- row[this.columns[index].key] = td.textContent?.trim() || '';
89
- }
90
- });
91
-
92
- return row;
93
- });
94
-
95
- // Clear the existing static table
96
- this.container.innerHTML = '';
97
- }
98
-
99
- /**
100
- * Initializes the table by rendering controls, structure, and content
101
- */
102
- private init(): void {
103
- this.renderControls();
104
- this.renderTableStructure();
105
- this.render();
106
- }
107
-
108
- /**
109
- * Renders the search and page size controls
110
- */
111
- private renderControls(): void {
112
- const controlsDiv = document.createElement('div');
113
- controlsDiv.className = 'table-controls';
114
-
115
- // Search input
116
- const searchInput = document.createElement('input');
117
- searchInput.type = 'text';
118
- searchInput.placeholder = 'Search...';
119
- searchInput.className = 'search-input';
120
- searchInput.addEventListener('input', (e) => {
121
- this.handleSearch((e.target as HTMLInputElement).value);
122
- }, { signal: this.abortController.signal });
123
- controlsDiv.appendChild(searchInput);
124
-
125
- // Page size selector
126
- const selectGroup = document.createElement('div');
127
- selectGroup.className = 'select-group';
128
-
129
- const label = document.createElement('label');
130
- label.textContent = 'Page Size';
131
- selectGroup.appendChild(label);
132
-
133
- const pageSizeSelect = document.createElement('select');
134
- pageSizeSelect.className = 'page-size-select';
135
-
136
- [5, 10, 20, 50].forEach(size => {
137
- const option = document.createElement('option');
138
- option.value = String(size);
139
- option.textContent = `${size} per page`;
140
- option.selected = size === this.pageSize;
141
- pageSizeSelect.appendChild(option);
142
- });
143
-
144
- pageSizeSelect.addEventListener('change', (e) => {
145
- this.handlePageSizeChange(parseInt((e.target as HTMLSelectElement).value, 10));
146
- }, { signal: this.abortController.signal });
147
-
148
- this.assignUniqueId(pageSizeSelect, 'page-size-select-0');
149
- selectGroup.appendChild(pageSizeSelect);
150
- controlsDiv.appendChild(selectGroup);
151
-
152
- this.container.appendChild(controlsDiv);
153
- new Select('#' + pageSizeSelect.id);
154
- }
155
-
156
- /**
157
- * Creates the table structure (table, thead, tbody, pagination container)
158
- */
159
- private renderTableStructure(): void {
160
- const wrapper = document.createElement('div');
161
- wrapper.className = 'table-wrapper';
162
-
163
- const table = document.createElement('table');
164
- const thead = document.createElement('thead');
165
- const tbody = document.createElement('tbody');
166
-
167
- // Create header row
168
- const tr = document.createElement('tr');
169
- this.columns.forEach(col => {
170
- const th = document.createElement('th');
171
- th.textContent = col.label;
172
- th.dataset.key = col.key;
173
-
174
- if (col.sortable !== false) {
175
- th.classList.add('sortable');
176
- th.addEventListener('click', () => this.handleSort(col.key), { signal: this.abortController.signal });
177
- }
178
-
179
- tr.appendChild(th);
180
- });
181
- thead.appendChild(tr);
182
-
183
- table.appendChild(thead);
184
- table.appendChild(tbody);
185
- wrapper.appendChild(table);
186
- this.container.appendChild(wrapper);
187
-
188
- // Create pagination container
189
- const paginationDiv = document.createElement('div');
190
- paginationDiv.className = 'pagination';
191
- this.container.appendChild(paginationDiv);
192
-
193
- this.tableBody = tbody;
194
- this.tableHeader = thead;
195
- this.paginationContainer = paginationDiv;
196
- }
197
-
198
- /**
199
- * Returns filtered and sorted data based on current state
200
- */
201
- private getFilteredAndSortedData(): TableRow[] {
202
- let processedData = [...this.data];
203
-
204
- // Apply filter
205
- if (this.filterText) {
206
- const lowerFilter = this.filterText.toLowerCase();
207
- processedData = processedData.filter(row => {
208
- return this.columns.some(col => {
209
- const val = String(row[col.key] ?? '').toLowerCase();
210
- return val.includes(lowerFilter);
211
- });
212
- });
213
- }
214
-
215
- // Apply sort
216
- if (this.sortColumn) {
217
- processedData.sort((a, b) => {
218
- const valA = a[this.sortColumn!];
219
- const valB = b[this.sortColumn!];
220
-
221
- // Handle null/undefined values
222
- if (valA == null && valB == null) return 0;
223
- if (valA == null) return 1;
224
- if (valB == null) return -1;
225
-
226
- if (valA < valB) return this.sortDirection === 'asc' ? -1 : 1;
227
- if (valA > valB) return this.sortDirection === 'asc' ? 1 : -1;
228
- return 0;
229
- });
230
- }
231
-
232
- return processedData;
233
- }
234
-
235
- /**
236
- * Renders the table body, pagination, and header sort indicators
237
- */
238
- private render(): void {
239
- const processedData = this.getFilteredAndSortedData();
240
- const totalItems = processedData.length;
241
- const totalPages = Math.ceil(totalItems / this.pageSize);
242
-
243
- // Ensure current page is valid
244
- if (this.currentPage > totalPages && totalPages > 0) {
245
- this.currentPage = totalPages;
246
- }
247
- if (this.currentPage < 1 && totalPages > 0) {
248
- this.currentPage = 1;
249
- }
250
-
251
- const startIndex = (this.currentPage - 1) * this.pageSize;
252
- const endIndex = Math.min(startIndex + this.pageSize, totalItems);
253
- const pageData = processedData.slice(startIndex, endIndex);
254
-
255
- this.renderBody(pageData);
256
- this.renderPagination(totalItems, totalPages, startIndex, endIndex);
257
- this.updateHeaderSortIcons();
258
- }
259
-
260
- /**
261
- * Renders the table body rows
262
- */
263
- private renderBody(data: TableRow[]): void {
264
- this.tableBody.innerHTML = '';
265
-
266
- if (data.length === 0) {
267
- const tr = document.createElement('tr');
268
- const td = document.createElement('td');
269
- td.colSpan = this.columns.length;
270
- td.textContent = 'No results found';
271
- td.style.textAlign = 'center';
272
- tr.appendChild(td);
273
- this.tableBody.appendChild(tr);
274
- return;
275
- }
276
-
277
- data.forEach(row => {
278
- const tr = document.createElement('tr');
279
- this.columns.forEach(col => {
280
- const td = document.createElement('td');
281
- td.textContent = String(row[col.key] ?? '');
282
- td.setAttribute('data-label', col.label); // For mobile view
283
- tr.appendChild(td);
284
- });
285
- this.tableBody.appendChild(tr);
286
- });
287
- }
288
-
289
- /**
290
- * Updates the sort direction indicators in table headers
291
- */
292
- private updateHeaderSortIcons(): void {
293
- const ths = this.tableHeader.querySelectorAll('th');
294
- ths.forEach(th => {
295
- th.classList.remove('sort-asc', 'sort-desc');
296
- if (th.dataset.key === this.sortColumn) {
297
- th.classList.add(this.sortDirection === 'asc' ? 'sort-asc' : 'sort-desc');
298
- }
299
- });
300
- }
301
-
302
- /**
303
- * Renders pagination controls and info
304
- */
305
- private renderPagination(
306
- totalItems: number,
307
- totalPages: number,
308
- startIndex: number,
309
- endIndex: number
310
- ): void {
311
- this.paginationContainer.innerHTML = '';
312
-
313
- if (totalItems === 0) return;
314
-
315
- // Info text
316
- const info = document.createElement('div');
317
- info.className = 'pagination-info';
318
- info.textContent = `Showing ${startIndex + 1} to ${endIndex} of ${totalItems} entries`;
319
- this.paginationContainer.appendChild(info);
320
-
321
- // Pagination buttons
322
- const buttonsDiv = document.createElement('div');
323
- buttonsDiv.className = 'pagination-buttons';
324
-
325
- // Previous button
326
- const prevBtn = document.createElement('button');
327
- prevBtn.className = 'page-btn';
328
- prevBtn.textContent = 'Previous';
329
- prevBtn.disabled = this.currentPage === 1;
330
- prevBtn.addEventListener('click', () => this.setPage(this.currentPage - 1));
331
- buttonsDiv.appendChild(prevBtn);
332
-
333
- // Calculate page range to display (max 5 pages)
334
- let startPage = Math.max(1, this.currentPage - 2);
335
- let endPage = Math.min(totalPages, startPage + 4);
336
-
337
- if (endPage - startPage < 4) {
338
- startPage = Math.max(1, endPage - 4);
339
- }
340
-
341
- // Page number buttons
342
- for (let i = startPage; i <= endPage; i++) {
343
- const btn = document.createElement('button');
344
- btn.className = `page-btn ${i === this.currentPage ? 'active' : ''}`;
345
- btn.textContent = String(i);
346
- btn.addEventListener('click', () => this.setPage(i));
347
- buttonsDiv.appendChild(btn);
348
- }
349
-
350
- // Next button
351
- const nextBtn = document.createElement('button');
352
- nextBtn.className = 'page-btn';
353
- nextBtn.textContent = 'Next';
354
- nextBtn.disabled = this.currentPage === totalPages;
355
- nextBtn.addEventListener('click', () => this.setPage(this.currentPage + 1));
356
- buttonsDiv.appendChild(nextBtn);
357
-
358
- this.paginationContainer.appendChild(buttonsDiv);
359
- }
360
-
361
- /**
362
- * Handles search input changes
363
- */
364
- private handleSearch(text: string): void {
365
- this.filterText = text;
366
- this.currentPage = 1; // Reset to first page on search
367
- this.render();
368
- }
369
-
370
- /**
371
- * Handles column header clicks for sorting
372
- */
373
- private handleSort(key: string): void {
374
- if (this.sortColumn === key) {
375
- // Toggle sort direction
376
- this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
377
- } else {
378
- this.sortColumn = key;
379
- this.sortDirection = 'asc';
380
- }
381
- this.render();
382
- }
383
-
384
- /**
385
- * Handles page size changes
386
- */
387
- private handlePageSizeChange(size: number): void {
388
- this.pageSize = size;
389
- this.currentPage = 1;
390
- this.render();
391
- }
392
-
393
- /**
394
- * Sets the current page and re-renders
395
- */
396
- private setPage(page: number): void {
397
- this.currentPage = page;
398
- this.render();
399
- }
400
-
401
- /**
402
- * Assigns a unique ID to an element, incrementing if necessary
403
- */
404
- private assignUniqueId(element: HTMLElement, baseId: string): string | null {
405
- if (!element || !baseId) return null;
406
-
407
- let id = baseId;
408
- let counter = 1;
409
-
410
- // If baseId already ends with a number, extract it
411
- const match = baseId.match(/^(.*?)(\d+)$/);
412
- if (match) {
413
- id = match[1];
414
- counter = parseInt(match[2], 10);
415
- }
416
-
417
- let uniqueId = baseId;
418
-
419
- while (document.getElementById(uniqueId)) {
420
- counter++;
421
- uniqueId = `${id}${counter}`;
422
- }
423
-
424
- element.id = uniqueId;
425
- return uniqueId;
426
- }
427
-
428
- /**
429
- * Public API: Updates the table data and re-renders
430
- */
431
- public setData(data: TableRow[]): void {
432
- this.data = data;
433
- this.currentPage = 1;
434
- this.render();
435
- }
436
-
437
- /**
438
- * Public API: Updates the columns and re-renders
439
- */
440
- public setColumns(columns: TableColumn[]): void {
441
- this.columns = columns;
442
- this.container.innerHTML = '';
443
- this.init();
444
- }
445
-
446
- /**
447
- * Public API: Gets the current filtered and sorted data
448
- */
449
- public getData(): TableRow[] {
450
- return this.getFilteredAndSortedData();
451
- }
452
-
453
- public destroy(): void {
454
- this.abortController.abort();
455
- this.container.innerHTML = '';
456
- }
457
- }
458
-
459
- export { Table, TableRow, TableColumn, TableOptions };