🏷️(react) allow autocompletion for DataGrid's renderCell
Previously the type of the row parameter of renderCell was hardcoded as Row. This wasn't ideal because the best case scenario we want it to enable Typescript to use the type of rows props. Now that's the case. Resolve #62
This commit is contained in:
5
.changeset/neat-sheep-collect.md
Normal file
5
.changeset/neat-sheep-collect.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@openfun/cunningham-react": minor
|
||||
---
|
||||
|
||||
allow autocompletion for DataGrid's renderCell
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
import { BaseProps, DataGrid } from ":/components/DataGrid/index";
|
||||
import { BaseProps, DataGrid, Row } from ":/components/DataGrid/index";
|
||||
|
||||
export const DataList = ({ rows, ...props }: BaseProps) => {
|
||||
export const DataList = <T extends Row>({ rows, ...props }: BaseProps<T>) => {
|
||||
return <DataGrid {...props} displayHeader={false} rows={rows} />;
|
||||
};
|
||||
|
||||
@@ -10,18 +10,18 @@ import {
|
||||
/**
|
||||
* Handles sorting, pagination.
|
||||
*/
|
||||
export const SimpleDataGrid = ({
|
||||
export const SimpleDataGrid = <T extends Row>({
|
||||
rows,
|
||||
defaultPaginationParams,
|
||||
defaultSortModel = [],
|
||||
...props
|
||||
}: BaseProps & {
|
||||
}: BaseProps<T> & {
|
||||
/** Pagination default props, should never change. */
|
||||
defaultPaginationParams?: Parameters<typeof usePagination>[0] | boolean;
|
||||
/** Pagination default props, should never change. */
|
||||
defaultSortModel?: SortModel;
|
||||
}) => {
|
||||
const [realRows, setRealRows] = useState<Row[]>([]);
|
||||
const [realRows, setRealRows] = useState<T[]>([]);
|
||||
const [sortModel, setSortModel] = useState<SortModel>(defaultSortModel);
|
||||
const realPaginationParams = useMemo(() => {
|
||||
if (typeof defaultPaginationParams === "boolean") {
|
||||
|
||||
@@ -173,7 +173,7 @@ export const FullServerSide = () => {
|
||||
sort: "desc",
|
||||
},
|
||||
]);
|
||||
const [rows, setRows] = useState<any[]>([]);
|
||||
const [rows, setRows] = useState<typeof database>([]);
|
||||
|
||||
useEffect(() => {
|
||||
// Simulate server-side fetching.
|
||||
@@ -258,19 +258,29 @@ export const DataListOnly = () => {
|
||||
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} />
|
||||
<DataList
|
||||
rows={database}
|
||||
columns={[
|
||||
{ field: "title" },
|
||||
{ field: "date" },
|
||||
{
|
||||
headerName: "action",
|
||||
renderCell: () => {
|
||||
return (
|
||||
<Button size="small" color="secondary">
|
||||
Do it
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</CunninghamProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -37,7 +37,7 @@ export interface BaseProps<T extends Row = Row> {
|
||||
columns: Column<T>[];
|
||||
rows: T[];
|
||||
isLoading?: boolean;
|
||||
enableRowSelection?: boolean | ((row: T) => boolean);
|
||||
enableRowSelection?: TableOptions<T>["enableRowSelection"];
|
||||
onRowSelectionChange?: (newSelection: RowSelectionState) => void;
|
||||
rowSelection?: RowSelectionState;
|
||||
}
|
||||
@@ -47,11 +47,11 @@ interface Props<T extends Row = Row> extends BaseProps<T> {
|
||||
sortModel?: SortModel;
|
||||
onSortModelChange?: (newSortModel: SortModel) => void;
|
||||
/** Options for the underlying tanstack table. */
|
||||
tableOptions?: TableOptions<Row>;
|
||||
tableOptions?: TableOptions<T>;
|
||||
displayHeader?: boolean;
|
||||
}
|
||||
|
||||
export const DataGrid = ({
|
||||
export const DataGrid = <T extends Row>({
|
||||
columns,
|
||||
rows,
|
||||
pagination,
|
||||
@@ -63,7 +63,7 @@ export const DataGrid = ({
|
||||
rowSelection,
|
||||
tableOptions,
|
||||
displayHeader = true,
|
||||
}: Props) => {
|
||||
}: Props<T>) => {
|
||||
const { t } = useCunningham();
|
||||
const headlessColumns = useHeadlessColumns({ columns, enableRowSelection });
|
||||
|
||||
|
||||
@@ -1,32 +1,27 @@
|
||||
import {
|
||||
CellContext,
|
||||
ColumnDef,
|
||||
createColumnHelper,
|
||||
PaginationState,
|
||||
SortingState,
|
||||
} from "@tanstack/react-table";
|
||||
import React, { ReactNode } from "react";
|
||||
import {
|
||||
ColumnDefBase,
|
||||
DisplayColumnDef,
|
||||
} from "@tanstack/table-core/src/types";
|
||||
import React from "react";
|
||||
import { Checkbox } from ":/components/Forms/Checkbox";
|
||||
import { PaginationProps } from ":/components/Pagination";
|
||||
import { Column, Row, SortModel } from ":/components/DataGrid/index";
|
||||
import { BaseProps, Column, Row, SortModel } from ":/components/DataGrid/index";
|
||||
import { useCunningham } from ":/components/Provider";
|
||||
|
||||
/**
|
||||
* Converts Cunningham's columns to the underlying tanstack table.
|
||||
*/
|
||||
export const useHeadlessColumns = ({
|
||||
export const useHeadlessColumns = <T extends Row>({
|
||||
columns,
|
||||
enableRowSelection,
|
||||
}: {
|
||||
columns: Column[];
|
||||
enableRowSelection?: boolean | ((row: Row) => boolean);
|
||||
}): ColumnDef<Row, any>[] => {
|
||||
columns: Column<T>[];
|
||||
enableRowSelection?: BaseProps<T>["enableRowSelection"];
|
||||
}): ColumnDef<T, any>[] => {
|
||||
const { t } = useCunningham();
|
||||
const columnHelper = createColumnHelper<Row>();
|
||||
const columnHelper = createColumnHelper<T>();
|
||||
let headlessColumns = columns.map((column) => {
|
||||
const opts = {
|
||||
id: column.field ?? "actions",
|
||||
@@ -34,7 +29,9 @@ export const useHeadlessColumns = ({
|
||||
header: column.headerName,
|
||||
};
|
||||
if (column.field) {
|
||||
return columnHelper.accessor(column.field, opts);
|
||||
// The any cast is needed because the type of the accessor is hard-defined on react-table.
|
||||
// On our side we only use string as type for simplicity purpose.
|
||||
return columnHelper.accessor(column.field as any, opts);
|
||||
}
|
||||
return columnHelper.display({
|
||||
...opts,
|
||||
|
||||
Reference in New Issue
Block a user