import List from '@mui/material/List' ; import ListItem from '@mui/material/ListItem' ; import { styled } from '@mui/material' ; import Typography from '@mui/material/Typography' ; import clsx from 'clsx' ; import React from 'react' ; type DataValueTypePrimitive = number | string ; type DataValueTypeArray = DataValueTypePrimitive [ ] ; type DataValueType = DataValueTypePrimitive | DataValueTypeArray ; param name param value param className param className . value param className . overrideValue param className . overrideArrayItemValue param disabled param wrap export interface SimpleInfoData < T extends DataValueType = DataValueType > { name : string ; value : T ; className ? : { value ? : T extends DataValueTypeArray ? string | string [ ] : string ; overrideValue ? : string ; overrideArrayItemValue ? : string ; } ; disabled ? : boolean ; wrap ? : boolean ; } const classes = { container : 'simpleinfo-container' , tableRow : 'simpleinfo-table-row' , displayName : 'simpleinfo-display-name' , value : 'simpleinfo-value' , arrayListItem : 'simpleinfo-array-list-item' , arrayItemValue : 'simpleinfo-array-item-value' , disabled : 'simpleinfo-disabled' , } ; const StyledDiv = styled ( 'div' ) ( ( { theme } ) => ( { [ `& .${ classes . container }` ] : { display : 'table' , borderCollapse : 'collapse' , width : '100%' , overflowX : 'auto' , } , [ `& .${ classes . tableRow }` ] : { display : 'table-row' , } , [ `& .${ classes . displayName }` ] : { display : 'table-cell' , borderBottom : '1px solid' , borderBottomColor : theme . palette . divider , borderTop : '1px solid' , borderTopColor : theme . palette . divider , background : theme . palette . action . hover , padding : theme . spacing ( 0.25 , 2 ) , width : '30%' , } , [ `& .${ classes . value }` ] : { display : 'table-cell' , textAlign : 'end' , borderBottom : '1px solid' , borderBottomColor : theme . palette . divider , borderTop : '1px solid' , borderTopColor : theme . palette . divider , padding : theme . spacing ( 0.25 , 2 ) , } , [ `& .${ classes . arrayListItem }` ] : { justifyContent : 'flex-end' , } , [ `& .${ classes . arrayItemValue }` ] : { textAlign : 'end' , } , [ `& .${ classes . disabled }` ] : { color : theme . palette . action . disabled , } , } ) ) ; export interface SimpleInfoProps extends React . DetailedHTMLProps < React . HTMLAttributes < HTMLDivElement > , HTMLDivElement > { infoData : SimpleInfoData [ ] ; overrideStyle ? : { container ? : string ; tableRow ? : string ; } ; } export const SimpleInfo = ( props ) : JSX . Element => { const { infoData , overrideStyle , ... otherProps } = props ; const renderPrimitive = ( { name , value , className , disabled , wrap , } ) => ( < > < Typography className = { classes . displayName } variant = "body1" role = "rowheader" > { name } < /Typography> < Typography noWrap = { ! wrap } variant = "body1" className = { clsx ( className ?. overrideValue ? className ?. overrideValue : classes . value , disabled ? classes . disabled : undefined , className ?. value ) } role = "cell" > { value } < /Typography> < />); const renderArray = ( { name , value , className , disabled , } ) => { const arrayItemValueStyle = className ?. overrideArrayItemValue ? className ?. overrideArrayItemValue : classes . arrayItemValue ; const valueStyle = className ?. overrideValue ? className ?. overrideValue : classes . value ; return ( < > < Typography className = { classes . displayName } variant = "body1" role = "rowheader" > { name } < /Typography> < List className = { valueStyle } dense role = "cell" > { value . map ( ( item , i ) => ( < ListItem key = { i } className = { classes . arrayListItem } > < Typography variant = "body1" className = { clsx ( arrayItemValueStyle , disabled ? classes . disabled : undefined , Array . isArray ( className ?. value ) ? className ?. value [ i ] : className ?. value ) } > { item } < /Typography> < /ListItem>))} < /List> < />); } ; const renderLine = ( data ) => { switch ( typeof data . value ) { case 'object' : if ( Array . isArray ( data . value ) ) { return renderArray ( data as SimpleInfoData < DataValueTypeArray > ) ; } else { throw Error ( 'nested object is not supported' ) ; } break ; case 'function' : case 'symbol' : break ; default : return renderPrimitive ( data as SimpleInfoData < DataValueTypePrimitive > ) ; } } ; return ( < StyledDiv { ... otherProps } > < div className = { overrideStyle ?. container ? overrideStyle ?. container : classes . container } role = "table" > { infoData . map ( ( item ) => ( < React . Fragment key = { item . name } > < div className = { overrideStyle ?. tableRow ? overrideStyle ?. tableRow : classes . tableRow } role = "row" aria - label = { item . name } > { renderLine ( item ) } < /div> < /React.Fragment>))} < /div> < /StyledDiv>); } ; export default SimpleInfoProps ;