I am using a MUI5 React table and have a hard time figuring out how to adjust the column and cell width. The table needs to span 100% but the fields have to stay together and not spread out automatically like they are doing now. Ideally, I need to set the width of the cell to the width of the content, or at least to a fixed width. Here are my components:
const StyledTableCell = styled(TableCell)(({ theme }) => ({
height: "44px",
padding: "5px 12px",
[`&.${tableCellClasses.head}`]: {
color: theme.palette.gray.main,
fontWeight: 700,
fontSize: "12px",
lineHeight: "14px",
height: "20px",
},
[`&.${tableCellClasses.body}`]: {
fontWeight: 400,
fontSize: "13px",
color: theme.palette.darkGray.main,
},
}));
const StyledTableRow = styled(TableRow)(({ theme }) => ({
"&:nth-of-type(even)": {
backgroundColor: theme.palette.action.hover,
},
border: 0,
}));
function DataTable({data}) {
function createData(fields) {
const res = { ...fields };
return res;
}
const rows = data.map((el) => {
return createData(el);
});
return (
<TableContainer sx={{ width: "100%", marginBottom: "25px" }}>
<Table
sx={{
[`& .${tableCellClasses.root}`]: {
borderBottom: "none",
},
}}
>
<TableHead>
<TableRow>
{SectionTitles.container.fields.map((field, index) => {
return (
<StyledTableCell key={index} align="left">
{field}
</StyledTableCell>
);
})}
</TableRow>
</TableHead>
<TableBody>
{rows.map((row, index) => (
<StyledTableRow key={index}>
{Object.keys(row).map((el, index) => {
return (
<StyledTableCell key={index} align="left">
{row[el]}
</StyledTableCell>
);
})}
</StyledTableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
I have tried setting the width in the styled components and tried to set it in sx as well but nothing is working, the columns still spread out. I have explored pretty much every solution I could find on SO and on google and nothing is making it change the width.
Related
import * as React from "react";
import {
Select,
MenuItem,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Paper
} from "#mui/material";
import KeyboardArrowDownIcon from "#mui/icons-material/KeyboardArrowDown";
function createData(name, mobile, access) {
return { name, mobile, access };
}
const rows = [
createData("Sam", 9865745159),
createData("Amily", 8723879237),
createData("Eva", 9432671262),
createData("Jack", 7898083305),
createData("Diana", 8973667356)
];
export default function DenseTable() {
const [access, setAccess] = React.useState(1);
const handleChange = (event, index, data) => {
setAccess(event.target.value);
};
return (
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} size="small" aria-label="a dense table">
<TableHead>
<TableRow>
<TableCell align="center">Name</TableCell>
<TableCell align="center">Mobile</TableCell>
<TableCell align="center">Access</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow
key={row.name}
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
>
<TableCell component="th" scope="row" align="center">
{row.name}
</TableCell>
<TableCell align="center">{row.mobile}</TableCell>
<TableCell align="center">
<Select
value={access}
onChange={handleChange}
MenuProps={{
MenuListProps: { disablePadding: true }
}}
fullWidth
size="small"
IconComponent={() => (
<KeyboardArrowDownIcon
sx={{
position: "absolute",
right: 10,
width: "20px",
pointerEvents: "none"
}}
/>
)}
sx={{
fontSize: "14px",
width: "100px",
height: "28px"
}}
>
<MenuItem
value={1}
sx={{
fontSize: "14px",
height: "25px",
width: "100%"
}}
>
Allow
</MenuItem>
<MenuItem
value={2}
sx={{
fontSize: "14px",
height: "30px",
width: "100%"
}}
>
Decline
</MenuItem>
</Select>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
I am using ReactJs with Material UI table with dropdown in each row of the table cell. Whenever I am changing the dropdown option of one row then automatically changes to same option in dropdown of all rows.I have to handle each row separately. How to change dropdown in each row of mui table cell in a loop? file.
Move the dropdown to a new jsx component and manage the state there
function dropdownComponent (){
const [access, setAccess] = React.useState(1);
const handleChange = (event, index, data) => {
setAccess(event.target.value);
};
return
(<Select
value={access}
onChange={handleChange}
MenuProps={{
MenuListProps: { disablePadding: true }
}}
fullWidth
size="small"
IconComponent={() => (
<KeyboardArrowDownIcon
sx={{
position: "absolute",
right: 10,
width: "20px",
pointerEvents: "none"
}}
/>
)}
sx={{
fontSize: "14px",
width: "100px",
height: "28px"
}}
>
<MenuItem
value={1}
sx={{
fontSize: "14px",
height: "25px",
width: "100%"
}}
>
Allow
</MenuItem>
<MenuItem
value={2}
sx={{
fontSize: "14px",
height: "30px",
width: "100%"
}}
>
Decline
</MenuItem>
</Select>
)
}
Call it like this
<TableCell align="center">
<dropdownComponent />
I've got a MUI table with cells that link to another part of the app when clicked. Rather than wrap the entire row, I'm selectively wrapping certain cells. The link/routing is working - but I'm left with this annoying dead unclickable space due to some styling interactions.
In the picture below I've opened the 'inspect element' view on dev tools to show specifically the dead zone I'm dealing with in the first cell, and to show some mui styling details that might be relevant. Code with styles included further down.
Styles:
const useStyles = makeStyles(theme => ({
table: {
minWidth: 650,
position: 'relative',
fontSize: 10
},
largeIcon: {
width: 60,
height: 60
},
tableContainer: {
minHeight: 320
},
tableBodyContainer: {
minHeight: 265
},
tableHeadRow: {
'& .MuiTableCell-root': {
borderRight: `1px solid ${COLORS.WHITE}`,
borderBottom: `none`,
padding: '8px 5px 8px',
fontSize: 10,
cursor: 'pointer'
}
},
arrow: {
color: theme.palette.grey[500]
},
arrowActive: {
transform: 'rotate(-180deg)',
color: theme.palette.primary.main,
display: 'inline-block'
},
tableRow: {
'& .MuiTableCell-root': {
borderRight: `1px solid ${theme.palette.grey[200]}`,
borderBottom: 'none',
cursor: 'pointer',
padding: 5,
paddingTop: 8,
paddingBottom: 8,
minWidth: 25
},
'& .MuiTableCell-root:first-child': {
border: 'none'
}
},
selectedRow: {
backgroundColor: `${COLORS.SECONDARY} !important`,
'& .MuiTableCell-root': {
color: COLORS.WHITE
}
},
editIcon: {
backgroundImage: `url(${EditIcon})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
width: 18,
height: 18
}
}));
And the table:
return (
<div className={classes.tableContainer}>
<TableContainer className={classes.tableBodyContainer}>
<Table className={classes.table} size="small">
<TableHead>
<TableRow className={classes.tableHeadRow}>
<TableCell />
{tableHeadElements.map(e => (
<TableCell key={e.key} align="center">
{e.label}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{folders?.items.map((folder: IFolderDTO, index: number) => {
const { id, name, updatedAt } = folder;
return (
<TableRow
className={classes.tableRow}
classes={{ selected: classes.selectedRow }}
selected={selectedRow === id}
onClick={() => setSelectedRow(id)}
key={index}
>
<TableCell align="center" >
<Link to={APP_DASHBOARD_CHILD_FOLDER_CONTENTS_PATH(id)}>
<Box>
<IconButton color="default" size={'medium'}>
<FolderIcon fontSize="default" />
</IconButton>
</Box>
</Link>
</TableCell>
{[name, new Date(updatedAt)].map(cell => (
<TableCell key={index} align="center">
<Link to={APP_DASHBOARD_CHILD_FOLDER_CONTENTS_PATH(id)}>
<Box>{getCorrectFormat(cell)}</Box>
</Link>
</TableCell>
))}
<FolderActionsMenu
folderId={id}
onDeleteFolder={onDeleteFolder}
openDialogWithId={openDialogWithId}
/>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
<FolderFormDialog />
</div>
Kill the dead unclickable space! (please)
Thanks
I'm using react-select autocomplete component for my react js web site. I just copied the example code in this link inside to a table cell, but it is not working properly as shown in the below image.
However, it individually works fine. Please help me with this issue. Here is the code.
Autocomplete.jsx has the same code as in the above link.
...
import Autocomplete from './Autocomplete.jsx';
...
const useStyles = makeStyles(theme => ({
textField: {
padding: theme.spacing(),
width: '100%',
},
}));
...
export default function Mapping(props) {
const classes = useStyles();
...
return (
<TableRow>
<TableCell>
<TextField
required
id='outlined-required'
label='URL pattern'
variant='outlined'
value={name}
onChange={event => setName(event.target.value)}
className={classes.textField}
/>
</TableCell>
<TableCell>
<Autocomplete arn={arn} setArn={setArn} />
</TableCell>
{resource.editable ?
<TableCell>
<Button onClick={saveResource}>Save</Button>
<Button onClick={cancel}>Cancel</Button>
</TableCell>
:
<TableCell>
<Button onClick={addResource}>Add</Button>
</TableCell>
}
</TableRow>
);
}
=========================================================================
...
import Mapping from './Mapping.jsx';
...
const useStyles = makeStyles(theme => ({
root: {
paddingBottom: theme.spacing(),
paddingTop: theme.spacing(),
width: '100%',
marginTop: theme.spacing(),
},
mappingsWrapper: {
padding: theme.spacing(),
borderRight: '#c4c4c4',
borderRightStyle: 'solid',
borderRightWidth: 'thin',
},
mappingsHeading: {
display: 'flex',
alignItems: 'center',
},
mappingsTitle: {
paddingLeft: theme.spacing(),
fontSize: '1rem',
paddingTop: theme.spacing(),
paddingBottom: theme.spacing(),
},
}));
...
export default function Mappings() {
const classes = useStyles();
...
return (
<Paper className={classes.root}>
<Grid container item xs={12}>
<Grid xs className={classes.mappingsWrapper}>
<div className={classes.mappingsHeading}>
<Typography className={classes.mappingsTitle}>
Mappings
</Typography>
</div>
<Table stickyHeader>
<TableHead>
<TableRow>
{columns.map(column => (
<TableCell
key={column.id}
align={column.align}
style={{ minWidth: column.minWidth }}
>
{column.label}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{resources.map((resource) => {
if (resource.editable) {
return (
<Mapping
resource={resource}
resources={resources}
setResources={setResources}
/>
);
} else {
return (
<TableRow>
<TableCell>{resource.name}</TableCell>
<TableCell>{resource.arn}</TableCell>
<TableCell>
<Button onClick={() => editResource(resource)}>Edit</Button>
<Button onClick={() => deleteResource(resource)}>Delete</Button>
</TableCell>
</TableRow>
);
}
})}
<Mapping
resource={{ name: '', arn: '', editable: false }}
resources={resources}
setResources={setResources}
/>
</TableBody>
</Table>
</Grid>
</Grid>
</Paper>
);
}
The problem I have is I try to center out the fixed-sized table in the middle of the page (in a Paper component) and fail miserably. I am also quite new in Material-ui, so I am not sure this is a proper way for structuring this kind of items. Can you please help me centering it out in the middle of the page?
import rows from "./mockdata/mock_dashboard";
const rowsData = rows;
const useStyles = makeStyles(theme => ({
root: {
width: "100%"
},
paper: {
marginTop: theme.spacing(3),
width: "100%",
overflowX: "auto",
marginBottom: theme.spacing(2),
margin: "auto"
},
table: {
minWidth: 650,
maxWidth: 1200
}
}));
export default function MainDashboard() {
const classes = useStyles();
return (
<div className={classes.root}>
<Paper className={classes.paper}>
<Table className={classes.table} size="small">
<TableHead>
<TableRow>
<TableCell>Nz.</TableCell>
<TableCell>Data Przyjęcia</TableCell>
<TableCell>Koordynator</TableCell>
<TableCell>Link do Pliku</TableCell>
<TableCell>Dod. opis</TableCell>
<TableCell>Data Wykonania</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rowsData.map(row => (
<TableRow key={row.orderNo}>
<TableCell component="th" scope="row">
{row.orderNo}
</TableCell>
<TableCell align="center">{row.orderDate}</TableCell>
<TableCell align="center">{row.coordinator}</TableCell>
<TableCell align="center">{row.link}</TableCell>
<TableCell align="center" className={classes.descriptionFont}>
{row.description}
</TableCell>
<TableCell align="center">{row.dueDate}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Paper>
</div>
);
What about wrapping table in fixed Container and get rid of fixed table width? It is basic element for Material-ui layout.
import Container from '#material-ui/core/Container';
import rows from "./mockdata/mock_dashboard";
const rowsData = rows;
const useStyles = makeStyles(theme => ({
root: {
width: "100%"
},
paper: {
marginTop: theme.spacing(3),
width: "100%",
overflowX: "auto",
marginBottom: theme.spacing(2),
margin: "auto"
},
table: {
width: '100%',
}
}));
export default function MainDashboard() {
const classes = useStyles();
return (
<Container fixed>
<Paper className={classes.paper}>
<Table className={classes.table} size="small">
<TableHead>
<TableRow>
<TableCell>Nz.</TableCell>
<TableCell>Data Przyjęcia</TableCell>
<TableCell>Koordynator</TableCell>
<TableCell>Link do Pliku</TableCell>
<TableCell>Dod. opis</TableCell>
<TableCell>Data Wykonania</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rowsData.map(row => (
<TableRow key={row.orderNo}>
<TableCell component="th" scope="row">
{row.orderNo}
</TableCell>
<TableCell align="center">{row.orderDate}</TableCell>
<TableCell align="center">{row.coordinator}</TableCell>
<TableCell align="center">{row.link}</TableCell>
<TableCell align="center" className={classes.descriptionFont}>
{row.description}
</TableCell>
<TableCell align="center">{row.dueDate}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Paper>
</Container>
);
}
How do I reduce the height of the TableFooter component? I am trying to reduce the height of the TableFooter component in materials-UI but below 56px, the height of the footer does not get any smaller. There's no problem in increasing/making it bigger, however.
I've tried using the MUI Theme override based on other articles I've read here but they also do not work.
const theme = createMuiTheme({
overrides:{
MuiTableRow: {
root: { //for the body
height: "100%"
},
head: { //for the head
height: "100%"
},
footer: {
height: '30px',
minHeight: '20px',
backgroundColor: 'grey'
},
}
}
})
The code for my table based mostly on the Custom Pagination demo from the material-UI website aside from the codes that try to reduce the footer size.
<Paper className={classes.root}>
<div className={classes.tableWrapper}>
<Table className={classes.table} padding={"none"}>
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map(row => (
<TableRow key={row.id}>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
</TableRow>
))}
{emptyRows > 0 && (
<TableRow style={{ height: 48 * emptyRows }}>
<TableCell colSpan={4} />
</TableRow>
)}
</TableBody>
<TableFooter className={classes.footer}>
<TableRow className={classes.footer}>
<TablePagination
rowsPerPageOptions={[]}
colSpan={3}
count={rows.length}
rowsPerPage={rowsPerPage}
page={page}
SelectProps={{
native: true,
}}
onChangePage={this.handleChangePage}
ActionsComponent={TablePaginationActionsWrapped}
style={{ padding: 0, margin: 0 }}
/>
</TableRow>
</TableFooter>
</Table>
</div>
</Paper>
https://codesandbox.io/s/moj46v62oy?fontsize=14
The current output where the size doesn't get any smaller than that. I was hoping to lessen the space between the top and bottom of the arrow.
You can use:
footer: {
"& > td > div": {
height: 30,
minHeight: 30
},
backgroundColor: "grey",
height: 30
}
This should become easier once v4 is out and global styles are being used.
Example: https://codesandbox.io/s/pmokwxxmvj