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,400 +0,0 @@
|
|
|
1
|
-
// test/components/textfield.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.HTMLInputElement = dom.window.HTMLInputElement;
|
|
12
|
-
global.HTMLTextAreaElement = dom.window.HTMLTextAreaElement;
|
|
13
|
-
global.Event = dom.window.Event;
|
|
14
|
-
global.CustomEvent = dom.window.CustomEvent;
|
|
15
|
-
|
|
16
|
-
// Import types directly to avoid circular dependencies
|
|
17
|
-
import type {
|
|
18
|
-
TextfieldComponent,
|
|
19
|
-
TextfieldConfig,
|
|
20
|
-
TextfieldVariant,
|
|
21
|
-
TextfieldTypes,
|
|
22
|
-
TextfieldSize
|
|
23
|
-
} from '../../src/components/textfield/types';
|
|
24
|
-
|
|
25
|
-
// Define constants here to avoid circular dependencies
|
|
26
|
-
const TEXTFIELD_VARIANTS = {
|
|
27
|
-
FILLED: 'filled',
|
|
28
|
-
OUTLINED: 'outlined'
|
|
29
|
-
} as const;
|
|
30
|
-
|
|
31
|
-
const TEXTFIELD_SIZES = {
|
|
32
|
-
SMALL: 'small',
|
|
33
|
-
MEDIUM: 'medium',
|
|
34
|
-
LARGE: 'large'
|
|
35
|
-
} as const;
|
|
36
|
-
|
|
37
|
-
const TEXTFIELD_TYPES = {
|
|
38
|
-
TEXT: 'text',
|
|
39
|
-
PASSWORD: 'password',
|
|
40
|
-
EMAIL: 'email',
|
|
41
|
-
NUMBER: 'number',
|
|
42
|
-
TEL: 'tel',
|
|
43
|
-
URL: 'url',
|
|
44
|
-
SEARCH: 'search',
|
|
45
|
-
MULTILINE: 'multiline'
|
|
46
|
-
} as const;
|
|
47
|
-
|
|
48
|
-
// Create a mock textfield implementation
|
|
49
|
-
const createTextfield = (config: TextfieldConfig = {}): TextfieldComponent => {
|
|
50
|
-
// Create base element
|
|
51
|
-
const element = document.createElement('div');
|
|
52
|
-
element.className = `mtrl-textfield ${config.class || ''}`;
|
|
53
|
-
|
|
54
|
-
// Add variant class if provided
|
|
55
|
-
if (config.variant) {
|
|
56
|
-
element.classList.add(`mtrl-textfield--${config.variant}`);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Add size class if provided
|
|
60
|
-
if (config.size) {
|
|
61
|
-
element.classList.add(`mtrl-textfield--${config.size}`);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Create input element
|
|
65
|
-
const input = document.createElement(config.type === TEXTFIELD_TYPES.MULTILINE ? 'textarea' : 'input') as HTMLInputElement | HTMLTextAreaElement;
|
|
66
|
-
input.className = 'mtrl-textfield-input';
|
|
67
|
-
|
|
68
|
-
if (input instanceof HTMLInputElement) {
|
|
69
|
-
input.type = config.type || TEXTFIELD_TYPES.TEXT;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
input.value = config.value || '';
|
|
73
|
-
input.placeholder = config.placeholder || '';
|
|
74
|
-
|
|
75
|
-
if (config.name) input.name = config.name;
|
|
76
|
-
if (config.maxLength) input.maxLength = config.maxLength;
|
|
77
|
-
if (config.required) input.required = true;
|
|
78
|
-
if (config.disabled) input.disabled = true;
|
|
79
|
-
|
|
80
|
-
element.appendChild(input);
|
|
81
|
-
|
|
82
|
-
// Create label if provided
|
|
83
|
-
let label: HTMLLabelElement | null = null;
|
|
84
|
-
if (config.label) {
|
|
85
|
-
label = document.createElement('label');
|
|
86
|
-
label.className = 'mtrl-textfield-label';
|
|
87
|
-
label.textContent = config.label;
|
|
88
|
-
element.appendChild(label);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Event handlers
|
|
92
|
-
const eventHandlers: Record<string, EventListener[]> = {};
|
|
93
|
-
|
|
94
|
-
// Create the textfield component instance
|
|
95
|
-
const textfield: TextfieldComponent = {
|
|
96
|
-
element,
|
|
97
|
-
input,
|
|
98
|
-
config,
|
|
99
|
-
|
|
100
|
-
getValue: () => input.value,
|
|
101
|
-
|
|
102
|
-
setValue: (value: string) => {
|
|
103
|
-
input.value = value || '';
|
|
104
|
-
return textfield;
|
|
105
|
-
},
|
|
106
|
-
|
|
107
|
-
setLabel: (text: string) => {
|
|
108
|
-
if (label) {
|
|
109
|
-
label.textContent = text;
|
|
110
|
-
}
|
|
111
|
-
return textfield;
|
|
112
|
-
},
|
|
113
|
-
|
|
114
|
-
getLabel: () => label?.textContent || '',
|
|
115
|
-
|
|
116
|
-
setAttribute: (name: string, value: string) => {
|
|
117
|
-
input.setAttribute(name, value);
|
|
118
|
-
return textfield;
|
|
119
|
-
},
|
|
120
|
-
|
|
121
|
-
getAttribute: (name: string) => input.getAttribute(name),
|
|
122
|
-
|
|
123
|
-
removeAttribute: (name: string) => {
|
|
124
|
-
input.removeAttribute(name);
|
|
125
|
-
return textfield;
|
|
126
|
-
},
|
|
127
|
-
|
|
128
|
-
on: (event: string, handler: Function) => {
|
|
129
|
-
const listener = handler as EventListener;
|
|
130
|
-
if (!eventHandlers[event]) {
|
|
131
|
-
eventHandlers[event] = [];
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
eventHandlers[event].push(listener);
|
|
135
|
-
input.addEventListener(event, listener);
|
|
136
|
-
return textfield;
|
|
137
|
-
},
|
|
138
|
-
|
|
139
|
-
off: (event: string, handler: Function) => {
|
|
140
|
-
const listener = handler as EventListener;
|
|
141
|
-
input.removeEventListener(event, listener);
|
|
142
|
-
|
|
143
|
-
if (eventHandlers[event]) {
|
|
144
|
-
eventHandlers[event] = eventHandlers[event].filter(h => h !== listener);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return textfield;
|
|
148
|
-
},
|
|
149
|
-
|
|
150
|
-
enable: () => {
|
|
151
|
-
input.disabled = false;
|
|
152
|
-
element.classList.remove('mtrl-textfield--disabled');
|
|
153
|
-
return textfield;
|
|
154
|
-
},
|
|
155
|
-
|
|
156
|
-
disable: () => {
|
|
157
|
-
input.disabled = true;
|
|
158
|
-
element.classList.add('mtrl-textfield--disabled');
|
|
159
|
-
return textfield;
|
|
160
|
-
},
|
|
161
|
-
|
|
162
|
-
destroy: () => {
|
|
163
|
-
// Clean up event listeners
|
|
164
|
-
Object.entries(eventHandlers).forEach(([event, handlers]) => {
|
|
165
|
-
handlers.forEach(handler => {
|
|
166
|
-
input.removeEventListener(event, handler);
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
// Clear handlers
|
|
171
|
-
Object.keys(eventHandlers).forEach(key => {
|
|
172
|
-
eventHandlers[key] = [];
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
// Remove from DOM if attached
|
|
176
|
-
if (element.parentNode) {
|
|
177
|
-
element.parentNode.removeChild(element);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
return textfield;
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
describe('Textfield Component', () => {
|
|
186
|
-
test('should create a textfield element', () => {
|
|
187
|
-
const textfield = createTextfield();
|
|
188
|
-
expect(textfield.element).toBeDefined();
|
|
189
|
-
expect(textfield.element.tagName).toBe('DIV');
|
|
190
|
-
expect(textfield.element.className).toContain('mtrl-textfield');
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
test('should apply variant class', () => {
|
|
194
|
-
// Test filled variant
|
|
195
|
-
const filledTextField = createTextfield({
|
|
196
|
-
variant: TEXTFIELD_VARIANTS.FILLED
|
|
197
|
-
});
|
|
198
|
-
expect(filledTextField.element.className).toContain('mtrl-textfield--filled');
|
|
199
|
-
|
|
200
|
-
// Test outlined variant
|
|
201
|
-
const outlinedTextField = createTextfield({
|
|
202
|
-
variant: TEXTFIELD_VARIANTS.OUTLINED
|
|
203
|
-
});
|
|
204
|
-
expect(outlinedTextField.element.className).toContain('mtrl-textfield--outlined');
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
test('should apply size class', () => {
|
|
208
|
-
// Test small size
|
|
209
|
-
const smallTextField = createTextfield({
|
|
210
|
-
size: TEXTFIELD_SIZES.SMALL
|
|
211
|
-
});
|
|
212
|
-
expect(smallTextField.element.className).toContain('mtrl-textfield--small');
|
|
213
|
-
|
|
214
|
-
// Test large size
|
|
215
|
-
const largeTextField = createTextfield({
|
|
216
|
-
size: TEXTFIELD_SIZES.LARGE
|
|
217
|
-
});
|
|
218
|
-
expect(largeTextField.element.className).toContain('mtrl-textfield--large');
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
test('should set initial value', () => {
|
|
222
|
-
const initialValue = 'Hello World';
|
|
223
|
-
const textfield = createTextfield({
|
|
224
|
-
value: initialValue
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
expect(textfield.getValue()).toBe(initialValue);
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
test('should update value', () => {
|
|
231
|
-
const textfield = createTextfield();
|
|
232
|
-
const newValue = 'Updated Value';
|
|
233
|
-
|
|
234
|
-
textfield.setValue(newValue);
|
|
235
|
-
expect(textfield.getValue()).toBe(newValue);
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
test('should set and get label', () => {
|
|
239
|
-
const initialLabel = 'Username';
|
|
240
|
-
const textfield = createTextfield({
|
|
241
|
-
label: initialLabel
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
expect(textfield.getLabel()).toBe(initialLabel);
|
|
245
|
-
|
|
246
|
-
// Update label
|
|
247
|
-
const newLabel = 'New Label';
|
|
248
|
-
textfield.setLabel(newLabel);
|
|
249
|
-
expect(textfield.getLabel()).toBe(newLabel);
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
test('should handle attributes', () => {
|
|
253
|
-
const textfield = createTextfield();
|
|
254
|
-
|
|
255
|
-
// Set attribute
|
|
256
|
-
textfield.setAttribute('data-test', 'test-value');
|
|
257
|
-
expect(textfield.getAttribute('data-test')).toBe('test-value');
|
|
258
|
-
|
|
259
|
-
// Remove attribute
|
|
260
|
-
textfield.removeAttribute('data-test');
|
|
261
|
-
expect(textfield.getAttribute('data-test')).toBeNull();
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
test('should support disabled state', () => {
|
|
265
|
-
// Create initially enabled
|
|
266
|
-
const textfield = createTextfield();
|
|
267
|
-
|
|
268
|
-
// Check API methods
|
|
269
|
-
expect(typeof textfield.disable).toBe('function');
|
|
270
|
-
expect(typeof textfield.enable).toBe('function');
|
|
271
|
-
|
|
272
|
-
// Disable and check state
|
|
273
|
-
textfield.disable();
|
|
274
|
-
expect(textfield.input.disabled).toBe(true);
|
|
275
|
-
|
|
276
|
-
// Enable and check state
|
|
277
|
-
textfield.enable();
|
|
278
|
-
expect(textfield.input.disabled).toBe(false);
|
|
279
|
-
|
|
280
|
-
// Test initially disabled through config
|
|
281
|
-
const disabledTextfield = createTextfield({ disabled: true });
|
|
282
|
-
expect(disabledTextfield.input.disabled).toBe(true);
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
test('should support different input types', () => {
|
|
286
|
-
// Test regular text input
|
|
287
|
-
const textInput = createTextfield({
|
|
288
|
-
type: TEXTFIELD_TYPES.TEXT
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
if (textInput.input instanceof HTMLInputElement) {
|
|
292
|
-
expect(textInput.input.type).toBe('text');
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// Test password input
|
|
296
|
-
const passwordInput = createTextfield({
|
|
297
|
-
type: TEXTFIELD_TYPES.PASSWORD
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
if (passwordInput.input instanceof HTMLInputElement) {
|
|
301
|
-
expect(passwordInput.input.type).toBe('password');
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// Test email input
|
|
305
|
-
const emailInput = createTextfield({
|
|
306
|
-
type: TEXTFIELD_TYPES.EMAIL
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
if (emailInput.input instanceof HTMLInputElement) {
|
|
310
|
-
expect(emailInput.input.type).toBe('email');
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// Test multiline input (textarea)
|
|
314
|
-
const multilineInput = createTextfield({
|
|
315
|
-
type: TEXTFIELD_TYPES.MULTILINE
|
|
316
|
-
});
|
|
317
|
-
expect(multilineInput.input.tagName).toBe('TEXTAREA');
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
test('should register event handlers', () => {
|
|
321
|
-
const textfield = createTextfield();
|
|
322
|
-
|
|
323
|
-
// Create a mock handler
|
|
324
|
-
const mockHandler = mock(() => {});
|
|
325
|
-
|
|
326
|
-
// Register handler
|
|
327
|
-
textfield.on('input', mockHandler);
|
|
328
|
-
|
|
329
|
-
// Trigger an input event
|
|
330
|
-
const inputEvent = new Event('input');
|
|
331
|
-
textfield.input.dispatchEvent(inputEvent);
|
|
332
|
-
|
|
333
|
-
// Check that handler was called
|
|
334
|
-
expect(mockHandler.mock.calls.length).toBeGreaterThan(0);
|
|
335
|
-
|
|
336
|
-
// Unregister handler and trigger again
|
|
337
|
-
textfield.off('input', mockHandler);
|
|
338
|
-
textfield.input.dispatchEvent(inputEvent);
|
|
339
|
-
|
|
340
|
-
// Handler call count should not increase
|
|
341
|
-
expect(mockHandler.mock.calls.length).toBe(1);
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
test('should apply custom class', () => {
|
|
345
|
-
const customClass = 'custom-textfield';
|
|
346
|
-
const textfield = createTextfield({
|
|
347
|
-
class: customClass
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
expect(textfield.element.className).toContain(customClass);
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
test('should set placeholder', () => {
|
|
354
|
-
const placeholder = 'Enter text here';
|
|
355
|
-
const textfield = createTextfield({
|
|
356
|
-
placeholder
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
expect(textfield.input.placeholder).toBe(placeholder);
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
test('should set required attribute', () => {
|
|
363
|
-
const textfield = createTextfield({
|
|
364
|
-
required: true
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
expect(textfield.input.required).toBe(true);
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
test('should set name attribute', () => {
|
|
371
|
-
const name = 'username';
|
|
372
|
-
const textfield = createTextfield({
|
|
373
|
-
name
|
|
374
|
-
});
|
|
375
|
-
|
|
376
|
-
expect(textfield.input.name).toBe(name);
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
test('should set maxLength attribute', () => {
|
|
380
|
-
const maxLength = 50;
|
|
381
|
-
const textfield = createTextfield({
|
|
382
|
-
maxLength
|
|
383
|
-
});
|
|
384
|
-
|
|
385
|
-
expect(textfield.input.maxLength).toBe(maxLength);
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
test('should properly clean up resources on destroy', () => {
|
|
389
|
-
const textfield = createTextfield();
|
|
390
|
-
|
|
391
|
-
const parentElement = document.createElement('div');
|
|
392
|
-
parentElement.appendChild(textfield.element);
|
|
393
|
-
|
|
394
|
-
// Destroy the component
|
|
395
|
-
textfield.destroy();
|
|
396
|
-
|
|
397
|
-
// Check if element was removed
|
|
398
|
-
expect(parentElement.children.length).toBe(0);
|
|
399
|
-
});
|
|
400
|
-
});
|