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,641 +0,0 @@
|
|
|
1
|
-
// test/components/sheet.test.ts
|
|
2
|
-
import { describe, test, expect } from 'bun:test';
|
|
3
|
-
import {
|
|
4
|
-
type SheetComponent,
|
|
5
|
-
type SheetConfig
|
|
6
|
-
} from '../../src/components/sheet/types';
|
|
7
|
-
|
|
8
|
-
// Constants for sheet variants
|
|
9
|
-
const SHEET_VARIANTS = {
|
|
10
|
-
STANDARD: 'standard',
|
|
11
|
-
MODAL: 'modal',
|
|
12
|
-
EXPANDED: 'expanded'
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
// Constants for sheet positions
|
|
16
|
-
const SHEET_POSITIONS = {
|
|
17
|
-
BOTTOM: 'bottom',
|
|
18
|
-
TOP: 'top',
|
|
19
|
-
LEFT: 'left',
|
|
20
|
-
RIGHT: 'right'
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
// Constants for sheet events
|
|
24
|
-
const SHEET_EVENTS = {
|
|
25
|
-
OPEN: 'open',
|
|
26
|
-
CLOSE: 'close',
|
|
27
|
-
DRAG_START: 'dragstart',
|
|
28
|
-
DRAG_END: 'dragend'
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
// Mock sheet implementation
|
|
32
|
-
const createMockSheet = (config: SheetConfig = {}): SheetComponent => {
|
|
33
|
-
// Create main elements
|
|
34
|
-
const element = document.createElement('div');
|
|
35
|
-
element.className = 'mtrl-sheet';
|
|
36
|
-
|
|
37
|
-
const scrim = document.createElement('div');
|
|
38
|
-
scrim.className = 'mtrl-sheet__scrim';
|
|
39
|
-
|
|
40
|
-
const container = document.createElement('div');
|
|
41
|
-
container.className = 'mtrl-sheet__container';
|
|
42
|
-
|
|
43
|
-
// Default settings
|
|
44
|
-
const settings = {
|
|
45
|
-
variant: config.variant || SHEET_VARIANTS.STANDARD,
|
|
46
|
-
position: config.position || SHEET_POSITIONS.BOTTOM,
|
|
47
|
-
open: config.open || false,
|
|
48
|
-
dismissible: config.dismissible !== undefined ? config.dismissible : true,
|
|
49
|
-
dragHandle: config.dragHandle !== undefined ? config.dragHandle : true,
|
|
50
|
-
content: config.content || '',
|
|
51
|
-
title: config.title || '',
|
|
52
|
-
prefix: config.prefix || 'mtrl',
|
|
53
|
-
componentName: config.componentName || 'sheet',
|
|
54
|
-
elevation: config.elevation || 3,
|
|
55
|
-
maxHeight: config.maxHeight || '80%',
|
|
56
|
-
enableGestures: config.enableGestures !== undefined ? config.enableGestures : true
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// Apply variant class
|
|
60
|
-
element.classList.add(`mtrl-sheet--${settings.variant}`);
|
|
61
|
-
|
|
62
|
-
// Apply position class
|
|
63
|
-
element.classList.add(`mtrl-sheet--${settings.position}`);
|
|
64
|
-
|
|
65
|
-
// Apply elevation class
|
|
66
|
-
element.classList.add(`mtrl-sheet--elevation-${settings.elevation}`);
|
|
67
|
-
|
|
68
|
-
// Apply open state
|
|
69
|
-
if (settings.open) {
|
|
70
|
-
element.classList.add('mtrl-sheet--open');
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Apply additional classes
|
|
74
|
-
if (config.class) {
|
|
75
|
-
const classes = config.class.split(' ');
|
|
76
|
-
classes.forEach(className => element.classList.add(className));
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Create drag handle if enabled
|
|
80
|
-
let dragHandleElement: HTMLElement | null = null;
|
|
81
|
-
if (settings.dragHandle) {
|
|
82
|
-
dragHandleElement = document.createElement('div');
|
|
83
|
-
dragHandleElement.className = 'mtrl-sheet__handle';
|
|
84
|
-
container.appendChild(dragHandleElement);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Create title if provided
|
|
88
|
-
let titleElement: HTMLElement | null = null;
|
|
89
|
-
if (settings.title) {
|
|
90
|
-
titleElement = document.createElement('div');
|
|
91
|
-
titleElement.className = 'mtrl-sheet__title';
|
|
92
|
-
titleElement.textContent = settings.title;
|
|
93
|
-
container.appendChild(titleElement);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Create content element
|
|
97
|
-
const contentElement = document.createElement('div');
|
|
98
|
-
contentElement.className = 'mtrl-sheet__content';
|
|
99
|
-
|
|
100
|
-
if (settings.content) {
|
|
101
|
-
contentElement.innerHTML = settings.content;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
container.appendChild(contentElement);
|
|
105
|
-
|
|
106
|
-
// Add max height to container
|
|
107
|
-
if (settings.maxHeight) {
|
|
108
|
-
container.style.maxHeight = settings.maxHeight;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Assemble the sheet
|
|
112
|
-
element.appendChild(scrim);
|
|
113
|
-
element.appendChild(container);
|
|
114
|
-
|
|
115
|
-
// Track event handlers
|
|
116
|
-
const eventHandlers: Record<string, Function[]> = {};
|
|
117
|
-
|
|
118
|
-
// Emit an event
|
|
119
|
-
const emit = (event: string) => {
|
|
120
|
-
const handlers = eventHandlers[event];
|
|
121
|
-
if (handlers) {
|
|
122
|
-
handlers.forEach(handler => handler());
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Direct callbacks
|
|
126
|
-
if (event === SHEET_EVENTS.OPEN && config.onOpen) {
|
|
127
|
-
config.onOpen();
|
|
128
|
-
} else if (event === SHEET_EVENTS.CLOSE && config.onClose) {
|
|
129
|
-
config.onClose();
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
// Set up event handlers
|
|
134
|
-
scrim.addEventListener('click', () => {
|
|
135
|
-
if (settings.dismissible) {
|
|
136
|
-
sheet.close();
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// Content API
|
|
141
|
-
const contentAPI = {
|
|
142
|
-
setContent: (html: string) => {
|
|
143
|
-
contentElement.innerHTML = html;
|
|
144
|
-
settings.content = html;
|
|
145
|
-
return contentAPI;
|
|
146
|
-
},
|
|
147
|
-
|
|
148
|
-
getContent: () => settings.content,
|
|
149
|
-
|
|
150
|
-
getElement: () => contentElement
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
// Title API
|
|
154
|
-
const titleAPI = {
|
|
155
|
-
setTitle: (text: string) => {
|
|
156
|
-
settings.title = text;
|
|
157
|
-
|
|
158
|
-
if (text) {
|
|
159
|
-
if (!titleElement) {
|
|
160
|
-
titleElement = document.createElement('div');
|
|
161
|
-
titleElement.className = 'mtrl-sheet__title';
|
|
162
|
-
if (dragHandleElement) {
|
|
163
|
-
container.insertBefore(titleElement, dragHandleElement.nextSibling);
|
|
164
|
-
} else {
|
|
165
|
-
container.insertBefore(titleElement, container.firstChild);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
titleElement.textContent = text;
|
|
170
|
-
} else if (titleElement) {
|
|
171
|
-
titleElement.remove();
|
|
172
|
-
titleElement = null;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return titleAPI;
|
|
176
|
-
},
|
|
177
|
-
|
|
178
|
-
getTitle: () => settings.title,
|
|
179
|
-
|
|
180
|
-
getElement: () => titleElement
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
// Create the sheet component
|
|
184
|
-
const sheet: SheetComponent = {
|
|
185
|
-
element,
|
|
186
|
-
container,
|
|
187
|
-
content: contentAPI,
|
|
188
|
-
title: titleAPI,
|
|
189
|
-
|
|
190
|
-
state: {
|
|
191
|
-
open: () => {
|
|
192
|
-
if (!settings.open) {
|
|
193
|
-
element.classList.add('mtrl-sheet--open');
|
|
194
|
-
settings.open = true;
|
|
195
|
-
emit(SHEET_EVENTS.OPEN);
|
|
196
|
-
}
|
|
197
|
-
},
|
|
198
|
-
|
|
199
|
-
close: () => {
|
|
200
|
-
if (settings.open) {
|
|
201
|
-
element.classList.remove('mtrl-sheet--open');
|
|
202
|
-
settings.open = false;
|
|
203
|
-
emit(SHEET_EVENTS.CLOSE);
|
|
204
|
-
}
|
|
205
|
-
},
|
|
206
|
-
|
|
207
|
-
isOpen: () => settings.open
|
|
208
|
-
},
|
|
209
|
-
|
|
210
|
-
lifecycle: {
|
|
211
|
-
destroy: () => {
|
|
212
|
-
sheet.destroy();
|
|
213
|
-
}
|
|
214
|
-
},
|
|
215
|
-
|
|
216
|
-
getClass: (name: string) => {
|
|
217
|
-
const prefix = settings.prefix;
|
|
218
|
-
return name ? `${prefix}-${name}` : `${prefix}-sheet`;
|
|
219
|
-
},
|
|
220
|
-
|
|
221
|
-
open: () => {
|
|
222
|
-
sheet.state.open();
|
|
223
|
-
return sheet;
|
|
224
|
-
},
|
|
225
|
-
|
|
226
|
-
close: () => {
|
|
227
|
-
sheet.state.close();
|
|
228
|
-
return sheet;
|
|
229
|
-
},
|
|
230
|
-
|
|
231
|
-
setContent: (html: string) => {
|
|
232
|
-
contentAPI.setContent(html);
|
|
233
|
-
return sheet;
|
|
234
|
-
},
|
|
235
|
-
|
|
236
|
-
getContent: () => contentAPI.getContent(),
|
|
237
|
-
|
|
238
|
-
setTitle: (text: string) => {
|
|
239
|
-
titleAPI.setTitle(text);
|
|
240
|
-
return sheet;
|
|
241
|
-
},
|
|
242
|
-
|
|
243
|
-
getTitle: () => titleAPI.getTitle(),
|
|
244
|
-
|
|
245
|
-
setDragHandle: (enabled: boolean) => {
|
|
246
|
-
if (enabled && !dragHandleElement) {
|
|
247
|
-
// Create drag handle
|
|
248
|
-
dragHandleElement = document.createElement('div');
|
|
249
|
-
dragHandleElement.className = 'mtrl-sheet__handle';
|
|
250
|
-
container.insertBefore(dragHandleElement, container.firstChild);
|
|
251
|
-
} else if (!enabled && dragHandleElement) {
|
|
252
|
-
// Remove drag handle
|
|
253
|
-
dragHandleElement.remove();
|
|
254
|
-
dragHandleElement = null;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
settings.dragHandle = enabled;
|
|
258
|
-
return sheet;
|
|
259
|
-
},
|
|
260
|
-
|
|
261
|
-
setMaxHeight: (height: string) => {
|
|
262
|
-
settings.maxHeight = height;
|
|
263
|
-
container.style.maxHeight = height;
|
|
264
|
-
return sheet;
|
|
265
|
-
},
|
|
266
|
-
|
|
267
|
-
destroy: () => {
|
|
268
|
-
// Remove element from DOM if it has a parent
|
|
269
|
-
if (element.parentNode) {
|
|
270
|
-
element.parentNode.removeChild(element);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// Clear event handlers
|
|
274
|
-
for (const event in eventHandlers) {
|
|
275
|
-
eventHandlers[event] = [];
|
|
276
|
-
}
|
|
277
|
-
},
|
|
278
|
-
|
|
279
|
-
on: (event: string, handler: Function) => {
|
|
280
|
-
if (!eventHandlers[event]) {
|
|
281
|
-
eventHandlers[event] = [];
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
eventHandlers[event].push(handler);
|
|
285
|
-
return sheet;
|
|
286
|
-
},
|
|
287
|
-
|
|
288
|
-
off: (event: string, handler: Function) => {
|
|
289
|
-
if (eventHandlers[event]) {
|
|
290
|
-
eventHandlers[event] = eventHandlers[event].filter(h => h !== handler);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
return sheet;
|
|
294
|
-
},
|
|
295
|
-
|
|
296
|
-
addClass: (...classes: string[]) => {
|
|
297
|
-
classes.forEach(className => element.classList.add(className));
|
|
298
|
-
return sheet;
|
|
299
|
-
}
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
return sheet;
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
describe('Sheet Component', () => {
|
|
306
|
-
test('should create a sheet element', () => {
|
|
307
|
-
const sheet = createMockSheet();
|
|
308
|
-
|
|
309
|
-
expect(sheet.element).toBeDefined();
|
|
310
|
-
expect(sheet.element.tagName).toBe('DIV');
|
|
311
|
-
expect(sheet.element.className).toContain('mtrl-sheet');
|
|
312
|
-
|
|
313
|
-
expect(sheet.container).toBeDefined();
|
|
314
|
-
expect(sheet.container.className).toContain('mtrl-sheet__container');
|
|
315
|
-
|
|
316
|
-
const scrim = sheet.element.querySelector('.mtrl-sheet__scrim');
|
|
317
|
-
expect(scrim).toBeDefined();
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
test('should apply standard variant by default', () => {
|
|
321
|
-
const sheet = createMockSheet();
|
|
322
|
-
expect(sheet.element.className).toContain('mtrl-sheet--standard');
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
test('should apply different variants', () => {
|
|
326
|
-
const variants = Object.values(SHEET_VARIANTS);
|
|
327
|
-
|
|
328
|
-
variants.forEach(variant => {
|
|
329
|
-
const sheet = createMockSheet({ variant });
|
|
330
|
-
expect(sheet.element.className).toContain(`mtrl-sheet--${variant}`);
|
|
331
|
-
});
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
test('should apply bottom position by default', () => {
|
|
335
|
-
const sheet = createMockSheet();
|
|
336
|
-
expect(sheet.element.className).toContain('mtrl-sheet--bottom');
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
test('should apply different positions', () => {
|
|
340
|
-
const positions = Object.values(SHEET_POSITIONS);
|
|
341
|
-
|
|
342
|
-
positions.forEach(position => {
|
|
343
|
-
const sheet = createMockSheet({ position });
|
|
344
|
-
expect(sheet.element.className).toContain(`mtrl-sheet--${position}`);
|
|
345
|
-
});
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
test('should apply elevation level', () => {
|
|
349
|
-
const sheet = createMockSheet({ elevation: 4 });
|
|
350
|
-
expect(sheet.element.className).toContain('mtrl-sheet--elevation-4');
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
test('should be closed by default', () => {
|
|
354
|
-
const sheet = createMockSheet();
|
|
355
|
-
expect(sheet.element.className).not.toContain('mtrl-sheet--open');
|
|
356
|
-
expect(sheet.state.isOpen()).toBe(false);
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
test('should be initially open when configured', () => {
|
|
360
|
-
const sheet = createMockSheet({ open: true });
|
|
361
|
-
expect(sheet.element.className).toContain('mtrl-sheet--open');
|
|
362
|
-
expect(sheet.state.isOpen()).toBe(true);
|
|
363
|
-
});
|
|
364
|
-
|
|
365
|
-
test('should create drag handle by default', () => {
|
|
366
|
-
const sheet = createMockSheet();
|
|
367
|
-
|
|
368
|
-
const handle = sheet.element.querySelector('.mtrl-sheet__handle');
|
|
369
|
-
expect(handle).toBeDefined();
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
test('should not create drag handle when disabled', () => {
|
|
373
|
-
const sheet = createMockSheet({ dragHandle: false });
|
|
374
|
-
|
|
375
|
-
const handle = sheet.element.querySelector('.mtrl-sheet__handle');
|
|
376
|
-
expect(handle).toBeNull();
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
test('should set initial content', () => {
|
|
380
|
-
const content = '<p>Sheet content</p>';
|
|
381
|
-
const sheet = createMockSheet({ content });
|
|
382
|
-
|
|
383
|
-
const contentElement = sheet.element.querySelector('.mtrl-sheet__content');
|
|
384
|
-
expect(contentElement).toBeDefined();
|
|
385
|
-
expect(contentElement?.innerHTML).toBe(content);
|
|
386
|
-
|
|
387
|
-
expect(sheet.getContent()).toBe(content);
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
test('should set initial title', () => {
|
|
391
|
-
const title = 'Sheet Title';
|
|
392
|
-
const sheet = createMockSheet({ title });
|
|
393
|
-
|
|
394
|
-
const titleElement = sheet.element.querySelector('.mtrl-sheet__title');
|
|
395
|
-
expect(titleElement).toBeDefined();
|
|
396
|
-
expect(titleElement?.textContent).toBe(title);
|
|
397
|
-
|
|
398
|
-
expect(sheet.getTitle()).toBe(title);
|
|
399
|
-
});
|
|
400
|
-
|
|
401
|
-
test('should apply max height', () => {
|
|
402
|
-
const maxHeight = '50%';
|
|
403
|
-
const sheet = createMockSheet({ maxHeight });
|
|
404
|
-
|
|
405
|
-
expect(sheet.container.style.maxHeight).toBe(maxHeight);
|
|
406
|
-
});
|
|
407
|
-
|
|
408
|
-
test('should open and close', () => {
|
|
409
|
-
const sheet = createMockSheet();
|
|
410
|
-
|
|
411
|
-
expect(sheet.state.isOpen()).toBe(false);
|
|
412
|
-
|
|
413
|
-
sheet.open();
|
|
414
|
-
|
|
415
|
-
expect(sheet.state.isOpen()).toBe(true);
|
|
416
|
-
expect(sheet.element.className).toContain('mtrl-sheet--open');
|
|
417
|
-
|
|
418
|
-
sheet.close();
|
|
419
|
-
|
|
420
|
-
expect(sheet.state.isOpen()).toBe(false);
|
|
421
|
-
expect(sheet.element.className).not.toContain('mtrl-sheet--open');
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
test('should update content', () => {
|
|
425
|
-
const sheet = createMockSheet();
|
|
426
|
-
|
|
427
|
-
const initialContent = sheet.element.querySelector('.mtrl-sheet__content');
|
|
428
|
-
expect(initialContent?.innerHTML).toBe('');
|
|
429
|
-
|
|
430
|
-
const newContent = '<div>New content</div>';
|
|
431
|
-
sheet.setContent(newContent);
|
|
432
|
-
|
|
433
|
-
expect(sheet.getContent()).toBe(newContent);
|
|
434
|
-
expect(initialContent?.innerHTML).toBe(newContent);
|
|
435
|
-
});
|
|
436
|
-
|
|
437
|
-
test('should add title dynamically', () => {
|
|
438
|
-
const sheet = createMockSheet();
|
|
439
|
-
|
|
440
|
-
let titleElement = sheet.element.querySelector('.mtrl-sheet__title');
|
|
441
|
-
expect(titleElement).toBeNull();
|
|
442
|
-
|
|
443
|
-
sheet.setTitle('New Title');
|
|
444
|
-
|
|
445
|
-
titleElement = sheet.element.querySelector('.mtrl-sheet__title');
|
|
446
|
-
expect(titleElement).toBeDefined();
|
|
447
|
-
expect(titleElement?.textContent).toBe('New Title');
|
|
448
|
-
expect(sheet.getTitle()).toBe('New Title');
|
|
449
|
-
});
|
|
450
|
-
|
|
451
|
-
test('should remove title when setting empty string', () => {
|
|
452
|
-
const sheet = createMockSheet({ title: 'Initial Title' });
|
|
453
|
-
|
|
454
|
-
let titleElement = sheet.element.querySelector('.mtrl-sheet__title');
|
|
455
|
-
expect(titleElement).toBeDefined();
|
|
456
|
-
|
|
457
|
-
sheet.setTitle('');
|
|
458
|
-
|
|
459
|
-
titleElement = sheet.element.querySelector('.mtrl-sheet__title');
|
|
460
|
-
expect(titleElement).toBeNull();
|
|
461
|
-
expect(sheet.getTitle()).toBe('');
|
|
462
|
-
});
|
|
463
|
-
|
|
464
|
-
test('should add and remove drag handle', () => {
|
|
465
|
-
const sheet = createMockSheet({ dragHandle: false });
|
|
466
|
-
|
|
467
|
-
let handleElement = sheet.element.querySelector('.mtrl-sheet__handle');
|
|
468
|
-
expect(handleElement).toBeNull();
|
|
469
|
-
|
|
470
|
-
sheet.setDragHandle(true);
|
|
471
|
-
|
|
472
|
-
handleElement = sheet.element.querySelector('.mtrl-sheet__handle');
|
|
473
|
-
expect(handleElement).toBeDefined();
|
|
474
|
-
|
|
475
|
-
sheet.setDragHandle(false);
|
|
476
|
-
|
|
477
|
-
handleElement = sheet.element.querySelector('.mtrl-sheet__handle');
|
|
478
|
-
expect(handleElement).toBeNull();
|
|
479
|
-
});
|
|
480
|
-
|
|
481
|
-
test('should update max height', () => {
|
|
482
|
-
const sheet = createMockSheet({ maxHeight: '80%' });
|
|
483
|
-
|
|
484
|
-
expect(sheet.container.style.maxHeight).toBe('80%');
|
|
485
|
-
|
|
486
|
-
sheet.setMaxHeight('40%');
|
|
487
|
-
|
|
488
|
-
expect(sheet.container.style.maxHeight).toBe('40%');
|
|
489
|
-
});
|
|
490
|
-
|
|
491
|
-
test('should close when clicking scrim if dismissible', () => {
|
|
492
|
-
const sheet = createMockSheet({
|
|
493
|
-
open: true,
|
|
494
|
-
dismissible: true
|
|
495
|
-
});
|
|
496
|
-
|
|
497
|
-
expect(sheet.state.isOpen()).toBe(true);
|
|
498
|
-
|
|
499
|
-
const scrim = sheet.element.querySelector('.mtrl-sheet__scrim');
|
|
500
|
-
scrim?.dispatchEvent(new Event('click'));
|
|
501
|
-
|
|
502
|
-
expect(sheet.state.isOpen()).toBe(false);
|
|
503
|
-
});
|
|
504
|
-
|
|
505
|
-
test('should not close when clicking scrim if not dismissible', () => {
|
|
506
|
-
const sheet = createMockSheet({
|
|
507
|
-
open: true,
|
|
508
|
-
dismissible: false
|
|
509
|
-
});
|
|
510
|
-
|
|
511
|
-
expect(sheet.state.isOpen()).toBe(true);
|
|
512
|
-
|
|
513
|
-
const scrim = sheet.element.querySelector('.mtrl-sheet__scrim');
|
|
514
|
-
scrim?.dispatchEvent(new Event('click'));
|
|
515
|
-
|
|
516
|
-
expect(sheet.state.isOpen()).toBe(true);
|
|
517
|
-
});
|
|
518
|
-
|
|
519
|
-
test('should emit open events', () => {
|
|
520
|
-
const sheet = createMockSheet();
|
|
521
|
-
|
|
522
|
-
let eventFired = false;
|
|
523
|
-
sheet.on(SHEET_EVENTS.OPEN, () => {
|
|
524
|
-
eventFired = true;
|
|
525
|
-
});
|
|
526
|
-
|
|
527
|
-
sheet.open();
|
|
528
|
-
|
|
529
|
-
expect(eventFired).toBe(true);
|
|
530
|
-
});
|
|
531
|
-
|
|
532
|
-
test('should emit close events', () => {
|
|
533
|
-
const sheet = createMockSheet({ open: true });
|
|
534
|
-
|
|
535
|
-
let eventFired = false;
|
|
536
|
-
sheet.on(SHEET_EVENTS.CLOSE, () => {
|
|
537
|
-
eventFired = true;
|
|
538
|
-
});
|
|
539
|
-
|
|
540
|
-
sheet.close();
|
|
541
|
-
|
|
542
|
-
expect(eventFired).toBe(true);
|
|
543
|
-
});
|
|
544
|
-
|
|
545
|
-
test('should call onOpen callback', () => {
|
|
546
|
-
let callbackFired = false;
|
|
547
|
-
|
|
548
|
-
const sheet = createMockSheet({
|
|
549
|
-
onOpen: () => {
|
|
550
|
-
callbackFired = true;
|
|
551
|
-
}
|
|
552
|
-
});
|
|
553
|
-
|
|
554
|
-
sheet.open();
|
|
555
|
-
|
|
556
|
-
expect(callbackFired).toBe(true);
|
|
557
|
-
});
|
|
558
|
-
|
|
559
|
-
test('should call onClose callback', () => {
|
|
560
|
-
let callbackFired = false;
|
|
561
|
-
|
|
562
|
-
const sheet = createMockSheet({
|
|
563
|
-
open: true,
|
|
564
|
-
onClose: () => {
|
|
565
|
-
callbackFired = true;
|
|
566
|
-
}
|
|
567
|
-
});
|
|
568
|
-
|
|
569
|
-
sheet.close();
|
|
570
|
-
|
|
571
|
-
expect(callbackFired).toBe(true);
|
|
572
|
-
});
|
|
573
|
-
|
|
574
|
-
test('should not emit events when state does not change', () => {
|
|
575
|
-
const sheet = createMockSheet({ open: true });
|
|
576
|
-
|
|
577
|
-
let eventCount = 0;
|
|
578
|
-
sheet.on(SHEET_EVENTS.OPEN, () => {
|
|
579
|
-
eventCount++;
|
|
580
|
-
});
|
|
581
|
-
|
|
582
|
-
// Open when already open
|
|
583
|
-
sheet.open();
|
|
584
|
-
|
|
585
|
-
expect(eventCount).toBe(0);
|
|
586
|
-
|
|
587
|
-
// Similarly for close
|
|
588
|
-
const closedSheet = createMockSheet({ open: false });
|
|
589
|
-
|
|
590
|
-
let closeEventCount = 0;
|
|
591
|
-
closedSheet.on(SHEET_EVENTS.CLOSE, () => {
|
|
592
|
-
closeEventCount++;
|
|
593
|
-
});
|
|
594
|
-
|
|
595
|
-
// Close when already closed
|
|
596
|
-
closedSheet.close();
|
|
597
|
-
|
|
598
|
-
expect(closeEventCount).toBe(0);
|
|
599
|
-
});
|
|
600
|
-
|
|
601
|
-
test('should add CSS classes', () => {
|
|
602
|
-
const sheet = createMockSheet();
|
|
603
|
-
|
|
604
|
-
sheet.addClass('custom-class', 'special-sheet');
|
|
605
|
-
|
|
606
|
-
expect(sheet.element.className).toContain('custom-class');
|
|
607
|
-
expect(sheet.element.className).toContain('special-sheet');
|
|
608
|
-
});
|
|
609
|
-
|
|
610
|
-
test('should remove event listeners', () => {
|
|
611
|
-
const sheet = createMockSheet();
|
|
612
|
-
|
|
613
|
-
let eventCount = 0;
|
|
614
|
-
|
|
615
|
-
const handler = () => {
|
|
616
|
-
eventCount++;
|
|
617
|
-
};
|
|
618
|
-
|
|
619
|
-
sheet.on(SHEET_EVENTS.OPEN, handler);
|
|
620
|
-
|
|
621
|
-
sheet.open();
|
|
622
|
-
expect(eventCount).toBe(1);
|
|
623
|
-
|
|
624
|
-
sheet.off(SHEET_EVENTS.OPEN, handler);
|
|
625
|
-
|
|
626
|
-
sheet.close();
|
|
627
|
-
sheet.open();
|
|
628
|
-
expect(eventCount).toBe(1); // Count should not increase
|
|
629
|
-
});
|
|
630
|
-
|
|
631
|
-
test('should be properly destroyed', () => {
|
|
632
|
-
const sheet = createMockSheet();
|
|
633
|
-
document.body.appendChild(sheet.element);
|
|
634
|
-
|
|
635
|
-
expect(document.body.contains(sheet.element)).toBe(true);
|
|
636
|
-
|
|
637
|
-
sheet.destroy();
|
|
638
|
-
|
|
639
|
-
expect(document.body.contains(sheet.element)).toBe(false);
|
|
640
|
-
});
|
|
641
|
-
});
|