1 |
|
2 | <script>
|
3 | import { GlTooltipDirective } from '../../../directives/tooltip';
|
4 | import { GlResizeObserverDirective } from '../../../directives/resize_observer/resize_observer';
|
5 | import { POSITION } from './constants';
|
6 |
|
7 | export default {
|
8 | POSITION,
|
9 | directives: {
|
10 | GlTooltip: GlTooltipDirective,
|
11 | GlResizeObserver: GlResizeObserverDirective,
|
12 | },
|
13 | props: {
|
14 | /**
|
15 | * Text to be ellipsized
|
16 | */
|
17 | text: {
|
18 | type: String,
|
19 | required: true,
|
20 | },
|
21 | /**
|
22 | * Ellipsis position
|
23 | */
|
24 | position: {
|
25 | type: String,
|
26 | required: false,
|
27 | default: POSITION.END,
|
28 | validator: (value) => Object.values(POSITION).includes(value),
|
29 | },
|
30 | /**
|
31 | * Display the full text in a tooltip only if it is being truncated
|
32 | */
|
33 | withTooltip: {
|
34 | type: Boolean,
|
35 | required: false,
|
36 | default: false,
|
37 | },
|
38 | },
|
39 | data() {
|
40 | return {
|
41 | isTruncated: false,
|
42 | };
|
43 | },
|
44 | computed: {
|
45 | middleIndex() {
|
46 | return Math.floor(this.text.length / 2);
|
47 | },
|
48 |
|
49 | first() {
|
50 | return this.text.slice(0, this.middleIndex);
|
51 | },
|
52 | last() {
|
53 | return this.text.slice(this.middleIndex);
|
54 | },
|
55 | isTooltipDisabled() {
|
56 | return !this.withTooltip || !this.isTruncated;
|
57 | },
|
58 | },
|
59 | watch: {
|
60 | withTooltip(withTooltip) {
|
61 | if (withTooltip) {
|
62 | this.checkTruncationState();
|
63 | }
|
64 | },
|
65 | },
|
66 | methods: {
|
67 | checkTruncationState() {
|
68 | if (this.withTooltip) {
|
69 | this.isTruncated = this.$refs.text.scrollWidth > this.$refs.text.offsetWidth;
|
70 | }
|
71 | },
|
72 | },
|
73 | };
|
74 | </script>
|
75 |
|
76 | <template>
|
77 |
|
78 | <span
|
79 | v-if="position === $options.POSITION.START"
|
80 | v-gl-tooltip="{ disabled: isTooltipDisabled }"
|
81 | v-gl-resize-observer:[withTooltip]="checkTruncationState"
|
82 | class="gl-truncate"
|
83 | :title="text"
|
84 | >
|
85 | <span ref="text" class="gl-truncate-start gl-text-overflow-ellipsis!"
|
86 | >‎{{ text }}‎</span
|
87 | >
|
88 | </span>
|
89 |
|
90 |
|
91 | <span
|
92 | v-else-if="position === $options.POSITION.MIDDLE"
|
93 | v-gl-tooltip="{ disabled: isTooltipDisabled }"
|
94 | v-gl-resize-observer:[withTooltip]="checkTruncationState"
|
95 | class="gl-truncate"
|
96 | :title="text"
|
97 | >
|
98 | <span ref="text" class="gl-truncate-end">{{ first }}</span
|
99 | ><span class="gl-truncate-start">‎{{ last }}‎</span>
|
100 | </span>
|
101 |
|
102 |
|
103 | <span
|
104 | v-else
|
105 | v-gl-tooltip="{ disabled: isTooltipDisabled }"
|
106 | v-gl-resize-observer:[withTooltip]="checkTruncationState"
|
107 | class="gl-truncate"
|
108 | data-testid="truncate-end-container"
|
109 | :title="text"
|
110 | >
|
111 | <span ref="text" class="gl-truncate-end">{{ text }}</span>
|
112 | </span>
|
113 | </template>
|