import React, { useState, useMemo, useCallback } from 'react'; import _ from 'lodash'; export interface Field { key: string; label: string; transform?: (value: string) => JSX.Element | string; } interface Props { items?: T[]; fields: Field[]; handleRowClick?: (item: T, index?: number) => void; } const sortLabels = { asc: '^', desc: 'v', }; const getItemField = (item: any, field: Field) => { const value = _.get(item, field.key); return field.transform ? field.transform(value) : value; }; const ListTable: React.FC = ({ items = [], fields, handleRowClick = () => {} }) => { const [sortBy, setSortBy] = useState(''); const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('asc'); const sortedItems = useMemo(() => { const result = _.sortBy(items, sortBy); if (sortOrder === 'asc') result.reverse(); return result; }, [items, sortBy, sortOrder]); const handleFieldClick = useCallback((field: Field) => { if (sortBy === field.key) setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc'); else setSortOrder('desc'); setSortBy(field.key); }, [sortBy, sortOrder]); if (!items.length) return
No data
; return ( {fields.map(field => ( ))} {sortedItems.map((item, index) => ( handleRowClick(item, index)} > {fields.map(field => ( ))} ))}
handleFieldClick(field)}> {field.label} {field.key === sortBy && sortLabels[sortOrder]}
{getItemField(item, field)}
); }; export default ListTable;