From 5baed891ed4b4bdba53b83b7089baf2ed80722c8 Mon Sep 17 00:00:00 2001 From: twisger Date: Fri, 8 Jun 2018 17:36:54 +0800 Subject: [PATCH] feature: consider full-width character length as 2 when calculate string length --- src/components/Ellipsis/index.d.ts | 1 + src/components/Ellipsis/index.en-US.md | 1 + src/components/Ellipsis/index.js | 46 +++++++++++++++++++++++--- src/components/Ellipsis/index.test.js | 13 ++++++++ src/components/Ellipsis/index.zh-CN.md | 1 + 5 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 src/components/Ellipsis/index.test.js diff --git a/src/components/Ellipsis/index.d.ts b/src/components/Ellipsis/index.d.ts index 4643ee76..a7673c8d 100644 --- a/src/components/Ellipsis/index.d.ts +++ b/src/components/Ellipsis/index.d.ts @@ -5,6 +5,7 @@ export interface IEllipsisProps { lines?: number; style?: React.CSSProperties; className?: string; + caculateShowLength?: boolean; } export default class Ellipsis extends React.Component {} diff --git a/src/components/Ellipsis/index.en-US.md b/src/components/Ellipsis/index.en-US.md index fa5beb64..2f34cc3f 100644 --- a/src/components/Ellipsis/index.en-US.md +++ b/src/components/Ellipsis/index.en-US.md @@ -13,3 +13,4 @@ Property | Description | Type | Default tooltip | tooltip for showing the full text content when hovering over | boolean | - length | maximum number of characters in the text before being truncated | number | - lines | maximum number of rows in the text before being truncated | number | `1` +caculateShowLength | whether consider full-width character length as 2 when calculate string length | boolean | - diff --git a/src/components/Ellipsis/index.js b/src/components/Ellipsis/index.js index 671bc453..69439fad 100644 --- a/src/components/Ellipsis/index.js +++ b/src/components/Ellipsis/index.js @@ -8,11 +8,40 @@ import styles from './index.less'; const isSupportLineClamp = document.body.style.webkitLineClamp !== undefined; -const EllipsisText = ({ text, length, tooltip, ...other }) => { +export const getStrShowLength = (str = '') => { + return str.split('').reduce((pre, cur) => { + const charCode = cur.charCodeAt(0); + if (charCode >= 0 && charCode <= 128) { + return pre + 1; + } else { + return pre + 2; + } + }, 0); +}; + +export const cutStrByShowLength = (str = '', maxLength) => { + let showLength = 0; + return str.split('').reduce((pre, cur) => { + const charCode = cur.charCodeAt(0); + if (charCode >= 0 && charCode <= 128) { + showLength += 1; + } else { + showLength += 2; + } + if (showLength <= maxLength) { + return pre + cur; + } else { + return pre; + } + }, ''); +}; + +const EllipsisText = ({ text, length, tooltip, caculateShowLength, ...other }) => { if (typeof text !== 'string') { throw new Error('Ellipsis children must be string.'); } - if (text.length <= length || length < 0) { + const textLength = caculateShowLength ? getStrShowLength(text) : text.length; + if (textLength <= length || length < 0) { return {text}; } const tail = '...'; @@ -20,7 +49,7 @@ const EllipsisText = ({ text, length, tooltip, ...other }) => { if (length - tail.length <= 0) { displayText = ''; } else { - displayText = text.slice(0, length); + displayText = caculateShowLength ? cutStrByShowLength(text, length) : text.slice(0, length); } if (tooltip) { @@ -147,7 +176,15 @@ export default class Ellipsis extends Component { render() { const { text, targetCount } = this.state; - const { children, lines, length, className, tooltip, ...restProps } = this.props; + const { + children, + lines, + length, + className, + tooltip, + caculateShowLength, + ...restProps + } = this.props; const cls = classNames(styles.ellipsis, className, { [styles.lines]: lines && !isSupportLineClamp, @@ -170,6 +207,7 @@ export default class Ellipsis extends Component { length={length} text={children || ''} tooltip={tooltip} + caculateShowLength={caculateShowLength} {...restProps} /> ); diff --git a/src/components/Ellipsis/index.test.js b/src/components/Ellipsis/index.test.js new file mode 100644 index 00000000..18772f02 --- /dev/null +++ b/src/components/Ellipsis/index.test.js @@ -0,0 +1,13 @@ +import { getStrShowLength, cutStrByShowLength } from './index.js'; + +describe('test calculateShowLength', () => { + it('get show length', () => { + expect(getStrShowLength('一二,a,')).toEqual(8); + }); + it('cut str by show length', () => { + expect(cutStrByShowLength('一二,a,', 7)).toEqual('一二,a'); + }); + it('cut str when length small', () => { + expect(cutStrByShowLength('一22三', 5)).toEqual('一22'); + }); +}); diff --git a/src/components/Ellipsis/index.zh-CN.md b/src/components/Ellipsis/index.zh-CN.md index 8fe98bb0..20157878 100644 --- a/src/components/Ellipsis/index.zh-CN.md +++ b/src/components/Ellipsis/index.zh-CN.md @@ -14,3 +14,4 @@ order: 10 tooltip | 移动到文本展示完整内容的提示 | boolean | - length | 在按照长度截取下的文本最大字符数,超过则截取省略 | number | - lines | 在按照行数截取下最大的行数,超过则截取省略 | number | `1` +caculateShowLength | 是否将全角字符的长度视为2来计算字符串长度 | boolean | - -- GitLab