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,452 +0,0 @@
1
- // test/components/switch.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
- SwitchComponent,
17
- SwitchConfig,
18
- SwitchLabelPosition
19
- } from '../../src/components/switch/types';
20
-
21
- // Define constants here to avoid circular dependencies
22
- const SWITCH_LABEL_POSITION = {
23
- START: 'start',
24
- END: 'end'
25
- } as const;
26
-
27
- // Create a mock switch implementation
28
- const createMockSwitch = (config: SwitchConfig = {}): SwitchComponent => {
29
- // Default configuration
30
- const defaultConfig: SwitchConfig = {
31
- label: '',
32
- labelPosition: 'end',
33
- checked: false,
34
- disabled: false,
35
- required: false,
36
- prefix: 'mtrl',
37
- componentName: 'switch'
38
- };
39
-
40
- // Merge with user configuration
41
- const mergedConfig = {
42
- ...defaultConfig,
43
- ...config
44
- };
45
-
46
- // Create main element
47
- const element = document.createElement('div');
48
- element.className = `${mergedConfig.prefix}-switch`;
49
-
50
- // Add custom class if provided
51
- if (mergedConfig.class) {
52
- element.className += ` ${mergedConfig.class}`;
53
- }
54
-
55
- // Create input element
56
- const input = document.createElement('input');
57
- input.type = 'checkbox';
58
- input.className = `${mergedConfig.prefix}-switch-input`;
59
- input.checked = Boolean(mergedConfig.checked);
60
- input.disabled = Boolean(mergedConfig.disabled);
61
- input.required = Boolean(mergedConfig.required);
62
-
63
- if (mergedConfig.name) {
64
- input.name = mergedConfig.name;
65
- }
66
-
67
- if (mergedConfig.value) {
68
- input.value = mergedConfig.value;
69
- }
70
-
71
- // Create track element
72
- const track = document.createElement('div');
73
- track.className = `${mergedConfig.prefix}-switch-track`;
74
-
75
- // Create thumb element
76
- const thumb = document.createElement('div');
77
- thumb.className = `${mergedConfig.prefix}-switch-thumb`;
78
- track.appendChild(thumb);
79
-
80
- // Create label if provided
81
- let labelElement: HTMLLabelElement | null = null;
82
-
83
- if (mergedConfig.label) {
84
- labelElement = document.createElement('label');
85
- labelElement.className = `${mergedConfig.prefix}-switch-label`;
86
- labelElement.textContent = mergedConfig.label;
87
-
88
- // Position the label appropriately
89
- if (mergedConfig.labelPosition) {
90
- element.classList.add(`${mergedConfig.prefix}-switch--label-${mergedConfig.labelPosition}`);
91
- }
92
- }
93
-
94
- // Add elements to main element
95
- if (labelElement && mergedConfig.labelPosition === 'start') {
96
- element.appendChild(labelElement);
97
- }
98
-
99
- element.appendChild(input);
100
- element.appendChild(track);
101
-
102
- if (labelElement && mergedConfig.labelPosition !== 'start') {
103
- element.appendChild(labelElement);
104
- }
105
-
106
- // Create supporting text element if provided
107
- let supportingTextElement: HTMLElement | null = null;
108
-
109
- if (mergedConfig.supportingText) {
110
- supportingTextElement = document.createElement('div');
111
- supportingTextElement.className = `${mergedConfig.prefix}-switch-helper`;
112
- supportingTextElement.textContent = mergedConfig.supportingText;
113
-
114
- if (mergedConfig.error) {
115
- supportingTextElement.classList.add(`${mergedConfig.prefix}-switch-helper--error`);
116
- element.classList.add(`${mergedConfig.prefix}-switch--error`);
117
- }
118
-
119
- element.appendChild(supportingTextElement);
120
- }
121
-
122
- // Event handlers
123
- const eventHandlers: Record<string, Function[]> = {};
124
-
125
- // Create the label manager
126
- const label = {
127
- setText: (text: string) => {
128
- if (labelElement) {
129
- labelElement.textContent = text;
130
- }
131
- mergedConfig.label = text;
132
- return label;
133
- },
134
- getText: () => {
135
- if (labelElement) {
136
- return labelElement.textContent || '';
137
- }
138
- return mergedConfig.label || '';
139
- },
140
- getElement: () => {
141
- return labelElement as HTMLElement;
142
- }
143
- };
144
-
145
- // Create the switch instance
146
- const switchComp: SwitchComponent = {
147
- element,
148
- input,
149
- config: mergedConfig,
150
- supportingTextElement,
151
-
152
- getValue: () => input.value,
153
- setValue: (value: string) => {
154
- input.value = value;
155
- return switchComp;
156
- },
157
-
158
- check: () => {
159
- input.checked = true;
160
- return switchComp;
161
- },
162
-
163
- uncheck: () => {
164
- input.checked = false;
165
- return switchComp;
166
- },
167
-
168
- toggle: () => {
169
- input.checked = !input.checked;
170
- return switchComp;
171
- },
172
-
173
- isChecked: () => input.checked,
174
-
175
- setLabel: (text: string) => {
176
- mergedConfig.label = text;
177
- if (labelElement) {
178
- labelElement.textContent = text;
179
- } else if (text) {
180
- labelElement = document.createElement('label');
181
- labelElement.className = `${mergedConfig.prefix}-switch-label`;
182
- labelElement.textContent = text;
183
- element.appendChild(labelElement);
184
- }
185
- return switchComp;
186
- },
187
-
188
- getLabel: () => {
189
- if (labelElement) {
190
- return labelElement.textContent || '';
191
- }
192
- return '';
193
- },
194
-
195
- setSupportingText: (text: string, isError = false) => {
196
- if (!supportingTextElement) {
197
- supportingTextElement = document.createElement('div');
198
- supportingTextElement.className = `${mergedConfig.prefix}-switch-helper`;
199
- element.appendChild(supportingTextElement);
200
- }
201
-
202
- supportingTextElement.textContent = text;
203
- supportingTextElement.classList.toggle(`${mergedConfig.prefix}-switch-helper--error`, isError);
204
- element.classList.toggle(`${mergedConfig.prefix}-switch--error`, isError);
205
-
206
- return switchComp;
207
- },
208
-
209
- removeSupportingText: () => {
210
- if (supportingTextElement && supportingTextElement.parentNode) {
211
- supportingTextElement.remove();
212
- supportingTextElement = null;
213
- }
214
- return switchComp;
215
- },
216
-
217
- on: (event: string, handler: Function) => {
218
- if (!eventHandlers[event]) {
219
- eventHandlers[event] = [];
220
- }
221
-
222
- eventHandlers[event].push(handler);
223
- return switchComp;
224
- },
225
-
226
- off: (event: string, handler: Function) => {
227
- if (!eventHandlers[event]) return switchComp;
228
-
229
- eventHandlers[event] = eventHandlers[event].filter(h => h !== handler);
230
- return switchComp;
231
- },
232
-
233
- emit: (event: string, data: any = {}) => {
234
- if (!eventHandlers[event]) return;
235
-
236
- eventHandlers[event].forEach(handler => handler(data));
237
- },
238
-
239
- enable: () => {
240
- input.disabled = false;
241
- element.classList.remove(`${mergedConfig.prefix}-switch--disabled`);
242
- return switchComp;
243
- },
244
-
245
- disable: () => {
246
- input.disabled = true;
247
- element.classList.add(`${mergedConfig.prefix}-switch--disabled`);
248
- return switchComp;
249
- },
250
-
251
- destroy: () => {
252
- // Clear event handlers
253
- Object.keys(eventHandlers).forEach(key => {
254
- eventHandlers[key] = [];
255
- });
256
-
257
- // Remove from DOM if attached
258
- if (element.parentNode) {
259
- element.parentNode.removeChild(element);
260
- }
261
- }
262
- };
263
-
264
- return switchComp;
265
- };
266
-
267
- describe('Switch Component', () => {
268
- test('should create a switch element', () => {
269
- const switchComp = createMockSwitch();
270
- expect(switchComp.element).toBeDefined();
271
- expect(switchComp.element.tagName).toBe('DIV');
272
- expect(switchComp.element.className).toContain('mtrl-switch');
273
- });
274
-
275
- test('should create input element with type checkbox', () => {
276
- const switchComp = createMockSwitch();
277
-
278
- // Check for input through direct property
279
- expect(switchComp.input).toBeDefined();
280
- expect(switchComp.input.type).toBe('checkbox');
281
- });
282
-
283
- test('should apply custom class', () => {
284
- const customClass = 'custom-switch';
285
- const switchComp = createMockSwitch({
286
- class: customClass
287
- });
288
-
289
- expect(switchComp.element.className).toContain(customClass);
290
- });
291
-
292
- test('should add label content through config', () => {
293
- const labelText = 'Toggle me';
294
- const switchComp = createMockSwitch({
295
- label: labelText
296
- });
297
-
298
- // Check config has label
299
- expect(switchComp.config.label).toBe(labelText);
300
- });
301
-
302
- test('should position label correctly', () => {
303
- // Test if the configuration is stored correctly
304
- const startPos = SWITCH_LABEL_POSITION.START;
305
- const startSwitch = createMockSwitch({
306
- label: 'Label at Start',
307
- labelPosition: startPos
308
- });
309
-
310
- // Check label position in config
311
- expect(startSwitch.config.labelPosition).toBe(startPos);
312
-
313
- // Check class is applied
314
- expect(startSwitch.element.className).toContain('mtrl-switch--label-start');
315
-
316
- // Default position (end)
317
- const endSwitch = createMockSwitch({
318
- label: 'Label at End'
319
- });
320
-
321
- expect(endSwitch.element.className).toContain('mtrl-switch--label-end');
322
- });
323
-
324
- test('should handle change events', () => {
325
- const switchComp = createMockSwitch();
326
- const handleChange = mock(() => {});
327
-
328
- // Check if the event handler is registered
329
- switchComp.on('change', handleChange);
330
-
331
- // Simulate change by calling the emit method if it exists
332
- if (switchComp.emit) {
333
- switchComp.emit('change', {});
334
- expect(handleChange).toHaveBeenCalled();
335
- }
336
- });
337
-
338
- test('should support disabled state', () => {
339
- const switchComp = createMockSwitch();
340
-
341
- // Check API methods
342
- expect(typeof switchComp.disable).toBe('function');
343
- expect(typeof switchComp.enable).toBe('function');
344
-
345
- // Test the API methods without making assumptions about implementation
346
- switchComp.disable();
347
- switchComp.enable();
348
-
349
- // Test initially disabled through config
350
- const disabledSwitch = createMockSwitch({ disabled: true });
351
- expect(disabledSwitch.config.disabled).toBe(true);
352
- });
353
-
354
- test('should support checked state', () => {
355
- // Check API methods
356
- const switchComp = createMockSwitch();
357
- expect(typeof switchComp.check).toBe('function');
358
- expect(typeof switchComp.uncheck).toBe('function');
359
- expect(typeof switchComp.toggle).toBe('function');
360
-
361
- // Initial unchecked state
362
- const uncheckedSwitch = createMockSwitch();
363
- expect(uncheckedSwitch.config.checked).toBeFalsy();
364
-
365
- // Initial checked state
366
- const checkedSwitch = createMockSwitch({ checked: true });
367
- expect(checkedSwitch.config.checked).toBe(true);
368
-
369
- // Verify methods execute without errors
370
- switchComp.check();
371
- switchComp.uncheck();
372
- switchComp.toggle();
373
- });
374
-
375
- test('should set name attribute correctly', () => {
376
- const name = 'theme-toggle';
377
- const switchComp = createMockSwitch({ name });
378
-
379
- // Check config
380
- expect(switchComp.config.name).toBe(name);
381
- });
382
-
383
- test('should set value attribute correctly', () => {
384
- const value = 'dark-mode';
385
- const switchComp = createMockSwitch({ value });
386
-
387
- // Check config
388
- expect(switchComp.config.value).toBe(value);
389
- });
390
-
391
- test('should set required attribute correctly', () => {
392
- const switchComp = createMockSwitch({ required: true });
393
-
394
- // Check config
395
- expect(switchComp.config.required).toBe(true);
396
- });
397
-
398
- test('should allow updating label', () => {
399
- const initialLabel = 'Initial Label';
400
- const switchComp = createMockSwitch({
401
- label: initialLabel
402
- });
403
-
404
- // Check initial label in config
405
- expect(switchComp.config.label).toBe(initialLabel);
406
-
407
- // Check setLabel method exists
408
- expect(typeof switchComp.setLabel).toBe('function');
409
-
410
- // Update label
411
- const newLabel = 'Updated Label';
412
- switchComp.setLabel(newLabel);
413
-
414
- // Check if label was updated
415
- expect(switchComp.getLabel()).toBe(newLabel);
416
- });
417
-
418
- test('should include track and thumb elements', () => {
419
- const switchComp = createMockSwitch();
420
-
421
- // Check for track - it might be directly accessible or through the DOM
422
- const hasTrack = switchComp.element.querySelector('.mtrl-switch-track') !== null;
423
-
424
- expect(hasTrack).toBe(true);
425
- });
426
-
427
- test('should have value getter and setter', () => {
428
- const switchComp = createMockSwitch();
429
-
430
- // Check API methods
431
- expect(typeof switchComp.getValue).toBe('function');
432
- expect(typeof switchComp.setValue).toBe('function');
433
-
434
- // Set a value
435
- const testValue = 'test-value';
436
- switchComp.setValue(testValue);
437
-
438
- // Check value
439
- expect(switchComp.getValue()).toBe(testValue);
440
- });
441
-
442
- test('should properly clean up resources', () => {
443
- const switchComp = createMockSwitch();
444
- const parentElement = document.createElement('div');
445
- parentElement.appendChild(switchComp.element);
446
-
447
- // Destroy should remove the element and clean up resources
448
- switchComp.destroy();
449
-
450
- expect(parentElement.children.length).toBe(0);
451
- });
452
- });