React只读列表

业务中会出现只读状态的表格,表格可以只有单纯的数字展示,也可以支持JSX元素的装入。和其他类型表格不一样,这种表格主要用于信息展示,没有什么业务上的交互。
分为两个部分,一部分是TSX文件的业务逻辑,一个是less的描述。

ReadOnlyTable.tsx文件

import * as React from 'react;
import {Memo,useState,useEffect} from 'react';
import './readOnlyTable.less';

interface ReadOnlyTableItems{
    key:string;
    value :string | number | JSX.Element;
    itemClassName ?:string;
}
interface ReadOnlyTableProps{
    data:ReadOnlyTableItems[][];
    className?:string;
    textFontSize?:number;
    defaultProps?:any;
    keyMaxNumber ?: number; // max number of title words
}

const textPadding = 0.4; // init text padding

const ReadOnlyTable:React.FC = (props:ReadOnlyTableProps) :JSX.Element | null =>{
    const [titleWidth,setTitleWidth] = useState(textPadding);
    useEffect(()=>{
        const textFontSize = props.textFontSize ? props.textFontSize : 0.16;
        setTitleWidth(getKeyMaxNumber(props.data) * textFontSize+textPadding);
    },[]);
    useEffect(()=>{
        setTitleWidth(getKeyMaxNumber(props.data)*0.16+textPadding);
    },[props.data]);
    
    const { data,className}= props;
    const getKeyMaxNumber(item:any[],maxNumber:number = 0):number =>{
        if(props.keyMaxNumber) {
            return props.keyMaxNumber;
        }
        let max = maxNumber;
        item.forEach(item=>{
            if(item.constructor === Array){
                max = getKeyMaxNumber(item,max);
            }else if(String(item.key.length > max){
                max = String(item.key).length;
            }
        });
        return max;
    }
    
    if(!Array.isArray(props.data) || props.data.length === 0 )  {
        return null;
    }
    
    return (
        
{data.map((v:ReadOnlyTableItems,i:number)=>
{v.map((val:ReadOnlyTableItems,index:number)=>
{val.key}
{val.value ? val.value : ''}
)}
)} ) } ReadOnlyTable.defaultProps = { textFontSize = 0.16; } export default Memo(ReadOnlyTable);

less文件描述

.read-only-table-container {
    background:#fff;
    width:100%;
    font-size:.16rem;
    border-right:.01rem solid #e1e3ec;
    .read-only-table-row{
        display:flex;
        background-clip:padding-box;
        &:last-of-type{
            .read-only-table-key{
                border-bottom:.01rem solid #e1e3ec;
             }
             .read-only-table-value{
                border-bottom:.01rem solid #e1e3ec;
             }
        }
        .read-only-table-items{
            display:flex;
            overflow:hidden;
            white-space:nowrap;
            text-overflow:ellipsis;
            &.defaultClassName{
                flex:1;
            }
            .read-only-table-key{
                line-height:.5rem;
                text-align:right;
                border-right:.01rem solid #e1e3ec;
                padding:.2rem;
                width:1.5rem;
                color:#666666;
                background:#fafafc;
                background-clip:padding-box;
                border-top:.01rem solid #e1e3ec;
                border-left:.01rem solid #e1e3ec;
            }
            .read-only-table-value{
                line-height:.5rem;
                flex:1;
                padding: 0 0.2rem;
                white-space:nowrap;
                color:#333333;
                overflow:hidden;
                text-overflow:ellipsis;
                border-top:.01rem solid #e1e3ec;
            }
        }
    }
}

传入数据格式如下:

    const data =[
        [{key:'一行一列',value:data}],
        [{key:'一行两列',value:data},{key:'一行两列',value:data}],
        [{key:'一行一列',value:data,itemClassName:'custom-style',style:{height:'1.5rem'}}],
        [{key:'jsx element',value:{JSX.Element}}]
    ]
    

你可能感兴趣的:(javascript,typescript,react.js,hook)