import { Table as NativeTable, Row } from "react-native-reanimated-table"; import { Pressable, ScrollView, Text, View } from "react-native"; import { styles } from "@/styles/components/table"; import { MaterialIcons } from "@expo/vector-icons"; import { useState, type ReactNode } from "react"; type HeaderRow = { row: ReactNode; sortable?: boolean; searchable?: boolean; id?: string; }; interface RowSort { [key: string]: "asc" | "desc" | null; } interface Props { headerRow: Array; rows: Array>; rowWidth: Array; sortKey?: { id: string; sortOrder: "asc" | "desc"; }; onSortOrderChange?: ( sortKey: string, sortOrder: "asc" | "desc", ) => Promise | void; onSearch?: (searchKey: string) => Promise | void; } export default function Table({ headerRow, rows, rowWidth, sortKey, onSearch = () => {}, onSortOrderChange = () => {}, }: Props) { const defaultSortOrders: RowSort = {}; for (const row of headerRow) { if (!row.id) continue; defaultSortOrders[row.id] = null; } if (sortKey) defaultSortOrders[sortKey.id] = sortKey.sortOrder; const [sortOrders, setSortOrders] = useState(defaultSortOrders); const updatedHeaderRow = headerRow.map((row) => { if (!row.id || (!row.searchable && !row.sortable)) return row.row; const sortIcon = getSortIcon(sortOrders[row.id]); return ( { if (!row.id) return; const sortOrder = sortOrders[row.id] === "asc" ? "desc" : "asc"; setSortOrders((prev) => { if (!row.id) return prev; const previous = Object.keys(prev).reduce((acc, key) => { acc[key as string] = null; return acc; }, {} as RowSort); return { ...previous, [row.id]: sortOrder, }; }); onSortOrderChange(row.id, sortOrder); }} style={styles.rowContainer} > {["string", "number", "boolean"].includes(typeof row.row) ? ( {row.row} ) : ( row.row )} {row.sortable && ( )} {row.searchable && row.id && ( { if (row.id) return onSearch(row.id); }} > )} ); }); function getSortIcon( order: "asc" | "desc" | null, ): keyof typeof MaterialIcons.glyphMap { switch (order) { case "asc": return "north"; case "desc": return "south"; default: return "sort"; } } return ( {rows.map((row, index) => { let rowStyle = styles.row; if (index === 0) rowStyle = { ...styles.row, ...styles.firstRow, }; if (index === rows.length - 1) rowStyle = { ...styles.row, ...styles.lastRow, }; return ( ); })} ); }