@gitlab/ui 37.8.0 → 37.9.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 +7 -0
- package/dist/components/utilities/truncate/truncate.js +2 -2
- package/package.json +1 -1
- package/src/components/utilities/truncate/truncate.spec.js +49 -14
- package/src/components/utilities/truncate/truncate.stories.js +59 -1
- package/src/components/utilities/truncate/truncate.vue +21 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [37.9.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v37.8.0...v37.9.0) (2022-03-15)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **GlTruncate:** add slots to surround the text ([4a79750](https://gitlab.com/gitlab-org/gitlab-ui/commit/4a797503c85ac755e7dd4df1b2d46e95f3102e04))
|
|
7
|
+
|
|
1
8
|
# [37.8.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v37.7.0...v37.8.0) (2022-03-15)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { GlTooltipDirective } from '../../../directives/tooltip';
|
|
2
1
|
import { GlResizeObserverDirective } from '../../../directives/resize_observer/resize_observer';
|
|
2
|
+
import { GlTooltipDirective } from '../../../directives/tooltip';
|
|
3
3
|
import { POSITION } from './constants';
|
|
4
4
|
import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
|
|
5
5
|
|
|
@@ -84,7 +84,7 @@ var script = {
|
|
|
84
84
|
const __vue_script__ = script;
|
|
85
85
|
|
|
86
86
|
/* template */
|
|
87
|
-
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return (_vm.position === _vm.$options.POSITION.START)?_c('span',{directives:[{name:"gl-tooltip",rawName:"v-gl-tooltip",value:({ disabled: _vm.isTooltipDisabled }),expression:"{ disabled: isTooltipDisabled }"},{name:"gl-resize-observer",rawName:"v-gl-resize-observer:[withTooltip]",value:(_vm.checkTruncationState),expression:"checkTruncationState",arg:_vm.withTooltip}],staticClass:"gl-truncate",attrs:{"title":_vm.text}},[_c('span',{ref:"text",staticClass:"gl-truncate-start gl-text-overflow-ellipsis!"},[_vm._v(""+_vm._s(_vm.text)+"")])]):(_vm.position === _vm.$options.POSITION.MIDDLE)?_c('span',{directives:[{name:"gl-tooltip",rawName:"v-gl-tooltip",value:({ disabled: _vm.isTooltipDisabled }),expression:"{ disabled: isTooltipDisabled }"},{name:"gl-resize-observer",rawName:"v-gl-resize-observer:[withTooltip]",value:(_vm.checkTruncationState),expression:"checkTruncationState",arg:_vm.withTooltip}],staticClass:"gl-truncate",attrs:{"title":_vm.text}},[_c('span',{ref:"text",staticClass:"gl-truncate-end"},[_vm._v(_vm._s(_vm.first))]),_c('span',{staticClass:"gl-truncate-start"},[_vm._v(""+_vm._s(_vm.last)+"")])]):_c('span',{directives:[{name:"gl-tooltip",rawName:"v-gl-tooltip",value:({ disabled: _vm.isTooltipDisabled }),expression:"{ disabled: isTooltipDisabled }"},{name:"gl-resize-observer",rawName:"v-gl-resize-observer:[withTooltip]",value:(_vm.checkTruncationState),expression:"checkTruncationState",arg:_vm.withTooltip}],staticClass:"gl-truncate",attrs:{"data-testid":"truncate-end-container","title":_vm.text}},[_c('span',{ref:"text",staticClass:"gl-truncate-end"},[_vm._v(_vm._s(_vm.text))])])};
|
|
87
|
+
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return (_vm.position === _vm.$options.POSITION.START)?_c('span',{directives:[{name:"gl-tooltip",rawName:"v-gl-tooltip",value:({ disabled: _vm.isTooltipDisabled }),expression:"{ disabled: isTooltipDisabled }"},{name:"gl-resize-observer",rawName:"v-gl-resize-observer:[withTooltip]",value:(_vm.checkTruncationState),expression:"checkTruncationState",arg:_vm.withTooltip}],staticClass:"gl-truncate",attrs:{"title":_vm.text}},[(_vm.$scopedSlots['before-text'])?_c('span',{staticClass:"gl-pr-3"},[_vm._t("before-text")],2):_vm._e(),_vm._v(" "),_c('span',{ref:"text",staticClass:"gl-truncate-start gl-text-overflow-ellipsis!"},[_vm._v(""+_vm._s(_vm.text)+"")]),_vm._v(" "),(_vm.$scopedSlots['after-text'])?_c('span',{staticClass:"gl-pl-3"},[_vm._t("after-text")],2):_vm._e()]):(_vm.position === _vm.$options.POSITION.MIDDLE)?_c('span',{directives:[{name:"gl-tooltip",rawName:"v-gl-tooltip",value:({ disabled: _vm.isTooltipDisabled }),expression:"{ disabled: isTooltipDisabled }"},{name:"gl-resize-observer",rawName:"v-gl-resize-observer:[withTooltip]",value:(_vm.checkTruncationState),expression:"checkTruncationState",arg:_vm.withTooltip}],staticClass:"gl-truncate",attrs:{"title":_vm.text}},[(_vm.$scopedSlots['before-text'])?_c('span',{staticClass:"gl-pr-3"},[_vm._t("before-text")],2):_vm._e(),_vm._v(" "),_c('span',{ref:"text",staticClass:"gl-truncate-end",attrs:{"data-testid":"text-beginning"}},[_vm._v(_vm._s(_vm.first))]),_c('span',{staticClass:"gl-truncate-start",attrs:{"data-testid":"text-ending"}},[_vm._v(""+_vm._s(_vm.last)+"")]),_vm._v(" "),(_vm.$scopedSlots['after-text'])?_c('span',{staticClass:"gl-pl-3"},[_vm._t("after-text")],2):_vm._e()]):_c('span',{directives:[{name:"gl-tooltip",rawName:"v-gl-tooltip",value:({ disabled: _vm.isTooltipDisabled }),expression:"{ disabled: isTooltipDisabled }"},{name:"gl-resize-observer",rawName:"v-gl-resize-observer:[withTooltip]",value:(_vm.checkTruncationState),expression:"checkTruncationState",arg:_vm.withTooltip}],staticClass:"gl-truncate",attrs:{"data-testid":"truncate-end-container","title":_vm.text}},[(_vm.$scopedSlots['before-text'])?_c('span',{staticClass:"gl-pr-3"},[_vm._t("before-text")],2):_vm._e(),_vm._v(" "),_c('span',{ref:"text",staticClass:"gl-truncate-end"},[_vm._v(_vm._s(_vm.text))]),_vm._v(" "),(_vm.$scopedSlots['after-text'])?_c('span',{staticClass:"gl-pl-3"},[_vm._t("after-text")],2):_vm._e()])};
|
|
88
88
|
var __vue_staticRenderFns__ = [];
|
|
89
89
|
|
|
90
90
|
/* style */
|
package/package.json
CHANGED
|
@@ -16,10 +16,12 @@ describe('Truncate component', () => {
|
|
|
16
16
|
text: 'ee/app/assets/javascripts/vue_shared/src/utils_reports/components/utils/index.js',
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
const
|
|
19
|
+
const findByTestId = (testId) => wrapper.find(`[data-testid="${testId}"]`);
|
|
20
|
+
|
|
21
|
+
const createComponent = (props, slots = {}) => {
|
|
20
22
|
wrapper = shallowMount(
|
|
21
23
|
{ extends: Truncate, directives: { GlTooltip: createMockDirective('gl-tooltip') } },
|
|
22
|
-
{ propsData: { ...defaultProps, ...props } }
|
|
24
|
+
{ propsData: { ...defaultProps, ...props }, slots }
|
|
23
25
|
);
|
|
24
26
|
};
|
|
25
27
|
|
|
@@ -55,12 +57,13 @@ describe('Truncate component', () => {
|
|
|
55
57
|
createComponent({ position: 'start' });
|
|
56
58
|
});
|
|
57
59
|
|
|
58
|
-
it('should have the truncate-start class', () => {
|
|
59
|
-
|
|
60
|
+
it('should have the truncate-start class on the text span', () => {
|
|
61
|
+
const textSpan = wrapper.findComponent({ ref: 'text' });
|
|
62
|
+
expect(textSpan.classes('gl-truncate-start')).toBe(true);
|
|
60
63
|
});
|
|
61
64
|
|
|
62
65
|
it('should have the special char surrounded', () => {
|
|
63
|
-
const spanTag = wrapper.
|
|
66
|
+
const spanTag = wrapper.findComponent({ ref: 'text' }).text();
|
|
64
67
|
|
|
65
68
|
expect(spanTag.charAt(0)).toBe('\u200E');
|
|
66
69
|
expect(spanTag.charAt(spanTag.length - 1)).toBe('\u200E');
|
|
@@ -68,27 +71,27 @@ describe('Truncate component', () => {
|
|
|
68
71
|
});
|
|
69
72
|
|
|
70
73
|
describe('middle truncation', () => {
|
|
71
|
-
let
|
|
72
|
-
let
|
|
74
|
+
let firstTextSpan;
|
|
75
|
+
let secondTextSpan;
|
|
73
76
|
|
|
74
77
|
beforeEach(() => {
|
|
75
78
|
createComponent({ position: 'middle' });
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
firstTextSpan = findByTestId('text-beginning');
|
|
80
|
+
secondTextSpan = findByTestId('text-ending');
|
|
78
81
|
});
|
|
79
82
|
|
|
80
83
|
it('should have appropriate classes applied', () => {
|
|
81
|
-
expect(
|
|
82
|
-
expect(
|
|
84
|
+
expect(firstTextSpan.classes('gl-truncate-end')).toBe(true);
|
|
85
|
+
expect(secondTextSpan.classes('gl-truncate-start')).toBe(true);
|
|
83
86
|
});
|
|
84
87
|
|
|
85
88
|
it('should have the spans positioned correctly', () => {
|
|
86
|
-
expect(
|
|
87
|
-
expect(
|
|
89
|
+
expect(firstTextSpan.text()).toBe('ee/app/assets/javascripts/vue_shared/src');
|
|
90
|
+
expect(secondTextSpan.text()).toBe('/utils_reports/components/utils/index.js');
|
|
88
91
|
});
|
|
89
92
|
|
|
90
93
|
it('last part should have the special char surrounded', () => {
|
|
91
|
-
const lastPart =
|
|
94
|
+
const lastPart = secondTextSpan.text();
|
|
92
95
|
|
|
93
96
|
expect(lastPart.charAt(0)).toBe('\u200E');
|
|
94
97
|
expect(lastPart.charAt(lastPart.length - 1)).toBe('\u200E');
|
|
@@ -108,4 +111,36 @@ describe('Truncate component', () => {
|
|
|
108
111
|
expect(wrapper.find('.gl-truncate-end').exists()).toBe(true);
|
|
109
112
|
});
|
|
110
113
|
});
|
|
114
|
+
|
|
115
|
+
describe('slots', () => {
|
|
116
|
+
const beforeText = 'Before Text Slot';
|
|
117
|
+
const afterText = 'After Text Slot';
|
|
118
|
+
const slotOptions = {
|
|
119
|
+
'before-text': {
|
|
120
|
+
slot: `<span id="before-text">${beforeText}</span>`,
|
|
121
|
+
text: beforeText,
|
|
122
|
+
},
|
|
123
|
+
'after-text': {
|
|
124
|
+
slot: `<span id="after-text">${afterText}</span>`,
|
|
125
|
+
text: afterText,
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
it.each`
|
|
130
|
+
position | slotType
|
|
131
|
+
${'start'} | ${'before-text'}
|
|
132
|
+
${'start'} | ${'after-text'}
|
|
133
|
+
${'middle'} | ${'before-text'}
|
|
134
|
+
${'middle'} | ${'after-text'}
|
|
135
|
+
${'end'} | ${'before-text'}
|
|
136
|
+
${'end'} | ${'after-text'}
|
|
137
|
+
`('$position truncation $slot slot', ({ position, slotType }) => {
|
|
138
|
+
const slot = { [slotType]: slotOptions[slotType].slot };
|
|
139
|
+
|
|
140
|
+
createComponent({ position }, slot);
|
|
141
|
+
|
|
142
|
+
const slotComponent = wrapper.find(`#${slotType}`);
|
|
143
|
+
expect(slotComponent.text()).toBe(slotOptions[slotType].text);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
111
146
|
});
|
|
@@ -1,8 +1,21 @@
|
|
|
1
|
-
import { GlTruncate } from '../../../index';
|
|
1
|
+
import { GlIcon, GlTruncate } from '../../../index';
|
|
2
2
|
import { POSITION } from './constants';
|
|
3
3
|
import readme from './truncate.md';
|
|
4
4
|
|
|
5
5
|
const template = '<gl-truncate :text="text" :position="position" :with-tooltip="withTooltip" />';
|
|
6
|
+
const beforeTextTemplate = `
|
|
7
|
+
<gl-truncate :text="text" :position="position" :with-tooltip="withTooltip">
|
|
8
|
+
<template #before-text><gl-icon name="container-image" /></template>
|
|
9
|
+
</gl-truncate>`;
|
|
10
|
+
const afterTextTemplate = `
|
|
11
|
+
<gl-truncate :text="text" :position="position" :with-tooltip="withTooltip">
|
|
12
|
+
<template #after-text><gl-icon name="abuse" /></template>
|
|
13
|
+
</gl-truncate>`;
|
|
14
|
+
const bothSlotsTemplate = `
|
|
15
|
+
<gl-truncate :text="text" :position="position" :with-tooltip="withTooltip">
|
|
16
|
+
<template #before-text><gl-icon name="rocket" /></template>
|
|
17
|
+
<template #after-text><gl-icon name="requirements" /></template>
|
|
18
|
+
</gl-truncate>`;
|
|
6
19
|
|
|
7
20
|
const generateProps = ({
|
|
8
21
|
text = 'src/thisIs/AVeryLongFilePath/that/needs/to/be/smartly/truncated/from/the/middle/so/we/dont/lose/important/information/here.vue',
|
|
@@ -24,6 +37,51 @@ const Template = (args, { argTypes }) => ({
|
|
|
24
37
|
export const Default = Template.bind({});
|
|
25
38
|
Default.args = generateProps();
|
|
26
39
|
|
|
40
|
+
const BeforeTextTemplate = (args, { argTypes }) => ({
|
|
41
|
+
components: { GlIcon, GlTruncate },
|
|
42
|
+
props: Object.keys(argTypes),
|
|
43
|
+
template: beforeTextTemplate,
|
|
44
|
+
});
|
|
45
|
+
export const BeforeText = BeforeTextTemplate.bind({});
|
|
46
|
+
BeforeText.args = generateProps({ position: 'start' });
|
|
47
|
+
BeforeText.parameters = {
|
|
48
|
+
docs: {
|
|
49
|
+
source: {
|
|
50
|
+
code: beforeTextTemplate,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const AfterTextTemplate = (args, { argTypes }) => ({
|
|
56
|
+
components: { GlIcon, GlTruncate },
|
|
57
|
+
props: Object.keys(argTypes),
|
|
58
|
+
template: afterTextTemplate,
|
|
59
|
+
});
|
|
60
|
+
export const AfterText = AfterTextTemplate.bind({});
|
|
61
|
+
AfterText.args = generateProps({ position: 'end' });
|
|
62
|
+
AfterText.parameters = {
|
|
63
|
+
docs: {
|
|
64
|
+
source: {
|
|
65
|
+
code: afterTextTemplate,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const BothSlotsTemplate = (args, { argTypes }) => ({
|
|
71
|
+
components: { GlIcon, GlTruncate },
|
|
72
|
+
props: Object.keys(argTypes),
|
|
73
|
+
template: bothSlotsTemplate,
|
|
74
|
+
});
|
|
75
|
+
export const BothSlots = BothSlotsTemplate.bind({});
|
|
76
|
+
BothSlots.args = generateProps();
|
|
77
|
+
BothSlots.parameters = {
|
|
78
|
+
docs: {
|
|
79
|
+
source: {
|
|
80
|
+
code: bothSlotsTemplate,
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
27
85
|
export default {
|
|
28
86
|
title: 'utilities/truncate',
|
|
29
87
|
component: GlTruncate,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { GlTooltipDirective } from '../../../directives/tooltip';
|
|
3
2
|
import { GlResizeObserverDirective } from '../../../directives/resize_observer/resize_observer';
|
|
3
|
+
import { GlTooltipDirective } from '../../../directives/tooltip';
|
|
4
4
|
import { POSITION } from './constants';
|
|
5
5
|
|
|
6
6
|
export default {
|
|
@@ -81,9 +81,15 @@ export default {
|
|
|
81
81
|
class="gl-truncate"
|
|
82
82
|
:title="text"
|
|
83
83
|
>
|
|
84
|
+
<span v-if="$scopedSlots['before-text']" class="gl-pr-3">
|
|
85
|
+
<slot name="before-text"></slot>
|
|
86
|
+
</span>
|
|
84
87
|
<span ref="text" class="gl-truncate-start gl-text-overflow-ellipsis!"
|
|
85
88
|
>‎{{ text }}‎</span
|
|
86
89
|
>
|
|
90
|
+
<span v-if="$scopedSlots['after-text']" class="gl-pl-3">
|
|
91
|
+
<slot name="after-text"></slot>
|
|
92
|
+
</span>
|
|
87
93
|
</span>
|
|
88
94
|
|
|
89
95
|
<!-- MIDDLE -->
|
|
@@ -94,8 +100,14 @@ export default {
|
|
|
94
100
|
class="gl-truncate"
|
|
95
101
|
:title="text"
|
|
96
102
|
>
|
|
97
|
-
<span
|
|
98
|
-
|
|
103
|
+
<span v-if="$scopedSlots['before-text']" class="gl-pr-3">
|
|
104
|
+
<slot name="before-text"></slot>
|
|
105
|
+
</span>
|
|
106
|
+
<span ref="text" class="gl-truncate-end" data-testid="text-beginning">{{ first }}</span
|
|
107
|
+
><span class="gl-truncate-start" data-testid="text-ending">‎{{ last }}‎</span>
|
|
108
|
+
<span v-if="$scopedSlots['after-text']" class="gl-pl-3">
|
|
109
|
+
<slot name="after-text"></slot>
|
|
110
|
+
</span>
|
|
99
111
|
</span>
|
|
100
112
|
|
|
101
113
|
<!-- END -->
|
|
@@ -107,6 +119,12 @@ export default {
|
|
|
107
119
|
data-testid="truncate-end-container"
|
|
108
120
|
:title="text"
|
|
109
121
|
>
|
|
122
|
+
<span v-if="$scopedSlots['before-text']" class="gl-pr-3">
|
|
123
|
+
<slot name="before-text"></slot>
|
|
124
|
+
</span>
|
|
110
125
|
<span ref="text" class="gl-truncate-end">{{ text }}</span>
|
|
126
|
+
<span v-if="$scopedSlots['after-text']" class="gl-pl-3">
|
|
127
|
+
<slot name="after-text"></slot>
|
|
128
|
+
</span>
|
|
111
129
|
</span>
|
|
112
130
|
</template>
|