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,365 +0,0 @@
|
|
|
1
|
-
// test/components/list.test.ts
|
|
2
|
-
import { describe, test, expect, beforeAll, afterAll } from 'bun:test';
|
|
3
|
-
import { JSDOM } from 'jsdom';
|
|
4
|
-
import { LIST_TYPES } from '../../src/components/list/constants';
|
|
5
|
-
import type { ListConfig, ListComponent, ListItemConfig } from '../../src/components/list/types';
|
|
6
|
-
|
|
7
|
-
// IMPORTANT: Due to potential circular dependencies in the actual list component
|
|
8
|
-
// we are using a mock implementation for tests.
|
|
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.Event = window.Event;
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
afterAll(() => {
|
|
41
|
-
// Restore original globals
|
|
42
|
-
global.document = originalGlobalDocument;
|
|
43
|
-
global.window = originalGlobalWindow;
|
|
44
|
-
|
|
45
|
-
// Clean up jsdom
|
|
46
|
-
window.close();
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
// Mock list component factory
|
|
50
|
-
const createList = (config: ListConfig = {}): ListComponent => {
|
|
51
|
-
// Set defaults
|
|
52
|
-
const listConfig: ListConfig = {
|
|
53
|
-
type: LIST_TYPES.DEFAULT,
|
|
54
|
-
prefix: 'mtrl',
|
|
55
|
-
items: [],
|
|
56
|
-
...config
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// Create main element
|
|
60
|
-
const element = document.createElement('div');
|
|
61
|
-
element.className = `${listConfig.prefix}-list`;
|
|
62
|
-
|
|
63
|
-
if (listConfig.class) {
|
|
64
|
-
element.className += ` ${listConfig.class}`;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
element.setAttribute('role', 'list');
|
|
68
|
-
element.setAttribute('data-type', listConfig.type as string);
|
|
69
|
-
|
|
70
|
-
// Create maps for items and selection
|
|
71
|
-
const items = new Map();
|
|
72
|
-
const selectedItems = new Set<string>();
|
|
73
|
-
|
|
74
|
-
// Event handlers
|
|
75
|
-
const eventHandlers: Record<string, Function[]> = {};
|
|
76
|
-
|
|
77
|
-
// Create list items
|
|
78
|
-
const createListItem = (item: ListItemConfig): HTMLElement => {
|
|
79
|
-
const itemElement = document.createElement('div');
|
|
80
|
-
itemElement.className = `${listConfig.prefix}-list-item`;
|
|
81
|
-
itemElement.setAttribute('role', 'listitem');
|
|
82
|
-
itemElement.setAttribute('data-id', item.id);
|
|
83
|
-
|
|
84
|
-
// Create content
|
|
85
|
-
if (item.headline) {
|
|
86
|
-
const headline = document.createElement('div');
|
|
87
|
-
headline.className = `${listConfig.prefix}-list-item-headline`;
|
|
88
|
-
headline.textContent = item.headline;
|
|
89
|
-
itemElement.appendChild(headline);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (item.supportingText) {
|
|
93
|
-
const supporting = document.createElement('div');
|
|
94
|
-
supporting.className = `${listConfig.prefix}-list-item-supporting`;
|
|
95
|
-
supporting.textContent = item.supportingText;
|
|
96
|
-
itemElement.appendChild(supporting);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Handle selection
|
|
100
|
-
if (item.selected) {
|
|
101
|
-
itemElement.setAttribute('aria-selected', 'true');
|
|
102
|
-
selectedItems.add(item.id);
|
|
103
|
-
} else {
|
|
104
|
-
itemElement.setAttribute('aria-selected', 'false');
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Add to items map
|
|
108
|
-
items.set(item.id, {
|
|
109
|
-
element: itemElement,
|
|
110
|
-
disabled: item.disabled || false,
|
|
111
|
-
config: item
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
// Add click handler for selection
|
|
115
|
-
itemElement.addEventListener('click', () => {
|
|
116
|
-
if (listConfig.type === LIST_TYPES.SINGLE_SELECT) {
|
|
117
|
-
// For single select, deselect all others
|
|
118
|
-
items.forEach((item, id) => {
|
|
119
|
-
if (id !== itemElement.dataset.id) {
|
|
120
|
-
item.element.setAttribute('aria-selected', 'false');
|
|
121
|
-
selectedItems.delete(id);
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
// Toggle selection of clicked item
|
|
126
|
-
if (itemElement.getAttribute('aria-selected') === 'true') {
|
|
127
|
-
itemElement.setAttribute('aria-selected', 'false');
|
|
128
|
-
selectedItems.delete(itemElement.dataset.id as string);
|
|
129
|
-
} else {
|
|
130
|
-
itemElement.setAttribute('aria-selected', 'true');
|
|
131
|
-
selectedItems.add(itemElement.dataset.id as string);
|
|
132
|
-
}
|
|
133
|
-
} else if (listConfig.type === LIST_TYPES.MULTI_SELECT) {
|
|
134
|
-
// For multi select, toggle selection
|
|
135
|
-
if (itemElement.getAttribute('aria-selected') === 'true') {
|
|
136
|
-
itemElement.setAttribute('aria-selected', 'false');
|
|
137
|
-
selectedItems.delete(itemElement.dataset.id as string);
|
|
138
|
-
} else {
|
|
139
|
-
itemElement.setAttribute('aria-selected', 'true');
|
|
140
|
-
selectedItems.add(itemElement.dataset.id as string);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Emit selection change event
|
|
145
|
-
emit('selectionchange', {
|
|
146
|
-
selected: Array.from(selectedItems),
|
|
147
|
-
item: items.get(itemElement.dataset.id as string),
|
|
148
|
-
type: listConfig.type
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
return itemElement;
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
// Create initial items
|
|
156
|
-
if (listConfig.items && listConfig.items.length > 0) {
|
|
157
|
-
listConfig.items.forEach(item => {
|
|
158
|
-
const itemElement = createListItem(item);
|
|
159
|
-
element.appendChild(itemElement);
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Event emitter function
|
|
164
|
-
const emit = (event: string, data: any): void => {
|
|
165
|
-
if (eventHandlers[event]) {
|
|
166
|
-
eventHandlers[event].forEach(handler => handler(data));
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
// Public API
|
|
171
|
-
return {
|
|
172
|
-
element,
|
|
173
|
-
items,
|
|
174
|
-
selectedItems,
|
|
175
|
-
|
|
176
|
-
getSelected(): string[] {
|
|
177
|
-
return Array.from(selectedItems);
|
|
178
|
-
},
|
|
179
|
-
|
|
180
|
-
setSelected(ids: string[]): void {
|
|
181
|
-
// First, deselect all
|
|
182
|
-
items.forEach((item, id) => {
|
|
183
|
-
item.element.setAttribute('aria-selected', 'false');
|
|
184
|
-
selectedItems.delete(id);
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
// Then select the specified items
|
|
188
|
-
ids.forEach(id => {
|
|
189
|
-
const item = items.get(id);
|
|
190
|
-
if (item) {
|
|
191
|
-
item.element.setAttribute('aria-selected', 'true');
|
|
192
|
-
selectedItems.add(id);
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
// Emit selection change event
|
|
197
|
-
emit('selectionchange', {
|
|
198
|
-
selected: Array.from(selectedItems),
|
|
199
|
-
type: listConfig.type
|
|
200
|
-
});
|
|
201
|
-
},
|
|
202
|
-
|
|
203
|
-
addItem(itemConfig: ListItemConfig): void {
|
|
204
|
-
const itemElement = createListItem(itemConfig);
|
|
205
|
-
element.appendChild(itemElement);
|
|
206
|
-
},
|
|
207
|
-
|
|
208
|
-
removeItem(id: string): void {
|
|
209
|
-
const item = items.get(id);
|
|
210
|
-
if (item) {
|
|
211
|
-
element.removeChild(item.element);
|
|
212
|
-
items.delete(id);
|
|
213
|
-
selectedItems.delete(id);
|
|
214
|
-
}
|
|
215
|
-
},
|
|
216
|
-
|
|
217
|
-
on(event: string, handler: Function): ListComponent {
|
|
218
|
-
if (!eventHandlers[event]) {
|
|
219
|
-
eventHandlers[event] = [];
|
|
220
|
-
}
|
|
221
|
-
eventHandlers[event].push(handler);
|
|
222
|
-
return this;
|
|
223
|
-
},
|
|
224
|
-
|
|
225
|
-
off(event: string, handler: Function): ListComponent {
|
|
226
|
-
if (eventHandlers[event]) {
|
|
227
|
-
eventHandlers[event] = eventHandlers[event].filter(h => h !== handler);
|
|
228
|
-
}
|
|
229
|
-
return this;
|
|
230
|
-
},
|
|
231
|
-
|
|
232
|
-
enable(): ListComponent {
|
|
233
|
-
element.removeAttribute('disabled');
|
|
234
|
-
return this;
|
|
235
|
-
},
|
|
236
|
-
|
|
237
|
-
disable(): ListComponent {
|
|
238
|
-
element.setAttribute('disabled', '');
|
|
239
|
-
return this;
|
|
240
|
-
},
|
|
241
|
-
|
|
242
|
-
emit,
|
|
243
|
-
prefix: listConfig.prefix,
|
|
244
|
-
|
|
245
|
-
destroy(): void {
|
|
246
|
-
// Clean up event handlers
|
|
247
|
-
items.forEach(item => {
|
|
248
|
-
item.element.removeEventListener('click', () => {});
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
// Clear maps
|
|
252
|
-
items.clear();
|
|
253
|
-
selectedItems.clear();
|
|
254
|
-
|
|
255
|
-
// Remove from DOM
|
|
256
|
-
if (element.parentNode) {
|
|
257
|
-
element.parentNode.removeChild(element);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
describe('List Component', () => {
|
|
264
|
-
test('should create a default list element', () => {
|
|
265
|
-
const list = createList({
|
|
266
|
-
items: [{ id: 'item1', headline: 'Item 1' }]
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
expect(list.element).toBeDefined();
|
|
270
|
-
// Default type is "default" and role "list"
|
|
271
|
-
expect(list.element.getAttribute('data-type')).toBe(LIST_TYPES.DEFAULT);
|
|
272
|
-
expect(list.element.getAttribute('role')).toBe('list');
|
|
273
|
-
|
|
274
|
-
// Check at least one list item exists
|
|
275
|
-
const listItem = list.element.querySelector(`.${list.prefix}-list-item`);
|
|
276
|
-
expect(listItem).not.toBeNull();
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
test('should support single select behavior', () => {
|
|
280
|
-
const list = createList({
|
|
281
|
-
type: LIST_TYPES.SINGLE_SELECT,
|
|
282
|
-
items: [
|
|
283
|
-
{ id: 'item1', headline: 'Item 1' },
|
|
284
|
-
{ id: 'item2', headline: 'Item 2' }
|
|
285
|
-
]
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
// Simulate clicking on the first item
|
|
289
|
-
const items = list.element.querySelectorAll(`.${list.prefix}-list-item`);
|
|
290
|
-
const firstItem = items[0];
|
|
291
|
-
firstItem.dispatchEvent(new Event('click'));
|
|
292
|
-
expect(firstItem.getAttribute('aria-selected')).toBe('true');
|
|
293
|
-
|
|
294
|
-
// Now click the second item; the first should be deselected
|
|
295
|
-
const secondItem = items[1];
|
|
296
|
-
secondItem.dispatchEvent(new Event('click'));
|
|
297
|
-
expect(firstItem.getAttribute('aria-selected')).toBe('false');
|
|
298
|
-
expect(secondItem.getAttribute('aria-selected')).toBe('true');
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
test('should support multi select behavior', () => {
|
|
302
|
-
const list = createList({
|
|
303
|
-
type: LIST_TYPES.MULTI_SELECT,
|
|
304
|
-
items: [
|
|
305
|
-
{ id: 'item1', headline: 'Item 1' },
|
|
306
|
-
{ id: 'item2', headline: 'Item 2' }
|
|
307
|
-
]
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
const items = list.element.querySelectorAll(`.${list.prefix}-list-item`);
|
|
311
|
-
const firstItem = items[0];
|
|
312
|
-
const secondItem = items[1];
|
|
313
|
-
|
|
314
|
-
// Click to select first item
|
|
315
|
-
firstItem.dispatchEvent(new Event('click'));
|
|
316
|
-
expect(firstItem.getAttribute('aria-selected')).toBe('true');
|
|
317
|
-
|
|
318
|
-
// Click to select second item
|
|
319
|
-
secondItem.dispatchEvent(new Event('click'));
|
|
320
|
-
expect(secondItem.getAttribute('aria-selected')).toBe('true');
|
|
321
|
-
expect(list.getSelected().length).toBe(2);
|
|
322
|
-
|
|
323
|
-
// Click first item again to deselect it
|
|
324
|
-
firstItem.dispatchEvent(new Event('click'));
|
|
325
|
-
expect(firstItem.getAttribute('aria-selected')).toBe('false');
|
|
326
|
-
expect(list.getSelected().length).toBe(1);
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
test('should set selected items via setSelected', () => {
|
|
330
|
-
const list = createList({
|
|
331
|
-
type: LIST_TYPES.MULTI_SELECT,
|
|
332
|
-
items: [
|
|
333
|
-
{ id: 'item1', headline: 'Item 1' },
|
|
334
|
-
{ id: 'item2', headline: 'Item 2' },
|
|
335
|
-
{ id: 'item3', headline: 'Item 3' }
|
|
336
|
-
]
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
list.setSelected(['item2', 'item3']);
|
|
340
|
-
const items = Array.from(
|
|
341
|
-
list.element.querySelectorAll(`.${list.prefix}-list-item`)
|
|
342
|
-
);
|
|
343
|
-
const item2 = items.find(i => i.getAttribute('data-id') === 'item2');
|
|
344
|
-
const item3 = items.find(i => i.getAttribute('data-id') === 'item3');
|
|
345
|
-
|
|
346
|
-
expect(item2?.getAttribute('aria-selected')).toBe('true');
|
|
347
|
-
expect(item3?.getAttribute('aria-selected')).toBe('true');
|
|
348
|
-
expect(list.getSelected()).toEqual(expect.arrayContaining(['item2', 'item3']));
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
test('should add and remove items dynamically', () => {
|
|
352
|
-
const list = createList({
|
|
353
|
-
items: [{ id: 'item1', headline: 'Item 1' }]
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
const initialCount = list.element.querySelectorAll(`.${list.prefix}-list-item`).length;
|
|
357
|
-
list.addItem({ id: 'item2', headline: 'Item 2' });
|
|
358
|
-
const newCount = list.element.querySelectorAll(`.${list.prefix}-list-item`).length;
|
|
359
|
-
expect(newCount).toBe(initialCount + 1);
|
|
360
|
-
|
|
361
|
-
list.removeItem('item1');
|
|
362
|
-
const finalCount = list.element.querySelectorAll(`.${list.prefix}-list-item`).length;
|
|
363
|
-
expect(finalCount).toBe(newCount - 1);
|
|
364
|
-
});
|
|
365
|
-
});
|