@gitlab/ui 66.12.0 → 66.13.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/broadcast_message/broadcast_message.js +1 -1
- package/dist/components/base/datepicker/datepicker.js +29 -6
- package/dist/components/base/form/form_input/form_input.js +24 -4
- package/dist/components/base/form/form_select/form_select.js +24 -4
- 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 +7 -1
- package/package.json +17 -17
- package/src/components/base/broadcast_message/broadcast_message.scss +7 -0
- package/src/components/base/broadcast_message/broadcast_message.vue +2 -2
- package/src/components/base/datepicker/datepicker.spec.js +17 -0
- package/src/components/base/datepicker/datepicker.stories.js +20 -4
- package/src/components/base/datepicker/datepicker.vue +33 -5
- package/src/components/base/form/form_input/form_input.spec.js +52 -0
- package/src/components/base/form/form_input/form_input.stories.js +10 -0
- package/src/components/base/form/form_input/form_input.vue +25 -4
- package/src/components/base/form/form_select/form_select.spec.js +25 -0
- package/src/components/base/form/form_select/form_select.stories.js +7 -0
- package/src/components/base/form/form_select/form_select.vue +25 -4
- package/src/scss/utilities.scss +2 -2
- package/src/scss/utility-mixins/text.scss +1 -1
- package/src/utils/constants.js +7 -0
package/dist/utils/constants.js
CHANGED
|
@@ -123,6 +123,12 @@ const datepickerSizeOptionsMap = {
|
|
|
123
123
|
small: 'sm',
|
|
124
124
|
medium: 'md'
|
|
125
125
|
};
|
|
126
|
+
const datepickerWidthOptionsMap = {
|
|
127
|
+
sm: 'sm',
|
|
128
|
+
md: 'md',
|
|
129
|
+
lg: 'lg',
|
|
130
|
+
xl: 'xl'
|
|
131
|
+
};
|
|
126
132
|
|
|
127
133
|
// size options all have corresponding styles (e.g. .s12 defined in icon.scss)
|
|
128
134
|
const iconSizeOptions = glIconSizes.split(' ').map(Number);
|
|
@@ -267,4 +273,4 @@ const loadingIconVariants = {
|
|
|
267
273
|
dots: 'dots'
|
|
268
274
|
};
|
|
269
275
|
|
|
270
|
-
export { COMMA, LEFT_MOUSE_BUTTON, alertVariantIconMap, alertVariantOptions, alignOptions, avatarShapeOptions, avatarSizeOptions, avatarsInlineSizeOptions, badgeForButtonOptions, badgeIconSizeOptions, badgeSizeOptions, badgeVariantOptions, bannerVariants, buttonCategoryOptions, buttonSizeOptions, buttonVariantOptions, colorThemes, columnOptions, datepickerSizeOptionsMap, defaultDateFormat, drawerVariants, dropdownAllowedAutoPlacements, dropdownPlacements, dropdownVariantOptions, focusableTags, formInputSizes, formStateOptions, glThemes, iconSizeOptions, keyboard, labelColorOptions, labelSizeOptions, loadingIconSizes, loadingIconVariants, maxZIndex, modalButtonDefaults, modalSizeOptions, popoverPlacements, resizeDebounceTime, tabsButtonDefaults, targetOptions, toggleLabelPosition, tokenVariants, tooltipActionEvents, tooltipDelay, tooltipPlacements, triggerVariantOptions, truncateOptions, variantCssColorMap, variantOptions, variantOptionsWithNoDefault, viewModeOptions };
|
|
276
|
+
export { COMMA, LEFT_MOUSE_BUTTON, alertVariantIconMap, alertVariantOptions, alignOptions, avatarShapeOptions, avatarSizeOptions, avatarsInlineSizeOptions, badgeForButtonOptions, badgeIconSizeOptions, badgeSizeOptions, badgeVariantOptions, bannerVariants, buttonCategoryOptions, buttonSizeOptions, buttonVariantOptions, colorThemes, columnOptions, datepickerSizeOptionsMap, datepickerWidthOptionsMap, defaultDateFormat, drawerVariants, dropdownAllowedAutoPlacements, dropdownPlacements, dropdownVariantOptions, focusableTags, formInputSizes, formStateOptions, glThemes, iconSizeOptions, keyboard, labelColorOptions, labelSizeOptions, loadingIconSizes, loadingIconVariants, maxZIndex, modalButtonDefaults, modalSizeOptions, popoverPlacements, resizeDebounceTime, tabsButtonDefaults, targetOptions, toggleLabelPosition, tokenVariants, tooltipActionEvents, tooltipDelay, tooltipPlacements, triggerVariantOptions, truncateOptions, variantCssColorMap, variantOptions, variantOptionsWithNoDefault, viewModeOptions };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gitlab/ui",
|
|
3
|
-
"version": "66.
|
|
3
|
+
"version": "66.13.1",
|
|
4
4
|
"description": "GitLab UI Components",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -94,22 +94,22 @@
|
|
|
94
94
|
"@gitlab/eslint-plugin": "19.0.0",
|
|
95
95
|
"@gitlab/fonts": "^1.2.0",
|
|
96
96
|
"@gitlab/stylelint-config": "5.0.0",
|
|
97
|
-
"@gitlab/svgs": "3.
|
|
97
|
+
"@gitlab/svgs": "3.63.0",
|
|
98
98
|
"@rollup/plugin-commonjs": "^11.1.0",
|
|
99
99
|
"@rollup/plugin-node-resolve": "^7.1.3",
|
|
100
100
|
"@rollup/plugin-replace": "^2.3.2",
|
|
101
|
-
"@storybook/addon-a11y": "7.4.
|
|
102
|
-
"@storybook/addon-docs": "7.4.
|
|
103
|
-
"@storybook/addon-essentials": "7.4.
|
|
104
|
-
"@storybook/addon-storyshots": "7.4.
|
|
105
|
-
"@storybook/addon-storyshots-puppeteer": "7.4.
|
|
106
|
-
"@storybook/addon-viewport": "7.4.
|
|
107
|
-
"@storybook/builder-webpack5": "7.4.
|
|
108
|
-
"@storybook/theming": "7.4.
|
|
109
|
-
"@storybook/vue": "7.4.
|
|
110
|
-
"@storybook/vue-webpack5": "7.4.
|
|
111
|
-
"@storybook/vue3": "7.4.
|
|
112
|
-
"@storybook/vue3-webpack5": "7.4.
|
|
101
|
+
"@storybook/addon-a11y": "7.4.3",
|
|
102
|
+
"@storybook/addon-docs": "7.4.3",
|
|
103
|
+
"@storybook/addon-essentials": "7.4.3",
|
|
104
|
+
"@storybook/addon-storyshots": "7.4.3",
|
|
105
|
+
"@storybook/addon-storyshots-puppeteer": "7.4.3",
|
|
106
|
+
"@storybook/addon-viewport": "7.4.3",
|
|
107
|
+
"@storybook/builder-webpack5": "7.4.3",
|
|
108
|
+
"@storybook/theming": "7.4.3",
|
|
109
|
+
"@storybook/vue": "7.4.3",
|
|
110
|
+
"@storybook/vue-webpack5": "7.4.3",
|
|
111
|
+
"@storybook/vue3": "7.4.3",
|
|
112
|
+
"@storybook/vue3-webpack5": "7.4.3",
|
|
113
113
|
"@vue/compat": "^3.2.40",
|
|
114
114
|
"@vue/compiler-sfc": "^3.2.40",
|
|
115
115
|
"@vue/test-utils": "1.3.0",
|
|
@@ -128,8 +128,8 @@
|
|
|
128
128
|
"emoji-regex": "^10.0.0",
|
|
129
129
|
"eslint": "8.49.0",
|
|
130
130
|
"eslint-import-resolver-jest": "3.0.2",
|
|
131
|
-
"eslint-plugin-cypress": "2.
|
|
132
|
-
"eslint-plugin-storybook": "0.6.
|
|
131
|
+
"eslint-plugin-cypress": "2.15.1",
|
|
132
|
+
"eslint-plugin-storybook": "0.6.14",
|
|
133
133
|
"glob": "10.3.3",
|
|
134
134
|
"identity-obj-proxy": "^3.0.0",
|
|
135
135
|
"inquirer-select-directory": "^1.2.0",
|
|
@@ -160,7 +160,7 @@
|
|
|
160
160
|
"sass-loader": "^10.2.0",
|
|
161
161
|
"sass-true": "^6.1.0",
|
|
162
162
|
"start-server-and-test": "^1.10.6",
|
|
163
|
-
"storybook": "7.4.
|
|
163
|
+
"storybook": "7.4.3",
|
|
164
164
|
"storybook-dark-mode": "3.0.1",
|
|
165
165
|
"style-dictionary": "^3.8.0",
|
|
166
166
|
"stylelint": "15.10.2",
|
|
@@ -79,12 +79,19 @@
|
|
|
79
79
|
|
|
80
80
|
&-icon {
|
|
81
81
|
@include gl-mr-5;
|
|
82
|
+
line-height: $gl-line-height-16;
|
|
82
83
|
|
|
83
84
|
> svg {
|
|
84
85
|
@include gl-vertical-align-bottom;
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
|
|
89
|
+
&-text {
|
|
90
|
+
margin-top: -$gl-spacing-scale-1;
|
|
91
|
+
margin-bottom: -$gl-spacing-scale-1;
|
|
92
|
+
@include gl-overflow-break-word;
|
|
93
|
+
}
|
|
94
|
+
|
|
88
95
|
&-dismiss {
|
|
89
96
|
@include gl-my-n2;
|
|
90
97
|
@include gl-ml-5;
|
|
@@ -77,10 +77,10 @@ export default {
|
|
|
77
77
|
<template>
|
|
78
78
|
<div class="gl-broadcast-message" :class="`${theme} ${type}`">
|
|
79
79
|
<div class="gl-broadcast-message-content">
|
|
80
|
-
<div class="gl-broadcast-message-icon
|
|
80
|
+
<div class="gl-broadcast-message-icon">
|
|
81
81
|
<gl-icon :name="iconName" />
|
|
82
82
|
</div>
|
|
83
|
-
<div class="gl-
|
|
83
|
+
<div class="gl-broadcast-message-text">
|
|
84
84
|
<h2 class="gl-sr-only">Admin message</h2>
|
|
85
85
|
<!-- @slot The broadcast message's text -->
|
|
86
86
|
<slot></slot>
|
|
@@ -426,4 +426,21 @@ describe('datepicker component', () => {
|
|
|
426
426
|
|
|
427
427
|
expect(wrapper.classes()).toContain(expectedClass);
|
|
428
428
|
});
|
|
429
|
+
|
|
430
|
+
it.each`
|
|
431
|
+
width | expectedClass
|
|
432
|
+
${undefined} | ${'gl-form-input-md'}
|
|
433
|
+
${'sm'} | ${'gl-form-input-sm'}
|
|
434
|
+
${'md'} | ${'gl-form-input-md'}
|
|
435
|
+
${'lg'} | ${'gl-form-input-lg'}
|
|
436
|
+
${'xl'} | ${'gl-form-input-xl'}
|
|
437
|
+
`('applies $expectedClass class when width is $width', ({ width, expectedClass }) => {
|
|
438
|
+
const wrapper = mountWithOptions({
|
|
439
|
+
propsData: {
|
|
440
|
+
width,
|
|
441
|
+
},
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
expect(wrapper.classes()).toContain(expectedClass);
|
|
445
|
+
});
|
|
429
446
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import GlFormGroup from '../form/form_group/form_group.vue';
|
|
2
|
+
import { datepickerWidthOptionsMap, datepickerSizeOptionsMap } from '../../../utils/constants';
|
|
2
3
|
import { disableControls } from '../../../utils/stories_utils';
|
|
3
4
|
import { useFakeDate } from '../../../utils/use_fake_date';
|
|
4
5
|
import { makeContainer } from '../../../utils/story_decorators/container';
|
|
@@ -69,16 +70,23 @@ export const DifferentSizes = (_args, { argTypes }) => ({
|
|
|
69
70
|
props: Object.keys(argTypes),
|
|
70
71
|
data() {
|
|
71
72
|
return {
|
|
73
|
+
datepickerWidthOptionsMap,
|
|
72
74
|
pickerValue: defaultDate,
|
|
73
75
|
};
|
|
74
76
|
},
|
|
75
77
|
template: `
|
|
76
78
|
<div class="gl-display-flex gl-flex-direction-column gl-gap-3">
|
|
77
|
-
<gl-form-group label="
|
|
78
|
-
<gl-datepicker showClearButton :max-date="maxDate" :min-date="minDate" v-model="pickerValue"
|
|
79
|
+
<gl-form-group label="Width: sm">
|
|
80
|
+
<gl-datepicker showClearButton :max-date="maxDate" :min-date="minDate" v-model="pickerValue" width="sm" />
|
|
79
81
|
</gl-form-group>
|
|
80
|
-
<gl-form-group label="
|
|
81
|
-
<gl-datepicker showClearButton :max-date="maxDate" :min-date="minDate" v-model="pickerValue"
|
|
82
|
+
<gl-form-group label="Width: md (default)">
|
|
83
|
+
<gl-datepicker showClearButton :max-date="maxDate" :min-date="minDate" v-model="pickerValue" width="md" />
|
|
84
|
+
</gl-form-group>
|
|
85
|
+
<gl-form-group label="Width: lg">
|
|
86
|
+
<gl-datepicker showClearButton :max-date="maxDate" :min-date="minDate" v-model="pickerValue" width="lg" />
|
|
87
|
+
</gl-form-group>
|
|
88
|
+
<gl-form-group label="Width: xl">
|
|
89
|
+
<gl-datepicker showClearButton :max-date="maxDate" :min-date="minDate" v-model="pickerValue" width="xl" />
|
|
82
90
|
</gl-form-group>
|
|
83
91
|
</div>
|
|
84
92
|
`,
|
|
@@ -125,5 +133,13 @@ export default {
|
|
|
125
133
|
maxDate: {
|
|
126
134
|
control: 'date',
|
|
127
135
|
},
|
|
136
|
+
width: {
|
|
137
|
+
options: datepickerWidthOptionsMap,
|
|
138
|
+
control: 'select',
|
|
139
|
+
},
|
|
140
|
+
size: {
|
|
141
|
+
options: datepickerSizeOptionsMap,
|
|
142
|
+
control: 'select',
|
|
143
|
+
},
|
|
128
144
|
},
|
|
129
145
|
};
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
<script>
|
|
3
3
|
import isString from 'lodash/isString';
|
|
4
4
|
import Pikaday from 'pikaday';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
defaultDateFormat,
|
|
7
|
+
datepickerWidthOptionsMap,
|
|
8
|
+
datepickerSizeOptionsMap,
|
|
9
|
+
} from '../../../utils/constants';
|
|
6
10
|
import { areDatesEqual } from '../../../utils/datetime_utility';
|
|
7
11
|
import GlButton from '../button/button.vue';
|
|
8
12
|
import GlFormInput from '../form/form_input/form_input.vue';
|
|
@@ -172,10 +176,27 @@ export default {
|
|
|
172
176
|
required: false,
|
|
173
177
|
default: null,
|
|
174
178
|
},
|
|
179
|
+
/**
|
|
180
|
+
* Maximum width of the Datepicker
|
|
181
|
+
*/
|
|
182
|
+
width: {
|
|
183
|
+
type: String,
|
|
184
|
+
required: false,
|
|
185
|
+
default: null,
|
|
186
|
+
validator: (value) => Object.keys(datepickerWidthOptionsMap).includes(value),
|
|
187
|
+
},
|
|
188
|
+
/**
|
|
189
|
+
* ⚠️ DEPRECATED:
|
|
190
|
+
*
|
|
191
|
+
* Will be replaced by the
|
|
192
|
+
* property width
|
|
193
|
+
*
|
|
194
|
+
* Maximum width of the Datepicker
|
|
195
|
+
*/
|
|
175
196
|
size: {
|
|
176
197
|
type: String,
|
|
177
198
|
required: false,
|
|
178
|
-
default:
|
|
199
|
+
default: null,
|
|
179
200
|
validator: (value) => Object.keys(datepickerSizeOptionsMap).includes(value),
|
|
180
201
|
},
|
|
181
202
|
},
|
|
@@ -216,11 +237,18 @@ export default {
|
|
|
216
237
|
'gl-datepicker',
|
|
217
238
|
'd-inline-block',
|
|
218
239
|
'gl-w-full',
|
|
219
|
-
`gl-form-input-${this.
|
|
240
|
+
`gl-form-input-${this.computedWidth}`,
|
|
220
241
|
];
|
|
221
242
|
},
|
|
222
|
-
|
|
223
|
-
|
|
243
|
+
computedWidth() {
|
|
244
|
+
if (this.width) {
|
|
245
|
+
return this.width;
|
|
246
|
+
// eslint-disable-next-line no-else-return
|
|
247
|
+
} else if (this.size) {
|
|
248
|
+
return datepickerSizeOptionsMap[this.size];
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return 'md';
|
|
224
252
|
},
|
|
225
253
|
},
|
|
226
254
|
watch: {
|
|
@@ -66,6 +66,58 @@ describe('GlFormInput', () => {
|
|
|
66
66
|
});
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
+
describe('width prop', () => {
|
|
70
|
+
describe('when number is passed', () => {
|
|
71
|
+
// Exclude the default null value
|
|
72
|
+
const widths = Object.values(formInputSizes).filter(Boolean);
|
|
73
|
+
|
|
74
|
+
it.each(widths)('adds correct class for width %s', (width) => {
|
|
75
|
+
createComponent({ width });
|
|
76
|
+
|
|
77
|
+
expect(wrapper.classes()).toEqual(['gl-form-input', `gl-form-input-${width}`]);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('does not add a width class if not given the width prop', () => {
|
|
81
|
+
createComponent();
|
|
82
|
+
|
|
83
|
+
expect(wrapper.classes()).toEqual(['gl-form-input']);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('does not add a width class if passed null', () => {
|
|
87
|
+
createComponent({ width: null });
|
|
88
|
+
|
|
89
|
+
expect(wrapper.classes()).toEqual(['gl-form-input']);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
describe('when object is passed', () => {
|
|
94
|
+
describe('when `default` key is provided', () => {
|
|
95
|
+
it('adds responsive CSS classes and base class', () => {
|
|
96
|
+
createComponent({ width: { default: 'md', md: 'lg', lg: 'xl' } });
|
|
97
|
+
|
|
98
|
+
expect(wrapper.classes()).toEqual([
|
|
99
|
+
'gl-form-input',
|
|
100
|
+
'gl-form-input-md',
|
|
101
|
+
'gl-md-form-input-lg',
|
|
102
|
+
'gl-lg-form-input-xl',
|
|
103
|
+
]);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
describe('when `default` key is not provided', () => {
|
|
108
|
+
it('adds responsive CSS classes', () => {
|
|
109
|
+
createComponent({ width: { md: 'lg', lg: 'xl' } });
|
|
110
|
+
|
|
111
|
+
expect(wrapper.classes()).toEqual([
|
|
112
|
+
'gl-form-input',
|
|
113
|
+
'gl-md-form-input-lg',
|
|
114
|
+
'gl-lg-form-input-xl',
|
|
115
|
+
]);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
69
121
|
describe('v-model', () => {
|
|
70
122
|
beforeEach(() => {
|
|
71
123
|
createComponent({}, mount);
|
|
@@ -8,15 +8,18 @@ const template = `
|
|
|
8
8
|
:readonly="readonly"
|
|
9
9
|
:disabled="disabled"
|
|
10
10
|
:value="value"
|
|
11
|
+
:width="width"
|
|
11
12
|
:size="size"
|
|
12
13
|
/>`;
|
|
13
14
|
|
|
14
15
|
const generateProps = ({
|
|
16
|
+
width = GlFormInput.props.size.default,
|
|
15
17
|
size = GlFormInput.props.size.default,
|
|
16
18
|
value = '',
|
|
17
19
|
disabled = false,
|
|
18
20
|
readonly = false,
|
|
19
21
|
} = {}) => ({
|
|
22
|
+
width,
|
|
20
23
|
size,
|
|
21
24
|
value,
|
|
22
25
|
disabled,
|
|
@@ -49,6 +52,7 @@ export const Sizes = (args, { argTypes }) => ({
|
|
|
49
52
|
<gl-form-input
|
|
50
53
|
v-for="(size, name) in formInputSizes"
|
|
51
54
|
:key="size"
|
|
55
|
+
:width="width"
|
|
52
56
|
:size="size"
|
|
53
57
|
:value="name"
|
|
54
58
|
/>
|
|
@@ -63,11 +67,13 @@ export const ResponsiveSizes = (args, { argTypes }) => ({
|
|
|
63
67
|
template: `
|
|
64
68
|
<div>
|
|
65
69
|
<gl-form-input
|
|
70
|
+
:width="{ default: 'md', md: 'lg', lg: 'xl' }"
|
|
66
71
|
:size="{ default: 'md', md: 'lg', lg: 'xl' }"
|
|
67
72
|
value="With \`default\` key"
|
|
68
73
|
/>
|
|
69
74
|
<gl-form-input
|
|
70
75
|
class="gl-mt-4"
|
|
76
|
+
:width="{ md: 'lg', lg: 'xl' }"
|
|
71
77
|
:size="{ md: 'lg', lg: 'xl' }"
|
|
72
78
|
value="Without \`default\` key"
|
|
73
79
|
/>
|
|
@@ -88,6 +94,10 @@ export default {
|
|
|
88
94
|
},
|
|
89
95
|
},
|
|
90
96
|
argTypes: {
|
|
97
|
+
width: {
|
|
98
|
+
options: formInputSizes,
|
|
99
|
+
control: 'select',
|
|
100
|
+
},
|
|
91
101
|
size: {
|
|
92
102
|
options: formInputSizes,
|
|
93
103
|
control: 'select',
|
|
@@ -21,6 +21,24 @@ export default {
|
|
|
21
21
|
/**
|
|
22
22
|
* Maximum width of the input
|
|
23
23
|
*/
|
|
24
|
+
width: {
|
|
25
|
+
type: [String, Object],
|
|
26
|
+
required: false,
|
|
27
|
+
default: null,
|
|
28
|
+
validator: (value) => {
|
|
29
|
+
const widths = isObject(value) ? Object.values(value) : [value];
|
|
30
|
+
|
|
31
|
+
return widths.every((width) => Object.values(formInputSizes).includes(width));
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
/**
|
|
35
|
+
* ⚠️ DEPRECATED:
|
|
36
|
+
*
|
|
37
|
+
* Will be replaced by the
|
|
38
|
+
* property width
|
|
39
|
+
*
|
|
40
|
+
* Maximum width of the input
|
|
41
|
+
*/
|
|
24
42
|
size: {
|
|
25
43
|
type: [String, Object],
|
|
26
44
|
required: false,
|
|
@@ -33,13 +51,16 @@ export default {
|
|
|
33
51
|
},
|
|
34
52
|
},
|
|
35
53
|
computed: {
|
|
54
|
+
computedWidth() {
|
|
55
|
+
return this.width ? this.width : this.size;
|
|
56
|
+
},
|
|
36
57
|
cssClasses() {
|
|
37
|
-
if (this.
|
|
58
|
+
if (this.computedWidth === null) {
|
|
38
59
|
return [];
|
|
39
60
|
}
|
|
40
61
|
|
|
41
|
-
if (isObject(this.
|
|
42
|
-
const { default: defaultSize, ...nonDefaultSizes } = this.
|
|
62
|
+
if (isObject(this.computedWidth)) {
|
|
63
|
+
const { default: defaultSize, ...nonDefaultSizes } = this.computedWidth;
|
|
43
64
|
|
|
44
65
|
return [
|
|
45
66
|
...(defaultSize ? [`gl-form-input-${defaultSize}`] : []),
|
|
@@ -49,7 +70,7 @@ export default {
|
|
|
49
70
|
];
|
|
50
71
|
}
|
|
51
72
|
|
|
52
|
-
return [`gl-form-input-${this.
|
|
73
|
+
return [`gl-form-input-${this.computedWidth}`];
|
|
53
74
|
},
|
|
54
75
|
listeners() {
|
|
55
76
|
return {
|
|
@@ -56,6 +56,31 @@ describe('GlFormSelect', () => {
|
|
|
56
56
|
});
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
+
describe('width prop', () => {
|
|
60
|
+
// Exclude the default null value
|
|
61
|
+
const nonNullSizes = excludeDefaultNull(formInputSizes);
|
|
62
|
+
|
|
63
|
+
it.each(nonNullSizes)('adds correct class for width %s', (width) => {
|
|
64
|
+
createComponent({ width });
|
|
65
|
+
|
|
66
|
+
expect(wrapper.classes().sort()).toEqual(
|
|
67
|
+
[...DEFAULT_SELECT_CLASSES, `gl-form-select-${width}`].sort()
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('does not add a width class if not given the width prop', () => {
|
|
72
|
+
createComponent();
|
|
73
|
+
|
|
74
|
+
expect(wrapper.classes().sort()).toEqual([...DEFAULT_SELECT_CLASSES].sort());
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('does not add a width class if passed null', () => {
|
|
78
|
+
createComponent({ width: null });
|
|
79
|
+
|
|
80
|
+
expect(wrapper.classes().sort()).toEqual([...DEFAULT_SELECT_CLASSES].sort());
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
59
84
|
describe('v-model', () => {
|
|
60
85
|
it('should select an option element and update the v-model bound data', async () => {
|
|
61
86
|
createComponent({ options: formSelectOptions });
|
|
@@ -10,6 +10,7 @@ const data = () => ({
|
|
|
10
10
|
const template = `
|
|
11
11
|
<gl-form-select
|
|
12
12
|
v-model="selected"
|
|
13
|
+
:width="width"
|
|
13
14
|
:size="size"
|
|
14
15
|
:disabled="disabled"
|
|
15
16
|
:state="state"
|
|
@@ -20,6 +21,7 @@ const template = `
|
|
|
20
21
|
`;
|
|
21
22
|
|
|
22
23
|
const generateProps = ({
|
|
24
|
+
width = null,
|
|
23
25
|
size = null,
|
|
24
26
|
state = null,
|
|
25
27
|
disabled = false,
|
|
@@ -27,6 +29,7 @@ const generateProps = ({
|
|
|
27
29
|
selectSize = 1,
|
|
28
30
|
options = formSelectOptions,
|
|
29
31
|
} = {}) => ({
|
|
32
|
+
width,
|
|
30
33
|
size,
|
|
31
34
|
disabled,
|
|
32
35
|
state,
|
|
@@ -89,6 +92,10 @@ export default {
|
|
|
89
92
|
},
|
|
90
93
|
},
|
|
91
94
|
argTypes: {
|
|
95
|
+
width: {
|
|
96
|
+
options: formInputSizes,
|
|
97
|
+
control: 'select',
|
|
98
|
+
},
|
|
92
99
|
size: {
|
|
93
100
|
options: formInputSizes,
|
|
94
101
|
control: 'select',
|
|
@@ -13,6 +13,24 @@ export default {
|
|
|
13
13
|
/**
|
|
14
14
|
* Maximum width of the Select
|
|
15
15
|
*/
|
|
16
|
+
width: {
|
|
17
|
+
type: [String, Object],
|
|
18
|
+
required: false,
|
|
19
|
+
default: null,
|
|
20
|
+
validator: (value) => {
|
|
21
|
+
const widths = isObject(value) ? Object.values(value) : [value];
|
|
22
|
+
|
|
23
|
+
return widths.every((width) => Object.values(formInputSizes).includes(width));
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
/**
|
|
27
|
+
* ⚠️ DEPRECATED:
|
|
28
|
+
*
|
|
29
|
+
* Will be replaced by the
|
|
30
|
+
* property width
|
|
31
|
+
*
|
|
32
|
+
* Maximum width of the Select
|
|
33
|
+
*/
|
|
16
34
|
size: {
|
|
17
35
|
type: [String, Object],
|
|
18
36
|
required: false,
|
|
@@ -25,13 +43,16 @@ export default {
|
|
|
25
43
|
},
|
|
26
44
|
},
|
|
27
45
|
computed: {
|
|
46
|
+
computedWidth() {
|
|
47
|
+
return this.width ? this.width : this.size;
|
|
48
|
+
},
|
|
28
49
|
cssClasses() {
|
|
29
|
-
if (this.
|
|
50
|
+
if (this.computedWidth === null) {
|
|
30
51
|
return [];
|
|
31
52
|
}
|
|
32
53
|
|
|
33
|
-
if (isObject(this.
|
|
34
|
-
const { default: defaultSize, ...nonDefaultSizes } = this.
|
|
54
|
+
if (isObject(this.computedWidth)) {
|
|
55
|
+
const { default: defaultSize, ...nonDefaultSizes } = this.computedWidth;
|
|
35
56
|
|
|
36
57
|
return [
|
|
37
58
|
...(defaultSize ? [`gl-form-select-${defaultSize}`] : []),
|
|
@@ -41,7 +62,7 @@ export default {
|
|
|
41
62
|
];
|
|
42
63
|
}
|
|
43
64
|
|
|
44
|
-
return [`gl-form-select-${this.
|
|
65
|
+
return [`gl-form-select-${this.computedWidth}`];
|
|
45
66
|
},
|
|
46
67
|
},
|
|
47
68
|
};
|
package/src/scss/utilities.scss
CHANGED
|
@@ -8359,13 +8359,13 @@ $gl-animate-skeleton-loader-max-width: 64 * $grid-size;
|
|
|
8359
8359
|
}
|
|
8360
8360
|
.gl-overflow-break-word {
|
|
8361
8361
|
overflow-wrap: break-word;
|
|
8362
|
-
word-wrap: break-word;
|
|
8363
8362
|
hyphens: auto;
|
|
8363
|
+
-webkit-hyphens: auto;
|
|
8364
8364
|
}
|
|
8365
8365
|
.gl-overflow-break-word\! {
|
|
8366
8366
|
overflow-wrap: break-word !important;
|
|
8367
|
-
word-wrap: break-word !important;
|
|
8368
8367
|
hyphens: auto !important;
|
|
8368
|
+
-webkit-hyphens: auto !important;
|
|
8369
8369
|
}
|
|
8370
8370
|
.gl-str-truncated {
|
|
8371
8371
|
@include str-truncated;
|
package/src/utils/constants.js
CHANGED
|
@@ -151,6 +151,13 @@ export const datepickerSizeOptionsMap = {
|
|
|
151
151
|
medium: 'md',
|
|
152
152
|
};
|
|
153
153
|
|
|
154
|
+
export const datepickerWidthOptionsMap = {
|
|
155
|
+
sm: 'sm',
|
|
156
|
+
md: 'md',
|
|
157
|
+
lg: 'lg',
|
|
158
|
+
xl: 'xl',
|
|
159
|
+
};
|
|
160
|
+
|
|
154
161
|
// size options all have corresponding styles (e.g. .s12 defined in icon.scss)
|
|
155
162
|
export const iconSizeOptions = glIconSizesVariable.split(' ').map(Number);
|
|
156
163
|
|