UNPKG

@voilajsx/uikit

Version:

Cross-platform React components with beautiful themes and OKLCH color science

83 lines (82 loc) 3.82 kB
import { jsxs, jsx } from "react/jsx-runtime"; import { forwardRef, useState } from "react"; import { Search, ArrowUpDown, ArrowUp, ArrowDown } from "lucide-react"; import { cn } from "./utils.js"; import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from "./table.js"; import "./button.js"; import { Input } from "./input.js"; const DataTable = forwardRef(({ className, columns = [], data = [], searchable = true, sortable = true, ...props }, ref) => { const [sorting, setSorting] = useState({ column: null, direction: null }); const [searchTerm, setSearchTerm] = useState(""); const filteredData = searchable ? data.filter( (row) => Object.values(row).some( (value) => String(value).toLowerCase().includes(searchTerm.toLowerCase()) ) ) : data; const sortedData = sortable && sorting.column ? [...filteredData].sort((a, b) => { const aVal = a[sorting.column]; const bVal = b[sorting.column]; if (aVal < bVal) return sorting.direction === "asc" ? -1 : 1; if (aVal > bVal) return sorting.direction === "asc" ? 1 : -1; return 0; }) : filteredData; const handleSort = (columnKey) => { if (!sortable) return; setSorting((prev) => { if (prev.column === columnKey) { if (prev.direction === "asc") return { column: columnKey, direction: "desc" }; if (prev.direction === "desc") return { column: null, direction: null }; } return { column: columnKey, direction: "asc" }; }); }; const getSortIcon = (columnKey) => { if (sorting.column !== columnKey) return /* @__PURE__ */ jsx(ArrowUpDown, { className: "ml-2 h-4 w-4" }); if (sorting.direction === "asc") return /* @__PURE__ */ jsx(ArrowUp, { className: "ml-2 h-4 w-4" }); if (sorting.direction === "desc") return /* @__PURE__ */ jsx(ArrowDown, { className: "ml-2 h-4 w-4" }); return /* @__PURE__ */ jsx(ArrowUpDown, { className: "ml-2 h-4 w-4" }); }; return /* @__PURE__ */ jsxs("div", { className: cn("w-full space-y-4", className), ref, ...props, children: [ searchable && /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [ /* @__PURE__ */ jsx(Search, { className: "h-4 w-4 text-muted-foreground" }), /* @__PURE__ */ jsx( Input, { placeholder: "Search...", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), className: "max-w-sm" } ) ] }), /* @__PURE__ */ jsx("div", { className: "rounded-md border", children: /* @__PURE__ */ jsxs(Table, { children: [ /* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsx(TableRow, { children: columns.map((column) => /* @__PURE__ */ jsx( TableHead, { className: cn( sortable && column.sortable !== false ? "cursor-pointer select-none" : "" ), onClick: () => column.sortable !== false && handleSort(column.key), children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [ column.title, sortable && column.sortable !== false && getSortIcon(column.key) ] }) }, column.key )) }) }), /* @__PURE__ */ jsx(TableBody, { children: sortedData.length === 0 ? /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: columns.length, className: "h-24 text-center", children: "No results." }) }) : sortedData.map((row, index) => /* @__PURE__ */ jsx(TableRow, { children: columns.map((column) => /* @__PURE__ */ jsx(TableCell, { children: column.render ? column.render(row[column.key], row) : row[column.key] }, column.key)) }, index)) }) ] }) }) ] }); }); DataTable.displayName = "DataTable"; export { DataTable }; //# sourceMappingURL=data-table.js.map