@gitlab/ui 44.1.0 → 46.0.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.
- package/CHANGELOG.md +65 -0
- package/dist/components/base/alert/alert.js +9 -1
- package/dist/components/base/new_dropdowns/base_dropdown/base_dropdown.js +8 -0
- package/dist/components/base/new_dropdowns/listbox/listbox.js +116 -18
- package/dist/utility_classes.css +1 -1
- package/dist/utility_classes.css.map +1 -1
- package/package.json +2 -2
- package/src/components/base/alert/alert.spec.js +13 -14
- package/src/components/base/alert/alert.vue +14 -1
- package/src/components/base/banner/banner.spec.js +4 -4
- package/src/components/base/datepicker/datepicker.spec.js +1 -1
- package/src/components/base/daterange_picker/daterange_picker.spec.js +4 -4
- package/src/components/base/drawer/drawer.spec.js +2 -2
- package/src/components/base/dropdown/dropdown.spec.js +5 -5
- package/src/components/base/filtered_search/filtered_search.spec.js +4 -4
- package/src/components/base/filtered_search/filtered_search_token.spec.js +9 -9
- package/src/components/base/filtered_search/filtered_search_token_segment.spec.js +12 -12
- package/src/components/base/form/form_textarea/form_textarea.spec.js +2 -2
- package/src/components/base/infinite_scroll/infinite_scroll.spec.js +6 -6
- package/src/components/base/label/label.spec.js +5 -5
- package/src/components/base/modal/modal.spec.js +1 -1
- package/src/components/base/nav/nav.spec.js +1 -1
- package/src/components/base/nav/nav_item_dropdown.spec.js +3 -3
- package/src/components/base/new_dropdowns/base_dropdown/base_dropdown.vue +6 -0
- package/src/components/base/new_dropdowns/listbox/listbox.md +22 -0
- package/src/components/base/new_dropdowns/listbox/listbox.spec.js +101 -7
- package/src/components/base/new_dropdowns/listbox/listbox.stories.js +244 -20
- package/src/components/base/new_dropdowns/listbox/listbox.vue +138 -12
- package/src/components/base/paginated_list/paginated_list.spec.js +1 -1
- package/src/components/base/pagination/pagination.spec.js +2 -2
- package/src/components/base/search_box_by_click/search_box_by_click.spec.js +7 -7
- package/src/components/base/search_box_by_type/search_box_by_type.spec.js +2 -2
- package/src/components/base/sorting/sorting.spec.js +1 -1
- package/src/components/base/sorting/sorting_item.spec.js +2 -2
- package/src/components/base/tabs/tabs/scrollable_tabs.spec.js +1 -1
- package/src/components/base/tabs/tabs/tabs.spec.js +6 -6
- package/src/components/base/token/token.spec.js +1 -1
- package/src/components/base/token_selector/token_container.spec.js +1 -1
- package/src/components/base/token_selector/token_selector.spec.js +4 -4
- package/src/components/base/token_selector/token_selector_dropdown.spec.js +1 -1
- package/src/components/charts/column/column_chart.spec.js +1 -1
- package/src/components/charts/sparkline/sparkline.spec.js +2 -2
- package/src/directives/resize_observer/resize_observer.spec.js +5 -5
- package/src/scss/utilities.scss +0 -202
- package/src/scss/utility-mixins/display.scss +0 -35
- package/src/scss/utility-mixins/flex.scss +0 -7
- package/src/scss/utility-mixins/spacing.scss +0 -91
|
@@ -15,6 +15,8 @@ import {
|
|
|
15
15
|
buttonSizeOptions,
|
|
16
16
|
dropdownVariantOptions,
|
|
17
17
|
} from '../../../../utils/constants';
|
|
18
|
+
import GlLoadingIcon from '../../loading_icon/loading_icon.vue';
|
|
19
|
+
import GlSearchBoxByType from '../../search_box_by_type/search_box_by_type.vue';
|
|
18
20
|
import GlBaseDropdown from '../base_dropdown/base_dropdown.vue';
|
|
19
21
|
import GlListboxItem from './listbox_item.vue';
|
|
20
22
|
import GlListboxGroup from './listbox_group.vue';
|
|
@@ -22,6 +24,7 @@ import { isOption, itemsValidator, flattenedOptions } from './utils';
|
|
|
22
24
|
|
|
23
25
|
export const ITEM_SELECTOR = '[role="option"]';
|
|
24
26
|
const GROUP_TOP_BORDER_CLASSES = ['gl-border-t', 'gl-pt-3', 'gl-mt-3'];
|
|
27
|
+
export const SEARCH_INPUT_SELECTOR = '.gl-search-box-by-type-input';
|
|
25
28
|
|
|
26
29
|
export default {
|
|
27
30
|
events: {
|
|
@@ -32,6 +35,8 @@ export default {
|
|
|
32
35
|
GlBaseDropdown,
|
|
33
36
|
GlListboxItem,
|
|
34
37
|
GlListboxGroup,
|
|
38
|
+
GlSearchBoxByType,
|
|
39
|
+
GlLoadingIcon,
|
|
35
40
|
},
|
|
36
41
|
model: {
|
|
37
42
|
prop: 'selected',
|
|
@@ -124,6 +129,7 @@ export default {
|
|
|
124
129
|
},
|
|
125
130
|
/**
|
|
126
131
|
* Set to "true" when dropdown content (items) is loading
|
|
132
|
+
* It will render a small loader in the dropdown toggle and make it disabled
|
|
127
133
|
*/
|
|
128
134
|
loading: {
|
|
129
135
|
type: Boolean,
|
|
@@ -164,18 +170,55 @@ export default {
|
|
|
164
170
|
},
|
|
165
171
|
/**
|
|
166
172
|
* The `aria-labelledby` attribute value for the toggle button
|
|
173
|
+
* Provide the string of ids seperated by space
|
|
167
174
|
*/
|
|
168
|
-
|
|
175
|
+
toggleAriaLabelledBy: {
|
|
169
176
|
type: String,
|
|
170
177
|
required: false,
|
|
171
178
|
default: null,
|
|
172
179
|
},
|
|
180
|
+
/**
|
|
181
|
+
* The `aria-labelledby` attribute value for the list of options
|
|
182
|
+
* Provide the string of ids seperated by space
|
|
183
|
+
*/
|
|
184
|
+
listAriaLabelledBy: {
|
|
185
|
+
type: String,
|
|
186
|
+
required: false,
|
|
187
|
+
default: null,
|
|
188
|
+
},
|
|
189
|
+
/**
|
|
190
|
+
* Enable search
|
|
191
|
+
*/
|
|
192
|
+
searchable: {
|
|
193
|
+
type: Boolean,
|
|
194
|
+
required: false,
|
|
195
|
+
default: false,
|
|
196
|
+
},
|
|
197
|
+
/**
|
|
198
|
+
* Set to "true" when items search is in progress.
|
|
199
|
+
* It will display loading icon below the search input
|
|
200
|
+
*/
|
|
201
|
+
searching: {
|
|
202
|
+
type: Boolean,
|
|
203
|
+
required: false,
|
|
204
|
+
default: false,
|
|
205
|
+
},
|
|
206
|
+
/**
|
|
207
|
+
* Message to be displayed when filtering produced no results
|
|
208
|
+
*/
|
|
209
|
+
noResultsText: {
|
|
210
|
+
type: String,
|
|
211
|
+
required: false,
|
|
212
|
+
default: 'No results found',
|
|
213
|
+
},
|
|
173
214
|
},
|
|
174
215
|
data() {
|
|
175
216
|
return {
|
|
176
217
|
selectedValues: [],
|
|
177
218
|
toggleId: uniqueId('dropdown-toggle-btn-'),
|
|
219
|
+
listboxId: uniqueId('listbox-'),
|
|
178
220
|
nextFocusedItemIndex: null,
|
|
221
|
+
searchStr: '',
|
|
179
222
|
};
|
|
180
223
|
},
|
|
181
224
|
computed: {
|
|
@@ -201,6 +244,17 @@ export default {
|
|
|
201
244
|
.map((selected) => this.flattenedOptions.findIndex(({ value }) => value === selected))
|
|
202
245
|
.sort();
|
|
203
246
|
},
|
|
247
|
+
showList() {
|
|
248
|
+
return this.flattenedOptions.length && !this.searching;
|
|
249
|
+
},
|
|
250
|
+
showNoResultsText() {
|
|
251
|
+
return !this.flattenedOptions.length && !this.searching;
|
|
252
|
+
},
|
|
253
|
+
announceSRSearchResults() {
|
|
254
|
+
return (
|
|
255
|
+
this.searchable && !this.showNoResultsText && this.$scopedSlots['search-summary-sr-only']
|
|
256
|
+
);
|
|
257
|
+
},
|
|
204
258
|
},
|
|
205
259
|
watch: {
|
|
206
260
|
selected: {
|
|
@@ -218,12 +272,22 @@ export default {
|
|
|
218
272
|
},
|
|
219
273
|
},
|
|
220
274
|
methods: {
|
|
275
|
+
open() {
|
|
276
|
+
this.$refs.baseDropdown.open();
|
|
277
|
+
},
|
|
278
|
+
close() {
|
|
279
|
+
this.$refs.baseDropdown.close();
|
|
280
|
+
},
|
|
221
281
|
groupClasses(index) {
|
|
222
282
|
return index === 0 ? null : GROUP_TOP_BORDER_CLASSES;
|
|
223
283
|
},
|
|
224
284
|
onShow() {
|
|
225
285
|
this.$nextTick(() => {
|
|
226
|
-
|
|
286
|
+
if (this.searchable) {
|
|
287
|
+
this.focusSearchInput();
|
|
288
|
+
} else {
|
|
289
|
+
this.focusItem(this.selectedIndices[0] ?? 0, this.getFocusableListItemElements());
|
|
290
|
+
}
|
|
227
291
|
/**
|
|
228
292
|
* Emitted when dropdown is shown
|
|
229
293
|
*
|
|
@@ -242,21 +306,33 @@ export default {
|
|
|
242
306
|
this.nextFocusedItemIndex = null;
|
|
243
307
|
},
|
|
244
308
|
onKeydown(event) {
|
|
245
|
-
const { code } = event;
|
|
309
|
+
const { code, target } = event;
|
|
246
310
|
const elements = this.getFocusableListItemElements();
|
|
247
311
|
|
|
248
312
|
if (elements.length < 1) return;
|
|
249
313
|
|
|
250
314
|
let stop = true;
|
|
315
|
+
const isSearchInput = target.matches(SEARCH_INPUT_SELECTOR);
|
|
251
316
|
|
|
252
317
|
if (code === HOME) {
|
|
253
318
|
this.focusItem(0, elements);
|
|
254
319
|
} else if (code === END) {
|
|
255
320
|
this.focusItem(elements.length - 1, elements);
|
|
256
321
|
} else if (code === ARROW_UP) {
|
|
257
|
-
|
|
322
|
+
if (isSearchInput) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
if (this.searchable && elements.indexOf(target) === 0) {
|
|
326
|
+
this.focusSearchInput();
|
|
327
|
+
} else {
|
|
328
|
+
this.focusNextItem(event, elements, -1);
|
|
329
|
+
}
|
|
258
330
|
} else if (code === ARROW_DOWN) {
|
|
259
|
-
|
|
331
|
+
if (isSearchInput) {
|
|
332
|
+
this.focusItem(0, elements);
|
|
333
|
+
} else {
|
|
334
|
+
this.focusNextItem(event, elements, 1);
|
|
335
|
+
}
|
|
260
336
|
} else {
|
|
261
337
|
stop = false;
|
|
262
338
|
}
|
|
@@ -266,8 +342,8 @@ export default {
|
|
|
266
342
|
}
|
|
267
343
|
},
|
|
268
344
|
getFocusableListItemElements() {
|
|
269
|
-
const items = this.$refs.list
|
|
270
|
-
return Array.from(items);
|
|
345
|
+
const items = this.$refs.list?.querySelectorAll(ITEM_SELECTOR);
|
|
346
|
+
return Array.from(items || []);
|
|
271
347
|
},
|
|
272
348
|
focusNextItem(event, elements, offset) {
|
|
273
349
|
const { target } = event;
|
|
@@ -283,11 +359,14 @@ export default {
|
|
|
283
359
|
elements[index]?.focus();
|
|
284
360
|
});
|
|
285
361
|
},
|
|
286
|
-
|
|
362
|
+
focusSearchInput() {
|
|
363
|
+
this.$refs.searchBox.focusInput();
|
|
364
|
+
},
|
|
365
|
+
onSelect(item, isSelected) {
|
|
287
366
|
if (this.multiple) {
|
|
288
|
-
this.onMultiSelect(value, isSelected);
|
|
367
|
+
this.onMultiSelect(item.value, isSelected);
|
|
289
368
|
} else {
|
|
290
|
-
this.onSingleSelect(value, isSelected);
|
|
369
|
+
this.onSingleSelect(item.value, isSelected);
|
|
291
370
|
}
|
|
292
371
|
},
|
|
293
372
|
isSelected(item) {
|
|
@@ -318,6 +397,15 @@ export default {
|
|
|
318
397
|
);
|
|
319
398
|
}
|
|
320
399
|
},
|
|
400
|
+
search(searchTerm) {
|
|
401
|
+
/**
|
|
402
|
+
* Emitted when the search query string is changed
|
|
403
|
+
*
|
|
404
|
+
* @event search
|
|
405
|
+
* @type {string}
|
|
406
|
+
*/
|
|
407
|
+
this.$emit('search', searchTerm);
|
|
408
|
+
},
|
|
321
409
|
isOption,
|
|
322
410
|
},
|
|
323
411
|
};
|
|
@@ -327,7 +415,7 @@ export default {
|
|
|
327
415
|
<gl-base-dropdown
|
|
328
416
|
ref="baseDropdown"
|
|
329
417
|
aria-haspopup="listbox"
|
|
330
|
-
:aria-labelledby="
|
|
418
|
+
:aria-labelledby="toggleAriaLabelledBy"
|
|
331
419
|
:toggle-id="toggleId"
|
|
332
420
|
:toggle-text="listboxToggleText"
|
|
333
421
|
:toggle-class="toggleClass"
|
|
@@ -346,10 +434,29 @@ export default {
|
|
|
346
434
|
<!-- @slot Content to display in dropdown header -->
|
|
347
435
|
<slot name="header"></slot>
|
|
348
436
|
|
|
437
|
+
<div v-if="searchable" class="gl-border-b-1 gl-border-b-solid gl-border-b-gray-200">
|
|
438
|
+
<gl-search-box-by-type
|
|
439
|
+
ref="searchBox"
|
|
440
|
+
v-model="searchStr"
|
|
441
|
+
:aria-owns="listboxId"
|
|
442
|
+
data-testid="listbox-search-input"
|
|
443
|
+
@input="search"
|
|
444
|
+
@keydown="onKeydown"
|
|
445
|
+
/>
|
|
446
|
+
<gl-loading-icon
|
|
447
|
+
v-if="searching"
|
|
448
|
+
data-testid="listbox-search-loader"
|
|
449
|
+
size="md"
|
|
450
|
+
class="gl-my-3"
|
|
451
|
+
/>
|
|
452
|
+
</div>
|
|
453
|
+
|
|
349
454
|
<component
|
|
350
455
|
:is="listboxTag"
|
|
456
|
+
v-if="showList"
|
|
457
|
+
id="listbox"
|
|
351
458
|
ref="list"
|
|
352
|
-
:aria-labelledby="toggleId"
|
|
459
|
+
:aria-labelledby="listAriaLabelledBy || toggleId"
|
|
353
460
|
role="listbox"
|
|
354
461
|
class="gl-new-dropdown-contents gl-list-style-none gl-pl-0 gl-mb-0"
|
|
355
462
|
tabindex="-1"
|
|
@@ -395,6 +502,25 @@ export default {
|
|
|
395
502
|
</template>
|
|
396
503
|
</template>
|
|
397
504
|
</component>
|
|
505
|
+
|
|
506
|
+
<span
|
|
507
|
+
v-if="announceSRSearchResults"
|
|
508
|
+
data-testid="listbox-number-of-results"
|
|
509
|
+
class="gl-sr-only"
|
|
510
|
+
aria-live="assertive"
|
|
511
|
+
>
|
|
512
|
+
<!-- @slot Text read by screen reader announcing a number of search results -->
|
|
513
|
+
<slot name="search-summary-sr-only"></slot>
|
|
514
|
+
</span>
|
|
515
|
+
|
|
516
|
+
<div
|
|
517
|
+
v-else-if="showNoResultsText"
|
|
518
|
+
aria-live="assertive"
|
|
519
|
+
class="gl-pl-7 gl-pr-5 gl-pt-3 gl-font-base gl-text-gray-600"
|
|
520
|
+
data-testid="listbox-no-results-text"
|
|
521
|
+
>
|
|
522
|
+
{{ noResultsText }}
|
|
523
|
+
</div>
|
|
398
524
|
<!-- @slot Content to display in dropdown footer -->
|
|
399
525
|
<slot name="footer"></slot>
|
|
400
526
|
</gl-base-dropdown>
|
|
@@ -161,7 +161,7 @@ describe('Paginated List', () => {
|
|
|
161
161
|
it('has search enabled by default', () => {
|
|
162
162
|
createComponent();
|
|
163
163
|
|
|
164
|
-
expect(wrapper.findComponent(GlSearchBoxByType).exists()).
|
|
164
|
+
expect(wrapper.findComponent(GlSearchBoxByType).exists()).toBe(true);
|
|
165
165
|
});
|
|
166
166
|
|
|
167
167
|
it('has search disabled when filterable prop set to false', () => {
|
|
@@ -63,7 +63,7 @@ describe('pagination component', () => {
|
|
|
63
63
|
});
|
|
64
64
|
await wrapper.vm.$nextTick();
|
|
65
65
|
|
|
66
|
-
expect(wrapper.html()).
|
|
66
|
+
expect(wrapper.html()).toBe('');
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
it('supports slots customization', () => {
|
|
@@ -114,7 +114,7 @@ describe('pagination component', () => {
|
|
|
114
114
|
const nextButton = buttons.at(buttons.length - 1);
|
|
115
115
|
nextButton.trigger('click');
|
|
116
116
|
|
|
117
|
-
expect(wrapper.emitted('input')).
|
|
117
|
+
expect(wrapper.emitted('input')).toHaveLength(1);
|
|
118
118
|
expect(wrapper.emitted('input')[0]).toEqual([2]);
|
|
119
119
|
});
|
|
120
120
|
|
|
@@ -33,7 +33,7 @@ describe('search box by click component', () => {
|
|
|
33
33
|
wrapper.findComponent({ ref: 'input' }).vm.$emit('input', 'new value');
|
|
34
34
|
|
|
35
35
|
await wrapper.vm.$nextTick();
|
|
36
|
-
expect(wrapper.emitted(
|
|
36
|
+
expect(wrapper.emitted('input')).toEqual([['new value']]);
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
it('does not emit an input event when input is updated to the same value', async () => {
|
|
@@ -41,7 +41,7 @@ describe('search box by click component', () => {
|
|
|
41
41
|
|
|
42
42
|
await wrapper.setProps({ value: 'another value' });
|
|
43
43
|
|
|
44
|
-
expect(wrapper.emitted(
|
|
44
|
+
expect(wrapper.emitted('input')).toBe(undefined);
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
it('does not displays history dropdown by default', () => {
|
|
@@ -70,7 +70,7 @@ describe('search box by click component', () => {
|
|
|
70
70
|
findClearIcon().vm.$emit('click');
|
|
71
71
|
|
|
72
72
|
await wrapper.vm.$nextTick();
|
|
73
|
-
expect(wrapper.emitted(
|
|
73
|
+
expect(wrapper.emitted('input')).toEqual([['']]);
|
|
74
74
|
});
|
|
75
75
|
|
|
76
76
|
it('emits clear event when clicked', async () => {
|
|
@@ -78,7 +78,7 @@ describe('search box by click component', () => {
|
|
|
78
78
|
findClearIcon().vm.$emit('click');
|
|
79
79
|
await wrapper.vm.$nextTick();
|
|
80
80
|
|
|
81
|
-
expect(wrapper.emitted(
|
|
81
|
+
expect(wrapper.emitted('clear')).toHaveLength(1);
|
|
82
82
|
});
|
|
83
83
|
});
|
|
84
84
|
|
|
@@ -109,7 +109,7 @@ describe('search box by click component', () => {
|
|
|
109
109
|
wrapper.findComponent(GlDropdownItem).vm.$emit('click');
|
|
110
110
|
|
|
111
111
|
await wrapper.vm.$nextTick();
|
|
112
|
-
expect(wrapper.emitted()
|
|
112
|
+
expect(wrapper.emitted('input')[0]).toEqual(['one']);
|
|
113
113
|
expect(wrapper.emitted()['history-item-selected'][0]).toEqual(['one']);
|
|
114
114
|
});
|
|
115
115
|
});
|
|
@@ -149,7 +149,7 @@ describe('search box by click component', () => {
|
|
|
149
149
|
wrapper.findComponent(GlFormInput).vm.$emit('keydown', { type: 'key', keyCode: 13 });
|
|
150
150
|
|
|
151
151
|
await wrapper.vm.$nextTick();
|
|
152
|
-
expect(wrapper.emitted()
|
|
152
|
+
expect(wrapper.emitted('submit')[0]).toEqual(['some-input']);
|
|
153
153
|
});
|
|
154
154
|
|
|
155
155
|
it('emits submit event when search button is pressed', async () => {
|
|
@@ -157,7 +157,7 @@ describe('search box by click component', () => {
|
|
|
157
157
|
findSearchButton().vm.$emit('click');
|
|
158
158
|
|
|
159
159
|
await wrapper.vm.$nextTick();
|
|
160
|
-
expect(wrapper.emitted()
|
|
160
|
+
expect(wrapper.emitted('submit')[0]).toEqual(['some-input']);
|
|
161
161
|
});
|
|
162
162
|
|
|
163
163
|
it('adds `searchButtonAttributes` prop to search button', () => {
|
|
@@ -40,7 +40,7 @@ describe('search box by type component', () => {
|
|
|
40
40
|
it('emits empty value when clicked', () => {
|
|
41
41
|
findClearIcon().vm.$emit('click', { stopPropagation: jest.fn() });
|
|
42
42
|
|
|
43
|
-
expect(wrapper.emitted(
|
|
43
|
+
expect(wrapper.emitted('input')).toEqual([['']]);
|
|
44
44
|
});
|
|
45
45
|
});
|
|
46
46
|
|
|
@@ -59,7 +59,7 @@ describe('search box by type component', () => {
|
|
|
59
59
|
it(`emits ${modelEvent} event when input value changes`, () => {
|
|
60
60
|
findInput().setValue(newValue);
|
|
61
61
|
|
|
62
|
-
expect(wrapper.emitted(
|
|
62
|
+
expect(wrapper.emitted('input')).toEqual([[newValue]]);
|
|
63
63
|
});
|
|
64
64
|
});
|
|
65
65
|
|
|
@@ -85,7 +85,7 @@ describe('sorting component', () => {
|
|
|
85
85
|
|
|
86
86
|
selectDirectionButton().trigger('click');
|
|
87
87
|
|
|
88
|
-
expect(wrapper.emitted()
|
|
88
|
+
expect(wrapper.emitted('sortDirectionChange')[0]).toEqual([true]);
|
|
89
89
|
});
|
|
90
90
|
|
|
91
91
|
it('should allow custom sort tooltip to be applied', () => {
|
|
@@ -36,7 +36,7 @@ describe('sorting item component', () => {
|
|
|
36
36
|
it('does not show the check icon when the active prop is not provided', () => {
|
|
37
37
|
createComponent();
|
|
38
38
|
|
|
39
|
-
expect(findActiveIcon().exists()).
|
|
39
|
+
expect(findActiveIcon().exists()).toBe(true);
|
|
40
40
|
expect(findActiveIcon().classes()).toContain('inactive');
|
|
41
41
|
});
|
|
42
42
|
|
|
@@ -45,7 +45,7 @@ describe('sorting item component', () => {
|
|
|
45
45
|
active: true,
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
-
expect(findActiveIcon().exists()).
|
|
48
|
+
expect(findActiveIcon().exists()).toBe(true);
|
|
49
49
|
expect(findActiveIcon().classes()).not.toContain('inactive');
|
|
50
50
|
});
|
|
51
51
|
|
|
@@ -88,7 +88,7 @@ describe('GlScrollableTabs', () => {
|
|
|
88
88
|
});
|
|
89
89
|
|
|
90
90
|
it('passes props through', () => {
|
|
91
|
-
expect(NAV_CLASS).
|
|
91
|
+
expect(NAV_CLASS).toBe('gl-scrollable-tabs-nav');
|
|
92
92
|
expect(wrapper.findComponent(GlTabs).props()).toMatchObject({
|
|
93
93
|
...TEST_DEFAULT_PROPS,
|
|
94
94
|
navClass: [NAV_CLASS, TEST_DEFAULT_PROPS.navClass],
|
|
@@ -234,9 +234,9 @@ describe('tabs component', () => {
|
|
|
234
234
|
|
|
235
235
|
// `input` event should only be fired if the active tab changes.
|
|
236
236
|
if (expectedActiveTabIndex > 0) {
|
|
237
|
-
expect(wrapper.emitted()
|
|
237
|
+
expect(wrapper.emitted('input')[1]).toEqual([expectedActiveTabIndex]);
|
|
238
238
|
} else {
|
|
239
|
-
expect(wrapper.emitted()
|
|
239
|
+
expect(wrapper.emitted('input')[1]).toBeUndefined();
|
|
240
240
|
}
|
|
241
241
|
});
|
|
242
242
|
}
|
|
@@ -339,8 +339,8 @@ describe('tabs component', () => {
|
|
|
339
339
|
|
|
340
340
|
await nextTick();
|
|
341
341
|
|
|
342
|
-
expect(wrapper.emitted()
|
|
343
|
-
expect(wrapper.emitted()
|
|
342
|
+
expect(wrapper.emitted('input')[0]).toEqual([1]);
|
|
343
|
+
expect(wrapper.emitted('input')[1]).toEqual([1]);
|
|
344
344
|
});
|
|
345
345
|
});
|
|
346
346
|
});
|
|
@@ -352,7 +352,7 @@ describe('tabs component', () => {
|
|
|
352
352
|
|
|
353
353
|
await nextTick();
|
|
354
354
|
|
|
355
|
-
expect(wrapper.emitted()
|
|
355
|
+
expect(wrapper.emitted('input')[0]).toEqual([0]);
|
|
356
356
|
});
|
|
357
357
|
});
|
|
358
358
|
|
|
@@ -363,7 +363,7 @@ describe('tabs component', () => {
|
|
|
363
363
|
await nextTick();
|
|
364
364
|
await findTabByText('Second').trigger('click');
|
|
365
365
|
|
|
366
|
-
expect(wrapper.emitted()
|
|
366
|
+
expect(wrapper.emitted('input')[1]).toEqual([1]);
|
|
367
367
|
});
|
|
368
368
|
});
|
|
369
369
|
|
|
@@ -17,7 +17,7 @@ describe('Token component', () => {
|
|
|
17
17
|
it('emits close when "x" is clicked', () => {
|
|
18
18
|
wrapper = createComponent();
|
|
19
19
|
findIcon(wrapper).vm.$emit('click');
|
|
20
|
-
expect(wrapper.emitted(
|
|
20
|
+
expect(wrapper.emitted('close')).toHaveLength(1);
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
it('hides the icon when view-only', () => {
|
|
@@ -205,7 +205,7 @@ describe('GlTokenContainer', () => {
|
|
|
205
205
|
describe('when escape key is pressed', () => {
|
|
206
206
|
it('fires `cancel-focus` event', async () => {
|
|
207
207
|
await setup(0, keyboard.escape);
|
|
208
|
-
expect(wrapper.emitted('cancel-focus')).
|
|
208
|
+
expect(wrapper.emitted('cancel-focus')).toHaveLength(1);
|
|
209
209
|
});
|
|
210
210
|
});
|
|
211
211
|
|
|
@@ -398,7 +398,7 @@ describe('GlTokenSelector', () => {
|
|
|
398
398
|
});
|
|
399
399
|
|
|
400
400
|
it('fires `focus` event', () => {
|
|
401
|
-
expect(wrapper.emitted('focus')).
|
|
401
|
+
expect(wrapper.emitted('focus')).toHaveLength(1);
|
|
402
402
|
});
|
|
403
403
|
});
|
|
404
404
|
|
|
@@ -414,7 +414,7 @@ describe('GlTokenSelector', () => {
|
|
|
414
414
|
});
|
|
415
415
|
|
|
416
416
|
it('fires `blur` event', () => {
|
|
417
|
-
expect(wrapper.emitted('blur')).
|
|
417
|
+
expect(wrapper.emitted('blur')).toHaveLength(1);
|
|
418
418
|
});
|
|
419
419
|
|
|
420
420
|
it('removes focus class from main container', () => {
|
|
@@ -566,7 +566,7 @@ describe('GlTokenSelector', () => {
|
|
|
566
566
|
|
|
567
567
|
textInput.trigger('keydown');
|
|
568
568
|
|
|
569
|
-
expect(wrapper.emitted('keydown')).
|
|
569
|
+
expect(wrapper.emitted('keydown')).toHaveLength(1);
|
|
570
570
|
});
|
|
571
571
|
});
|
|
572
572
|
});
|
|
@@ -624,7 +624,7 @@ describe('GlTokenSelector', () => {
|
|
|
624
624
|
|
|
625
625
|
container.trigger('click');
|
|
626
626
|
|
|
627
|
-
expect(wrapper.emitted('focus')).
|
|
627
|
+
expect(wrapper.emitted('focus')).toHaveLength(1);
|
|
628
628
|
});
|
|
629
629
|
});
|
|
630
630
|
|
|
@@ -55,7 +55,7 @@ describe('column chart component', () => {
|
|
|
55
55
|
it('emits "created" when onCreated is called', () => {
|
|
56
56
|
wrapper.vm.onCreated(wrapper.vm.chart);
|
|
57
57
|
|
|
58
|
-
expect(wrapper.emitted('created')).
|
|
58
|
+
expect(wrapper.emitted('created')).toHaveLength(1);
|
|
59
59
|
});
|
|
60
60
|
|
|
61
61
|
it('calls event listener when "chartItemClicked" is emitted on the Chart component', () => {
|
|
@@ -119,7 +119,7 @@ describe('sparkline chart component', () => {
|
|
|
119
119
|
});
|
|
120
120
|
|
|
121
121
|
it('shows the tooltip when mousing over an axis point in the component', async () => {
|
|
122
|
-
expect(getTooltip().attributes('show')).
|
|
122
|
+
expect(getTooltip().attributes('show')).toBe(undefined);
|
|
123
123
|
|
|
124
124
|
const mockData = { seriesData: [{ data: [5, 8] }] };
|
|
125
125
|
getXAxisLabelFormatter()(mockData);
|
|
@@ -137,7 +137,7 @@ describe('sparkline chart component', () => {
|
|
|
137
137
|
wrapper.trigger('mouseleave');
|
|
138
138
|
await wrapper.vm.$nextTick();
|
|
139
139
|
|
|
140
|
-
expect(getTooltip().attributes('show')).
|
|
140
|
+
expect(getTooltip().attributes('show')).toBe(undefined);
|
|
141
141
|
});
|
|
142
142
|
|
|
143
143
|
it('adds the right content to the tooltip', async () => {
|
|
@@ -76,15 +76,15 @@ describe('resize observer directive', () => {
|
|
|
76
76
|
});
|
|
77
77
|
|
|
78
78
|
expect(observersCount()).toBe(1);
|
|
79
|
-
expect(wrapper.element.glResizeHandler).not.
|
|
79
|
+
expect(wrapper.element.glResizeHandler).not.toBe(undefined);
|
|
80
80
|
|
|
81
81
|
await wrapper.setData({ isEnabled: false });
|
|
82
82
|
|
|
83
|
-
expect(wrapper.element.glResizeHandler).
|
|
83
|
+
expect(wrapper.element.glResizeHandler).toBe(undefined);
|
|
84
84
|
|
|
85
85
|
await wrapper.setData({ isEnabled: true });
|
|
86
86
|
|
|
87
|
-
expect(wrapper.element.glResizeHandler).not.
|
|
87
|
+
expect(wrapper.element.glResizeHandler).not.toBe(undefined);
|
|
88
88
|
});
|
|
89
89
|
|
|
90
90
|
it('does a clean up when the component is destroyed', () => {
|
|
@@ -92,11 +92,11 @@ describe('resize observer directive', () => {
|
|
|
92
92
|
|
|
93
93
|
const { element } = wrapper;
|
|
94
94
|
|
|
95
|
-
expect(element.glResizeHandler).not.
|
|
95
|
+
expect(element.glResizeHandler).not.toBe(undefined);
|
|
96
96
|
|
|
97
97
|
wrapper.destroy();
|
|
98
98
|
|
|
99
|
-
expect(element.glResizeHandler).
|
|
99
|
+
expect(element.glResizeHandler).toBe(undefined);
|
|
100
100
|
});
|
|
101
101
|
|
|
102
102
|
describe('check directive value', () => {
|