@dodlhuat/basix 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.
Files changed (142) hide show
  1. package/README.md +1 -1
  2. package/css/accordion.scss +31 -22
  3. package/css/alert.scss +79 -27
  4. package/css/button.scss +151 -102
  5. package/css/card.scss +11 -12
  6. package/css/carousel.scss +123 -87
  7. package/css/chart.scss +9 -11
  8. package/css/chat-bubbles.scss +2 -2
  9. package/css/checkbox.scss +72 -55
  10. package/css/chips.scss +52 -52
  11. package/css/code-viewer.scss +73 -98
  12. package/css/datepicker.scss +20 -0
  13. package/css/dropdown.scss +151 -137
  14. package/css/editor.scss +9 -6
  15. package/css/file-uploader.scss +187 -195
  16. package/css/flyout-menu.scss +20 -13
  17. package/css/form.scss +168 -115
  18. package/css/gallery.scss +62 -63
  19. package/css/grid.scss +0 -1
  20. package/css/modal.scss +117 -72
  21. package/css/placeholder.scss +17 -12
  22. package/css/properties.scss +6 -0
  23. package/css/push-menu.scss +70 -23
  24. package/css/radiobutton.scss +86 -64
  25. package/css/range-slider.scss +136 -0
  26. package/css/scrollbar.scss +69 -69
  27. package/css/spinner.scss +41 -66
  28. package/css/style.css +4351 -3735
  29. package/css/style.css.map +1 -1
  30. package/css/style.scss +2 -1
  31. package/css/switch.scss +43 -42
  32. package/css/table.scss +61 -40
  33. package/css/tabs.scss +12 -7
  34. package/css/timeline.scss +72 -69
  35. package/css/timepicker.scss +151 -72
  36. package/css/toast.scss +49 -48
  37. package/css/tooltip.scss +112 -122
  38. package/css/tree.scss +135 -192
  39. package/css/typography.scss +70 -9
  40. package/css/virtual-dropdown.scss +201 -142
  41. package/js/carousel.js +45 -18
  42. package/js/carousel.ts +217 -173
  43. package/js/datepicker.js +505 -497
  44. package/js/datepicker.ts +9 -0
  45. package/js/editor.js +398 -415
  46. package/js/file-uploader.js +142 -128
  47. package/js/file-uploader.ts +364 -350
  48. package/js/gallery.js +22 -15
  49. package/js/gallery.ts +17 -12
  50. package/js/index.js +718 -720
  51. package/js/index.ts +7 -8
  52. package/js/push-menu.js +113 -101
  53. package/js/push-menu.ts +17 -2
  54. package/js/range-slider.js +26 -0
  55. package/js/range-slider.ts +33 -0
  56. package/js/timepicker.js +144 -98
  57. package/js/timepicker.ts +194 -131
  58. package/js/tree.js +56 -28
  59. package/js/tree.ts +239 -218
  60. package/package.json +1 -1
  61. package/css/accordion.css +0 -109
  62. package/css/accordion.css.map +0 -1
  63. package/css/alert.css +0 -57
  64. package/css/alert.css.map +0 -1
  65. package/css/button.css +0 -69
  66. package/css/button.css.map +0 -1
  67. package/css/card.css +0 -144
  68. package/css/card.css.map +0 -1
  69. package/css/carousel.css +0 -118
  70. package/css/carousel.css.map +0 -1
  71. package/css/chart.css +0 -159
  72. package/css/chart.css.map +0 -1
  73. package/css/chat-bubbles.css +0 -97
  74. package/css/chat-bubbles.css.map +0 -1
  75. package/css/checkbox.css +0 -77
  76. package/css/checkbox.css.map +0 -1
  77. package/css/chips.css +0 -72
  78. package/css/chips.css.map +0 -1
  79. package/css/code-viewer.css +0 -97
  80. package/css/code-viewer.css.map +0 -1
  81. package/css/colors.css +0 -63
  82. package/css/colors.css.map +0 -1
  83. package/css/datepicker.css +0 -264
  84. package/css/datepicker.css.map +0 -1
  85. package/css/defaults.css +0 -118
  86. package/css/defaults.css.map +0 -1
  87. package/css/dropdown.css +0 -146
  88. package/css/dropdown.css.map +0 -1
  89. package/css/editor.css +0 -413
  90. package/css/file-uploader.css +0 -194
  91. package/css/file-uploader.css.map +0 -1
  92. package/css/flyout-menu.css +0 -345
  93. package/css/flyout-menu.css.map +0 -1
  94. package/css/form-builder.css +0 -9
  95. package/css/form-builder.css.map +0 -1
  96. package/css/form-builder.scss +0 -11
  97. package/css/form.css +0 -130
  98. package/css/form.css.map +0 -1
  99. package/css/gallery.css +0 -91
  100. package/css/gallery.css.map +0 -1
  101. package/css/grid.css +0 -44
  102. package/css/grid.css.map +0 -1
  103. package/css/icons.css +0 -327
  104. package/css/icons.css.map +0 -1
  105. package/css/modal.css +0 -97
  106. package/css/modal.css.map +0 -1
  107. package/css/parameters.css +0 -1
  108. package/css/parameters.css.map +0 -1
  109. package/css/placeholder.css +0 -50
  110. package/css/placeholder.css.map +0 -1
  111. package/css/progress.css +0 -51
  112. package/css/progress.css.map +0 -1
  113. package/css/properties.css +0 -31
  114. package/css/properties.css.map +0 -1
  115. package/css/push-menu.css +0 -145
  116. package/css/push-menu.css.map +0 -1
  117. package/css/radiobutton.css +0 -91
  118. package/css/radiobutton.css.map +0 -1
  119. package/css/reset.css +0 -46
  120. package/css/reset.css.map +0 -1
  121. package/css/scrollbar.css +0 -91
  122. package/css/scrollbar.css.map +0 -1
  123. package/css/spinner.css +0 -118
  124. package/css/spinner.css.map +0 -1
  125. package/css/switch.css +0 -66
  126. package/css/switch.css.map +0 -1
  127. package/css/table.css +0 -201
  128. package/css/table.css.map +0 -1
  129. package/css/tabs.css +0 -135
  130. package/css/tabs.css.map +0 -1
  131. package/css/timeline.css +0 -69
  132. package/css/timeline.css.map +0 -1
  133. package/css/toast.css +0 -98
  134. package/css/toast.css.map +0 -1
  135. package/css/tooltip.css +0 -151
  136. package/css/tooltip.css.map +0 -1
  137. package/css/tree.css +0 -199
  138. package/css/tree.css.map +0 -1
  139. package/css/typography.css +0 -137
  140. package/css/typography.css.map +0 -1
  141. package/css/virtual-dropdown.css +0 -149
  142. package/css/virtual-dropdown.css.map +0 -1
package/js/carousel.ts CHANGED
@@ -1,173 +1,217 @@
1
- interface CarouselOptions {
2
- loop?: boolean;
3
- autoPlay?: boolean;
4
- autoPlayInterval?: number;
5
- }
6
-
7
- class Carousel {
8
- private root: HTMLElement;
9
- private options: CarouselOptions;
10
- private track!: HTMLUListElement;
11
- private slides!: HTMLElement[];
12
- private slideWidth!: number;
13
- private currentIndex!: number;
14
- private prevButton!: HTMLButtonElement;
15
- private nextButton!: HTMLButtonElement;
16
- private dotsNav!: HTMLDivElement;
17
- private dots!: HTMLButtonElement[];
18
-
19
- constructor(elementOrSelector: string | HTMLElement, options: CarouselOptions = {}) {
20
- const element = typeof elementOrSelector === 'string'
21
- ? document.querySelector<HTMLElement>(elementOrSelector)
22
- : elementOrSelector;
23
-
24
- this.options = {
25
- loop: options.loop ?? false,
26
- autoPlay: options.autoPlay ?? false,
27
- autoPlayInterval: options.autoPlayInterval ?? 3000
28
- };
29
-
30
- if (!element) {
31
- throw new Error(`Carousel: Element not found for selector "${elementOrSelector}"`);
32
- }
33
-
34
- this.root = element;
35
-
36
- this.init();
37
- }
38
-
39
- private init(): void {
40
- this.setupDOM();
41
- this.slides = Array.from(this.track.children) as HTMLElement[];
42
- this.slideWidth = this.slides[0].getBoundingClientRect().width;
43
- this.currentIndex = 0;
44
- this.bindEvents();
45
- this.updateDots(0);
46
- if (this.options.autoPlay) {
47
- this.startAutoPlay();
48
- }
49
- }
50
-
51
- private setupDOM(): void {
52
- const slides = Array.from(this.root.children) as HTMLElement[];
53
- const container = document.createElement('div');
54
- container.classList.add('carousel-track-container');
55
-
56
- this.track = document.createElement('ul');
57
- this.track.classList.add('carousel-track');
58
-
59
- slides.forEach(slide => {
60
- slide.classList.add('carousel-slide');
61
- this.track.appendChild(slide);
62
- });
63
-
64
- container.appendChild(this.track);
65
- this.root.appendChild(container);
66
-
67
- this.prevButton = document.createElement('button');
68
- this.prevButton.classList.add('carousel-button', 'carousel-button--left');
69
- this.prevButton.innerHTML = '<span class="icon-navigate_before icon"></span>';
70
- this.prevButton.setAttribute('aria-label', 'Previous Slide');
71
-
72
- this.nextButton = document.createElement('button');
73
- this.nextButton.classList.add('carousel-button', 'carousel-button--right');
74
- this.nextButton.innerHTML = '<span class="icon-navigate_next icon"></span>';
75
- this.nextButton.setAttribute('aria-label', 'Next Slide');
76
-
77
- this.root.appendChild(this.prevButton);
78
- this.root.appendChild(this.nextButton);
79
-
80
- this.dotsNav = document.createElement('div');
81
- this.dotsNav.classList.add('carousel-nav');
82
-
83
- this.dots = [];
84
- slides.forEach((_, index) => {
85
- const dot = document.createElement('button');
86
- dot.classList.add('carousel-indicator');
87
- dot.setAttribute('aria-label', `Slide ${index + 1}`);
88
- this.dotsNav.appendChild(dot);
89
- this.dots.push(dot);
90
- });
91
-
92
- this.root.appendChild(this.dotsNav);
93
- }
94
-
95
- private bindEvents(): void {
96
- this.nextButton.addEventListener('click', () => this.moveToNextSlide());
97
- this.prevButton.addEventListener('click', () => this.moveToPrevSlide());
98
-
99
- this.dotsNav.addEventListener('click', (e: MouseEvent) => {
100
- const targetDot = (e.target as HTMLElement).closest('button');
101
- if (!targetDot) return;
102
-
103
- const targetIndex = this.dots.findIndex(dot => dot === targetDot);
104
- this.moveToSlide(targetIndex);
105
- });
106
-
107
- window.addEventListener('resize', () => {
108
- this.slideWidth = this.slides[0].getBoundingClientRect().width;
109
- this.moveToSlide(this.currentIndex, false);
110
- });
111
-
112
- this.addTouchSupport();
113
- }
114
-
115
- private moveToSlide(targetIndex: number, animate: boolean = true): void {
116
- if (targetIndex < 0) {
117
- if (this.options.loop) targetIndex = this.slides.length - 1;
118
- else targetIndex = 0;
119
- } else if (targetIndex >= this.slides.length) {
120
- if (this.options.loop) targetIndex = 0;
121
- else targetIndex = this.slides.length - 1;
122
- }
123
-
124
- const amountToMove = -1 * (this.slideWidth * targetIndex);
125
- this.track.style.transform = `translateX(${amountToMove}px)`;
126
-
127
- this.updateDots(targetIndex);
128
- this.currentIndex = targetIndex;
129
- }
130
-
131
- private moveToNextSlide(): void {
132
- this.moveToSlide(this.currentIndex + 1);
133
- }
134
-
135
- private moveToPrevSlide(): void {
136
- this.moveToSlide(this.currentIndex - 1);
137
- }
138
-
139
- private updateDots(targetIndex: number): void {
140
- this.dots.forEach(dot => dot.classList.remove('current-slide'));
141
- this.dots[targetIndex].classList.add('current-slide');
142
- }
143
-
144
- private addTouchSupport(): void {
145
- let startX = 0;
146
- let isDragging = false;
147
-
148
- this.track.addEventListener('touchstart', (e: TouchEvent) => {
149
- startX = e.touches[0].clientX;
150
- isDragging = true;
151
- }, { passive: true });
152
-
153
- this.track.addEventListener('touchend', (e: TouchEvent) => {
154
- if (!isDragging) return;
155
- const endX = e.changedTouches[0].clientX;
156
- const diffX = startX - endX;
157
-
158
- if (Math.abs(diffX) > 50) {
159
- if (diffX > 0) this.moveToNextSlide();
160
- else this.moveToPrevSlide();
161
- }
162
- isDragging = false;
163
- });
164
- }
165
-
166
- private startAutoPlay(): void {
167
- setInterval(() => {
168
- this.moveToNextSlide();
169
- }, this.options.autoPlayInterval);
170
- }
171
- }
172
- export { Carousel };
173
- export type { CarouselOptions };
1
+ interface CarouselOptions {
2
+ loop?: boolean;
3
+ autoPlay?: boolean;
4
+ autoPlayInterval?: number;
5
+ }
6
+
7
+ class Carousel {
8
+ private root: HTMLElement;
9
+ private options: CarouselOptions;
10
+ private track!: HTMLUListElement;
11
+ private slides!: HTMLElement[];
12
+ private slideWidth!: number;
13
+ private currentIndex!: number;
14
+ private prevButton!: HTMLButtonElement;
15
+ private nextButton!: HTMLButtonElement;
16
+ private dotsNav!: HTMLDivElement;
17
+ private dots!: HTMLButtonElement[];
18
+ private autoPlayTimer: number | null = null;
19
+
20
+ constructor(elementOrSelector: string | HTMLElement, options: CarouselOptions = {}) {
21
+ const element = typeof elementOrSelector === 'string'
22
+ ? document.querySelector<HTMLElement>(elementOrSelector)
23
+ : elementOrSelector;
24
+
25
+ this.options = {
26
+ loop: options.loop ?? false,
27
+ autoPlay: options.autoPlay ?? false,
28
+ autoPlayInterval: options.autoPlayInterval ?? 3000
29
+ };
30
+
31
+ if (!element) {
32
+ throw new Error(`Carousel: Element not found for selector "${elementOrSelector}"`);
33
+ }
34
+
35
+ this.root = element;
36
+ this.init();
37
+ }
38
+
39
+ private init(): void {
40
+ this.setupDOM();
41
+ this.slides = Array.from(this.track.children) as HTMLElement[];
42
+ this.slideWidth = this.slides[0].getBoundingClientRect().width;
43
+ this.currentIndex = 0;
44
+ this.bindEvents();
45
+ this.updateDots(0);
46
+ if (this.options.autoPlay) {
47
+ this.startAutoPlay();
48
+ }
49
+ }
50
+
51
+ private setupDOM(): void {
52
+ const slides = Array.from(this.root.children) as HTMLElement[];
53
+ const container = document.createElement('div');
54
+ container.classList.add('carousel-track-container');
55
+
56
+ this.track = document.createElement('ul');
57
+ this.track.classList.add('carousel-track');
58
+
59
+ slides.forEach(slide => {
60
+ slide.classList.add('carousel-slide');
61
+ this.track.appendChild(slide);
62
+ });
63
+
64
+ container.appendChild(this.track);
65
+ this.root.appendChild(container);
66
+
67
+ this.prevButton = document.createElement('button');
68
+ this.prevButton.classList.add('carousel-button', 'carousel-button--left');
69
+ this.prevButton.innerHTML = '<span class="icon-navigate_before icon"></span>';
70
+ this.prevButton.setAttribute('aria-label', 'Previous Slide');
71
+
72
+ this.nextButton = document.createElement('button');
73
+ this.nextButton.classList.add('carousel-button', 'carousel-button--right');
74
+ this.nextButton.innerHTML = '<span class="icon-navigate_next icon"></span>';
75
+ this.nextButton.setAttribute('aria-label', 'Next Slide');
76
+
77
+ this.root.appendChild(this.prevButton);
78
+ this.root.appendChild(this.nextButton);
79
+
80
+ this.dotsNav = document.createElement('div');
81
+ this.dotsNav.classList.add('carousel-nav');
82
+
83
+ this.dots = [];
84
+ slides.forEach((_, index) => {
85
+ const dot = document.createElement('button');
86
+ dot.classList.add('carousel-indicator');
87
+ dot.setAttribute('aria-label', `Slide ${index + 1}`);
88
+ this.dotsNav.appendChild(dot);
89
+ this.dots.push(dot);
90
+ });
91
+
92
+ this.root.appendChild(this.dotsNav);
93
+
94
+ // Make focusable for keyboard nav
95
+ this.root.setAttribute('tabindex', '0');
96
+ }
97
+
98
+ private bindEvents(): void {
99
+ this.nextButton.addEventListener('click', () => this.moveToNextSlide());
100
+ this.prevButton.addEventListener('click', () => this.moveToPrevSlide());
101
+
102
+ this.dotsNav.addEventListener('click', (e: MouseEvent) => {
103
+ const targetDot = (e.target as HTMLElement).closest('button');
104
+ if (!targetDot) return;
105
+ const targetIndex = this.dots.findIndex(dot => dot === targetDot);
106
+ this.moveToSlide(targetIndex);
107
+ });
108
+
109
+ window.addEventListener('resize', () => {
110
+ this.slideWidth = this.slides[0].getBoundingClientRect().width;
111
+ this.moveToSlide(this.currentIndex, false);
112
+ });
113
+
114
+ // Keyboard navigation
115
+ this.root.addEventListener('keydown', (e: KeyboardEvent) => {
116
+ if (e.key === 'ArrowLeft') this.moveToPrevSlide();
117
+ if (e.key === 'ArrowRight') this.moveToNextSlide();
118
+ });
119
+
120
+ // Pause autoplay on hover / focus
121
+ if (this.options.autoPlay) {
122
+ this.root.addEventListener('mouseenter', () => this.pauseAutoPlay());
123
+ this.root.addEventListener('mouseleave', () => this.resumeAutoPlay());
124
+ this.root.addEventListener('focusin', () => this.pauseAutoPlay());
125
+ this.root.addEventListener('focusout', () => this.resumeAutoPlay());
126
+ }
127
+
128
+ this.addTouchSupport();
129
+ }
130
+
131
+ private moveToSlide(targetIndex: number, animate: boolean = true): void {
132
+ if (targetIndex < 0) {
133
+ if (this.options.loop) targetIndex = this.slides.length - 1;
134
+ else targetIndex = 0;
135
+ } else if (targetIndex >= this.slides.length) {
136
+ if (this.options.loop) targetIndex = 0;
137
+ else targetIndex = this.slides.length - 1;
138
+ }
139
+
140
+ if (!animate) {
141
+ this.track.style.transitionDuration = '0ms';
142
+ }
143
+
144
+ const amountToMove = -1 * (this.slideWidth * targetIndex);
145
+ this.track.style.transform = `translateX(${amountToMove}px)`;
146
+
147
+ if (!animate) {
148
+ // Restore CSS transition after the paint to avoid a flash
149
+ requestAnimationFrame(() => {
150
+ this.track.style.transitionDuration = '';
151
+ });
152
+ }
153
+
154
+ this.updateDots(targetIndex);
155
+ this.currentIndex = targetIndex;
156
+ }
157
+
158
+ private moveToNextSlide(): void {
159
+ this.moveToSlide(this.currentIndex + 1);
160
+ }
161
+
162
+ private moveToPrevSlide(): void {
163
+ this.moveToSlide(this.currentIndex - 1);
164
+ }
165
+
166
+ private updateDots(targetIndex: number): void {
167
+ this.dots.forEach(dot => dot.classList.remove('current-slide'));
168
+ this.dots[targetIndex].classList.add('current-slide');
169
+ }
170
+
171
+ private addTouchSupport(): void {
172
+ let startX = 0;
173
+ let isDragging = false;
174
+
175
+ this.track.addEventListener('touchstart', (e: TouchEvent) => {
176
+ startX = e.touches[0].clientX;
177
+ isDragging = true;
178
+ }, { passive: true });
179
+
180
+ this.track.addEventListener('touchend', (e: TouchEvent) => {
181
+ if (!isDragging) return;
182
+ const endX = e.changedTouches[0].clientX;
183
+ const diffX = startX - endX;
184
+ if (Math.abs(diffX) > 50) {
185
+ if (diffX > 0) this.moveToNextSlide();
186
+ else this.moveToPrevSlide();
187
+ }
188
+ isDragging = false;
189
+ });
190
+ }
191
+
192
+ private startAutoPlay(): void {
193
+ this.autoPlayTimer = window.setInterval(() => {
194
+ this.moveToNextSlide();
195
+ }, this.options.autoPlayInterval);
196
+ }
197
+
198
+ private pauseAutoPlay(): void {
199
+ if (this.autoPlayTimer !== null) {
200
+ clearInterval(this.autoPlayTimer);
201
+ this.autoPlayTimer = null;
202
+ }
203
+ }
204
+
205
+ private resumeAutoPlay(): void {
206
+ if (this.options.autoPlay && this.autoPlayTimer === null) {
207
+ this.startAutoPlay();
208
+ }
209
+ }
210
+
211
+ public destroy(): void {
212
+ this.pauseAutoPlay();
213
+ }
214
+ }
215
+
216
+ export { Carousel };
217
+ export type { CarouselOptions };