Trying to make a table that looks like this with css grid:
Without using dynamic data and an array.map I can do it, but when it comes to writing this in a DRY way I just cant figure it out.
Snippet wont run(cant figure out how to use react with it), just to show code.
:root {
--color-primary-purple: #c3a5ff;
--color-primary-blue: #6fdce0;
--title-font-h2: 30px;
}
.infoTable {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(4, 1fr);
grid-template-areas: "c1 c2 c3" "c4 c5 c6" "c7 c8 c9" "c10 c11 c12";
justify-content: center;
align-content: center;
font-family: "Roboto";
width: 944px;
}
.infoTable__cell_1 {
grid-area: c1;
}
.infoTable__cell_2 {
grid-area: c2;
}
.infoTable__cell_3 {
grid-area: c3;
}
.infoTable__cell_4 {
grid-area: c4;
}
.infoTable__cell_5 {
grid-area: c5;
}
.infoTable__cell_6 {
grid-area: c6;
}
.infoTable__cell_7 {
grid-area: c7;
}
.infoTable__cell_8 {
grid-area: c8;
}
.infoTable__cell_9 {
grid-area: c9;
}
.infoTable__cell_10 {
grid-area: c10;
}
.infoTable__cell_11 {
grid-area: c11;
}
.infoTable__cell_12 {
grid-area: c12;
}
.infoTable__cell_4,
.infoTable__cell_5,
.infoTable__cell_7,
.infoTable__cell_8,
.infoTable__cell_10,
.infoTable__cell_11 {
border-right: 3px solid rgba(196, 196, 196, 0.06);
}
.infoTable__cell {
text-align: start;
padding: 0 25px 5px 25px;
display: flex;
align-items: center;
}
.infoTable__columnTitle {
font-size: var(--title-font-h2);
font-weight: 700;
margin: 0;
color: white;
}
.infoTable__text {
font-size: 20px;
font-weight: 700;
margin: 0;
width: 280px;
color: var(--color-primary-purple);
}
.infoTable__text_2 {
color: var(--color-primary-blue);
}
<div className="infoTable">
<div className="infoTable__cell infoTable__cell_1">
<h2 className="infoTable__columnTitle">Name</h2>
</div>
<div className="infoTable__cell infoTable__cell_2">
<h2 className="infoTable__columnTitle">Client</h2>
</div>
<div className="infoTable__cell infoTable__cell_3">
<h2 className="infoTable__columnTitle">Date</h2>
</div>
<div className="infoTable__cell infoTable__cell_4">
<p className="infoTable__text">Build Intranet API</p>
</div>
<div className="infoTable__cell infoTable__cell_5">
<p className="infoTable__text">Demo Customer 1</p>
</div>
<div className="infoTable__cell infoTable__cell_6">
<p className="infoTable__text">06/15/20</p>
</div>
<div className="infoTable__cell infoTable__cell_7">
<p className="infoTable__text">Migrate Sage Data to Sharepoint</p>
</div>
<div className="infoTable__cell infoTable__cell_8">
<p className="infoTable__text">Demo Customer 1</p>
</div>
<div className="infoTable__cell infoTable__cell_9">
<p className="infoTable__text">11/05/21</p>
</div>
<div className="infoTable__cell infoTable__cell_10">
<p
className={
customer2 ? `infoTable__text infoTable__text_2 ` : `infoTable__text`
}
>
Build Dynamics 365 to ProCore Integration
</p>
</div>
<div className="infoTable__cell infoTable__cell_11">
<p
className={
customer2 ? `infoTable__text infoTable__text_2 ` : `infoTable__text`
}
>
Demo Customer 2
</p>
</div>
<div className="infoTable__cell infoTable__cell_12">
<p
className={
customer2 ? `infoTable__text infoTable__text_2 ` : `infoTable__text`
}
>
01/05/20
</p>
</div>
</div>
Runnable code: https://codesandbox.io/s/polished-bush-x7vllz?file=/src/InfoTable/InfoTable.js:212-2192
CodePudding user response:
If you maintain your data as an array of objects you can iterate over them to produce a series of divs that will make up your grid. You can assign different colour classes to them based on a clientid which you add to your data objects.
const { Fragment } = React;
// The data which we pass into the component as a prop
const data = [
{ clientId: 1, task: 'Build internet API', clientName: 'Demo customer one', date: '06/15/20' },
{ clientId: 1, task: 'Migrate Sage data to Sharepoint', clientName: 'Demo customer one', date: '11/05/21' },
{ clientId: 2, task: 'Build Dynamics 365 to ProCore Integration', clientName: 'Demo customer two', date: '06/15/20' }
];
// The function that returns all the grid data
function buildGrid(data) {
// `map` over the data, and for each object
return data.map(obj => {
// get the clientId, the name, client (name), and the date
const { clientId, task, clientName, date } = obj;
// Create a class name from the clientId property
const clientClass = `client${clientId}`;
// And then return a series of divs contained by
// a fragment. We need the fragment instead of a container
// otherwise we end up with columns instead of rows
return (
<Fragment>
<div class={clientClass}>{task}</div>
<div class={clientClass}>{clientName}</div>
<div class={clientClass}>{date}</div>
</Fragment>
);
});
}
function Example({ data }) {
// And then in your JSX just add in the headings
// add call the function with your data
return (
<div >
<div >Task</div>
<div >Client</div>
<div >Date</div>
{buildGrid(data)}
</div>
);
}
ReactDOM.render(
<Example data={data} />,
document.getElementById('react')
);
.grid { display: grid; grid-template-columns: repeat(3, 1fr); justify-content: center; align-content: center; width: 100%; padding: 0.5em; background-color: #272a2f; gap: 1em; }
.heading { font-size: 1.2em; font-weight: 600; color: #efefef; }
.client1 { color: #ab9af7; }
.client2 { color: #65d3da; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>