A component for displaying structured data in rows and columns.
| Employee ID | Name | Role | Salary |
|---|---|---|---|
| EMP001 | Amit Sharma | Frontend Developer | $80,000 |
| EMP002 | Priya Desai | UI/UX Designer | $72,000 |
| EMP003 | Rahul Verma | Backend Developer | $90,000 |
| EMP004 | Neha Patel | Project Manager | $110,000 |
| EMP005 | Karan Mehta | QA Engineer | $68,000 |
| Total Employees | 5 | ||
1import {
2 Table,
3 TableBody,
4 TableCaption,
5 TableCell,
6 TableFooter,
7 TableHead,
8 TableHeader,
9 TableRow,
10} from '@/components/ui/table'
11
12const employees = [
13 {
14 id: 'EMP001',
15 name: 'Amit Sharma',
16 role: 'Frontend Developer',
17 salary: '$80,000',
18 },
19 {
20 id: 'EMP002',
21 name: 'Priya Desai',
22 role: 'UI/UX Designer',
23 salary: '$72,000',
24 },
25 {
26 id: 'EMP003',
27 name: 'Rahul Verma',
28 role: 'Backend Developer',
29 salary: '$90,000',
30 },
31 {
32 id: 'EMP004',
33 name: 'Neha Patel',
34 role: 'Project Manager',
35 salary: '$110,000',
36 },
37 {
38 id: 'EMP005',
39 name: 'Karan Mehta',
40 role: 'QA Engineer',
41 salary: '$68,000',
42 },
43]
44
45export function TableDemo() {
46 return (
47 <Table>
48 <TableCaption>A summary of your company’s employees.</TableCaption>
49 <TableHeader>
50 <TableRow>
51 <TableHead className="w-[120px]">Employee ID</TableHead>
52 <TableHead>Name</TableHead>
53 <TableHead>Role</TableHead>
54 <TableHead className="text-right">Salary</TableHead>
55 </TableRow>
56 </TableHeader>
57 <TableBody>
58 {employees.map((emp) => (
59 <TableRow key={emp.id}>
60 <TableCell className="font-medium">{emp.id}</TableCell>
61 <TableCell>{emp.name}</TableCell>
62 <TableCell>{emp.role}</TableCell>
63 <TableCell className="text-right">
64 {emp.salary}
65 </TableCell>
66 </TableRow>
67 ))}
68 </TableBody>
69 <TableFooter>
70 <TableRow>
71 <TableCell colSpan={3}>Total Employees</TableCell>
72 <TableCell className="text-right">
73 {employees.length}
74 </TableCell>
75 </TableRow>
76 </TableFooter>
77 </Table>
78 )
79}
80Install the following dependencies:
| Product ID | Name | Category | Price | Action | |
|---|---|---|---|---|---|
| P-101 | Wireless Headphones | Electronics | $120.00 | ||
| P-102 | Office Chair | Furniture | $180.00 | ||
| P-103 | Smart Watch | Gadgets | $90.00 | ||
| P-104 | Running Shoes | Fashion | $75.00 | ||
| Total | $465.00 | ||||
1'use client'
2
3import { useState } from 'react'
4import { Pencil, Trash } from 'lucide-react'
5
6import { Button } from '@/components/ui/button'
7import { Checkbox } from '@/components/ui/checkbox'
8import {
9 Table,
10 TableBody,
11 TableCaption,
12 TableCell,
13 TableFooter,
14 TableHead,
15 TableHeader,
16 TableRow,
17} from '@/components/ui/table'
18
19const products = [
20 {
21 id: 'P-101',
22 name: 'Wireless Headphones',
23 category: 'Electronics',
24 price: '$120.00',
25 },
26 {
27 id: 'P-102',
28 name: 'Office Chair',
29 category: 'Furniture',
30 price: '$180.00',
31 },
32 {
33 id: 'P-103',
34 name: 'Smart Watch',
35 category: 'Gadgets',
36 price: '$90.00',
37 },
38 {
39 id: 'P-104',
40 name: 'Running Shoes',
41 category: 'Fashion',
42 price: '$75.00',
43 },
44]
45
46export function CustomTable() {
47 const [selected, setSelected] = useState<string[]>([])
48
49 const toggleRow = (id: string) => {
50 setSelected((prev) =>
51 prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id],
52 )
53 }
54
55 const toggleAll = () => {
56 if (selected.length === products.length) {
57 setSelected([])
58 } else {
59 setSelected(products.map((p) => p.id))
60 }
61 }
62
63 const isAllSelected = selected.length === products.length
64 const isIndeterminate =
65 selected.length > 0 && selected.length < products.length
66 return (
67 <Table className="custom-table overflow-hidden rounded-lg border">
68 <TableCaption className="text-secondary">
69 Product inventory overview.
70 </TableCaption>
71
72 <TableHeader className="bg-secondary">
73 <TableRow className="border-secondary">
74 <TableHead className="w-[50px] text-center text-white">
75 <Checkbox
76 className="data-[state=checked]:text-secondary data-[state=checked]:border-white data-[state=checked]:bg-white"
77 checked={isAllSelected}
78 onCheckedChange={toggleAll}
79 />
80 </TableHead>{' '}
81 <TableHead className="w-[120px] text-white">
82 Product ID
83 </TableHead>
84 <TableHead className="text-white">Name</TableHead>
85 <TableHead className="text-white">Category</TableHead>
86 <TableHead className="text-white">Price</TableHead>
87 <TableHead className="text-center text-white">
88 Action
89 </TableHead>
90 </TableRow>
91 </TableHeader>
92
93 <TableBody>
94 {products.map((item) => (
95 <TableRow
96 key={item.id}
97 className="hover:bg-secondary/30 bg-secondary/10 text-secondary transition-colors"
98 >
99 <TableCell className="text-center">
100 <Checkbox
101 className="data-[state=checked]:bg-secondary data-[state=checked]:border-secondary border-secondary data-[state=checked]:text-white"
102 checked={selected.includes(item.id)}
103 onCheckedChange={() => toggleRow(item.id)}
104 />
105 </TableCell>
106 <TableCell className="font-medium">{item.id}</TableCell>
107 <TableCell>{item.name}</TableCell>
108 <TableCell>{item.category}</TableCell>
109 <TableCell>{item.price}</TableCell>
110 <TableCell className="text-center">
111 <Button variant="ghost" size="sm">
112 <Pencil className="h-3 w-3" />
113 </Button>
114 <Button variant="ghost" size="sm">
115 <Trash className="text-danger h-3 w-3" />
116 </Button>
117 </TableCell>
118 </TableRow>
119 ))}
120 </TableBody>
121 <TableFooter className="bg-secondary">
122 <TableRow className="text-white">
123 <TableCell colSpan={3}>Total</TableCell>
124 <TableCell colSpan={3} className="text-right">
125 $465.00
126 </TableCell>
127 </TableRow>
128 </TableFooter>
129 </Table>
130 )
131}
132| Product ID | Product Name | Stock |
|---|---|---|
| PRD001 | Wireless Mouse | 120 |
| PRD002 | Mechanical Keyboard | 60 |
| PRD003 | Noise Cancelling Headphones | 35 |
| PRD004 | LED Monitor 24" | 18 |
| PRD005 | USB-C Hub | 200 |
| Total Products | 13 | |
1'use client'
2
3import * as React from 'react'
4
5import {
6 Pagination,
7 PaginationContent,
8 PaginationItem,
9 PaginationLink,
10 PaginationNext,
11 PaginationPrevious,
12} from '@/components/ui/pagination'
13import {
14 Table,
15 TableBody,
16 TableCaption,
17 TableCell,
18 TableFooter,
19 TableHead,
20 TableHeader,
21 TableRow,
22} from '@/components/ui/table'
23
24const products = [
25 { id: 'PRD001', name: 'Wireless Mouse', stock: 120 },
26 { id: 'PRD002', name: 'Mechanical Keyboard', stock: 60 },
27 { id: 'PRD003', name: 'Noise Cancelling Headphones', stock: 35 },
28 { id: 'PRD004', name: 'LED Monitor 24"', stock: 18 },
29 { id: 'PRD005', name: 'USB-C Hub', stock: 200 },
30 { id: 'PRD006', name: 'Portable SSD 1TB', stock: 40 },
31 { id: 'PRD007', name: 'Webcam HD', stock: 75 },
32 { id: 'PRD008', name: 'Bluetooth Speaker', stock: 95 },
33 { id: 'PRD009', name: 'Gaming Chair', stock: 22 },
34 { id: 'PRD010', name: 'Smartwatch Pro', stock: 50 },
35 { id: 'PRD011', name: 'Laptop Stand', stock: 130 },
36 { id: 'PRD012', name: 'Graphic Tablet', stock: 15 },
37 { id: 'PRD013', name: 'Wireless Charger', stock: 180 },
38]
39
40export function TableWithPaginationDemo() {
41 const [page, setPage] = React.useState(1)
42 const pageSize = 5
43 const totalPages = Math.ceil(products.length / pageSize)
44
45 const paginatedProducts = products.slice(
46 (page - 1) * pageSize,
47 page * pageSize,
48 )
49
50 function goToPage(p: number) {
51 if (p >= 1 && p <= totalPages) setPage(p)
52 }
53
54 return (
55 <div className="space-y-4">
56 <Table>
57 <TableHeader>
58 <TableRow>
59 <TableHead className="w-[120px]">Product ID</TableHead>
60 <TableHead>Product Name</TableHead>
61 <TableHead className="text-right">Stock</TableHead>
62 </TableRow>
63 </TableHeader>
64
65 <TableBody>
66 {paginatedProducts.map((prod) => (
67 <TableRow key={prod.id}>
68 <TableCell className="font-medium">
69 {prod.id}
70 </TableCell>
71 <TableCell>{prod.name}</TableCell>
72 <TableCell className="text-right">
73 {prod.stock}
74 </TableCell>
75 </TableRow>
76 ))}
77 </TableBody>
78
79 <TableFooter>
80 <TableRow>
81 <TableCell colSpan={2}>Total Products</TableCell>
82 <TableCell className="text-right">
83 {products.length}
84 </TableCell>
85 </TableRow>
86 </TableFooter>
87 </Table>
88
89 <Pagination className="justify-end">
90 <PaginationContent>
91 <PaginationItem>
92 <PaginationPrevious
93 onClick={() => goToPage(page - 1)}
94 aria-disabled={page === 1}
95 />
96 </PaginationItem>
97
98 {Array.from({ length: totalPages }, (_, i) => i + 1).map(
99 (p) => (
100 <PaginationItem key={p}>
101 <PaginationLink
102 href="#"
103 isActive={p === page}
104 onClick={() => goToPage(p)}
105 >
106 {p}
107 </PaginationLink>
108 </PaginationItem>
109 ),
110 )}
111
112 <PaginationItem>
113 <PaginationNext
114 onClick={() => goToPage(page + 1)}
115 aria-disabled={page === totalPages}
116 />
117 </PaginationItem>
118 </PaginationContent>
119 </Pagination>
120 </div>
121 )
122}
123