@gitlab/ui 64.10.0 → 64.10.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/CHANGELOG.md +14 -0
- package/dist/components/base/new_dropdowns/listbox/listbox.js +25 -4
- package/dist/components/base/new_dropdowns/listbox/mock_data.js +7 -1
- package/package.json +3 -3
- package/src/components/base/new_dropdowns/listbox/listbox.spec.js +92 -14
- package/src/components/base/new_dropdowns/listbox/listbox.vue +27 -4
- package/src/components/base/new_dropdowns/listbox/mock_data.js +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [64.10.2](https://gitlab.com/gitlab-org/gitlab-ui/compare/v64.10.1...v64.10.2) (2023-06-16)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **GlCollapsibleListbox:** reverse clear all logic ([270777b](https://gitlab.com/gitlab-org/gitlab-ui/commit/270777bd74cfa2e76eff594ec1612ea408b4372f))
|
|
7
|
+
|
|
8
|
+
## [64.10.1](https://gitlab.com/gitlab-org/gitlab-ui/compare/v64.10.0...v64.10.1) (2023-06-14)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **GlCollapsibleListbox:** listbox stays open ([a83355d](https://gitlab.com/gitlab-org/gitlab-ui/commit/a83355d527c483ca6bd6587da64f565ef118b8da))
|
|
14
|
+
|
|
1
15
|
# [64.10.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v64.9.0...v64.10.0) (2023-06-14)
|
|
2
16
|
|
|
3
17
|
|
|
@@ -329,7 +329,7 @@ var script = {
|
|
|
329
329
|
},
|
|
330
330
|
computed: {
|
|
331
331
|
listboxTag() {
|
|
332
|
-
if (this.
|
|
332
|
+
if (!this.hasItems || isOption(this.items[0])) return 'ul';
|
|
333
333
|
return 'div';
|
|
334
334
|
},
|
|
335
335
|
listboxClasses() {
|
|
@@ -345,6 +345,9 @@ var script = {
|
|
|
345
345
|
flattenedOptions() {
|
|
346
346
|
return flattenedOptions(this.items);
|
|
347
347
|
},
|
|
348
|
+
hasItems() {
|
|
349
|
+
return this.items.length > 0;
|
|
350
|
+
},
|
|
348
351
|
listboxToggleText() {
|
|
349
352
|
if (!this.toggleText) {
|
|
350
353
|
if (!this.multiple && this.selectedValues.length) {
|
|
@@ -384,8 +387,19 @@ var script = {
|
|
|
384
387
|
if (!this.resetButtonLabel) {
|
|
385
388
|
return false;
|
|
386
389
|
}
|
|
390
|
+
if (!this.multiple) {
|
|
391
|
+
return false;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* if dropdown has no items
|
|
396
|
+
* reset all should be hidden
|
|
397
|
+
*/
|
|
398
|
+
if (!this.hasItems) {
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
387
401
|
if (this.multiple) {
|
|
388
|
-
return this.selected.length
|
|
402
|
+
return this.selected.length === this.items.length;
|
|
389
403
|
}
|
|
390
404
|
return Boolean(this.selected);
|
|
391
405
|
},
|
|
@@ -396,7 +410,15 @@ var script = {
|
|
|
396
410
|
if (!this.multiple) {
|
|
397
411
|
return false;
|
|
398
412
|
}
|
|
399
|
-
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* if dropdown has no items
|
|
416
|
+
* select all should be hidden
|
|
417
|
+
*/
|
|
418
|
+
if (!this.hasItems) {
|
|
419
|
+
return false;
|
|
420
|
+
}
|
|
421
|
+
return this.selected.length !== this.items.length;
|
|
400
422
|
},
|
|
401
423
|
showIntersectionObserver() {
|
|
402
424
|
return this.infiniteScroll && !this.infiniteScrollLoading && !this.loading && !this.searching;
|
|
@@ -614,7 +636,6 @@ var script = {
|
|
|
614
636
|
* @event reset
|
|
615
637
|
*/
|
|
616
638
|
this.$emit('reset');
|
|
617
|
-
this.closeAndFocus();
|
|
618
639
|
},
|
|
619
640
|
onSelectAllButtonClicked() {
|
|
620
641
|
/**
|
|
@@ -35,6 +35,12 @@ const mockOptions = [{
|
|
|
35
35
|
value: 'sup',
|
|
36
36
|
text: 'Support'
|
|
37
37
|
}];
|
|
38
|
+
const mockOptionsValues = mockOptions.map(_ref => {
|
|
39
|
+
let {
|
|
40
|
+
value
|
|
41
|
+
} = _ref;
|
|
42
|
+
return value;
|
|
43
|
+
});
|
|
38
44
|
const mockGroups = [{
|
|
39
45
|
text: 'Branches',
|
|
40
46
|
options: [{
|
|
@@ -103,4 +109,4 @@ const mockUsers = [{
|
|
|
103
109
|
icon: 'bin'
|
|
104
110
|
}];
|
|
105
111
|
|
|
106
|
-
export { mockGroups, mockGroupsWithTextSrOnly, mockOptions, mockUsers };
|
|
112
|
+
export { mockGroups, mockGroupsWithTextSrOnly, mockOptions, mockOptionsValues, mockUsers };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gitlab/ui",
|
|
3
|
-
"version": "64.10.
|
|
3
|
+
"version": "64.10.2",
|
|
4
4
|
"description": "GitLab UI Components",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -156,8 +156,8 @@
|
|
|
156
156
|
"storybook": "7.0.20",
|
|
157
157
|
"storybook-dark-mode": "3.0.0",
|
|
158
158
|
"stylelint": "14.9.1",
|
|
159
|
-
"stylelint-config-prettier": "9.0.
|
|
160
|
-
"stylelint-prettier": "
|
|
159
|
+
"stylelint-config-prettier": "^9.0.5",
|
|
160
|
+
"stylelint-prettier": "3.0.0",
|
|
161
161
|
"vue": "2.7.14",
|
|
162
162
|
"vue-loader": "^15.8.3",
|
|
163
163
|
"vue-loader-vue3": "npm:vue-loader@17",
|
|
@@ -18,7 +18,7 @@ import GlIntersectionObserver from '../../../utilities/intersection_observer/int
|
|
|
18
18
|
import GlCollapsibleListbox, { ITEM_SELECTOR } from './listbox.vue';
|
|
19
19
|
import GlListboxItem from './listbox_item.vue';
|
|
20
20
|
import GlListboxGroup from './listbox_group.vue';
|
|
21
|
-
import { mockOptions, mockGroups, mockGroupsWithTextSrOnly } from './mock_data';
|
|
21
|
+
import { mockOptions, mockOptionsValues, mockGroups, mockGroupsWithTextSrOnly } from './mock_data';
|
|
22
22
|
|
|
23
23
|
jest.mock('@floating-ui/dom');
|
|
24
24
|
autoUpdate.mockImplementation(() => {
|
|
@@ -179,6 +179,15 @@ describe('GlCollapsibleListbox', () => {
|
|
|
179
179
|
await nextTick();
|
|
180
180
|
expect(wrapper.emitted('select')[0][0]).toEqual(mockOptions[2].value);
|
|
181
181
|
});
|
|
182
|
+
|
|
183
|
+
it('close dropdown for single selection', () => {
|
|
184
|
+
jest.spyOn(wrapper.vm, 'closeAndFocus');
|
|
185
|
+
expect(wrapper.vm.closeAndFocus).not.toHaveBeenCalled();
|
|
186
|
+
|
|
187
|
+
findListboxItems().at(2).vm.$emit('select', true);
|
|
188
|
+
|
|
189
|
+
expect(wrapper.vm.closeAndFocus).toHaveBeenCalled();
|
|
190
|
+
});
|
|
182
191
|
});
|
|
183
192
|
|
|
184
193
|
describe('with groups', () => {
|
|
@@ -475,17 +484,47 @@ describe('GlCollapsibleListbox', () => {
|
|
|
475
484
|
expect(wrapper).toHaveLoggedVueErrors();
|
|
476
485
|
});
|
|
477
486
|
|
|
478
|
-
it
|
|
487
|
+
it.each`
|
|
488
|
+
title | multiple | selected
|
|
489
|
+
${'shows'} | ${true} | ${mockOptionsValues}
|
|
490
|
+
${'hides'} | ${false} | ${mockOptions[1].value}
|
|
491
|
+
`(
|
|
492
|
+
'$title the reset button if the label is provided and the selection is complete and mode if multiple mode is $multiple',
|
|
493
|
+
({ multiple, selected }) => {
|
|
494
|
+
buildWrapper({
|
|
495
|
+
headerText: 'Select assignee',
|
|
496
|
+
resetButtonLabel: 'Unassign',
|
|
497
|
+
selected,
|
|
498
|
+
items: mockOptions,
|
|
499
|
+
multiple,
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
expect(findResetButton().exists()).toBe(multiple);
|
|
503
|
+
}
|
|
504
|
+
);
|
|
505
|
+
|
|
506
|
+
it('hides reset button if the label is provided and the selection is not complete', () => {
|
|
479
507
|
buildWrapper({
|
|
480
508
|
headerText: 'Select assignee',
|
|
481
509
|
resetButtonLabel: 'Unassign',
|
|
482
510
|
selected: mockOptions[1].value,
|
|
483
511
|
items: mockOptions,
|
|
512
|
+
multiple: true,
|
|
484
513
|
});
|
|
485
|
-
const button = findResetButton();
|
|
486
514
|
|
|
487
|
-
expect(
|
|
488
|
-
|
|
515
|
+
expect(findResetButton().exists()).toBe(false);
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
it('hides reset button if dropdown has no items', () => {
|
|
519
|
+
buildWrapper({
|
|
520
|
+
headerText: 'Select assignee',
|
|
521
|
+
resetButtonLabel: 'Unassign',
|
|
522
|
+
selected: mockOptions[1].value,
|
|
523
|
+
items: [],
|
|
524
|
+
multiple: true,
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
expect(findResetButton().exists()).toBe(false);
|
|
489
528
|
});
|
|
490
529
|
|
|
491
530
|
it.each`
|
|
@@ -503,12 +542,13 @@ describe('GlCollapsibleListbox', () => {
|
|
|
503
542
|
expect(findResetButton().exists()).toBe(false);
|
|
504
543
|
});
|
|
505
544
|
|
|
506
|
-
it('on click, emits the reset event and
|
|
545
|
+
it('on click, emits the reset event does not and call closeAndFocus() for multiple mode', () => {
|
|
507
546
|
buildWrapper({
|
|
508
547
|
headerText: 'Select assignee',
|
|
509
548
|
resetButtonLabel: 'Unassign',
|
|
510
|
-
selected:
|
|
549
|
+
selected: mockOptionsValues,
|
|
511
550
|
items: mockOptions,
|
|
551
|
+
multiple: true,
|
|
512
552
|
});
|
|
513
553
|
jest.spyOn(wrapper.vm, 'closeAndFocus');
|
|
514
554
|
|
|
@@ -518,7 +558,7 @@ describe('GlCollapsibleListbox', () => {
|
|
|
518
558
|
findResetButton().trigger('click');
|
|
519
559
|
|
|
520
560
|
expect(wrapper.emitted('reset')).toHaveLength(1);
|
|
521
|
-
expect(wrapper.vm.closeAndFocus).toHaveBeenCalled();
|
|
561
|
+
expect(wrapper.vm.closeAndFocus).not.toHaveBeenCalled();
|
|
522
562
|
});
|
|
523
563
|
});
|
|
524
564
|
|
|
@@ -533,12 +573,12 @@ describe('GlCollapsibleListbox', () => {
|
|
|
533
573
|
});
|
|
534
574
|
|
|
535
575
|
it.each`
|
|
536
|
-
multiple |
|
|
537
|
-
${false} | ${false}
|
|
538
|
-
${true} | ${true}
|
|
576
|
+
multiple | resetVisible | selectAllVisible
|
|
577
|
+
${false} | ${false} | ${false}
|
|
578
|
+
${true} | ${false} | ${true}
|
|
539
579
|
`(
|
|
540
580
|
'shows the select all button if the label is provided and the selection is empty and multiple option is $multiple',
|
|
541
|
-
({ multiple,
|
|
581
|
+
({ multiple, resetVisible, selectAllVisible }) => {
|
|
542
582
|
buildWrapper({
|
|
543
583
|
headerText: 'Select assignee',
|
|
544
584
|
resetButtonLabel: 'Unassign',
|
|
@@ -548,11 +588,49 @@ describe('GlCollapsibleListbox', () => {
|
|
|
548
588
|
multiple,
|
|
549
589
|
});
|
|
550
590
|
|
|
551
|
-
expect(findResetButton().exists()).toBe(
|
|
552
|
-
expect(findSelectAllButton().exists()).toBe(
|
|
591
|
+
expect(findResetButton().exists()).toBe(resetVisible);
|
|
592
|
+
expect(findSelectAllButton().exists()).toBe(selectAllVisible);
|
|
553
593
|
}
|
|
554
594
|
);
|
|
555
595
|
|
|
596
|
+
it('hides select all button if dropdown has no items', () => {
|
|
597
|
+
buildWrapper({
|
|
598
|
+
headerText: 'Select assignee',
|
|
599
|
+
resetButtonLabel: 'Unassign',
|
|
600
|
+
showSelectAllButtonLabel: 'Select All',
|
|
601
|
+
items: [],
|
|
602
|
+
multiple: true,
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
expect(findSelectAllButton().exists()).toBe(false);
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
it('hides select all button if all items are selected', () => {
|
|
609
|
+
buildWrapper({
|
|
610
|
+
headerText: 'Select assignee',
|
|
611
|
+
resetButtonLabel: 'Unassign',
|
|
612
|
+
showSelectAllButtonLabel: 'Select All',
|
|
613
|
+
selected: mockOptionsValues,
|
|
614
|
+
items: mockOptions,
|
|
615
|
+
multiple: true,
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
expect(findSelectAllButton().exists()).toBe(false);
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
it('has the label text "Select All" if the label is provided and some items are selected', () => {
|
|
622
|
+
buildWrapper({
|
|
623
|
+
headerText: 'Select assignee',
|
|
624
|
+
resetButtonLabel: 'Unassign',
|
|
625
|
+
showSelectAllButtonLabel: 'Select All',
|
|
626
|
+
selected: [mockOptions[1].value],
|
|
627
|
+
items: mockOptions,
|
|
628
|
+
multiple: true,
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
expect(findSelectAllButton().text()).toBe('Select All');
|
|
632
|
+
});
|
|
633
|
+
|
|
556
634
|
it('has the label text "Select All" if the label is provided and the selection is empty', () => {
|
|
557
635
|
buildWrapper({
|
|
558
636
|
headerText: 'Select assignee',
|
|
@@ -345,7 +345,7 @@ export default {
|
|
|
345
345
|
},
|
|
346
346
|
computed: {
|
|
347
347
|
listboxTag() {
|
|
348
|
-
if (this.
|
|
348
|
+
if (!this.hasItems || isOption(this.items[0])) return 'ul';
|
|
349
349
|
return 'div';
|
|
350
350
|
},
|
|
351
351
|
listboxClasses() {
|
|
@@ -361,6 +361,9 @@ export default {
|
|
|
361
361
|
flattenedOptions() {
|
|
362
362
|
return flattenedOptions(this.items);
|
|
363
363
|
},
|
|
364
|
+
hasItems() {
|
|
365
|
+
return this.items.length > 0;
|
|
366
|
+
},
|
|
364
367
|
listboxToggleText() {
|
|
365
368
|
if (!this.toggleText) {
|
|
366
369
|
if (!this.multiple && this.selectedValues.length) {
|
|
@@ -394,8 +397,21 @@ export default {
|
|
|
394
397
|
if (!this.resetButtonLabel) {
|
|
395
398
|
return false;
|
|
396
399
|
}
|
|
400
|
+
|
|
401
|
+
if (!this.multiple) {
|
|
402
|
+
return false;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* if dropdown has no items
|
|
407
|
+
* reset all should be hidden
|
|
408
|
+
*/
|
|
409
|
+
if (!this.hasItems) {
|
|
410
|
+
return false;
|
|
411
|
+
}
|
|
412
|
+
|
|
397
413
|
if (this.multiple) {
|
|
398
|
-
return this.selected.length
|
|
414
|
+
return this.selected.length === this.items.length;
|
|
399
415
|
}
|
|
400
416
|
return Boolean(this.selected);
|
|
401
417
|
},
|
|
@@ -408,7 +424,15 @@ export default {
|
|
|
408
424
|
return false;
|
|
409
425
|
}
|
|
410
426
|
|
|
411
|
-
|
|
427
|
+
/**
|
|
428
|
+
* if dropdown has no items
|
|
429
|
+
* select all should be hidden
|
|
430
|
+
*/
|
|
431
|
+
if (!this.hasItems) {
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
return this.selected.length !== this.items.length;
|
|
412
436
|
},
|
|
413
437
|
showIntersectionObserver() {
|
|
414
438
|
return this.infiniteScroll && !this.infiniteScrollLoading && !this.loading && !this.searching;
|
|
@@ -636,7 +660,6 @@ export default {
|
|
|
636
660
|
* @event reset
|
|
637
661
|
*/
|
|
638
662
|
this.$emit('reset');
|
|
639
|
-
this.closeAndFocus();
|
|
640
663
|
},
|
|
641
664
|
onSelectAllButtonClicked() {
|
|
642
665
|
/**
|