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,641 +0,0 @@
1
- // test/components/sheet.test.ts
2
- import { describe, test, expect } from 'bun:test';
3
- import {
4
- type SheetComponent,
5
- type SheetConfig
6
- } from '../../src/components/sheet/types';
7
-
8
- // Constants for sheet variants
9
- const SHEET_VARIANTS = {
10
- STANDARD: 'standard',
11
- MODAL: 'modal',
12
- EXPANDED: 'expanded'
13
- };
14
-
15
- // Constants for sheet positions
16
- const SHEET_POSITIONS = {
17
- BOTTOM: 'bottom',
18
- TOP: 'top',
19
- LEFT: 'left',
20
- RIGHT: 'right'
21
- };
22
-
23
- // Constants for sheet events
24
- const SHEET_EVENTS = {
25
- OPEN: 'open',
26
- CLOSE: 'close',
27
- DRAG_START: 'dragstart',
28
- DRAG_END: 'dragend'
29
- };
30
-
31
- // Mock sheet implementation
32
- const createMockSheet = (config: SheetConfig = {}): SheetComponent => {
33
- // Create main elements
34
- const element = document.createElement('div');
35
- element.className = 'mtrl-sheet';
36
-
37
- const scrim = document.createElement('div');
38
- scrim.className = 'mtrl-sheet__scrim';
39
-
40
- const container = document.createElement('div');
41
- container.className = 'mtrl-sheet__container';
42
-
43
- // Default settings
44
- const settings = {
45
- variant: config.variant || SHEET_VARIANTS.STANDARD,
46
- position: config.position || SHEET_POSITIONS.BOTTOM,
47
- open: config.open || false,
48
- dismissible: config.dismissible !== undefined ? config.dismissible : true,
49
- dragHandle: config.dragHandle !== undefined ? config.dragHandle : true,
50
- content: config.content || '',
51
- title: config.title || '',
52
- prefix: config.prefix || 'mtrl',
53
- componentName: config.componentName || 'sheet',
54
- elevation: config.elevation || 3,
55
- maxHeight: config.maxHeight || '80%',
56
- enableGestures: config.enableGestures !== undefined ? config.enableGestures : true
57
- };
58
-
59
- // Apply variant class
60
- element.classList.add(`mtrl-sheet--${settings.variant}`);
61
-
62
- // Apply position class
63
- element.classList.add(`mtrl-sheet--${settings.position}`);
64
-
65
- // Apply elevation class
66
- element.classList.add(`mtrl-sheet--elevation-${settings.elevation}`);
67
-
68
- // Apply open state
69
- if (settings.open) {
70
- element.classList.add('mtrl-sheet--open');
71
- }
72
-
73
- // Apply additional classes
74
- if (config.class) {
75
- const classes = config.class.split(' ');
76
- classes.forEach(className => element.classList.add(className));
77
- }
78
-
79
- // Create drag handle if enabled
80
- let dragHandleElement: HTMLElement | null = null;
81
- if (settings.dragHandle) {
82
- dragHandleElement = document.createElement('div');
83
- dragHandleElement.className = 'mtrl-sheet__handle';
84
- container.appendChild(dragHandleElement);
85
- }
86
-
87
- // Create title if provided
88
- let titleElement: HTMLElement | null = null;
89
- if (settings.title) {
90
- titleElement = document.createElement('div');
91
- titleElement.className = 'mtrl-sheet__title';
92
- titleElement.textContent = settings.title;
93
- container.appendChild(titleElement);
94
- }
95
-
96
- // Create content element
97
- const contentElement = document.createElement('div');
98
- contentElement.className = 'mtrl-sheet__content';
99
-
100
- if (settings.content) {
101
- contentElement.innerHTML = settings.content;
102
- }
103
-
104
- container.appendChild(contentElement);
105
-
106
- // Add max height to container
107
- if (settings.maxHeight) {
108
- container.style.maxHeight = settings.maxHeight;
109
- }
110
-
111
- // Assemble the sheet
112
- element.appendChild(scrim);
113
- element.appendChild(container);
114
-
115
- // Track event handlers
116
- const eventHandlers: Record<string, Function[]> = {};
117
-
118
- // Emit an event
119
- const emit = (event: string) => {
120
- const handlers = eventHandlers[event];
121
- if (handlers) {
122
- handlers.forEach(handler => handler());
123
- }
124
-
125
- // Direct callbacks
126
- if (event === SHEET_EVENTS.OPEN && config.onOpen) {
127
- config.onOpen();
128
- } else if (event === SHEET_EVENTS.CLOSE && config.onClose) {
129
- config.onClose();
130
- }
131
- };
132
-
133
- // Set up event handlers
134
- scrim.addEventListener('click', () => {
135
- if (settings.dismissible) {
136
- sheet.close();
137
- }
138
- });
139
-
140
- // Content API
141
- const contentAPI = {
142
- setContent: (html: string) => {
143
- contentElement.innerHTML = html;
144
- settings.content = html;
145
- return contentAPI;
146
- },
147
-
148
- getContent: () => settings.content,
149
-
150
- getElement: () => contentElement
151
- };
152
-
153
- // Title API
154
- const titleAPI = {
155
- setTitle: (text: string) => {
156
- settings.title = text;
157
-
158
- if (text) {
159
- if (!titleElement) {
160
- titleElement = document.createElement('div');
161
- titleElement.className = 'mtrl-sheet__title';
162
- if (dragHandleElement) {
163
- container.insertBefore(titleElement, dragHandleElement.nextSibling);
164
- } else {
165
- container.insertBefore(titleElement, container.firstChild);
166
- }
167
- }
168
-
169
- titleElement.textContent = text;
170
- } else if (titleElement) {
171
- titleElement.remove();
172
- titleElement = null;
173
- }
174
-
175
- return titleAPI;
176
- },
177
-
178
- getTitle: () => settings.title,
179
-
180
- getElement: () => titleElement
181
- };
182
-
183
- // Create the sheet component
184
- const sheet: SheetComponent = {
185
- element,
186
- container,
187
- content: contentAPI,
188
- title: titleAPI,
189
-
190
- state: {
191
- open: () => {
192
- if (!settings.open) {
193
- element.classList.add('mtrl-sheet--open');
194
- settings.open = true;
195
- emit(SHEET_EVENTS.OPEN);
196
- }
197
- },
198
-
199
- close: () => {
200
- if (settings.open) {
201
- element.classList.remove('mtrl-sheet--open');
202
- settings.open = false;
203
- emit(SHEET_EVENTS.CLOSE);
204
- }
205
- },
206
-
207
- isOpen: () => settings.open
208
- },
209
-
210
- lifecycle: {
211
- destroy: () => {
212
- sheet.destroy();
213
- }
214
- },
215
-
216
- getClass: (name: string) => {
217
- const prefix = settings.prefix;
218
- return name ? `${prefix}-${name}` : `${prefix}-sheet`;
219
- },
220
-
221
- open: () => {
222
- sheet.state.open();
223
- return sheet;
224
- },
225
-
226
- close: () => {
227
- sheet.state.close();
228
- return sheet;
229
- },
230
-
231
- setContent: (html: string) => {
232
- contentAPI.setContent(html);
233
- return sheet;
234
- },
235
-
236
- getContent: () => contentAPI.getContent(),
237
-
238
- setTitle: (text: string) => {
239
- titleAPI.setTitle(text);
240
- return sheet;
241
- },
242
-
243
- getTitle: () => titleAPI.getTitle(),
244
-
245
- setDragHandle: (enabled: boolean) => {
246
- if (enabled && !dragHandleElement) {
247
- // Create drag handle
248
- dragHandleElement = document.createElement('div');
249
- dragHandleElement.className = 'mtrl-sheet__handle';
250
- container.insertBefore(dragHandleElement, container.firstChild);
251
- } else if (!enabled && dragHandleElement) {
252
- // Remove drag handle
253
- dragHandleElement.remove();
254
- dragHandleElement = null;
255
- }
256
-
257
- settings.dragHandle = enabled;
258
- return sheet;
259
- },
260
-
261
- setMaxHeight: (height: string) => {
262
- settings.maxHeight = height;
263
- container.style.maxHeight = height;
264
- return sheet;
265
- },
266
-
267
- destroy: () => {
268
- // Remove element from DOM if it has a parent
269
- if (element.parentNode) {
270
- element.parentNode.removeChild(element);
271
- }
272
-
273
- // Clear event handlers
274
- for (const event in eventHandlers) {
275
- eventHandlers[event] = [];
276
- }
277
- },
278
-
279
- on: (event: string, handler: Function) => {
280
- if (!eventHandlers[event]) {
281
- eventHandlers[event] = [];
282
- }
283
-
284
- eventHandlers[event].push(handler);
285
- return sheet;
286
- },
287
-
288
- off: (event: string, handler: Function) => {
289
- if (eventHandlers[event]) {
290
- eventHandlers[event] = eventHandlers[event].filter(h => h !== handler);
291
- }
292
-
293
- return sheet;
294
- },
295
-
296
- addClass: (...classes: string[]) => {
297
- classes.forEach(className => element.classList.add(className));
298
- return sheet;
299
- }
300
- };
301
-
302
- return sheet;
303
- };
304
-
305
- describe('Sheet Component', () => {
306
- test('should create a sheet element', () => {
307
- const sheet = createMockSheet();
308
-
309
- expect(sheet.element).toBeDefined();
310
- expect(sheet.element.tagName).toBe('DIV');
311
- expect(sheet.element.className).toContain('mtrl-sheet');
312
-
313
- expect(sheet.container).toBeDefined();
314
- expect(sheet.container.className).toContain('mtrl-sheet__container');
315
-
316
- const scrim = sheet.element.querySelector('.mtrl-sheet__scrim');
317
- expect(scrim).toBeDefined();
318
- });
319
-
320
- test('should apply standard variant by default', () => {
321
- const sheet = createMockSheet();
322
- expect(sheet.element.className).toContain('mtrl-sheet--standard');
323
- });
324
-
325
- test('should apply different variants', () => {
326
- const variants = Object.values(SHEET_VARIANTS);
327
-
328
- variants.forEach(variant => {
329
- const sheet = createMockSheet({ variant });
330
- expect(sheet.element.className).toContain(`mtrl-sheet--${variant}`);
331
- });
332
- });
333
-
334
- test('should apply bottom position by default', () => {
335
- const sheet = createMockSheet();
336
- expect(sheet.element.className).toContain('mtrl-sheet--bottom');
337
- });
338
-
339
- test('should apply different positions', () => {
340
- const positions = Object.values(SHEET_POSITIONS);
341
-
342
- positions.forEach(position => {
343
- const sheet = createMockSheet({ position });
344
- expect(sheet.element.className).toContain(`mtrl-sheet--${position}`);
345
- });
346
- });
347
-
348
- test('should apply elevation level', () => {
349
- const sheet = createMockSheet({ elevation: 4 });
350
- expect(sheet.element.className).toContain('mtrl-sheet--elevation-4');
351
- });
352
-
353
- test('should be closed by default', () => {
354
- const sheet = createMockSheet();
355
- expect(sheet.element.className).not.toContain('mtrl-sheet--open');
356
- expect(sheet.state.isOpen()).toBe(false);
357
- });
358
-
359
- test('should be initially open when configured', () => {
360
- const sheet = createMockSheet({ open: true });
361
- expect(sheet.element.className).toContain('mtrl-sheet--open');
362
- expect(sheet.state.isOpen()).toBe(true);
363
- });
364
-
365
- test('should create drag handle by default', () => {
366
- const sheet = createMockSheet();
367
-
368
- const handle = sheet.element.querySelector('.mtrl-sheet__handle');
369
- expect(handle).toBeDefined();
370
- });
371
-
372
- test('should not create drag handle when disabled', () => {
373
- const sheet = createMockSheet({ dragHandle: false });
374
-
375
- const handle = sheet.element.querySelector('.mtrl-sheet__handle');
376
- expect(handle).toBeNull();
377
- });
378
-
379
- test('should set initial content', () => {
380
- const content = '<p>Sheet content</p>';
381
- const sheet = createMockSheet({ content });
382
-
383
- const contentElement = sheet.element.querySelector('.mtrl-sheet__content');
384
- expect(contentElement).toBeDefined();
385
- expect(contentElement?.innerHTML).toBe(content);
386
-
387
- expect(sheet.getContent()).toBe(content);
388
- });
389
-
390
- test('should set initial title', () => {
391
- const title = 'Sheet Title';
392
- const sheet = createMockSheet({ title });
393
-
394
- const titleElement = sheet.element.querySelector('.mtrl-sheet__title');
395
- expect(titleElement).toBeDefined();
396
- expect(titleElement?.textContent).toBe(title);
397
-
398
- expect(sheet.getTitle()).toBe(title);
399
- });
400
-
401
- test('should apply max height', () => {
402
- const maxHeight = '50%';
403
- const sheet = createMockSheet({ maxHeight });
404
-
405
- expect(sheet.container.style.maxHeight).toBe(maxHeight);
406
- });
407
-
408
- test('should open and close', () => {
409
- const sheet = createMockSheet();
410
-
411
- expect(sheet.state.isOpen()).toBe(false);
412
-
413
- sheet.open();
414
-
415
- expect(sheet.state.isOpen()).toBe(true);
416
- expect(sheet.element.className).toContain('mtrl-sheet--open');
417
-
418
- sheet.close();
419
-
420
- expect(sheet.state.isOpen()).toBe(false);
421
- expect(sheet.element.className).not.toContain('mtrl-sheet--open');
422
- });
423
-
424
- test('should update content', () => {
425
- const sheet = createMockSheet();
426
-
427
- const initialContent = sheet.element.querySelector('.mtrl-sheet__content');
428
- expect(initialContent?.innerHTML).toBe('');
429
-
430
- const newContent = '<div>New content</div>';
431
- sheet.setContent(newContent);
432
-
433
- expect(sheet.getContent()).toBe(newContent);
434
- expect(initialContent?.innerHTML).toBe(newContent);
435
- });
436
-
437
- test('should add title dynamically', () => {
438
- const sheet = createMockSheet();
439
-
440
- let titleElement = sheet.element.querySelector('.mtrl-sheet__title');
441
- expect(titleElement).toBeNull();
442
-
443
- sheet.setTitle('New Title');
444
-
445
- titleElement = sheet.element.querySelector('.mtrl-sheet__title');
446
- expect(titleElement).toBeDefined();
447
- expect(titleElement?.textContent).toBe('New Title');
448
- expect(sheet.getTitle()).toBe('New Title');
449
- });
450
-
451
- test('should remove title when setting empty string', () => {
452
- const sheet = createMockSheet({ title: 'Initial Title' });
453
-
454
- let titleElement = sheet.element.querySelector('.mtrl-sheet__title');
455
- expect(titleElement).toBeDefined();
456
-
457
- sheet.setTitle('');
458
-
459
- titleElement = sheet.element.querySelector('.mtrl-sheet__title');
460
- expect(titleElement).toBeNull();
461
- expect(sheet.getTitle()).toBe('');
462
- });
463
-
464
- test('should add and remove drag handle', () => {
465
- const sheet = createMockSheet({ dragHandle: false });
466
-
467
- let handleElement = sheet.element.querySelector('.mtrl-sheet__handle');
468
- expect(handleElement).toBeNull();
469
-
470
- sheet.setDragHandle(true);
471
-
472
- handleElement = sheet.element.querySelector('.mtrl-sheet__handle');
473
- expect(handleElement).toBeDefined();
474
-
475
- sheet.setDragHandle(false);
476
-
477
- handleElement = sheet.element.querySelector('.mtrl-sheet__handle');
478
- expect(handleElement).toBeNull();
479
- });
480
-
481
- test('should update max height', () => {
482
- const sheet = createMockSheet({ maxHeight: '80%' });
483
-
484
- expect(sheet.container.style.maxHeight).toBe('80%');
485
-
486
- sheet.setMaxHeight('40%');
487
-
488
- expect(sheet.container.style.maxHeight).toBe('40%');
489
- });
490
-
491
- test('should close when clicking scrim if dismissible', () => {
492
- const sheet = createMockSheet({
493
- open: true,
494
- dismissible: true
495
- });
496
-
497
- expect(sheet.state.isOpen()).toBe(true);
498
-
499
- const scrim = sheet.element.querySelector('.mtrl-sheet__scrim');
500
- scrim?.dispatchEvent(new Event('click'));
501
-
502
- expect(sheet.state.isOpen()).toBe(false);
503
- });
504
-
505
- test('should not close when clicking scrim if not dismissible', () => {
506
- const sheet = createMockSheet({
507
- open: true,
508
- dismissible: false
509
- });
510
-
511
- expect(sheet.state.isOpen()).toBe(true);
512
-
513
- const scrim = sheet.element.querySelector('.mtrl-sheet__scrim');
514
- scrim?.dispatchEvent(new Event('click'));
515
-
516
- expect(sheet.state.isOpen()).toBe(true);
517
- });
518
-
519
- test('should emit open events', () => {
520
- const sheet = createMockSheet();
521
-
522
- let eventFired = false;
523
- sheet.on(SHEET_EVENTS.OPEN, () => {
524
- eventFired = true;
525
- });
526
-
527
- sheet.open();
528
-
529
- expect(eventFired).toBe(true);
530
- });
531
-
532
- test('should emit close events', () => {
533
- const sheet = createMockSheet({ open: true });
534
-
535
- let eventFired = false;
536
- sheet.on(SHEET_EVENTS.CLOSE, () => {
537
- eventFired = true;
538
- });
539
-
540
- sheet.close();
541
-
542
- expect(eventFired).toBe(true);
543
- });
544
-
545
- test('should call onOpen callback', () => {
546
- let callbackFired = false;
547
-
548
- const sheet = createMockSheet({
549
- onOpen: () => {
550
- callbackFired = true;
551
- }
552
- });
553
-
554
- sheet.open();
555
-
556
- expect(callbackFired).toBe(true);
557
- });
558
-
559
- test('should call onClose callback', () => {
560
- let callbackFired = false;
561
-
562
- const sheet = createMockSheet({
563
- open: true,
564
- onClose: () => {
565
- callbackFired = true;
566
- }
567
- });
568
-
569
- sheet.close();
570
-
571
- expect(callbackFired).toBe(true);
572
- });
573
-
574
- test('should not emit events when state does not change', () => {
575
- const sheet = createMockSheet({ open: true });
576
-
577
- let eventCount = 0;
578
- sheet.on(SHEET_EVENTS.OPEN, () => {
579
- eventCount++;
580
- });
581
-
582
- // Open when already open
583
- sheet.open();
584
-
585
- expect(eventCount).toBe(0);
586
-
587
- // Similarly for close
588
- const closedSheet = createMockSheet({ open: false });
589
-
590
- let closeEventCount = 0;
591
- closedSheet.on(SHEET_EVENTS.CLOSE, () => {
592
- closeEventCount++;
593
- });
594
-
595
- // Close when already closed
596
- closedSheet.close();
597
-
598
- expect(closeEventCount).toBe(0);
599
- });
600
-
601
- test('should add CSS classes', () => {
602
- const sheet = createMockSheet();
603
-
604
- sheet.addClass('custom-class', 'special-sheet');
605
-
606
- expect(sheet.element.className).toContain('custom-class');
607
- expect(sheet.element.className).toContain('special-sheet');
608
- });
609
-
610
- test('should remove event listeners', () => {
611
- const sheet = createMockSheet();
612
-
613
- let eventCount = 0;
614
-
615
- const handler = () => {
616
- eventCount++;
617
- };
618
-
619
- sheet.on(SHEET_EVENTS.OPEN, handler);
620
-
621
- sheet.open();
622
- expect(eventCount).toBe(1);
623
-
624
- sheet.off(SHEET_EVENTS.OPEN, handler);
625
-
626
- sheet.close();
627
- sheet.open();
628
- expect(eventCount).toBe(1); // Count should not increase
629
- });
630
-
631
- test('should be properly destroyed', () => {
632
- const sheet = createMockSheet();
633
- document.body.appendChild(sheet.element);
634
-
635
- expect(document.body.contains(sheet.element)).toBe(true);
636
-
637
- sheet.destroy();
638
-
639
- expect(document.body.contains(sheet.element)).toBe(false);
640
- });
641
- });