✨(react) add DataList
Implement DataList that is a wrapper of DataGrid without header, sorting nor pagination.
This commit is contained in:
5
.changeset/red-pots-worry.md
Normal file
5
.changeset/red-pots-worry.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@openfun/cunningham-react": minor
|
||||
---
|
||||
|
||||
Add DataList component
|
||||
36
packages/react/src/components/DataGrid/DataList.spec.tsx
Normal file
36
packages/react/src/components/DataGrid/DataList.spec.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import React from "react";
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { getAllByRole, queryAllByRole } from "@testing-library/dom";
|
||||
import { expect } from "vitest";
|
||||
import { CunninghamProvider } from ":/components/Provider";
|
||||
import { DataList } from ":/components/DataGrid/DataList";
|
||||
|
||||
describe("<DataList/>", () => {
|
||||
it("should render a DataList", async () => {
|
||||
const rows = Array.from(Array(3)).map((_value, index) => ({
|
||||
id: `list key for element ${index}`,
|
||||
firstName: faker.name.firstName(),
|
||||
lastName: faker.name.lastName(),
|
||||
}));
|
||||
render(
|
||||
<CunninghamProvider>
|
||||
<DataList
|
||||
columns={[{ field: "firstName" }, { field: "lastName" }]}
|
||||
rows={rows}
|
||||
/>
|
||||
</CunninghamProvider>
|
||||
);
|
||||
|
||||
const table = screen.getByRole("table");
|
||||
expect(queryAllByRole(table, "columnheader")).toEqual([]);
|
||||
|
||||
rows.forEach((row) => {
|
||||
const element = screen.getByTestId(row.id);
|
||||
const tds = getAllByRole(element, "cell");
|
||||
expect(tds.length).toBe(2);
|
||||
expect(tds[0].textContent).toEqual(row.firstName);
|
||||
expect(tds[1].textContent).toEqual(row.lastName);
|
||||
});
|
||||
});
|
||||
});
|
||||
6
packages/react/src/components/DataGrid/DataList.tsx
Normal file
6
packages/react/src/components/DataGrid/DataList.tsx
Normal file
@@ -0,0 +1,6 @@
|
||||
import React from "react";
|
||||
import { BaseProps, DataGrid } from ":/components/DataGrid/index";
|
||||
|
||||
export const DataList = ({ rows, ...props }: BaseProps) => {
|
||||
return <DataGrid {...props} displayHeader={false} rows={rows} />;
|
||||
};
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Canvas, Meta, Story, Source, ArgsTable } from '@storybook/addon-docs';
|
||||
import { DataGrid } from './index';
|
||||
import { SimpleDataGrid } from './SimpleDataGrid';
|
||||
import { DataList } from './DataList';
|
||||
|
||||
<Meta title="Components/DataGrid/Doc" component={DataGrid}/>
|
||||
|
||||
@@ -26,6 +27,27 @@ The `rows` props is an array of objects that describe the rows of the table. Eac
|
||||
|
||||
We will explore the possibilities that those props provide through the following examples.
|
||||
|
||||
## DataList
|
||||
|
||||
<Source
|
||||
language='ts'
|
||||
dark
|
||||
format={false}
|
||||
code={`import { DataList } from "@openfun/cunningham-react";`}
|
||||
/>
|
||||
|
||||
This component is a wrapper around the more complicated DataGrid component. It is made to be used for simple lists of elements that don't need pagination nor sorting. Also, it doesn't display any header.
|
||||
|
||||
Here a quick usage example
|
||||
|
||||
<Canvas withSource="open">
|
||||
<Story id="components-datagrid--data-list-only"/>
|
||||
</Canvas>
|
||||
|
||||
### Props
|
||||
|
||||
<ArgsTable of={DataList} />
|
||||
|
||||
## SimpleDataGrid
|
||||
|
||||
<Source
|
||||
|
||||
@@ -6,6 +6,7 @@ import { usePagination } from ":/components/Pagination";
|
||||
import { CunninghamProvider } from ":/components/Provider";
|
||||
import { Button } from ":/components/Button";
|
||||
import { SimpleDataGrid } from ":/components/DataGrid/SimpleDataGrid";
|
||||
import { DataList } from ":/components/DataGrid/DataList";
|
||||
|
||||
export default {
|
||||
title: "Components/DataGrid",
|
||||
@@ -249,3 +250,27 @@ export const FullServerSide = () => {
|
||||
</CunninghamProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export const DataListOnly = () => {
|
||||
const database = useMemo(
|
||||
() =>
|
||||
Array.from(Array(5)).map((_value, index) => ({
|
||||
id: `list key for element ${index}`,
|
||||
title: faker.random.word(),
|
||||
date: faker.date.past(1).toISOString(),
|
||||
action: (
|
||||
<Button size="small" color="secondary">
|
||||
Do it
|
||||
</Button>
|
||||
),
|
||||
})),
|
||||
[]
|
||||
);
|
||||
const columns = [{ field: "title" }, { field: "date" }, { field: "action" }];
|
||||
|
||||
return (
|
||||
<CunninghamProvider>
|
||||
<DataList rows={database} columns={columns} />
|
||||
</CunninghamProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// import { Button } from "components/Button";
|
||||
import React, { useMemo } from "react";
|
||||
import classNames from "classnames";
|
||||
import {
|
||||
@@ -49,6 +48,7 @@ interface Props<T extends Row = Row> extends BaseProps<T> {
|
||||
onSortModelChange?: (newSortModel: SortModel) => void;
|
||||
/** Options for the underlying tanstack table. */
|
||||
tableOptions?: TableOptions<Row>;
|
||||
displayHeader?: boolean;
|
||||
}
|
||||
|
||||
export const DataGrid = ({
|
||||
@@ -62,6 +62,7 @@ export const DataGrid = ({
|
||||
onRowSelectionChange,
|
||||
rowSelection,
|
||||
tableOptions,
|
||||
displayHeader = true,
|
||||
}: Props) => {
|
||||
const { t } = useCunningham();
|
||||
const headlessColumns = useHeadlessColumns({ columns, enableRowSelection });
|
||||
@@ -147,50 +148,51 @@ export const DataGrid = ({
|
||||
<>
|
||||
<table>
|
||||
<thead>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<tr key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<th key={header.id} colSpan={header.colSpan}>
|
||||
{header.isPlaceholder ? null : (
|
||||
<div
|
||||
className={classNames("c__datagrid__header", {
|
||||
"c__datagrid__header--sortable":
|
||||
header.column.getCanSort(),
|
||||
})}
|
||||
{...(header.column.getCanSort()
|
||||
? {
|
||||
role: "button",
|
||||
tabIndex: 0,
|
||||
onClick:
|
||||
header.column.getToggleSortingHandler(),
|
||||
}
|
||||
: {})}
|
||||
>
|
||||
{flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
{header.column.getIsSorted() === "asc" && (
|
||||
<span className="material-icons">
|
||||
arrow_drop_up
|
||||
</span>
|
||||
)}
|
||||
{header.column.getIsSorted() === "desc" && (
|
||||
<span className="material-icons">
|
||||
arrow_drop_down
|
||||
</span>
|
||||
)}
|
||||
{!header.column.getIsSorted() && (
|
||||
<span className="c__datagrid__header__icon-placeholder" />
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</th>
|
||||
);
|
||||
})}
|
||||
</tr>
|
||||
))}
|
||||
{displayHeader &&
|
||||
table.getHeaderGroups().map((headerGroup) => (
|
||||
<tr key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => {
|
||||
return (
|
||||
<th key={header.id} colSpan={header.colSpan}>
|
||||
{header.isPlaceholder ? null : (
|
||||
<div
|
||||
className={classNames("c__datagrid__header", {
|
||||
"c__datagrid__header--sortable":
|
||||
header.column.getCanSort(),
|
||||
})}
|
||||
{...(header.column.getCanSort()
|
||||
? {
|
||||
role: "button",
|
||||
tabIndex: 0,
|
||||
onClick:
|
||||
header.column.getToggleSortingHandler(),
|
||||
}
|
||||
: {})}
|
||||
>
|
||||
{flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
{header.column.getIsSorted() === "asc" && (
|
||||
<span className="material-icons">
|
||||
arrow_drop_up
|
||||
</span>
|
||||
)}
|
||||
{header.column.getIsSorted() === "desc" && (
|
||||
<span className="material-icons">
|
||||
arrow_drop_down
|
||||
</span>
|
||||
)}
|
||||
{!header.column.getIsSorted() && (
|
||||
<span className="c__datagrid__header__icon-placeholder" />
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</th>
|
||||
);
|
||||
})}
|
||||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
<tbody>
|
||||
{table.getRowModel().rows.map((row) => (
|
||||
|
||||
@@ -3,6 +3,7 @@ import "./index.scss";
|
||||
export * from "./components/Button";
|
||||
export * from "./components/DataGrid";
|
||||
export * from "./components/DataGrid/SimpleDataGrid";
|
||||
export * from "./components/DataGrid/DataList";
|
||||
export * from "./components/Forms/Field";
|
||||
export * from "./components/Forms/Input";
|
||||
export * from "./components/Loader";
|
||||
|
||||
Reference in New Issue
Block a user