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,545 +0,0 @@
1
- // test/components/badge.test.ts
2
- import { describe, test, expect, mock } from 'bun:test';
3
- import { JSDOM } from 'jsdom';
4
-
5
- // Set up JSDOM
6
- const dom = new JSDOM(`<!DOCTYPE html><html><body></body></html>`);
7
- global.document = dom.window.document;
8
- global.window = dom.window;
9
- global.Element = dom.window.Element;
10
- global.HTMLElement = dom.window.HTMLElement;
11
- global.Event = dom.window.Event;
12
- global.CustomEvent = dom.window.CustomEvent;
13
-
14
- // Import types directly to avoid circular dependencies
15
- import type {
16
- BadgeComponent,
17
- BadgeConfig,
18
- BadgeVariant,
19
- BadgeColor,
20
- BadgePosition
21
- } from '../../src/components/badge/types';
22
-
23
- // Define constants here to avoid circular dependencies
24
- const BADGE_VARIANTS = {
25
- SMALL: 'small',
26
- LARGE: 'large'
27
- } as const;
28
-
29
- const BADGE_COLORS = {
30
- ERROR: 'error',
31
- PRIMARY: 'primary',
32
- SECONDARY: 'secondary',
33
- TERTIARY: 'tertiary',
34
- SUCCESS: 'success',
35
- WARNING: 'warning',
36
- INFO: 'info'
37
- } as const;
38
-
39
- const BADGE_POSITIONS = {
40
- TOP_RIGHT: 'top-right',
41
- TOP_LEFT: 'top-left',
42
- BOTTOM_RIGHT: 'bottom-right',
43
- BOTTOM_LEFT: 'bottom-left'
44
- } as const;
45
-
46
- const BADGE_MAX_CHARACTERS = 4;
47
-
48
- // Create a mock badge implementation
49
- const createMockBadge = (config: BadgeConfig = {}): BadgeComponent => {
50
- // Default configuration
51
- const defaultConfig: BadgeConfig = {
52
- variant: BADGE_VARIANTS.LARGE,
53
- color: BADGE_COLORS.ERROR,
54
- position: BADGE_POSITIONS.TOP_RIGHT,
55
- visible: true,
56
- prefix: 'mtrl'
57
- };
58
-
59
- // Merge with user configuration
60
- const mergedConfig = {
61
- ...defaultConfig,
62
- ...config
63
- };
64
-
65
- // Create main element
66
- const element = document.createElement('div');
67
- element.className = `${mergedConfig.prefix}-badge`;
68
-
69
- // Add custom class if provided
70
- if (mergedConfig.class) {
71
- element.className += ` ${mergedConfig.class}`;
72
- }
73
-
74
- // Add variant class
75
- element.className += ` ${mergedConfig.prefix}-badge--${mergedConfig.variant}`;
76
-
77
- // Add color class
78
- element.className += ` ${mergedConfig.prefix}-badge--${mergedConfig.color}`;
79
-
80
- // Add position class
81
- element.className += ` ${mergedConfig.prefix}-badge--${mergedConfig.position}`;
82
-
83
- // Set visibility
84
- if (!mergedConfig.visible) {
85
- element.style.display = 'none';
86
- }
87
-
88
- // Set label content
89
- if (mergedConfig.variant === BADGE_VARIANTS.LARGE && mergedConfig.label) {
90
- element.textContent = String(mergedConfig.label);
91
-
92
- // Apply max if needed
93
- if (mergedConfig.max && typeof mergedConfig.label === 'number' && mergedConfig.label > mergedConfig.max) {
94
- element.textContent = `${mergedConfig.max}+`;
95
- }
96
- }
97
-
98
- // Create wrapper if there's a target
99
- let wrapper: HTMLElement | undefined;
100
- if (mergedConfig.target) {
101
- wrapper = document.createElement('div');
102
- wrapper.className = `${mergedConfig.prefix}-badge-wrapper`;
103
- wrapper.appendChild(mergedConfig.target.cloneNode(true));
104
- wrapper.appendChild(element);
105
- }
106
-
107
- // Event handlers
108
- const eventHandlers: Record<string, Function[]> = {};
109
-
110
- // Create the badge instance
111
- const badge: BadgeComponent = {
112
- element,
113
- wrapper,
114
-
115
- getClass: (name: string) => `${mergedConfig.prefix}-badge${name ? '--' + name : ''}`,
116
-
117
- setLabel: (label: string | number) => {
118
- if (mergedConfig.variant !== BADGE_VARIANTS.LARGE) {
119
- return badge;
120
- }
121
-
122
- let content = String(label);
123
-
124
- // Apply max if needed
125
- if (mergedConfig.max && typeof label === 'number' && label > mergedConfig.max) {
126
- content = `${mergedConfig.max}+`;
127
- }
128
-
129
- element.textContent = content;
130
- return badge;
131
- },
132
-
133
- getLabel: () => element.textContent || '',
134
-
135
- show: () => {
136
- element.style.display = '';
137
- return badge;
138
- },
139
-
140
- hide: () => {
141
- element.style.display = 'none';
142
- return badge;
143
- },
144
-
145
- toggle: (visible?: boolean) => {
146
- const shouldBeVisible = visible === undefined ?
147
- element.style.display === 'none' : visible;
148
-
149
- if (shouldBeVisible) {
150
- badge.show();
151
- } else {
152
- badge.hide();
153
- }
154
-
155
- return badge;
156
- },
157
-
158
- isVisible: () => element.style.display !== 'none',
159
-
160
- setMax: (max: number) => {
161
- mergedConfig.max = max;
162
-
163
- // Update display if needed
164
- if (mergedConfig.variant === BADGE_VARIANTS.LARGE &&
165
- element.textContent &&
166
- !isNaN(Number(element.textContent)) &&
167
- Number(element.textContent) > max) {
168
- element.textContent = `${max}+`;
169
- }
170
-
171
- return badge;
172
- },
173
-
174
- setColor: (color: BadgeColor | string) => {
175
- // Remove old color class
176
- element.classList.remove(`${mergedConfig.prefix}-badge--${mergedConfig.color}`);
177
-
178
- // Update config
179
- mergedConfig.color = color;
180
-
181
- // Add new color class
182
- element.classList.add(`${mergedConfig.prefix}-badge--${color}`);
183
-
184
- return badge;
185
- },
186
-
187
- setVariant: (variant: BadgeVariant | string) => {
188
- // Remove old variant class
189
- element.classList.remove(`${mergedConfig.prefix}-badge--${mergedConfig.variant}`);
190
-
191
- // Update config
192
- mergedConfig.variant = variant;
193
-
194
- // Add new variant class
195
- element.classList.add(`${mergedConfig.prefix}-badge--${variant}`);
196
-
197
- // Clear content if switching to small variant
198
- if (variant === BADGE_VARIANTS.SMALL) {
199
- element.textContent = '';
200
- } else if (mergedConfig.label) {
201
- badge.setLabel(mergedConfig.label);
202
- }
203
-
204
- return badge;
205
- },
206
-
207
- setPosition: (position: BadgePosition | string) => {
208
- // Remove old position class
209
- element.classList.remove(`${mergedConfig.prefix}-badge--${mergedConfig.position}`);
210
-
211
- // Update config
212
- mergedConfig.position = position;
213
-
214
- // Add new position class
215
- element.classList.add(`${mergedConfig.prefix}-badge--${position}`);
216
-
217
- return badge;
218
- },
219
-
220
- attachTo: (target: HTMLElement) => {
221
- // Detach first if already attached
222
- if (wrapper) {
223
- badge.detach();
224
- }
225
-
226
- // Create wrapper
227
- wrapper = document.createElement('div');
228
- wrapper.className = `${mergedConfig.prefix}-badge-wrapper`;
229
-
230
- // Clone target's style and parent connections
231
- const parent = target.parentNode;
232
- const nextSibling = target.nextSibling;
233
-
234
- // Add target and badge to wrapper
235
- wrapper.appendChild(target);
236
- wrapper.appendChild(element);
237
-
238
- // Insert wrapper where target was
239
- if (parent) {
240
- parent.insertBefore(wrapper, nextSibling);
241
- }
242
-
243
- return badge;
244
- },
245
-
246
- detach: () => {
247
- if (!wrapper) {
248
- return badge;
249
- }
250
-
251
- // Find the target (first child of wrapper)
252
- const target = wrapper.childNodes[0] as HTMLElement;
253
-
254
- // Get wrapper's position in DOM
255
- const parent = wrapper.parentNode;
256
- const nextSibling = wrapper.nextSibling;
257
-
258
- if (parent) {
259
- // Move badge element to document body (or keep as-is)
260
- document.body.appendChild(element);
261
-
262
- // Move target back to original position
263
- parent.insertBefore(target, nextSibling);
264
-
265
- // Remove wrapper
266
- wrapper.remove();
267
- }
268
-
269
- wrapper = undefined;
270
- return badge;
271
- },
272
-
273
- addClass: (...classes: string[]) => {
274
- element.classList.add(...classes);
275
- return badge;
276
- },
277
-
278
- removeClass: (...classes: string[]) => {
279
- element.classList.remove(...classes);
280
- return badge;
281
- },
282
-
283
- on: (event: string, handler: Function) => {
284
- if (!eventHandlers[event]) {
285
- eventHandlers[event] = [];
286
- }
287
-
288
- eventHandlers[event].push(handler);
289
- return badge;
290
- },
291
-
292
- off: (event: string, handler: Function) => {
293
- if (!eventHandlers[event]) return badge;
294
-
295
- eventHandlers[event] = eventHandlers[event].filter(h => h !== handler);
296
- return badge;
297
- },
298
-
299
- destroy: () => {
300
- // Clear event handlers
301
- Object.keys(eventHandlers).forEach(key => {
302
- eventHandlers[key] = [];
303
- });
304
-
305
- // Remove elements
306
- if (wrapper && wrapper.parentNode) {
307
- wrapper.parentNode.removeChild(wrapper);
308
- } else if (element.parentNode) {
309
- element.parentNode.removeChild(element);
310
- }
311
- }
312
- };
313
-
314
- return badge;
315
- };
316
-
317
- describe('Badge Component', () => {
318
- test('should create a badge element', () => {
319
- const badge = createMockBadge();
320
- expect(badge.element).toBeDefined();
321
- expect(badge.element.tagName).toBe('DIV');
322
- expect(badge.element.className).toContain('mtrl-badge');
323
- });
324
-
325
- test('should apply variant class', () => {
326
- // Test small variant
327
- const smallBadge = createMockBadge({
328
- variant: BADGE_VARIANTS.SMALL
329
- });
330
- expect(smallBadge.element.className).toContain('mtrl-badge--small');
331
-
332
- // Test large variant
333
- const largeBadge = createMockBadge({
334
- variant: BADGE_VARIANTS.LARGE
335
- });
336
- expect(largeBadge.element.className).toContain('mtrl-badge--large');
337
- });
338
-
339
- test('should apply color class', () => {
340
- // Test primary color
341
- const primaryBadge = createMockBadge({
342
- color: BADGE_COLORS.PRIMARY
343
- });
344
- expect(primaryBadge.element.className).toContain('mtrl-badge--primary');
345
-
346
- // Test error color
347
- const errorBadge = createMockBadge({
348
- color: BADGE_COLORS.ERROR
349
- });
350
- expect(errorBadge.element.className).toContain('mtrl-badge--error');
351
- });
352
-
353
- test('should apply position class', () => {
354
- // Test top-right position
355
- const topRightBadge = createMockBadge({
356
- position: BADGE_POSITIONS.TOP_RIGHT
357
- });
358
- expect(topRightBadge.element.className).toContain('mtrl-badge--top-right');
359
-
360
- // Test bottom-left position
361
- const bottomLeftBadge = createMockBadge({
362
- position: BADGE_POSITIONS.BOTTOM_LEFT
363
- });
364
- expect(bottomLeftBadge.element.className).toContain('mtrl-badge--bottom-left');
365
- });
366
-
367
- test('should set label text for large badges', () => {
368
- const label = '42';
369
- const badge = createMockBadge({
370
- variant: BADGE_VARIANTS.LARGE,
371
- label
372
- });
373
-
374
- expect(badge.getLabel()).toBe(label);
375
- });
376
-
377
- test('should not set label text for small badges', () => {
378
- const label = '42';
379
- const badge = createMockBadge({
380
- variant: BADGE_VARIANTS.SMALL,
381
- label
382
- });
383
-
384
- expect(badge.getLabel()).toBe('');
385
- });
386
-
387
- test('should update badge label', () => {
388
- const badge = createMockBadge({
389
- variant: BADGE_VARIANTS.LARGE
390
- });
391
-
392
- const newLabel = '99';
393
- badge.setLabel(newLabel);
394
- expect(badge.getLabel()).toBe(newLabel);
395
- });
396
-
397
- test('should handle visibility', () => {
398
- // Default is visible
399
- const badge = createMockBadge();
400
- expect(badge.isVisible()).toBe(true);
401
-
402
- // Hide badge
403
- badge.hide();
404
- expect(badge.isVisible()).toBe(false);
405
-
406
- // Show badge
407
- badge.show();
408
- expect(badge.isVisible()).toBe(true);
409
-
410
- // Toggle badge
411
- badge.toggle();
412
- expect(badge.isVisible()).toBe(false);
413
-
414
- badge.toggle();
415
- expect(badge.isVisible()).toBe(true);
416
-
417
- // Explicit toggle
418
- badge.toggle(false);
419
- expect(badge.isVisible()).toBe(false);
420
- });
421
-
422
- test('should respect max value', () => {
423
- const max = 99;
424
- const badge = createMockBadge({
425
- variant: BADGE_VARIANTS.LARGE,
426
- max,
427
- label: max + 1
428
- });
429
-
430
- expect(badge.getLabel()).toBe('99+');
431
-
432
- // Set a lower label
433
- badge.setLabel(50);
434
- expect(badge.getLabel()).toBe('50');
435
-
436
- // Set a higher label
437
- badge.setLabel(100);
438
- expect(badge.getLabel()).toBe('99+');
439
-
440
- // Change max
441
- badge.setMax(999);
442
- badge.setLabel(100);
443
- expect(badge.getLabel()).toBe('100');
444
- });
445
-
446
- test('should change color', () => {
447
- const badge = createMockBadge({
448
- color: BADGE_COLORS.ERROR
449
- });
450
-
451
- expect(badge.element.className).toContain('mtrl-badge--error');
452
-
453
- badge.setColor(BADGE_COLORS.SUCCESS);
454
- expect(badge.element.className).toContain('mtrl-badge--success');
455
- expect(badge.element.className).not.toContain('mtrl-badge--error');
456
- });
457
-
458
- test('should change variant', () => {
459
- const badge = createMockBadge({
460
- variant: BADGE_VARIANTS.LARGE,
461
- label: '42'
462
- });
463
-
464
- expect(badge.element.className).toContain('mtrl-badge--large');
465
- expect(badge.getLabel()).toBe('42');
466
-
467
- badge.setVariant(BADGE_VARIANTS.SMALL);
468
- expect(badge.element.className).toContain('mtrl-badge--small');
469
- expect(badge.element.className).not.toContain('mtrl-badge--large');
470
- expect(badge.getLabel()).toBe('');
471
- });
472
-
473
- test('should change position', () => {
474
- const badge = createMockBadge({
475
- position: BADGE_POSITIONS.TOP_RIGHT
476
- });
477
-
478
- expect(badge.element.className).toContain('mtrl-badge--top-right');
479
-
480
- badge.setPosition(BADGE_POSITIONS.BOTTOM_LEFT);
481
- expect(badge.element.className).toContain('mtrl-badge--bottom-left');
482
- expect(badge.element.className).not.toContain('mtrl-badge--top-right');
483
- });
484
-
485
- test('should have attachment methods', () => {
486
- const badge = createMockBadge();
487
- const target = document.createElement('button');
488
-
489
- // Check if methods exist
490
- expect(typeof badge.attachTo).toBe('function');
491
- expect(typeof badge.detach).toBe('function');
492
-
493
- // Test that methods can be called without errors
494
- badge.attachTo(target);
495
- badge.detach();
496
- });
497
-
498
- test('should support wrapping with attachTo', () => {
499
- const badge = createMockBadge({
500
- target: document.createElement('button')
501
- });
502
-
503
- // A badge created with a target should have a wrapper
504
- expect(badge.wrapper).toBeDefined();
505
- });
506
-
507
- test('should add and remove CSS classes', () => {
508
- const badge = createMockBadge();
509
- const customClass = 'custom-badge';
510
-
511
- badge.addClass(customClass);
512
- expect(badge.element.className).toContain(customClass);
513
-
514
- badge.removeClass(customClass);
515
- expect(badge.element.className).not.toContain(customClass);
516
- });
517
-
518
- test('should register event handlers', () => {
519
- const badge = createMockBadge();
520
- const handler = mock(() => {});
521
-
522
- badge.on('click', handler);
523
- // We don't actually trigger events in this mock implementation
524
- // In a real implementation, we would test event handling here
525
- });
526
-
527
- test('should properly clean up resources on destroy', () => {
528
- const badge = createMockBadge();
529
- const parent = document.createElement('div');
530
- parent.appendChild(badge.element);
531
-
532
- badge.destroy();
533
-
534
- expect(parent.children.length).toBe(0);
535
- });
536
-
537
- test('should apply custom class', () => {
538
- const customClass = 'custom-badge';
539
- const badge = createMockBadge({
540
- class: customClass
541
- });
542
-
543
- expect(badge.element.className).toContain(customClass);
544
- });
545
- });