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
6 changed files with 75 additions and 44 deletions

View File

@ -25,7 +25,7 @@ text/sizes
## Ellipsis ## 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 text/truncated
@ -52,10 +52,11 @@ text/mixed
### Attributes ### Attributes
| Name | Description | Type | Default | | Name | Description | Type | Default |
| --------- | ------------------ | ------------------------------------------------------------------ | ------- | | ------------------- | ------------------ | ------------------------------------------------------------------ | ------- |
| type | text type | ^[enum]`'primary' \| 'success' \| 'warning' \| 'danger' \| 'info'` | — | | type | text type | ^[enum]`'primary' \| 'success' \| 'warning' \| 'danger' \| 'info'` | — |
| size | text size | ^[enum]`'large' \| 'default' \| 'small'` | default | | size | text size | ^[enum]`'large' \| 'default' \| 'small'` | default |
| truncated | render ellipsis | ^[boolean] | false | | truncated | render ellipsis | ^[boolean] | false |
| line-clamp ^(2.4.0) | maximum lines | ^[string] / ^[number] | - |
| tag | custom element tag | ^[string] | span | | tag | custom element tag | ^[string] | span |
### Slots ### Slots

View File

@ -1,8 +1,13 @@
<template> <template>
<el-text class="w-100px" truncated>Self element set width 100px</el-text> <el-text class="w-150px mb-2" truncated>
<el-row> Self element set width 100px
<el-col :span="4"> </el-text>
<el-row class="w-150px mb-2">
<el-text truncated>Squeezed by parent element</el-text> <el-text truncated>Squeezed by parent element</el-text>
</el-col>
</el-row> </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> </template>

View File

@ -5,7 +5,43 @@ import Text from '../src/text.vue'
const AXIOM = 'Rem is the best girl' const AXIOM = 'Rem is the best girl'
describe('Text.vue', () => { 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(() => ( const wrapper = mount(() => (
<Text <Text
v-slots={{ 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) 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 { buildProps } from '@element-plus/utils'
import { componentSizes } from '@element-plus/constants' import { componentSizes } from '@element-plus/constants'
import type Text from './text.vue'
import type { ExtractPropTypes } from 'vue' import type { ExtractPropTypes } from 'vue'
@ -27,6 +26,12 @@ export const textProps = buildProps({
truncated: { truncated: {
type: Boolean, type: Boolean,
}, },
/**
* @description maximum lines
*/
lineClamp: {
type: [String, Number],
},
/** /**
* @description custom element tag * @description custom element tag
*/ */
@ -35,5 +40,5 @@ export const textProps = buildProps({
default: 'span', default: 'span',
}, },
} as const) } as const)
export type TextProps = ExtractPropTypes<typeof textProps> export type TextProps = ExtractPropTypes<typeof textProps>
export type TextInstance = InstanceType<typeof Text>

View File

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

View File

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