✨(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:
5
.changeset/popular-wasps-bathe.md
Normal file
5
.changeset/popular-wasps-bathe.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@openfun/cunningham-react": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
add width property to DataGrid columns
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
font-weight: var(--c--theme--font--weights--regular);
|
font-weight: var(--c--theme--font--weights--regular);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
table-layout: fixed;
|
||||||
|
|
||||||
th, td {
|
th, td {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-size: var(--c--theme--font--sizes--m);
|
font-size: var(--c--theme--font--sizes--m);
|
||||||
height: 3rem;
|
height: 3rem;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
|
|||||||
@@ -381,4 +381,44 @@ describe("<DataGrid/>", () => {
|
|||||||
expect(tds[0].textContent).toEqual(row.sub.name);
|
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("");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { ReactNode, useMemo } from "react";
|
import React, { CSSProperties, ReactNode, useMemo } from "react";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import {
|
import {
|
||||||
flexRender,
|
flexRender,
|
||||||
@@ -48,6 +48,7 @@ export type Column<T extends Row = Row> = (
|
|||||||
headerName?: string;
|
headerName?: string;
|
||||||
highlight?: boolean;
|
highlight?: boolean;
|
||||||
enableSorting?: boolean;
|
enableSorting?: boolean;
|
||||||
|
size?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SortModel = { field: string; sort: "asc" | "desc" | null }[];
|
export type SortModel = { field: string; sort: "asc" | "desc" | null }[];
|
||||||
@@ -192,7 +193,13 @@ export const DataGrid = <T extends Row>({
|
|||||||
{displayHeader &&
|
{displayHeader &&
|
||||||
table.getHeaderGroups().map((headerGroup) => (
|
table.getHeaderGroups().map((headerGroup) => (
|
||||||
<tr key={headerGroup.id}>
|
<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 (
|
return (
|
||||||
<th
|
<th
|
||||||
key={header.id}
|
key={header.id}
|
||||||
@@ -201,6 +208,7 @@ export const DataGrid = <T extends Row>({
|
|||||||
"c__datagrid__header--select":
|
"c__datagrid__header--select":
|
||||||
header.id === "select",
|
header.id === "select",
|
||||||
})}
|
})}
|
||||||
|
style={style}
|
||||||
>
|
>
|
||||||
{header.isPlaceholder ? null : (
|
{header.isPlaceholder ? null : (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ export const useHeadlessColumns = <T extends Row>({
|
|||||||
enableSorting:
|
enableSorting:
|
||||||
column.enableSorting === undefined ? true : column.enableSorting,
|
column.enableSorting === undefined ? true : column.enableSorting,
|
||||||
header: column.headerName,
|
header: column.headerName,
|
||||||
|
size: column.size,
|
||||||
cell: (info: CellContext<any, any>) => {
|
cell: (info: CellContext<any, any>) => {
|
||||||
if (column.renderCell) {
|
if (column.renderCell) {
|
||||||
return column.renderCell({ row: info.row.original });
|
return column.renderCell({ row: info.row.original });
|
||||||
|
|||||||
Reference in New Issue
Block a user