mtrl 0.3.1 → 0.3.2

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 (159) hide show
  1. package/.env +15 -0
  2. package/CONTRIBUTING.md +8 -8
  3. package/DOCS.md +3 -3
  4. package/README.md +43 -20
  5. package/TESTING.md +128 -18
  6. package/dist/index.js +14865 -0
  7. package/git-user-stats.js +545 -0
  8. package/index.ts +9 -67
  9. package/package.json +8 -3
  10. package/src/components/badge/api.ts +15 -1
  11. package/src/components/badge/badge.ts +43 -4
  12. package/src/components/badge/config.ts +40 -8
  13. package/src/components/badge/index.ts +64 -3
  14. package/src/components/badge/types.ts +175 -33
  15. package/src/components/button/api.ts +63 -1
  16. package/src/components/button/button.ts +39 -3
  17. package/src/components/button/config.ts +21 -4
  18. package/src/components/button/index.ts +26 -1
  19. package/src/components/button/types.ts +7 -1
  20. package/src/components/card/api.ts +78 -9
  21. package/src/components/card/card.ts +58 -3
  22. package/src/components/card/config.ts +41 -11
  23. package/src/components/card/features.ts +39 -12
  24. package/src/components/card/index.ts +84 -19
  25. package/src/components/card/types.ts +218 -29
  26. package/src/components/carousel/carousel.ts +92 -28
  27. package/src/components/carousel/constants.ts +107 -21
  28. package/src/components/carousel/index.ts +31 -13
  29. package/src/components/checkbox/checkbox.ts +83 -16
  30. package/src/components/checkbox/index.ts +43 -1
  31. package/src/components/checkbox/types.ts +219 -32
  32. package/src/components/chips/api.ts +194 -0
  33. package/src/components/{chip → chips/chip}/api.ts +42 -2
  34. package/src/components/chips/chip/chip.ts +131 -0
  35. package/src/components/{chip → chips/chip}/config.ts +3 -3
  36. package/src/components/chips/chip/index.ts +3 -0
  37. package/src/components/chips/chips.md +481 -0
  38. package/src/components/chips/chips.ts +75 -0
  39. package/src/components/chips/config.ts +109 -0
  40. package/src/components/chips/constants.ts +61 -0
  41. package/src/components/chips/features/chip-items.ts +33 -0
  42. package/src/components/chips/features/container.ts +77 -0
  43. package/src/components/chips/features/controller.ts +448 -0
  44. package/src/components/chips/features/index.ts +5 -0
  45. package/src/components/chips/features/label.ts +108 -0
  46. package/src/components/chips/index.ts +11 -0
  47. package/src/components/chips/schema.ts +61 -0
  48. package/src/components/{chip → chips}/types.ts +203 -92
  49. package/src/components/dialog/dialog.ts +99 -16
  50. package/src/components/dialog/index.ts +97 -1
  51. package/src/components/dialog/types.ts +375 -69
  52. package/src/components/divider/config.ts +90 -6
  53. package/src/components/divider/divider.ts +32 -2
  54. package/src/components/divider/features.ts +26 -0
  55. package/src/components/divider/index.ts +30 -0
  56. package/src/components/divider/types.ts +86 -9
  57. package/src/components/extended-fab/api.ts +53 -1
  58. package/src/components/extended-fab/config.ts +29 -1
  59. package/src/components/extended-fab/extended-fab.ts +28 -0
  60. package/src/components/extended-fab/index.ts +36 -0
  61. package/src/components/extended-fab/types.ts +458 -13
  62. package/src/components/fab/api.ts +42 -2
  63. package/src/components/fab/config.ts +29 -1
  64. package/src/components/fab/fab.ts +16 -2
  65. package/src/components/fab/index.ts +35 -0
  66. package/src/components/fab/types.ts +374 -10
  67. package/src/components/list/api.ts +12 -2
  68. package/src/components/list/config.ts +21 -0
  69. package/src/components/list/features.ts +6 -0
  70. package/src/components/list/index.ts +56 -1
  71. package/src/components/list/list-item.ts +46 -2
  72. package/src/components/list/list.ts +73 -2
  73. package/src/components/list/types.ts +172 -0
  74. package/src/components/list/utils.ts +26 -2
  75. package/src/components/menu/api.ts +217 -20
  76. package/src/components/menu/config.ts +27 -0
  77. package/src/components/menu/features/visibility.ts +55 -6
  78. package/src/components/menu/index.ts +64 -0
  79. package/src/components/menu/menu-item.ts +46 -3
  80. package/src/components/menu/menu.ts +77 -1
  81. package/src/components/menu/types.ts +404 -39
  82. package/src/components/sheet/config.ts +1 -2
  83. package/src/components/sheet/features/gestures.ts +1 -1
  84. package/src/components/sheet/features/position.ts +1 -2
  85. package/src/components/sheet/features/state.ts +1 -1
  86. package/src/components/sheet/index.ts +10 -2
  87. package/src/components/sheet/sheet.ts +1 -2
  88. package/src/components/sheet/types.ts +29 -1
  89. package/src/components/slider/api.ts +1 -1
  90. package/src/components/slider/config.ts +1 -1
  91. package/src/components/slider/features/controller.ts +1 -1
  92. package/src/components/slider/features/handlers.ts +1 -1
  93. package/src/components/slider/features/states.ts +1 -1
  94. package/src/components/slider/index.ts +12 -5
  95. package/src/components/slider/schema.ts +1 -1
  96. package/src/components/slider/types.ts +31 -0
  97. package/src/components/tabs/tab-api.ts +1 -1
  98. package/src/components/tabs/types.ts +1 -1
  99. package/src/components/tooltip/api.ts +6 -2
  100. package/src/components/tooltip/config.ts +9 -28
  101. package/src/components/tooltip/index.ts +10 -1
  102. package/src/components/tooltip/types.ts +38 -3
  103. package/src/index.ts +129 -31
  104. package/src/styles/abstract/_mixins.scss +23 -9
  105. package/src/styles/abstract/_variables.scss +14 -4
  106. package/src/styles/components/_card.scss +1 -1
  107. package/src/styles/components/_chip.scss +323 -113
  108. package/src/styles/components/_tabs.scss +1 -1
  109. package/CLAUDE.md +0 -33
  110. package/src/components/checkbox/constants.ts +0 -37
  111. package/src/components/chip/chip-set.ts +0 -225
  112. package/src/components/chip/chip.ts +0 -118
  113. package/src/components/chip/constants.ts +0 -28
  114. package/src/components/chip/index.ts +0 -12
  115. package/src/components/list/constants.ts +0 -116
  116. package/src/components/sheet/constants.ts +0 -20
  117. package/src/components/slider/constants.ts +0 -32
  118. package/src/components/tooltip/constants.ts +0 -27
  119. package/test/components/badge.test.ts +0 -545
  120. package/test/components/bottom-app-bar.test.ts +0 -303
  121. package/test/components/button.test.ts +0 -233
  122. package/test/components/card.test.ts +0 -560
  123. package/test/components/carousel.test.ts +0 -951
  124. package/test/components/checkbox.test.ts +0 -462
  125. package/test/components/chip.test.ts +0 -692
  126. package/test/components/datepicker.test.ts +0 -1124
  127. package/test/components/dialog.test.ts +0 -990
  128. package/test/components/divider.test.ts +0 -412
  129. package/test/components/extended-fab.test.ts +0 -672
  130. package/test/components/fab.test.ts +0 -561
  131. package/test/components/list.test.ts +0 -365
  132. package/test/components/menu.test.ts +0 -718
  133. package/test/components/navigation.test.ts +0 -186
  134. package/test/components/progress.test.ts +0 -567
  135. package/test/components/radios.test.ts +0 -699
  136. package/test/components/search.test.ts +0 -1135
  137. package/test/components/segmented-button.test.ts +0 -732
  138. package/test/components/sheet.test.ts +0 -641
  139. package/test/components/slider.test.ts +0 -1220
  140. package/test/components/snackbar.test.ts +0 -461
  141. package/test/components/switch.test.ts +0 -452
  142. package/test/components/tabs.test.ts +0 -1369
  143. package/test/components/textfield.test.ts +0 -400
  144. package/test/components/timepicker.test.ts +0 -592
  145. package/test/components/tooltip.test.ts +0 -630
  146. package/test/components/top-app-bar.test.ts +0 -566
  147. package/test/core/dom.attributes.test.ts +0 -148
  148. package/test/core/dom.classes.test.ts +0 -152
  149. package/test/core/dom.events.test.ts +0 -243
  150. package/test/core/emitter.test.ts +0 -141
  151. package/test/core/ripple.test.ts +0 -99
  152. package/test/core/state.store.test.ts +0 -189
  153. package/test/core/utils.normalize.test.ts +0 -61
  154. package/test/core/utils.object.test.ts +0 -120
  155. package/test/setup.js +0 -371
  156. package/test/setup.ts +0 -451
  157. package/tsconfig.json +0 -22
  158. package/typedoc.json +0 -28
  159. package/typedoc.simple.json +0 -14
@@ -1,567 +0,0 @@
1
- // test/components/progress.test.ts
2
- import { describe, test, expect } from 'bun:test';
3
- import {
4
- type ProgressComponent,
5
- type ProgressConfig,
6
- type ProgressVariant,
7
- type ProgressEvent
8
- } from '../../src/components/progress/types';
9
-
10
- // Constants for progress variants
11
- const PROGRESS_VARIANTS = {
12
- LINEAR: 'linear',
13
- CIRCULAR: 'circular'
14
- } as const;
15
-
16
- // Constants for progress events
17
- const PROGRESS_EVENTS = {
18
- CHANGE: 'change',
19
- COMPLETE: 'complete'
20
- } as const;
21
-
22
- // Mock progress component implementation
23
- const createMockProgress = (config: ProgressConfig = {}): ProgressComponent => {
24
- // Create main elements
25
- const element = document.createElement('div');
26
- element.className = 'mtrl-progress';
27
-
28
- const trackElement = document.createElement('div');
29
- trackElement.className = 'mtrl-progress-track';
30
-
31
- const indicatorElement = document.createElement('div');
32
- indicatorElement.className = 'mtrl-progress-indicator';
33
-
34
- // Default settings
35
- const settings = {
36
- variant: config.variant || PROGRESS_VARIANTS.LINEAR,
37
- value: config.value !== undefined ? config.value : 0,
38
- max: config.max !== undefined ? config.max : 100,
39
- buffer: config.buffer !== undefined ? config.buffer : 0,
40
- disabled: config.disabled || false,
41
- indeterminate: config.indeterminate || false,
42
- showLabel: config.showLabel || false,
43
- labelFormatter: config.labelFormatter || ((value, max) => `${Math.round((value/max) * 100)}%`),
44
- componentName: 'progress',
45
- prefix: config.prefix || 'mtrl'
46
- };
47
-
48
- // Apply variant class
49
- element.classList.add(`mtrl-progress--${settings.variant}`);
50
-
51
- // Apply disabled state
52
- if (settings.disabled) {
53
- element.classList.add('mtrl-progress--disabled');
54
- }
55
-
56
- // Apply indeterminate state
57
- if (settings.indeterminate) {
58
- element.classList.add('mtrl-progress--indeterminate');
59
- }
60
-
61
- // Apply additional classes
62
- if (config.class) {
63
- const classes = config.class.split(' ');
64
- classes.forEach(className => element.classList.add(className));
65
- }
66
-
67
- // Create buffer element for linear variant
68
- let bufferElement: HTMLElement | undefined;
69
- if (settings.variant === PROGRESS_VARIANTS.LINEAR) {
70
- bufferElement = document.createElement('div');
71
- bufferElement.className = 'mtrl-progress-buffer';
72
- trackElement.appendChild(bufferElement);
73
- }
74
-
75
- // Create label element if enabled
76
- let labelElement: HTMLElement | undefined;
77
- if (settings.showLabel) {
78
- labelElement = document.createElement('div');
79
- labelElement.className = 'mtrl-progress-label';
80
- labelElement.textContent = settings.labelFormatter(settings.value, settings.max);
81
- }
82
-
83
- // Assemble elements
84
- trackElement.appendChild(indicatorElement);
85
- element.appendChild(trackElement);
86
-
87
- if (labelElement) {
88
- element.appendChild(labelElement);
89
- }
90
-
91
- // Track event handlers
92
- const eventHandlers: Record<string, Function[]> = {};
93
-
94
- // Update visuals based on current value
95
- const updateVisuals = () => {
96
- if (!settings.indeterminate) {
97
- const percentage = (settings.value / settings.max) * 100;
98
-
99
- if (settings.variant === PROGRESS_VARIANTS.LINEAR) {
100
- indicatorElement.style.width = `${percentage}%`;
101
-
102
- if (bufferElement) {
103
- const bufferPercentage = (settings.buffer / settings.max) * 100;
104
- bufferElement.style.width = `${bufferPercentage}%`;
105
- }
106
- } else if (settings.variant === PROGRESS_VARIANTS.CIRCULAR) {
107
- // For circular progress, update stroke-dashoffset or similar property
108
- const circumference = 100; // Simplified for testing
109
- const offset = circumference - (percentage / 100 * circumference);
110
- indicatorElement.style.setProperty('--progress-offset', `${offset}`);
111
- }
112
-
113
- // Update label if present
114
- if (labelElement) {
115
- labelElement.textContent = settings.labelFormatter(settings.value, settings.max);
116
- }
117
- }
118
- };
119
-
120
- // Initialize visuals
121
- updateVisuals();
122
-
123
- // Emit an event
124
- const emit = (event: string, data?: any) => {
125
- if (eventHandlers[event]) {
126
- eventHandlers[event].forEach(handler => handler(data));
127
- }
128
- };
129
-
130
- // Create the progress component
131
- const progress: ProgressComponent = {
132
- element,
133
- trackElement,
134
- indicatorElement,
135
- bufferElement,
136
- labelElement,
137
-
138
- getClass: (name: string) => {
139
- const prefix = settings.prefix;
140
- return name ? `${prefix}-${name}` : `${prefix}-progress`;
141
- },
142
-
143
- setValue: (value: number) => {
144
- // Ensure value is within bounds
145
- value = Math.max(0, Math.min(value, settings.max));
146
-
147
- const oldValue = settings.value;
148
- settings.value = value;
149
-
150
- // Update visuals
151
- updateVisuals();
152
-
153
- // Emit change event
154
- emit(PROGRESS_EVENTS.CHANGE, { value, oldValue });
155
-
156
- // Emit complete event if reached 100%
157
- if (value === settings.max && oldValue !== settings.max) {
158
- emit(PROGRESS_EVENTS.COMPLETE, { value });
159
- }
160
-
161
- return progress;
162
- },
163
-
164
- getValue: () => settings.value,
165
-
166
- setBuffer: (value: number) => {
167
- // Ensure buffer is within bounds
168
- value = Math.max(0, Math.min(value, settings.max));
169
- settings.buffer = value;
170
-
171
- // Update visuals
172
- updateVisuals();
173
-
174
- return progress;
175
- },
176
-
177
- getBuffer: () => settings.buffer,
178
-
179
- enable: () => {
180
- progress.disabled.enable();
181
- return progress;
182
- },
183
-
184
- disable: () => {
185
- progress.disabled.disable();
186
- return progress;
187
- },
188
-
189
- isDisabled: () => progress.disabled.isDisabled(),
190
-
191
- showLabel: () => {
192
- settings.showLabel = true;
193
-
194
- if (!labelElement) {
195
- labelElement = document.createElement('div');
196
- labelElement.className = 'mtrl-progress-label';
197
- labelElement.textContent = settings.labelFormatter(settings.value, settings.max);
198
- element.appendChild(labelElement);
199
- progress.labelElement = labelElement;
200
- }
201
-
202
- return progress;
203
- },
204
-
205
- hideLabel: () => {
206
- settings.showLabel = false;
207
-
208
- if (labelElement) {
209
- element.removeChild(labelElement);
210
- labelElement = undefined;
211
- progress.labelElement = undefined;
212
- }
213
-
214
- return progress;
215
- },
216
-
217
- setLabelFormatter: (formatter: (value: number, max: number) => string) => {
218
- settings.labelFormatter = formatter;
219
-
220
- if (labelElement) {
221
- labelElement.textContent = formatter(settings.value, settings.max);
222
- }
223
-
224
- return progress;
225
- },
226
-
227
- setIndeterminate: (indeterminate: boolean) => {
228
- settings.indeterminate = indeterminate;
229
-
230
- if (indeterminate) {
231
- element.classList.add('mtrl-progress--indeterminate');
232
- } else {
233
- element.classList.remove('mtrl-progress--indeterminate');
234
- updateVisuals();
235
- }
236
-
237
- return progress;
238
- },
239
-
240
- isIndeterminate: () => settings.indeterminate,
241
-
242
- on: (event: string, handler: Function) => {
243
- if (!eventHandlers[event]) {
244
- eventHandlers[event] = [];
245
- }
246
-
247
- eventHandlers[event].push(handler);
248
- return progress;
249
- },
250
-
251
- off: (event: string, handler: Function) => {
252
- if (eventHandlers[event]) {
253
- eventHandlers[event] = eventHandlers[event].filter(h => h !== handler);
254
- }
255
-
256
- return progress;
257
- },
258
-
259
- destroy: () => {
260
- // Remove element from DOM if it has a parent
261
- if (element.parentNode) {
262
- element.parentNode.removeChild(element);
263
- }
264
-
265
- // Clear event handlers
266
- for (const event in eventHandlers) {
267
- eventHandlers[event] = [];
268
- }
269
- },
270
-
271
- addClass: (...classes: string[]) => {
272
- classes.forEach(className => element.classList.add(className));
273
- return progress;
274
- },
275
-
276
- disabled: {
277
- enable: () => {
278
- settings.disabled = false;
279
- element.classList.remove('mtrl-progress--disabled');
280
- },
281
-
282
- disable: () => {
283
- settings.disabled = true;
284
- element.classList.add('mtrl-progress--disabled');
285
- },
286
-
287
- isDisabled: () => settings.disabled
288
- },
289
-
290
- lifecycle: {
291
- destroy: () => {
292
- progress.destroy();
293
- }
294
- }
295
- };
296
-
297
- return progress;
298
- };
299
-
300
- describe('Progress Component', () => {
301
- test('should create a progress element', () => {
302
- const progress = createMockProgress();
303
-
304
- expect(progress.element).toBeDefined();
305
- expect(progress.element.tagName).toBe('DIV');
306
- expect(progress.element.className).toContain('mtrl-progress');
307
-
308
- expect(progress.trackElement).toBeDefined();
309
- expect(progress.trackElement.className).toContain('mtrl-progress-track');
310
-
311
- expect(progress.indicatorElement).toBeDefined();
312
- expect(progress.indicatorElement.className).toContain('mtrl-progress-indicator');
313
- });
314
-
315
- test('should apply linear variant by default', () => {
316
- const progress = createMockProgress();
317
-
318
- expect(progress.element.className).toContain('mtrl-progress--linear');
319
- expect(progress.bufferElement).toBeDefined();
320
- });
321
-
322
- test('should apply circular variant when specified', () => {
323
- const progress = createMockProgress({
324
- variant: PROGRESS_VARIANTS.CIRCULAR
325
- });
326
-
327
- expect(progress.element.className).toContain('mtrl-progress--circular');
328
- expect(progress.bufferElement).toBeUndefined();
329
- });
330
-
331
- test('should set initial value', () => {
332
- const progress = createMockProgress({
333
- value: 25
334
- });
335
-
336
- expect(progress.getValue()).toBe(25);
337
- expect(progress.indicatorElement.style.width).toBe('25%');
338
- });
339
-
340
- test('should set initial buffer value', () => {
341
- const progress = createMockProgress({
342
- buffer: 50
343
- });
344
-
345
- expect(progress.getBuffer()).toBe(50);
346
- expect(progress.bufferElement?.style.width).toBe('50%');
347
- });
348
-
349
- test('should apply disabled state', () => {
350
- const progress = createMockProgress({
351
- disabled: true
352
- });
353
-
354
- expect(progress.element.className).toContain('mtrl-progress--disabled');
355
- expect(progress.isDisabled()).toBe(true);
356
- });
357
-
358
- test('should apply indeterminate state', () => {
359
- const progress = createMockProgress({
360
- indeterminate: true
361
- });
362
-
363
- expect(progress.element.className).toContain('mtrl-progress--indeterminate');
364
- expect(progress.isIndeterminate()).toBe(true);
365
- });
366
-
367
- test('should show label when configured', () => {
368
- const progress = createMockProgress({
369
- showLabel: true,
370
- value: 75
371
- });
372
-
373
- expect(progress.labelElement).toBeDefined();
374
- expect(progress.labelElement?.textContent).toBe('75%');
375
- });
376
-
377
- test('should use custom label formatter', () => {
378
- const formatter = (value: number, max: number) => `${value} of ${max}`;
379
-
380
- const progress = createMockProgress({
381
- showLabel: true,
382
- value: 50,
383
- max: 200,
384
- labelFormatter: formatter
385
- });
386
-
387
- expect(progress.labelElement?.textContent).toBe('50 of 200');
388
- });
389
-
390
- test('should update value and appearance', () => {
391
- const progress = createMockProgress({
392
- value: 0
393
- });
394
-
395
- expect(progress.getValue()).toBe(0);
396
- expect(progress.indicatorElement.style.width).toBe('0%');
397
-
398
- progress.setValue(60);
399
-
400
- expect(progress.getValue()).toBe(60);
401
- expect(progress.indicatorElement.style.width).toBe('60%');
402
- });
403
-
404
- test('should update buffer value', () => {
405
- const progress = createMockProgress();
406
-
407
- expect(progress.getBuffer()).toBe(0);
408
-
409
- progress.setBuffer(75);
410
-
411
- expect(progress.getBuffer()).toBe(75);
412
- expect(progress.bufferElement?.style.width).toBe('75%');
413
- });
414
-
415
- test('should constrain values within bounds', () => {
416
- const progress = createMockProgress({
417
- max: 100
418
- });
419
-
420
- progress.setValue(-10);
421
- expect(progress.getValue()).toBe(0);
422
-
423
- progress.setValue(150);
424
- expect(progress.getValue()).toBe(100);
425
-
426
- progress.setBuffer(-20);
427
- expect(progress.getBuffer()).toBe(0);
428
-
429
- progress.setBuffer(200);
430
- expect(progress.getBuffer()).toBe(100);
431
- });
432
-
433
- test('should toggle disabled state', () => {
434
- const progress = createMockProgress();
435
-
436
- expect(progress.isDisabled()).toBe(false);
437
-
438
- progress.disable();
439
-
440
- expect(progress.isDisabled()).toBe(true);
441
- expect(progress.element.className).toContain('mtrl-progress--disabled');
442
-
443
- progress.enable();
444
-
445
- expect(progress.isDisabled()).toBe(false);
446
- expect(progress.element.className).not.toContain('mtrl-progress--disabled');
447
- });
448
-
449
- test('should toggle indeterminate state', () => {
450
- const progress = createMockProgress();
451
-
452
- expect(progress.isIndeterminate()).toBe(false);
453
-
454
- progress.setIndeterminate(true);
455
-
456
- expect(progress.isIndeterminate()).toBe(true);
457
- expect(progress.element.className).toContain('mtrl-progress--indeterminate');
458
-
459
- progress.setIndeterminate(false);
460
-
461
- expect(progress.isIndeterminate()).toBe(false);
462
- expect(progress.element.className).not.toContain('mtrl-progress--indeterminate');
463
- });
464
-
465
- test('should show and hide label', () => {
466
- const progress = createMockProgress();
467
-
468
- expect(progress.labelElement).toBeUndefined();
469
-
470
- progress.showLabel();
471
-
472
- expect(progress.labelElement).toBeDefined();
473
- expect(progress.element.contains(progress.labelElement)).toBe(true);
474
-
475
- progress.hideLabel();
476
-
477
- expect(progress.labelElement).toBeUndefined();
478
- expect(progress.element.querySelector('.mtrl-progress-label')).toBeNull();
479
- });
480
-
481
- test('should update label formatter', () => {
482
- const progress = createMockProgress({
483
- showLabel: true,
484
- value: 50
485
- });
486
-
487
- expect(progress.labelElement?.textContent).toBe('50%');
488
-
489
- progress.setLabelFormatter((value) => `${value} units`);
490
-
491
- expect(progress.labelElement?.textContent).toBe('50 units');
492
- });
493
-
494
- test('should emit change event when value changes', () => {
495
- const progress = createMockProgress();
496
- let changeEventFired = false;
497
- let eventData = null;
498
-
499
- progress.on(PROGRESS_EVENTS.CHANGE, (data) => {
500
- changeEventFired = true;
501
- eventData = data;
502
- });
503
-
504
- progress.setValue(50);
505
-
506
- expect(changeEventFired).toBe(true);
507
- expect(eventData).toEqual({ value: 50, oldValue: 0 });
508
- });
509
-
510
- test('should emit complete event when reaching max', () => {
511
- const progress = createMockProgress({
512
- value: 50,
513
- max: 100
514
- });
515
-
516
- let completeEventFired = false;
517
-
518
- progress.on(PROGRESS_EVENTS.COMPLETE, () => {
519
- completeEventFired = true;
520
- });
521
-
522
- progress.setValue(99);
523
- expect(completeEventFired).toBe(false);
524
-
525
- progress.setValue(100);
526
- expect(completeEventFired).toBe(true);
527
- });
528
-
529
- test('should remove event listeners', () => {
530
- const progress = createMockProgress();
531
- let eventCount = 0;
532
-
533
- const handler = () => {
534
- eventCount++;
535
- };
536
-
537
- progress.on(PROGRESS_EVENTS.CHANGE, handler);
538
-
539
- progress.setValue(10);
540
- expect(eventCount).toBe(1);
541
-
542
- progress.off(PROGRESS_EVENTS.CHANGE, handler);
543
-
544
- progress.setValue(20);
545
- expect(eventCount).toBe(1); // Count should not increase
546
- });
547
-
548
- test('should add CSS classes', () => {
549
- const progress = createMockProgress();
550
-
551
- progress.addClass('custom-class', 'special-progress');
552
-
553
- expect(progress.element.className).toContain('custom-class');
554
- expect(progress.element.className).toContain('special-progress');
555
- });
556
-
557
- test('should be properly destroyed', () => {
558
- const progress = createMockProgress();
559
- document.body.appendChild(progress.element);
560
-
561
- expect(document.body.contains(progress.element)).toBe(true);
562
-
563
- progress.destroy();
564
-
565
- expect(document.body.contains(progress.element)).toBe(false);
566
- });
567
- });