mtrl 0.3.1 → 0.3.3

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 (162) hide show
  1. package/.env +15 -0
  2. package/CONTRIBUTING.md +62 -23
  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/navigation/nav-item.ts +13 -2
  83. package/src/components/sheet/config.ts +1 -2
  84. package/src/components/sheet/features/gestures.ts +1 -1
  85. package/src/components/sheet/features/position.ts +1 -2
  86. package/src/components/sheet/features/state.ts +1 -1
  87. package/src/components/sheet/index.ts +10 -2
  88. package/src/components/sheet/sheet.ts +1 -2
  89. package/src/components/sheet/types.ts +29 -1
  90. package/src/components/slider/api.ts +1 -1
  91. package/src/components/slider/config.ts +1 -1
  92. package/src/components/slider/features/controller.ts +1 -1
  93. package/src/components/slider/features/handlers.ts +1 -1
  94. package/src/components/slider/features/states.ts +1 -1
  95. package/src/components/slider/index.ts +12 -5
  96. package/src/components/slider/schema.ts +1 -1
  97. package/src/components/slider/types.ts +31 -0
  98. package/src/components/tabs/tab-api.ts +1 -1
  99. package/src/components/tabs/types.ts +1 -1
  100. package/src/components/tooltip/api.ts +6 -2
  101. package/src/components/tooltip/config.ts +9 -28
  102. package/src/components/tooltip/index.ts +10 -1
  103. package/src/components/tooltip/types.ts +38 -3
  104. package/src/core/dom/create.ts +57 -51
  105. package/src/index.ts +129 -31
  106. package/src/styles/abstract/_mixins.scss +23 -9
  107. package/src/styles/abstract/_variables.scss +14 -4
  108. package/src/styles/components/_card.scss +1 -1
  109. package/src/styles/components/_chip.scss +323 -113
  110. package/src/styles/components/_tabs.scss +1 -1
  111. package/src/styles/themes/_autumn.scss +3 -0
  112. package/CLAUDE.md +0 -33
  113. package/src/components/checkbox/constants.ts +0 -37
  114. package/src/components/chip/chip-set.ts +0 -225
  115. package/src/components/chip/chip.ts +0 -118
  116. package/src/components/chip/constants.ts +0 -28
  117. package/src/components/chip/index.ts +0 -12
  118. package/src/components/list/constants.ts +0 -116
  119. package/src/components/sheet/constants.ts +0 -20
  120. package/src/components/slider/constants.ts +0 -32
  121. package/src/components/tooltip/constants.ts +0 -27
  122. package/test/components/badge.test.ts +0 -545
  123. package/test/components/bottom-app-bar.test.ts +0 -303
  124. package/test/components/button.test.ts +0 -233
  125. package/test/components/card.test.ts +0 -560
  126. package/test/components/carousel.test.ts +0 -951
  127. package/test/components/checkbox.test.ts +0 -462
  128. package/test/components/chip.test.ts +0 -692
  129. package/test/components/datepicker.test.ts +0 -1124
  130. package/test/components/dialog.test.ts +0 -990
  131. package/test/components/divider.test.ts +0 -412
  132. package/test/components/extended-fab.test.ts +0 -672
  133. package/test/components/fab.test.ts +0 -561
  134. package/test/components/list.test.ts +0 -365
  135. package/test/components/menu.test.ts +0 -718
  136. package/test/components/navigation.test.ts +0 -186
  137. package/test/components/progress.test.ts +0 -567
  138. package/test/components/radios.test.ts +0 -699
  139. package/test/components/search.test.ts +0 -1135
  140. package/test/components/segmented-button.test.ts +0 -732
  141. package/test/components/sheet.test.ts +0 -641
  142. package/test/components/slider.test.ts +0 -1220
  143. package/test/components/snackbar.test.ts +0 -461
  144. package/test/components/switch.test.ts +0 -452
  145. package/test/components/tabs.test.ts +0 -1369
  146. package/test/components/textfield.test.ts +0 -400
  147. package/test/components/timepicker.test.ts +0 -592
  148. package/test/components/tooltip.test.ts +0 -630
  149. package/test/components/top-app-bar.test.ts +0 -566
  150. package/test/core/dom.attributes.test.ts +0 -148
  151. package/test/core/dom.classes.test.ts +0 -152
  152. package/test/core/dom.events.test.ts +0 -243
  153. package/test/core/emitter.test.ts +0 -141
  154. package/test/core/ripple.test.ts +0 -99
  155. package/test/core/state.store.test.ts +0 -189
  156. package/test/core/utils.normalize.test.ts +0 -61
  157. package/test/core/utils.object.test.ts +0 -120
  158. package/test/setup.js +0 -371
  159. package/test/setup.ts +0 -451
  160. package/tsconfig.json +0 -22
  161. package/typedoc.json +0 -28
  162. package/typedoc.simple.json +0 -14
@@ -1,152 +0,0 @@
1
- // test/core/dom.classes.test.ts
2
- import { describe, test, expect, beforeAll, afterAll } from 'bun:test';
3
- import { JSDOM } from 'jsdom';
4
- import { addClass, removeClass, toggleClass, hasClass } from '../../src/core/dom/classes';
5
-
6
- // Setup jsdom environment
7
- let dom: JSDOM;
8
- let window: Window;
9
- let document: Document;
10
- let originalGlobalDocument: any;
11
- let originalGlobalWindow: any;
12
-
13
- beforeAll(() => {
14
- // Create a new JSDOM instance
15
- dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
16
- url: 'http://localhost/',
17
- pretendToBeVisual: true
18
- });
19
-
20
- // Get window and document from jsdom
21
- window = dom.window;
22
- document = window.document;
23
-
24
- // Store original globals
25
- originalGlobalDocument = global.document;
26
- originalGlobalWindow = global.window;
27
-
28
- // Set globals to use jsdom
29
- global.document = document;
30
- global.window = window;
31
- global.Element = window.Element;
32
- global.HTMLElement = window.HTMLElement;
33
- });
34
-
35
- afterAll(() => {
36
- // Restore original globals
37
- global.document = originalGlobalDocument;
38
- global.window = originalGlobalWindow;
39
-
40
- // Clean up jsdom
41
- window.close();
42
- });
43
-
44
- describe('DOM Classes Utilities', () => {
45
- test('should add a single class', () => {
46
- const element = document.createElement('div');
47
- addClass(element, 'test');
48
- expect(element.classList.contains('test')).toBe(true);
49
- });
50
-
51
- test('should add multiple classes', () => {
52
- const element = document.createElement('div');
53
- addClass(element, 'test1', 'test2', 'test3');
54
- expect(element.classList.contains('test1')).toBe(true);
55
- expect(element.classList.contains('test2')).toBe(true);
56
- expect(element.classList.contains('test3')).toBe(true);
57
- });
58
-
59
- test('should add classes from an array', () => {
60
- const element = document.createElement('div');
61
- addClass(element, ['test1', 'test2', 'test3']);
62
- expect(element.classList.contains('test1')).toBe(true);
63
- expect(element.classList.contains('test2')).toBe(true);
64
- expect(element.classList.contains('test3')).toBe(true);
65
- });
66
-
67
- test('should add classes from space-separated strings', () => {
68
- const element = document.createElement('div');
69
- addClass(element, 'test1 test2', 'test3');
70
- expect(element.classList.contains('test1')).toBe(true);
71
- expect(element.classList.contains('test2')).toBe(true);
72
- expect(element.classList.contains('test3')).toBe(true);
73
- });
74
-
75
- test('should not add empty classes', () => {
76
- const element = document.createElement('div');
77
- addClass(element, '', ' ', 'test');
78
- expect(element.classList.contains('')).toBe(false);
79
- expect(element.classList.contains(' ')).toBe(false);
80
- expect(element.classList.contains('test')).toBe(true);
81
- expect(element.className).toBe('test');
82
- });
83
-
84
- test('should remove a single class', () => {
85
- const element = document.createElement('div');
86
- element.classList.add('test');
87
- removeClass(element, 'test');
88
- expect(element.classList.contains('test')).toBe(false);
89
- });
90
-
91
- test('should remove multiple classes', () => {
92
- const element = document.createElement('div');
93
- element.classList.add('test1', 'test2', 'test3');
94
- removeClass(element, 'test1', 'test3');
95
- expect(element.classList.contains('test1')).toBe(false);
96
- expect(element.classList.contains('test2')).toBe(true);
97
- expect(element.classList.contains('test3')).toBe(false);
98
- });
99
-
100
- test('should remove classes from an array', () => {
101
- const element = document.createElement('div');
102
- element.classList.add('test1', 'test2', 'test3');
103
- removeClass(element, ['test1', 'test3']);
104
- expect(element.classList.contains('test1')).toBe(false);
105
- expect(element.classList.contains('test2')).toBe(true);
106
- expect(element.classList.contains('test3')).toBe(false);
107
- });
108
-
109
- test('should toggle a single class', () => {
110
- const element = document.createElement('div');
111
- toggleClass(element, 'test');
112
- expect(element.classList.contains('test')).toBe(true);
113
- toggleClass(element, 'test');
114
- expect(element.classList.contains('test')).toBe(false);
115
- });
116
-
117
- test('should toggle multiple classes', () => {
118
- const element = document.createElement('div');
119
- toggleClass(element, 'test1', 'test2');
120
- expect(element.classList.contains('test1')).toBe(true);
121
- expect(element.classList.contains('test2')).toBe(true);
122
- toggleClass(element, 'test1', 'test3');
123
- expect(element.classList.contains('test1')).toBe(false);
124
- expect(element.classList.contains('test2')).toBe(true);
125
- expect(element.classList.contains('test3')).toBe(true);
126
- });
127
-
128
- test('should check if element has a class', () => {
129
- const element = document.createElement('div');
130
- element.classList.add('test1', 'test2');
131
- expect(hasClass(element, 'test1')).toBe(true);
132
- expect(hasClass(element, 'test3')).toBe(false);
133
- });
134
-
135
- test('should check if element has multiple classes', () => {
136
- const element = document.createElement('div');
137
- element.classList.add('test1', 'test2', 'test3');
138
- expect(hasClass(element, 'test1', 'test2')).toBe(true);
139
- expect(hasClass(element, 'test1', 'test4')).toBe(false);
140
- });
141
-
142
- test('should return the element from modifier functions', () => {
143
- const element = document.createElement('div');
144
- const result1 = addClass(element, 'test');
145
- const result2 = removeClass(element, 'test');
146
- const result3 = toggleClass(element, 'test');
147
-
148
- expect(result1).toBe(element);
149
- expect(result2).toBe(element);
150
- expect(result3).toBe(element);
151
- });
152
- });
@@ -1,243 +0,0 @@
1
- // test/core/dom.events.test.ts
2
- import { describe, test, expect, mock, beforeAll, afterAll } from 'bun:test';
3
- import { JSDOM } from 'jsdom';
4
- import { createEventManager } from '../../src/core/dom/events';
5
-
6
- // Setup jsdom environment
7
- let dom: JSDOM;
8
- let window: Window;
9
- let document: Document;
10
- let originalGlobalDocument: any;
11
- let originalGlobalWindow: any;
12
- let originalConsoleError: any;
13
- let originalConsoleWarn: any;
14
-
15
- beforeAll(() => {
16
- // Create a new JSDOM instance
17
- dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
18
- url: 'http://localhost/',
19
- pretendToBeVisual: true
20
- });
21
-
22
- // Get window and document from jsdom
23
- window = dom.window;
24
- document = window.document;
25
-
26
- // Store original globals
27
- originalGlobalDocument = global.document;
28
- originalGlobalWindow = global.window;
29
- originalConsoleError = console.error;
30
- originalConsoleWarn = console.warn;
31
-
32
- // Set globals to use jsdom
33
- global.document = document;
34
- global.window = window;
35
- global.Element = window.Element;
36
- global.HTMLElement = window.HTMLElement;
37
- global.Event = window.Event;
38
-
39
- // Mock console methods
40
- console.error = mock(() => {});
41
- console.warn = mock(() => {});
42
- });
43
-
44
- afterAll(() => {
45
- // Restore original globals
46
- global.document = originalGlobalDocument;
47
- global.window = originalGlobalWindow;
48
- console.error = originalConsoleError;
49
- console.warn = originalConsoleWarn;
50
-
51
- // Clean up jsdom
52
- window.close();
53
- });
54
-
55
- describe('DOM Events Manager', () => {
56
- test('should create an event manager', () => {
57
- const element = document.createElement('div');
58
- const manager = createEventManager(element);
59
-
60
- expect(manager).toBeDefined();
61
- expect(typeof manager.on).toBe('function');
62
- expect(typeof manager.off).toBe('function');
63
- expect(typeof manager.pause).toBe('function');
64
- expect(typeof manager.resume).toBe('function');
65
- expect(typeof manager.destroy).toBe('function');
66
- expect(typeof manager.getHandlers).toBe('function');
67
- expect(typeof manager.hasHandler).toBe('function');
68
- });
69
-
70
- test('should add event listener', () => {
71
- const element = document.createElement('div');
72
- const manager = createEventManager(element);
73
- const handler = mock(() => {});
74
-
75
- manager.on('click', handler);
76
-
77
- // Trigger the event
78
- element.dispatchEvent(new Event('click'));
79
-
80
- expect(handler).toHaveBeenCalledTimes(1);
81
- expect(manager.hasHandler('click', handler)).toBe(true);
82
- });
83
-
84
- test('should remove event listener', () => {
85
- const element = document.createElement('div');
86
- const manager = createEventManager(element);
87
- const handler = mock(() => {});
88
-
89
- manager.on('click', handler);
90
- manager.off('click', handler);
91
-
92
- // Trigger the event
93
- element.dispatchEvent(new Event('click'));
94
-
95
- expect(handler).toHaveBeenCalledTimes(0);
96
- expect(manager.hasHandler('click', handler)).toBe(false);
97
- });
98
-
99
- test('should handle multiple event listeners', () => {
100
- const element = document.createElement('div');
101
- const manager = createEventManager(element);
102
- const clickHandler = mock(() => {});
103
- const mouseoverHandler = mock(() => {});
104
-
105
- manager.on('click', clickHandler);
106
- manager.on('mouseover', mouseoverHandler);
107
-
108
- // Trigger events
109
- element.dispatchEvent(new Event('click'));
110
- element.dispatchEvent(new Event('mouseover'));
111
-
112
- expect(clickHandler).toHaveBeenCalledTimes(1);
113
- expect(mouseoverHandler).toHaveBeenCalledTimes(1);
114
- expect(manager.hasHandler('click', clickHandler)).toBe(true);
115
- expect(manager.hasHandler('mouseover', mouseoverHandler)).toBe(true);
116
- });
117
-
118
- test('should pause and resume all event listeners', () => {
119
- const element = document.createElement('div');
120
- const manager = createEventManager(element);
121
- const handler = mock(() => {});
122
-
123
- manager.on('click', handler);
124
-
125
- // Pause events
126
- manager.pause();
127
-
128
- // Trigger event (should not call handler)
129
- element.dispatchEvent(new Event('click'));
130
- expect(handler).toHaveBeenCalledTimes(0);
131
-
132
- // Resume events
133
- manager.resume();
134
-
135
- // Trigger event (should call handler)
136
- element.dispatchEvent(new Event('click'));
137
- expect(handler).toHaveBeenCalledTimes(1);
138
- });
139
-
140
- test('should destroy all event listeners', () => {
141
- const element = document.createElement('div');
142
- const manager = createEventManager(element);
143
- const clickHandler = mock(() => {});
144
- const mouseoverHandler = mock(() => {});
145
-
146
- manager.on('click', clickHandler);
147
- manager.on('mouseover', mouseoverHandler);
148
-
149
- // Destroy all handlers
150
- manager.destroy();
151
-
152
- // Trigger events
153
- element.dispatchEvent(new Event('click'));
154
- element.dispatchEvent(new Event('mouseover'));
155
-
156
- expect(clickHandler).toHaveBeenCalledTimes(0);
157
- expect(mouseoverHandler).toHaveBeenCalledTimes(0);
158
- expect(manager.hasHandler('click', clickHandler)).toBe(false);
159
- expect(manager.hasHandler('mouseover', mouseoverHandler)).toBe(false);
160
- expect(manager.getHandlers().size).toBe(0);
161
- });
162
-
163
- test('should provide access to all handlers', () => {
164
- const element = document.createElement('div');
165
- const manager = createEventManager(element);
166
- const clickHandler = mock(() => {});
167
- const mouseoverHandler = mock(() => {});
168
-
169
- manager.on('click', clickHandler);
170
- manager.on('mouseover', mouseoverHandler);
171
-
172
- const handlers = manager.getHandlers();
173
- expect(handlers.size).toBe(2);
174
-
175
- // Check first handler keys (can't check exact values since the Map keys are generated)
176
- const keys = Array.from(handlers.keys());
177
- expect(keys.length).toBe(2);
178
- expect(keys[0]).toContain('click_');
179
- expect(keys[1]).toContain('mouseover_');
180
-
181
- // Check entries have expected properties
182
- const firstEntry = handlers.get(keys[0]);
183
- expect(firstEntry).toBeDefined();
184
- if (firstEntry) {
185
- expect(firstEntry.event).toBe('click');
186
- expect(firstEntry.original).toBe(clickHandler);
187
- expect(typeof firstEntry.enhanced).toBe('function');
188
- }
189
- });
190
-
191
- test('should support event listener options', () => {
192
- const element = document.createElement('div');
193
- const manager = createEventManager(element);
194
- const handler = mock(() => {});
195
- const options = { once: true };
196
-
197
- manager.on('click', handler, options);
198
-
199
- // Trigger event twice
200
- element.dispatchEvent(new Event('click'));
201
- element.dispatchEvent(new Event('click'));
202
-
203
- // Handler should only be called once due to { once: true }
204
- expect(handler).toHaveBeenCalledTimes(1);
205
- });
206
-
207
- test('should catch errors in event handlers', () => {
208
- const element = document.createElement('div');
209
- const manager = createEventManager(element);
210
-
211
- const errorHandler = () => {
212
- throw new Error('Test error');
213
- };
214
-
215
- // Add handler that throws
216
- manager.on('click', errorHandler);
217
-
218
- // Should not throw when dispatching the event
219
- expect(() => {
220
- element.dispatchEvent(new Event('click'));
221
- }).not.toThrow();
222
-
223
- // Console.error should have been called
224
- expect(console.error).toHaveBeenCalledTimes(1);
225
- });
226
-
227
- test('should chain method calls', () => {
228
- const element = document.createElement('div');
229
- const manager = createEventManager(element);
230
- const handler1 = mock(() => {});
231
- const handler2 = mock(() => {});
232
-
233
- // Chain methods
234
- manager
235
- .on('click', handler1)
236
- .on('mouseover', handler2)
237
- .off('mouseover', handler2);
238
-
239
- // Check results
240
- expect(manager.hasHandler('click', handler1)).toBe(true);
241
- expect(manager.hasHandler('mouseover', handler2)).toBe(false);
242
- });
243
- });
@@ -1,141 +0,0 @@
1
- // test/core/emitter.test.ts
2
- import { describe, test, expect, mock } from 'bun:test';
3
- import { createEmitter } from '../../src/core/state/emitter';
4
-
5
- describe('Event Emitter', () => {
6
- test('should create an emitter with expected methods', () => {
7
- const emitter = createEmitter();
8
- expect(emitter).toBeDefined();
9
- expect(emitter.on).toBeInstanceOf(Function);
10
- expect(emitter.off).toBeInstanceOf(Function);
11
- expect(emitter.emit).toBeInstanceOf(Function);
12
- expect(emitter.clear).toBeInstanceOf(Function);
13
- });
14
-
15
- test('should register event handlers with on()', () => {
16
- const emitter = createEmitter();
17
- const handler = mock(() => {});
18
-
19
- const unsubscribe = emitter.on('test', handler);
20
-
21
- expect(unsubscribe).toBeInstanceOf(Function);
22
- });
23
-
24
- test('should invoke handlers when event is emitted', () => {
25
- const emitter = createEmitter();
26
- const handler1 = mock(() => {});
27
- const handler2 = mock(() => {});
28
- const eventData = { foo: 'bar' };
29
-
30
- emitter.on('test', handler1);
31
- emitter.on('test', handler2);
32
-
33
- emitter.emit('test', eventData);
34
-
35
- expect(handler1).toHaveBeenCalledTimes(1);
36
- expect(handler1).toHaveBeenCalledWith(eventData);
37
-
38
- expect(handler2).toHaveBeenCalledTimes(1);
39
- expect(handler2).toHaveBeenCalledWith(eventData);
40
- });
41
-
42
- test('should remove handlers with off()', () => {
43
- const emitter = createEmitter();
44
- const handler = mock(() => {});
45
-
46
- emitter.on('test', handler);
47
- emitter.off('test', handler);
48
-
49
- emitter.emit('test');
50
-
51
- expect(handler).not.toHaveBeenCalled();
52
- });
53
-
54
- test('should remove specific handlers while keeping others', () => {
55
- const emitter = createEmitter();
56
- const handler1 = mock(() => {});
57
- const handler2 = mock(() => {});
58
-
59
- emitter.on('test', handler1);
60
- emitter.on('test', handler2);
61
-
62
- emitter.off('test', handler1);
63
-
64
- emitter.emit('test');
65
-
66
- expect(handler1).not.toHaveBeenCalled();
67
- expect(handler2).toHaveBeenCalledTimes(1);
68
- });
69
-
70
- test('should unsubscribe handlers using the returned function', () => {
71
- const emitter = createEmitter();
72
- const handler = mock(() => {});
73
-
74
- const unsubscribe = emitter.on('test', handler);
75
- unsubscribe();
76
-
77
- emitter.emit('test');
78
-
79
- expect(handler).not.toHaveBeenCalled();
80
- });
81
-
82
- test('should support multiple event types', () => {
83
- const emitter = createEmitter();
84
- const handler1 = mock(() => {});
85
- const handler2 = mock(() => {});
86
-
87
- emitter.on('event1', handler1);
88
- emitter.on('event2', handler2);
89
-
90
- emitter.emit('event1');
91
-
92
- expect(handler1).toHaveBeenCalledTimes(1);
93
- expect(handler2).not.toHaveBeenCalled();
94
-
95
- emitter.emit('event2');
96
-
97
- expect(handler1).toHaveBeenCalledTimes(1);
98
- expect(handler2).toHaveBeenCalledTimes(1);
99
- });
100
-
101
- test('should clear all event handlers', () => {
102
- const emitter = createEmitter();
103
- const handler1 = mock(() => {});
104
- const handler2 = mock(() => {});
105
-
106
- emitter.on('event1', handler1);
107
- emitter.on('event2', handler2);
108
-
109
- emitter.clear();
110
-
111
- emitter.emit('event1');
112
- emitter.emit('event2');
113
-
114
- expect(handler1).not.toHaveBeenCalled();
115
- expect(handler2).not.toHaveBeenCalled();
116
- });
117
-
118
- test('should pass multiple arguments to handlers', () => {
119
- const emitter = createEmitter();
120
- const handler = mock(() => {});
121
-
122
- emitter.on('test', handler);
123
-
124
- const arg1 = { id: 1 };
125
- const arg2 = 'string';
126
- const arg3 = [1, 2, 3];
127
-
128
- emitter.emit('test', arg1, arg2, arg3);
129
-
130
- expect(handler).toHaveBeenCalledWith(arg1, arg2, arg3);
131
- });
132
-
133
- test('should do nothing when emitting event with no handlers', () => {
134
- const emitter = createEmitter();
135
-
136
- // This should not throw
137
- expect(() => {
138
- emitter.emit('nonexistent');
139
- }).not.toThrow();
140
- });
141
- });
@@ -1,99 +0,0 @@
1
- // test/core/ripple.test.ts
2
- import { describe, test, expect, mock, beforeAll, afterAll } from 'bun:test';
3
- import { JSDOM } from 'jsdom';
4
- import { createRipple } from '../../src/core/build/ripple';
5
-
6
- // Setup jsdom environment
7
- let dom: JSDOM;
8
- let window: Window;
9
- let document: Document;
10
- let originalGlobalDocument: any;
11
- let originalGlobalWindow: any;
12
-
13
- beforeAll(() => {
14
- // Create a new JSDOM instance
15
- dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
16
- url: 'http://localhost/',
17
- pretendToBeVisual: true
18
- });
19
-
20
- // Get window and document from jsdom
21
- window = dom.window;
22
- document = window.document;
23
-
24
- // Store original globals
25
- originalGlobalDocument = global.document;
26
- originalGlobalWindow = global.window;
27
-
28
- // Set globals to use jsdom
29
- global.document = document;
30
- global.window = window;
31
- global.Element = window.Element;
32
- global.HTMLElement = window.HTMLElement;
33
- global.Event = window.Event;
34
- });
35
-
36
- afterAll(() => {
37
- // Restore original globals
38
- global.document = originalGlobalDocument;
39
- global.window = originalGlobalWindow;
40
-
41
- // Clean up jsdom
42
- window.close();
43
- });
44
-
45
- describe('Ripple Effect', () => {
46
- test('should create a ripple controller', () => {
47
- const ripple = createRipple();
48
- expect(ripple).toBeDefined();
49
- expect(typeof ripple.mount).toBe('function');
50
- expect(typeof ripple.unmount).toBe('function');
51
- });
52
-
53
- test('should mount ripple effect to an element', () => {
54
- const ripple = createRipple();
55
- const element = document.createElement('div');
56
-
57
- // Mount ripple to element
58
- ripple.mount(element);
59
-
60
- // Just verify that the mount function doesn't throw
61
- // The actual style changes may vary based on implementation
62
- expect(true).toBe(true);
63
- });
64
-
65
- test('should not fail when mounting to a null element', () => {
66
- const ripple = createRipple();
67
- expect(() => ripple.mount(null as any)).not.toThrow();
68
- });
69
-
70
- test('should create ripple element on mousedown', () => {
71
- // Skip this test as it requires more advanced DOM mocking
72
- // than we currently have available
73
- console.log('Skipping "should create ripple element on mousedown" test - requires advanced DOM mocking');
74
- });
75
-
76
- test('should add document cleanup event listeners', () => {
77
- // Skip this test as it requires more advanced DOM mocking
78
- // than we currently have available
79
- console.log('Skipping "should add document cleanup event listeners" test - requires advanced DOM mocking');
80
- });
81
-
82
- test('should remove ripple elements on unmount', () => {
83
- const ripple = createRipple();
84
- const element = document.createElement('div');
85
-
86
- // Mount and then unmount
87
- ripple.mount(element);
88
- ripple.unmount(element);
89
-
90
- // Just verify that the unmount function doesn't throw
91
- // The actual DOM changes may vary based on implementation
92
- expect(true).toBe(true);
93
- });
94
-
95
- test('should not fail when unmounting a null element', () => {
96
- const ripple = createRipple();
97
- expect(() => ripple.unmount(null as any)).not.toThrow();
98
- });
99
- });