Commit b6570f15 authored by nikogu's avatar nikogu

use -webkit-line-clamp & remove cover mode

parent d04c138e
---
order: 2
title: 按照行数省略的覆盖后缀模式
---
通过设置 `lines` 属性指定最大行数,如果超过这个行数的文本会自动截取。通过设置 `cover` 属性设置后缀的覆盖模式,在这种模式下可以在 `children` 中使用 `ReactNode`
但是因为是覆盖形式的后缀,可能需要通过 `suffixOffset` 以及 `suffixColor` 来设置 `...` 的样式以修正。
````jsx
import Ellipsis from 'ant-design-pro/lib/Ellipsis';
const article = <p>There were injuries alleged in three <a href="#cover">cases in 2015</a>, and a fourth incident in September, according to the safety recall report. After meeting with US regulators in October, the firm decided to issue a voluntary recall.</p>;
ReactDOM.render(
<div style={{ width: 200 }}>
<Ellipsis lines={3} cover>{article}</Ellipsis>
<h4 style={{ marginTop: 24 }}>Using SuffixOffset</h4>
<Ellipsis lines={3} cover suffixOffset={4}>{article}</Ellipsis>
</div>
, mountNode);
````
......@@ -14,7 +14,7 @@ const article = <p>There were injuries alleged in three <a href="#cover">cases i
ReactDOM.render(
<div style={{ width: 200 }}>
<Ellipsis lines={3}>{article}</Ellipsis>
<Ellipsis tooltip lines={3}>{article}</Ellipsis>
</div>
, mountNode);
````
......@@ -6,6 +6,8 @@ import styles from './index.less';
/* eslint react/no-did-mount-set-state: 0 */
/* eslint no-param-reassign: 0 */
const isSupportLineClamp = (document.body.style.webkitLineClamp !== undefined);
const EllipsisText = ({ text, length, tooltip, ...other }) => {
if (typeof text !== 'string') {
throw new Error('Ellipsis children must be string.');
......@@ -22,7 +24,7 @@ const EllipsisText = ({ text, length, tooltip, ...other }) => {
}
if (tooltip) {
return <span>{displayText}<Tooltip title={text}>{tail}</Tooltip></span>;
return <Tooltip title={text}><span>{displayText}{tail}</span></Tooltip>;
}
return (
......@@ -34,35 +36,25 @@ const EllipsisText = ({ text, length, tooltip, ...other }) => {
export default class Ellipsis extends Component {
state = {
lineHeight: 0,
text: '',
targetCount: 0,
}
componentDidMount() {
const { lines, cover } = this.props;
if (this.node) {
if (lines && cover) {
this.setState({
lineHeight: parseInt(window.getComputedStyle(this.node).lineHeight, 10),
});
}
this.computeLine();
}
}
componentWillReceiveProps(nextProps) {
if (this.props.lines !== nextProps.lines || this.props.cover !== nextProps.cover) {
this.setState({
lineHeight: parseInt(window.getComputedStyle(this.node).lineHeight, 10),
});
if (this.props.lines !== nextProps.lines) {
this.computeLine();
}
}
computeLine = () => {
const { lines, cover } = this.props;
if (lines && !cover) {
const { lines } = this.props;
if (lines && !isSupportLineClamp) {
const fontSize = parseInt(window.getComputedStyle(this.node).fontSize, 10) || 14;
const text = this.shadowChildren.innerText;
const targetWidth = (this.node.offsetWidth || this.node.parentNode.offsetWidth) * lines;
......@@ -128,22 +120,20 @@ export default class Ellipsis extends Component {
}
render() {
const { text, targetCount, lineHeight } = this.state;
const { text, targetCount } = this.state;
const {
children,
lines,
length,
cover = false,
suffixColor = '#fff',
suffixOffset = 0,
className,
tooltip,
...restProps
} = this.props;
const cls = classNames(styles.ellipsis, className, {
[styles.lines]: (lines && !cover),
[styles.linesCover]: (lines && cover),
[styles.lines]: (lines && !isSupportLineClamp),
[styles.lineClamp]: (lines && isSupportLineClamp),
});
if (!lines && !length) {
......@@ -155,29 +145,30 @@ export default class Ellipsis extends Component {
return (<EllipsisText className={cls} length={length} text={children || ''} tooltip={tooltip} {...restProps} />);
}
// lines cover
if (cover) {
const id = `antd-pro-ellipsis-${`${new Date().getTime()}${Math.floor(Math.random() * 100)}`}`;
const style = `#${id}:before{background-color:${suffixColor};padding-left:${suffixOffset}px;}`;
// support document.body.style.webkitLineClamp
if (isSupportLineClamp) {
const style = `#${id}{-webkit-line-clamp:${lines};}`;
return (
<div
{...restProps}
id={id}
ref={this.handleRef}
className={cls}
style={{
...restProps.style,
maxHeight: `${lines * lineHeight}px`,
}}
>
<div id={id} className={cls} {...restProps}>
<style>{style}</style>
{children}
</div>
);
{
tooltip ? (<Tooltip title={text}>{children}</Tooltip>) : children
}
</div>);
}
// lines no cover
const suffix = tooltip ? <Tooltip title={text}>...</Tooltip> : '...';
const childNode = (
<span>
{
(targetCount > 0) && text.substring(0, targetCount)
}
{
(targetCount > 0) && (targetCount < text.length) && '...'
}
</span>
);
return (
<div
......@@ -186,10 +177,9 @@ export default class Ellipsis extends Component {
className={cls}
>
{
(targetCount > 0) && text.substring(0, targetCount)
}
{
(targetCount > 0) && (targetCount < text.length) && suffix
tooltip ? (
<Tooltip title={text}>{childNode}</Tooltip>
) : childNode
}
<div className={styles.shadow} ref={this.handleShadowChildren}>{children}</div>
<div className={styles.shadow} ref={this.handleShadow}><span>{text}</span></div>
......
.textOverflowMulti(@line: 3, @bg: #fff) {
overflow: hidden;
position: relative;
line-height: 1.5em;
max-height: @line * 1.5em;
text-align: justify;
margin-right: -1em;
padding-right: 1em;
&:before {
background: @bg;
box-shadow: 2px 0 2px 1px rgba(255, 255, 255, 0.2);
content: '...';
padding-left: 0;
position: absolute;
right: 14px;
bottom: 0;
}
&:after {
background: white;
content: '';
margin-top: 0.2em;
position: absolute;
right: 14px;
width: 1em;
height: 1em;
}
}
.ellipsis {
display: inline-block;
word-break: break-all;
......@@ -45,7 +17,10 @@
}
}
.linesCover {
.textOverflowMulti();
display: block;
.lineClamp {
position: relative;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
}
......@@ -13,9 +13,6 @@ order: 10
参数 | 说明 | 类型 | 默认值
----|------|-----|------
tooltip | 移动到 `...` 展示完整内容的提示,在长度截取和覆盖模式的行数截取下可用 | boolean | -
tooltip | 移动到文本展示完整内容的提示 | boolean | -
length | 在按照长度截取下的文本最大字符数,超过则截取省略 | number | -
lines | 在按照行数截取下最大的行数,超过则截取省略 | number | `1`
cover | 在按照行数截取下开启覆盖模式,这种模式 `...` 是使用样式覆盖到文本上的,所以文本内容可以是 `ReactNode` | boolean | false
suffixColor | 在覆盖模式下后缀符号 `...` 的背景颜色 | string | `#fff`
suffixOffset | 在覆盖下后缀符号 `...` 位置偏移量,用于更精细的调整截取位置 | number | `0`
......@@ -68,7 +68,7 @@ export default class CardList extends PureComponent {
avatar={<img alt="" className={styles.cardAvatar} src={item.avatar} />}
title={<a href="#">{item.title}</a>}
description={(
<Ellipsis lines={3} cover suffixOffset={2}>{item.description}</Ellipsis>
<Ellipsis className={styles.item} lines={3}>{item.description}</Ellipsis>
)}
/>
</Card>
......
......@@ -22,6 +22,9 @@
}
}
}
.item {
height: 64px;
}
}
.extraImg {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment