@gitlab/ui 74.5.0 → 74.7.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 +14 -0
- package/dist/components/base/form/form_fields/form_fields.js +11 -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/play_utils.js +1 -1
- package/package.json +15 -17
- package/src/components/base/filtered_search/filtered_search.stories.js +1 -2
- package/src/components/base/filtered_search/filtered_search_suggestion_list.stories.js +1 -1
- package/src/components/base/form/form_combobox/form_combobox.stories.js +1 -2
- package/src/components/base/form/form_fields/form_fields.spec.js +16 -0
- package/src/components/base/form/form_fields/form_fields.stories.js +26 -3
- package/src/components/base/form/form_fields/form_fields.vue +12 -1
- package/src/components/base/sorting/sorting.stories.js +1 -2
- package/src/components/base/toast/toast.stories.js +1 -2
- package/src/components/base/token_selector/token_selector.stories.js +1 -2
- package/src/components/base/tooltip/tooltip.stories.js +1 -2
- package/src/scss/utilities.scss +24 -0
- package/src/scss/utility-mixins/background.scss +4 -0
- package/src/scss/utility-mixins/border.scss +4 -0
- package/src/scss/utility-mixins/color.scss +4 -0
- package/src/utils/play_utils.js +1 -1
package/dist/utils/play_utils.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gitlab/ui",
|
|
3
|
-
"version": "74.
|
|
3
|
+
"version": "74.7.0",
|
|
4
4
|
"description": "GitLab UI Components",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"markdownlint": "markdownlint '**/*.md' --ignore node_modules --ignore CHANGELOG.md",
|
|
62
62
|
"markdownlint:fix": "yarn markdownlint --fix",
|
|
63
63
|
"lint": "run-p prettier eslint stylelint markdownlint",
|
|
64
|
-
"lint:fix": "run-s
|
|
64
|
+
"lint:fix": "run-s eslint:fix prettier:fix stylelint:fix markdownlint:fix",
|
|
65
65
|
"generate:component": "plop",
|
|
66
66
|
"translations:collect": "make translations.json",
|
|
67
67
|
"tailwind-config-viewer": "tailwind-config-viewer -o"
|
|
@@ -106,21 +106,19 @@
|
|
|
106
106
|
"@rollup/plugin-commonjs": "^11.1.0",
|
|
107
107
|
"@rollup/plugin-node-resolve": "^7.1.3",
|
|
108
108
|
"@rollup/plugin-replace": "^2.3.2",
|
|
109
|
-
"@storybook/addon-a11y": "7.6.
|
|
110
|
-
"@storybook/addon-docs": "7.6.
|
|
111
|
-
"@storybook/addon-essentials": "7.6.
|
|
112
|
-
"@storybook/addon-interactions": "7.6.
|
|
113
|
-
"@storybook/addon-viewport": "7.6.
|
|
114
|
-
"@storybook/builder-webpack5": "7.6.
|
|
115
|
-
"@storybook/
|
|
109
|
+
"@storybook/addon-a11y": "7.6.14",
|
|
110
|
+
"@storybook/addon-docs": "7.6.14",
|
|
111
|
+
"@storybook/addon-essentials": "7.6.14",
|
|
112
|
+
"@storybook/addon-interactions": "7.6.14",
|
|
113
|
+
"@storybook/addon-viewport": "7.6.14",
|
|
114
|
+
"@storybook/builder-webpack5": "7.6.14",
|
|
115
|
+
"@storybook/test": "7.6.14",
|
|
116
116
|
"@storybook/test-runner": "0.16.0",
|
|
117
|
-
"@storybook/
|
|
118
|
-
"@storybook/
|
|
119
|
-
"@storybook/vue": "7.6.
|
|
120
|
-
"@storybook/
|
|
121
|
-
"@storybook/vue3": "7.6.
|
|
122
|
-
"@storybook/vue3-webpack5": "7.6.13",
|
|
123
|
-
"@types/jest": "^29.5.11",
|
|
117
|
+
"@storybook/theming": "7.6.14",
|
|
118
|
+
"@storybook/vue": "7.6.14",
|
|
119
|
+
"@storybook/vue-webpack5": "7.6.14",
|
|
120
|
+
"@storybook/vue3": "7.6.14",
|
|
121
|
+
"@storybook/vue3-webpack5": "7.6.14",
|
|
124
122
|
"@types/jest-image-snapshot": "^6.4.0",
|
|
125
123
|
"@vue/compat": "^3.2.40",
|
|
126
124
|
"@vue/compiler-sfc": "^3.2.40",
|
|
@@ -172,7 +170,7 @@
|
|
|
172
170
|
"sass-loader": "^10.2.0",
|
|
173
171
|
"sass-true": "^6.1.0",
|
|
174
172
|
"start-server-and-test": "^1.10.6",
|
|
175
|
-
"storybook": "7.6.
|
|
173
|
+
"storybook": "7.6.14",
|
|
176
174
|
"storybook-dark-mode": "3.0.3",
|
|
177
175
|
"style-dictionary": "^3.8.0",
|
|
178
176
|
"stylelint": "15.10.2",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import last from 'lodash/last';
|
|
2
|
-
import { userEvent, within, waitFor } from '@storybook/
|
|
3
|
-
import { expect } from '@storybook/jest';
|
|
2
|
+
import { userEvent, within, waitFor, expect } from '@storybook/test';
|
|
4
3
|
import GlLoadingIcon from '../loading_icon/loading_icon.vue';
|
|
5
4
|
import GlIcon from '../icon/icon.vue';
|
|
6
5
|
import GlToken from '../token/token.vue';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { userEvent, within } from '@storybook/
|
|
1
|
+
import { userEvent, within } from '@storybook/test';
|
|
2
2
|
import GlFilteredSearchSuggestionList from './filtered_search_suggestion_list.vue';
|
|
3
3
|
import GlFilteredSearchSuggestion from './filtered_search_suggestion.vue';
|
|
4
4
|
import { provide } from './common_story_options';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { userEvent, within, waitFor } from '@storybook/
|
|
2
|
-
import { expect } from '@storybook/jest';
|
|
1
|
+
import { userEvent, within, waitFor, expect } from '@storybook/test';
|
|
3
2
|
import { makeContainer } from '../../../../utils/story_decorators/container';
|
|
4
3
|
import { stringTokenList, labelText, objectTokenList, actionsList } from './constants';
|
|
5
4
|
import readme from './form_combobox.md';
|
|
@@ -345,6 +345,22 @@ describe('GlFormFields', () => {
|
|
|
345
345
|
});
|
|
346
346
|
}
|
|
347
347
|
);
|
|
348
|
+
|
|
349
|
+
describe('when there is a server validation message', () => {
|
|
350
|
+
beforeEach(async () => {
|
|
351
|
+
await submitForm();
|
|
352
|
+
|
|
353
|
+
wrapper.setProps({
|
|
354
|
+
serverValidations: { username: 'Username has already been taken.' },
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
it('renders error message', () => {
|
|
359
|
+
expect(
|
|
360
|
+
findFormGroupFromLabel(TEST_FIELDS.username.label).attributes('invalid-feedback')
|
|
361
|
+
).toBe('Username has already been taken.');
|
|
362
|
+
});
|
|
363
|
+
});
|
|
348
364
|
});
|
|
349
365
|
|
|
350
366
|
describe('with scoped slot', () => {
|
|
@@ -3,6 +3,7 @@ import omit from 'lodash/omit';
|
|
|
3
3
|
import GlModal from '../../modal/modal.vue';
|
|
4
4
|
import GlButton from '../../button/button.vue';
|
|
5
5
|
import GlListbox from '../../new_dropdowns/listbox/listbox.vue';
|
|
6
|
+
import { setStoryTimeout } from '../../../../utils/test_utils';
|
|
6
7
|
import GlFormFields from './form_fields.vue';
|
|
7
8
|
import readme from './form_fields.md';
|
|
8
9
|
import { required } from './validators';
|
|
@@ -49,6 +50,8 @@ const Template = () => ({
|
|
|
49
50
|
},
|
|
50
51
|
formValues: {},
|
|
51
52
|
testFormId: uniqueId('form_fields_story_'),
|
|
53
|
+
serverValidations: {},
|
|
54
|
+
loading: false,
|
|
52
55
|
};
|
|
53
56
|
},
|
|
54
57
|
computed: {
|
|
@@ -61,7 +64,27 @@ const Template = () => ({
|
|
|
61
64
|
},
|
|
62
65
|
},
|
|
63
66
|
methods: {
|
|
64
|
-
|
|
67
|
+
onInputField({ name }) {
|
|
68
|
+
this.$delete(this.serverValidations, name);
|
|
69
|
+
},
|
|
70
|
+
async onSubmit() {
|
|
71
|
+
this.loading = true;
|
|
72
|
+
|
|
73
|
+
// Simulate waiting for API request to resolve
|
|
74
|
+
await new Promise((resolve) => {
|
|
75
|
+
setStoryTimeout(resolve, 1000);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
this.loading = false;
|
|
79
|
+
|
|
80
|
+
// Manually checking field and validating for this example.
|
|
81
|
+
// In practice this error message would come from the API response.
|
|
82
|
+
if (this.formValues.USERNAME === 'FOO') {
|
|
83
|
+
this.$set(this.serverValidations, 'USERNAME', 'Username has already been taken.');
|
|
84
|
+
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
65
88
|
this.$refs.modal.show();
|
|
66
89
|
},
|
|
67
90
|
},
|
|
@@ -69,7 +92,7 @@ const Template = () => ({
|
|
|
69
92
|
<div>
|
|
70
93
|
<h3>Fields</h3>
|
|
71
94
|
<form :id="testFormId" @submit.prevent>
|
|
72
|
-
<gl-form-fields :fields="fields" v-model="formValues" :form-id="testFormId" @submit="onSubmit">
|
|
95
|
+
<gl-form-fields :fields="fields" v-model="formValues" :form-id="testFormId" :server-validations="serverValidations" @input-field="onInputField" @submit="onSubmit">
|
|
73
96
|
<template #input(custom)="{ id, value, input, blur }">
|
|
74
97
|
<button :id="id" @click="input(value + 1)" @blur="blur" type="button">{{value}}</button>
|
|
75
98
|
</template>
|
|
@@ -77,7 +100,7 @@ const Template = () => ({
|
|
|
77
100
|
<gl-listbox :id="id" :items="$options.ITEMS" :selected="value" @select="input" @hidden="blur" />
|
|
78
101
|
</template>
|
|
79
102
|
</gl-form-fields>
|
|
80
|
-
<gl-button type="submit" category="primary">Submit</gl-button>
|
|
103
|
+
<gl-button type="submit" category="primary" :loading="loading">Submit</gl-button>
|
|
81
104
|
</form>
|
|
82
105
|
<gl-modal ref="modal" modal-id="submission-modal" title="Form submission"><pre>{{ valuesJSON }}</pre></gl-modal>
|
|
83
106
|
</div>
|
|
@@ -51,6 +51,16 @@ export default {
|
|
|
51
51
|
type: String,
|
|
52
52
|
required: true,
|
|
53
53
|
},
|
|
54
|
+
/**
|
|
55
|
+
* Validation errors from the server. Generally passed to the component after making an API call.
|
|
56
|
+
*/
|
|
57
|
+
serverValidations: {
|
|
58
|
+
type: Object,
|
|
59
|
+
required: false,
|
|
60
|
+
default() {
|
|
61
|
+
return {};
|
|
62
|
+
},
|
|
63
|
+
},
|
|
54
64
|
},
|
|
55
65
|
data() {
|
|
56
66
|
return {
|
|
@@ -64,7 +74,8 @@ export default {
|
|
|
64
74
|
},
|
|
65
75
|
fieldValidationProps() {
|
|
66
76
|
return mapValues(this.fields, (_, fieldName) => {
|
|
67
|
-
const invalidFeedback =
|
|
77
|
+
const invalidFeedback =
|
|
78
|
+
this.serverValidations[fieldName] || this.fieldValidations[fieldName] || '';
|
|
68
79
|
|
|
69
80
|
return {
|
|
70
81
|
invalidFeedback,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { userEvent, within, waitFor } from '@storybook/
|
|
2
|
-
import { expect } from '@storybook/jest';
|
|
1
|
+
import { userEvent, within, waitFor, expect } from '@storybook/test';
|
|
3
2
|
import { makeContainer } from '../../../utils/story_decorators/container';
|
|
4
3
|
import GlSorting from './sorting.vue';
|
|
5
4
|
import readme from './sorting.md';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { userEvent, within, waitFor } from '@storybook/
|
|
2
|
-
import { expect } from '@storybook/jest';
|
|
1
|
+
import { userEvent, within, waitFor, expect } from '@storybook/test';
|
|
3
2
|
import Vue from 'vue';
|
|
4
3
|
import GlButton from '../button/button.vue';
|
|
5
4
|
import GlToast from './toast';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { userEvent, within, waitFor } from '@storybook/
|
|
2
|
-
import { expect } from '@storybook/jest';
|
|
1
|
+
import { userEvent, within, waitFor, expect } from '@storybook/test';
|
|
3
2
|
import readme from './token_selector.md';
|
|
4
3
|
import GlTokenSelector from './token_selector.vue';
|
|
5
4
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { userEvent, within, waitFor } from '@storybook/
|
|
2
|
-
import { expect } from '@storybook/jest';
|
|
1
|
+
import { userEvent, within, waitFor, expect } from '@storybook/test';
|
|
3
2
|
import { GlTooltipDirective } from '../../../directives/tooltip';
|
|
4
3
|
import GlButton from '../button/button.vue';
|
|
5
4
|
import GlTooltip from './tooltip.vue';
|
package/src/scss/utilities.scss
CHANGED
|
@@ -481,6 +481,14 @@ $gl-animate-skeleton-loader-max-width: 64 * $grid-size;
|
|
|
481
481
|
background-color: $purple-50 !important
|
|
482
482
|
}
|
|
483
483
|
|
|
484
|
+
.gl-bg-purple-500 {
|
|
485
|
+
background-color: $purple-500
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.gl-bg-purple-500\! {
|
|
489
|
+
background-color: $purple-500 !important
|
|
490
|
+
}
|
|
491
|
+
|
|
484
492
|
.gl-bg-purple-800 {
|
|
485
493
|
background-color: $purple-800
|
|
486
494
|
}
|
|
@@ -1388,6 +1396,14 @@ $gl-animate-skeleton-loader-max-width: 64 * $grid-size;
|
|
|
1388
1396
|
border-color: $purple-300 !important;
|
|
1389
1397
|
}
|
|
1390
1398
|
|
|
1399
|
+
.gl-border-purple-500 {
|
|
1400
|
+
border-color: $purple-500;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
.gl-border-purple-500\! {
|
|
1404
|
+
border-color: $purple-500 !important;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1391
1407
|
.gl-border-purple-700 {
|
|
1392
1408
|
border-color: $purple-700;
|
|
1393
1409
|
}
|
|
@@ -2816,6 +2832,14 @@ $gl-animate-skeleton-loader-max-width: 64 * $grid-size;
|
|
|
2816
2832
|
color: $red-900 !important;
|
|
2817
2833
|
}
|
|
2818
2834
|
|
|
2835
|
+
.gl-text-purple-500 {
|
|
2836
|
+
color: $purple-500;
|
|
2837
|
+
}
|
|
2838
|
+
|
|
2839
|
+
.gl-text-purple-500\! {
|
|
2840
|
+
color: $purple-500 !important;
|
|
2841
|
+
}
|
|
2842
|
+
|
|
2819
2843
|
.gl-text-purple-600 {
|
|
2820
2844
|
color: $purple-600;
|
|
2821
2845
|
}
|
package/src/utils/play_utils.js
CHANGED