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,462 +0,0 @@
1
- // test/components/checkbox.test.ts
2
- import { describe, test, expect, mock, beforeAll, afterAll } from 'bun:test';
3
- import { JSDOM } from 'jsdom';
4
- import { CHECKBOX_VARIANTS, CHECKBOX_LABEL_POSITION } from '../../src/components/checkbox/constants';
5
-
6
- // IMPORTANT: Due to potential circular dependencies in the actual checkbox component
7
- // we are using a mock implementation for tests. For a full implementation
8
- // with the actual component, see test/ts/components/checkbox.test.ts
9
-
10
- // Setup jsdom environment
11
- let dom: JSDOM;
12
- let window: Window;
13
- let document: Document;
14
- let originalGlobalDocument: any;
15
- let originalGlobalWindow: any;
16
-
17
- beforeAll(() => {
18
- // Create a new JSDOM instance
19
- dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
20
- url: 'http://localhost/',
21
- pretendToBeVisual: true
22
- });
23
-
24
- // Get window and document from jsdom
25
- window = dom.window;
26
- document = window.document;
27
-
28
- // Store original globals
29
- originalGlobalDocument = global.document;
30
- originalGlobalWindow = global.window;
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.HTMLInputElement = window.HTMLInputElement;
38
- global.Event = window.Event;
39
- });
40
-
41
- afterAll(() => {
42
- // Restore original globals
43
- global.document = originalGlobalDocument;
44
- global.window = originalGlobalWindow;
45
-
46
- // Clean up jsdom
47
- window.close();
48
- });
49
-
50
- // Mock checkbox component factory
51
- const createCheckbox = (config: any = {}) => {
52
- // Create main element
53
- const element = document.createElement('div');
54
- element.className = `mtrl-checkbox ${config.variant ? `mtrl-checkbox--${config.variant}` : ''}`;
55
-
56
- if (config.class) {
57
- element.className += ` ${config.class}`;
58
- }
59
-
60
- // Create input element
61
- const input = document.createElement('input');
62
- input.type = 'checkbox';
63
- input.className = 'mtrl-checkbox-input';
64
-
65
- if (config.name) {
66
- input.name = config.name;
67
- }
68
-
69
- if (config.value) {
70
- input.value = config.value;
71
- }
72
-
73
- if (config.checked) {
74
- input.checked = true;
75
- element.classList.add(`mtrl-checkbox--checked`);
76
- }
77
-
78
- if (config.required) {
79
- input.required = true;
80
- }
81
-
82
- if (config.disabled) {
83
- input.disabled = true;
84
- element.classList.add(`mtrl-checkbox--disabled`);
85
- }
86
-
87
- element.appendChild(input);
88
-
89
- // Create icon element
90
- const icon = document.createElement('span');
91
- icon.className = 'mtrl-checkbox-icon';
92
- element.appendChild(icon);
93
-
94
- // Create label if provided
95
- let labelElement: HTMLLabelElement | null = null;
96
- if (config.label) {
97
- labelElement = document.createElement('label');
98
- labelElement.className = 'mtrl-checkbox-label';
99
- labelElement.textContent = config.label;
100
-
101
- // Set label position
102
- if (config.labelPosition === CHECKBOX_LABEL_POSITION.START) {
103
- element.classList.add('mtrl-checkbox--label-start');
104
- element.insertBefore(labelElement, element.firstChild);
105
- } else {
106
- element.classList.add('mtrl-checkbox--label-end');
107
- element.appendChild(labelElement);
108
- }
109
- }
110
-
111
- // Store event handlers
112
- const eventHandlers: Record<string, Function[]> = {};
113
-
114
- // Default configuration
115
- const defaultConfig = {
116
- variant: CHECKBOX_VARIANTS.FILLED,
117
- labelPosition: CHECKBOX_LABEL_POSITION.END,
118
- ...config
119
- };
120
-
121
- return {
122
- element,
123
- input,
124
- config: defaultConfig,
125
-
126
- getValue() {
127
- return input.value;
128
- },
129
-
130
- setValue(value: string) {
131
- input.value = value;
132
- return this;
133
- },
134
-
135
- check() {
136
- input.checked = true;
137
- element.classList.add('mtrl-checkbox--checked');
138
- return this;
139
- },
140
-
141
- uncheck() {
142
- input.checked = false;
143
- element.classList.remove('mtrl-checkbox--checked');
144
- return this;
145
- },
146
-
147
- toggle() {
148
- if (input.checked) {
149
- this.uncheck();
150
- } else {
151
- this.check();
152
- }
153
- return this;
154
- },
155
-
156
- isChecked() {
157
- return input.checked;
158
- },
159
-
160
- setIndeterminate(state: boolean) {
161
- input.indeterminate = state;
162
- if (state) {
163
- element.classList.add('mtrl-checkbox--indeterminate');
164
- } else {
165
- element.classList.remove('mtrl-checkbox--indeterminate');
166
- }
167
- return this;
168
- },
169
-
170
- setLabel(text: string) {
171
- this.config.label = text;
172
- if (labelElement) {
173
- labelElement.textContent = text;
174
- } else if (text) {
175
- labelElement = document.createElement('label');
176
- labelElement.className = 'mtrl-checkbox-label';
177
- labelElement.textContent = text;
178
- element.appendChild(labelElement);
179
- }
180
- return this;
181
- },
182
-
183
- getLabel() {
184
- return this.config.label || '';
185
- },
186
-
187
- enable() {
188
- input.disabled = false;
189
- element.classList.remove('mtrl-checkbox--disabled');
190
- return this;
191
- },
192
-
193
- disable() {
194
- input.disabled = true;
195
- element.classList.add('mtrl-checkbox--disabled');
196
- return this;
197
- },
198
-
199
- on(event: string, handler: Function) {
200
- if (!eventHandlers[event]) {
201
- eventHandlers[event] = [];
202
- }
203
- eventHandlers[event].push(handler);
204
-
205
- if (event === 'change') {
206
- input.addEventListener('change', handler as EventListener);
207
- } else {
208
- element.addEventListener(event, handler as EventListener);
209
- }
210
-
211
- return this;
212
- },
213
-
214
- off(event: string, handler: Function) {
215
- if (eventHandlers[event]) {
216
- eventHandlers[event] = eventHandlers[event].filter(h => h !== handler);
217
- }
218
-
219
- if (event === 'change') {
220
- input.removeEventListener('change', handler as EventListener);
221
- } else {
222
- element.removeEventListener(event, handler as EventListener);
223
- }
224
-
225
- return this;
226
- },
227
-
228
- // For testing purposes - simulates emit method
229
- emit(event: string, data: any) {
230
- if (eventHandlers[event]) {
231
- eventHandlers[event].forEach(handler => handler(data));
232
- }
233
- },
234
-
235
- destroy() {
236
- // Clean up event handlers
237
- Object.entries(eventHandlers).forEach(([event, handlers]) => {
238
- handlers.forEach(handler => {
239
- if (event === 'change') {
240
- input.removeEventListener(event, handler as EventListener);
241
- } else {
242
- element.removeEventListener(event, handler as EventListener);
243
- }
244
- });
245
- });
246
-
247
- // Remove from DOM
248
- if (element.parentNode) {
249
- element.parentNode.removeChild(element);
250
- }
251
- }
252
- };
253
- };
254
-
255
- describe('Checkbox Component', () => {
256
- test('should create a checkbox element', () => {
257
- const checkbox = createCheckbox();
258
- expect(checkbox.element).toBeDefined();
259
- expect(checkbox.element.tagName).toBe('DIV');
260
- expect(checkbox.element.className).toContain('mtrl-checkbox');
261
- });
262
-
263
- test('should create input element with type checkbox', () => {
264
- const checkbox = createCheckbox();
265
- const input = checkbox.input;
266
- expect(input).toBeDefined();
267
- expect(input.type).toBe('checkbox');
268
- });
269
-
270
- test('should add label content', () => {
271
- const labelText = 'Accept terms';
272
- const checkbox = createCheckbox({
273
- label: labelText
274
- });
275
-
276
- expect(checkbox.config.label).toBe(labelText);
277
- });
278
-
279
- test('should apply variant class', () => {
280
- const variant = CHECKBOX_VARIANTS.FILLED;
281
- const checkbox = createCheckbox({
282
- variant
283
- });
284
-
285
- expect(checkbox.config.variant).toBe(variant);
286
- });
287
-
288
- test('should use filled as default variant', () => {
289
- const checkbox = createCheckbox();
290
- expect(checkbox.config.variant).toBe(CHECKBOX_VARIANTS.FILLED);
291
- });
292
-
293
- test('should handle change events', () => {
294
- const checkbox = createCheckbox();
295
- const handleChange = mock(() => {});
296
-
297
- checkbox.on('change', handleChange);
298
-
299
- checkbox.emit('change', {});
300
- expect(handleChange).toHaveBeenCalled();
301
- });
302
-
303
- test('should support disabled state', () => {
304
- const checkbox = createCheckbox();
305
-
306
- expect(typeof checkbox.disable).toBe('function');
307
- expect(typeof checkbox.enable).toBe('function');
308
-
309
- const initiallyEnabled = checkbox.element.hasAttribute('disabled') === false;
310
- expect(initiallyEnabled).toBe(true);
311
-
312
- checkbox.disable();
313
-
314
- expect(checkbox.input.disabled).toBe(true);
315
- });
316
-
317
- test('should support checked state', () => {
318
- const checkbox = createCheckbox();
319
-
320
- expect(typeof checkbox.check).toBe('function');
321
- expect(typeof checkbox.uncheck).toBe('function');
322
- expect(typeof checkbox.toggle).toBe('function');
323
-
324
- checkbox.check();
325
- expect(checkbox.input.checked).toBe(true);
326
-
327
- checkbox.uncheck();
328
- expect(checkbox.input.checked).toBe(false);
329
-
330
- checkbox.toggle();
331
- expect(checkbox.input.checked).toBe(true);
332
-
333
- const checkedCheckbox = createCheckbox({ checked: true });
334
- expect(checkedCheckbox.config.checked).toBe(true);
335
- expect(checkedCheckbox.input.checked).toBe(true);
336
- });
337
-
338
- test('should support indeterminate state', () => {
339
- const checkbox = createCheckbox();
340
-
341
- expect(typeof checkbox.setIndeterminate).toBe('function');
342
-
343
- checkbox.setIndeterminate(true);
344
- expect(checkbox.input.indeterminate).toBe(true);
345
-
346
- checkbox.setIndeterminate(false);
347
- expect(checkbox.input.indeterminate).toBe(false);
348
- });
349
-
350
- test('should set name attribute correctly', () => {
351
- const name = 'terms';
352
- const checkbox = createCheckbox({ name });
353
-
354
- expect(checkbox.config.name).toBe(name);
355
- expect(checkbox.input.name).toBe(name);
356
- });
357
-
358
- test('should set value attribute correctly', () => {
359
- const value = 'accept';
360
- const checkbox = createCheckbox({ value });
361
-
362
- expect(checkbox.config.value).toBe(value);
363
- expect(checkbox.input.value).toBe(value);
364
- });
365
-
366
- test('should set required attribute correctly', () => {
367
- const checkbox = createCheckbox({ required: true });
368
-
369
- expect(checkbox.config.required).toBe(true);
370
- expect(checkbox.input.required).toBe(true);
371
- });
372
-
373
- test('should position label correctly', () => {
374
- const startPos = CHECKBOX_LABEL_POSITION.START;
375
- const startCheckbox = createCheckbox({
376
- label: 'Start Label',
377
- labelPosition: startPos
378
- });
379
-
380
- expect(startCheckbox.config.labelPosition).toBe(startPos);
381
- expect(startCheckbox.element.classList.contains('mtrl-checkbox--label-start')).toBe(true);
382
-
383
- const endPos = CHECKBOX_LABEL_POSITION.END;
384
- const endCheckbox = createCheckbox({
385
- label: 'End Label',
386
- labelPosition: endPos
387
- });
388
-
389
- expect(endCheckbox.config.labelPosition).toBe(endPos);
390
- expect(endCheckbox.element.classList.contains('mtrl-checkbox--label-end')).toBe(true);
391
- });
392
-
393
- test('should allow updating label', () => {
394
- const initialLabel = 'Initial';
395
- const checkbox = createCheckbox({
396
- label: initialLabel
397
- });
398
-
399
- const initialLabelInConfig = checkbox.config.label;
400
- expect(initialLabelInConfig).toBe(initialLabel);
401
-
402
- const newLabel = 'Updated Label';
403
- checkbox.setLabel(newLabel);
404
-
405
- const labelElement = checkbox.element.querySelector('.mtrl-checkbox-label');
406
- expect(labelElement?.textContent).toBe(newLabel);
407
- });
408
-
409
- test('should get label text correctly', () => {
410
- const labelText = 'Test Label';
411
- const checkbox = createCheckbox({
412
- label: labelText
413
- });
414
-
415
- expect(checkbox.config.label).toBe(labelText);
416
- expect(checkbox.getLabel()).toBe(labelText);
417
- });
418
-
419
- test('should get value correctly', () => {
420
- const value = 'test-value';
421
- const checkbox = createCheckbox({
422
- value
423
- });
424
-
425
- expect(checkbox.config.value).toBe(value);
426
- expect(checkbox.getValue()).toBe(value);
427
- });
428
-
429
- test('should set value correctly', () => {
430
- const checkbox = createCheckbox();
431
- const newValue = 'new-value';
432
-
433
- checkbox.setValue(newValue);
434
- expect(checkbox.input.value).toBe(newValue);
435
- });
436
-
437
- test('should include check icon', () => {
438
- const checkbox = createCheckbox();
439
- const iconElement = checkbox.element.querySelector('.mtrl-checkbox-icon');
440
-
441
- expect(iconElement).toBeDefined();
442
- });
443
-
444
- test('should properly clean up resources', () => {
445
- const checkbox = createCheckbox();
446
- const parentElement = document.createElement('div');
447
- parentElement.appendChild(checkbox.element);
448
-
449
- checkbox.destroy();
450
-
451
- expect(parentElement.children.length).toBe(0);
452
- });
453
-
454
- test('should apply custom class', () => {
455
- const customClass = 'custom-checkbox';
456
- const checkbox = createCheckbox({
457
- class: customClass
458
- });
459
-
460
- expect(checkbox.element.className).toContain(customClass);
461
- });
462
- });