Data Table
thegridcn/data-tableFreeComponent
thegridcn publishes no description for this item.
See it running
Open the demo on thegridcn
thegridcn.com/r/data-tableInstall it
npx shadcn@latest add https://thegridcn.com/r/data-table.jsonSource
1"use client";23import * as React from "react";4import { cn } from "@/lib/utils";56interface DataTableColumn<T> {7 align?: "left" | "center" | "right";8 key: keyof T & string;9 label: string;10 render?: (value: T[keyof T], row: T) => React.ReactNode;11 sortable?: boolean;12}1314interface DataTableProps<T extends Record<string, unknown>>15 extends React.HTMLAttributes<HTMLDivElement> {16 columns: DataTableColumn<T>[];17 data: T[];18 label?: string;19 striped?: boolean;20}2122export function DataTable<T extends Record<string, unknown>>({23 columns,24 data,25 label,26 striped = true,27 className,28 ...props29}: DataTableProps<T>) {30 const [sortKey, setSortKey] = React.useState<string | null>(null);31 const [sortDir, setSortDir] = React.useState<"asc" | "desc">("asc");3233 function handleSort(key: string) {34 if (sortKey === key) {35 setSortDir((d) => (d === "asc" ? "desc" : "asc"));36 } else {37 setSortKey(key);38 setSortDir("asc");39 }40 }4142 const sortedData = React.useMemo(() => {43 if (!sortKey) {44 return data;45 }46 return [...data].sort((a, b) => {47 const aVal = a[sortKey];48 const bVal = b[sortKey];49 if (50 aVal === null ||51 aVal === undefined ||52 bVal === null ||53 bVal === undefined54 ) {55 return 0;56 }57 const cmp = aVal < bVal ? -1 : aVal > bVal ? 1 : 0;58 return sortDir === "asc" ? cmp : -cmp;59 });60 }, [data, sortKey, sortDir]);6162 // Stagger row reveal63 const [revealedRow, setRevealedRow] = React.useState(-1);64 React.useEffect(() => {65 let row = 0;66 const interval = setInterval(() => {67 setRevealedRow(row);68 row++;69 if (row >= sortedData.length) {70 clearInterval(interval);71 }72 }, 40);73 return () => clearInterval(interval);74 }, [sortedData.length]);7576 const alignClass = (align?: string) =>77 align === "center"78 ? "text-center"79 : align === "right"80 ? "text-right"81 : "text-left";8283 return (84 <div85 data-slot="tron-data-table"86 className={cn(87 "relative overflow-hidden rounded border border-primary/30 bg-card/80 backdrop-blur-sm",88 className89 )}90 {...props}91 >92 <div className="pointer-events-none absolute inset-0 bg-[repeating-linear-gradient(0deg,transparent,transparent_2px,rgba(0,0,0,0.03)_2px,rgba(0,0,0,0.03)_4px)]" />9394 {label ? (95// … truncated
Files it writes
More from thegridcn
All 139 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | thegridcn | Components | Free | 2 deps | |
| Agent Avataragent-avatar | thegridcn | Components | Free | no deps | |
| Alertalert | thegridcn | Components | Free | 1 dep | |
| Alert Dialogalert-dialog | thegridcn | Components | Free | 1 dep | |
| Announcement Barannouncement-bar | thegridcn | Components | Free | no deps | |
| Anomaly Banneranomaly-banner | thegridcn | Components | Free | no deps | |
| Arrival Panelarrival-panel | thegridcn | Components | Free | no deps | |
| Aspect Ratioaspect-ratio | thegridcn | Components | Free | 1 dep |
