diff --git a/packages/react/src/components/table/table.test.tsx b/packages/react/src/components/table/table.test.tsx index fe96165c8..90b9d23e5 100644 --- a/packages/react/src/components/table/table.test.tsx +++ b/packages/react/src/components/table/table.test.tsx @@ -188,7 +188,7 @@ describe('Table', () => { const callback = jest.fn(); const wrapper = mountWithTheme( { mountWithTheme(
{ const callback = jest.fn(); const wrapper = mountWithTheme(
{ const callback = jest.fn(); const wrapper = mountWithTheme(
{ }); test('has selectable rows styles', () => { - const tree = renderWithProviders(
); + const tree = renderWithProviders(
); expect(tree).toMatchSnapshot(); }); @@ -347,4 +347,20 @@ describe('Table', () => { expect(tree).toMatchSnapshot(); }); + + test('has radio buttons in single selection mode', () => { + const callback = jest.fn(); + const wrapper = mountWithTheme( +
, + ); + + expect(getByTestId(wrapper, 'row-radiobutton-0') + .find('input') + .prop('type')).toBe('radio'); + }); }); diff --git a/packages/react/src/components/table/table.tsx b/packages/react/src/components/table/table.tsx index d978c294c..815fa5d10 100644 --- a/packages/react/src/components/table/table.tsx +++ b/packages/react/src/components/table/table.tsx @@ -28,6 +28,8 @@ type RowSize = 'small' | 'medium'; type UtilityColumnType = 'selection' | 'numbers' | 'expand'; +type SelectionMode = 'single' | 'multiple'; + function getThPadding(device: DeviceType, rowSize?: RowSize): string { if (rowSize === 'small') { switch (device) { @@ -140,7 +142,16 @@ const ExpandButton = styled(IconButton) <{ $expanded: boolean }>` } `; -function getUtilityColumn(type: UtilityColumnType, t: TFunction<'translation'>): TableColumn { +const RadioButton = styled.input` + margin: 3px 3px 3px 5px; + vertical-align: inherit; +`; + +function getUtilityColumn( + type: UtilityColumnType, + t: TFunction<'translation'>, + selectionMode?: SelectionMode, +): TableColumn { const column: TableColumn = { id: type, className: utilColumnClassName, @@ -148,23 +159,38 @@ function getUtilityColumn(type: UtilityColumnType, t: TFunctio switch (type) { case 'selection': - column.header = ({ table }) => ( - - ); - column.cell = ({ row }) => ( - - ); + if (selectionMode === 'multiple') { + column.header = ({ table }) => ( + + ); + column.cell = ({ row }) => ( + + ); + } else if (selectionMode === 'single') { + column.cell = ({ table, row }) => ( + { + table.toggleAllRowsSelected(false); + }} + /> + ); + } break; case 'numbers': @@ -214,7 +240,7 @@ export interface TableProps { * @default medium */ rowSize?: RowSize; - selectableRows?: boolean; + selectionMode?: SelectionMode; /** * Adds striped rows * @default false @@ -239,7 +265,7 @@ export const Table = ({ stickyFooter = false, rowNumbers = false, rowSize = 'medium', - selectableRows, + selectionMode, striped = false, manualSort = false, onRowClick, @@ -257,8 +283,8 @@ export const Table = ({ const columns = useMemo(() => { const cols = [...providedColumns]; - if (selectableRows) { - cols.unshift(getUtilityColumn('selection', t)); + if (selectionMode) { + cols.unshift(getUtilityColumn('selection', t, selectionMode)); } else if (expandableRows) { cols.unshift(getUtilityColumn('expand', t)); } else if (rowNumbers) { @@ -266,7 +292,7 @@ export const Table = ({ } return cols; - }, [selectableRows, expandableRows, rowNumbers, providedColumns, t]); + }, [selectionMode, expandableRows, rowNumbers, providedColumns, t]); const tableOptions: TableOptions = { data, @@ -311,13 +337,13 @@ export const Table = ({ const currentRowSelection = table.getState().rowSelection; useEffect(() => { - if (selectableRows && onSelectedRowsChange) { + if (selectionMode && onSelectedRowsChange) { const selectedRowIds = currentRowSelection; const selectedIndexes = Object.keys(selectedRowIds).filter((index) => selectedRowIds[index]); const selectedRows = selectedIndexes.map((index) => data[parseInt(index, 10)]); onSelectedRowsChange(selectedRows); } - }, [selectableRows, currentRowSelection, onSelectedRowsChange, data]); + }, [selectionMode, currentRowSelection, onSelectedRowsChange, data]); return ( { ); }; -export const SelectableRows: Story = () => { +export const MultipleSelectableRows: Story = () => { interface SelectableData { column1: string; column2: string; @@ -569,7 +569,46 @@ export const SelectableRows: Story = () => { }, ]; return ( -
+
+ ); +}; + +export const SingleSelectableRows: Story = () => { + interface SelectableData { + column1: string; + column2: string; + column3: number; + } + + const columns: TableColumn[] = [ + { + header: 'Column 1', + accessorKey: 'column1', + }, + { + header: 'Column 2', + accessorKey: 'column2', + }, + { + header: 'Column 3', + accessorKey: 'column3', + }, + ]; + + const data: TableData[] = [ + { + column1: 'a', + column2: 'a', + column3: 10, + }, + { + column1: 'b', + column2: 'b', + column3: 20, + }, + ]; + return ( +
); }; @@ -1236,7 +1275,7 @@ export const WithBackgroundColor: Story = () => { return (