Browse Source

Merge pull request #2089 from DouyinFE/fix/typo-1731

fix: Fix Typo single-line css omission accuracy issue #1731
代强 1 year ago
parent
commit
edc8771db1

+ 9 - 0
cypress/e2e/typography.spec.js

@@ -115,4 +115,13 @@ describe('typography', () => {
     //     cy.get('.testPopoverCls.semi-typography-ellipsis-popover').should('exist');
     // });
 
+    // work in local, fail in online,  ignore
+    // it('single row css ellipsis accurate', () => {
+    //     cy.viewport(800, 1000);
+    //     cy.visit('http://127.0.0.1:6006/iframe.html?id=typography--single-row-css-ellipsis-accurate&args=&viewMode=story');
+    //     cy.get('.semi-typography').trigger('mouseover');
+    //     cy.wait(2000);
+    //     cy.get('.semi-tooltip-content').contains('Latin America-巴西-圣保罗');
+    // });
+
 });

+ 19 - 2
packages/semi-ui/typography/_story/typography.stories.jsx

@@ -1,4 +1,4 @@
-import React, { useCallback } from 'react';
+import React, { useCallback, useEffect, useRef } from 'react';
 import withPropsCombinations from 'react-storybook-addon-props-combinations';
 
 import Icon from '../../icons';
@@ -880,4 +880,21 @@ export const GlobalEllipsisPopoverCls = () => (
   >
     测试 showTooltip 中的 type 为 popover 时,传入的类名称正确
   </Title>
-)
+)
+
+export const SingleRowCssEllipsisAccurate = () => {
+  const { Text } = Typography;
+  return (
+    <div>
+      <p>文本截断,hover 展示 tooltip 正常</p>
+      <Text
+        style={{ width: 171 }}
+        ellipsis={{
+          showTooltip: true,
+        }}
+      >
+        Latin America-巴西-圣保罗
+      </Text>
+    </div>
+  );
+}

+ 24 - 1
packages/semi-ui/typography/base.tsx

@@ -263,11 +263,34 @@ export default class Base extends Component<BaseTypographyProps, BaseTypographyS
         }
         const updateOverflow =
             rows <= 1 ?
-                this.wrapperRef.current.scrollWidth > this.wrapperRef.current.offsetWidth :
+                this.compareSingleRow() :
                 this.wrapperRef.current.scrollHeight > this.wrapperRef.current.offsetHeight;
         return updateOverflow;
     };
 
+    /**
+     * 通过将 content 给到 Range 对象,借助 Range 的 getBoundingClientRect 拿到 content 的准确 width
+     * 不受 css ellipsis 与否的影响
+     * By giving the content to the Range object, get the exact width of the content with the help of Range's getBoundingClientRect
+     * Not affected by css ellipsis or not
+     * https://github.com/DouyinFE/semi-design/issues/1731
+     */
+    compareSingleRow = () => {
+        if (!(document && document.createRange)) {
+            return false;
+        }
+        const containerNode = this.wrapperRef.current;
+        const containerWidth = containerNode.getBoundingClientRect().width;
+        const childNodes = Array.from(containerNode.childNodes) as Node[];
+        const range = document.createRange();
+        const contentWidth = childNodes.reduce((acc: number, node: Node) => {
+            range.selectNodeContents(node as Node);
+            return acc + (range.getBoundingClientRect().width ?? 0);
+        }, 0);
+        range.detach();
+        return contentWidth > containerWidth;
+    }
+
     showTooltip = () => {
         const { isOverflowed, isTruncated, expanded } = this.state;
         const { showTooltip, expandable, expandText } = this.getEllipsisOpt();