Prechádzať zdrojové kódy

fix: [Descriptions] Children are not read directly in foundation, but adapter get is used to adapt to other frameworks. Adjust the calculation of horizontal colspan value to automatically complete the remaining part(#2121)

* fix: [Descriptions] Friendly to other frameworks such as vue
* fix: [Descriptions] When the layout is horizontal, the td automatically fills the remaining space

---------

Co-authored-by: kousum <[email protected]>
Co-authored-by: pointhalo <[email protected]>
rashagu 1 rok pred
rodič
commit
e5d53e0280

+ 17 - 12
packages/semi-foundation/descriptions/foundation.ts

@@ -1,6 +1,8 @@
 import BaseFoundation, { DefaultAdapter } from '../base/foundation';
 
-export interface DescriptionsAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {}
+export interface DescriptionsAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
+    getColumns: () => any[]
+}
 
 export default class DescriptionsFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<DescriptionsAdapter<P, S>, P, S> {
     constructor(adapter: DescriptionsAdapter<P, S>) {
@@ -9,16 +11,7 @@ export default class DescriptionsFoundation<P = Record<string, any>, S = Record<
 
     getHorizontalList() {
         const { column, data, children } = this.getProps();
-        let columns;
-        if (data?.length) {
-            columns = data || [];
-        } else {
-            columns =
-                children?.map(item => ({
-                    value: item.props.children,
-                    ...item.props,
-                })) || [];
-        }
+        const columns = this._adapter.getColumns();
         const horizontalList = [];
         const curSpan = { totalSpan: 0, itemList: [] };
         for (const item of columns) {
@@ -30,7 +23,19 @@ export default class DescriptionsFoundation<P = Record<string, any>, S = Record<
                 curSpan.totalSpan = 0;
             }
         }
-        if (curSpan.itemList.length != 0) horizontalList.push(curSpan.itemList);
+        if (curSpan.itemList.length != 0) {
+            const lastSpan = curSpan.itemList[curSpan.itemList.length - 1];
+            if (isNaN(lastSpan.span)) {
+                let total = 0;
+                curSpan.itemList.forEach(item=>{
+                    return total += !isNaN(item.span)?item.span:1;
+                });
+                if (total < column) {
+                    lastSpan.span = column - total + 1;
+                }
+            }
+            horizontalList.push(curSpan.itemList);
+        }
         return horizontalList;
     }
 }

+ 8 - 2
packages/semi-ui/descriptions/__test__/descriptions.test.js

@@ -194,7 +194,7 @@ describe('Descriptions', () => {
 
     it('Descriptions layout horizontal', () => {
         const desc = mount(
-            <Descriptions layout='horizontal' align='left'>
+            <Descriptions layout='horizontal' align='left' column={4}>
                 <Descriptions.Item itemKey={<strong style={{ color: 'red' }}>实际用户数量</strong>}>1,480,000</Descriptions.Item>
                 <Descriptions.Item itemKey="7天留存">98%</Descriptions.Item>
                 <Descriptions.Item itemKey="认证状态">未认证</Descriptions.Item>
@@ -222,6 +222,12 @@ describe('Descriptions', () => {
                 .getDOMNode()
                 .textContent
         ).toEqual('1,480,000');
+
+        let totalSpan = ths.length
+        tds.forEach(item=>{
+            totalSpan += +item.getAttribute('colspan')
+        })
+        expect(totalSpan).toEqual(8);
         desc.unmount();
     });
-})
+})

+ 19 - 3
packages/semi-ui/descriptions/index.tsx

@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { isValidElement } from 'react';
 import cls from 'classnames';
 import PropTypes from 'prop-types';
 import { strings, cssClasses } from '@douyinfe/semi-foundation/descriptions/constants';
@@ -72,7 +72,23 @@ class Descriptions extends BaseComponent<DescriptionsProps> {
     }
 
     get adapter(): DescriptionsAdapter<DescriptionsProps> {
-        return { ...super.adapter };
+        return {
+            ...super.adapter,
+            getColumns: ()=>{
+                if (this.props.data?.length) {
+                    return this.props.data;
+                }
+                if (this.props.children) {
+                    return React.Children.toArray(this.props.children)?.map(item => {
+                        return isValidElement(item)?({
+                            value: item.props.children,
+                            ...item.props,
+                        }):[];
+                    });
+                }
+                return [];
+            }
+        };
     }
 
     renderChildrenList = () => {
@@ -119,4 +135,4 @@ class Descriptions extends BaseComponent<DescriptionsProps> {
     }
 }
 
-export default Descriptions;
+export default Descriptions;

+ 1 - 1
packages/semi-ui/descriptions/item.tsx

@@ -50,7 +50,7 @@ export default class Item extends PureComponent<DescriptionsItemProps> {
                     {itemKey}
                 </span>
             </th>
-            <td className={`${prefixCls}-item ${prefixCls}-item-td`} colSpan={span || 1}>
+            <td className={`${prefixCls}-item ${prefixCls}-item-td`} colSpan={span? ((span * 2) - 1) : 1}>
                 <span className={valCls}>
                     {typeof children === 'function' ? children() : children}
                 </span>