/** biome-ignore-all lint/correctness/useHookAtTopLevel: False positive because of the way forwardRef() is added */ import React, { forwardRef, useState } from "react"; import { CheckboxInput } from "../../../form/checkbox/checkbox-input/CheckboxInput"; import { RadioInput } from "../../../form/radio/radio-input/RadioInput"; import { cl } from "../../../utils/helpers"; import { useMergeRefs } from "../../../utils/hooks"; import { useTableKeyboardNav } from "../hooks/useTableKeyboardNav"; import { type SelectionProps, useTableSelection, } from "../hooks/useTableSelection"; import { DataTableTbody } from "../tbody/DataTableTbody"; import { DataTableTd } from "../td/DataTableTd"; import { DataTableTh } from "../th/DataTableTh"; import { DataTableThead } from "../thead/DataTableThead"; import { DataTableTr } from "../tr/DataTableTr"; import type { ColumnDefinitions } from "./DataTable.types"; import { DataTableContextProvider } from "./DataTableRoot.context"; interface DataTableProps extends React.HTMLAttributes, SelectionProps { children?: never; /** * Controls vertical cell padding. * @default "normal" */ rowDensity?: "condensed" | "normal" | "spacious"; /** * Zebra striped table * @default false */ zebraStripes?: boolean; /** * Truncate content in cells and show ellipsis for overflowed text. * * **NB:** When using `layout="auto"`, you have to manually set a `maxWidth` on columns that should be truncated. * @default true */ truncateContent?: boolean; // TODO: Consider making this default false when layout=auto, and maybe disallow it but add a wrap prop on the td-comp. /** * Enables keyboard navigation for table rows and cells. * @default false */ withKeyboardNav?: boolean; /** * Custom callback to determine if navigation should be blocked. * Called before default blocking logic. * Requires `withKeyboardNav` to be `true`. */ shouldBlockNavigation?: (event: KeyboardEvent) => boolean; /** * Controls table layout. * * ### fixed * Gives you full control of column widths. This is required for resizable columns. * * ### auto * Makes the columns resize automatically based on the content. * The table will take up at least 100% of available width. * * **NB:** When using this with `truncateContent`, you have to manually * set a `contentMaxWidth` on cells that should be truncated. * @default "fixed" */ layout?: "fixed" | "auto"; /** * */ columnDefinitions: ColumnDefinitions; data: T[]; getRowId?: (rowData: T, index: number) => string | number; } function DataTableAutoInner( { className, rowDensity = "normal", withKeyboardNav = false, zebraStripes = false, truncateContent = true, shouldBlockNavigation, layout = "fixed", selectionMode: selectionModeProp = "none", selectedKeys, defaultSelectedKeys, onSelectionChange, disabledKeys = [], data, columnDefinitions, getRowId, ...rest }: DataTableProps, forwardedRef: React.ForwardedRef, ) { const [tableRef, setTableRef] = useState(null); const mergedRef = useMergeRefs(forwardedRef, setTableRef); const { tabIndex } = useTableKeyboardNav(tableRef, { enabled: withKeyboardNav, shouldBlockNavigation, }); const resolvedGetRowId = getRowId ?? (((_row: T, index: number) => index) as (rowData: T) => string | number); const selection = useTableSelection({ selectionMode: selectionModeProp, selectedKeys, defaultSelectedKeys, onSelectionChange, disabledKeys, data, getRowId: resolvedGetRowId, }); return (
{selection.selectionMode === "multiple" && ( )} {selection.selectionMode === "single" && ( )} {columnDefinitions.map((colDef, colDefIndex) => { return ( {colDef.header} ); })} {data.map((rowData, rowIndex) => { const rowId = selection.allKeys[rowIndex]; return ( {selection.selectionMode === "multiple" && ( )} {selection.selectionMode === "single" && ( {/* used with keyboard nav is funky, no longer auto-selects on keyboard-nav. Probably preventDefault somewhere breaking it. */} )} {columnDefinitions.map((colDef, colDefIndex) => { return ( {colDef.cell(rowData)} ); })} ); })}
); } const DataTableAuto = forwardRef(DataTableAutoInner) as ( props: DataTableProps & React.RefAttributes, ) => React.ReactElement | null; export { DataTableAuto }; export type { DataTableProps }; export default DataTableAuto;