(react) add width property to DataGrid columns

Without this feature we needed to override CSS directly in order to
make columns a specific width.

Closes #240
This commit is contained in:
Nathan Vasse
2024-02-28 16:57:42 +01:00
committed by NathanVss
parent 5446d70bca
commit f398e51db3
6 changed files with 112 additions and 2 deletions

View File

@@ -23,6 +23,7 @@
border-collapse: collapse;
font-weight: var(--c--theme--font--weights--regular);
width: 100%;
table-layout: fixed;
th, td {
text-align: left;
@@ -30,6 +31,7 @@
white-space: nowrap;
font-size: var(--c--theme--font--sizes--m);
height: 3rem;
overflow: hidden;
}
th {

View File

@@ -381,4 +381,44 @@ describe("<DataGrid/>", () => {
expect(tds[0].textContent).toEqual(row.sub.name);
});
});
it("should render column with specific width", async () => {
const database = Array.from(Array(10)).map(() => ({
id: faker.string.uuid(),
name: faker.person.fullName(),
email: faker.internet.email(),
}));
const Component = () => {
return (
<CunninghamProvider>
<DataGrid
columns={[
{
field: "firstName",
headerName: "First name",
size: 50,
},
{
field: "email",
headerName: "Email",
},
]}
rows={database}
/>
</CunninghamProvider>
);
};
render(<Component />);
const table = screen.getByRole("table");
const ths = getAllByRole(table, "columnheader");
expect(ths.length).toBe(2);
expect(ths[0].textContent).toEqual("First name");
expect(ths[1].textContent).toEqual("Email");
expect(ths[0].style.width).toEqual("50px");
expect(ths[1].style.width).toEqual("");
});
});

View File

@@ -335,3 +335,57 @@ export const DataListOnly = () => {
/>
);
};
export const WithColumnWidth = () => {
const database = useMemo(
() =>
Array.from(Array(23)).map(() => ({
id: faker.string.uuid(),
firstName: faker.person.firstName(),
lastName: faker.person.lastName(),
email: faker.internet.email(),
address: faker.location.streetAddress(),
})),
[],
);
return (
<SimpleDataGrid
columns={[
{
field: "firstName",
headerName: "First name",
highlight: true,
size: 100,
},
{
field: "lastName",
headerName: "Last name",
size: 100,
},
{
field: "email",
headerName: "Email",
highlight: true,
},
{
field: "address",
headerName: "Address",
enableSorting: false,
},
{
headerName: "Actions",
id: "actions",
size: 50,
renderCell: () => (
<Button
color="tertiary-text"
size="small"
icon={<span className="material-icons">delete</span>}
/>
),
},
]}
rows={database}
/>
);
};

View File

@@ -1,4 +1,4 @@
import React, { ReactNode, useMemo } from "react";
import React, { CSSProperties, ReactNode, useMemo } from "react";
import classNames from "classnames";
import {
flexRender,
@@ -48,6 +48,7 @@ export type Column<T extends Row = Row> = (
headerName?: string;
highlight?: boolean;
enableSorting?: boolean;
size?: number;
};
export type SortModel = { field: string; sort: "asc" | "desc" | null }[];
@@ -192,7 +193,13 @@ export const DataGrid = <T extends Row>({
{displayHeader &&
table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => {
{headerGroup.headers.map((header, i) => {
const style: CSSProperties = {};
const column = columns[i];
if (column && typeof column.size === "number") {
style.width = `${column.size}px`;
}
return (
<th
key={header.id}
@@ -201,6 +208,7 @@ export const DataGrid = <T extends Row>({
"c__datagrid__header--select":
header.id === "select",
})}
style={style}
>
{header.isPlaceholder ? null : (
<div

View File

@@ -31,6 +31,7 @@ export const useHeadlessColumns = <T extends Row>({
enableSorting:
column.enableSorting === undefined ? true : column.enableSorting,
header: column.headerName,
size: column.size,
cell: (info: CellContext<any, any>) => {
if (column.renderCell) {
return column.renderCell({ row: info.row.original });