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.
- package/.env +15 -0
- package/CONTRIBUTING.md +8 -8
- package/DOCS.md +3 -3
- package/README.md +43 -20
- package/TESTING.md +128 -18
- package/dist/index.js +14865 -0
- package/git-user-stats.js +545 -0
- package/index.ts +9 -67
- package/package.json +8 -3
- package/src/components/badge/api.ts +15 -1
- package/src/components/badge/badge.ts +43 -4
- package/src/components/badge/config.ts +40 -8
- package/src/components/badge/index.ts +64 -3
- package/src/components/badge/types.ts +175 -33
- package/src/components/button/api.ts +63 -1
- package/src/components/button/button.ts +39 -3
- package/src/components/button/config.ts +21 -4
- package/src/components/button/index.ts +26 -1
- package/src/components/button/types.ts +7 -1
- package/src/components/card/api.ts +78 -9
- package/src/components/card/card.ts +58 -3
- package/src/components/card/config.ts +41 -11
- package/src/components/card/features.ts +39 -12
- package/src/components/card/index.ts +84 -19
- package/src/components/card/types.ts +218 -29
- package/src/components/carousel/carousel.ts +92 -28
- package/src/components/carousel/constants.ts +107 -21
- package/src/components/carousel/index.ts +31 -13
- package/src/components/checkbox/checkbox.ts +83 -16
- package/src/components/checkbox/index.ts +43 -1
- package/src/components/checkbox/types.ts +219 -32
- package/src/components/chips/api.ts +194 -0
- package/src/components/{chip → chips/chip}/api.ts +42 -2
- package/src/components/chips/chip/chip.ts +131 -0
- package/src/components/{chip → chips/chip}/config.ts +3 -3
- package/src/components/chips/chip/index.ts +3 -0
- package/src/components/chips/chips.md +481 -0
- package/src/components/chips/chips.ts +75 -0
- package/src/components/chips/config.ts +109 -0
- package/src/components/chips/constants.ts +61 -0
- package/src/components/chips/features/chip-items.ts +33 -0
- package/src/components/chips/features/container.ts +77 -0
- package/src/components/chips/features/controller.ts +448 -0
- package/src/components/chips/features/index.ts +5 -0
- package/src/components/chips/features/label.ts +108 -0
- package/src/components/chips/index.ts +11 -0
- package/src/components/chips/schema.ts +61 -0
- package/src/components/{chip → chips}/types.ts +203 -92
- package/src/components/dialog/dialog.ts +99 -16
- package/src/components/dialog/index.ts +97 -1
- package/src/components/dialog/types.ts +375 -69
- package/src/components/divider/config.ts +90 -6
- package/src/components/divider/divider.ts +32 -2
- package/src/components/divider/features.ts +26 -0
- package/src/components/divider/index.ts +30 -0
- package/src/components/divider/types.ts +86 -9
- package/src/components/extended-fab/api.ts +53 -1
- package/src/components/extended-fab/config.ts +29 -1
- package/src/components/extended-fab/extended-fab.ts +28 -0
- package/src/components/extended-fab/index.ts +36 -0
- package/src/components/extended-fab/types.ts +458 -13
- package/src/components/fab/api.ts +42 -2
- package/src/components/fab/config.ts +29 -1
- package/src/components/fab/fab.ts +16 -2
- package/src/components/fab/index.ts +35 -0
- package/src/components/fab/types.ts +374 -10
- package/src/components/list/api.ts +12 -2
- package/src/components/list/config.ts +21 -0
- package/src/components/list/features.ts +6 -0
- package/src/components/list/index.ts +56 -1
- package/src/components/list/list-item.ts +46 -2
- package/src/components/list/list.ts +73 -2
- package/src/components/list/types.ts +172 -0
- package/src/components/list/utils.ts +26 -2
- package/src/components/menu/api.ts +217 -20
- package/src/components/menu/config.ts +27 -0
- package/src/components/menu/features/visibility.ts +55 -6
- package/src/components/menu/index.ts +64 -0
- package/src/components/menu/menu-item.ts +46 -3
- package/src/components/menu/menu.ts +77 -1
- package/src/components/menu/types.ts +404 -39
- package/src/components/sheet/config.ts +1 -2
- package/src/components/sheet/features/gestures.ts +1 -1
- package/src/components/sheet/features/position.ts +1 -2
- package/src/components/sheet/features/state.ts +1 -1
- package/src/components/sheet/index.ts +10 -2
- package/src/components/sheet/sheet.ts +1 -2
- package/src/components/sheet/types.ts +29 -1
- package/src/components/slider/api.ts +1 -1
- package/src/components/slider/config.ts +1 -1
- package/src/components/slider/features/controller.ts +1 -1
- package/src/components/slider/features/handlers.ts +1 -1
- package/src/components/slider/features/states.ts +1 -1
- package/src/components/slider/index.ts +12 -5
- package/src/components/slider/schema.ts +1 -1
- package/src/components/slider/types.ts +31 -0
- package/src/components/tabs/tab-api.ts +1 -1
- package/src/components/tabs/types.ts +1 -1
- package/src/components/tooltip/api.ts +6 -2
- package/src/components/tooltip/config.ts +9 -28
- package/src/components/tooltip/index.ts +10 -1
- package/src/components/tooltip/types.ts +38 -3
- package/src/index.ts +129 -31
- package/src/styles/abstract/_mixins.scss +23 -9
- package/src/styles/abstract/_variables.scss +14 -4
- package/src/styles/components/_card.scss +1 -1
- package/src/styles/components/_chip.scss +323 -113
- package/src/styles/components/_tabs.scss +1 -1
- package/CLAUDE.md +0 -33
- package/src/components/checkbox/constants.ts +0 -37
- package/src/components/chip/chip-set.ts +0 -225
- package/src/components/chip/chip.ts +0 -118
- package/src/components/chip/constants.ts +0 -28
- package/src/components/chip/index.ts +0 -12
- package/src/components/list/constants.ts +0 -116
- package/src/components/sheet/constants.ts +0 -20
- package/src/components/slider/constants.ts +0 -32
- package/src/components/tooltip/constants.ts +0 -27
- package/test/components/badge.test.ts +0 -545
- package/test/components/bottom-app-bar.test.ts +0 -303
- package/test/components/button.test.ts +0 -233
- package/test/components/card.test.ts +0 -560
- package/test/components/carousel.test.ts +0 -951
- package/test/components/checkbox.test.ts +0 -462
- package/test/components/chip.test.ts +0 -692
- package/test/components/datepicker.test.ts +0 -1124
- package/test/components/dialog.test.ts +0 -990
- package/test/components/divider.test.ts +0 -412
- package/test/components/extended-fab.test.ts +0 -672
- package/test/components/fab.test.ts +0 -561
- package/test/components/list.test.ts +0 -365
- package/test/components/menu.test.ts +0 -718
- package/test/components/navigation.test.ts +0 -186
- package/test/components/progress.test.ts +0 -567
- package/test/components/radios.test.ts +0 -699
- package/test/components/search.test.ts +0 -1135
- package/test/components/segmented-button.test.ts +0 -732
- package/test/components/sheet.test.ts +0 -641
- package/test/components/slider.test.ts +0 -1220
- package/test/components/snackbar.test.ts +0 -461
- package/test/components/switch.test.ts +0 -452
- package/test/components/tabs.test.ts +0 -1369
- package/test/components/textfield.test.ts +0 -400
- package/test/components/timepicker.test.ts +0 -592
- package/test/components/tooltip.test.ts +0 -630
- package/test/components/top-app-bar.test.ts +0 -566
- package/test/core/dom.attributes.test.ts +0 -148
- package/test/core/dom.classes.test.ts +0 -152
- package/test/core/dom.events.test.ts +0 -243
- package/test/core/emitter.test.ts +0 -141
- package/test/core/ripple.test.ts +0 -99
- package/test/core/state.store.test.ts +0 -189
- package/test/core/utils.normalize.test.ts +0 -61
- package/test/core/utils.object.test.ts +0 -120
- package/test/setup.js +0 -371
- package/test/setup.ts +0 -451
- package/tsconfig.json +0 -22
- package/typedoc.json +0 -28
- package/typedoc.simple.json +0 -14
|
@@ -1,561 +0,0 @@
|
|
|
1
|
-
// test/components/fab.test.ts
|
|
2
|
-
import { describe, test, expect, mock, beforeAll, afterAll } from 'bun:test';
|
|
3
|
-
import { JSDOM } from 'jsdom';
|
|
4
|
-
import {
|
|
5
|
-
type FabComponent,
|
|
6
|
-
type FabConfig,
|
|
7
|
-
type FabVariant,
|
|
8
|
-
type FabSize,
|
|
9
|
-
type FabPosition
|
|
10
|
-
} from '../../src/components/fab/types';
|
|
11
|
-
|
|
12
|
-
// Setup jsdom environment
|
|
13
|
-
let dom: JSDOM;
|
|
14
|
-
let window: Window;
|
|
15
|
-
let document: Document;
|
|
16
|
-
let originalGlobalDocument: any;
|
|
17
|
-
let originalGlobalWindow: any;
|
|
18
|
-
|
|
19
|
-
beforeAll(() => {
|
|
20
|
-
// Create a new JSDOM instance
|
|
21
|
-
dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
|
|
22
|
-
url: 'http://localhost/',
|
|
23
|
-
pretendToBeVisual: true
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
// Get window and document from jsdom
|
|
27
|
-
window = dom.window;
|
|
28
|
-
document = window.document;
|
|
29
|
-
|
|
30
|
-
// Store original globals
|
|
31
|
-
originalGlobalDocument = global.document;
|
|
32
|
-
originalGlobalWindow = global.window;
|
|
33
|
-
|
|
34
|
-
// Set globals to use jsdom
|
|
35
|
-
global.document = document;
|
|
36
|
-
global.window = window;
|
|
37
|
-
global.Element = window.Element;
|
|
38
|
-
global.HTMLElement = window.HTMLElement;
|
|
39
|
-
global.HTMLButtonElement = window.HTMLButtonElement;
|
|
40
|
-
global.Event = window.Event;
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
afterAll(() => {
|
|
44
|
-
// Restore original globals
|
|
45
|
-
global.document = originalGlobalDocument;
|
|
46
|
-
global.window = originalGlobalWindow;
|
|
47
|
-
|
|
48
|
-
// Clean up jsdom
|
|
49
|
-
window.close();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// Constants for fab variants
|
|
53
|
-
const FAB_VARIANTS = {
|
|
54
|
-
PRIMARY: 'primary',
|
|
55
|
-
SECONDARY: 'secondary',
|
|
56
|
-
TERTIARY: 'tertiary',
|
|
57
|
-
SURFACE: 'surface'
|
|
58
|
-
} as const;
|
|
59
|
-
|
|
60
|
-
// Constants for fab sizes
|
|
61
|
-
const FAB_SIZES = {
|
|
62
|
-
SMALL: 'small',
|
|
63
|
-
DEFAULT: 'default',
|
|
64
|
-
LARGE: 'large'
|
|
65
|
-
} as const;
|
|
66
|
-
|
|
67
|
-
// Constants for fab positions
|
|
68
|
-
const FAB_POSITIONS = {
|
|
69
|
-
TOP_RIGHT: 'top-right',
|
|
70
|
-
TOP_LEFT: 'top-left',
|
|
71
|
-
BOTTOM_RIGHT: 'bottom-right',
|
|
72
|
-
BOTTOM_LEFT: 'bottom-left'
|
|
73
|
-
} as const;
|
|
74
|
-
|
|
75
|
-
// Mock fab implementation
|
|
76
|
-
const createMockFab = (config: FabConfig = {}): FabComponent => {
|
|
77
|
-
// Create the main element
|
|
78
|
-
const element = document.createElement('button');
|
|
79
|
-
element.className = 'mtrl-fab';
|
|
80
|
-
element.type = config.type || 'button';
|
|
81
|
-
|
|
82
|
-
// Set default configuration
|
|
83
|
-
const settings = {
|
|
84
|
-
componentName: 'fab',
|
|
85
|
-
prefix: config.prefix || 'mtrl',
|
|
86
|
-
variant: config.variant || FAB_VARIANTS.PRIMARY,
|
|
87
|
-
size: config.size || FAB_SIZES.DEFAULT,
|
|
88
|
-
disabled: config.disabled || false,
|
|
89
|
-
ripple: config.ripple !== undefined ? config.ripple : true,
|
|
90
|
-
animate: config.animate || false
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
// Apply variant class
|
|
94
|
-
if (settings.variant) {
|
|
95
|
-
element.classList.add(`mtrl-fab--${settings.variant}`);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Apply size class
|
|
99
|
-
if (settings.size && settings.size !== FAB_SIZES.DEFAULT) {
|
|
100
|
-
element.classList.add(`mtrl-fab--${settings.size}`);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Apply disabled state
|
|
104
|
-
if (settings.disabled) {
|
|
105
|
-
element.disabled = true;
|
|
106
|
-
element.classList.add('mtrl-fab--disabled');
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Apply position if provided
|
|
110
|
-
if (config.position) {
|
|
111
|
-
element.classList.add(`mtrl-fab--${config.position}`);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Apply animation if configured
|
|
115
|
-
if (settings.animate) {
|
|
116
|
-
element.classList.add('mtrl-fab--animate');
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Apply additional classes
|
|
120
|
-
if (config.class) {
|
|
121
|
-
const classes = config.class.split(' ');
|
|
122
|
-
classes.forEach(className => element.classList.add(className));
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Apply value if provided
|
|
126
|
-
if (config.value) {
|
|
127
|
-
element.setAttribute('value', config.value);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Apply aria-label if provided
|
|
131
|
-
if (config.ariaLabel) {
|
|
132
|
-
element.setAttribute('aria-label', config.ariaLabel);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Create ripple element if enabled
|
|
136
|
-
if (settings.ripple) {
|
|
137
|
-
const ripple = document.createElement('span');
|
|
138
|
-
ripple.className = 'mtrl-fab__ripple';
|
|
139
|
-
element.appendChild(ripple);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Create icon element if provided
|
|
143
|
-
let iconElement: HTMLElement | null = null;
|
|
144
|
-
if (config.icon) {
|
|
145
|
-
iconElement = document.createElement('span');
|
|
146
|
-
iconElement.className = 'mtrl-fab__icon';
|
|
147
|
-
iconElement.innerHTML = config.icon;
|
|
148
|
-
|
|
149
|
-
if (config.iconSize) {
|
|
150
|
-
iconElement.style.width = config.iconSize;
|
|
151
|
-
iconElement.style.height = config.iconSize;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
element.appendChild(iconElement);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Initialize icon API
|
|
158
|
-
const iconAPI = {
|
|
159
|
-
setIcon: (html: string) => {
|
|
160
|
-
if (!iconElement) {
|
|
161
|
-
iconElement = document.createElement('span');
|
|
162
|
-
iconElement.className = 'mtrl-fab__icon';
|
|
163
|
-
element.appendChild(iconElement);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
iconElement.innerHTML = html;
|
|
167
|
-
return iconAPI;
|
|
168
|
-
},
|
|
169
|
-
|
|
170
|
-
getIcon: () => iconElement ? iconElement.innerHTML : '',
|
|
171
|
-
|
|
172
|
-
getElement: () => iconElement
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
// Set up event handlers
|
|
176
|
-
const eventHandlers: Record<string, Function[]> = {};
|
|
177
|
-
|
|
178
|
-
// Create the fab component
|
|
179
|
-
const fab: FabComponent = {
|
|
180
|
-
element,
|
|
181
|
-
icon: iconAPI,
|
|
182
|
-
|
|
183
|
-
disabled: {
|
|
184
|
-
enable: () => {
|
|
185
|
-
element.disabled = false;
|
|
186
|
-
element.classList.remove('mtrl-fab--disabled');
|
|
187
|
-
},
|
|
188
|
-
|
|
189
|
-
disable: () => {
|
|
190
|
-
element.disabled = true;
|
|
191
|
-
element.classList.add('mtrl-fab--disabled');
|
|
192
|
-
},
|
|
193
|
-
|
|
194
|
-
isDisabled: () => element.disabled
|
|
195
|
-
},
|
|
196
|
-
|
|
197
|
-
lifecycle: {
|
|
198
|
-
destroy: () => {
|
|
199
|
-
fab.destroy();
|
|
200
|
-
}
|
|
201
|
-
},
|
|
202
|
-
|
|
203
|
-
getClass: (name: string) => {
|
|
204
|
-
const prefix = settings.prefix;
|
|
205
|
-
return name ? `${prefix}-${name}` : `${prefix}-fab`;
|
|
206
|
-
},
|
|
207
|
-
|
|
208
|
-
getValue: () => element.getAttribute('value') || '',
|
|
209
|
-
|
|
210
|
-
setValue: (value: string) => {
|
|
211
|
-
element.setAttribute('value', value);
|
|
212
|
-
return fab;
|
|
213
|
-
},
|
|
214
|
-
|
|
215
|
-
enable: () => {
|
|
216
|
-
fab.disabled.enable();
|
|
217
|
-
return fab;
|
|
218
|
-
},
|
|
219
|
-
|
|
220
|
-
disable: () => {
|
|
221
|
-
fab.disabled.disable();
|
|
222
|
-
return fab;
|
|
223
|
-
},
|
|
224
|
-
|
|
225
|
-
setIcon: (icon: string) => {
|
|
226
|
-
iconAPI.setIcon(icon);
|
|
227
|
-
return fab;
|
|
228
|
-
},
|
|
229
|
-
|
|
230
|
-
getIcon: () => iconAPI.getIcon(),
|
|
231
|
-
|
|
232
|
-
setPosition: (position: string) => {
|
|
233
|
-
// Remove existing position classes
|
|
234
|
-
const positionValues = Object.values(FAB_POSITIONS);
|
|
235
|
-
positionValues.forEach(pos => {
|
|
236
|
-
element.classList.remove(`mtrl-fab--${pos}`);
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
// Add new position class
|
|
240
|
-
element.classList.add(`mtrl-fab--${position}`);
|
|
241
|
-
return fab;
|
|
242
|
-
},
|
|
243
|
-
|
|
244
|
-
getPosition: () => {
|
|
245
|
-
const positionValues = Object.values(FAB_POSITIONS);
|
|
246
|
-
for (const pos of positionValues) {
|
|
247
|
-
if (element.classList.contains(`mtrl-fab--${pos}`)) {
|
|
248
|
-
return pos;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
return null;
|
|
252
|
-
},
|
|
253
|
-
|
|
254
|
-
lower: () => {
|
|
255
|
-
element.classList.add('mtrl-fab--lowered');
|
|
256
|
-
return fab;
|
|
257
|
-
},
|
|
258
|
-
|
|
259
|
-
raise: () => {
|
|
260
|
-
element.classList.remove('mtrl-fab--lowered');
|
|
261
|
-
return fab;
|
|
262
|
-
},
|
|
263
|
-
|
|
264
|
-
destroy: () => {
|
|
265
|
-
// Remove element from DOM if it has a parent
|
|
266
|
-
if (element.parentNode) {
|
|
267
|
-
element.parentNode.removeChild(element);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// Clear event handlers
|
|
271
|
-
for (const event in eventHandlers) {
|
|
272
|
-
eventHandlers[event] = [];
|
|
273
|
-
}
|
|
274
|
-
},
|
|
275
|
-
|
|
276
|
-
on: (event: string, handler: Function) => {
|
|
277
|
-
if (!eventHandlers[event]) {
|
|
278
|
-
eventHandlers[event] = [];
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
eventHandlers[event].push(handler);
|
|
282
|
-
|
|
283
|
-
element.addEventListener(event, handler as EventListener);
|
|
284
|
-
return fab;
|
|
285
|
-
},
|
|
286
|
-
|
|
287
|
-
off: (event: string, handler: Function) => {
|
|
288
|
-
if (eventHandlers[event]) {
|
|
289
|
-
eventHandlers[event] = eventHandlers[event].filter(h => h !== handler);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
element.removeEventListener(event, handler as EventListener);
|
|
293
|
-
return fab;
|
|
294
|
-
},
|
|
295
|
-
|
|
296
|
-
addClass: (...classes: string[]) => {
|
|
297
|
-
classes.forEach(className => element.classList.add(className));
|
|
298
|
-
return fab;
|
|
299
|
-
}
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
return fab;
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
describe('FAB Component', () => {
|
|
306
|
-
test('should create a fab button element', () => {
|
|
307
|
-
const fab = createMockFab();
|
|
308
|
-
|
|
309
|
-
expect(fab.element).toBeDefined();
|
|
310
|
-
expect(fab.element.tagName).toBe('BUTTON');
|
|
311
|
-
expect(fab.element.className).toContain('mtrl-fab');
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
test('should apply variant classes', () => {
|
|
315
|
-
const variants: FabVariant[] = [
|
|
316
|
-
FAB_VARIANTS.PRIMARY,
|
|
317
|
-
FAB_VARIANTS.SECONDARY,
|
|
318
|
-
FAB_VARIANTS.TERTIARY,
|
|
319
|
-
FAB_VARIANTS.SURFACE
|
|
320
|
-
];
|
|
321
|
-
|
|
322
|
-
variants.forEach(variant => {
|
|
323
|
-
const fab = createMockFab({ variant });
|
|
324
|
-
expect(fab.element.className).toContain(`mtrl-fab--${variant}`);
|
|
325
|
-
});
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
test('should apply size classes', () => {
|
|
329
|
-
const sizes: FabSize[] = [
|
|
330
|
-
FAB_SIZES.SMALL,
|
|
331
|
-
FAB_SIZES.LARGE
|
|
332
|
-
];
|
|
333
|
-
|
|
334
|
-
sizes.forEach(size => {
|
|
335
|
-
const fab = createMockFab({ size });
|
|
336
|
-
expect(fab.element.className).toContain(`mtrl-fab--${size}`);
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
// Default size should not add a class
|
|
340
|
-
const defaultFab = createMockFab({ size: FAB_SIZES.DEFAULT });
|
|
341
|
-
expect(defaultFab.element.className).not.toContain(`mtrl-fab--${FAB_SIZES.DEFAULT}`);
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
test('should set initial icon', () => {
|
|
345
|
-
const iconHtml = '<svg><path></path></svg>';
|
|
346
|
-
const fab = createMockFab({
|
|
347
|
-
icon: iconHtml
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
const iconElement = fab.element.querySelector('.mtrl-fab__icon');
|
|
351
|
-
expect(iconElement).toBeDefined();
|
|
352
|
-
expect(iconElement?.innerHTML).toBe(iconHtml);
|
|
353
|
-
expect(fab.getIcon()).toBe(iconHtml);
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
test('should apply disabled state', () => {
|
|
357
|
-
const fab = createMockFab({
|
|
358
|
-
disabled: true
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
expect(fab.element.disabled).toBe(true);
|
|
362
|
-
expect(fab.element.className).toContain('mtrl-fab--disabled');
|
|
363
|
-
expect(fab.disabled.isDisabled()).toBe(true);
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
test('should apply position classes', () => {
|
|
367
|
-
const positions: FabPosition[] = [
|
|
368
|
-
FAB_POSITIONS.TOP_RIGHT,
|
|
369
|
-
FAB_POSITIONS.TOP_LEFT,
|
|
370
|
-
FAB_POSITIONS.BOTTOM_RIGHT,
|
|
371
|
-
FAB_POSITIONS.BOTTOM_LEFT
|
|
372
|
-
];
|
|
373
|
-
|
|
374
|
-
positions.forEach(position => {
|
|
375
|
-
const fab = createMockFab({ position });
|
|
376
|
-
expect(fab.element.className).toContain(`mtrl-fab--${position}`);
|
|
377
|
-
expect(fab.getPosition()).toBe(position);
|
|
378
|
-
});
|
|
379
|
-
});
|
|
380
|
-
|
|
381
|
-
test('should set value attribute', () => {
|
|
382
|
-
const fab = createMockFab({
|
|
383
|
-
value: 'new-item'
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
expect(fab.element.getAttribute('value')).toBe('new-item');
|
|
387
|
-
expect(fab.getValue()).toBe('new-item');
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
test('should set aria-label attribute', () => {
|
|
391
|
-
const fab = createMockFab({
|
|
392
|
-
ariaLabel: 'Create new item'
|
|
393
|
-
});
|
|
394
|
-
|
|
395
|
-
expect(fab.element.getAttribute('aria-label')).toBe('Create new item');
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
test('should create ripple element by default', () => {
|
|
399
|
-
const fab = createMockFab();
|
|
400
|
-
|
|
401
|
-
const rippleElement = fab.element.querySelector('.mtrl-fab__ripple');
|
|
402
|
-
expect(rippleElement).toBeDefined();
|
|
403
|
-
});
|
|
404
|
-
|
|
405
|
-
test('should not create ripple when disabled', () => {
|
|
406
|
-
const fab = createMockFab({
|
|
407
|
-
ripple: false
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
const rippleElement = fab.element.querySelector('.mtrl-fab__ripple');
|
|
411
|
-
expect(rippleElement).toBeNull();
|
|
412
|
-
});
|
|
413
|
-
|
|
414
|
-
test('should apply custom icon size', () => {
|
|
415
|
-
const fab = createMockFab({
|
|
416
|
-
icon: '<svg></svg>',
|
|
417
|
-
iconSize: '32px'
|
|
418
|
-
});
|
|
419
|
-
|
|
420
|
-
const iconElement = fab.element.querySelector('.mtrl-fab__icon');
|
|
421
|
-
expect(iconElement).toBeDefined();
|
|
422
|
-
expect((iconElement as HTMLElement).style.width).toBe('32px');
|
|
423
|
-
expect((iconElement as HTMLElement).style.height).toBe('32px');
|
|
424
|
-
});
|
|
425
|
-
|
|
426
|
-
test('should apply animation class when configured', () => {
|
|
427
|
-
const fab = createMockFab({
|
|
428
|
-
animate: true
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
expect(fab.element.className).toContain('mtrl-fab--animate');
|
|
432
|
-
});
|
|
433
|
-
|
|
434
|
-
test('should be able to change icon', () => {
|
|
435
|
-
const fab = createMockFab();
|
|
436
|
-
|
|
437
|
-
const initialIconElement = fab.element.querySelector('.mtrl-fab__icon');
|
|
438
|
-
expect(initialIconElement).toBeNull();
|
|
439
|
-
|
|
440
|
-
const iconHtml = '<svg><path></path></svg>';
|
|
441
|
-
fab.setIcon(iconHtml);
|
|
442
|
-
|
|
443
|
-
const updatedIconElement = fab.element.querySelector('.mtrl-fab__icon');
|
|
444
|
-
expect(updatedIconElement).toBeDefined();
|
|
445
|
-
expect(updatedIconElement?.innerHTML).toBe(iconHtml);
|
|
446
|
-
expect(fab.getIcon()).toBe(iconHtml);
|
|
447
|
-
});
|
|
448
|
-
|
|
449
|
-
test('should be able to change disabled state', () => {
|
|
450
|
-
const fab = createMockFab();
|
|
451
|
-
|
|
452
|
-
expect(fab.disabled.isDisabled()).toBe(false);
|
|
453
|
-
|
|
454
|
-
fab.disable();
|
|
455
|
-
|
|
456
|
-
expect(fab.disabled.isDisabled()).toBe(true);
|
|
457
|
-
expect(fab.element.disabled).toBe(true);
|
|
458
|
-
expect(fab.element.className).toContain('mtrl-fab--disabled');
|
|
459
|
-
|
|
460
|
-
fab.enable();
|
|
461
|
-
|
|
462
|
-
expect(fab.disabled.isDisabled()).toBe(false);
|
|
463
|
-
expect(fab.element.disabled).toBe(false);
|
|
464
|
-
expect(fab.element.className).not.toContain('mtrl-fab--disabled');
|
|
465
|
-
});
|
|
466
|
-
|
|
467
|
-
test('should be able to change value', () => {
|
|
468
|
-
const fab = createMockFab();
|
|
469
|
-
|
|
470
|
-
expect(fab.getValue()).toBe('');
|
|
471
|
-
|
|
472
|
-
fab.setValue('new-value');
|
|
473
|
-
|
|
474
|
-
expect(fab.getValue()).toBe('new-value');
|
|
475
|
-
expect(fab.element.getAttribute('value')).toBe('new-value');
|
|
476
|
-
});
|
|
477
|
-
|
|
478
|
-
test('should be able to change position', () => {
|
|
479
|
-
const fab = createMockFab({
|
|
480
|
-
position: FAB_POSITIONS.BOTTOM_RIGHT
|
|
481
|
-
});
|
|
482
|
-
|
|
483
|
-
expect(fab.getPosition()).toBe(FAB_POSITIONS.BOTTOM_RIGHT);
|
|
484
|
-
|
|
485
|
-
fab.setPosition(FAB_POSITIONS.TOP_LEFT);
|
|
486
|
-
|
|
487
|
-
expect(fab.getPosition()).toBe(FAB_POSITIONS.TOP_LEFT);
|
|
488
|
-
expect(fab.element.className).toContain(`mtrl-fab--${FAB_POSITIONS.TOP_LEFT}`);
|
|
489
|
-
expect(fab.element.className).not.toContain(`mtrl-fab--${FAB_POSITIONS.BOTTOM_RIGHT}`);
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
test('should be able to lower and raise', () => {
|
|
493
|
-
const fab = createMockFab();
|
|
494
|
-
|
|
495
|
-
expect(fab.element.className).not.toContain('mtrl-fab--lowered');
|
|
496
|
-
|
|
497
|
-
fab.lower();
|
|
498
|
-
|
|
499
|
-
expect(fab.element.className).toContain('mtrl-fab--lowered');
|
|
500
|
-
|
|
501
|
-
fab.raise();
|
|
502
|
-
|
|
503
|
-
expect(fab.element.className).not.toContain('mtrl-fab--lowered');
|
|
504
|
-
});
|
|
505
|
-
|
|
506
|
-
test('should add event listeners', () => {
|
|
507
|
-
const fab = createMockFab();
|
|
508
|
-
let clicked = false;
|
|
509
|
-
|
|
510
|
-
fab.on('click', () => {
|
|
511
|
-
clicked = true;
|
|
512
|
-
});
|
|
513
|
-
|
|
514
|
-
// Simulate click
|
|
515
|
-
fab.element.dispatchEvent(new Event('click'));
|
|
516
|
-
|
|
517
|
-
expect(clicked).toBe(true);
|
|
518
|
-
});
|
|
519
|
-
|
|
520
|
-
test('should remove event listeners', () => {
|
|
521
|
-
const fab = createMockFab();
|
|
522
|
-
let count = 0;
|
|
523
|
-
|
|
524
|
-
const handler = () => {
|
|
525
|
-
count++;
|
|
526
|
-
};
|
|
527
|
-
|
|
528
|
-
fab.on('click', handler);
|
|
529
|
-
|
|
530
|
-
// First click
|
|
531
|
-
fab.element.dispatchEvent(new Event('click'));
|
|
532
|
-
expect(count).toBe(1);
|
|
533
|
-
|
|
534
|
-
// Remove listener
|
|
535
|
-
fab.off('click', handler);
|
|
536
|
-
|
|
537
|
-
// Second click
|
|
538
|
-
fab.element.dispatchEvent(new Event('click'));
|
|
539
|
-
expect(count).toBe(1); // Count should not increase
|
|
540
|
-
});
|
|
541
|
-
|
|
542
|
-
test('should add CSS classes', () => {
|
|
543
|
-
const fab = createMockFab();
|
|
544
|
-
|
|
545
|
-
fab.addClass('custom-class', 'special-fab');
|
|
546
|
-
|
|
547
|
-
expect(fab.element.className).toContain('custom-class');
|
|
548
|
-
expect(fab.element.className).toContain('special-fab');
|
|
549
|
-
});
|
|
550
|
-
|
|
551
|
-
test('should be properly destroyed', () => {
|
|
552
|
-
const fab = createMockFab();
|
|
553
|
-
document.body.appendChild(fab.element);
|
|
554
|
-
|
|
555
|
-
expect(document.body.contains(fab.element)).toBe(true);
|
|
556
|
-
|
|
557
|
-
fab.destroy();
|
|
558
|
-
|
|
559
|
-
expect(document.body.contains(fab.element)).toBe(false);
|
|
560
|
-
});
|
|
561
|
-
});
|