Просмотр исходного кода

feature: consider full-width character length as 2 when calculate string length

twisger 7 лет назад
Родитель
Сommit
5baed891ed

+ 1 - 0
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<IEllipsisProps, any> {}

+ 1 - 0
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 | -

+ 42 - 4
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 <span {...other}>{text}</span>;
   }
   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}
         />
       );

+ 13 - 0
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');
+  });
+});

+ 1 - 0
src/components/Ellipsis/index.zh-CN.md

@@ -14,3 +14,4 @@ order: 10
 tooltip | 移动到文本展示完整内容的提示 | boolean | -
 length | 在按照长度截取下的文本最大字符数,超过则截取省略 | number | -
 lines | 在按照行数截取下最大的行数,超过则截取省略 | number | `1`
+caculateShowLength | 是否将全角字符的长度视为2来计算字符串长度 | boolean | -