@gitlab/ui 64.20.0 → 64.21.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 +21 -0
- package/dist/components/base/toggle/toggle.js +38 -17
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -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/dist/utility_classes.css +1 -1
- package/dist/utility_classes.css.map +1 -1
- package/dist/utils/constants.js +1 -0
- package/package.json +2 -2
- package/src/components/base/new_dropdowns/listbox/listbox.scss +1 -0
- package/src/components/base/toggle/toggle.scss +35 -6
- package/src/components/base/toggle/toggle.spec.js +38 -26
- package/src/components/base/toggle/toggle.stories.js +6 -0
- package/src/components/base/toggle/toggle.vue +76 -55
- package/src/scss/utilities.scss +8 -0
- package/src/scss/utility-mixins/flex.scss +4 -0
- package/src/utils/constants.js +1 -0
package/dist/utils/constants.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gitlab/ui",
|
|
3
|
-
"version": "64.
|
|
3
|
+
"version": "64.21.0",
|
|
4
4
|
"description": "GitLab UI Components",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
"babel-loader": "^8.0.5",
|
|
119
119
|
"babel-plugin-require-context-hook": "^1.0.0",
|
|
120
120
|
"bootstrap": "4.6.2",
|
|
121
|
-
"cypress": "12.17.
|
|
121
|
+
"cypress": "12.17.1",
|
|
122
122
|
"emoji-regex": "^10.0.0",
|
|
123
123
|
"eslint": "8.44.0",
|
|
124
124
|
"eslint-import-resolver-jest": "3.0.2",
|
|
@@ -9,6 +9,7 @@ $clear-button-size: 24px;
|
|
|
9
9
|
@include gl-line-height-normal;
|
|
10
10
|
@include gl-h-auto;
|
|
11
11
|
@include gl-border-none;
|
|
12
|
+
@include gl-rounded-0;
|
|
12
13
|
padding-left: calc(#{$gl-spacing-scale-7} + #{$gl-spacing-scale-2});
|
|
13
14
|
padding-right: calc(#{$gl-spacing-scale-6} + #{$gl-spacing-scale-2});
|
|
14
15
|
@include gl-py-4;
|
|
@@ -29,18 +29,18 @@
|
|
|
29
29
|
.gl-toggle {
|
|
30
30
|
@include gl-cursor-not-allowed;
|
|
31
31
|
@include gl-bg-gray-200;
|
|
32
|
+
}
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
34
|
+
.toggle-icon > svg {
|
|
35
|
+
@include gl-fill-gray-200;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
.gl-toggle.is-checked {
|
|
39
39
|
@include gl-bg-blue-200;
|
|
40
|
+
}
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
42
|
+
.toggle-icon > svg {
|
|
43
|
+
@include gl-fill-blue-200;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
.gl-toggle-label,
|
|
@@ -50,6 +50,35 @@
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
.gl-toggle-label-container {
|
|
54
|
+
@include gl-flex-shrink-0;
|
|
55
|
+
@include gl-display-flex;
|
|
56
|
+
@include gl-flex-direction-column;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.gl-toggle-switch-container {
|
|
60
|
+
@include gl-display-flex;
|
|
61
|
+
@include gl-flex-direction-column;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.gl-toggle-label-position-block {
|
|
65
|
+
@include gl-justify-content-space-between;
|
|
66
|
+
@include gl-align-items-center;
|
|
67
|
+
@include gl-w-full;
|
|
68
|
+
@include gl-gap-3;
|
|
69
|
+
|
|
70
|
+
.gl-toggle-label-container {
|
|
71
|
+
@include gl-gap-2;
|
|
72
|
+
@include gl-flex-shrink-1;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.gl-toggle-switch-container {
|
|
76
|
+
@include gl-align-items-flex-end;
|
|
77
|
+
@include gl-gap-2;
|
|
78
|
+
@include gl-flex-shrink-1;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
53
82
|
.gl-help-label {
|
|
54
83
|
@include gl-mt-3;
|
|
55
84
|
@include gl-text-gray-500;
|
|
@@ -138,31 +138,43 @@ describe('toggle', () => {
|
|
|
138
138
|
|
|
139
139
|
describe('label position', () => {
|
|
140
140
|
describe.each`
|
|
141
|
-
state | labelPosition | hasGlSrOnlyClass | flexDirection
|
|
142
|
-
${'top'} | ${toggleLabelPosition.top} | ${false} | ${'gl-flex-direction-column'}
|
|
143
|
-
${'left'} | ${toggleLabelPosition.left} | ${false} | ${'gl-toggle-label-inline'}
|
|
144
|
-
${'hidden'} | ${toggleLabelPosition.hidden} | ${true} | ${'gl-flex-direction-column'}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
141
|
+
state | labelPosition | hasGlSrOnlyClass | flexDirection | showsHelpText | showsDescription
|
|
142
|
+
${'top'} | ${toggleLabelPosition.top} | ${false} | ${'gl-flex-direction-column'} | ${true} | ${true}
|
|
143
|
+
${'left'} | ${toggleLabelPosition.left} | ${false} | ${'gl-toggle-label-inline'} | ${false} | ${false}
|
|
144
|
+
${'hidden'} | ${toggleLabelPosition.hidden} | ${true} | ${'gl-flex-direction-column'} | ${true} | ${true}
|
|
145
|
+
${'block'} | ${toggleLabelPosition.block} | ${false} | ${'gl-toggle-label-inline'} | ${true} | ${true}
|
|
146
|
+
`(
|
|
147
|
+
'when $state',
|
|
148
|
+
({ labelPosition, hasGlSrOnlyClass, flexDirection, showsHelpText, showsDescription }) => {
|
|
149
|
+
beforeEach(() => {
|
|
150
|
+
createWrapper({ labelPosition, help: helpText, description: descriptionText });
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it(`${flexDirection} class is added to the label`, () => {
|
|
154
|
+
const cssClasses = wrapper.find('[data-testid="toggle-wrapper"]').classes();
|
|
155
|
+
|
|
156
|
+
expect(cssClasses).toContain(flexDirection);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it(`${hasGlSrOnlyClass ? 'adds' : 'does not add'} 'gl-sr-only' class to the label`, () => {
|
|
160
|
+
const cssClasses = wrapper.find('[data-testid="toggle-label"]').classes();
|
|
161
|
+
return hasGlSrOnlyClass
|
|
162
|
+
? expect(cssClasses).toContain('gl-sr-only')
|
|
163
|
+
: expect(cssClasses).not.toContain('gl-sr-only');
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('has accessible name for the button', () => {
|
|
167
|
+
expect(findButton().attributes('aria-labelledby')).toBeDefined();
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it(`${showsHelpText ? 'shows' : 'does not show'} the help text`, () => {
|
|
171
|
+
expect(findHelpElement().exists()).toBe(showsHelpText);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it(`${showsDescription ? 'shows' : 'does not show'} the description`, () => {
|
|
175
|
+
expect(findDescriptionElement().exists()).toBe(showsDescription);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
);
|
|
167
179
|
});
|
|
168
180
|
});
|
|
@@ -67,6 +67,12 @@ LabelPositionLeft.args = generateProps({
|
|
|
67
67
|
labelPosition: 'left',
|
|
68
68
|
});
|
|
69
69
|
|
|
70
|
+
export const LabelPositionBlock = Template.bind({});
|
|
71
|
+
LabelPositionBlock.args = generateProps({
|
|
72
|
+
labelPosition: 'block',
|
|
73
|
+
description: withDescription,
|
|
74
|
+
});
|
|
75
|
+
|
|
70
76
|
export default {
|
|
71
77
|
title: 'base/toggle',
|
|
72
78
|
component: GlToggle,
|
|
@@ -90,19 +90,42 @@ export default {
|
|
|
90
90
|
};
|
|
91
91
|
},
|
|
92
92
|
computed: {
|
|
93
|
+
layoutAllowsDescription() {
|
|
94
|
+
return this.isVerticalLayout || this.isBlockLayout;
|
|
95
|
+
},
|
|
93
96
|
shouldRenderDescription() {
|
|
94
|
-
|
|
95
|
-
|
|
97
|
+
return (
|
|
98
|
+
Boolean(this.$scopedSlots.description || this.description) && this.layoutAllowsDescription
|
|
99
|
+
);
|
|
96
100
|
},
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return Boolean(this.$slots.help || this.help) && this.isVerticalLayout;
|
|
101
|
+
labelIsSrOnly() {
|
|
102
|
+
return this.labelPosition === 'hidden';
|
|
100
103
|
},
|
|
101
|
-
|
|
102
|
-
return
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
layoutAllowsHelp() {
|
|
105
|
+
return this.isVerticalLayout || this.isBlockLayout;
|
|
106
|
+
},
|
|
107
|
+
shouldRenderHelp() {
|
|
108
|
+
return Boolean(this.$scopedSlots.help || this.help) && this.layoutAllowsHelp;
|
|
109
|
+
},
|
|
110
|
+
labelContainerClasses() {
|
|
111
|
+
return {
|
|
112
|
+
'gl-mb-3': this.isVerticalLayout && !this.labelIsSrOnly,
|
|
113
|
+
};
|
|
114
|
+
},
|
|
115
|
+
labelClasses() {
|
|
116
|
+
if (this.labelIsSrOnly) return 'gl-sr-only';
|
|
117
|
+
return {
|
|
118
|
+
'gl-mb-2': this.shouldRenderDescription,
|
|
119
|
+
'gl-mb-3': !this.shouldRenderDescription && !this.isVerticalLayout,
|
|
120
|
+
};
|
|
121
|
+
},
|
|
122
|
+
wrapperClasses() {
|
|
123
|
+
return {
|
|
124
|
+
'gl-flex-direction-column': this.isVerticalLayout,
|
|
125
|
+
'gl-toggle-label-inline': !this.isVerticalLayout,
|
|
126
|
+
'is-disabled': this.disabled,
|
|
127
|
+
'gl-toggle-label-position-block': this.isBlockLayout,
|
|
128
|
+
};
|
|
106
129
|
},
|
|
107
130
|
icon() {
|
|
108
131
|
return this.value ? 'mobile-issue-close' : 'close';
|
|
@@ -116,6 +139,9 @@ export default {
|
|
|
116
139
|
isVerticalLayout() {
|
|
117
140
|
return this.labelPosition === 'top' || this.labelPosition === 'hidden';
|
|
118
141
|
},
|
|
142
|
+
isBlockLayout() {
|
|
143
|
+
return this.labelPosition === 'block';
|
|
144
|
+
},
|
|
119
145
|
},
|
|
120
146
|
|
|
121
147
|
beforeCreate() {
|
|
@@ -141,55 +167,50 @@ export default {
|
|
|
141
167
|
|
|
142
168
|
<template>
|
|
143
169
|
<div
|
|
144
|
-
class="gl-toggle-wrapper gl-display-flex gl-mb-0"
|
|
145
|
-
:class="
|
|
146
|
-
'gl-flex-direction-column': isVerticalLayout,
|
|
147
|
-
'gl-toggle-label-inline': !isVerticalLayout,
|
|
148
|
-
'is-disabled': disabled,
|
|
149
|
-
}"
|
|
170
|
+
class="gl-toggle-wrapper gl-display-flex gl-mb-0 flex-grow-1"
|
|
171
|
+
:class="wrapperClasses"
|
|
150
172
|
data-testid="toggle-wrapper"
|
|
151
173
|
>
|
|
152
|
-
<span
|
|
153
|
-
:id="labelId"
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
>
|
|
166
|
-
<!-- @slot A description text to be shown below the label. -->
|
|
167
|
-
<slot name="description">{{ description }}</slot>
|
|
174
|
+
<span :class="labelContainerClasses" class="gl-toggle-label-container">
|
|
175
|
+
<span :id="labelId" :class="labelClasses" class="gl-toggle-label" data-testid="toggle-label">
|
|
176
|
+
<!-- @slot The toggle's label. -->
|
|
177
|
+
<slot name="label">{{ label }}</slot>
|
|
178
|
+
</span>
|
|
179
|
+
<span
|
|
180
|
+
v-if="shouldRenderDescription"
|
|
181
|
+
class="gl-description-label"
|
|
182
|
+
data-testid="toggle-description"
|
|
183
|
+
>
|
|
184
|
+
<!-- @slot A description text to be shown below the label. -->
|
|
185
|
+
<slot name="description">{{ description }}</slot>
|
|
186
|
+
</span>
|
|
168
187
|
</span>
|
|
169
|
-
<
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
<
|
|
188
|
+
<span class="gl-toggle-switch-container">
|
|
189
|
+
<input v-if="name" :name="name" :value="value" type="hidden" />
|
|
190
|
+
<button
|
|
191
|
+
role="switch"
|
|
192
|
+
:aria-checked="isChecked"
|
|
193
|
+
:aria-labelledby="labelId"
|
|
194
|
+
:aria-describedby="helpId"
|
|
195
|
+
:aria-disabled="disabled"
|
|
196
|
+
:class="{
|
|
197
|
+
'gl-toggle': true,
|
|
198
|
+
'is-checked': value,
|
|
199
|
+
'is-disabled': disabled,
|
|
200
|
+
}"
|
|
201
|
+
class="gl-flex-shrink-0"
|
|
202
|
+
type="button"
|
|
203
|
+
@click.prevent="toggleFeature"
|
|
204
|
+
>
|
|
205
|
+
<gl-loading-icon v-if="isLoading" color="light" class="toggle-loading" />
|
|
206
|
+
<span v-else :class="{ 'toggle-icon': true, disabled: disabled }">
|
|
207
|
+
<gl-icon :name="icon" :size="16" />
|
|
208
|
+
</span>
|
|
209
|
+
</button>
|
|
210
|
+
<span v-if="shouldRenderHelp" :id="helpId" class="gl-help-label" data-testid="toggle-help">
|
|
211
|
+
<!-- @slot A help text to be shown below the toggle. -->
|
|
212
|
+
<slot name="help">{{ help }}</slot>
|
|
188
213
|
</span>
|
|
189
|
-
</button>
|
|
190
|
-
<span v-if="shouldRenderHelp" :id="helpId" class="gl-help-label" data-testid="toggle-help">
|
|
191
|
-
<!-- @slot A help text to be shown below the toggle. -->
|
|
192
|
-
<slot name="help">{{ help }}</slot>
|
|
193
214
|
</span>
|
|
194
215
|
</div>
|
|
195
216
|
</template>
|
package/src/scss/utilities.scss
CHANGED