@gitlab/ui 32.32.0 → 32.35.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_suggestion_list.js +7 -2
- package/dist/components/charts/area/area.js +3 -0
- package/dist/components/charts/bar/bar.js +2 -2
- package/dist/components/charts/chart/chart.js +20 -21
- package/dist/components/charts/legend/legend.js +1 -1
- package/dist/components/charts/tooltip/tooltip.js +1 -1
- package/dist/components/utilities/truncate/truncate.documentation.js +3 -0
- package/dist/components/utilities/truncate/truncate.js +34 -2
- package/dist/directives/resize_observer/resize_observer.documentation.js +1 -1
- package/dist/directives/resize_observer/resize_observer.js +43 -23
- package/dist/utility_classes.css +1 -1
- package/dist/utility_classes.css.map +1 -1
- package/dist/utils/charts/config.js +4 -3
- package/dist/utils/charts/mock_data.js +6 -3
- package/dist/utils/charts/theme.js +15 -9
- package/package.json +3 -3
- package/src/components/base/filtered_search/filtered_search_suggestion_list.spec.js +15 -8
- package/src/components/base/filtered_search/filtered_search_suggestion_list.vue +11 -2
- package/src/components/charts/area/area.vue +3 -0
- package/src/components/charts/bar/__snapshots__/bar.spec.js.snap +2 -2
- package/src/components/charts/bar/bar.vue +2 -2
- package/src/components/charts/chart/chart.spec.js +3 -1
- package/src/components/charts/chart/chart.vue +22 -20
- package/src/components/charts/column/__snapshots__/column_chart.spec.js.snap +6 -6
- package/src/components/charts/legend/legend.vue +1 -1
- package/src/components/charts/stacked_column/__snapshots__/stacked_column.spec.js.snap +26 -26
- package/src/components/charts/tooltip/tooltip.vue +1 -1
- package/src/components/utilities/truncate/truncate.documentation.js +3 -0
- package/src/components/utilities/truncate/truncate.spec.js +8 -0
- package/src/components/utilities/truncate/truncate.stories.js +6 -2
- package/src/components/utilities/truncate/truncate.vue +57 -7
- package/src/directives/resize_observer/resize_observer.js +34 -19
- package/src/directives/resize_observer/resize_observer.md +20 -0
- package/src/directives/resize_observer/resize_observer.spec.js +33 -1
- package/src/scss/utilities.scss +12 -0
- package/src/scss/utility-mixins/sizing.scss +6 -0
- package/src/utils/charts/config.js +3 -2
- package/src/utils/charts/mock_data.js +5 -2
- package/src/utils/charts/theme.js +14 -9
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
<script>
|
|
2
|
+
import { GlTooltipDirective } from '../../../directives/tooltip';
|
|
3
|
+
import { GlResizeObserverDirective } from '../../../directives/resize_observer/resize_observer';
|
|
2
4
|
import { POSITION } from './constants';
|
|
3
5
|
|
|
4
6
|
export default {
|
|
7
|
+
POSITION,
|
|
8
|
+
directives: {
|
|
9
|
+
GlTooltip: GlTooltipDirective,
|
|
10
|
+
GlResizeObserver: GlResizeObserverDirective,
|
|
11
|
+
},
|
|
5
12
|
props: {
|
|
6
13
|
text: {
|
|
7
14
|
type: String,
|
|
@@ -13,10 +20,15 @@ export default {
|
|
|
13
20
|
default: POSITION.END,
|
|
14
21
|
validator: (value) => Object.values(POSITION).includes(value),
|
|
15
22
|
},
|
|
23
|
+
withTooltip: {
|
|
24
|
+
type: Boolean,
|
|
25
|
+
required: false,
|
|
26
|
+
default: false,
|
|
27
|
+
},
|
|
16
28
|
},
|
|
17
29
|
data() {
|
|
18
30
|
return {
|
|
19
|
-
|
|
31
|
+
isTruncated: false,
|
|
20
32
|
};
|
|
21
33
|
},
|
|
22
34
|
computed: {
|
|
@@ -30,24 +42,62 @@ export default {
|
|
|
30
42
|
last() {
|
|
31
43
|
return this.text.slice(this.middleIndex);
|
|
32
44
|
},
|
|
45
|
+
isTooltipDisabled() {
|
|
46
|
+
return !this.withTooltip || !this.isTruncated;
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
watch: {
|
|
50
|
+
withTooltip(withTooltip) {
|
|
51
|
+
if (withTooltip) {
|
|
52
|
+
this.checkTruncationState();
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
methods: {
|
|
57
|
+
checkTruncationState() {
|
|
58
|
+
if (this.withTooltip) {
|
|
59
|
+
this.isTruncated = this.$refs.text.scrollWidth > this.$refs.text.offsetWidth;
|
|
60
|
+
}
|
|
61
|
+
},
|
|
33
62
|
},
|
|
34
63
|
};
|
|
35
64
|
</script>
|
|
36
65
|
|
|
37
66
|
<template>
|
|
38
67
|
<!-- START -->
|
|
39
|
-
<span
|
|
40
|
-
|
|
68
|
+
<span
|
|
69
|
+
v-if="position === $options.POSITION.START"
|
|
70
|
+
v-gl-tooltip="{ disabled: isTooltipDisabled }"
|
|
71
|
+
v-gl-resize-observer:[withTooltip]="checkTruncationState"
|
|
72
|
+
class="gl-truncate"
|
|
73
|
+
:title="text"
|
|
74
|
+
>
|
|
75
|
+
<span ref="text" class="gl-truncate-start gl-text-overflow-ellipsis!"
|
|
76
|
+
>‎{{ text }}‎</span
|
|
77
|
+
>
|
|
41
78
|
</span>
|
|
42
79
|
|
|
43
80
|
<!-- MIDDLE -->
|
|
44
|
-
<span
|
|
45
|
-
|
|
81
|
+
<span
|
|
82
|
+
v-else-if="position === $options.POSITION.MIDDLE"
|
|
83
|
+
v-gl-tooltip="{ disabled: isTooltipDisabled }"
|
|
84
|
+
v-gl-resize-observer:[withTooltip]="checkTruncationState"
|
|
85
|
+
class="gl-truncate"
|
|
86
|
+
:title="text"
|
|
87
|
+
>
|
|
88
|
+
<span ref="text" class="gl-truncate-end">{{ first }}</span
|
|
46
89
|
><span class="gl-truncate-start">‎{{ last }}‎</span>
|
|
47
90
|
</span>
|
|
48
91
|
|
|
49
92
|
<!-- END -->
|
|
50
|
-
<span
|
|
51
|
-
|
|
93
|
+
<span
|
|
94
|
+
v-else
|
|
95
|
+
v-gl-tooltip="{ disabled: isTooltipDisabled }"
|
|
96
|
+
v-gl-resize-observer:[withTooltip]="checkTruncationState"
|
|
97
|
+
class="gl-truncate"
|
|
98
|
+
data-testid="truncate-end-container"
|
|
99
|
+
:title="text"
|
|
100
|
+
>
|
|
101
|
+
<span ref="text" class="gl-truncate-end">{{ text }}</span>
|
|
52
102
|
</span>
|
|
53
103
|
</template>
|
|
@@ -2,29 +2,44 @@ import isFunction from 'lodash/isFunction';
|
|
|
2
2
|
|
|
3
3
|
let observer = null;
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
5
|
+
const attachObserver = (el, resizeHandler) => {
|
|
6
|
+
if (!isFunction(resizeHandler)) {
|
|
7
|
+
throw TypeError('directive value must be a function');
|
|
8
|
+
}
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
});
|
|
10
|
+
if (!observer) {
|
|
11
|
+
// the observer instance is shared for performance reasons
|
|
12
|
+
// more information: https://github.com/WICG/ResizeObserver/issues/59
|
|
13
|
+
observer = new ResizeObserver((entries) => {
|
|
14
|
+
entries.forEach((event) => {
|
|
15
|
+
event.target.glResizeHandler(event);
|
|
18
16
|
});
|
|
19
|
-
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
el.glResizeHandler = resizeHandler;
|
|
21
|
+
observer.observe(el);
|
|
22
|
+
};
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
const detachObserver = (el) => {
|
|
25
|
+
if (el.glResizeHandler) {
|
|
26
|
+
delete el.glResizeHandler;
|
|
27
|
+
observer?.unobserve(el);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const GlResizeObserverDirective = {
|
|
32
|
+
bind(el, { value: resizeHandler, arg: enabled = true }) {
|
|
33
|
+
if (enabled) {
|
|
34
|
+
attachObserver(el, resizeHandler);
|
|
35
|
+
}
|
|
23
36
|
},
|
|
24
|
-
|
|
25
|
-
if (
|
|
26
|
-
|
|
27
|
-
|
|
37
|
+
update(el, { value: resizeHandler, arg: enabled = true }) {
|
|
38
|
+
if (enabled) {
|
|
39
|
+
attachObserver(el, resizeHandler);
|
|
40
|
+
} else {
|
|
41
|
+
detachObserver(el);
|
|
28
42
|
}
|
|
29
43
|
},
|
|
44
|
+
unbind: detachObserver,
|
|
30
45
|
};
|
|
@@ -38,3 +38,23 @@ export default {
|
|
|
38
38
|
</div>
|
|
39
39
|
</template>
|
|
40
40
|
```
|
|
41
|
+
|
|
42
|
+
The observer can be toggled on or off by passing a boolean argument to the directive:
|
|
43
|
+
|
|
44
|
+
```html
|
|
45
|
+
<script>
|
|
46
|
+
export default {
|
|
47
|
+
data() {
|
|
48
|
+
return {
|
|
49
|
+
shouldObserve: true,
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
methods: {
|
|
53
|
+
handleResize() {},
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
</script>
|
|
57
|
+
<template>
|
|
58
|
+
<div v-gl-resize-observer-directive[shouldObserve]="handleResize"></div>
|
|
59
|
+
</template>
|
|
60
|
+
```
|
|
@@ -10,7 +10,7 @@ describe('resize observer directive', () => {
|
|
|
10
10
|
const localVue = createLocalVue();
|
|
11
11
|
let wrapper;
|
|
12
12
|
|
|
13
|
-
const createComponent = ({ template } = {}) => {
|
|
13
|
+
const createComponent = ({ template, data = {} } = {}) => {
|
|
14
14
|
const defaultTemplate = `<div v-resize-observer="handleResize"></div>`;
|
|
15
15
|
|
|
16
16
|
const component = {
|
|
@@ -21,6 +21,9 @@ describe('resize observer directive', () => {
|
|
|
21
21
|
handleResize: mockHandleResize,
|
|
22
22
|
},
|
|
23
23
|
template: template || defaultTemplate,
|
|
24
|
+
data() {
|
|
25
|
+
return data;
|
|
26
|
+
},
|
|
24
27
|
};
|
|
25
28
|
|
|
26
29
|
wrapper = shallowMount(component, { localVue });
|
|
@@ -52,6 +55,13 @@ describe('resize observer directive', () => {
|
|
|
52
55
|
expect(observesElement(wrapper.element)).toBe(true);
|
|
53
56
|
});
|
|
54
57
|
|
|
58
|
+
it('does not subscribe if the argument is false', () => {
|
|
59
|
+
createComponent({ template: '<div v-resize-observer:[false]="handleResize"></div>' });
|
|
60
|
+
|
|
61
|
+
expect(observersCount()).toBe(0);
|
|
62
|
+
expect(observesElement(wrapper.element)).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
|
|
55
65
|
it('passes the first entries "contentRect" and "target" to the given handler', () => {
|
|
56
66
|
createComponent();
|
|
57
67
|
|
|
@@ -61,6 +71,28 @@ describe('resize observer directive', () => {
|
|
|
61
71
|
expect(mockHandleResize).toHaveBeenCalledWith({ contentRect: {}, target: wrapper.element });
|
|
62
72
|
});
|
|
63
73
|
|
|
74
|
+
it("detaches then reattaches observer based on argument's value", async () => {
|
|
75
|
+
expect(observersCount()).toBe(0);
|
|
76
|
+
|
|
77
|
+
createComponent({
|
|
78
|
+
template: '<div v-resize-observer:[isEnabled]="handleResize"></div>',
|
|
79
|
+
data: {
|
|
80
|
+
isEnabled: true,
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
expect(observersCount()).toBe(1);
|
|
85
|
+
expect(wrapper.element.glResizeHandler).not.toBeFalsy();
|
|
86
|
+
|
|
87
|
+
await wrapper.setData({ isEnabled: false });
|
|
88
|
+
|
|
89
|
+
expect(wrapper.element.glResizeHandler).toBeFalsy();
|
|
90
|
+
|
|
91
|
+
await wrapper.setData({ isEnabled: true });
|
|
92
|
+
|
|
93
|
+
expect(wrapper.element.glResizeHandler).not.toBeFalsy();
|
|
94
|
+
});
|
|
95
|
+
|
|
64
96
|
it('does a clean up when the component is destroyed', () => {
|
|
65
97
|
createComponent();
|
|
66
98
|
|
package/src/scss/utilities.scss
CHANGED
|
@@ -4201,6 +4201,18 @@
|
|
|
4201
4201
|
}
|
|
4202
4202
|
}
|
|
4203
4203
|
|
|
4204
|
+
.gl-lg-w-1px {
|
|
4205
|
+
@media (min-width: $breakpoint-lg) {
|
|
4206
|
+
width: 1px;
|
|
4207
|
+
}
|
|
4208
|
+
}
|
|
4209
|
+
|
|
4210
|
+
.gl-lg-w-1px\! {
|
|
4211
|
+
@media (min-width: $breakpoint-lg) {
|
|
4212
|
+
width: 1px !important;
|
|
4213
|
+
}
|
|
4214
|
+
}
|
|
4215
|
+
|
|
4204
4216
|
.gl-md-w-50p {
|
|
4205
4217
|
@include gl-media-breakpoint-up(md) {
|
|
4206
4218
|
width: 50%;
|
|
@@ -12,6 +12,7 @@ import { ANNOTATIONS_SERIES_NAME, arrowSymbol, CHART_TYPE_BAR, CHART_TYPE_LINE }
|
|
|
12
12
|
export const defaultAreaOpacity = 0.2;
|
|
13
13
|
export const defaultFontSize = 12;
|
|
14
14
|
export const defaultHeight = 400;
|
|
15
|
+
export const defaultWidth = 300;
|
|
15
16
|
export const validRenderers = ['canvas', 'svg'];
|
|
16
17
|
|
|
17
18
|
export const axes = {
|
|
@@ -433,8 +434,8 @@ export const generateBarSeries = ({
|
|
|
433
434
|
yAxisIndex,
|
|
434
435
|
itemStyle: {
|
|
435
436
|
color: hexToRgba(color, 0.2),
|
|
436
|
-
|
|
437
|
-
|
|
437
|
+
borderColor: color,
|
|
438
|
+
borderWidth: 1,
|
|
438
439
|
},
|
|
439
440
|
emphasis: {
|
|
440
441
|
itemStyle: {
|
|
@@ -43,6 +43,9 @@ export const mockDefaultChartOptions = {
|
|
|
43
43
|
axisPointer: {
|
|
44
44
|
show: true,
|
|
45
45
|
label: {},
|
|
46
|
+
lineStyle: {
|
|
47
|
+
type: 'solid',
|
|
48
|
+
},
|
|
46
49
|
},
|
|
47
50
|
},
|
|
48
51
|
yAxis: {
|
|
@@ -204,8 +207,8 @@ export const mockDefaultBarChartConfig = {
|
|
|
204
207
|
yAxisIndex: 0,
|
|
205
208
|
itemStyle: {
|
|
206
209
|
color: hexToRgba(color, 0.2),
|
|
207
|
-
|
|
208
|
-
|
|
210
|
+
borderColor: color,
|
|
211
|
+
borderWidth: 1,
|
|
209
212
|
},
|
|
210
213
|
emphasis: {
|
|
211
214
|
itemStyle: {
|
|
@@ -105,15 +105,14 @@ const axes = {
|
|
|
105
105
|
margin: 8,
|
|
106
106
|
show: true,
|
|
107
107
|
color: gray600,
|
|
108
|
-
|
|
109
|
-
color: gray600,
|
|
110
|
-
},
|
|
108
|
+
hideOverlap: true,
|
|
111
109
|
},
|
|
112
110
|
axisLine: {
|
|
113
111
|
show: false,
|
|
114
112
|
},
|
|
115
113
|
axisPointer: {
|
|
116
114
|
lineStyle: {
|
|
115
|
+
type: 'solid',
|
|
117
116
|
color: gray600,
|
|
118
117
|
},
|
|
119
118
|
label: {
|
|
@@ -175,6 +174,7 @@ const createTheme = (options = {}) => ({
|
|
|
175
174
|
dataZoom: {
|
|
176
175
|
borderColor: 'transparent',
|
|
177
176
|
filterMode: 'none',
|
|
177
|
+
brushSelect: false,
|
|
178
178
|
dataBackground: {
|
|
179
179
|
lineStyle: {
|
|
180
180
|
width: 2,
|
|
@@ -184,7 +184,7 @@ const createTheme = (options = {}) => ({
|
|
|
184
184
|
// render unfilled zoom-graph if the series is a line chart without area styles
|
|
185
185
|
// more details: https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/2364#note_666637306
|
|
186
186
|
areaStyle: isLineChartWithoutArea(options)
|
|
187
|
-
? null
|
|
187
|
+
? {} // Use empty object instead of null, see https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/2185#note_707711029 for more context
|
|
188
188
|
: {
|
|
189
189
|
color: gray50,
|
|
190
190
|
opacity: 1,
|
|
@@ -192,7 +192,10 @@ const createTheme = (options = {}) => ({
|
|
|
192
192
|
},
|
|
193
193
|
fillerColor: hexToRgba(gray200, 0.23),
|
|
194
194
|
handleIcon: scrollHandleSvgPath,
|
|
195
|
-
|
|
195
|
+
handleStyle: {
|
|
196
|
+
borderColor: 'transparent',
|
|
197
|
+
color: gray500,
|
|
198
|
+
},
|
|
196
199
|
handleSize: '50%',
|
|
197
200
|
labelFormatter: () => null,
|
|
198
201
|
textStyle: {
|
|
@@ -203,14 +206,16 @@ const createTheme = (options = {}) => ({
|
|
|
203
206
|
top: '-5',
|
|
204
207
|
left: 'center',
|
|
205
208
|
itemSize: 14,
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
borderWidth: 0,
|
|
209
|
-
emphasis: {
|
|
209
|
+
emphasis: {
|
|
210
|
+
iconStyle: {
|
|
210
211
|
borderWidth: 0,
|
|
211
212
|
color: gray700,
|
|
212
213
|
},
|
|
213
214
|
},
|
|
215
|
+
iconStyle: {
|
|
216
|
+
color: gray200,
|
|
217
|
+
borderWidth: 0,
|
|
218
|
+
},
|
|
214
219
|
itemGap: 8,
|
|
215
220
|
feature: {
|
|
216
221
|
dataZoom: {
|