javascriptreactjsmaterial-uitablerowtablecell

How to apply style of TableRow similar to TableHead in material-ui / mui?


Currently I'm trying to apply the styling of TableHead to TableRow as well but I'm getting Warning: validateDOMNesting(...): cannot appear as a child of . how to fix this without warning message.

CollapisbleTableRow.js

import React, { Fragment, useCallback } from 'react'
import { makeStyles, IconButton, Checkbox, Collapse, TableCell, TableHead, TableRow } from '@mui/material'
import DeleteIcon from '@mui/icons-material/Delete'
import FileCopyIcon from '@mui/icons-material/FileCopy'
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'
import isEmpty from 'lodash/fp/isEmpty'
import ValidatedFramework from '../validated-framework'
import { formatError } from '../../tiles/client-search/utils'


const useRowStyles = makeStyles({
    root: {
        '& > *': {
            borderBottom: 'unset',
        },
    },
})

export default function CollapsibleTableRow({
    row,
    rowIndex,
    rowHeader,
    rowForm,
    onChangeRow,
    handleChange,
    onAddRow,
    onRemoveRow,
    onCollapseRow,
}) {
    const classes = useRowStyles()
    const handleColumnChange = useCallback(event => {
        const name = event.currentTarget.name || event.target.name
        const value = event.currentTarget.value || event.target.value
        if (name === 'urgent') {
            handleChange(value)
        } else if (name === 'addRow') {
            onAddRow(value)
        } else if (name === 'removeRow') {
            onRemoveRow(value)
        } else {
            onCollapseRow(value)
        }
    })

    return (
        <Fragment key={rowIndex}>
            <TableRow className={classes.root} key={rowIndex}>
                <TableCell style={{ width: '30px' }}>
                    <IconButton
                        size='small'
                        name={'arrow'}
                        value={rowIndex}
                        onClick={handleColumnChange}
                    >
                        {row.isCollapsed ? (
                            <KeyboardArrowDownIcon style={{ fontSize: '1.5rem', transform: 'scale(1.5)' }} />
                        ) : (
                            <KeyboardArrowRightIcon style={{ fontSize: '1.5rem', transform: 'scale(1.5)' }} />
                        )}
                    </IconButton>
                </TableCell>
                <TableCell style={{
                    color: 'green',
                    width: '30px'
                }}>
                    <div
                        style={{
                            alignItems: 'center',
                            display: 'flex',
                            height: '2em'
                        }}
                    >
                        {!isEmpty(row.validationErrors) && <ValidatedFramework value={formatError(row.validationErrors)}/>}
                        {isEmpty(row.validationErrors) && row.status === 'SUCCESS' && <ValidatedFramework value={[ ]}/>}
                    </div>
                </TableCell>
                {rowHeader(row, rowIndex, onChangeRow)}
                <TableCell
                    style={{
                        marginBottom: `${row.isCollapsed ? 'none' : '1px solid lightgray'}`,
                        width: '30px'
                    }}
                >
                    <div
                        style={{
                            alignItems: 'center',
                            display: 'flex',
                            height: '2em'
                        }}
                    >
                        <IconButton size='small' onClick={handleColumnChange}>
                            <Checkbox
                                checked={row.urgentRequest}
                                name={'urgent'}
                                value={rowIndex}
                                color='primary'
                                size='medium'
                                disabled={row.status === 'SUCCESS'}
                                inputProps={{
                                    'aria-label': 'secondary checkbox',
                                }}
                            />
                        </IconButton>
                    </div>
                </TableCell>
                <TableCell
                    style={{
                        marginBottom: `${row.isCollapsed ? 'none' : '1px solid lightgray'}`,
                        width: '30px'
                    }}
                >
                    <div
                        style={{
                            alignItems: 'center',
                            display: 'flex',
                            height: '2em'
                        }}
                    >
                        <IconButton
                            size='small'
                            name={'addRow'}
                            value={rowIndex}
                            onClick={handleColumnChange}
                        >
                            <FileCopyIcon style={{ fontSize: '1.1rem', transform: 'scale(1.1)' }}/>
                        </IconButton>
                        <IconButton
                            size='small'
                            name={'removeRow'}
                            value={rowIndex}
                            onClick={handleColumnChange}
                        >
                            <DeleteIcon style={{ fontSize: '1.2rem', transform: 'scale(1.2)' }}/>
                        </IconButton>
                    </div>
                </TableCell>
            </TableRow>
            <TableRow> // this is the main place I want to change styling 
                <TableCell
                    style={{ padding: 0 }}
                    colSpan={12}
                >
                    <Collapse
                        in={row.isCollapsed}
                        timeout='auto'
                        unmountOnExit
                    >
                        <TableHead style={{display: 'flex'}}>
                            <TableCell style={{flex: '1'}}>{rowForm(row, rowIndex, onChangeRow)}</TableCell>
                        </TableHead>
                    </Collapse>
                </TableCell>
            </TableRow>
        </Fragment>
    )
}

Solution

  • Finally I realized that Instead of using TableHead inside TableRow I have stlied the TableRow and TableCell in the following way and used it in component.

    import React, { Fragment, useCallback } from 'react'
    import { makeStyles, Checkbox, Collapse, IconButton } from '@mui/material'
    import TableCell, { tableCellClasses } from '@mui/material/TableCell'
    import { styled } from '@mui/material/styles'
    import TableRow from '@mui/material/TableRow'
    import DeleteIcon from '@mui/icons-material/Delete'
    import FileCopyIcon from '@mui/icons-material/FileCopy'
    import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'
    import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'
    import isEmpty from 'lodash/fp/isEmpty'
    import ValidatedFramework from '../validated-framework'
    import { formatError } from '../../tiles/client-search/utils'
    
    
    const useRowStyles = makeStyles({
        root: {
            '& > *': {
                borderBottom: 'unset',
            },
        },
    })
    
    const StyledTableCell = styled(TableCell)(({ theme }) => ({
        [`&.${tableCellClasses.head}`]: {
            backgroundColor: theme.palette.common.black,
            color: theme.palette.common.white,
        },
        [`&.${tableCellClasses.body}`]: {
            fontSize: 14,
        },
    }))
    
    const StyledTableRow = styled(TableRow)(({ theme }) => ({
        '&:nth-of-type(even)': {
            backgroundColor: theme.palette.action.hover,
        },
    }))
    
    export default function CollapsibleTableRow({
        row,
        rowIndex,
        rowHeader,
        rowForm,
        onChangeRow,
        handleChange,
        onAddRow,
        onRemoveRow,
        onCollapseRow,
    }) {
        const classes = useRowStyles()
        const handleColumnChange = useCallback(event => {
            const name = event.currentTarget.name || event.target.name
            const value = event.currentTarget.value || event.target.value
            if (name === 'urgent') {
                handleChange(value)
            } else if (name === 'addRow') {
                onAddRow(value)
            } else if (name === 'removeRow') {
                onRemoveRow(value)
            } else {
                onCollapseRow(value)
            }
        })
    
        return (
            <Fragment key={rowIndex}>
                <StyledTableRow className={classes.root} key={rowIndex}>
                    <StyledTableCell style={{ width: '30px' }}>
                        <IconButton
                            size='small'
                            name={'arrow'}
                            value={rowIndex}
                            onClick={handleColumnChange}
                        >
                            {row.isCollapsed ? (
                                <KeyboardArrowDownIcon style={{ fontSize: '1.5rem', transform: 'scale(1.5)' }} />
                            ) : (
                                <KeyboardArrowRightIcon style={{ fontSize: '1.5rem', transform: 'scale(1.5)' }} />
                            )}
                        </IconButton>
                    </StyledTableCell>
                    <StyledTableCell style={{
                        color: 'green',
                        width: '30px'
                    }}>
                        <div
                            style={{
                                alignItems: 'center',
                                display: 'flex',
                                height: '2em'
                            }}
                        >
                            {!isEmpty(row.validationErrors) && <ValidatedFramework value={formatError(row.validationErrors)}/>}
                            {isEmpty(row.validationErrors) && row.status === 'SUCCESS' && <ValidatedFramework value={[ ]}/>}
                        </div>
                    </StyledTableCell>
                    {rowHeader(row, rowIndex, onChangeRow)}
                    <StyledTableCell
                        style={{
                            marginBottom: `${row.isCollapsed ? 'none' : '1px solid lightgray'}`,
                            width: '30px'
                        }}
                    >
                        <div
                            style={{
                                alignItems: 'center',
                                display: 'flex',
                                height: '2em'
                            }}
                        >
                            <IconButton size='small' onClick={handleColumnChange}>
                                <Checkbox
                                    checked={row.urgentRequest}
                                    name={'urgent'}
                                    value={rowIndex}
                                    color='primary'
                                    size='medium'
                                    disabled={row.status === 'SUCCESS'}
                                    inputProps={{
                                        'aria-label': 'secondary checkbox',
                                    }}
                                />
                            </IconButton>
                        </div>
                    </StyledTableCell>
                    <StyledTableCell
                        style={{
                            marginBottom: `${row.isCollapsed ? 'none' : '1px solid lightgray'}`,
                            width: '30px'
                        }}
                    >
                        <div
                            style={{
                                alignItems: 'center',
                                display: 'flex',
                                height: '2em'
                            }}
                        >
                            <IconButton
                                size='small'
                                name={'addRow'}
                                value={rowIndex}
                                onClick={handleColumnChange}
                            >
                                <FileCopyIcon style={{ fontSize: '1.1rem', transform: 'scale(1.1)' }}/>
                            </IconButton>
                            <IconButton
                                size='small'
                                name={'removeRow'}
                                value={rowIndex}
                                onClick={handleColumnChange}
                            >
                                <DeleteIcon style={{ fontSize: '1.2rem', transform: 'scale(1.2)' }}/>
                            </IconButton>
                        </div>
                    </StyledTableCell>
                </StyledTableRow>
                <StyledTableRow>
                    <StyledTableCell
                        style={{ padding: 0 }}
                        colSpan={12}
                    >
                        <Collapse
                            in={row.isCollapsed}
                            timeout='auto'
                            unmountOnExit
                        >
                            <div style={{display: 'flex'}}>
                                <span style={{flex: '1'}}>{rowForm(row, rowIndex, onChangeRow)}</span>
                            </div>
                        </Collapse>
                    </StyledTableCell>
                </StyledTableRow>
            </Fragment>
        )
    }