@gitlab/ui 41.9.0 → 42.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 +32 -0
- package/dist/components/base/tabs/tab/tab.js +1 -10
- package/dist/components/base/token_selector/token_container.js +6 -1
- package/dist/components/base/token_selector/token_selector.js +15 -2
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/utils/constants.js +0 -2
- package/package.json +13 -14
- package/src/components/base/accordion/accordion.stories.js +0 -1
- package/src/components/base/accordion/accordion_item.stories.js +0 -1
- package/src/components/base/avatar/avatar.stories.js +0 -1
- package/src/components/base/avatar_labeled/avatar_labeled.stories.js +0 -1
- package/src/components/base/avatar_link/avatar_link.stories.js +0 -1
- package/src/components/base/avatars_inline/avatars_inline.stories.js +0 -1
- package/src/components/base/banner/banner.stories.js +0 -1
- package/src/components/base/breadcrumb/breadcrumb.stories.js +0 -1
- package/src/components/base/broadcast_message/broadcast_message.stories.js +0 -1
- package/src/components/base/button/button.scss +3 -60
- package/src/components/base/button/button.spec.js +0 -3
- package/src/components/base/button/button.stories.js +0 -3
- package/src/components/base/button_group/button_group.stories.js +0 -3
- package/src/components/base/card/card.stories.js +0 -1
- package/src/components/base/carousel/carousel.stories.js +0 -1
- package/src/components/base/collapse/collapse.stories.js +0 -3
- package/src/components/base/daterange_picker/daterange_picker.stories.js +0 -1
- package/src/components/base/drawer/drawer.stories.js +0 -1
- package/src/components/base/dropdown/dropdown.scss +1 -2
- package/src/components/base/form/form.stories.js +0 -1
- package/src/components/base/form/form_checkbox/form_checkbox.stories.js +0 -1
- package/src/components/base/form/form_combobox/form_combobox.stories.js +0 -1
- package/src/components/base/form/form_input/form_input.stories.js +0 -1
- package/src/components/base/form/form_input_group/form_input_group.stories.js +0 -2
- package/src/components/base/form/form_radio/form_radio.stories.js +0 -1
- package/src/components/base/form/form_radio_group/form_radio_group.stories.js +0 -1
- package/src/components/base/form/form_select/form_select.stories.js +0 -1
- package/src/components/base/form/form_text/form_text.stories.js +0 -1
- package/src/components/base/form/form_textarea/form_textarea.stories.js +0 -1
- package/src/components/base/form/input_group_text/input_group_text.stories.js +0 -1
- package/src/components/base/icon/icon.stories.js +0 -1
- package/src/components/base/infinite_scroll/infinite_scroll.stories.js +0 -1
- package/src/components/base/keyset_pagination/keyset_pagination.stories.js +0 -1
- package/src/components/base/label/label.stories.js +0 -1
- package/src/components/base/loading_icon/loading_icon.stories.js +0 -3
- package/src/components/base/markdown/markdown.stories.js +0 -1
- package/src/components/base/modal/modal.stories.js +0 -1
- package/src/components/base/nav/nav.stories.js +0 -1
- package/src/components/base/new_dropdowns/listbox/listbox.stories.js +0 -1
- package/src/components/base/paginated_list/paginated_list.stories.js +0 -1
- package/src/components/base/pagination/pagination.stories.js +0 -1
- package/src/components/base/path/path.stories.js +0 -1
- package/src/components/base/popover/popover.stories.js +0 -1
- package/src/components/base/progress_bar/progress_bar.stories.js +0 -1
- package/src/components/base/search_box_by_click/search_box_by_click.stories.js +0 -1
- package/src/components/base/search_box_by_type/search_box_by_type.stories.js +0 -1
- package/src/components/base/segmented_control/segmented_control.stories.js +0 -1
- package/src/components/base/skeleton_loader/skeleton_loader.stories.js +0 -1
- package/src/components/base/skeleton_loading/skeleton_loading.stories.js +0 -1
- package/src/components/base/sorting/sorting.stories.js +0 -1
- package/src/components/base/sorting/sorting_item.stories.js +0 -1
- package/src/components/base/table/table.stories.js +0 -1
- package/src/components/base/table_lite/table_lite.stories.js +0 -1
- package/src/components/base/tabs/tab/tab.spec.js +9 -19
- package/src/components/base/tabs/tab/tab.vue +0 -9
- package/src/components/base/tabs/tabs/tabs.stories.js +0 -14
- package/src/components/base/toast/toast.stories.js +0 -1
- package/src/components/base/token_selector/token_container.spec.js +9 -0
- package/src/components/base/token_selector/token_container.vue +6 -0
- package/src/components/base/token_selector/token_selector.spec.js +60 -0
- package/src/components/base/token_selector/token_selector.stories.js +0 -1
- package/src/components/base/token_selector/token_selector.vue +17 -1
- package/src/components/base/tooltip/tooltip.stories.js +0 -1
- package/src/components/charts/area/area.stories.js +0 -3
- package/src/components/charts/bar/bar.stories.js +0 -1
- package/src/components/charts/discrete_scatter/discrete_scatter.stories.js +0 -3
- package/src/components/charts/gauge/gauge.stories.js +0 -1
- package/src/components/charts/heatmap/heatmap.stories.js +0 -3
- package/src/components/charts/legend/legend.stories.js +0 -1
- package/src/components/charts/series_label/series_label.stories.js +0 -1
- package/src/components/charts/single_stat/single_stat.stories.js +0 -1
- package/src/components/charts/sparkline/sparkline.stories.js +0 -1
- package/src/components/charts/stacked_column/stacked_column.stories.js +0 -1
- package/src/components/charts/tooltip/tooltip.stories.js +0 -1
- package/src/components/regions/empty_state/empty_state.stories.js +0 -1
- package/src/components/utilities/friendly_wrap/friendly_wrap.stories.js +0 -1
- package/src/components/utilities/intersection_observer/intersection_observer.stories.js +0 -1
- package/src/components/utilities/intersperse/intersperse.stories.js +0 -1
- package/src/components/utilities/truncate/truncate.stories.js +0 -1
- package/src/directives/outside/outside.stories.js +0 -1
- package/src/directives/resize_observer/resize_observer.stories.js +0 -1
- package/src/directives/safe_html/safe_html.stories.js +0 -1
- package/src/directives/safe_link/safe_link.stories.js +0 -1
- package/src/utils/constants.js +0 -2
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { shallowMount } from '@vue/test-utils';
|
|
2
|
-
import { BTab } from 'bootstrap-vue';
|
|
3
2
|
import { DEFAULT_TAB_TITLE_LINK_CLASS } from '../constants';
|
|
4
3
|
import GlTab from './tab.vue';
|
|
5
4
|
|
|
@@ -7,7 +6,9 @@ describe('Tab component', () => {
|
|
|
7
6
|
let wrapper;
|
|
8
7
|
|
|
9
8
|
const createComponent = (options) => {
|
|
10
|
-
wrapper = shallowMount(GlTab, {
|
|
9
|
+
wrapper = shallowMount(GlTab, {
|
|
10
|
+
...options,
|
|
11
|
+
});
|
|
11
12
|
};
|
|
12
13
|
|
|
13
14
|
it.each`
|
|
@@ -21,25 +22,14 @@ describe('Tab component', () => {
|
|
|
21
22
|
'computed title link class is $expectedProp when titleLinkClass is $titleLinkClass',
|
|
22
23
|
({ titleLinkClass, expectedProp }) => {
|
|
23
24
|
createComponent({
|
|
24
|
-
propsData: {
|
|
25
|
+
propsData: {
|
|
26
|
+
titleLinkClass,
|
|
27
|
+
},
|
|
25
28
|
});
|
|
26
29
|
|
|
27
|
-
expect(wrapper.
|
|
30
|
+
expect(wrapper.html()).toBe(
|
|
31
|
+
`<b-tab-stub tag="div" title="" titlelinkclass="${expectedProp}"></b-tab-stub>`
|
|
32
|
+
);
|
|
28
33
|
}
|
|
29
34
|
);
|
|
30
|
-
|
|
31
|
-
it('passes title-link-attributes to b-tab when href is explicitly passed', () => {
|
|
32
|
-
const titleLinkAttributes = 'href-example';
|
|
33
|
-
const expectedProp = { href: titleLinkAttributes };
|
|
34
|
-
createComponent({
|
|
35
|
-
propsData: { href: titleLinkAttributes },
|
|
36
|
-
});
|
|
37
|
-
expect(wrapper.findComponent(BTab).props('titleLinkAttributes')).toEqual(expectedProp);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('passes # as href to b-tab when href is not passed', () => {
|
|
41
|
-
const expectedProp = { href: '#' };
|
|
42
|
-
createComponent();
|
|
43
|
-
expect(wrapper.findComponent(BTab).props('titleLinkAttributes')).toEqual(expectedProp);
|
|
44
|
-
});
|
|
45
35
|
});
|
|
@@ -24,14 +24,6 @@ export default {
|
|
|
24
24
|
required: false,
|
|
25
25
|
default: null,
|
|
26
26
|
},
|
|
27
|
-
/**
|
|
28
|
-
* Provide an `href` for the tab, for example to associate the tab with the tab panel's ID
|
|
29
|
-
*/
|
|
30
|
-
href: {
|
|
31
|
-
type: String,
|
|
32
|
-
required: false,
|
|
33
|
-
default: '#',
|
|
34
|
-
},
|
|
35
27
|
},
|
|
36
28
|
computed: {
|
|
37
29
|
linkClass() {
|
|
@@ -54,7 +46,6 @@ export default {
|
|
|
54
46
|
:title-link-class="linkClass"
|
|
55
47
|
:query-param-value="queryParamValue"
|
|
56
48
|
v-bind="$attrs"
|
|
57
|
-
:title-link-attributes="{ href }"
|
|
58
49
|
v-on="$listeners"
|
|
59
50
|
>
|
|
60
51
|
<template v-for="slot in Object.keys($slots)" #[slot]>
|
|
@@ -226,20 +226,6 @@ WithScrollAndGrowing.parameters = {
|
|
|
226
226
|
storyshots: { disable: true },
|
|
227
227
|
};
|
|
228
228
|
|
|
229
|
-
export const WithHref = (_args, { argTypes }) => ({
|
|
230
|
-
props: Object.keys(argTypes),
|
|
231
|
-
components: { ...components, GlBadge },
|
|
232
|
-
template: wrap(`
|
|
233
|
-
<gl-tab href="#tab-1" title="Tab 1">
|
|
234
|
-
<h2 id="tab-1">Tab panel 1</h2>
|
|
235
|
-
<p>Some paragraph text<p>
|
|
236
|
-
</gl-tab>
|
|
237
|
-
<gl-tab href="#tab-2" title="Tab 2">
|
|
238
|
-
<h2 id="tab-2">Tab panel 2</h2>
|
|
239
|
-
<p>Some paragraph text<p>
|
|
240
|
-
</gl-tab>`),
|
|
241
|
-
});
|
|
242
|
-
|
|
243
229
|
export default {
|
|
244
230
|
title: 'base/tabs',
|
|
245
231
|
component: GlTabs,
|
|
@@ -62,6 +62,15 @@ describe('GlTokenContainer', () => {
|
|
|
62
62
|
});
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
+
describe('viewOnly', () => {
|
|
66
|
+
it('passes viewOnly prop to tokens correctly', () => {
|
|
67
|
+
createComponent({ propsData: { viewOnly: true } });
|
|
68
|
+
const tokenWrappers = wrapper.findAllComponents(GlToken);
|
|
69
|
+
|
|
70
|
+
expect(tokenWrappers.wrappers.every((token) => token.props('viewOnly'))).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
65
74
|
describe('state', () => {
|
|
66
75
|
describe('when `state` is `false`', () => {
|
|
67
76
|
it('adds `aria-invalid="true"` attribute`', () => {
|
|
@@ -21,6 +21,11 @@ export default {
|
|
|
21
21
|
type: Function,
|
|
22
22
|
required: true,
|
|
23
23
|
},
|
|
24
|
+
viewOnly: {
|
|
25
|
+
type: Boolean,
|
|
26
|
+
required: false,
|
|
27
|
+
default: false,
|
|
28
|
+
},
|
|
24
29
|
},
|
|
25
30
|
data() {
|
|
26
31
|
return {
|
|
@@ -143,6 +148,7 @@ export default {
|
|
|
143
148
|
class="gl-cursor-default"
|
|
144
149
|
:class="token.class"
|
|
145
150
|
:style="token.style"
|
|
151
|
+
:view-only="viewOnly"
|
|
146
152
|
@close="handleClose(token)"
|
|
147
153
|
>
|
|
148
154
|
<slot name="token-content" :token="token">
|
|
@@ -46,6 +46,8 @@ describe('GlTokenSelector', () => {
|
|
|
46
46
|
},
|
|
47
47
|
];
|
|
48
48
|
|
|
49
|
+
const placeholderText = 'Test placeholder';
|
|
50
|
+
|
|
49
51
|
let wrapper;
|
|
50
52
|
|
|
51
53
|
const defaultProps = { selectedTokens: [] };
|
|
@@ -141,6 +143,22 @@ describe('GlTokenSelector', () => {
|
|
|
141
143
|
});
|
|
142
144
|
});
|
|
143
145
|
|
|
146
|
+
describe('viewOnly', () => {
|
|
147
|
+
beforeEach(() => {
|
|
148
|
+
createComponent({ propsData: { viewOnly: true } });
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('passes `viewOnly` prop to GlTokenContainer', () => {
|
|
152
|
+
expect(wrapper.findComponent(GlTokenContainer).props('viewOnly')).toBe(true);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('disables input field if viewOnly is true', () => {
|
|
156
|
+
findTextInput().trigger('focus');
|
|
157
|
+
|
|
158
|
+
expect(findTextInput().attributes('disabled')).toBe('disabled');
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
144
162
|
describe('containerClass', () => {
|
|
145
163
|
it('renders passed CSS classes', () => {
|
|
146
164
|
createComponent({
|
|
@@ -302,6 +320,48 @@ describe('GlTokenSelector', () => {
|
|
|
302
320
|
|
|
303
321
|
expect(wrapper.findComponent(component).vm.$scopedSlots).toHaveProperty(slot);
|
|
304
322
|
});
|
|
323
|
+
|
|
324
|
+
it('renders empty-placeholder slot if tokens list is empty and input is not focused', () => {
|
|
325
|
+
createComponent({
|
|
326
|
+
propsData: {
|
|
327
|
+
selectedTokens: [],
|
|
328
|
+
},
|
|
329
|
+
slots: {
|
|
330
|
+
'empty-placeholder': placeholderText,
|
|
331
|
+
},
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
expect(wrapper.text()).toContain(placeholderText);
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
it('does not render empty-placeholder slot if token list is not empty', () => {
|
|
338
|
+
createComponent({
|
|
339
|
+
propsData: {
|
|
340
|
+
selectedTokens: tokens,
|
|
341
|
+
},
|
|
342
|
+
slots: {
|
|
343
|
+
'empty-placeholder': placeholderText,
|
|
344
|
+
},
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
expect(wrapper.text()).not.toContain(placeholderText);
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
it('hides empty-placeholder slot if input is focused', async () => {
|
|
351
|
+
createComponent({
|
|
352
|
+
propsData: {
|
|
353
|
+
selectedTokens: [],
|
|
354
|
+
},
|
|
355
|
+
slots: {
|
|
356
|
+
'empty-placeholder': placeholderText,
|
|
357
|
+
},
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
expect(wrapper.text()).toContain(placeholderText);
|
|
361
|
+
|
|
362
|
+
await findTextInput().trigger('focus');
|
|
363
|
+
expect(wrapper.text()).not.toContain(placeholderText);
|
|
364
|
+
});
|
|
305
365
|
});
|
|
306
366
|
|
|
307
367
|
describe('text input events', () => {
|
|
@@ -113,6 +113,14 @@ export default {
|
|
|
113
113
|
validator: tokensValidator,
|
|
114
114
|
required: true,
|
|
115
115
|
},
|
|
116
|
+
/**
|
|
117
|
+
* Controls the `view-only` mode for the tokens
|
|
118
|
+
*/
|
|
119
|
+
viewOnly: {
|
|
120
|
+
type: Boolean,
|
|
121
|
+
required: false,
|
|
122
|
+
default: false,
|
|
123
|
+
},
|
|
116
124
|
},
|
|
117
125
|
data() {
|
|
118
126
|
return {
|
|
@@ -165,6 +173,9 @@ export default {
|
|
|
165
173
|
? 'is-valid gl-inset-border-1-gray-400!'
|
|
166
174
|
: 'is-invalid gl-inset-border-1-red-500!';
|
|
167
175
|
},
|
|
176
|
+
showEmptyPlaceholder() {
|
|
177
|
+
return this.selectedTokens.length === 0 && !this.inputFocused;
|
|
178
|
+
},
|
|
168
179
|
},
|
|
169
180
|
watch: {
|
|
170
181
|
inputText(newValue, oldValue) {
|
|
@@ -354,14 +365,18 @@ export default {
|
|
|
354
365
|
<div>
|
|
355
366
|
<div
|
|
356
367
|
ref="container"
|
|
357
|
-
class="gl-token-selector gl-form-input form-control form-control-plaintext gl-cursor-text! gl-py-2! gl-px-3!"
|
|
368
|
+
class="gl-token-selector gl-form-input gl-display-flex gl-align-items-center form-control form-control-plaintext gl-cursor-text! gl-py-2! gl-px-3!"
|
|
358
369
|
:class="[inputFocused ? 'gl-token-selector-focus-glow' : '', containerClass, stateClass]"
|
|
359
370
|
@click="handleContainerClick"
|
|
360
371
|
>
|
|
372
|
+
<!-- @slot Optional content to display a placeholder when tokens list is empty
|
|
373
|
+
and user doesn't edit tokens -->
|
|
374
|
+
<slot v-if="showEmptyPlaceholder" name="empty-placeholder"></slot>
|
|
361
375
|
<gl-token-container
|
|
362
376
|
:tokens="selectedTokens"
|
|
363
377
|
:state="state"
|
|
364
378
|
:register-focus-on-token="registerFocusOnToken"
|
|
379
|
+
:view-only="viewOnly"
|
|
365
380
|
@token-remove="removeToken"
|
|
366
381
|
@cancel-focus="cancelTokenFocus"
|
|
367
382
|
>
|
|
@@ -383,6 +398,7 @@ export default {
|
|
|
383
398
|
:autocomplete="autocomplete"
|
|
384
399
|
:aria-labelledby="ariaLabelledby"
|
|
385
400
|
:placeholder="placeholder"
|
|
401
|
+
:disabled="viewOnly"
|
|
386
402
|
v-bind="textInputAttrs"
|
|
387
403
|
@input="inputText = $event.target.value"
|
|
388
404
|
@focus="handleFocus"
|
package/src/utils/constants.js
CHANGED
|
@@ -97,7 +97,6 @@ export const buttonVariantOptions = {
|
|
|
97
97
|
confirm: 'confirm',
|
|
98
98
|
info: 'info (deprecated)',
|
|
99
99
|
success: 'success (deprecated)',
|
|
100
|
-
warning: 'warning (deprecated)',
|
|
101
100
|
danger: 'danger',
|
|
102
101
|
dashed: 'dashed',
|
|
103
102
|
link: 'link',
|
|
@@ -121,7 +120,6 @@ export const dropdownVariantOptions = {
|
|
|
121
120
|
confirm: 'confirm',
|
|
122
121
|
info: 'info (deprecated)',
|
|
123
122
|
success: 'success (deprecated)',
|
|
124
|
-
warning: 'warning (deprecated)',
|
|
125
123
|
danger: 'danger',
|
|
126
124
|
link: 'link',
|
|
127
125
|
};
|