Skip to content

Commit

Permalink
feat(table): Wrap table components with forwardRef (#1239)
Browse files Browse the repository at this point in the history
* feat(table): wrap table components with forwardRef

* fix(table): use ComponentPropsWithRef instead of ComponentProps
  • Loading branch information
nigellima committed Jan 22, 2024
1 parent ee3749f commit 4a26a50
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 91 deletions.
46 changes: 18 additions & 28 deletions src/components/Table/Table.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import type { ComponentProps, FC } from 'react';
import { forwardRef, type ComponentPropsWithRef } from 'react';
import { twMerge } from 'tailwind-merge';
import { mergeDeep } from '../../helpers/merge-deep';
import { getTheme } from '../../theme-store';
Expand All @@ -25,40 +25,30 @@ export interface FlowbiteTableRootTheme {
wrapper: string;
}

export interface TableProps extends ComponentProps<'table'> {
export interface TableProps extends ComponentPropsWithRef<'table'> {
striped?: boolean;
hoverable?: boolean;
theme?: DeepPartial<FlowbiteTableTheme>;
}

const TableComponent: FC<TableProps> = ({
children,
className,
striped,
hoverable,
theme: customTheme = {},
...props
}) => {
const theme = mergeDeep(getTheme().table, customTheme);

return (
<div data-testid="table-element" className={twMerge(theme.root.wrapper)}>
<TableContext.Provider value={{ theme, striped, hoverable }}>
<div className={twMerge(theme.root.shadow, className)}></div>
<table className={twMerge(theme.root.base, className)} {...props}>
{children}
</table>
</TableContext.Provider>
</div>
);
};
const TableComponent = forwardRef<HTMLTableElement, TableProps>(
({ children, className, striped, hoverable, theme: customTheme = {}, ...props }, ref) => {
const theme = mergeDeep(getTheme().table, customTheme);

return (
<div data-testid="table-element" className={twMerge(theme.root.wrapper)}>
<TableContext.Provider value={{ theme, striped, hoverable }}>
<div className={twMerge(theme.root.shadow, className)}></div>
<table className={twMerge(theme.root.base, className)} {...props} ref={ref}>
{children}
</table>
</TableContext.Provider>
</div>
);
},
);

TableComponent.displayName = 'Table';
TableHead.displayName = 'Table.Head';
TableBody.displayName = 'Table.Body';
TableRow.displayName = 'Table.Row';
TableCell.displayName = 'Table.Cell';
TableHeadCell.displayName = 'Table.HeadCell';

export const Table = Object.assign(TableComponent, {
Head: TableHead,
Expand Down
29 changes: 16 additions & 13 deletions src/components/Table/TableBody.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import type { ComponentProps, FC } from 'react';
import { forwardRef, type ComponentPropsWithRef } from 'react';
import { twMerge } from 'tailwind-merge';
import { mergeDeep } from '../../helpers/merge-deep';
import type { DeepPartial } from '../../types';
Expand All @@ -13,20 +13,23 @@ export interface FlowbiteTableBodyTheme {
cell: FlowbiteTableCellTheme;
}

export interface TableBodyProps extends ComponentProps<'tbody'> {
export interface TableBodyProps extends ComponentPropsWithRef<'tbody'> {
theme?: DeepPartial<FlowbiteTableBodyTheme>;
}

export const TableBody: FC<TableBodyProps> = ({ children, className, theme: customTheme = {}, ...props }) => {
const { theme: rootTheme } = useTableContext();
export const TableBody = forwardRef<HTMLTableSectionElement, TableBodyProps>(
({ children, className, theme: customTheme = {}, ...props }, ref) => {
const { theme: rootTheme } = useTableContext();

const theme = mergeDeep(rootTheme.body, customTheme);
const theme = mergeDeep(rootTheme.body, customTheme);

return (
<TableBodyContext.Provider value={{ theme }}>
<tbody className={twMerge(theme.base, className)} {...props}>
{children}
</tbody>
</TableBodyContext.Provider>
);
};
return (
<TableBodyContext.Provider value={{ theme }}>
<tbody className={twMerge(theme.base, className)} ref={ref} {...props}>
{children}
</tbody>
</TableBodyContext.Provider>
);
},
);
TableBody.displayName = 'Table.Body';
25 changes: 14 additions & 11 deletions src/components/Table/TableCell.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import type { ComponentProps, FC } from 'react';
import { forwardRef, type ComponentPropsWithRef } from 'react';
import { twMerge } from 'tailwind-merge';
import { mergeDeep } from '../../helpers/merge-deep';
import type { DeepPartial } from '../../types';
Expand All @@ -10,18 +10,21 @@ export interface FlowbiteTableCellTheme {
base: string;
}

export interface TableCellProps extends ComponentProps<'td'> {
export interface TableCellProps extends ComponentPropsWithRef<'td'> {
theme?: DeepPartial<FlowbiteTableCellTheme>;
}

export const TableCell: FC<TableCellProps> = ({ children, className, theme: customTheme = {}, ...props }) => {
const { theme: bodyTheme } = useTableBodyContext();
export const TableCell = forwardRef<HTMLTableCellElement, TableCellProps>(
({ children, className, theme: customTheme = {}, ...props }, ref) => {
const { theme: bodyTheme } = useTableBodyContext();

const theme = mergeDeep(bodyTheme.cell, customTheme);
const theme = mergeDeep(bodyTheme.cell, customTheme);

return (
<td className={twMerge(theme.base, className)} {...props}>
{children}
</td>
);
};
return (
<td className={twMerge(theme.base, className)} ref={ref} {...props}>
{children}
</td>
);
},
);
TableCell.displayName = 'Table.Cell';
29 changes: 16 additions & 13 deletions src/components/Table/TableHead.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import type { ComponentProps, FC } from 'react';
import { forwardRef, type ComponentPropsWithRef } from 'react';
import { twMerge } from 'tailwind-merge';
import { mergeDeep } from '../../helpers/merge-deep';
import type { DeepPartial } from '../../types';
Expand All @@ -13,20 +13,23 @@ export interface FlowbiteTableHeadTheme {
cell: FlowbiteTableHeadCellTheme;
}

export interface TableHeadProps extends ComponentProps<'thead'> {
export interface TableHeadProps extends ComponentPropsWithRef<'thead'> {
theme?: DeepPartial<FlowbiteTableHeadTheme>;
}

export const TableHead: FC<TableHeadProps> = ({ children, className, theme: customTheme = {}, ...props }) => {
const { theme: rootTheme } = useTableContext();
export const TableHead = forwardRef<HTMLTableSectionElement, TableHeadProps>(
({ children, className, theme: customTheme = {}, ...props }, ref) => {
const { theme: rootTheme } = useTableContext();

const theme = mergeDeep(rootTheme.head, customTheme);
const theme = mergeDeep(rootTheme.head, customTheme);

return (
<TableHeadContext.Provider value={{ theme }}>
<thead className={twMerge(theme.base, className)} {...props}>
<tr>{children}</tr>
</thead>
</TableHeadContext.Provider>
);
};
return (
<TableHeadContext.Provider value={{ theme }}>
<thead className={twMerge(theme.base, className)} ref={ref} {...props}>
<tr>{children}</tr>
</thead>
</TableHeadContext.Provider>
);
},
);
TableHead.displayName = 'Table.Head';
25 changes: 14 additions & 11 deletions src/components/Table/TableHeadCell.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import type { ComponentProps, FC } from 'react';
import { forwardRef, type ComponentPropsWithRef } from 'react';
import { twMerge } from 'tailwind-merge';
import { mergeDeep } from '../../helpers/merge-deep';
import type { DeepPartial } from '../../types';
Expand All @@ -10,18 +10,21 @@ export interface FlowbiteTableHeadCellTheme {
base: string;
}

export interface TableHeadCellProps extends ComponentProps<'th'> {
export interface TableHeadCellProps extends ComponentPropsWithRef<'th'> {
theme?: DeepPartial<FlowbiteTableHeadCellTheme>;
}

export const TableHeadCell: FC<TableHeadCellProps> = ({ children, className, theme: customTheme = {}, ...props }) => {
const { theme: headTheme } = useTableHeadContext();
export const TableHeadCell = forwardRef<HTMLTableCellElement, TableHeadCellProps>(
({ children, className, theme: customTheme = {}, ...props }, ref) => {
const { theme: headTheme } = useTableHeadContext();

const theme = mergeDeep(headTheme.cell, customTheme);
const theme = mergeDeep(headTheme.cell, customTheme);

return (
<th className={twMerge(theme.base, className)} {...props}>
{children}
</th>
);
};
return (
<th className={twMerge(theme.base, className)} ref={ref} {...props}>
{children}
</th>
);
},
);
TableHeadCell.displayName = 'Table.HeadCell';
34 changes: 19 additions & 15 deletions src/components/Table/TableRow.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import type { ComponentProps, FC } from 'react';
import { forwardRef, type ComponentPropsWithRef } from 'react';
import { twMerge } from 'tailwind-merge';
import { mergeDeep } from '../../helpers/merge-deep';
import type { DeepPartial } from '../../types';
Expand All @@ -12,22 +12,26 @@ export interface FlowbiteTableRowTheme {
striped: string;
}

export interface TableRowProps extends ComponentProps<'tr'> {
export interface TableRowProps extends ComponentPropsWithRef<'tr'> {
theme?: DeepPartial<FlowbiteTableRowTheme>;
}

export const TableRow: FC<TableRowProps> = ({ children, className, theme: customTheme = {}, ...props }) => {
const { theme: rootTheme, hoverable, striped } = useTableContext();
export const TableRow = forwardRef<HTMLTableRowElement, TableRowProps>(
({ children, className, theme: customTheme = {}, ...props }, ref) => {
const { theme: rootTheme, hoverable, striped } = useTableContext();

const theme = mergeDeep(rootTheme.row, customTheme);
const theme = mergeDeep(rootTheme.row, customTheme);

return (
<tr
data-testid="table-row-element"
className={twMerge(theme.base, striped && theme.striped, hoverable && theme.hovered, className)}
{...props}
>
{children}
</tr>
);
};
return (
<tr
ref={ref}
data-testid="table-row-element"
className={twMerge(theme.base, striped && theme.striped, hoverable && theme.hovered, className)}
{...props}
>
{children}
</tr>
);
},
);
TableRow.displayName = 'Table.Row';

1 comment on commit 4a26a50

@vercel
Copy link

@vercel vercel bot commented on 4a26a50 Jan 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.