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,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
- });