q2-tecton-elements 1.52.2 → 1.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/cjs/loader.cjs.js +1 -1
  2. package/dist/cjs/q2-file-picker.cjs.entry.js +236 -0
  3. package/dist/cjs/q2-file-picker.cjs.entry.js.map +1 -0
  4. package/dist/cjs/q2-item_3.cjs.entry.js +250 -0
  5. package/dist/cjs/q2-item_3.cjs.entry.js.map +1 -0
  6. package/dist/cjs/q2-pill.cjs.entry.js +7 -3
  7. package/dist/cjs/q2-pill.cjs.entry.js.map +1 -1
  8. package/dist/cjs/q2-select.cjs.entry.js +3 -2
  9. package/dist/cjs/q2-select.cjs.entry.js.map +1 -1
  10. package/dist/cjs/q2-tag.cjs.entry.js +3 -1
  11. package/dist/cjs/q2-tag.cjs.entry.js.map +1 -1
  12. package/dist/cjs/q2-tecton-elements.cjs.js +1 -1
  13. package/dist/collection/collection-manifest.json +1 -0
  14. package/dist/collection/components/q2-file-picker/q2-file-picker.css +288 -0
  15. package/dist/collection/components/q2-file-picker/q2-file-picker.js +426 -0
  16. package/dist/collection/components/q2-file-picker/q2-file-picker.js.map +1 -0
  17. package/dist/collection/components/q2-file-picker/test/q2-file-picker-test.e2e.js +11 -0
  18. package/dist/collection/components/q2-file-picker/test/q2-file-picker-test.e2e.js.map +1 -0
  19. package/dist/collection/components/q2-file-picker/test/q2-file-picker-test.spec.js +435 -0
  20. package/dist/collection/components/q2-file-picker/test/q2-file-picker-test.spec.js.map +1 -0
  21. package/dist/collection/components/q2-item/q2-item.css +3 -0
  22. package/dist/collection/components/q2-list/q2-list.css +6 -0
  23. package/dist/collection/components/q2-pill/q2-pill.js +7 -3
  24. package/dist/collection/components/q2-pill/q2-pill.js.map +1 -1
  25. package/dist/collection/components/q2-pill/test/q2-pill-test.e2e.js +108 -0
  26. package/dist/collection/components/q2-pill/test/q2-pill-test.e2e.js.map +1 -1
  27. package/dist/collection/components/q2-select/q2-select.js +3 -2
  28. package/dist/collection/components/q2-select/q2-select.js.map +1 -1
  29. package/dist/collection/components/q2-tag/q2-tag.js +3 -1
  30. package/dist/collection/components/q2-tag/q2-tag.js.map +1 -1
  31. package/dist/components/index.js +2 -0
  32. package/dist/components/index.js.map +1 -1
  33. package/dist/components/q2-file-picker.d.ts +11 -0
  34. package/dist/components/q2-file-picker.js +301 -0
  35. package/dist/components/q2-file-picker.js.map +1 -0
  36. package/dist/components/q2-item.js +1 -130
  37. package/dist/components/q2-item.js.map +1 -1
  38. package/dist/{esm/q2-item.entry.js → components/q2-item2.js} +29 -11
  39. package/dist/components/q2-item2.js.map +1 -0
  40. package/dist/components/q2-link.js +1 -86
  41. package/dist/components/q2-link.js.map +1 -1
  42. package/dist/{esm/q2-link.entry.js → components/q2-link2.js} +39 -9
  43. package/dist/components/q2-link2.js.map +1 -0
  44. package/dist/components/q2-list.js +1 -94
  45. package/dist/components/q2-list.js.map +1 -1
  46. package/dist/{esm/q2-list.entry.js → components/q2-list2.js} +30 -11
  47. package/dist/components/q2-list2.js.map +1 -0
  48. package/dist/components/q2-pill.js +7 -3
  49. package/dist/components/q2-pill.js.map +1 -1
  50. package/dist/components/q2-select2.js +3 -2
  51. package/dist/components/q2-select2.js.map +1 -1
  52. package/dist/components/q2-tag.js +3 -1
  53. package/dist/components/q2-tag.js.map +1 -1
  54. package/dist/esm/loader.js +1 -1
  55. package/dist/esm/q2-file-picker.entry.js +232 -0
  56. package/dist/esm/q2-file-picker.entry.js.map +1 -0
  57. package/dist/esm/q2-item_3.entry.js +244 -0
  58. package/dist/esm/q2-item_3.entry.js.map +1 -0
  59. package/dist/esm/q2-pill.entry.js +7 -3
  60. package/dist/esm/q2-pill.entry.js.map +1 -1
  61. package/dist/esm/q2-select.entry.js +3 -2
  62. package/dist/esm/q2-select.entry.js.map +1 -1
  63. package/dist/esm/q2-tag.entry.js +3 -1
  64. package/dist/esm/q2-tag.entry.js.map +1 -1
  65. package/dist/esm/q2-tecton-elements.js +1 -1
  66. package/dist/q2-tecton-elements/q2-file-picker.entry.js +338 -0
  67. package/dist/q2-tecton-elements/q2-file-picker.entry.js.map +1 -0
  68. package/dist/q2-tecton-elements/q2-item_3.entry.js +331 -0
  69. package/dist/q2-tecton-elements/q2-item_3.entry.js.map +1 -0
  70. package/dist/q2-tecton-elements/q2-pill.entry.js +22 -18
  71. package/dist/q2-tecton-elements/q2-pill.entry.js.map +1 -1
  72. package/dist/q2-tecton-elements/q2-select.entry.js +6 -5
  73. package/dist/q2-tecton-elements/q2-select.entry.js.map +1 -1
  74. package/dist/q2-tecton-elements/q2-tag.entry.js +36 -34
  75. package/dist/q2-tecton-elements/q2-tag.entry.js.map +1 -1
  76. package/dist/q2-tecton-elements/q2-tecton-elements.esm.js +1 -1
  77. package/dist/q2-tecton-elements/q2-tecton-elements.esm.js.map +1 -1
  78. package/dist/types/components/q2-file-picker/q2-file-picker.d.ts +98 -0
  79. package/dist/types/components/q2-pill/q2-pill.d.ts +1 -1
  80. package/dist/types/components.d.ts +101 -0
  81. package/package.json +3 -3
  82. package/dist/cjs/q2-item.cjs.entry.js +0 -120
  83. package/dist/cjs/q2-item.cjs.entry.js.map +0 -1
  84. package/dist/cjs/q2-link.cjs.entry.js +0 -64
  85. package/dist/cjs/q2-link.cjs.entry.js.map +0 -1
  86. package/dist/cjs/q2-list.cjs.entry.js +0 -83
  87. package/dist/cjs/q2-list.cjs.entry.js.map +0 -1
  88. package/dist/esm/q2-item.entry.js.map +0 -1
  89. package/dist/esm/q2-link.entry.js.map +0 -1
  90. package/dist/esm/q2-list.entry.js.map +0 -1
  91. package/dist/q2-tecton-elements/q2-item.entry.js +0 -158
  92. package/dist/q2-tecton-elements/q2-item.entry.js.map +0 -1
  93. package/dist/q2-tecton-elements/q2-link.entry.js +0 -83
  94. package/dist/q2-tecton-elements/q2-link.entry.js.map +0 -1
  95. package/dist/q2-tecton-elements/q2-list.entry.js +0 -100
  96. package/dist/q2-tecton-elements/q2-list.entry.js.map +0 -1
@@ -0,0 +1,435 @@
1
+ import { Q2FilePicker } from "../q2-file-picker";
2
+ import { objectToHTMLAttributes, setupSpecPageWithLoc } from "../../../utils/helpers";
3
+ describe('q2-legend', () => {
4
+ const buildSlots = (slots) => {
5
+ return slots.reduce((acc, slot) => {
6
+ return `${acc}<div slot="${slot.name}">${slot.content}</div>`;
7
+ }, '');
8
+ };
9
+ const setupPage = async (attributes = {}, testStrings = {}, slots = []) => {
10
+ const attributesString = objectToHTMLAttributes(attributes);
11
+ const slotsString = buildSlots(slots);
12
+ const page = await setupSpecPageWithLoc({
13
+ components: [Q2FilePicker],
14
+ html: `<q2-file-picker ${attributesString}>${slotsString}</q2-file-picker>`,
15
+ }, testStrings);
16
+ return page;
17
+ };
18
+ const createMockFile = (props = {}) => {
19
+ return {
20
+ name: props.name || 'test-file',
21
+ lastModified: props.lastModified || Date.now(),
22
+ webkitRelativePath: props.webkitRelativePath || '',
23
+ size: props.size || 1234,
24
+ type: props.type || 'text/plain', // 'application/pdf'
25
+ arrayBuffer: props.arrayBuffer || jest.fn(),
26
+ slice: props.slice || jest.fn(),
27
+ stream: props.stream || jest.fn(),
28
+ text: props.text || jest.fn(),
29
+ bytes: props.bytes || jest.fn(() => Promise.resolve(new Uint8Array())),
30
+ };
31
+ };
32
+ const createMockFileList = (files) => {
33
+ return Object.assign(Object.assign({}, files), { length: files.length, item: (index) => files[index] });
34
+ };
35
+ function simulateFileInputChange(page, mockFileList) {
36
+ const input = page.root.shadowRoot.querySelector('[test-id="file-input"]');
37
+ const changeCallback = jest.fn();
38
+ page.root.addEventListener('tctChange', changeCallback);
39
+ input.files = mockFileList;
40
+ input.dispatchEvent(new Event('change'));
41
+ return changeCallback;
42
+ }
43
+ describe('Props', () => {
44
+ describe('description', () => {
45
+ it('when set description rendered', async () => {
46
+ const descriptionText = 'Test Description';
47
+ const page = await setupPage({ description: descriptionText });
48
+ const description = page.root.shadowRoot.querySelector('[test-id="description"]');
49
+ expect(description).toEqualText(descriptionText);
50
+ });
51
+ it('is localizable', async () => {
52
+ const descriptionText = 'Test Description';
53
+ const page = await setupPage({ description: 'test.description' }, { 'test.description': descriptionText });
54
+ const description = page.root.shadowRoot.querySelector('[test-id="description"]');
55
+ expect(description).toEqualText(descriptionText);
56
+ });
57
+ });
58
+ describe('fileTypes', () => {
59
+ it('limits the types of files that can be selected', async () => {
60
+ const page = await setupPage();
61
+ page.root.fileTypes = ['pdf'];
62
+ const mockPdfFile = createMockFile({ name: 'test-file.pdf' });
63
+ const mockTextFile = createMockFile({ name: 'test-file.txt' });
64
+ const mockFileList = createMockFileList([mockPdfFile, mockTextFile]);
65
+ const changeCallback = simulateFileInputChange(page, mockFileList);
66
+ await page.waitForChanges();
67
+ const value = page.root.value;
68
+ const expectedValue = {
69
+ invalidFiles: [{ file: mockTextFile, status: 'invalid-type' }],
70
+ validFiles: [mockPdfFile],
71
+ };
72
+ expect(changeCallback).toHaveBeenCalledWith(expect.objectContaining({
73
+ detail: expect.objectContaining(expectedValue),
74
+ }));
75
+ expect(value).toEqual(expectedValue);
76
+ });
77
+ it('allows all file types when fileTypes is not defined', async () => {
78
+ const page = await setupPage();
79
+ const mockPdfFile = createMockFile({ name: 'test-file.pdf' });
80
+ const mockTextFile = createMockFile({ name: 'test-file.txt' });
81
+ const mockFileList = createMockFileList([mockPdfFile, mockTextFile]);
82
+ const changeCallback = simulateFileInputChange(page, mockFileList);
83
+ await page.waitForChanges();
84
+ const value = page.root.value;
85
+ const expectedValue = {
86
+ invalidFiles: [],
87
+ validFiles: [mockPdfFile, mockTextFile],
88
+ };
89
+ expect(changeCallback).toHaveBeenCalledWith(expect.objectContaining({
90
+ detail: expect.objectContaining(expectedValue),
91
+ }));
92
+ expect(value).toEqual(expectedValue);
93
+ });
94
+ });
95
+ describe('label', () => {
96
+ it('when set label rendered', async () => {
97
+ const labelText = 'Test Label';
98
+ const page = await setupPage({ label: labelText });
99
+ const label = page.root.shadowRoot.querySelector('[test-id="label"]');
100
+ expect(label).toEqualText(labelText);
101
+ });
102
+ it('is localizable', async () => {
103
+ const labelText = 'Test Label';
104
+ const page = await setupPage({ label: 'test.label' }, { 'test.label': labelText });
105
+ const label = page.root.shadowRoot.querySelector('[test-id="label"]');
106
+ expect(label).toEqualText(labelText);
107
+ });
108
+ });
109
+ describe('maxFiles', () => {
110
+ it('limits the number of files that can be selected', async () => {
111
+ const page = await setupPage({ 'max-files': 0 });
112
+ const mockPdfFile = createMockFile({ name: 'test-file.pdf', type: 'application/pdf' });
113
+ const mockFileList = createMockFileList([mockPdfFile]);
114
+ const changeCallback = simulateFileInputChange(page, mockFileList);
115
+ await page.waitForChanges();
116
+ const value = page.root.value;
117
+ const expectedValue = {
118
+ invalidFiles: [{ file: mockPdfFile, status: 'over-max-files-limit' }],
119
+ validFiles: [],
120
+ };
121
+ expect(changeCallback).toHaveBeenCalledWith(expect.objectContaining({
122
+ detail: expect.objectContaining(expectedValue),
123
+ }));
124
+ expect(value).toEqual(expectedValue);
125
+ });
126
+ it('allows multiple files to be selected when it is greater than 1', async () => {
127
+ const page = await setupPage({ maxFiles: 2 });
128
+ const mockFile = createMockFile({ name: 'test-file' });
129
+ const mockFile2 = Object.assign(Object.assign({}, mockFile), { name: 'test-file-2' });
130
+ const mockFileListMultiple = createMockFileList([mockFile, mockFile2]);
131
+ const changeCallback = simulateFileInputChange(page, mockFileListMultiple);
132
+ await page.waitForChanges();
133
+ const value = page.root.value;
134
+ const expectedValue = {
135
+ invalidFiles: [],
136
+ validFiles: [mockFile, mockFile2],
137
+ };
138
+ expect(changeCallback).toHaveBeenCalledWith(expect.objectContaining({
139
+ detail: expect.objectContaining(expectedValue),
140
+ }));
141
+ expect(value).toEqual(expectedValue);
142
+ });
143
+ it('allows any number of files to be selected when it is not set', async () => {
144
+ const page = await setupPage();
145
+ const mockFile = createMockFile({ name: 'test-file' });
146
+ const mockFile2 = Object.assign(Object.assign({}, mockFile), { name: 'test-file-2' });
147
+ const mockFile3 = Object.assign(Object.assign({}, mockFile), { name: 'test-file-3' });
148
+ const mockFileListMultiple = createMockFileList([mockFile, mockFile2, mockFile3]);
149
+ const changeCallback = simulateFileInputChange(page, mockFileListMultiple);
150
+ await page.waitForChanges();
151
+ const value = page.root.value;
152
+ const expectedValue = {
153
+ invalidFiles: [],
154
+ validFiles: [mockFile, mockFile2, mockFile3],
155
+ };
156
+ expect(changeCallback).toHaveBeenCalledWith(expect.objectContaining({
157
+ detail: expect.objectContaining(expectedValue),
158
+ }));
159
+ expect(value).toEqual(expectedValue);
160
+ });
161
+ });
162
+ describe('maxFileSize', () => {
163
+ it('limits the size of files that can be selected', async () => {
164
+ const page = await setupPage({ 'max-file-size': 2000 });
165
+ const mockFile = createMockFile({ name: 'test-file', size: 1000 });
166
+ const mockFileTooLarge = createMockFile({ name: 'test-file-2', size: 3000 });
167
+ const mockFileList = createMockFileList([mockFile, mockFileTooLarge]);
168
+ const changeCallback = simulateFileInputChange(page, mockFileList);
169
+ await page.waitForChanges();
170
+ const value = page.root.value;
171
+ const expectedValue = {
172
+ invalidFiles: [{ file: mockFileTooLarge, status: 'over-size-limit' }],
173
+ validFiles: [mockFile],
174
+ };
175
+ expect(changeCallback).toHaveBeenCalledWith(expect.objectContaining({
176
+ detail: expect.objectContaining(expectedValue),
177
+ }));
178
+ expect(value).toEqual(expectedValue);
179
+ });
180
+ });
181
+ describe('value', () => {
182
+ it('returns an object with empty arrays for prop values when no files have been selected', async () => {
183
+ const page = await setupPage();
184
+ const value = page.root.value;
185
+ const expectedValue = {
186
+ invalidFiles: [],
187
+ validFiles: [],
188
+ };
189
+ expect(value).toEqual(expectedValue);
190
+ });
191
+ it('returns an object with the selected files when files have been selected', async () => {
192
+ const page = await setupPage();
193
+ const mockFile = createMockFile({ name: 'test-file' });
194
+ const mockFileList = createMockFileList([mockFile]);
195
+ simulateFileInputChange(page, mockFileList);
196
+ await page.waitForChanges();
197
+ const value = page.root.value;
198
+ const expectedValue = {
199
+ invalidFiles: [],
200
+ validFiles: [mockFile],
201
+ };
202
+ expect(value).toEqual(expectedValue);
203
+ });
204
+ it('returns an object with the valid and invalid files when files have been selected', async () => {
205
+ const page = await setupPage();
206
+ page.root.fileTypes = ['pdf'];
207
+ const mockPdfFile = createMockFile({ name: 'test-file.pdf', type: 'application/pdf' });
208
+ const mockTextFile = createMockFile({ name: 'test-file.txt' });
209
+ const mockFileList = createMockFileList([mockPdfFile, mockTextFile]);
210
+ simulateFileInputChange(page, mockFileList);
211
+ await page.waitForChanges();
212
+ const value = page.root.value;
213
+ const expectedValue = {
214
+ invalidFiles: [{ file: mockTextFile, status: 'invalid-type' }],
215
+ validFiles: [mockPdfFile],
216
+ };
217
+ expect(value).toEqual(expectedValue);
218
+ });
219
+ });
220
+ describe('variant', () => {
221
+ it('when set to "browse-drop" displays drop zone', async () => {
222
+ const page = await setupPage({ variant: 'browse-drop' });
223
+ const dropZone = page.root.shadowRoot.querySelector('[test-id="drop-zone"]');
224
+ const browseButton = page.root.shadowRoot.querySelector('[test-id="browse-button"]');
225
+ expect(dropZone).not.toBeNull();
226
+ expect(browseButton).toBeNull();
227
+ });
228
+ it('when set to "browse" displays only the browse button', async () => {
229
+ const page = await setupPage({ variant: 'browse' });
230
+ const dropZone = page.root.shadowRoot.querySelector('[test-id="drop-zone"]');
231
+ const browseButton = page.root.shadowRoot.querySelector('[test-id="browse"]');
232
+ expect(dropZone).toBeNull();
233
+ expect(browseButton).not.toBeNull();
234
+ });
235
+ });
236
+ });
237
+ describe('Slots', () => {
238
+ describe('label', () => {
239
+ it('rendered when slot is provided', async () => {
240
+ const labelSlotContent = 'Test Label Slot';
241
+ const page = await setupPage({}, {}, [{ name: 'label', content: labelSlotContent }]);
242
+ const label = page.root.shadowRoot.querySelector('[test-id="label"]');
243
+ // check for the slot container without the slot content because
244
+ // newSpecPage appears to not render the slot content
245
+ expect(label.innerHTML).toEqualHtml('<slot name="label"></slot>');
246
+ });
247
+ it('not rendered when slot is provided and label prop set', async () => {
248
+ const labelText = 'Test Label';
249
+ const labelSlotContent = 'Test Label Slot';
250
+ const page = await setupPage({ label: labelText }, {}, [{ name: 'label', content: labelSlotContent }]);
251
+ const label = page.root.shadowRoot.querySelector('[test-id="label"]');
252
+ expect(label.innerHTML).toEqualHtml(labelText);
253
+ });
254
+ });
255
+ describe('description', () => {
256
+ it('rendered when slot is provided', async () => {
257
+ const descriptionSlotContent = 'Test Description Slot';
258
+ const page = await setupPage({}, {}, [{ name: 'description', content: descriptionSlotContent }]);
259
+ const description = page.root.shadowRoot.querySelector('[test-id="description"]');
260
+ // check for the slot container without the slot content because
261
+ // newSpecPage appears to not render the slot content
262
+ expect(description.innerHTML).toEqualHtml('<slot name="description"></slot>');
263
+ });
264
+ it('not rendered when slot is provided and label prop set', async () => {
265
+ const descriptionText = 'Test Description';
266
+ const descriptionSlotContent = 'Test Description Slot';
267
+ const page = await setupPage({ description: descriptionText }, {}, [
268
+ { name: 'description', content: descriptionSlotContent },
269
+ ]);
270
+ const label = page.root.shadowRoot.querySelector('[test-id="description"]');
271
+ expect(label.innerHTML).toEqualHtml(descriptionText);
272
+ });
273
+ });
274
+ });
275
+ describe('Events', () => {
276
+ describe('tctChange', () => {
277
+ it('emitted when a file input emits a change event', async () => {
278
+ const page = await setupPage();
279
+ const mockFile = createMockFile({ name: 'test-file' });
280
+ const mockFileList = createMockFileList([mockFile]);
281
+ const changeCallback = simulateFileInputChange(page, mockFileList);
282
+ await page.waitForChanges();
283
+ const expectedValue = {
284
+ invalidFiles: [],
285
+ validFiles: [mockFile],
286
+ };
287
+ expect(changeCallback).toHaveBeenCalledWith(expect.objectContaining({
288
+ detail: expect.objectContaining(expectedValue),
289
+ }));
290
+ });
291
+ });
292
+ });
293
+ describe('Watchers', () => {
294
+ describe('updateFileList', () => {
295
+ it('sets the status of a queued file when the status prop changes', async () => {
296
+ const page = await setupPage();
297
+ const mockFile = createMockFile({ name: 'test-file' });
298
+ page.rootInstance.queuedFiles = [mockFile];
299
+ page.rootInstance.updateFileList([{ name: 'test-file', status: 'uploaded' }]);
300
+ await page.waitForChanges();
301
+ expect(page.rootInstance.displayedFiles).toEqual([{ file: mockFile, status: 'uploaded' }]);
302
+ });
303
+ it('sets the status of a displayed file when the status prop changes', async () => {
304
+ const page = await setupPage();
305
+ const mockFile = createMockFile({ name: 'test-file' });
306
+ page.rootInstance.queuedFiles = [];
307
+ page.rootInstance.displayedFiles = [{ file: mockFile, status: 'queued' }];
308
+ page.rootInstance.updateFileList([{ name: 'test-file', status: 'uploaded' }]);
309
+ await page.waitForChanges();
310
+ expect(page.rootInstance.displayedFiles).toEqual([{ file: mockFile, status: 'uploaded' }]);
311
+ });
312
+ });
313
+ });
314
+ describe('Local methods', () => {
315
+ describe('disableLoaderIfAllFilesUploaded', () => {
316
+ it('sets the areFilesUploading flag to false when all files are uploaded', async () => {
317
+ const page = await setupPage();
318
+ const mockFile = createMockFile({ name: 'test-file' });
319
+ page.rootInstance.areFilesUploading = true;
320
+ page.rootInstance.displayedFiles = [{ file: mockFile, status: 'uploaded' }];
321
+ page.rootInstance.disableLoaderIfAllFilesUploaded();
322
+ await page.waitForChanges();
323
+ expect(page.rootInstance.areFilesUploading).toBeFalsy();
324
+ });
325
+ });
326
+ describe('getAnimationendHandlerToRemoveFileItem', () => {
327
+ it('returns a function that removes a file after animation has ended', async () => {
328
+ const page = await setupPage();
329
+ const fileItem = {
330
+ file: createMockFile(),
331
+ status: 'uploaded',
332
+ };
333
+ page.rootInstance.displayedFiles = [fileItem];
334
+ const animationEndHandler = page.rootInstance.getAnimationendHandlerToRemoveFileItem(fileItem.file.name);
335
+ const mockAnimationEvent = {
336
+ animationName: 'shrinkToCenterFadeOut',
337
+ };
338
+ animationEndHandler(mockAnimationEvent);
339
+ expect(page.rootInstance.displayedFiles.length).toEqual(0);
340
+ });
341
+ });
342
+ describe('getClickHandlerToRemoveFileItem', () => {
343
+ it('returns a function that flags the file as to be removed', async () => {
344
+ const page = await setupPage();
345
+ const fileItem = {
346
+ file: createMockFile(),
347
+ status: 'uploaded',
348
+ };
349
+ page.rootInstance.displayedFiles = [fileItem];
350
+ const clickHandler = page.rootInstance.getClickHandlerToRemoveFileItem(fileItem.file.name);
351
+ clickHandler();
352
+ expect(page.rootInstance.displayedFiles[0].toBeRemoved).toBeTruthy();
353
+ });
354
+ });
355
+ describe('getFileItemStatusMessage', () => {
356
+ it('returns the correct status message', async () => {
357
+ const page = await setupPage();
358
+ const statusAndResponses = [
359
+ { status: 'invalid-type', response: 'tecton.element.filePicker.unsupportedFileType' },
360
+ { status: 'over-size-limit', response: 'tecton.element.filePicker.sizeExceedsLimit' },
361
+ { status: 'over-max-files-limit', response: 'tecton.element.filePicker.overMaxFilesLimit' },
362
+ { status: 'in-progress', response: 'tecton.element.filePicker.uploadingEllipsis' },
363
+ { status: 'failed', response: 'tecton.element.filePicker.uploadFailed' },
364
+ { status: 'uploaded', response: 'tecton.element.filePicker.fileSize' },
365
+ ];
366
+ const size = 1234;
367
+ statusAndResponses.forEach(({ status, response }) => {
368
+ const result = page.rootInstance.getFileItemStatusMessage(status, size);
369
+ expect(result).toEqual(response);
370
+ });
371
+ });
372
+ });
373
+ describe('grabDroppedFiles', () => {
374
+ it('emits an event that contains a files object', async () => {
375
+ const page = await setupPage();
376
+ const mockFile = createMockFile({ name: 'test-file' });
377
+ const mockFileList = createMockFileList([mockFile]);
378
+ const dropCallback = jest.fn();
379
+ page.root.addEventListener('tctChange', dropCallback);
380
+ const mockDragEvent = {
381
+ dataTransfer: {
382
+ files: mockFileList,
383
+ },
384
+ preventDefault: jest.fn(),
385
+ stopPropagation: jest.fn(),
386
+ };
387
+ page.rootInstance.grabDroppedFiles(mockDragEvent);
388
+ await page.waitForChanges();
389
+ expect(dropCallback).toHaveBeenCalledWith(expect.objectContaining({
390
+ detail: expect.objectContaining({
391
+ invalidFiles: [],
392
+ validFiles: [mockFile],
393
+ }),
394
+ }));
395
+ });
396
+ });
397
+ describe('highlightDropZone', () => {
398
+ it('sets the isDropZoneHighlighted flag to true', async () => {
399
+ const page = await setupPage({ variant: 'browse-drop' });
400
+ const mockDragEvent = {
401
+ preventDefault: jest.fn(),
402
+ stopPropagation: jest.fn(),
403
+ };
404
+ page.rootInstance.highlightDropZone(mockDragEvent);
405
+ await page.waitForChanges();
406
+ expect(page.rootInstance.isDropZoneHighlighted).toBeTruthy();
407
+ });
408
+ });
409
+ describe('launchFileBrowser', () => {
410
+ it('called and clicks hidden file input when browse button clicked', async () => {
411
+ const launchFileBrowserSpy = jest.spyOn(Q2FilePicker.prototype, 'launchFileBrowser');
412
+ const page = await setupPage();
413
+ const input = page.root.shadowRoot.querySelector('[test-id="file-input"]');
414
+ const browseButton = page.root.shadowRoot.querySelector('[test-id="browse-button"]');
415
+ const clickCallback = jest.fn();
416
+ input.addEventListener('click', clickCallback);
417
+ browseButton.dispatchEvent(new MouseEvent('click'));
418
+ expect(launchFileBrowserSpy).toHaveBeenCalled();
419
+ expect(clickCallback).toHaveBeenCalled();
420
+ });
421
+ it('called and clicks hidden file input when browse link clicked', async () => {
422
+ const launchFileBrowserSpy = jest.spyOn(Q2FilePicker.prototype, 'launchFileBrowser');
423
+ const page = await setupPage({ variant: 'browse-drop' });
424
+ const input = page.root.shadowRoot.querySelector('[test-id="file-input"]');
425
+ const browseLink = page.root.shadowRoot.querySelector('[test-id="browse-link"]');
426
+ const clickCallback = jest.fn();
427
+ input.addEventListener('click', clickCallback);
428
+ await browseLink.dispatchEvent(new MouseEvent('tctClick'));
429
+ expect(launchFileBrowserSpy).toHaveBeenCalled();
430
+ expect(clickCallback).toHaveBeenCalled();
431
+ });
432
+ });
433
+ });
434
+ });
435
+ //# sourceMappingURL=q2-file-picker-test.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"q2-file-picker-test.spec.js","sourceRoot":"","sources":["../../../../src/components/q2-file-picker/test/q2-file-picker-test.spec.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Q2FilePicker } from '../q2-file-picker';\nimport { objectToHTMLAttributes, setupSpecPageWithLoc } from '@/utils/helpers';\n\ndescribe('q2-legend', () => {\n interface MockFileProps {\n name?: string;\n lastModified?: number;\n webkitRelativePath?: string;\n size?: number;\n type?: string;\n arrayBuffer?: () => Promise<ArrayBuffer>;\n slice?: () => Blob;\n stream?: () => ReadableStream;\n text?: () => Promise<string>;\n bytes?: () => Promise<Uint8Array>;\n }\n\n const buildSlots = (slots: Record<string, string>[]) => {\n return slots.reduce((acc, slot) => {\n return `${acc}<div slot=\"${slot.name}\">${slot.content}</div>`;\n }, '');\n };\n\n const setupPage = async (attributes = {}, testStrings = {}, slots = []) => {\n const attributesString = objectToHTMLAttributes(attributes);\n const slotsString = buildSlots(slots);\n\n const page = await setupSpecPageWithLoc(\n {\n components: [Q2FilePicker],\n html: `<q2-file-picker ${attributesString}>${slotsString}</q2-file-picker>`,\n },\n testStrings\n );\n\n return page;\n };\n\n const createMockFile = (props: MockFileProps = {}) => {\n return {\n name: props.name || 'test-file',\n lastModified: props.lastModified || Date.now(),\n webkitRelativePath: props.webkitRelativePath || '',\n size: props.size || 1234,\n type: props.type || 'text/plain', // 'application/pdf'\n arrayBuffer: props.arrayBuffer || jest.fn(),\n slice: props.slice || jest.fn(),\n stream: props.stream || jest.fn(),\n text: props.text || jest.fn(),\n bytes: props.bytes || jest.fn(() => Promise.resolve(new Uint8Array())),\n };\n };\n\n const createMockFileList = (files: File[]) => {\n return {\n ...files,\n length: files.length,\n item: (index: number) => files[index],\n };\n };\n\n function simulateFileInputChange(page, mockFileList) {\n const input = page.root.shadowRoot.querySelector('[test-id=\"file-input\"]') as HTMLInputElement;\n const changeCallback = jest.fn();\n page.root.addEventListener('tctChange', changeCallback);\n input.files = mockFileList;\n input.dispatchEvent(new Event('change'));\n\n return changeCallback;\n }\n\n describe('Props', () => {\n describe('description', () => {\n it('when set description rendered', async () => {\n const descriptionText = 'Test Description';\n const page = await setupPage({ description: descriptionText });\n const description = page.root.shadowRoot.querySelector('[test-id=\"description\"]');\n\n expect(description).toEqualText(descriptionText);\n });\n\n it('is localizable', async () => {\n const descriptionText = 'Test Description';\n const page = await setupPage(\n { description: 'test.description' },\n { 'test.description': descriptionText }\n );\n const description = page.root.shadowRoot.querySelector('[test-id=\"description\"]');\n\n expect(description).toEqualText(descriptionText);\n });\n });\n\n describe('fileTypes', () => {\n it('limits the types of files that can be selected', async () => {\n const page = await setupPage();\n page.root.fileTypes = ['pdf'];\n const mockPdfFile = createMockFile({ name: 'test-file.pdf' });\n const mockTextFile = createMockFile({ name: 'test-file.txt' });\n const mockFileList = createMockFileList([mockPdfFile, mockTextFile]);\n const changeCallback = simulateFileInputChange(page, mockFileList);\n await page.waitForChanges();\n const value = page.root.value;\n const expectedValue = {\n invalidFiles: [{ file: mockTextFile, status: 'invalid-type' }],\n validFiles: [mockPdfFile],\n };\n\n expect(changeCallback).toHaveBeenCalledWith(\n expect.objectContaining({\n detail: expect.objectContaining(expectedValue),\n })\n );\n expect(value).toEqual(expectedValue);\n });\n\n it('allows all file types when fileTypes is not defined', async () => {\n const page = await setupPage();\n const mockPdfFile = createMockFile({ name: 'test-file.pdf' });\n const mockTextFile = createMockFile({ name: 'test-file.txt' });\n const mockFileList = createMockFileList([mockPdfFile, mockTextFile]);\n const changeCallback = simulateFileInputChange(page, mockFileList);\n await page.waitForChanges();\n const value = page.root.value;\n const expectedValue = {\n invalidFiles: [],\n validFiles: [mockPdfFile, mockTextFile],\n };\n\n expect(changeCallback).toHaveBeenCalledWith(\n expect.objectContaining({\n detail: expect.objectContaining(expectedValue),\n })\n );\n expect(value).toEqual(expectedValue);\n });\n });\n\n describe('label', () => {\n it('when set label rendered', async () => {\n const labelText = 'Test Label';\n const page = await setupPage({ label: labelText });\n const label = page.root.shadowRoot.querySelector('[test-id=\"label\"]');\n\n expect(label).toEqualText(labelText);\n });\n\n it('is localizable', async () => {\n const labelText = 'Test Label';\n const page = await setupPage({ label: 'test.label' }, { 'test.label': labelText });\n const label = page.root.shadowRoot.querySelector('[test-id=\"label\"]');\n\n expect(label).toEqualText(labelText);\n });\n });\n\n describe('maxFiles', () => {\n it('limits the number of files that can be selected', async () => {\n const page = await setupPage({ 'max-files': 0 });\n const mockPdfFile = createMockFile({ name: 'test-file.pdf', type: 'application/pdf' });\n const mockFileList = createMockFileList([mockPdfFile]);\n const changeCallback = simulateFileInputChange(page, mockFileList);\n await page.waitForChanges();\n const value = page.root.value;\n const expectedValue = {\n invalidFiles: [{ file: mockPdfFile, status: 'over-max-files-limit' }],\n validFiles: [],\n };\n\n expect(changeCallback).toHaveBeenCalledWith(\n expect.objectContaining({\n detail: expect.objectContaining(expectedValue),\n })\n );\n expect(value).toEqual(expectedValue);\n });\n\n it('allows multiple files to be selected when it is greater than 1', async () => {\n const page = await setupPage({ maxFiles: 2 });\n const mockFile = createMockFile({ name: 'test-file' });\n const mockFile2 = { ...mockFile, name: 'test-file-2' };\n const mockFileListMultiple = createMockFileList([mockFile, mockFile2]);\n const changeCallback = simulateFileInputChange(page, mockFileListMultiple);\n await page.waitForChanges();\n const value = page.root.value;\n const expectedValue = {\n invalidFiles: [],\n validFiles: [mockFile, mockFile2],\n };\n\n expect(changeCallback).toHaveBeenCalledWith(\n expect.objectContaining({\n detail: expect.objectContaining(expectedValue),\n })\n );\n expect(value).toEqual(expectedValue);\n });\n\n it('allows any number of files to be selected when it is not set', async () => {\n const page = await setupPage();\n const mockFile = createMockFile({ name: 'test-file' });\n const mockFile2 = { ...mockFile, name: 'test-file-2' };\n const mockFile3 = { ...mockFile, name: 'test-file-3' };\n const mockFileListMultiple = createMockFileList([mockFile, mockFile2, mockFile3]);\n const changeCallback = simulateFileInputChange(page, mockFileListMultiple);\n await page.waitForChanges();\n const value = page.root.value;\n const expectedValue = {\n invalidFiles: [],\n validFiles: [mockFile, mockFile2, mockFile3],\n };\n\n expect(changeCallback).toHaveBeenCalledWith(\n expect.objectContaining({\n detail: expect.objectContaining(expectedValue),\n })\n );\n expect(value).toEqual(expectedValue);\n });\n });\n\n describe('maxFileSize', () => {\n it('limits the size of files that can be selected', async () => {\n const page = await setupPage({ 'max-file-size': 2000 });\n const mockFile = createMockFile({ name: 'test-file', size: 1000 });\n const mockFileTooLarge = createMockFile({ name: 'test-file-2', size: 3000 });\n const mockFileList = createMockFileList([mockFile, mockFileTooLarge]);\n const changeCallback = simulateFileInputChange(page, mockFileList);\n await page.waitForChanges();\n const value = page.root.value;\n const expectedValue = {\n invalidFiles: [{ file: mockFileTooLarge, status: 'over-size-limit' }],\n validFiles: [mockFile],\n };\n\n expect(changeCallback).toHaveBeenCalledWith(\n expect.objectContaining({\n detail: expect.objectContaining(expectedValue),\n })\n );\n expect(value).toEqual(expectedValue);\n });\n });\n\n describe('value', () => {\n it('returns an object with empty arrays for prop values when no files have been selected', async () => {\n const page = await setupPage();\n const value = page.root.value;\n const expectedValue = {\n invalidFiles: [],\n validFiles: [],\n };\n\n expect(value).toEqual(expectedValue);\n });\n\n it('returns an object with the selected files when files have been selected', async () => {\n const page = await setupPage();\n const mockFile = createMockFile({ name: 'test-file' });\n const mockFileList = createMockFileList([mockFile]);\n simulateFileInputChange(page, mockFileList);\n await page.waitForChanges();\n const value = page.root.value;\n const expectedValue = {\n invalidFiles: [],\n validFiles: [mockFile],\n };\n\n expect(value).toEqual(expectedValue);\n });\n\n it('returns an object with the valid and invalid files when files have been selected', async () => {\n const page = await setupPage();\n page.root.fileTypes = ['pdf'];\n const mockPdfFile = createMockFile({ name: 'test-file.pdf', type: 'application/pdf' });\n const mockTextFile = createMockFile({ name: 'test-file.txt' });\n const mockFileList = createMockFileList([mockPdfFile, mockTextFile]);\n simulateFileInputChange(page, mockFileList);\n await page.waitForChanges();\n const value = page.root.value;\n const expectedValue = {\n invalidFiles: [{ file: mockTextFile, status: 'invalid-type' }],\n validFiles: [mockPdfFile],\n };\n\n expect(value).toEqual(expectedValue);\n });\n });\n\n describe('variant', () => {\n it('when set to \"browse-drop\" displays drop zone', async () => {\n const page = await setupPage({ variant: 'browse-drop' });\n const dropZone = page.root.shadowRoot.querySelector('[test-id=\"drop-zone\"]');\n const browseButton = page.root.shadowRoot.querySelector('[test-id=\"browse-button\"]');\n\n expect(dropZone).not.toBeNull();\n expect(browseButton).toBeNull();\n });\n\n it('when set to \"browse\" displays only the browse button', async () => {\n const page = await setupPage({ variant: 'browse' });\n const dropZone = page.root.shadowRoot.querySelector('[test-id=\"drop-zone\"]');\n const browseButton = page.root.shadowRoot.querySelector('[test-id=\"browse\"]');\n\n expect(dropZone).toBeNull();\n expect(browseButton).not.toBeNull();\n });\n });\n });\n\n describe('Slots', () => {\n describe('label', () => {\n it('rendered when slot is provided', async () => {\n const labelSlotContent = 'Test Label Slot';\n const page = await setupPage({}, {}, [{ name: 'label', content: labelSlotContent }]);\n const label = page.root.shadowRoot.querySelector('[test-id=\"label\"]');\n\n // check for the slot container without the slot content because\n // newSpecPage appears to not render the slot content\n expect(label.innerHTML).toEqualHtml('<slot name=\"label\"></slot>');\n });\n\n it('not rendered when slot is provided and label prop set', async () => {\n const labelText = 'Test Label';\n const labelSlotContent = 'Test Label Slot';\n const page = await setupPage({ label: labelText }, {}, [{ name: 'label', content: labelSlotContent }]);\n const label = page.root.shadowRoot.querySelector('[test-id=\"label\"]');\n\n expect(label.innerHTML).toEqualHtml(labelText);\n });\n });\n\n describe('description', () => {\n it('rendered when slot is provided', async () => {\n const descriptionSlotContent = 'Test Description Slot';\n const page = await setupPage({}, {}, [{ name: 'description', content: descriptionSlotContent }]);\n const description = page.root.shadowRoot.querySelector('[test-id=\"description\"]');\n\n // check for the slot container without the slot content because\n // newSpecPage appears to not render the slot content\n expect(description.innerHTML).toEqualHtml('<slot name=\"description\"></slot>');\n });\n\n it('not rendered when slot is provided and label prop set', async () => {\n const descriptionText = 'Test Description';\n const descriptionSlotContent = 'Test Description Slot';\n const page = await setupPage({ description: descriptionText }, {}, [\n { name: 'description', content: descriptionSlotContent },\n ]);\n const label = page.root.shadowRoot.querySelector('[test-id=\"description\"]');\n\n expect(label.innerHTML).toEqualHtml(descriptionText);\n });\n });\n });\n\n describe('Events', () => {\n describe('tctChange', () => {\n it('emitted when a file input emits a change event', async () => {\n const page = await setupPage();\n const mockFile = createMockFile({ name: 'test-file' });\n const mockFileList = createMockFileList([mockFile]);\n const changeCallback = simulateFileInputChange(page, mockFileList);\n await page.waitForChanges();\n const expectedValue = {\n invalidFiles: [],\n validFiles: [mockFile],\n };\n\n expect(changeCallback).toHaveBeenCalledWith(\n expect.objectContaining({\n detail: expect.objectContaining(expectedValue),\n })\n );\n });\n });\n });\n\n describe('Watchers', () => {\n describe('updateFileList', () => {\n it('sets the status of a queued file when the status prop changes', async () => {\n const page = await setupPage();\n const mockFile = createMockFile({ name: 'test-file' });\n page.rootInstance.queuedFiles = [mockFile];\n page.rootInstance.updateFileList([{ name: 'test-file', status: 'uploaded' }]);\n await page.waitForChanges();\n\n expect(page.rootInstance.displayedFiles).toEqual([{ file: mockFile, status: 'uploaded' }]);\n });\n\n it('sets the status of a displayed file when the status prop changes', async () => {\n const page = await setupPage();\n const mockFile = createMockFile({ name: 'test-file' });\n page.rootInstance.queuedFiles = [];\n page.rootInstance.displayedFiles = [{ file: mockFile, status: 'queued' }];\n page.rootInstance.updateFileList([{ name: 'test-file', status: 'uploaded' }]);\n await page.waitForChanges();\n\n expect(page.rootInstance.displayedFiles).toEqual([{ file: mockFile, status: 'uploaded' }]);\n });\n });\n });\n\n describe('Local methods', () => {\n describe('disableLoaderIfAllFilesUploaded', () => {\n it('sets the areFilesUploading flag to false when all files are uploaded', async () => {\n const page = await setupPage();\n const mockFile = createMockFile({ name: 'test-file' });\n page.rootInstance.areFilesUploading = true;\n page.rootInstance.displayedFiles = [{ file: mockFile, status: 'uploaded' }];\n page.rootInstance.disableLoaderIfAllFilesUploaded();\n await page.waitForChanges();\n\n expect(page.rootInstance.areFilesUploading).toBeFalsy();\n });\n });\n\n describe('getAnimationendHandlerToRemoveFileItem', () => {\n it('returns a function that removes a file after animation has ended', async () => {\n const page = await setupPage();\n const fileItem = {\n file: createMockFile(),\n status: 'uploaded',\n };\n page.rootInstance.displayedFiles = [fileItem];\n const animationEndHandler = page.rootInstance.getAnimationendHandlerToRemoveFileItem(\n fileItem.file.name\n );\n const mockAnimationEvent = {\n animationName: 'shrinkToCenterFadeOut',\n } as AnimationEvent;\n animationEndHandler(mockAnimationEvent);\n\n expect(page.rootInstance.displayedFiles.length).toEqual(0);\n });\n });\n\n describe('getClickHandlerToRemoveFileItem', () => {\n it('returns a function that flags the file as to be removed', async () => {\n const page = await setupPage();\n const fileItem = {\n file: createMockFile(),\n status: 'uploaded',\n };\n page.rootInstance.displayedFiles = [fileItem];\n const clickHandler = page.rootInstance.getClickHandlerToRemoveFileItem(fileItem.file.name);\n clickHandler();\n\n expect(page.rootInstance.displayedFiles[0].toBeRemoved).toBeTruthy();\n });\n });\n\n describe('getFileItemStatusMessage', () => {\n it('returns the correct status message', async () => {\n const page = await setupPage();\n\n const statusAndResponses = [\n { status: 'invalid-type', response: 'tecton.element.filePicker.unsupportedFileType' },\n { status: 'over-size-limit', response: 'tecton.element.filePicker.sizeExceedsLimit' },\n { status: 'over-max-files-limit', response: 'tecton.element.filePicker.overMaxFilesLimit' },\n { status: 'in-progress', response: 'tecton.element.filePicker.uploadingEllipsis' },\n { status: 'failed', response: 'tecton.element.filePicker.uploadFailed' },\n { status: 'uploaded', response: 'tecton.element.filePicker.fileSize' },\n ];\n const size = 1234;\n\n statusAndResponses.forEach(({ status, response }) => {\n const result = page.rootInstance.getFileItemStatusMessage(status, size);\n\n expect(result).toEqual(response);\n });\n });\n });\n\n describe('grabDroppedFiles', () => {\n it('emits an event that contains a files object', async () => {\n const page = await setupPage();\n const mockFile = createMockFile({ name: 'test-file' });\n const mockFileList = createMockFileList([mockFile]);\n const dropCallback = jest.fn();\n page.root.addEventListener('tctChange', dropCallback);\n const mockDragEvent = {\n dataTransfer: {\n files: mockFileList,\n },\n preventDefault: jest.fn(),\n stopPropagation: jest.fn(),\n } as unknown as DragEvent;\n page.rootInstance.grabDroppedFiles(mockDragEvent);\n await page.waitForChanges();\n\n expect(dropCallback).toHaveBeenCalledWith(\n expect.objectContaining({\n detail: expect.objectContaining({\n invalidFiles: [],\n validFiles: [mockFile],\n }),\n })\n );\n });\n });\n\n describe('highlightDropZone', () => {\n it('sets the isDropZoneHighlighted flag to true', async () => {\n const page = await setupPage({ variant: 'browse-drop' });\n const mockDragEvent = {\n preventDefault: jest.fn(),\n stopPropagation: jest.fn(),\n } as unknown as DragEvent;\n page.rootInstance.highlightDropZone(mockDragEvent);\n await page.waitForChanges();\n\n expect(page.rootInstance.isDropZoneHighlighted).toBeTruthy();\n });\n });\n\n describe('launchFileBrowser', () => {\n it('called and clicks hidden file input when browse button clicked', async () => {\n const launchFileBrowserSpy = jest.spyOn(Q2FilePicker.prototype, 'launchFileBrowser');\n const page = await setupPage();\n const input = page.root.shadowRoot.querySelector('[test-id=\"file-input\"]');\n const browseButton = page.root.shadowRoot.querySelector('[test-id=\"browse-button\"]');\n const clickCallback = jest.fn();\n input.addEventListener('click', clickCallback);\n browseButton.dispatchEvent(new MouseEvent('click'));\n\n expect(launchFileBrowserSpy).toHaveBeenCalled();\n expect(clickCallback).toHaveBeenCalled();\n });\n\n it('called and clicks hidden file input when browse link clicked', async () => {\n const launchFileBrowserSpy = jest.spyOn(Q2FilePicker.prototype, 'launchFileBrowser');\n const page = await setupPage({ variant: 'browse-drop' });\n const input = page.root.shadowRoot.querySelector('[test-id=\"file-input\"]');\n const browseLink = page.root.shadowRoot.querySelector('[test-id=\"browse-link\"]');\n const clickCallback = jest.fn();\n input.addEventListener('click', clickCallback);\n await browseLink.dispatchEvent(new MouseEvent('tctClick'));\n\n expect(launchFileBrowserSpy).toHaveBeenCalled();\n expect(clickCallback).toHaveBeenCalled();\n });\n });\n });\n});\n"]}
@@ -135,6 +135,9 @@ button {
135
135
  :host {
136
136
  display: block;
137
137
  }
138
+ :host .item {
139
+ --comp-border-radius: var(--tct-item-border-radius, var(--app-border-radius-0, 0));
140
+ }
138
141
 
139
142
  :host([clickable]) {
140
143
  cursor: pointer;
@@ -167,4 +167,10 @@ button {
167
167
  font-size: var(--tct-list-label-font-size, var(--app-font-size, 14px));
168
168
  font-weight: var(--tct-list-label-font-weight, 600);
169
169
  color: var(--tct-list-label-font-color, var(--t-text, #4d4d4d));
170
+ }
171
+
172
+ slot:not([name]) {
173
+ display: flex;
174
+ flex-direction: column;
175
+ gap: var(--tct-list-item-gap, 0);
170
176
  }
@@ -26,6 +26,7 @@ export class Q2Pill {
26
26
  };
27
27
  this.executeActionSheet = async (event) => {
28
28
  const result = await showActionSheetList(this, event);
29
+ this.primaryBtn.focus();
29
30
  this.handleSelectionChanges(result);
30
31
  };
31
32
  this.getOption = async (value) => {
@@ -37,9 +38,12 @@ export class Q2Pill {
37
38
  return this.hostElement.querySelector(`q2-option[value="${value}"]`);
38
39
  }
39
40
  };
40
- this.handleButtonFocusout = async (event) => {
41
+ this.handleFocusOut = async (event) => {
42
+ var _a;
41
43
  const relatedTarget = event.relatedTarget;
42
- if ((relatedTarget === null || relatedTarget === void 0 ? void 0 : relatedTarget.tagName) === 'Q2-OPTION')
44
+ if ((_a = this.popoverElement) === null || _a === void 0 ? void 0 : _a.contains(relatedTarget))
45
+ return;
46
+ if (this.hostElement.contains(relatedTarget))
43
47
  return;
44
48
  this.open = false;
45
49
  };
@@ -337,7 +341,7 @@ export class Q2Pill {
337
341
  wrapperClassNames.push('has-icon');
338
342
  if (optionCount)
339
343
  wrapperClassNames.push('has-options');
340
- return (h("click-elsewhere", { key: '2e6401852016f9edeb1e27b8b69335755a7a9202', onChange: this.onClickElsewhere }, h("div", { key: '997b3609f4cbd894fdf412d71624de290558a53c', class: wrapperClassNames.join(' ') }, h("div", { key: '6326d50ba96228f78ccf29f1ac3ec2f88d4d88aa', class: "btn-height-wrapper", ref: el => (this.primaryBtnWrapper = el), onClick: this.handleWrapperClick, tabIndex: -1 }, h("button", { key: 'bf29ea540b04bef1a58c9106b15a0155e8c9f81b', class: "btn-primary", "test-id": "btn-control", type: "button", role: (optionCount && 'combobox') || undefined, ref: el => (this.primaryBtn = el), onClick: this.handleClick, onKeyDown: this.handleKeydown, onFocusout: this.handleButtonFocusout, disabled: this.disabled, "aria-roledescription": !optionCount && 'filter', "aria-controls": (optionCount && 'option-list') || undefined, "aria-expanded": (optionCount && `${!!open}`) || undefined, "aria-label": this.buttonContent, "aria-describedby": (optionCount && 'option-description') || undefined }, this.truncatedButtonContent, !optionCount && active && h("span", { key: '927bcd7ece084b5eb47bea58357f0f3f62d07536', class: "sr" }, "(", loc('tecton.element.pill.active'), ")"))), this.renderIcon(), !!optionCount && this.renderHiddenElement()), this.optionCount > 0 && (h("q2-popover", { key: 'a87ee59b7a7b9b0f4cecb7d74aa71618e50c57ba', ref: el => (this.popoverElement = el), controlElement: this.primaryBtn, open: this.open, "max-height": this.popoverMaxHeight, minHeight: this.popoverMinHeight, direction: this.popoverDirection, align: this.popoverAlignment }, h("div", { key: '3952981f8a3dec4126035529df72e04f59dd3245', class: "popover-content" }, h("div", { key: 'f31e255a8f052cd2d3d1a53506ba51b4fdb936c3', ref: el => (this.popoverTopContainer = el), class: "popover-top-container", tabindex: "-1", hidden: !this.hasPopoverTop, onKeyDown: this.handleKeydown }, h("slot", { key: '18a55b89efe4ca840cbb80c8266c5aa5cdd2c9d8', name: "popover-top" })), h("q2-option-list", { key: '923c991cc3dddc5ad8d8416b488f5c151b215984', type: "listbox", ref: el => (this.optionList = el), id: "option-list", onChange: this.handleChange, multiple: this.multiple, selectedOptions: this.selectedOptions, onReady: () => this.updateSelectedOptionElements(), label: loc('tecton.element.optionList.label', [this.optionListLabel]) }, h("slot", { key: '00d05bcff3be94a8de0dad038f67f9650234ef0f' })), h("div", { key: 'cbbb918f147fe82de2411dba9d7297d18d540c2e', ref: el => (this.popoverBottomContainer = el), class: "popover-bottom-container", tabindex: "-1", hidden: !this.hasPopoverBottom, onKeyDown: this.handleKeydown }, h("slot", { key: 'd327cd4e04931acd87f4889229543d69b3340860', name: "popover-bottom" })))))));
344
+ return (h("click-elsewhere", { key: '65e932df96cd2135dd8340aefea2523e0ac3084c', onChange: this.onClickElsewhere }, h("div", { key: '0c4dfad1705c5f0f72ac03878776bdad4e209fa0', class: wrapperClassNames.join(' ') }, h("div", { key: 'da4d69d59bdbb4609e6638fce7b3abbf53c791e7', class: "btn-height-wrapper", ref: el => (this.primaryBtnWrapper = el), onClick: this.handleWrapperClick, tabIndex: -1 }, h("button", { key: '0d5f3a4984991bb1c47c241d9cf6676d486cd4dd', class: "btn-primary", "test-id": "btn-control", type: "button", role: (optionCount && 'combobox') || undefined, ref: el => (this.primaryBtn = el), onClick: this.handleClick, onKeyDown: this.handleKeydown, onFocusout: this.handleFocusOut, disabled: this.disabled, "aria-roledescription": !optionCount && 'filter', "aria-controls": (optionCount && 'option-list') || undefined, "aria-expanded": (optionCount && `${!!open}`) || undefined, "aria-label": this.buttonContent, "aria-describedby": (optionCount && 'option-description') || undefined }, this.truncatedButtonContent, !optionCount && active && h("span", { key: '18619ff31d265eaa351390a367ef3712dbd9547a', class: "sr" }, "(", loc('tecton.element.pill.active'), ")"))), this.renderIcon(), !!optionCount && this.renderHiddenElement()), this.optionCount > 0 && (h("q2-popover", { key: '02eb90f588ea93c7153bdbaa709eaac678359249', ref: el => (this.popoverElement = el), controlElement: this.primaryBtn, open: this.open, "max-height": this.popoverMaxHeight, minHeight: this.popoverMinHeight, direction: this.popoverDirection, align: this.popoverAlignment, onFocusout: this.handleFocusOut }, h("div", { key: 'eb74c87224cc28e45db944411cc749350c99e77b', class: "popover-content" }, h("div", { key: 'de444989719d4c154f17e484918ee6e206414642', ref: el => (this.popoverTopContainer = el), class: "popover-top-container", tabindex: "-1", hidden: !this.hasPopoverTop, onKeyDown: this.handleKeydown }, h("slot", { key: 'b58a201205c6a3980425db57d551fcd6f01583e0', name: "popover-top" })), h("q2-option-list", { key: '1eb22efce706be5803dc035cedb9232ea1bcbde8', type: "listbox", ref: el => (this.optionList = el), id: "option-list", onChange: this.handleChange, multiple: this.multiple, selectedOptions: this.selectedOptions, onReady: () => this.updateSelectedOptionElements(), label: loc('tecton.element.optionList.label', [this.optionListLabel]) }, h("slot", { key: 'de65981f3e33f12693927e4b5d9510fe751537d6' })), h("div", { key: '1c78d8873df7f63f7e7eab76c3a1a33459d3af4f', ref: el => (this.popoverBottomContainer = el), class: "popover-bottom-container", tabindex: "-1", hidden: !this.hasPopoverBottom, onKeyDown: this.handleKeydown }, h("slot", { key: '8eee76d64492fde1b01fd55f8d3e4ecb099d0b4e', name: "popover-bottom" })))))));
341
345
  }
342
346
  static get is() { return "q2-pill"; }
343
347
  static get encapsulation() { return "shadow"; }