From 21b3c22e5c673623e8245a528828afa721755e02 Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Sat, 2 Aug 2025 23:38:48 -0600 Subject: [PATCH] pass generics onto the components themselves --- .../BusterInfiniteList/BusterInfiniteList.tsx | 7 +- .../ui/list/BusterList/BusterListHeader.tsx | 130 ++++++------- .../BusterList/BusterListRowComponent.tsx | 181 +++++++++--------- .../BusterListRowComponentSelector.tsx | 131 ++++++------- .../ui/list/BusterList/BusterListVirtua.tsx | 7 +- 5 files changed, 221 insertions(+), 235 deletions(-) diff --git a/apps/web/src/components/ui/list/BusterInfiniteList/BusterInfiniteList.tsx b/apps/web/src/components/ui/list/BusterInfiniteList/BusterInfiniteList.tsx index acf4e5531..1e327a7ec 100644 --- a/apps/web/src/components/ui/list/BusterInfiniteList/BusterInfiniteList.tsx +++ b/apps/web/src/components/ui/list/BusterInfiniteList/BusterInfiniteList.tsx @@ -29,9 +29,6 @@ function BusterInfiniteListComponent({ rowClassName = '', scrollEndThreshold = 48 // Default threshold of 200px }: BusterInfiniteListProps) { - const Header = BusterListHeader(); - const RowSelector = BusterListRowComponentSelector(); - const containerRef = useRef(null); const scrollRef = useRef(null); const lastChildIndex = useMemo(() => { @@ -139,7 +136,7 @@ function BusterInfiniteListComponent({ return (
{showHeader && !showEmptyState && ( -
columns={columns} onGlobalSelectChange={onSelectChange ? onGlobalSelectChange : undefined} globalCheckStatus={globalCheckStatus} @@ -153,7 +150,7 @@ function BusterInfiniteListComponent({ rows .filter((row) => !row.hidden) .map((row, index) => ( - key={row.id} row={row} id={row.id} diff --git a/apps/web/src/components/ui/list/BusterList/BusterListHeader.tsx b/apps/web/src/components/ui/list/BusterList/BusterListHeader.tsx index ae837f21c..a84241e28 100644 --- a/apps/web/src/components/ui/list/BusterList/BusterListHeader.tsx +++ b/apps/web/src/components/ui/list/BusterList/BusterListHeader.tsx @@ -5,70 +5,70 @@ import { CheckboxColumn } from './CheckboxColumn'; import { HEIGHT_OF_HEADER } from './config'; import type { BusterListColumn } from './interfaces'; -export const BusterListHeader = - (): React.FC<{ - columns: BusterListColumn[]; - onGlobalSelectChange?: (v: boolean) => void; - globalCheckStatus?: 'checked' | 'unchecked' | 'indeterminate'; - showSelectAll?: boolean; - rowsLength: number; - rowClassName: string; - }> => - ({ - columns, - rowClassName, - showSelectAll = true, - onGlobalSelectChange, - globalCheckStatus, - rowsLength - }) => { - const showCheckboxColumn = !!onGlobalSelectChange; - const showGlobalCheckbox = - globalCheckStatus === 'indeterminate' || globalCheckStatus === 'checked'; +interface BusterListHeaderProps { + columns: BusterListColumn[]; + onGlobalSelectChange?: (v: boolean) => void; + globalCheckStatus?: 'checked' | 'unchecked' | 'indeterminate'; + showSelectAll?: boolean; + rowsLength: number; + rowClassName: string; +} - return ( -
- {showCheckboxColumn && ( - - )} +export const BusterListHeader = ({ + columns, + rowClassName, + showSelectAll = true, + onGlobalSelectChange, + globalCheckStatus, + rowsLength +}: BusterListHeaderProps) => { + const showCheckboxColumn = !!onGlobalSelectChange; + const showGlobalCheckbox = + globalCheckStatus === 'indeterminate' || globalCheckStatus === 'checked'; - {columns.map((column, index) => ( -
- {column.headerRender ? ( - column.headerRender(column.title) - ) : ( - - {column.title} - - )} -
- ))} -
- ); - }; + return ( +
+ {showCheckboxColumn && ( + + )} + + {columns.map((column, index) => ( +
+ {column.headerRender ? ( + column.headerRender(column.title) + ) : ( + + {column.title} + + )} +
+ ))} +
+ ); +}; diff --git a/apps/web/src/components/ui/list/BusterList/BusterListRowComponent.tsx b/apps/web/src/components/ui/list/BusterList/BusterListRowComponent.tsx index d5a07b443..af35f33c0 100644 --- a/apps/web/src/components/ui/list/BusterList/BusterListRowComponent.tsx +++ b/apps/web/src/components/ui/list/BusterList/BusterListRowComponent.tsx @@ -12,104 +12,101 @@ import type { BusterListRowItem } from './interfaces'; -export const BusterListRowComponent = () => - React.memo( - React.forwardRef< - HTMLDivElement, +interface BusterListRowComponentProps { + row: BusterListRow; + columns: BusterListColumn[]; + checked: boolean; + onSelectChange?: (v: boolean, id: string, e: React.MouseEvent) => void; + onContextMenuClick?: (e: React.MouseEvent, id: string) => void; + style?: React.CSSProperties; + hideLastRowBorder: NonNullable; + useRowClickSelectChange: boolean; + rowClassName?: string; + isLastChild: boolean; +} + +export const BusterListRowComponent = React.memo( + React.forwardRef( + ( { - row: BusterListRow; - columns: BusterListColumn[]; - checked: boolean; - onSelectChange?: (v: boolean, id: string, e: React.MouseEvent) => void; - onContextMenuClick?: (e: React.MouseEvent, id: string) => void; - style?: React.CSSProperties; - hideLastRowBorder: NonNullable; - useRowClickSelectChange: boolean; - rowClassName?: string; - isLastChild: boolean; - } - >( - ( - { - style, - hideLastRowBorder, - row, - columns, - onSelectChange, - checked, - onContextMenuClick, - rowClassName = '', - isLastChild, - useRowClickSelectChange - }, - ref - ) => { - const link = row.link; + style, + hideLastRowBorder, + row, + columns, + onSelectChange, + checked, + onContextMenuClick, + rowClassName = '', + isLastChild, + useRowClickSelectChange + }: BusterListRowComponentProps, + ref: React.ForwardedRef + ) => { + const link = row.link; - const onContextMenu = useMemoizedFn((e: React.MouseEvent) => { - onContextMenuClick?.(e, row.id); - }); + const onContextMenu = useMemoizedFn((e: React.MouseEvent) => { + onContextMenuClick?.(e, row.id); + }); - const onChange = useMemoizedFn((newChecked: boolean, e: React.MouseEvent) => { - onSelectChange?.(newChecked, row.id, e); - }); + const onChange = useMemoizedFn((newChecked: boolean, e: React.MouseEvent) => { + onSelectChange?.(newChecked, row.id, e); + }); - const onContainerClick = useMemoizedFn((e: React.MouseEvent) => { - if (useRowClickSelectChange) { - onChange(!checked, e); - } - row.onClick?.(); - }); + const onContainerClick = useMemoizedFn((e: React.MouseEvent) => { + if (useRowClickSelectChange) { + onChange(!checked, e); + } + row.onClick?.(); + }); - const rowStyles = { - height: `${HEIGHT_OF_ROW}px`, - minHeight: `${HEIGHT_OF_ROW}px`, - ...style - }; + const rowStyles = { + height: `${HEIGHT_OF_ROW}px`, + minHeight: `${HEIGHT_OF_ROW}px`, + ...style + }; - return ( - -
- {onSelectChange ? ( - - ) : null} - {columns.map((column, columnIndex) => ( - - ))} -
-
- ); - } - ) - ); + return ( + +
+ {onSelectChange ? ( + + ) : null} + {columns.map((column, columnIndex) => ( + + ))} +
+
+ ); + } + ) +) as any as ( + props: BusterListRowComponentProps & React.RefAttributes +) => React.ReactElement | null; const BusterListCellComponent: React.FC<{ data: string | number | React.ReactNode; diff --git a/apps/web/src/components/ui/list/BusterList/BusterListRowComponentSelector.tsx b/apps/web/src/components/ui/list/BusterList/BusterListRowComponentSelector.tsx index 2ae98bdeb..1e4d0bac9 100644 --- a/apps/web/src/components/ui/list/BusterList/BusterListRowComponentSelector.tsx +++ b/apps/web/src/components/ui/list/BusterList/BusterListRowComponentSelector.tsx @@ -3,80 +3,75 @@ import { BusterListRowComponent } from './BusterListRowComponent'; import { BusterListSectionComponent } from './BusterListSectionComponent'; import type { BusterListColumn, BusterListProps, BusterListRow } from './interfaces'; -export const BusterListRowComponentSelector = () => { - // const RowComponent = BusterListRowComponent(); +interface BusterListRowComponentSelectorProps { + row: BusterListRow; + columns: BusterListColumn[]; + id: string; + onSelectChange?: (v: boolean, id: string, e: React.MouseEvent) => void; + onSelectSectionChange?: (v: boolean, id: string) => void; + onContextMenuClick?: (e: React.MouseEvent, id: string) => void; + selectedRowKeys?: string[]; + rows: BusterListRow[]; + style?: React.CSSProperties; + hideLastRowBorder: NonNullable; + rowClassName?: string; + isLastChild: boolean; + useRowClickSelectChange?: boolean; +} - return React.forwardRef< - HTMLDivElement, +export const BusterListRowComponentSelector = React.forwardRef( + ( { - row: BusterListRow; - columns: BusterListColumn[]; - id: string; - onSelectChange?: (v: boolean, id: string, e: React.MouseEvent) => void; - onSelectSectionChange?: (v: boolean, id: string) => void; - onContextMenuClick?: (e: React.MouseEvent, id: string) => void; - selectedRowKeys?: string[]; - rows: BusterListRow[]; - style?: React.CSSProperties; - hideLastRowBorder: NonNullable; - rowClassName?: string; - isLastChild: boolean; - useRowClickSelectChange?: boolean; - } - >( - ( - { - style, - row, - rows, - columns, - isLastChild, - onSelectChange, - onSelectSectionChange, - selectedRowKeys, - onContextMenuClick, - hideLastRowBorder, - rowClassName, - useRowClickSelectChange = false - }, - ref - ) => { - if (row.hidden) return null; - - if (row.rowSection) { - return ( - - ); - } - - const RowComponent = BusterListRowComponent(); + style, + row, + rows, + columns, + isLastChild, + onSelectChange, + onSelectSectionChange, + selectedRowKeys, + onContextMenuClick, + hideLastRowBorder, + rowClassName, + useRowClickSelectChange = false + }: BusterListRowComponentSelectorProps, + ref: React.ForwardedRef + ) => { + if (row.hidden) return null; + if (row.rowSection) { return ( - ); } - ); -}; + + return ( + + style={style} + row={row} + columns={columns} + key={row.id} + rowClassName={rowClassName} + onSelectChange={onSelectChange} + checked={!!selectedRowKeys?.includes(row.id)} + ref={ref} + onContextMenuClick={onContextMenuClick} + hideLastRowBorder={hideLastRowBorder} + useRowClickSelectChange={useRowClickSelectChange} + isLastChild={isLastChild} + /> + ); + } +) as any as ( + props: BusterListRowComponentSelectorProps & React.RefAttributes +) => React.ReactElement | null; diff --git a/apps/web/src/components/ui/list/BusterList/BusterListVirtua.tsx b/apps/web/src/components/ui/list/BusterList/BusterListVirtua.tsx index d022c1e9d..4909b3613 100644 --- a/apps/web/src/components/ui/list/BusterList/BusterListVirtua.tsx +++ b/apps/web/src/components/ui/list/BusterList/BusterListVirtua.tsx @@ -23,9 +23,6 @@ function BusterListVirtuaComponent({ rowClassName = '', hideLastRowBorder = false }: BusterListProps) { - const Header = BusterListHeader(); - const RowSelector = BusterListRowComponentSelector(); - const showEmptyState = (!rows || rows.length === 0) && !!emptyState; const lastChildIndex = rows.length - 1; const lastSelectedIdRef = useRef(null); @@ -126,7 +123,7 @@ function BusterListVirtuaComponent({
{showHeader && !showEmptyState && ( -
columns={columns} onGlobalSelectChange={onSelectChange ? onGlobalSelectChange : undefined} globalCheckStatus={globalCheckStatus} @@ -140,7 +137,7 @@ function BusterListVirtuaComponent({ {rows.map((row, index) => (
- row={row} id={row.id} isLastChild={index === lastChildIndex}