@gitlab/ui 36.0.0 → 36.4.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 +28 -0
- package/dist/components/base/filtered_search/filtered_search.documentation.js +6 -0
- package/dist/components/base/filtered_search/filtered_search.js +12 -2
- package/dist/components/base/filtered_search/filtered_search_term.documentation.js +6 -0
- package/dist/components/base/filtered_search/filtered_search_term.js +11 -1
- package/dist/components/base/filtered_search/filtered_search_token_segment.documentation.js +6 -0
- package/dist/components/base/filtered_search/filtered_search_token_segment.js +11 -1
- package/dist/components/base/popover/popover.documentation.js +1 -23
- package/dist/components/base/popover/popover.js +10 -0
- package/dist/components/base/search_box_by_click/search_box_by_click.documentation.js +3 -0
- package/dist/components/base/search_box_by_click/search_box_by_click.js +6 -1
- package/dist/components/charts/single_stat/single_stat.documentation.js +1 -4
- package/dist/components/regions/empty_state/empty_state.js +3 -2
- package/dist/utility_classes.css +1 -1
- package/dist/utility_classes.css.map +1 -1
- package/documentation/documented_stories.js +2 -0
- package/package.json +2 -2
- package/src/components/base/filtered_search/filtered_search.documentation.js +6 -0
- package/src/components/base/filtered_search/filtered_search.spec.js +81 -47
- package/src/components/base/filtered_search/filtered_search.vue +13 -0
- package/src/components/base/filtered_search/filtered_search_term.documentation.js +6 -0
- package/src/components/base/filtered_search/filtered_search_term.spec.js +42 -9
- package/src/components/base/filtered_search/filtered_search_term.vue +13 -0
- package/src/components/base/filtered_search/filtered_search_token_segment.documentation.js +6 -0
- package/src/components/base/filtered_search/filtered_search_token_segment.spec.js +53 -0
- package/src/components/base/filtered_search/filtered_search_token_segment.vue +12 -0
- package/src/components/base/popover/popover.documentation.js +0 -25
- package/src/components/base/popover/popover.stories.js +78 -74
- package/src/components/base/popover/popover.vue +8 -0
- package/src/components/base/search_box_by_click/search_box_by_click.documentation.js +3 -0
- package/src/components/base/search_box_by_click/search_box_by_click.spec.js +14 -3
- package/src/components/base/search_box_by_click/search_box_by_click.vue +7 -0
- package/src/components/charts/single_stat/single_stat.documentation.js +0 -2
- package/src/components/charts/single_stat/single_stat.md +0 -2
- package/src/components/charts/single_stat/single_stat.stories.js +73 -80
- package/src/components/regions/empty_state/empty_state.spec.js +49 -0
- package/src/components/regions/empty_state/empty_state.vue +11 -8
- package/src/scss/utilities.scss +20 -0
- package/src/scss/utility-mixins/color.scss +4 -0
- package/src/scss/utility-mixins/spacing.scss +6 -0
- package/dist/components/base/popover/examples/index.js +0 -25
- package/dist/components/base/popover/examples/popover.basic.example.js +0 -38
- package/dist/components/base/popover/examples/popover.loading.example.js +0 -38
- package/dist/components/base/popover/examples/popover.notitle.example.js +0 -38
- package/dist/components/charts/single_stat/examples/index.js +0 -32
- package/dist/components/charts/single_stat/examples/single_stat.badge.example.js +0 -38
- package/dist/components/charts/single_stat/examples/single_stat.hover.example.js +0 -38
- package/dist/components/charts/single_stat/examples/single_stat.meta_icon.example.js +0 -38
- package/dist/components/charts/single_stat/examples/single_stat.simple.example.js +0 -38
- package/dist/components/charts/single_stat/examples/single_stat.title_icon.example.js +0 -38
- package/src/components/base/popover/examples/index.js +0 -29
- package/src/components/base/popover/examples/popover.basic.example.vue +0 -13
- package/src/components/base/popover/examples/popover.loading.example.vue +0 -15
- package/src/components/base/popover/examples/popover.notitle.example.vue +0 -12
- package/src/components/charts/single_stat/examples/index.js +0 -38
- package/src/components/charts/single_stat/examples/single_stat.badge.example.vue +0 -31
- package/src/components/charts/single_stat/examples/single_stat.hover.example.vue +0 -7
- package/src/components/charts/single_stat/examples/single_stat.meta_icon.example.vue +0 -10
- package/src/components/charts/single_stat/examples/single_stat.simple.example.vue +0 -7
- package/src/components/charts/single_stat/examples/single_stat.title_icon.example.vue +0 -7
|
@@ -49,6 +49,16 @@ export default {
|
|
|
49
49
|
required: true,
|
|
50
50
|
validator: () => true,
|
|
51
51
|
},
|
|
52
|
+
searchInputAttributes: {
|
|
53
|
+
type: Object,
|
|
54
|
+
required: false,
|
|
55
|
+
default: () => ({}),
|
|
56
|
+
},
|
|
57
|
+
isLastToken: {
|
|
58
|
+
type: Boolean,
|
|
59
|
+
required: false,
|
|
60
|
+
default: false,
|
|
61
|
+
},
|
|
52
62
|
},
|
|
53
63
|
|
|
54
64
|
data() {
|
|
@@ -244,6 +254,7 @@ export default {
|
|
|
244
254
|
|
|
245
255
|
<template>
|
|
246
256
|
<div
|
|
257
|
+
v-bind="isLastToken && !active && searchInputAttributes"
|
|
247
258
|
class="gl-filtered-search-token-segment"
|
|
248
259
|
:class="{ 'gl-filtered-search-token-segment-active': active }"
|
|
249
260
|
data-testid="filtered-search-token-segment"
|
|
@@ -252,6 +263,7 @@ export default {
|
|
|
252
263
|
<template v-if="active">
|
|
253
264
|
<input
|
|
254
265
|
ref="input"
|
|
266
|
+
v-bind="searchInputAttributes"
|
|
255
267
|
v-model="inputValue"
|
|
256
268
|
class="gl-filtered-search-token-segment-input"
|
|
257
269
|
:aria-label="label"
|
|
@@ -1,28 +1,3 @@
|
|
|
1
|
-
import examples from './examples';
|
|
2
|
-
|
|
3
1
|
export default {
|
|
4
2
|
followsDesignSystem: true,
|
|
5
|
-
examples,
|
|
6
|
-
bootstrapComponent: 'b-popover',
|
|
7
|
-
bootstrapPropsInfo: {
|
|
8
|
-
target: {
|
|
9
|
-
additionalInfo:
|
|
10
|
-
'Element string ID, or a reference to an element or component, that you want to trigger the popover.',
|
|
11
|
-
required: true,
|
|
12
|
-
},
|
|
13
|
-
triggers: {
|
|
14
|
-
enum: 'triggerVariantOptions',
|
|
15
|
-
},
|
|
16
|
-
placement: {
|
|
17
|
-
enum: 'popoverPlacements',
|
|
18
|
-
},
|
|
19
|
-
boundary: {
|
|
20
|
-
additionalInfo:
|
|
21
|
-
'"scrollParent", "viewport", "window", or a reference to an HTML element. This is the container that the popover will be constrained to visually.You may need to change this if your target element is in a small container with overflow scroll',
|
|
22
|
-
},
|
|
23
|
-
container: {
|
|
24
|
-
additionalInfo:
|
|
25
|
-
'Specify container as null (default, appends to <body>) to avoid rendering problems in more complex components (like input groups, button groups, etc). You can use container to optionally specify a different element to append the popover to.',
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
3
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { withKnobs, select, text } from '@storybook/addon-knobs';
|
|
2
1
|
import { GlPopover, GlButton } from '../../../index';
|
|
3
|
-
import { documentedStoriesOf } from '../../../../documentation/documented_stories';
|
|
4
2
|
import { popoverPlacements } from '../../../utils/constants';
|
|
5
3
|
|
|
4
|
+
const defaultValue = (prop) => GlPopover.props[prop].default;
|
|
5
|
+
|
|
6
6
|
const components = { GlPopover, GlButton };
|
|
7
7
|
|
|
8
8
|
const contentString = `
|
|
@@ -11,84 +11,88 @@ const contentString = `
|
|
|
11
11
|
massa ac, porta condimentum libero. Ut id lacus tristique, egestas arcu non, molestie nisi.
|
|
12
12
|
`;
|
|
13
13
|
|
|
14
|
-
const
|
|
15
|
-
<div class="gl-display-flex gl-justify-content-center gl-
|
|
16
|
-
<gl-button id="
|
|
17
|
-
<gl-popover
|
|
18
|
-
|
|
14
|
+
const getTemplate = (id, slots = '') => `
|
|
15
|
+
<div style="height:400px;" class="gl-display-flex gl-justify-content-center gl-align-items-center">
|
|
16
|
+
<gl-button id="${id}">{{placement}}</gl-button>
|
|
17
|
+
<gl-popover
|
|
18
|
+
target="${id}"
|
|
19
|
+
:triggers="triggers"
|
|
19
20
|
:title="title"
|
|
20
21
|
:placement="placement"
|
|
22
|
+
:show-close-button="showCloseButton"
|
|
21
23
|
content="${contentString}"
|
|
22
|
-
data-testid="
|
|
23
|
-
show
|
|
24
|
-
|
|
25
|
-
</div>
|
|
26
|
-
`;
|
|
24
|
+
data-testid="${id}"
|
|
25
|
+
:show="$options.viewMode !== 'docs'">${slots}</gl-popover>
|
|
26
|
+
</div>`;
|
|
27
27
|
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
28
|
+
const generateProps = ({
|
|
29
|
+
placement = popoverPlacements.top,
|
|
30
|
+
title = 'Popover',
|
|
31
|
+
triggers = defaultValue('triggers'),
|
|
32
|
+
cssClasses = defaultValue('cssClasses'),
|
|
33
|
+
showCloseButton = defaultValue('showCloseButton'),
|
|
34
|
+
} = {}) => ({
|
|
35
|
+
placement,
|
|
36
|
+
title,
|
|
37
|
+
triggers,
|
|
38
|
+
cssClasses,
|
|
39
|
+
showCloseButton,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
export const Default = (_args, { viewMode, argTypes }) => ({
|
|
43
|
+
viewMode,
|
|
44
|
+
components,
|
|
45
|
+
props: Object.keys(argTypes),
|
|
46
|
+
template: getTemplate('popover-with-props'),
|
|
47
|
+
});
|
|
48
|
+
Default.args = generateProps();
|
|
42
49
|
|
|
43
|
-
|
|
44
|
-
|
|
50
|
+
export const WithCloseButton = (_args, { viewMode, argTypes }) => ({
|
|
51
|
+
viewMode,
|
|
52
|
+
components,
|
|
53
|
+
props: Object.keys(argTypes),
|
|
54
|
+
template: getTemplate('popover-with-close-button'),
|
|
55
|
+
});
|
|
56
|
+
WithCloseButton.args = generateProps({
|
|
57
|
+
showCloseButton: true,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
export const OnClick = (_args, { viewMode, argTypes }) => ({
|
|
61
|
+
viewMode,
|
|
62
|
+
components,
|
|
63
|
+
props: Object.keys(argTypes),
|
|
64
|
+
template: getTemplate(
|
|
65
|
+
'popover-button-click',
|
|
66
|
+
`
|
|
67
|
+
<template #title>
|
|
68
|
+
<span data-testid="popover-title">Popover title</span>
|
|
69
|
+
</template>
|
|
70
|
+
`
|
|
71
|
+
),
|
|
72
|
+
});
|
|
73
|
+
OnClick.args = generateProps({
|
|
74
|
+
triggers: 'click',
|
|
75
|
+
});
|
|
76
|
+
OnClick.parameters = {
|
|
77
|
+
storyshots: { disable: true },
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export default {
|
|
81
|
+
title: 'base/popover',
|
|
82
|
+
component: GlPopover,
|
|
83
|
+
parameters: {
|
|
84
|
+
knobs: { disable: true },
|
|
85
|
+
bootstrapComponent: 'b-popover',
|
|
86
|
+
},
|
|
87
|
+
argTypes: {
|
|
45
88
|
placement: {
|
|
46
|
-
|
|
47
|
-
|
|
89
|
+
options: Object.values(popoverPlacements),
|
|
90
|
+
control: {
|
|
91
|
+
type: 'select',
|
|
92
|
+
},
|
|
48
93
|
},
|
|
49
94
|
title: {
|
|
50
|
-
type:
|
|
51
|
-
default: text('title', title),
|
|
95
|
+
control: { type: 'text' },
|
|
52
96
|
},
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
default: text('hover focus', triggers),
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
documentedStoriesOf('base/popover', '')
|
|
61
|
-
.addDecorator(withKnobs)
|
|
62
|
-
.add('default', () => ({
|
|
63
|
-
components,
|
|
64
|
-
template,
|
|
65
|
-
props: generateProps(),
|
|
66
|
-
}))
|
|
67
|
-
.add('with close button', () => ({
|
|
68
|
-
components,
|
|
69
|
-
template: `
|
|
70
|
-
<div class="gl-display-flex gl-justify-content-center gl-p-6">
|
|
71
|
-
<gl-button id="pop-with-close-button">{{placement}}</gl-button>
|
|
72
|
-
<gl-popover
|
|
73
|
-
target="pop-with-close-button"
|
|
74
|
-
data-testid="popover-with-close-button"
|
|
75
|
-
triggers="hover focus"
|
|
76
|
-
:title="title"
|
|
77
|
-
:placement="placement"
|
|
78
|
-
content="${contentString}"
|
|
79
|
-
show
|
|
80
|
-
show-close-button
|
|
81
|
-
/>
|
|
82
|
-
</div>
|
|
83
|
-
`,
|
|
84
|
-
props: generateProps(),
|
|
85
|
-
}))
|
|
86
|
-
.add(
|
|
87
|
-
'on click',
|
|
88
|
-
() => ({
|
|
89
|
-
components,
|
|
90
|
-
template: scopedSlotTemplate,
|
|
91
|
-
props: generateProps(),
|
|
92
|
-
}),
|
|
93
|
-
{ storyshots: false }
|
|
94
|
-
);
|
|
97
|
+
},
|
|
98
|
+
};
|
|
@@ -18,6 +18,11 @@ export default {
|
|
|
18
18
|
required: false,
|
|
19
19
|
default: () => [],
|
|
20
20
|
},
|
|
21
|
+
/**
|
|
22
|
+
* Space-separated triggers for the popover.
|
|
23
|
+
*
|
|
24
|
+
* @values click, hover, focus, manual
|
|
25
|
+
*/
|
|
21
26
|
triggers: {
|
|
22
27
|
type: String,
|
|
23
28
|
required: false,
|
|
@@ -45,6 +50,9 @@ export default {
|
|
|
45
50
|
methods: {
|
|
46
51
|
close(e) {
|
|
47
52
|
this.$refs[popoverRefName].doClose();
|
|
53
|
+
/**
|
|
54
|
+
* Emitted when the close button is clicked (requires showCloseButton to be `true`).
|
|
55
|
+
*/
|
|
48
56
|
this.$emit('close-button-clicked', e);
|
|
49
57
|
},
|
|
50
58
|
},
|
|
@@ -52,6 +52,9 @@ export default {
|
|
|
52
52
|
additionalInfo:
|
|
53
53
|
'Container for tooltip. Valid values: DOM node, selector string or `false` for default',
|
|
54
54
|
},
|
|
55
|
+
searchButtonAttributes: {
|
|
56
|
+
additionalInfo: 'HTML attributes to add to the search button',
|
|
57
|
+
},
|
|
55
58
|
},
|
|
56
59
|
events: [
|
|
57
60
|
{
|
|
@@ -25,6 +25,7 @@ describe('search box by click component', () => {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
const findClearIcon = () => wrapper.findComponent(ClearIcon);
|
|
28
|
+
const findSearchButton = () => wrapper.find('[data-testid="search-button"]');
|
|
28
29
|
|
|
29
30
|
it('emits input event when input changes', async () => {
|
|
30
31
|
createComponent({ value: 'somevalue' });
|
|
@@ -125,8 +126,8 @@ describe('search box by click component', () => {
|
|
|
125
126
|
});
|
|
126
127
|
|
|
127
128
|
it('displays disabled search button', () => {
|
|
128
|
-
expect(
|
|
129
|
-
expect(
|
|
129
|
+
expect(findSearchButton().exists()).toBe(true);
|
|
130
|
+
expect(findSearchButton().attributes('disabled')).toBe('true');
|
|
130
131
|
});
|
|
131
132
|
|
|
132
133
|
it('does not render clear icon even with value', () => {
|
|
@@ -145,9 +146,19 @@ describe('search box by click component', () => {
|
|
|
145
146
|
|
|
146
147
|
it('emits submit event when search button is pressed', async () => {
|
|
147
148
|
createComponent({ value: 'some-input' });
|
|
148
|
-
|
|
149
|
+
findSearchButton().vm.$emit('click');
|
|
149
150
|
|
|
150
151
|
await wrapper.vm.$nextTick();
|
|
151
152
|
expect(wrapper.emitted().submit[0]).toEqual(['some-input']);
|
|
152
153
|
});
|
|
154
|
+
|
|
155
|
+
it('adds `searchButtonAttributes` prop to search button', () => {
|
|
156
|
+
const searchButtonAttributes = { 'data-qa-selector': 'foo-bar' };
|
|
157
|
+
|
|
158
|
+
createComponent({ searchButtonAttributes });
|
|
159
|
+
|
|
160
|
+
expect(findSearchButton().attributes('data-qa-selector')).toBe(
|
|
161
|
+
searchButtonAttributes['data-qa-selector']
|
|
162
|
+
);
|
|
163
|
+
});
|
|
153
164
|
});
|
|
@@ -84,6 +84,11 @@ export default {
|
|
|
84
84
|
validator: (value) =>
|
|
85
85
|
value === false || typeof value === 'string' || value instanceof HTMLElement,
|
|
86
86
|
},
|
|
87
|
+
searchButtonAttributes: {
|
|
88
|
+
type: Object,
|
|
89
|
+
required: false,
|
|
90
|
+
default: () => ({}),
|
|
91
|
+
},
|
|
87
92
|
},
|
|
88
93
|
data() {
|
|
89
94
|
return {
|
|
@@ -216,11 +221,13 @@ export default {
|
|
|
216
221
|
/>
|
|
217
222
|
<template #append class="gl-search-box-by-click-input-group-control">
|
|
218
223
|
<gl-button
|
|
224
|
+
v-bind="searchButtonAttributes"
|
|
219
225
|
ref="searchButton"
|
|
220
226
|
class="gl-search-box-by-click-search-button"
|
|
221
227
|
icon="search"
|
|
222
228
|
:disabled="disabled"
|
|
223
229
|
aria-label="Search"
|
|
230
|
+
data-testid="search-button"
|
|
224
231
|
@click="search(currentValue)"
|
|
225
232
|
/>
|
|
226
233
|
</template>
|
|
@@ -1,100 +1,93 @@
|
|
|
1
1
|
import iconSpriteInfo from '@gitlab/svgs/dist/icons.json';
|
|
2
|
-
import { withKnobs, text, select, boolean, number } from '@storybook/addon-knobs';
|
|
3
2
|
import { GlSingleStat } from '../../../charts';
|
|
4
|
-
import { documentedStoriesOf } from '../../../../documentation/documented_stories';
|
|
5
3
|
import { badgeVariantOptions } from '../../../utils/constants';
|
|
6
4
|
import readme from './single_stat.md';
|
|
7
5
|
|
|
8
|
-
const components = {
|
|
9
|
-
GlSingleStat,
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const template = `
|
|
13
|
-
<gl-single-stat
|
|
14
|
-
:title="title"
|
|
15
|
-
:value="value"
|
|
16
|
-
:unit="unit"
|
|
17
|
-
:variant="variant"
|
|
18
|
-
:meta-text="metaText"
|
|
19
|
-
:meta-icon="metaIcon"
|
|
20
|
-
:title-icon="titleIcon"
|
|
21
|
-
:should-animate="shouldAnimate"
|
|
22
|
-
:animation-decimal-places="animationDecimalPlaces"
|
|
23
|
-
/>
|
|
24
|
-
`;
|
|
25
|
-
|
|
26
6
|
const generateProps = ({
|
|
27
7
|
variant = GlSingleStat.props.variant.default,
|
|
28
8
|
title = 'Single stat',
|
|
29
9
|
value = '100',
|
|
30
|
-
unit =
|
|
31
|
-
metaText =
|
|
10
|
+
unit = '',
|
|
11
|
+
metaText = '',
|
|
32
12
|
metaIcon = null,
|
|
33
13
|
titleIcon = null,
|
|
34
14
|
shouldAnimate = false,
|
|
35
15
|
animationDecimalPlaces = 0,
|
|
36
16
|
} = {}) => ({
|
|
37
|
-
variant
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
type: String,
|
|
47
|
-
default: text('value', value),
|
|
48
|
-
},
|
|
49
|
-
unit: {
|
|
50
|
-
type: [String, Number],
|
|
51
|
-
default: text('unit', unit),
|
|
52
|
-
},
|
|
53
|
-
metaText: {
|
|
54
|
-
type: String,
|
|
55
|
-
default: text('metaText', metaText),
|
|
56
|
-
},
|
|
57
|
-
metaIcon: {
|
|
58
|
-
type: String,
|
|
59
|
-
default: select('metaIcon', ['', ...iconSpriteInfo.icons], metaIcon),
|
|
60
|
-
},
|
|
61
|
-
titleIcon: {
|
|
62
|
-
type: String,
|
|
63
|
-
default: select('titleIcon', ['', ...iconSpriteInfo.icons], titleIcon),
|
|
64
|
-
},
|
|
65
|
-
shouldAnimate: {
|
|
66
|
-
type: Boolean,
|
|
67
|
-
default: boolean('shouldAnimate', shouldAnimate),
|
|
68
|
-
},
|
|
69
|
-
animationDecimalPlaces: {
|
|
70
|
-
type: Number,
|
|
71
|
-
default: number('animationDecimalPlaces', animationDecimalPlaces),
|
|
72
|
-
},
|
|
17
|
+
variant,
|
|
18
|
+
title,
|
|
19
|
+
value,
|
|
20
|
+
unit,
|
|
21
|
+
metaText,
|
|
22
|
+
metaIcon,
|
|
23
|
+
titleIcon,
|
|
24
|
+
shouldAnimate,
|
|
25
|
+
animationDecimalPlaces,
|
|
73
26
|
});
|
|
74
27
|
|
|
75
28
|
const metaText = 'Super fast';
|
|
76
29
|
const metaIcon = 'check-circle';
|
|
77
30
|
const titleIcon = 'hourglass';
|
|
78
31
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
32
|
+
const Template = (args, { argTypes }) => ({
|
|
33
|
+
components: {
|
|
34
|
+
GlSingleStat,
|
|
35
|
+
},
|
|
36
|
+
props: Object.keys(argTypes),
|
|
37
|
+
template: `
|
|
38
|
+
<gl-single-stat
|
|
39
|
+
:title="title"
|
|
40
|
+
:value="value"
|
|
41
|
+
:unit="unit"
|
|
42
|
+
:variant="variant"
|
|
43
|
+
:meta-text="metaText"
|
|
44
|
+
:meta-icon="metaIcon"
|
|
45
|
+
:title-icon="titleIcon"
|
|
46
|
+
:should-animate="shouldAnimate"
|
|
47
|
+
:animation-decimal-places="animationDecimalPlaces"
|
|
48
|
+
/>`,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
export const Default = Template.bind({});
|
|
52
|
+
Default.args = generateProps();
|
|
53
|
+
|
|
54
|
+
export const WithBadge = Template.bind({});
|
|
55
|
+
WithBadge.args = generateProps({ metaText, metaIcon });
|
|
56
|
+
|
|
57
|
+
export const WithMetaIcon = Template.bind({});
|
|
58
|
+
WithMetaIcon.args = generateProps({ metaIcon });
|
|
59
|
+
|
|
60
|
+
export const WithTitleIcon = Template.bind({});
|
|
61
|
+
WithTitleIcon.args = generateProps({ titleIcon });
|
|
62
|
+
|
|
63
|
+
export default {
|
|
64
|
+
title: 'charts/single-stat',
|
|
65
|
+
component: GlSingleStat,
|
|
66
|
+
parameters: {
|
|
67
|
+
knobs: { disable: true },
|
|
68
|
+
docs: {
|
|
69
|
+
description: {
|
|
70
|
+
component: readme,
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
argTypes: {
|
|
75
|
+
variant: {
|
|
76
|
+
options: Object.values(badgeVariantOptions),
|
|
77
|
+
control: {
|
|
78
|
+
type: 'select',
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
metaIcon: {
|
|
82
|
+
options: iconSpriteInfo.icons,
|
|
83
|
+
control: 'select',
|
|
84
|
+
},
|
|
85
|
+
titleIcon: {
|
|
86
|
+
options: iconSpriteInfo.icons,
|
|
87
|
+
control: 'select',
|
|
88
|
+
},
|
|
89
|
+
unit: {
|
|
90
|
+
control: 'text',
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
};
|
|
@@ -148,6 +148,55 @@ describe('empty state component', () => {
|
|
|
148
148
|
});
|
|
149
149
|
});
|
|
150
150
|
|
|
151
|
+
describe('with different titles', () => {
|
|
152
|
+
it('should render title from prop', () => {
|
|
153
|
+
component = shallowMount(EmptyState, {
|
|
154
|
+
propsData: {
|
|
155
|
+
...props,
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const title = component.find('h1');
|
|
160
|
+
expect(title.text()).toBe(props.title);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it('should render title from slot', () => {
|
|
164
|
+
const slotTitle = 'Slotted title';
|
|
165
|
+
|
|
166
|
+
component = shallowMount(EmptyState, {
|
|
167
|
+
propsData: {
|
|
168
|
+
...props,
|
|
169
|
+
title: null,
|
|
170
|
+
},
|
|
171
|
+
slots: {
|
|
172
|
+
title: `<strong id="slotted">${slotTitle}</strong>`,
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const title = component.find('#slotted');
|
|
177
|
+
expect(title.text()).toBe(slotTitle);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should render a slotted title over a props title', () => {
|
|
181
|
+
const slotTitle = 'Slotted title';
|
|
182
|
+
|
|
183
|
+
component = shallowMount(EmptyState, {
|
|
184
|
+
propsData: {
|
|
185
|
+
...props,
|
|
186
|
+
},
|
|
187
|
+
slots: {
|
|
188
|
+
title: `<strong id="slotted">${slotTitle}</strong>`,
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
const title = component.find('#slotted');
|
|
193
|
+
const propTitle = component.find('h1');
|
|
194
|
+
|
|
195
|
+
expect(title.text()).toBe(slotTitle);
|
|
196
|
+
expect(propTitle.exists()).toBe(false);
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
|
|
151
200
|
describe('with different descriptions', () => {
|
|
152
201
|
it('should render description from prop', () => {
|
|
153
202
|
component = shallowMount(EmptyState, {
|
|
@@ -11,7 +11,8 @@ export default {
|
|
|
11
11
|
*/
|
|
12
12
|
title: {
|
|
13
13
|
type: String,
|
|
14
|
-
required:
|
|
14
|
+
required: false,
|
|
15
|
+
default: null,
|
|
15
16
|
},
|
|
16
17
|
/**
|
|
17
18
|
* The illustration's URL.
|
|
@@ -112,13 +113,15 @@ export default {
|
|
|
112
113
|
</div>
|
|
113
114
|
<div :class="compact ? 'gl-flex-grow-1 gl-flex-basis-0 gl-px-4' : 'gl-max-w-full gl-m-auto'">
|
|
114
115
|
<div class="gl-mx-auto gl-my-0" :class="{ 'gl-p-5': !compact }">
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
>
|
|
120
|
-
|
|
121
|
-
|
|
116
|
+
<!--
|
|
117
|
+
@slot Use this slot to customize the empty state's title area.
|
|
118
|
+
Overrides the `title` prop.
|
|
119
|
+
-->
|
|
120
|
+
<slot ref="title" name="title">
|
|
121
|
+
<h1 class="gl-font-size-h-display gl-line-height-36" :class="compact ? 'h5' : 'h4'">
|
|
122
|
+
{{ title }}
|
|
123
|
+
</h1>
|
|
124
|
+
</slot>
|
|
122
125
|
<p v-if="description || $scopedSlots.description" ref="description" class="gl-mt-3">
|
|
123
126
|
<!--
|
|
124
127
|
@slot Use this slot to customize the empty state's description
|
package/src/scss/utilities.scss
CHANGED
|
@@ -1981,6 +1981,14 @@
|
|
|
1981
1981
|
color: inherit !important;
|
|
1982
1982
|
}
|
|
1983
1983
|
|
|
1984
|
+
.gl-text-transparent {
|
|
1985
|
+
color: transparent;
|
|
1986
|
+
}
|
|
1987
|
+
|
|
1988
|
+
.gl-text-transparent\! {
|
|
1989
|
+
color: transparent !important;
|
|
1990
|
+
}
|
|
1991
|
+
|
|
1984
1992
|
.gl-text-white {
|
|
1985
1993
|
color: $white;
|
|
1986
1994
|
}
|
|
@@ -6392,6 +6400,18 @@
|
|
|
6392
6400
|
padding-left: $gl-spacing-scale-7 !important;
|
|
6393
6401
|
}
|
|
6394
6402
|
}
|
|
6403
|
+
.gl-md-px-7 {
|
|
6404
|
+
@include gl-media-breakpoint-up(md) {
|
|
6405
|
+
padding-left: $gl-spacing-scale-7;
|
|
6406
|
+
padding-right: $gl-spacing-scale-7;
|
|
6407
|
+
}
|
|
6408
|
+
}
|
|
6409
|
+
.gl-md-px-7\! {
|
|
6410
|
+
@include gl-media-breakpoint-up(md) {
|
|
6411
|
+
padding-left: $gl-spacing-scale-7 !important;
|
|
6412
|
+
padding-right: $gl-spacing-scale-7 !important;
|
|
6413
|
+
}
|
|
6414
|
+
}
|
|
6395
6415
|
.gl-lg-pt-0 {
|
|
6396
6416
|
@include gl-media-breakpoint-up(lg) {
|
|
6397
6417
|
padding-top: 0;
|