|
|
|
@@ -24,6 +24,7 @@ export function DataTable<T extends { id: string }>({
|
|
|
|
rowAccent,
|
|
|
|
rowAccent,
|
|
|
|
expandedContent,
|
|
|
|
expandedContent,
|
|
|
|
flush = false,
|
|
|
|
flush = false,
|
|
|
|
|
|
|
|
onSortChange,
|
|
|
|
}: DataTableProps<T>) {
|
|
|
|
}: DataTableProps<T>) {
|
|
|
|
const [sortKey, setSortKey] = useState<string | null>(null)
|
|
|
|
const [sortKey, setSortKey] = useState<string | null>(null)
|
|
|
|
const [sortDir, setSortDir] = useState<SortDir>('asc')
|
|
|
|
const [sortDir, setSortDir] = useState<SortDir>('asc')
|
|
|
|
@@ -31,14 +32,16 @@ export function DataTable<T extends { id: string }>({
|
|
|
|
const [pageSize, setPageSize] = useState(initialPageSize)
|
|
|
|
const [pageSize, setPageSize] = useState(initialPageSize)
|
|
|
|
const [expandedId, setExpandedId] = useState<string | null>(null)
|
|
|
|
const [expandedId, setExpandedId] = useState<string | null>(null)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// When onSortChange is provided (controlled mode), skip client-side sorting
|
|
|
|
const sorted = useMemo(() => {
|
|
|
|
const sorted = useMemo(() => {
|
|
|
|
|
|
|
|
if (onSortChange) return data
|
|
|
|
if (!sortKey) return data
|
|
|
|
if (!sortKey) return data
|
|
|
|
return [...data].sort((a, b) => {
|
|
|
|
return [...data].sort((a, b) => {
|
|
|
|
const av = (a as Record<string, unknown>)[sortKey]
|
|
|
|
const av = (a as Record<string, unknown>)[sortKey]
|
|
|
|
const bv = (b as Record<string, unknown>)[sortKey]
|
|
|
|
const bv = (b as Record<string, unknown>)[sortKey]
|
|
|
|
return compareValues(av, bv, sortDir)
|
|
|
|
return compareValues(av, bv, sortDir)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}, [data, sortKey, sortDir])
|
|
|
|
}, [data, sortKey, sortDir, onSortChange])
|
|
|
|
|
|
|
|
|
|
|
|
const totalRows = sorted.length
|
|
|
|
const totalRows = sorted.length
|
|
|
|
const totalPages = Math.max(1, Math.ceil(totalRows / pageSize))
|
|
|
|
const totalPages = Math.max(1, Math.ceil(totalRows / pageSize))
|
|
|
|
@@ -52,13 +55,17 @@ export function DataTable<T extends { id: string }>({
|
|
|
|
|
|
|
|
|
|
|
|
function handleHeaderClick(col: Column<T>) {
|
|
|
|
function handleHeaderClick(col: Column<T>) {
|
|
|
|
if (!sortable && !col.sortable) return
|
|
|
|
if (!sortable && !col.sortable) return
|
|
|
|
|
|
|
|
let newDir: SortDir
|
|
|
|
if (sortKey === col.key) {
|
|
|
|
if (sortKey === col.key) {
|
|
|
|
setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'))
|
|
|
|
newDir = sortDir === 'asc' ? 'desc' : 'asc'
|
|
|
|
|
|
|
|
setSortDir(newDir)
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
|
|
|
|
newDir = 'asc'
|
|
|
|
setSortKey(col.key)
|
|
|
|
setSortKey(col.key)
|
|
|
|
setSortDir('asc')
|
|
|
|
setSortDir(newDir)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setPage(1)
|
|
|
|
setPage(1)
|
|
|
|
|
|
|
|
onSortChange?.(col.key, newDir)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function handleRowClick(row: T) {
|
|
|
|
function handleRowClick(row: T) {
|
|
|
|
|