@gitlab/ui 55.2.1 → 55.3.1
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 +15 -0
- package/dist/components/base/new_dropdowns/disclosure/constants.js +4 -0
- package/dist/components/base/new_dropdowns/disclosure/disclosure_dropdown.js +7 -16
- package/dist/components/base/new_dropdowns/disclosure/disclosure_dropdown_group.js +3 -1
- package/dist/components/base/new_dropdowns/disclosure/disclosure_dropdown_item.js +2 -0
- package/dist/components/base/new_dropdowns/disclosure/utils.js +23 -3
- package/dist/components/base/toggle/toggle.js +18 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/package.json +1 -1
- package/src/components/base/new_dropdowns/disclosure/constants.js +2 -0
- package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.spec.js +51 -8
- package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.stories.js +18 -13
- package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.vue +6 -18
- package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown_group.vue +4 -2
- package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown_item.vue +2 -0
- package/src/components/base/new_dropdowns/disclosure/utils.js +28 -3
- package/src/components/base/toggle/toggle.scss +1 -2
- package/src/components/base/toggle/toggle.spec.js +24 -0
- package/src/components/base/toggle/toggle.stories.js +20 -2
- package/src/components/base/toggle/toggle.vue +27 -1
package/package.json
CHANGED
|
@@ -22,6 +22,7 @@ describe('GlDisclosureDropdown', () => {
|
|
|
22
22
|
const buildWrapper = (propsData, slots = {}) => {
|
|
23
23
|
wrapper = mount(GlDisclosureDropdown, {
|
|
24
24
|
propsData,
|
|
25
|
+
components: { GlDisclosureDropdownItem, GlDisclosureDropdownGroup },
|
|
25
26
|
slots,
|
|
26
27
|
attachTo: document.body,
|
|
27
28
|
});
|
|
@@ -216,23 +217,65 @@ describe('GlDisclosureDropdown', () => {
|
|
|
216
217
|
});
|
|
217
218
|
});
|
|
218
219
|
|
|
219
|
-
describe('disclosure
|
|
220
|
-
it('should render
|
|
220
|
+
describe('disclosure tag', () => {
|
|
221
|
+
it('should render `ul` as content tag when items is a list of items', () => {
|
|
221
222
|
buildWrapper({ items: mockItems });
|
|
222
223
|
expect(findDisclosureContent().element.tagName).toBe('UL');
|
|
223
|
-
expect(findDisclosureContent().attributes('role')).toBeUndefined();
|
|
224
224
|
});
|
|
225
225
|
|
|
226
|
-
it('should render
|
|
226
|
+
it('should render `ul` as content tag when items is a list of groups', () => {
|
|
227
227
|
buildWrapper({ items: mockGroups });
|
|
228
|
+
expect(findDisclosureContent().element.tagName).toBe('UL');
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('should render `ul` as content tag when default slot contains only groups', () => {
|
|
232
|
+
const slots = {
|
|
233
|
+
default: `
|
|
234
|
+
<gl-disclosure-dropdown-group>
|
|
235
|
+
<gl-disclosure-dropdown-item>Item</gl-disclosure-dropdown-item>
|
|
236
|
+
<gl-disclosure-dropdown-item>Item</gl-disclosure-dropdown-item>
|
|
237
|
+
</gl-disclosure-dropdown-group>
|
|
238
|
+
<gl-disclosure-dropdown-group>
|
|
239
|
+
<gl-disclosure-dropdown-item>Item</gl-disclosure-dropdown-item>
|
|
240
|
+
</gl-disclosure-dropdown-group>
|
|
241
|
+
`,
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
buildWrapper({}, slots);
|
|
245
|
+
expect(findDisclosureContent().element.tagName).toBe('UL');
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it('should render `ul` as content tag when default slot contains only items', () => {
|
|
249
|
+
const slots = {
|
|
250
|
+
default: `
|
|
251
|
+
<gl-disclosure-dropdown-item>Item</gl-disclosure-dropdown-item>
|
|
252
|
+
<gl-disclosure-dropdown-item>Item</gl-disclosure-dropdown-item>
|
|
253
|
+
<gl-disclosure-dropdown-item>Item</gl-disclosure-dropdown-item>
|
|
254
|
+
`,
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
buildWrapper({}, slots);
|
|
258
|
+
expect(findDisclosureContent().element.tagName).toBe('UL');
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
it('should render `div` as content tag when default slot does not contain valid list item', () => {
|
|
262
|
+
const slots = {
|
|
263
|
+
default: `
|
|
264
|
+
<div>Item</div>
|
|
265
|
+
<gl-disclosure-dropdown-group>
|
|
266
|
+
<gl-disclosure-dropdown-item>Item</gl-disclosure-dropdown-item>
|
|
267
|
+
<gl-disclosure-dropdown-item>Item</gl-disclosure-dropdown-item>
|
|
268
|
+
</gl-disclosure-dropdown-group>
|
|
269
|
+
`,
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
buildWrapper({}, slots);
|
|
228
273
|
expect(findDisclosureContent().element.tagName).toBe('DIV');
|
|
229
|
-
expect(findDisclosureContent().attributes('role')).toBe('group');
|
|
230
274
|
});
|
|
231
275
|
|
|
232
|
-
it('should render
|
|
233
|
-
buildWrapper({
|
|
276
|
+
it('should render `div` as content tag when slot is not a list item', () => {
|
|
277
|
+
buildWrapper({}, { default: 'Some other content' });
|
|
234
278
|
expect(findDisclosureContent().element.tagName).toBe('DIV');
|
|
235
|
-
expect(findDisclosureContent().attributes('role')).toBeUndefined();
|
|
236
279
|
});
|
|
237
280
|
});
|
|
238
281
|
});
|
|
@@ -52,13 +52,16 @@ function openDisclosure(component) {
|
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
const template = (content, { bindingOverrides = {} } = {}) => `
|
|
55
|
+
const template = (content, { bindingOverrides = {} } = {}, after) => `
|
|
56
|
+
<div>
|
|
56
57
|
<gl-disclosure-dropdown
|
|
57
58
|
ref="disclosure"
|
|
58
59
|
${makeBindings(bindingOverrides)}
|
|
59
60
|
>
|
|
60
61
|
${content || ''}
|
|
61
62
|
</gl-disclosure-dropdown>
|
|
63
|
+
${after || ''}
|
|
64
|
+
</div>
|
|
62
65
|
`;
|
|
63
66
|
|
|
64
67
|
const TOGGLE_ID = 'custom-toggle-id';
|
|
@@ -217,15 +220,14 @@ CustomGroupsAndItems.args = {
|
|
|
217
220
|
CustomGroupsAndItems.decorators = [makeContainer({ height: '200px' })];
|
|
218
221
|
|
|
219
222
|
export const CustomGroupsItemsAndToggle = makeGroupedExample({
|
|
220
|
-
template: template(
|
|
221
|
-
|
|
222
|
-
<
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
<div role="group">
|
|
223
|
+
template: template(
|
|
224
|
+
`
|
|
225
|
+
<template #toggle>
|
|
226
|
+
<span class="gl-sr-only">
|
|
227
|
+
Orange Fox user's menu
|
|
228
|
+
</span>
|
|
229
|
+
<gl-avatar :size="32" entity-name="Orange Fox" aria-hidden="true"></gl-avatar>
|
|
230
|
+
</template>
|
|
229
231
|
<gl-disclosure-dropdown-group>
|
|
230
232
|
<gl-disclosure-dropdown-item>
|
|
231
233
|
<span class="gl-display-flex gl-flex-direction-column">
|
|
@@ -256,15 +258,18 @@ export const CustomGroupsItemsAndToggle = makeGroupedExample({
|
|
|
256
258
|
<gl-toggle label="New navigation" label-position="left" v-model="newNavigation"/>
|
|
257
259
|
</gl-disclosure-dropdown-item>
|
|
258
260
|
<gl-disclosure-dropdown-item @action="toggleModalVisibility(true)">
|
|
259
|
-
|
|
261
|
+
Provide feedback
|
|
260
262
|
</gl-disclosure-dropdown-item>
|
|
261
263
|
</gl-disclosure-dropdown-group>
|
|
262
264
|
<gl-disclosure-dropdown-group bordered :group="$options.groups[1]"> </gl-disclosure-dropdown-group>
|
|
265
|
+
`,
|
|
266
|
+
{},
|
|
267
|
+
`
|
|
263
268
|
<gl-modal :visible="feedBackModalVisible" @change="toggleModalVisibility" modal-id="feedbackModal" size="sm">
|
|
264
269
|
<textarea class="gl-w-full">Tell us what you think!</textarea>
|
|
265
270
|
</gl-modal>
|
|
266
|
-
|
|
267
|
-
|
|
271
|
+
`
|
|
272
|
+
),
|
|
268
273
|
data() {
|
|
269
274
|
return {
|
|
270
275
|
newNavigation: true,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
import GlBaseDropdown from '../base_dropdown/base_dropdown.vue';
|
|
20
20
|
import GlDisclosureDropdownItem, { ITEM_CLASS } from './disclosure_dropdown_item.vue';
|
|
21
21
|
import GlDisclosureDropdownGroup from './disclosure_dropdown_group.vue';
|
|
22
|
-
import { itemsValidator, isItem,
|
|
22
|
+
import { itemsValidator, isItem, hasOnlyListItems } from './utils';
|
|
23
23
|
|
|
24
24
|
export default {
|
|
25
25
|
events: {
|
|
@@ -169,22 +169,11 @@ export default {
|
|
|
169
169
|
};
|
|
170
170
|
},
|
|
171
171
|
computed: {
|
|
172
|
-
|
|
173
|
-
if (this.items) {
|
|
174
|
-
|
|
175
|
-
return {
|
|
176
|
-
tag: 'ul',
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (isAllGroups(this.items))
|
|
181
|
-
return {
|
|
182
|
-
tag: 'div',
|
|
183
|
-
role: 'group',
|
|
184
|
-
};
|
|
172
|
+
disclosureTag() {
|
|
173
|
+
if (this.items?.length || hasOnlyListItems(this.$scopedSlots)) {
|
|
174
|
+
return 'ul';
|
|
185
175
|
}
|
|
186
|
-
|
|
187
|
-
return { tag: 'div' };
|
|
176
|
+
return 'div';
|
|
188
177
|
},
|
|
189
178
|
hasCustomToggle() {
|
|
190
179
|
return Boolean(this.$scopedSlots.toggle);
|
|
@@ -305,10 +294,9 @@ export default {
|
|
|
305
294
|
<slot name="header"></slot>
|
|
306
295
|
|
|
307
296
|
<component
|
|
308
|
-
:is="
|
|
297
|
+
:is="disclosureTag"
|
|
309
298
|
:id="disclosureId"
|
|
310
299
|
ref="content"
|
|
311
|
-
:role="disclosureOptions.role"
|
|
312
300
|
:aria-labelledby="listAriaLabelledBy || toggleId"
|
|
313
301
|
data-testid="disclosure-content"
|
|
314
302
|
class="gl-new-dropdown-contents"
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
import { uniqueId } from 'lodash';
|
|
3
3
|
import GlDisclosureDropdownItem from './disclosure_dropdown_item.vue';
|
|
4
4
|
import { isGroup } from './utils';
|
|
5
|
+
import { DISCLOSURE_DROPDOWN_GROUP_NAME } from './constants';
|
|
5
6
|
|
|
6
7
|
export const GROUP_TOP_BORDER_CLASSES = 'gl-border-t gl-pt-2 gl-mt-2';
|
|
7
8
|
|
|
8
9
|
export default {
|
|
10
|
+
name: DISCLOSURE_DROPDOWN_GROUP_NAME,
|
|
9
11
|
components: {
|
|
10
12
|
GlDisclosureDropdownItem,
|
|
11
13
|
},
|
|
@@ -52,7 +54,7 @@ export default {
|
|
|
52
54
|
</script>
|
|
53
55
|
|
|
54
56
|
<template>
|
|
55
|
-
<
|
|
57
|
+
<li :class="borderClass">
|
|
56
58
|
<div
|
|
57
59
|
v-if="showHeader"
|
|
58
60
|
:id="nameId"
|
|
@@ -73,5 +75,5 @@ export default {
|
|
|
73
75
|
</gl-disclosure-dropdown-item>
|
|
74
76
|
</slot>
|
|
75
77
|
</ul>
|
|
76
|
-
</
|
|
78
|
+
</li>
|
|
77
79
|
</template>
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
import { ENTER, SPACE } from '../constants';
|
|
3
3
|
import { stopEvent } from '../../../../utils/utils';
|
|
4
4
|
import { isItem } from './utils';
|
|
5
|
+
import { DISCLOSURE_DROPDOWN_ITEM_NAME } from './constants';
|
|
5
6
|
|
|
6
7
|
export const ITEM_CLASS = 'gl-new-dropdown-item';
|
|
7
8
|
|
|
8
9
|
export default {
|
|
10
|
+
name: DISCLOSURE_DROPDOWN_ITEM_NAME,
|
|
9
11
|
ITEM_CLASS,
|
|
10
12
|
props: {
|
|
11
13
|
item: {
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { isFunction } from 'lodash';
|
|
2
|
+
import { DISCLOSURE_DROPDOWN_ITEM_NAME, DISCLOSURE_DROPDOWN_GROUP_NAME } from './constants';
|
|
3
|
+
|
|
1
4
|
const itemValidator = (item) => item?.text?.length > 0 && !Array.isArray(item?.items);
|
|
2
5
|
|
|
3
6
|
const isItem = (item) => Boolean(item) && itemValidator(item);
|
|
@@ -10,8 +13,30 @@ const isGroup = (group) =>
|
|
|
10
13
|
|
|
11
14
|
const itemsValidator = (items) => items.every(isItem) || items.every(isGroup);
|
|
12
15
|
|
|
13
|
-
const
|
|
16
|
+
const isListItem = (tag) =>
|
|
17
|
+
['gl-disclosure-dropdown-group', 'gl-disclosure-dropdown-item', 'li'].includes(tag);
|
|
18
|
+
|
|
19
|
+
const isValidSlotTagVue2 = (vNode) =>
|
|
20
|
+
Boolean(vNode) && isListItem(vNode.componentOptions?.tag || vNode.tag);
|
|
21
|
+
|
|
22
|
+
const isValidSlotTag = (vNode) => {
|
|
23
|
+
return (
|
|
24
|
+
[DISCLOSURE_DROPDOWN_ITEM_NAME, DISCLOSURE_DROPDOWN_GROUP_NAME].includes(vNode.type?.name) ||
|
|
25
|
+
vNode.type === 'li'
|
|
26
|
+
);
|
|
27
|
+
};
|
|
14
28
|
|
|
15
|
-
const
|
|
29
|
+
const hasOnlyListItems = ({ default: defaultSlot }) => {
|
|
30
|
+
if (!isFunction(defaultSlot)) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
const nodes = defaultSlot();
|
|
34
|
+
return (
|
|
35
|
+
Array.isArray(nodes) &&
|
|
36
|
+
nodes.filter((vNode) => vNode.tag).length &&
|
|
37
|
+
(nodes.filter((vNode) => vNode.tag).every(isValidSlotTagVue2) ||
|
|
38
|
+
nodes.filter((vNode) => vNode.tag).every(isValidSlotTag))
|
|
39
|
+
);
|
|
40
|
+
};
|
|
16
41
|
|
|
17
|
-
export { itemsValidator, isItem, isGroup,
|
|
42
|
+
export { itemsValidator, isItem, isGroup, hasOnlyListItems };
|
|
@@ -8,6 +8,7 @@ describe('toggle', () => {
|
|
|
8
8
|
let wrapper;
|
|
9
9
|
|
|
10
10
|
const label = 'toggle label';
|
|
11
|
+
const descriptionText = 'description text';
|
|
11
12
|
const helpText = 'help text';
|
|
12
13
|
|
|
13
14
|
const createWrapper = (props = {}, options = {}) => {
|
|
@@ -21,6 +22,7 @@ describe('toggle', () => {
|
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
const findButton = () => wrapper.find('button');
|
|
25
|
+
const findDescriptionElement = () => wrapper.find('[data-testid="toggle-description"]');
|
|
24
26
|
const findHelpElement = () => wrapper.find('[data-testid="toggle-help"]');
|
|
25
27
|
|
|
26
28
|
it('has role=switch', () => {
|
|
@@ -85,6 +87,28 @@ describe('toggle', () => {
|
|
|
85
87
|
});
|
|
86
88
|
});
|
|
87
89
|
|
|
90
|
+
describe.each`
|
|
91
|
+
state | description | props | options
|
|
92
|
+
${'with description'} | ${descriptionText} | ${{ description: descriptionText }} | ${undefined}
|
|
93
|
+
${'with description in slot'} | ${descriptionText} | ${undefined} | ${{ slots: { description: descriptionText } }}
|
|
94
|
+
${'without description'} | ${undefined} | ${undefined} | ${undefined}
|
|
95
|
+
${'with description and labelPosition left'} | ${undefined} | ${{ desciption: descriptionText, labelPosition: toggleLabelPosition.left }} | ${undefined}
|
|
96
|
+
`('$state', ({ description, props, options }) => {
|
|
97
|
+
beforeEach(() => {
|
|
98
|
+
createWrapper(props, options);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
if (description) {
|
|
102
|
+
it('shows description', () => {
|
|
103
|
+
expect(findDescriptionElement().text()).toBe(description);
|
|
104
|
+
});
|
|
105
|
+
} else {
|
|
106
|
+
it('does not show description', () => {
|
|
107
|
+
expect(findDescriptionElement().exists()).toBe(false);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
88
112
|
describe.each`
|
|
89
113
|
state | help | props | options | getAriaDescribedBy
|
|
90
114
|
${'with help'} | ${helpText} | ${{ help: helpText }} | ${undefined} | ${() => findHelpElement().attributes('id')}
|
|
@@ -5,7 +5,9 @@ import readme from './toggle.md';
|
|
|
5
5
|
|
|
6
6
|
const defaultValue = (prop) => GlToggle.props[prop].default;
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const withDescription = 'A dark color theme that is easier on the eyes.';
|
|
9
|
+
|
|
10
|
+
const longHelp = `This is a toggle component with a long help message.
|
|
9
11
|
You can notice how the text wraps when the width of the container
|
|
10
12
|
is not enough to fix the entire text.`;
|
|
11
13
|
|
|
@@ -15,7 +17,8 @@ const generateProps = ({
|
|
|
15
17
|
isLoading = defaultValue('isLoading'),
|
|
16
18
|
label = 'Dark mode',
|
|
17
19
|
labelId = 'dark-mode-toggle',
|
|
18
|
-
|
|
20
|
+
description = '',
|
|
21
|
+
help = 'Toggle dark mode for the website.',
|
|
19
22
|
labelPosition = defaultValue('labelPosition'),
|
|
20
23
|
} = {}) => ({
|
|
21
24
|
value,
|
|
@@ -23,6 +26,7 @@ const generateProps = ({
|
|
|
23
26
|
isLoading,
|
|
24
27
|
label,
|
|
25
28
|
labelId,
|
|
29
|
+
description,
|
|
26
30
|
help,
|
|
27
31
|
labelPosition,
|
|
28
32
|
});
|
|
@@ -35,6 +39,7 @@ const Template = (args, { argTypes }) => ({
|
|
|
35
39
|
<gl-toggle
|
|
36
40
|
v-model="value"
|
|
37
41
|
:disabled="disabled"
|
|
42
|
+
:description="description"
|
|
38
43
|
:help="help"
|
|
39
44
|
:label-id="labelId"
|
|
40
45
|
:is-loading="isLoading"
|
|
@@ -47,11 +52,21 @@ const Template = (args, { argTypes }) => ({
|
|
|
47
52
|
export const Default = Template.bind({});
|
|
48
53
|
Default.args = generateProps();
|
|
49
54
|
|
|
55
|
+
export const WithDescription = Template.bind({});
|
|
56
|
+
WithDescription.args = generateProps({
|
|
57
|
+
description: withDescription,
|
|
58
|
+
});
|
|
59
|
+
|
|
50
60
|
export const WithLongHelp = Template.bind({});
|
|
51
61
|
WithLongHelp.args = generateProps({
|
|
52
62
|
help: longHelp,
|
|
53
63
|
});
|
|
54
64
|
|
|
65
|
+
export const LabelPositionLeft = Template.bind({});
|
|
66
|
+
LabelPositionLeft.args = generateProps({
|
|
67
|
+
labelPosition: 'left',
|
|
68
|
+
});
|
|
69
|
+
|
|
55
70
|
export default {
|
|
56
71
|
title: 'base/toggle',
|
|
57
72
|
component: GlToggle,
|
|
@@ -71,6 +86,9 @@ export default {
|
|
|
71
86
|
label: {
|
|
72
87
|
control: 'text',
|
|
73
88
|
},
|
|
89
|
+
description: {
|
|
90
|
+
control: 'text',
|
|
91
|
+
},
|
|
74
92
|
help: {
|
|
75
93
|
control: 'text',
|
|
76
94
|
},
|
|
@@ -55,6 +55,14 @@ export default {
|
|
|
55
55
|
type: String,
|
|
56
56
|
required: true,
|
|
57
57
|
},
|
|
58
|
+
/**
|
|
59
|
+
* The toggle's description.
|
|
60
|
+
*/
|
|
61
|
+
description: {
|
|
62
|
+
type: String,
|
|
63
|
+
required: false,
|
|
64
|
+
default: undefined,
|
|
65
|
+
},
|
|
58
66
|
/**
|
|
59
67
|
* A help text to be shown below the toggle.
|
|
60
68
|
*/
|
|
@@ -81,10 +89,20 @@ export default {
|
|
|
81
89
|
};
|
|
82
90
|
},
|
|
83
91
|
computed: {
|
|
92
|
+
shouldRenderDescription() {
|
|
93
|
+
// eslint-disable-next-line @gitlab/vue-prefer-dollar-scopedslots
|
|
94
|
+
return Boolean(this.$scopedSlots.description || this.description) && this.isVerticalLayout;
|
|
95
|
+
},
|
|
84
96
|
shouldRenderHelp() {
|
|
85
97
|
// eslint-disable-next-line @gitlab/vue-prefer-dollar-scopedslots
|
|
86
98
|
return Boolean(this.$slots.help || this.help) && this.isVerticalLayout;
|
|
87
99
|
},
|
|
100
|
+
toggleClasses() {
|
|
101
|
+
return [
|
|
102
|
+
{ 'gl-sr-only': this.labelPosition === 'hidden' },
|
|
103
|
+
this.shouldRenderDescription ? 'gl-mb-2' : 'gl-mb-3',
|
|
104
|
+
];
|
|
105
|
+
},
|
|
88
106
|
icon() {
|
|
89
107
|
return this.value ? 'mobile-issue-close' : 'close';
|
|
90
108
|
},
|
|
@@ -132,13 +150,21 @@ export default {
|
|
|
132
150
|
>
|
|
133
151
|
<span
|
|
134
152
|
:id="labelId"
|
|
135
|
-
:class="
|
|
153
|
+
:class="toggleClasses"
|
|
136
154
|
class="gl-toggle-label gl-flex-shrink-0"
|
|
137
155
|
data-testid="toggle-label"
|
|
138
156
|
>
|
|
139
157
|
<!-- @slot The toggle's label. -->
|
|
140
158
|
<slot name="label">{{ label }}</slot>
|
|
141
159
|
</span>
|
|
160
|
+
<span
|
|
161
|
+
v-if="shouldRenderDescription"
|
|
162
|
+
class="gl-description-label gl-mb-3"
|
|
163
|
+
data-testid="toggle-description"
|
|
164
|
+
>
|
|
165
|
+
<!-- @slot A description text to be shown below the label. -->
|
|
166
|
+
<slot name="description">{{ description }}</slot>
|
|
167
|
+
</span>
|
|
142
168
|
<input v-if="name" :name="name" :value="value" type="hidden" />
|
|
143
169
|
<button
|
|
144
170
|
role="switch"
|