@gitlab/ui 72.14.0 → 73.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 +13 -0
- package/dist/components/base/sorting/sorting.js +4 -9
- package/dist/index.js +0 -1
- package/dist/tokens/css/tokens.css +1 -1
- package/dist/tokens/css/tokens.dark.css +1 -1
- package/dist/tokens/js/tokens.dark.js +1 -1
- package/dist/tokens/js/tokens.js +1 -1
- package/dist/tokens/scss/_tokens.dark.scss +1 -1
- package/dist/tokens/scss/_tokens.scss +1 -1
- package/package.json +1 -1
- package/src/components/base/button/button.stories.js +22 -7
- package/src/components/base/sorting/sorting.md +0 -63
- package/src/components/base/sorting/sorting.spec.js +11 -87
- package/src/components/base/sorting/sorting.stories.js +6 -45
- package/src/components/base/sorting/sorting.vue +2 -20
- package/src/index.js +0 -1
- package/dist/components/base/sorting/sorting_item.js +0 -109
- package/src/components/base/sorting/sorting_item.md +0 -5
- package/src/components/base/sorting/sorting_item.spec.js +0 -65
- package/src/components/base/sorting/sorting_item.stories.js +0 -50
- package/src/components/base/sorting/sorting_item.vue +0 -69
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
# [73.0.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v72.14.0...v73.0.0) (2024-01-30)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* remove deprecated GlDropdown usage from GlSorting ([9621e68](https://gitlab.com/gitlab-org/gitlab-ui/commit/9621e6872f650570a106a5534ed007c1b76c40f3))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### BREAKING CHANGES
|
|
10
|
+
|
|
11
|
+
* Remove `GlSortingItem` component and deprecated API
|
|
12
|
+
from GlSorting
|
|
13
|
+
|
|
1
14
|
# [72.14.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v72.13.0...v72.14.0) (2024-01-30)
|
|
2
15
|
|
|
3
16
|
|
|
@@ -3,7 +3,6 @@ import GlButton from '../button/button';
|
|
|
3
3
|
import GlButtonGroup from '../button_group/button_group';
|
|
4
4
|
import GlCollapsibleListbox from '../new_dropdowns/listbox/listbox';
|
|
5
5
|
import { isOption } from '../new_dropdowns/listbox/utils';
|
|
6
|
-
import GlDropdown from '../dropdown/dropdown';
|
|
7
6
|
import { translate } from '../../../utils/i18n';
|
|
8
7
|
import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
|
|
9
8
|
|
|
@@ -12,8 +11,7 @@ var script = {
|
|
|
12
11
|
components: {
|
|
13
12
|
GlButton,
|
|
14
13
|
GlButtonGroup,
|
|
15
|
-
GlCollapsibleListbox
|
|
16
|
-
GlDropdown
|
|
14
|
+
GlCollapsibleListbox
|
|
17
15
|
},
|
|
18
16
|
directives: {
|
|
19
17
|
GlTooltip: GlTooltipDirective
|
|
@@ -33,7 +31,7 @@ var script = {
|
|
|
33
31
|
sortOptions: {
|
|
34
32
|
type: Array,
|
|
35
33
|
required: false,
|
|
36
|
-
default:
|
|
34
|
+
default: () => [],
|
|
37
35
|
// eslint-disable-next-line unicorn/no-array-callback-reference
|
|
38
36
|
validator: sortOptions => sortOptions.every(isOption)
|
|
39
37
|
},
|
|
@@ -64,7 +62,7 @@ var script = {
|
|
|
64
62
|
default: null
|
|
65
63
|
},
|
|
66
64
|
/**
|
|
67
|
-
* Additional class(es) to apply to the root element of the
|
|
65
|
+
* Additional class(es) to apply to the root element of the GlCollapsibleListbox.
|
|
68
66
|
*/
|
|
69
67
|
dropdownClass: {
|
|
70
68
|
type: String,
|
|
@@ -96,9 +94,6 @@ var script = {
|
|
|
96
94
|
if (this.sortDirectionToolTip) return this.sortDirectionToolTip;
|
|
97
95
|
return this.isAscending ? translate('GlSorting.sortAscending', 'Sort direction: ascending') : translate('GlSorting.sortDescending', 'Sort direction: descending');
|
|
98
96
|
},
|
|
99
|
-
useListbox() {
|
|
100
|
-
return Boolean(this.sortOptions);
|
|
101
|
-
},
|
|
102
97
|
listboxToggleClass() {
|
|
103
98
|
return [this.dropdownToggleClass, 'gl-rounded-top-right-none!', 'gl-rounded-bottom-right-none!', 'gl-focus-z-index-1'];
|
|
104
99
|
}
|
|
@@ -136,7 +131,7 @@ var script = {
|
|
|
136
131
|
const __vue_script__ = script;
|
|
137
132
|
|
|
138
133
|
/* template */
|
|
139
|
-
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-button-group',{staticClass:"gl-sorting"},[
|
|
134
|
+
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-button-group',{staticClass:"gl-sorting"},[_c('gl-collapsible-listbox',{class:_vm.dropdownClass,attrs:{"toggle-text":_vm.text,"items":_vm.sortOptions,"selected":_vm.sortBy,"toggle-class":_vm.listboxToggleClass,"placement":"right"},on:{"select":_vm.onSortByChanged}}),_vm._v(" "),_c('gl-button',{directives:[{name:"gl-tooltip",rawName:"v-gl-tooltip"}],class:['sorting-direction-button', _vm.sortDirectionToggleClass],attrs:{"title":_vm.sortDirectionText,"icon":_vm.localSortDirection,"aria-label":_vm.sortDirectionText},on:{"click":_vm.toggleSortDirection}})],1)};
|
|
140
135
|
var __vue_staticRenderFns__ = [];
|
|
141
136
|
|
|
142
137
|
/* style */
|
package/dist/index.js
CHANGED
|
@@ -67,7 +67,6 @@ export { default as GlDatepicker } from './components/base/datepicker/datepicker
|
|
|
67
67
|
export { default as GlDaterangePicker } from './components/base/daterange_picker/daterange_picker';
|
|
68
68
|
export { default as GlToggle } from './components/base/toggle/toggle';
|
|
69
69
|
export { default as GlSorting } from './components/base/sorting/sorting';
|
|
70
|
-
export { default as GlSortingItem } from './components/base/sorting/sorting_item';
|
|
71
70
|
export { default as GlInfiniteScroll } from './components/base/infinite_scroll/infinite_scroll';
|
|
72
71
|
export { default as GlAlert } from './components/base/alert/alert';
|
|
73
72
|
export { default as GlSegmentedControl } from './components/base/segmented_control/segmented_control';
|
package/dist/tokens/js/tokens.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import GlDropdown from '../dropdown/dropdown.vue';
|
|
2
2
|
import GlDropdownItem from '../dropdown/dropdown_item.vue';
|
|
3
3
|
import GlSorting from '../sorting/sorting.vue';
|
|
4
|
-
import GlSortingItem from '../sorting/sorting_item.vue';
|
|
5
4
|
import {
|
|
6
5
|
buttonCategoryOptions,
|
|
7
6
|
buttonVariantOptions,
|
|
@@ -501,15 +500,31 @@ BadgeWithSROnlyText.parameters = { controls: { disable: true } };
|
|
|
501
500
|
|
|
502
501
|
export const SortingDropdownSplitButton = (args, { argTypes }) => ({
|
|
503
502
|
props: Object.keys(argTypes),
|
|
504
|
-
components: { GlSorting
|
|
503
|
+
components: { GlSorting },
|
|
505
504
|
template: `
|
|
506
|
-
<gl-sorting
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
505
|
+
<gl-sorting
|
|
506
|
+
text="Sorting options"
|
|
507
|
+
:sort-options="sortOptions"
|
|
508
|
+
sort-by="first"
|
|
509
|
+
/>
|
|
511
510
|
`,
|
|
512
511
|
});
|
|
512
|
+
SortingDropdownSplitButton.args = {
|
|
513
|
+
sortOptions: [
|
|
514
|
+
{
|
|
515
|
+
value: 'first',
|
|
516
|
+
text: 'First item',
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
value: 'second',
|
|
520
|
+
text: 'Second item',
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
value: 'last',
|
|
524
|
+
text: 'Last item',
|
|
525
|
+
},
|
|
526
|
+
],
|
|
527
|
+
};
|
|
513
528
|
SortingDropdownSplitButton.parameters = { controls: { disable: true } };
|
|
514
529
|
|
|
515
530
|
export default {
|
|
@@ -78,66 +78,3 @@ export default {
|
|
|
78
78
|
}
|
|
79
79
|
</script>
|
|
80
80
|
```
|
|
81
|
-
|
|
82
|
-
## Deprecated usage
|
|
83
|
-
|
|
84
|
-
> **NOTE:** This documents the deprecated API, which will be removed in a future major release.
|
|
85
|
-
|
|
86
|
-
The dropdown part of the sorting component is a standard `gl-dropdown` component, with the items
|
|
87
|
-
exposed as a slot. Inside the `gl-sorting` component, you should add a list of `gl-sorting-item`
|
|
88
|
-
components to construct your sorting options. The check icon will be displayed when a
|
|
89
|
-
`gl-sorting-item` has its `active` prop set to `true`.
|
|
90
|
-
|
|
91
|
-
The `gl-sorting` component expects its parent component to manage the `text` and `is-ascending`
|
|
92
|
-
props. It does not track these using internal state.
|
|
93
|
-
|
|
94
|
-
A sort update should be triggered by clicking a `gl-sorting-item` component (and therefore should
|
|
95
|
-
have a `@click` event bound or a `href` prop in the case of navigation) or by clicking the direction
|
|
96
|
-
button. You should bind a function to the `sortDirectionChange` event to receive the new
|
|
97
|
-
`is-ascending` value and re-order your data appropriately.
|
|
98
|
-
|
|
99
|
-
A complete implementation example might look like:
|
|
100
|
-
|
|
101
|
-
```html
|
|
102
|
-
<template>
|
|
103
|
-
<gl-sorting
|
|
104
|
-
:text="dropdownText"
|
|
105
|
-
:is-ascending="isAscending"
|
|
106
|
-
@sortDirectionChange="onDirectionChange"
|
|
107
|
-
>
|
|
108
|
-
<gl-sorting-item @click="onSortItemClick('Item 1')">Item 1</gl-sorting-item>
|
|
109
|
-
<gl-sorting-item @click="onSortItemClick('Item 2')">Item 2</gl-sorting-item>
|
|
110
|
-
<gl-sorting-item @click="onSortItemClick('Item 3')">Item 3</gl-sorting-item>
|
|
111
|
-
</gl-sorting>
|
|
112
|
-
</template>
|
|
113
|
-
|
|
114
|
-
<script>
|
|
115
|
-
import { GlSorting, GlSortingItem } from '@gitlab/ui';
|
|
116
|
-
|
|
117
|
-
export default {
|
|
118
|
-
components: {
|
|
119
|
-
GlSorting,
|
|
120
|
-
GlSortingItem,
|
|
121
|
-
},
|
|
122
|
-
data() {
|
|
123
|
-
return {
|
|
124
|
-
isAscending: false,
|
|
125
|
-
dropdownText: 'Sort...'
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
methods: {
|
|
129
|
-
onSortItemClick(sortByItem) {
|
|
130
|
-
this.dropdownText = sortByItem;
|
|
131
|
-
this.sortMyData(sortByItem, this.isAscending);
|
|
132
|
-
},
|
|
133
|
-
onDirectionChange(isAscending) {
|
|
134
|
-
this.isAscending = isAscending;
|
|
135
|
-
this.sortMyData(this.dropdownText, this.isAscending);
|
|
136
|
-
},
|
|
137
|
-
sortMyData(sortBy, isAscending) {
|
|
138
|
-
// Use sortBy and direction to sort your data
|
|
139
|
-
},
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
</script>
|
|
143
|
-
```
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { mount } from '@vue/test-utils';
|
|
2
2
|
import { useMockIntersectionObserver } from '~/utils/use_mock_intersection_observer';
|
|
3
3
|
import GlCollapsibleListbox from '../new_dropdowns/listbox/listbox.vue';
|
|
4
|
-
import GlDropdown from '../dropdown/dropdown.vue';
|
|
5
4
|
import GlIcon from '../icon/icon.vue';
|
|
6
5
|
import GlSorting from './sorting.vue';
|
|
7
6
|
|
|
@@ -18,7 +17,6 @@ describe('sorting component', () => {
|
|
|
18
17
|
|
|
19
18
|
const selectDropdownButton = () => wrapper.find('button');
|
|
20
19
|
const selectDirectionButton = () => wrapper.findAll('button').at(1);
|
|
21
|
-
const selectDropdown = () => wrapper.findComponent(GlDropdown);
|
|
22
20
|
const findListbox = () => wrapper.findComponent(GlCollapsibleListbox);
|
|
23
21
|
const findListboxItem = (text) =>
|
|
24
22
|
wrapper
|
|
@@ -35,91 +33,6 @@ describe('sorting component', () => {
|
|
|
35
33
|
});
|
|
36
34
|
};
|
|
37
35
|
|
|
38
|
-
it('should display default text in dropdown', () => {
|
|
39
|
-
createComponent();
|
|
40
|
-
|
|
41
|
-
expect(selectDropdownButton().text()).toBe(defaultDropdownText);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('should have a default sort direction of desc and displays the descending icon', () => {
|
|
45
|
-
createComponent();
|
|
46
|
-
|
|
47
|
-
expect(selectDirectionButton().findComponent(GlIcon).props('name')).toBe('sort-highest');
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('should show new text value when passed in as a prop', () => {
|
|
51
|
-
const newDropdownText = 'Some new text';
|
|
52
|
-
|
|
53
|
-
createComponent({
|
|
54
|
-
text: newDropdownText,
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
expect(selectDropdownButton().text()).toBe(newDropdownText);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('should accept isAscending true as a default sort direction and display the ascending icon', () => {
|
|
61
|
-
createComponent({
|
|
62
|
-
isAscending: true,
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
expect(selectDirectionButton().findComponent(GlIcon).props('name')).toBe('sort-lowest');
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('should emit the sortDirectionChange event when direction button is clicked', () => {
|
|
69
|
-
createComponent();
|
|
70
|
-
|
|
71
|
-
selectDirectionButton().trigger('click');
|
|
72
|
-
|
|
73
|
-
expect(wrapper.emitted('sortDirectionChange')[0]).toEqual([true]);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('should allow custom sort direction text to be applied', () => {
|
|
77
|
-
const newDirectionTooltip = 'New tooltip text';
|
|
78
|
-
|
|
79
|
-
createComponent({
|
|
80
|
-
sortDirectionToolTip: newDirectionTooltip,
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
expect(selectDirectionButton().attributes('title')).toBe(newDirectionTooltip);
|
|
84
|
-
expect(selectDirectionButton().attributes('aria-label')).toBe(newDirectionTooltip);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('adds classes passed in `dropdownClass` prop to dropdown', () => {
|
|
88
|
-
createComponent({
|
|
89
|
-
dropdownClass: 'foo-bar',
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
expect(selectDropdown().classes()).toContain('foo-bar');
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('adds classes passed in `dropdownToggleClass` prop to dropdown toggle', () => {
|
|
96
|
-
createComponent({
|
|
97
|
-
dropdownToggleClass: 'foo-bar',
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
expect(selectDropdownButton().classes()).toEqual(expect.arrayContaining(['foo-bar']));
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('adds classes passed in `sortDirectionToggleClass` prop to sort direction toggle', () => {
|
|
104
|
-
createComponent({
|
|
105
|
-
sortDirectionToggleClass: 'foo-bar',
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
expect(selectDirectionButton().classes()).toEqual(
|
|
109
|
-
expect.arrayContaining(['sorting-direction-button', 'foo-bar'])
|
|
110
|
-
);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it('sets aria-label of sort direction button', async () => {
|
|
114
|
-
createComponent();
|
|
115
|
-
|
|
116
|
-
expect(selectDirectionButton().attributes('aria-label')).toBe('Sort direction: descending');
|
|
117
|
-
|
|
118
|
-
await wrapper.setProps({ isAscending: true });
|
|
119
|
-
|
|
120
|
-
expect(selectDirectionButton().attributes('aria-label')).toBe('Sort direction: ascending');
|
|
121
|
-
});
|
|
122
|
-
|
|
123
36
|
describe('using listbox', () => {
|
|
124
37
|
useMockIntersectionObserver();
|
|
125
38
|
|
|
@@ -129,6 +42,16 @@ describe('sorting component', () => {
|
|
|
129
42
|
expect(selectDropdownButton().text()).toBe(defaultDropdownText);
|
|
130
43
|
});
|
|
131
44
|
|
|
45
|
+
it('should show new text value when passed in as a prop', () => {
|
|
46
|
+
const newDropdownText = 'Some new text';
|
|
47
|
+
|
|
48
|
+
createComponent({
|
|
49
|
+
text: newDropdownText,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
expect(selectDropdownButton().text()).toBe(newDropdownText);
|
|
53
|
+
});
|
|
54
|
+
|
|
132
55
|
it('should use the selected sort option text in dropdown if text is not given', () => {
|
|
133
56
|
createComponent({ text: null, sortOptions: [{ value: 0, text: 'Foo' }], sortBy: 0 });
|
|
134
57
|
|
|
@@ -194,6 +117,7 @@ describe('sorting component', () => {
|
|
|
194
117
|
});
|
|
195
118
|
|
|
196
119
|
expect(selectDirectionButton().attributes('title')).toBe(newDirectionTooltip);
|
|
120
|
+
expect(selectDirectionButton().attributes('aria-label')).toBe(newDirectionTooltip);
|
|
197
121
|
});
|
|
198
122
|
|
|
199
123
|
it('adds classes passed in `dropdownClass` prop to dropdown', () => {
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { makeContainer } from '../../../utils/story_decorators/container';
|
|
2
|
-
import GlSortingItem from './sorting_item.vue';
|
|
3
2
|
import GlSorting from './sorting.vue';
|
|
4
3
|
import readme from './sorting.md';
|
|
5
4
|
|
|
6
5
|
const components = {
|
|
7
6
|
GlSorting,
|
|
8
|
-
GlSortingItem,
|
|
9
7
|
};
|
|
10
8
|
|
|
11
9
|
const propDefault = (prop) => GlSorting.props[prop].default;
|
|
@@ -33,59 +31,27 @@ const generateProps = ({
|
|
|
33
31
|
const template = `
|
|
34
32
|
<gl-sorting
|
|
35
33
|
:text="text"
|
|
34
|
+
:sort-options="sortOptions"
|
|
35
|
+
:sort-by="sortBy"
|
|
36
36
|
:is-ascending="isAscending"
|
|
37
37
|
:sort-direction-tool-tip="sortDirectionToolTip"
|
|
38
38
|
:dropdown-class="dropdownClass"
|
|
39
39
|
:dropdown-toggle-class="dropdownToggleClass"
|
|
40
40
|
:sort-direction-toggle-class="sortDirectionToggleClass"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<gl-sorting-item>Second item</gl-sorting-item>
|
|
44
|
-
<gl-sorting-item>Last item</gl-sorting-item>
|
|
45
|
-
</gl-sorting>`;
|
|
41
|
+
/>
|
|
42
|
+
`;
|
|
46
43
|
|
|
47
44
|
const Template = (args) => ({
|
|
48
45
|
components,
|
|
49
46
|
props: Object.keys(args),
|
|
50
47
|
mounted() {
|
|
51
|
-
this.$nextTick(() => this.$el.querySelector('
|
|
48
|
+
this.$nextTick(() => this.$el.querySelector('button').click());
|
|
52
49
|
},
|
|
53
50
|
template,
|
|
54
51
|
});
|
|
55
52
|
|
|
56
53
|
export const Default = Template.bind({});
|
|
57
54
|
Object.assign(Default, {
|
|
58
|
-
args: generateProps(),
|
|
59
|
-
parameters: {
|
|
60
|
-
controls: {
|
|
61
|
-
// These props/events only apply when using the listbox form, so don't
|
|
62
|
-
// show their controls.
|
|
63
|
-
exclude: ['sortBy', 'sortOptions', 'sortByChange'],
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
export const UsingListbox = (args) => ({
|
|
69
|
-
components,
|
|
70
|
-
props: Object.keys(args),
|
|
71
|
-
mounted() {
|
|
72
|
-
// The first button is the dropdown trigger.
|
|
73
|
-
this.$nextTick(() => this.$el.querySelector('button').click());
|
|
74
|
-
},
|
|
75
|
-
template: `
|
|
76
|
-
<gl-sorting
|
|
77
|
-
:text="text"
|
|
78
|
-
:sort-options="sortOptions"
|
|
79
|
-
:sort-by="sortBy"
|
|
80
|
-
:is-ascending="isAscending"
|
|
81
|
-
:sort-direction-tool-tip="sortDirectionToolTip"
|
|
82
|
-
:dropdown-class="dropdownClass"
|
|
83
|
-
:dropdown-toggle-class="dropdownToggleClass"
|
|
84
|
-
:sort-direction-toggle-class="sortDirectionToggleClass"
|
|
85
|
-
/>
|
|
86
|
-
`,
|
|
87
|
-
});
|
|
88
|
-
Object.assign(UsingListbox, {
|
|
89
55
|
args: generateProps({
|
|
90
56
|
text: '',
|
|
91
57
|
sortOptions: [
|
|
@@ -104,12 +70,7 @@ Object.assign(UsingListbox, {
|
|
|
104
70
|
],
|
|
105
71
|
sortBy: 'first',
|
|
106
72
|
}),
|
|
107
|
-
parameters: {
|
|
108
|
-
controls: {
|
|
109
|
-
// The default slot is deprecated, so don't show it in the controls.
|
|
110
|
-
exclude: ['default'],
|
|
111
|
-
},
|
|
112
|
-
},
|
|
73
|
+
parameters: {},
|
|
113
74
|
});
|
|
114
75
|
|
|
115
76
|
export default {
|
|
@@ -4,7 +4,6 @@ import GlButton from '../button/button.vue';
|
|
|
4
4
|
import GlButtonGroup from '../button_group/button_group.vue';
|
|
5
5
|
import GlCollapsibleListbox from '../new_dropdowns/listbox/listbox.vue';
|
|
6
6
|
import { isOption } from '../new_dropdowns/listbox/utils';
|
|
7
|
-
import GlDropdown from '../dropdown/dropdown.vue';
|
|
8
7
|
import { translate } from '../../../utils/i18n';
|
|
9
8
|
|
|
10
9
|
export default {
|
|
@@ -13,7 +12,6 @@ export default {
|
|
|
13
12
|
GlButton,
|
|
14
13
|
GlButtonGroup,
|
|
15
14
|
GlCollapsibleListbox,
|
|
16
|
-
GlDropdown,
|
|
17
15
|
},
|
|
18
16
|
directives: {
|
|
19
17
|
GlTooltip: GlTooltipDirective,
|
|
@@ -33,7 +31,7 @@ export default {
|
|
|
33
31
|
sortOptions: {
|
|
34
32
|
type: Array,
|
|
35
33
|
required: false,
|
|
36
|
-
default:
|
|
34
|
+
default: () => [],
|
|
37
35
|
// eslint-disable-next-line unicorn/no-array-callback-reference
|
|
38
36
|
validator: (sortOptions) => sortOptions.every(isOption),
|
|
39
37
|
},
|
|
@@ -64,7 +62,7 @@ export default {
|
|
|
64
62
|
default: null,
|
|
65
63
|
},
|
|
66
64
|
/**
|
|
67
|
-
* Additional class(es) to apply to the root element of the
|
|
65
|
+
* Additional class(es) to apply to the root element of the GlCollapsibleListbox.
|
|
68
66
|
*/
|
|
69
67
|
dropdownClass: {
|
|
70
68
|
type: String,
|
|
@@ -99,9 +97,6 @@ export default {
|
|
|
99
97
|
? translate('GlSorting.sortAscending', 'Sort direction: ascending')
|
|
100
98
|
: translate('GlSorting.sortDescending', 'Sort direction: descending');
|
|
101
99
|
},
|
|
102
|
-
useListbox() {
|
|
103
|
-
return Boolean(this.sortOptions);
|
|
104
|
-
},
|
|
105
100
|
listboxToggleClass() {
|
|
106
101
|
return [
|
|
107
102
|
this.dropdownToggleClass,
|
|
@@ -144,7 +139,6 @@ export default {
|
|
|
144
139
|
<template>
|
|
145
140
|
<gl-button-group class="gl-sorting">
|
|
146
141
|
<gl-collapsible-listbox
|
|
147
|
-
v-if="useListbox"
|
|
148
142
|
:toggle-text="text"
|
|
149
143
|
:items="sortOptions"
|
|
150
144
|
:selected="sortBy"
|
|
@@ -153,18 +147,6 @@ export default {
|
|
|
153
147
|
placement="right"
|
|
154
148
|
@select="onSortByChanged"
|
|
155
149
|
/>
|
|
156
|
-
<gl-dropdown
|
|
157
|
-
v-else
|
|
158
|
-
v-bind="$props"
|
|
159
|
-
:text="text"
|
|
160
|
-
category="secondary"
|
|
161
|
-
:class="dropdownClass"
|
|
162
|
-
:toggle-class="dropdownToggleClass"
|
|
163
|
-
right
|
|
164
|
-
>
|
|
165
|
-
<!-- @slot Deprecated slot to place the dropdown items, works best with a gl-sorting-item component. -->
|
|
166
|
-
<slot></slot>
|
|
167
|
-
</gl-dropdown>
|
|
168
150
|
<gl-button
|
|
169
151
|
v-gl-tooltip
|
|
170
152
|
:title="sortDirectionText"
|
package/src/index.js
CHANGED
|
@@ -76,7 +76,6 @@ export { default as GlDatepicker } from './components/base/datepicker/datepicker
|
|
|
76
76
|
export { default as GlDaterangePicker } from './components/base/daterange_picker/daterange_picker.vue';
|
|
77
77
|
export { default as GlToggle } from './components/base/toggle/toggle.vue';
|
|
78
78
|
export { default as GlSorting } from './components/base/sorting/sorting.vue';
|
|
79
|
-
export { default as GlSortingItem } from './components/base/sorting/sorting_item.vue';
|
|
80
79
|
export { default as GlInfiniteScroll } from './components/base/infinite_scroll/infinite_scroll.vue';
|
|
81
80
|
export { default as GlAlert } from './components/base/alert/alert.vue';
|
|
82
81
|
export { default as GlSegmentedControl } from './components/base/segmented_control/segmented_control.vue';
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import GlDropdownItem from '../dropdown/dropdown_item';
|
|
2
|
-
import GlIcon from '../icon/icon';
|
|
3
|
-
import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Sorting Item
|
|
7
|
-
*
|
|
8
|
-
* NOTE: This component is deprecated. Instead, use the `sortOptions` prop of
|
|
9
|
-
* `GlSorting`.
|
|
10
|
-
*
|
|
11
|
-
* This is written as a functional component because it is a simple wrapper over
|
|
12
|
-
* the GlDropdownItem component and does not use internal state. Functional
|
|
13
|
-
* components are cheaper to render and often used as wrappers like this. We're
|
|
14
|
-
* not using the <template functional> syntax here because it does not support
|
|
15
|
-
* custom child components wihtout extra work inside GitLab or extra work
|
|
16
|
-
* required by the user.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
var script = {
|
|
20
|
-
name: 'GlSortingItem',
|
|
21
|
-
functional: true,
|
|
22
|
-
props: {
|
|
23
|
-
/**
|
|
24
|
-
* Adds a check mark next to the item to indicate it is active.
|
|
25
|
-
*/
|
|
26
|
-
active: {
|
|
27
|
-
type: Boolean,
|
|
28
|
-
default: false,
|
|
29
|
-
required: false
|
|
30
|
-
},
|
|
31
|
-
/**
|
|
32
|
-
* If given, makes the item a link pointing to the given value. Otherwise,
|
|
33
|
-
* the item is a button.
|
|
34
|
-
*/
|
|
35
|
-
href: {
|
|
36
|
-
type: String,
|
|
37
|
-
default: null,
|
|
38
|
-
required: false
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
/**
|
|
42
|
-
* The content of the item.
|
|
43
|
-
* @slot default
|
|
44
|
-
*/
|
|
45
|
-
render(createElement, _ref) {
|
|
46
|
-
let {
|
|
47
|
-
scopedSlots,
|
|
48
|
-
data,
|
|
49
|
-
props = {}
|
|
50
|
-
} = _ref;
|
|
51
|
-
const classNames = `gl-sorting-item js-active-icon gl-flex-shrink-0 gl-mr-2 ${props.active ? '' : 'inactive gl-visibility-hidden'}`;
|
|
52
|
-
const icon = createElement(GlIcon, {
|
|
53
|
-
class: classNames,
|
|
54
|
-
attrs: {
|
|
55
|
-
name: 'mobile-issue-close',
|
|
56
|
-
size: 16,
|
|
57
|
-
ariaLabel: 'Selected'
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
return createElement(GlDropdownItem, {
|
|
61
|
-
...data,
|
|
62
|
-
attrs: {
|
|
63
|
-
...props
|
|
64
|
-
},
|
|
65
|
-
scopedSlots: {
|
|
66
|
-
default: () => {
|
|
67
|
-
var _scopedSlots$default;
|
|
68
|
-
return [icon, (_scopedSlots$default = scopedSlots.default) === null || _scopedSlots$default === void 0 ? void 0 : _scopedSlots$default.call(scopedSlots)];
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
/* script */
|
|
76
|
-
const __vue_script__ = script;
|
|
77
|
-
|
|
78
|
-
/* template */
|
|
79
|
-
|
|
80
|
-
/* style */
|
|
81
|
-
const __vue_inject_styles__ = undefined;
|
|
82
|
-
/* scoped */
|
|
83
|
-
const __vue_scope_id__ = undefined;
|
|
84
|
-
/* module identifier */
|
|
85
|
-
const __vue_module_identifier__ = undefined;
|
|
86
|
-
/* functional template */
|
|
87
|
-
const __vue_is_functional_template__ = undefined;
|
|
88
|
-
/* style inject */
|
|
89
|
-
|
|
90
|
-
/* style inject SSR */
|
|
91
|
-
|
|
92
|
-
/* style inject shadow dom */
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const __vue_component__ = __vue_normalize__(
|
|
97
|
-
{},
|
|
98
|
-
__vue_inject_styles__,
|
|
99
|
-
__vue_script__,
|
|
100
|
-
__vue_scope_id__,
|
|
101
|
-
__vue_is_functional_template__,
|
|
102
|
-
__vue_module_identifier__,
|
|
103
|
-
false,
|
|
104
|
-
undefined,
|
|
105
|
-
undefined,
|
|
106
|
-
undefined
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
export default __vue_component__;
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
> **NOTE:** This component is deprecated. Instead, use the `sortOptions` prop of `GlSorting`.
|
|
2
|
-
|
|
3
|
-
The sorting item component is meant to be used for clickable entries inside a `gl-sorting` component.
|
|
4
|
-
This is a wrapper around the `gl-dropdown-item` component and includes a check icon when active,
|
|
5
|
-
and an empty space for alignment when not.
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { shallowMount } from '@vue/test-utils';
|
|
2
|
-
import GlDropdownItem from '../dropdown/dropdown_item.vue';
|
|
3
|
-
import GlSortingItem from './sorting_item.vue';
|
|
4
|
-
|
|
5
|
-
describe('sorting item component', () => {
|
|
6
|
-
let wrapper;
|
|
7
|
-
|
|
8
|
-
const sortingItemText = 'Some test text';
|
|
9
|
-
|
|
10
|
-
const defaultProps = {};
|
|
11
|
-
|
|
12
|
-
const findActiveIcon = () => wrapper.find('.js-active-icon');
|
|
13
|
-
const findGlDropdownItem = () => wrapper.findComponent(GlDropdownItem);
|
|
14
|
-
|
|
15
|
-
const createComponent = (propsData) => {
|
|
16
|
-
wrapper = shallowMount(GlSortingItem, {
|
|
17
|
-
context: {
|
|
18
|
-
props: {
|
|
19
|
-
...defaultProps,
|
|
20
|
-
...propsData,
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
slots: {
|
|
24
|
-
default: sortingItemText,
|
|
25
|
-
},
|
|
26
|
-
stubs: {
|
|
27
|
-
GlDropdownItem,
|
|
28
|
-
},
|
|
29
|
-
});
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
it('should render and display the supplied text', () => {
|
|
33
|
-
createComponent();
|
|
34
|
-
|
|
35
|
-
expect(wrapper.text()).toBe(sortingItemText);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it('does not show the check icon when the active prop is not provided', () => {
|
|
39
|
-
createComponent();
|
|
40
|
-
|
|
41
|
-
expect(findActiveIcon().exists()).toBe(true);
|
|
42
|
-
expect(findActiveIcon().classes()).toContain('inactive');
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('does render a check icon when the active prop is provided', () => {
|
|
46
|
-
createComponent({
|
|
47
|
-
active: true,
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
expect(findActiveIcon().exists()).toBe(true);
|
|
51
|
-
expect(findActiveIcon().classes()).not.toContain('inactive');
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('passes the props down to the gl-dropdown-item component', () => {
|
|
55
|
-
const url = 'https://about.gitlab.com';
|
|
56
|
-
|
|
57
|
-
createComponent({
|
|
58
|
-
active: true,
|
|
59
|
-
href: url,
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
expect(findGlDropdownItem().attributes('active')).toBe('true');
|
|
63
|
-
expect(findGlDropdownItem().attributes('href')).toBe(url);
|
|
64
|
-
});
|
|
65
|
-
});
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { makeContainer } from '../../../utils/story_decorators/container';
|
|
2
|
-
import GlSortingItem from './sorting_item.vue';
|
|
3
|
-
import GlSorting from './sorting.vue';
|
|
4
|
-
import readme from './sorting_item.md';
|
|
5
|
-
|
|
6
|
-
const components = {
|
|
7
|
-
GlSorting,
|
|
8
|
-
GlSortingItem,
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
const generateProps = ({ href = null, active = false } = {}) => ({
|
|
12
|
-
href,
|
|
13
|
-
active,
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
const template = `
|
|
17
|
-
<gl-sorting text="Sorting options">
|
|
18
|
-
<gl-sorting-item :href="href" :active="active">Some item</gl-sorting-item>
|
|
19
|
-
</gl-sorting>`;
|
|
20
|
-
|
|
21
|
-
const Template = (args) => ({
|
|
22
|
-
components,
|
|
23
|
-
props: Object.keys(args),
|
|
24
|
-
mounted() {
|
|
25
|
-
this.$nextTick(() => this.$el.querySelector('.gl-dropdown-toggle').click());
|
|
26
|
-
},
|
|
27
|
-
template,
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
export const Default = Template.bind({});
|
|
31
|
-
Default.args = generateProps();
|
|
32
|
-
|
|
33
|
-
export const WithHref = Template.bind({});
|
|
34
|
-
WithHref.args = generateProps({ href: 'https://about.gitlab.com/' });
|
|
35
|
-
|
|
36
|
-
export const WithActive = Template.bind({});
|
|
37
|
-
WithActive.args = generateProps({ active: true });
|
|
38
|
-
|
|
39
|
-
export default {
|
|
40
|
-
title: 'base/sorting/sorting-item',
|
|
41
|
-
component: GlSortingItem,
|
|
42
|
-
decorators: [makeContainer({ height: '50px', paddingLeft: '100px' })],
|
|
43
|
-
parameters: {
|
|
44
|
-
docs: {
|
|
45
|
-
description: {
|
|
46
|
-
component: readme,
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
};
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import GlDropdownItem from '../dropdown/dropdown_item.vue';
|
|
3
|
-
import GlIcon from '../icon/icon.vue';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Sorting Item
|
|
7
|
-
*
|
|
8
|
-
* NOTE: This component is deprecated. Instead, use the `sortOptions` prop of
|
|
9
|
-
* `GlSorting`.
|
|
10
|
-
*
|
|
11
|
-
* This is written as a functional component because it is a simple wrapper over
|
|
12
|
-
* the GlDropdownItem component and does not use internal state. Functional
|
|
13
|
-
* components are cheaper to render and often used as wrappers like this. We're
|
|
14
|
-
* not using the <template functional> syntax here because it does not support
|
|
15
|
-
* custom child components wihtout extra work inside GitLab or extra work
|
|
16
|
-
* required by the user.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
export default {
|
|
20
|
-
name: 'GlSortingItem',
|
|
21
|
-
functional: true,
|
|
22
|
-
props: {
|
|
23
|
-
/**
|
|
24
|
-
* Adds a check mark next to the item to indicate it is active.
|
|
25
|
-
*/
|
|
26
|
-
active: {
|
|
27
|
-
type: Boolean,
|
|
28
|
-
default: false,
|
|
29
|
-
required: false,
|
|
30
|
-
},
|
|
31
|
-
/**
|
|
32
|
-
* If given, makes the item a link pointing to the given value. Otherwise,
|
|
33
|
-
* the item is a button.
|
|
34
|
-
*/
|
|
35
|
-
href: {
|
|
36
|
-
type: String,
|
|
37
|
-
default: null,
|
|
38
|
-
required: false,
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
/**
|
|
42
|
-
* The content of the item.
|
|
43
|
-
* @slot default
|
|
44
|
-
*/
|
|
45
|
-
render(createElement, { scopedSlots, data, props = {} }) {
|
|
46
|
-
const classNames = `gl-sorting-item js-active-icon gl-flex-shrink-0 gl-mr-2 ${
|
|
47
|
-
props.active ? '' : 'inactive gl-visibility-hidden'
|
|
48
|
-
}`;
|
|
49
|
-
const icon = createElement(GlIcon, {
|
|
50
|
-
class: classNames,
|
|
51
|
-
attrs: {
|
|
52
|
-
name: 'mobile-issue-close',
|
|
53
|
-
size: 16,
|
|
54
|
-
ariaLabel: 'Selected',
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
return createElement(GlDropdownItem, {
|
|
59
|
-
...data,
|
|
60
|
-
attrs: {
|
|
61
|
-
...props,
|
|
62
|
-
},
|
|
63
|
-
scopedSlots: {
|
|
64
|
-
default: () => [icon, scopedSlots.default?.()],
|
|
65
|
-
},
|
|
66
|
-
});
|
|
67
|
-
},
|
|
68
|
-
};
|
|
69
|
-
</script>
|