fix(components): [text] not support multi-line ellipsis (#11976)

* docs(components): [text] line-clamp prop and update example

* test(components): [text] line-clamp test

* fix(components): [text] not support multi-line ellipsis

* docs: updata

---------

Co-authored-by: qiang <qw13131wang@gmail.com>
This commit is contained in:
gimjin 2023-10-13 11:26:54 +08:00 committed by GitHub
parent cba217228f
commit 4b5a9bf279
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 75 additions and 44 deletions

View File

@ -25,7 +25,7 @@ text/sizes
## Ellipsis
:::demo Pass the `truncated` prop to render an ellipsis when the text exceeds the width of the viewport or max-width set.
:::demo Pass the `truncated` prop to render an ellipsis when the text exceeds the width of the viewport or max-width set. `line-clamp` prop to render multiline ellipsis.
text/truncated
@ -51,12 +51,13 @@ text/mixed
### Attributes
| Name | Description | Type | Default |
| --------- | ------------------ | ------------------------------------------------------------------ | ------- |
| type | text type | ^[enum]`'primary' \| 'success' \| 'warning' \| 'danger' \| 'info'` | — |
| size | text size | ^[enum]`'large' \| 'default' \| 'small'` | default |
| truncated | render ellipsis | ^[boolean] | false |
| tag | custom element tag | ^[string] | span |
| Name | Description | Type | Default |
| ------------------- | ------------------ | ------------------------------------------------------------------ | ------- |
| type | text type | ^[enum]`'primary' \| 'success' \| 'warning' \| 'danger' \| 'info'` | — |
| size | text size | ^[enum]`'large' \| 'default' \| 'small'` | default |
| truncated | render ellipsis | ^[boolean] | false |
| line-clamp ^(2.4.0) | maximum lines | ^[string] / ^[number] | - |
| tag | custom element tag | ^[string] | span |
### Slots

View File

@ -1,8 +1,13 @@
<template>
<el-text class="w-100px" truncated>Self element set width 100px</el-text>
<el-row>
<el-col :span="4">
<el-text truncated>Squeezed by parent element</el-text>
</el-col>
<el-text class="w-150px mb-2" truncated>
Self element set width 100px
</el-text>
<el-row class="w-150px mb-2">
<el-text truncated>Squeezed by parent element</el-text>
</el-row>
<el-text line-clamp="2">
The -webkit-line-clamp CSS property<br />
allows limiting of the contents of<br />
a block to the specified number of lines.
</el-text>
</template>

View File

@ -5,7 +5,43 @@ import Text from '../src/text.vue'
const AXIOM = 'Rem is the best girl'
describe('Text.vue', () => {
test('render text & class', () => {
test('create', () => {
const wrapper = mount(() => <Text />)
expect(wrapper.classes()).toContain('el-text')
})
test('type', () => {
const wrapper = mount(() => <Text type="success" />)
expect(wrapper.classes()).toContain('el-text--success')
})
test('size', () => {
const wrapper = mount(() => <Text size="large" />)
expect(wrapper.classes()).toContain('el-text--large')
})
test('truncated', () => {
const wrapper = mount(() => <Text truncated />)
expect(wrapper.classes()).toContain('is-truncated')
})
test('line-clamp', () => {
const wrapper = mount(() => <Text line-clamp="2" />)
expect(wrapper.classes()).toContain('is-line-clamp')
})
test('tag', () => {
const wrapper = mount(() => <Text tag="del" />)
expect(wrapper.vm.$el.tagName).toEqual('DEL')
})
test('default slot', () => {
const wrapper = mount(() => (
<Text
v-slots={{
@ -13,35 +49,7 @@ describe('Text.vue', () => {
}}
/>
))
const vm = wrapper.vm
expect(vm.$el.classList.contains('el-text')).toEqual(true)
expect(wrapper.text()).toEqual(AXIOM)
})
test('type', () => {
const wrapper = mount(() => <Text type="success" />)
const vm = wrapper.vm
expect(vm.$el.classList.contains('el-text--success')).toEqual(true)
})
test('size', () => {
const wrapper = mount(() => <Text size="large" />)
const vm = wrapper.vm
expect(vm.$el.className.includes('el-text--large')).toEqual(true)
expect(vm.$el.className.includes('el-text--default')).toEqual(false)
expect(vm.$el.className.includes('el-text--small')).toEqual(false)
})
test('truncated', () => {
const wrapper = mount(() => <Text truncated />)
const vm = wrapper.vm
expect(vm.$el.className.includes('is-truncated')).toEqual(true)
})
test('tag', () => {
const wrapper = mount(() => <Text tag="del" />)
const vm = wrapper.vm
expect(vm.$el.tagName).toEqual('DEL')
})
})

View File

@ -1,6 +1,5 @@
import { buildProps } from '@element-plus/utils'
import { componentSizes } from '@element-plus/constants'
import type Text from './text.vue'
import type { ExtractPropTypes } from 'vue'
@ -27,6 +26,12 @@ export const textProps = buildProps({
truncated: {
type: Boolean,
},
/**
* @description maximum lines
*/
lineClamp: {
type: [String, Number],
},
/**
* @description custom element tag
*/
@ -35,5 +40,5 @@ export const textProps = buildProps({
default: 'span',
},
} as const)
export type TextProps = ExtractPropTypes<typeof textProps>
export type TextInstance = InstanceType<typeof Text>

View File

@ -1,5 +1,9 @@
<template>
<component :is="tag" :class="textKls">
<component
:is="tag"
:class="textKls"
:style="{ '-webkit-line-clamp': lineClamp }"
>
<slot />
</component>
</template>
@ -8,6 +12,7 @@
import { computed } from 'vue'
import { useNamespace } from '@element-plus/hooks'
import { useFormSize } from '@element-plus/components/form'
import { isUndefined } from '@element-plus/utils'
import { textProps } from './text'
defineOptions({
@ -24,5 +29,6 @@ const textKls = computed(() => [
ns.m(props.type),
ns.m(textSize.value),
ns.is('truncated', props.truncated),
ns.is('line-clamp', !isUndefined(props.lineClamp)),
])
</script>

View File

@ -24,6 +24,12 @@
overflow: hidden;
}
@include when(line-clamp) {
display: -webkit-inline-box;
-webkit-box-orient: vertical;
overflow: hidden;
}
@each $size in (large, default, small) {
@include m($size) {
@include set-css-var-value(