Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MaterialUI Table - Equal width Columns using Span?

I'm trying to utilize the Table component from Material UI to build a data table. However, I'm struggling with making equal width columns for my datatable. Currently I'm trying something like this:

<TableCell key={props.name} style={{width: '25%'}}>
          <span
            style={{
              width: `${(100 / props.numCols)}%`,
              whiteSpace: "pre",
              overflow: "scroll",
              display: 'block'
            }}
          >
            {props.value}
          </span>
 </TableCell>

However, this doesn't seem to do the trick. I expect 4 columns of equal widths but in this photo you'll see that you can only see 3 of the columns (the 4th one is way off-screen) and notably, the 3rd column is extremely long. I would appreciate any pointers!

enter image description here

Edit: It seems like the width property is actually taking 100% of the length of the text? Is there a way I can get it to take the width of the tablerow?

like image 646
Tim Avatar asked Dec 24 '22 03:12

Tim


2 Answers

I know this question is a little bit dated, but you can do the following to get more control over your table row width distribution:

<Table style={{ tableLayout: 'fixed' }} > .. </Table>
like image 156
Ronnie Avatar answered Jan 15 '23 21:01

Ronnie


It seems like the only way to set an even column width is to force a tablehead/th width by utilizing max-width and mix-width. Unfortunately, neither property utilizes the calc() function. And, unfortunately, plain old width will not affect the rows. You have to set a predefined max-width and mix-width in px/em/rem.

Even more bad news... Material UI utilizes dynamic classNames, so you can't overwrite their styles if you wanted to.

You're forced to either: Set inline styles for every component {{ maxWidth: 300 }}, use Material UI's Global CSS Override (see working example here), or just change the entire element with scoped CSS.

The path of least resistance/less project clutter would be to use CSS and scope elements by wrapping them in a containing div or span with a className, for example:

<div className="container">
  <table>
    ...
  <table>
<div>

which would translate to:

.container > table { ... }

however, not all elements can be wrapped AND it still requires some properties to be !important.

Working example: https://codesandbox.io/s/6nwpkylw33

Table.js

import React from "react";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";
import rows from "./rowsData";

export default () => (
  <div>
    <h1 className="title">Material UI - Responsive Table</h1>
    <Paper className="container">
      <Table>
        <TableHead>
          <TableRow>
            <TableCell>Dessert (100g serving)</TableCell>
            <TableCell numeric>Calories</TableCell>
            <TableCell numeric>Fat (g)</TableCell>
            <TableCell numeric>Carbs (g)</TableCell>
            <TableCell numeric>Protein (g)</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {rows.map(({ id, name, calories, fat, carbs, protein }) => (
            <TableRow key={id}>
              <TableCell component="th" scope="row">
                {name}
              </TableCell>
              <TableCell numeric>{calories}</TableCell>
              <TableCell numeric>{fat}</TableCell>
              <TableCell numeric>{carbs}</TableCell>
              <TableCell numeric>{protein}</TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </Paper>
  </div>
);

styles.css

.container {
  overflow-x: auto;
  margin-right: auto;
  margin-left: auto;
  margin-top: 50px;
  padding: 10px;
  margin: 10px;
}

.title {
  margin-top: 20px;
  text-align: center;
}

tr {
  height: 40px !important;
}

th {
  max-width: 125px;
  min-width: 125px;
  padding: 0 !important;
  overflow-x: auto;
  white-space: nowrap; /* <== comment/remove this if you want long strings to alter row heights */
  text-align: center !important;
}

td {
  height: 40px !important;
  padding: 5px !important;
  text-align: center !important;
}
like image 43
Matt Carlotta Avatar answered Jan 15 '23 20:01

Matt Carlotta