Skip to content

Commit

Permalink
feat(mantine): add getRowAttributes prop on table (#3719)
Browse files Browse the repository at this point in the history
  • Loading branch information
gdostie committed May 14, 2024
1 parent 9ecc38b commit e7bee4f
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 11 deletions.
3 changes: 3 additions & 0 deletions packages/mantine/src/components/table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export const Table = <T,>(props: TableProps<T> & {ref?: ForwardedRef<HTMLDivElem
store,
data,
getRowId,
getRowAttributes,
getExpandChildren,
columns,
layouts,
Expand Down Expand Up @@ -233,6 +234,7 @@ export const Table = <T,>(props: TableProps<T> & {ref?: ForwardedRef<HTMLDivElem
doubleClickAction={doubleClickAction}
getExpandChildren={getExpandChildren}
loading={loading}
getRowAttributes={getRowAttributes}
{...layoutProps}
/>
</thead>
Expand All @@ -242,6 +244,7 @@ export const Table = <T,>(props: TableProps<T> & {ref?: ForwardedRef<HTMLDivElem
doubleClickAction={doubleClickAction}
getExpandChildren={getExpandChildren}
loading={loading}
getRowAttributes={getRowAttributes}
{...layoutProps}
/>
) : (
Expand Down
8 changes: 8 additions & 0 deletions packages/mantine/src/components/table/Table.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export interface TableLayoutProps<TData = unknown> {
* @param datum the row for which the children should be generated.
*/
getExpandChildren?: (datum: TData) => ReactNode;
/**
* Function that can be used to add additional attributes on rows
*/
getRowAttributes?: (datum: TData) => Record<string, unknown>;
}

export interface TableLayout {
Expand Down Expand Up @@ -55,6 +59,10 @@ export interface TableProps<TData> extends BoxProps, StylesApiProps<PlasmaTableF
* Defines how each row is uniquely identified. It is highly recommended that you specify this prop to an ID that makes sense.
*/
getRowId?: CoreOptions<TData>['getRowId'];
/**
* Allows to define html attributes that will be passed down to each row.
*/
getRowAttributes?: (row: TData) => Record<string, unknown>;
/**
* Columns to display in the table.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {Table} from '../../Table';
import {useTable} from '../../use-table';

describe('RowLayout', () => {
type RowData = {id: string; firstName: string; lastName?: string};
type RowData = {id: string; firstName: string; lastName?: string; disabled?: boolean};

const columnHelper = createColumnHelper<RowData>();
const columns: Array<ColumnDef<RowData>> = [
Expand Down Expand Up @@ -399,4 +399,38 @@ describe('RowLayout', () => {
});
});
});

it('passes down attributes given by getRowAttributes function to the row element', () => {
const customColumns: Array<ColumnDef<RowData>> = [
columnHelper.accessor('firstName', {
header: () => 'First Name',
cell: (info) => info.getValue().toUpperCase(),
enableSorting: false,
}),
columnHelper.accessor('lastName', {
header: () => 'Last Name',
cell: (info) => info.getValue().toUpperCase(),
enableSorting: false,
}),
];
const data: RowData[] = [
{id: '1', firstName: 'Alberto', lastName: 'Contador'},
{id: '2', firstName: 'Lance', lastName: 'Armstrong', disabled: true},
];
const Fixture = () => {
const store = useTable<RowData>();
return (
<Table
store={store}
data={data}
columns={customColumns}
getRowAttributes={({disabled}) => ({'data-disabled': disabled})}
/>
);
};
render(<Fixture />);

expect(screen.getByRole('row', {name: /alberto contador/i})).not.toHaveAttribute('data-disabled');
expect(screen.getByRole('row', {name: /lance armstrong/i})).toHaveAttribute('data-disabled');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,17 @@ const defaultProps: Partial<RowLayoutBodyProps<unknown>> = {};

export const RowLayoutBody = <T,>(props: RowLayoutBodyProps<T> & {ref?: ForwardedRef<HTMLTableRowElement>}) => {
const ctx = useRowLayout();
const {doubleClickAction, getExpandChildren, loading, classNames, className, styles, style, ...others} = useProps(
'RowLayoutBody',
defaultProps as RowLayoutBodyProps<T>,
props,
);
const {
doubleClickAction,
getExpandChildren,
loading,
classNames,
className,
styles,
style,
getRowAttributes,
...others
} = useProps('RowLayoutBody', defaultProps as RowLayoutBodyProps<T>, props);
const {table, store} = useTableContext<T>();
const toggleCollapsible = (el: HTMLTableRowElement) => {
const cell = el.children[el.children.length - 1] as HTMLTableCellElement;
Expand Down Expand Up @@ -63,6 +69,7 @@ export const RowLayoutBody = <T,>(props: RowLayoutBodyProps<T> & {ref?: Forwarde
aria-selected={isSelected}
data-testid={row.id}
{...ctx.getStyles('row', {classNames, className, styles, style})}
{...(getRowAttributes?.(row.original) ?? {})}
{...others}
>
{row.getVisibleCells().map((cell) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,17 @@ const defaultProps: Partial<RowLayoutHeaderProps<unknown>> = {};

export const RowLayoutHeader = <T,>(props: RowLayoutHeaderProps<T> & {ref?: ForwardedRef<HTMLTableRowElement>}) => {
const ctx = useRowLayout();
const {getExpandChildren, loading, doubleClickAction, className, style, classNames, styles, ...others} = useProps(
'RowLayoutHeader',
defaultProps as RowLayoutHeaderProps<T>,
props,
);
const {
getExpandChildren,
loading,
doubleClickAction,
className,
style,
classNames,
styles,
getRowAttributes,
...others
} = useProps('RowLayoutHeader', defaultProps as RowLayoutHeaderProps<T>, props);
const {table, store} = useTableContext<T>();

const headers = table.getHeaderGroups().map((headerGroup) => (
Expand Down

0 comments on commit e7bee4f

Please sign in to comment.