diff --git a/src/Table/BaseTable.story.tsx b/src/Table/BaseTable.story.tsx index bc8a0b56a..5ef729655 100644 --- a/src/Table/BaseTable.story.tsx +++ b/src/Table/BaseTable.story.tsx @@ -4,6 +4,7 @@ import { boolean, text } from "@storybook/addon-knobs"; import { action } from "@storybook/addon-actions"; import { Box, DropdownButton, DropdownMenu, Button, Text } from ".."; import { getMockRows, mockColumns } from "./Table.mock-utils"; +import { ColumnType } from "./Table.types"; import { Table } from "."; const dateToString = ({ cellData }) => { @@ -29,7 +30,7 @@ const dropdownCellRenderer = ({ cellData }) => ( </Box> ); -const columns = [ +const columns: ColumnType[] = [ { label: "Date", dataKey: "date" }, { label: "Expected Quantity", dataKey: "expectedQuantity" }, { label: "Actual Quantity", dataKey: "actualQuantity", align: "right" }, @@ -183,7 +184,7 @@ const columnsWithFormatter = [ { label: "Actual Quantity", dataKey: "actualQuantity" }, ]; -const columnsWithAlignment = [ +const columnsWithAlignment: ColumnType[] = [ { label: "Date", dataKey: "date" }, { label: "Expected Eaches", dataKey: "expectedQuantity" }, { label: "Actual Eaches", dataKey: "actualQuantity", align: "right" }, diff --git a/src/Table/Table.story.tsx b/src/Table/Table.story.tsx index 1dcb9b03b..7166fcd2d 100644 --- a/src/Table/Table.story.tsx +++ b/src/Table/Table.story.tsx @@ -1,4 +1,3 @@ -/* eslint-disable react/prop-types */ import React from "react"; import { action } from "@storybook/addon-actions"; import { boolean, number } from "@storybook/addon-knobs"; @@ -50,7 +49,7 @@ const columnsWithEverything = [ { label: "Note", dataKey: "note", width: "45%" }, { label: "", - dataKey: "actions", + key: "actions", width: "5%", cellRenderer: dropdownCellRenderer, }, diff --git a/src/Table/Table.types.ts b/src/Table/Table.types.ts index 6b38c109b..85e8f47e9 100644 --- a/src/Table/Table.types.ts +++ b/src/Table/Table.types.ts @@ -1,35 +1,38 @@ +import { Key, CSSProperties } from "react"; import PropTypes from "prop-types"; -export type RowType = any; +export type RowType = unknown; export type CellInfoType = { - cellData: any; + cellData: unknown; column: ColumnType; row: RowType; }; type ColumnInfoType = { - align?: string; + align?: ColumnAlignment; label: string; - dataKey?: string; - width?: string; + dataKey?: Key; + width?: CSSProperties["width"]; }; +type ColumnAlignment = "left" | "right" | "center"; + export type ColumnType = { - align?: string; + align?: ColumnAlignment; label?: string; - dataKey?: string; - cellFormatter?: (cell: CellInfoType) => React.ReactNode | JSX.Element; - cellRenderer?: (cell: CellInfoType) => React.ReactNode | JSX.Element; - headerRenderer?: (column: ColumnInfoType) => React.ReactNode | JSX.Element; - headerFormatter?: (column: ColumnInfoType) => React.ReactNode | JSX.Element; - width?: string; -}; + cellFormatter?: (cell: CellInfoType) => React.ReactNode; + cellRenderer?: (cell: CellInfoType) => React.ReactNode; + headerRenderer?: (column: ColumnInfoType) => React.ReactNode; + headerFormatter?: (column: ColumnInfoType) => React.ReactNode; + width?: string | number; +} & ({ key: Key; dataKey?: never | undefined } | { dataKey: Key; key?: never | undefined }); export const columnPropType = PropTypes.shape({ align: PropTypes.oneOf(["right", "left", "center"]), label: PropTypes.string, - dataKey: PropTypes.string, + dataKey: PropTypes.oneOf([PropTypes.string, PropTypes.number]), + key: PropTypes.oneOf([PropTypes.string, PropTypes.number]), cellFormatter: PropTypes.func, cellRenderer: PropTypes.func, headerRenderer: PropTypes.func, diff --git a/src/Table/TableBody.tsx b/src/Table/TableBody.tsx index b6680847d..8be0c1242 100644 --- a/src/Table/TableBody.tsx +++ b/src/Table/TableBody.tsx @@ -2,9 +2,9 @@ import React from "react"; import PropTypes from "prop-types"; import styled from "styled-components"; import { Box } from "../Box"; +import { DefaultNDSThemeType } from "../theme.type"; import { rowsPropType, columnsPropType, rowPropType } from "./Table.types"; import TableCell from "./TableCell"; -import { DefaultNDSThemeType } from "../theme.type"; const StyledMessageContainer = styled(Box)(({ theme }) => ({ padding: `${theme.space.x3} 0`, @@ -64,8 +64,14 @@ const TableBodyRow = ({ onMouseEnter, }: TableBodyRowProps) => { const renderAllCells = () => - columns.map((column) => ( - <TableCell key={column.dataKey} row={row} column={column} cellData={row[column.dataKey]} compact={compact} /> + columns.map((column, index) => ( + <TableCell + key={column.dataKey ?? column.key ?? index} + row={row} + column={column} + cellData={row[column.dataKey]} + compact={compact} + /> )); return ( <> diff --git a/src/Table/TableFoot.tsx b/src/Table/TableFoot.tsx index 99d56c086..832681981 100644 --- a/src/Table/TableFoot.tsx +++ b/src/Table/TableFoot.tsx @@ -3,7 +3,7 @@ import PropTypes from "prop-types"; import styled from "styled-components"; import TableCell from "./TableCell"; import StyledTh from "./StyledTh"; -import { columnsPropType, rowsPropType, rowPropType } from "./Table.types"; +import { columnsPropType, rowsPropType, rowPropType, ColumnType, RowType } from "./Table.types"; const StyledFooterRow = styled.tr(({ theme }) => ({ "&:first-of-type": { @@ -31,7 +31,7 @@ const TableFooterRow = ({ row, columns, loading, compact }) => { ) : ( !loading && ( <TableCell - key={column.dataKey} + key={column.dataKey ?? column.key ?? index} row={row} column={{ dataKey: column.dataKey, @@ -55,9 +55,19 @@ TableFooterRow.propTypes = { compact: PropTypes.bool.isRequired, }; -const TableFoot = ({ columns, rows, keyField, loading, compact }) => ( - <tfoot>{renderRows(rows, columns, keyField, loading, compact)}</tfoot> -); +const TableFoot = ({ + columns, + rows, + keyField, + loading, + compact, +}: { + columns: ColumnType[]; + rows: RowType[]; + keyField?: string; + loading?: boolean; + compact?: boolean; +}) => <tfoot>{renderRows(rows, columns, keyField, loading, compact)}</tfoot>; TableFoot.propTypes = { columns: columnsPropType.isRequired, diff --git a/src/Table/TableHead.tsx b/src/Table/TableHead.tsx index d492764c7..c8cd4063b 100644 --- a/src/Table/TableHead.tsx +++ b/src/Table/TableHead.tsx @@ -23,7 +23,7 @@ const TableHead: React.FC<TableHeadProps> = ({ columns, compact, sticky }) => { allColumns.map((column) => ( <StyledTh scope="col" - key={column.dataKey} + key={column.dataKey ?? column.key ?? index} width={column.width} compact={compact} data-testid="table-head"