An advanced table for displaying and managing large datasets with interactive controls.
@tanstack/react-table lucide-reactProduct | Category | Price | Stock | Status |
|---|---|---|---|---|
| Wireless Mouse | Electronics | 29.99 | 120 | INSTOCK |
| Mechanical Keyboard | Electronics | 89.99 | 15 | LOWSTOCK |
| Office Chair | Furniture | 199 | 0 | OUTOFSTOCK |
| Noise Cancelling Headphones | Audio | 149.99 | 42 | INSTOCK |
| Smart Watch | Wearables | 179.99 | 8 | LOWSTOCK |
| Laptop Stand | Accessories | 39.99 | 65 | INSTOCK |
| USB-C Hub | Accessories | 49.99 | 0 | OUTOFSTOCK |
1'use client'
2
3import { Badge } from '@/components/ui/badge'
4import { DataTable } from '@/components/ui/data-table'
5import { ColumnDef } from '@tanstack/react-table'
6
7type Product = {
8 id: string
9 code: string
10 name: string
11 category: string
12 price: number
13 stock: number
14 status: 'INSTOCK' | 'LOWSTOCK' | 'OUTOFSTOCK'
15 rating: number
16}
17
18const statusVariantMap: Record<
19 Product['status'],
20 'success' | 'secondary' | 'error'
21> = {
22 INSTOCK: 'success',
23 LOWSTOCK: 'secondary',
24 OUTOFSTOCK: 'error',
25}
26
27const columns: ColumnDef<Product>[] = [
28 { accessorKey: 'name', header: 'Product' },
29 { accessorKey: 'category', header: 'Category' },
30 { accessorKey: 'price', header: 'Price' },
31 { accessorKey: 'stock', header: 'Stock' },
32 {
33 accessorKey: 'status',
34 header: 'Status',
35 cell: ({ row }) => {
36 const status = row.getValue<Product['status']>('status')
37
38 return <Badge variant={statusVariantMap[status]}>{status}</Badge>
39 },
40 },
41]
42
43const data: Product[] = [
44 {
45 id: '1001',
46 code: 'p1001',
47 name: 'Wireless Mouse',
48 category: 'Electronics',
49 price: 29.99,
50 stock: 120,
51 status: 'INSTOCK',
52 rating: 4.3,
53 },
54 {
55 id: '1002',
56 code: 'p1002',
57 name: 'Mechanical Keyboard',
58 category: 'Electronics',
59 price: 89.99,
60 stock: 15,
61 status: 'LOWSTOCK',
62 rating: 4.7,
63 },
64 {
65 id: '1003',
66 code: 'p1003',
67 name: 'Office Chair',
68 category: 'Furniture',
69 price: 199,
70 stock: 0,
71 status: 'OUTOFSTOCK',
72 rating: 4.1,
73 },
74 {
75 id: '1004',
76 code: 'p1004',
77 name: 'Noise Cancelling Headphones',
78 category: 'Audio',
79 price: 149.99,
80 stock: 42,
81 status: 'INSTOCK',
82 rating: 4.6,
83 },
84 {
85 id: '1005',
86 code: 'p1005',
87 name: 'Smart Watch',
88 category: 'Wearables',
89 price: 179.99,
90 stock: 8,
91 status: 'LOWSTOCK',
92 rating: 4.4,
93 },
94 {
95 id: '1006',
96 code: 'p1006',
97 name: 'Laptop Stand',
98 category: 'Accessories',
99 price: 39.99,
100 stock: 65,
101 status: 'INSTOCK',
102 rating: 4.2,
103 },
104 {
105 id: '1007',
106 code: 'p1007',
107 name: 'USB-C Hub',
108 category: 'Accessories',
109 price: 49.99,
110 stock: 0,
111 status: 'OUTOFSTOCK',
112 rating: 4.0,
113 },
114]
115
116export function DataTableDemo() {
117 return (
118 <div className="space-y-6">
119 <DataTable columns={columns} data={data} />
120 </div>
121 )
122}
123Install the following dependencies:
Products | ||||
|---|---|---|---|---|
Product | Category | Price | Stock | Rating |
| Wireless Mouse | Electronics | 29.99 | 120 | 4.3 |
| Mechanical Keyboard | Electronics | 89.99 | 15 | 4.7 |
| Office Chair | Furniture | 199 | 0 | 4.1 |
| Noise Cancelling Headphones | Audio | 149.99 | 42 | 4.6 |
| Smart Watch | Wearables | 179.99 | 8 | 4.4 |
| Laptop Stand | Accessories | 39.99 | 65 | 4.2 |
| USB-C Hub | Accessories | 49.99 | 0 | 4 |
| In total there are 7 products. | ||||
1'use client'
2
3import { RefreshCcwIcon } from 'lucide-react'
4
5import { Button } from '@/components/ui/button'
6import { DataTable } from '@/components/ui/data-table'
7import { ColumnDef } from '@tanstack/react-table'
8
9type Product = {
10 id: string
11 code: string
12 name: string
13 category: string
14 price: number
15 stock: number
16 status: 'INSTOCK' | 'LOWSTOCK' | 'OUTOFSTOCK'
17 rating: number
18}
19
20const columns: ColumnDef<Product>[] = [
21 { accessorKey: 'name', header: 'Product' },
22 { accessorKey: 'category', header: 'Category' },
23 { accessorKey: 'price', header: 'Price' },
24 { accessorKey: 'stock', header: 'Stock' },
25 { accessorKey: 'rating', header: 'Rating' },
26]
27
28const data: Product[] = [
29 {
30 id: '1001',
31 code: 'p1001',
32 name: 'Wireless Mouse',
33 category: 'Electronics',
34 price: 29.99,
35 stock: 120,
36 status: 'INSTOCK',
37 rating: 4.3,
38 },
39 {
40 id: '1002',
41 code: 'p1002',
42 name: 'Mechanical Keyboard',
43 category: 'Electronics',
44 price: 89.99,
45 stock: 15,
46 status: 'LOWSTOCK',
47 rating: 4.7,
48 },
49 {
50 id: '1003',
51 code: 'p1003',
52 name: 'Office Chair',
53 category: 'Furniture',
54 price: 199,
55 stock: 0,
56 status: 'OUTOFSTOCK',
57 rating: 4.1,
58 },
59 {
60 id: '1004',
61 code: 'p1004',
62 name: 'Noise Cancelling Headphones',
63 category: 'Audio',
64 price: 149.99,
65 stock: 42,
66 status: 'INSTOCK',
67 rating: 4.6,
68 },
69 {
70 id: '1005',
71 code: 'p1005',
72 name: 'Smart Watch',
73 category: 'Wearables',
74 price: 179.99,
75 stock: 8,
76 status: 'LOWSTOCK',
77 rating: 4.4,
78 },
79 {
80 id: '1006',
81 code: 'p1006',
82 name: 'Laptop Stand',
83 category: 'Accessories',
84 price: 39.99,
85 stock: 65,
86 status: 'INSTOCK',
87 rating: 4.2,
88 },
89 {
90 id: '1007',
91 code: 'p1007',
92 name: 'USB-C Hub',
93 category: 'Accessories',
94 price: 49.99,
95 stock: 0,
96 status: 'OUTOFSTOCK',
97 rating: 4.0,
98 },
99]
100
101export function DataTableHeaderFooter() {
102 const header = (
103 <div className="flex w-full items-center justify-between">
104 <h4 className="text-lg font-semibold">Products</h4>
105 <Button size="sm">
106 <RefreshCcwIcon className="h-4 w-4" />
107 </Button>
108 </div>
109 )
110
111 const footer = (
112 <span>
113 In total there are <strong>{data.length}</strong> products.
114 </span>
115 )
116
117 return (
118 <div className="space-y-6">
119 <DataTable
120 columns={columns}
121 data={data}
122 header={header}
123 footer={footer}
124 />
125 </div>
126 )
127}
128Products | |||||
|---|---|---|---|---|---|
Product | Category | Price | Stock | Status | |
| Wireless Mouse | Electronics | 29.99 | 120 | INSTOCK | |
| Mechanical Keyboard | Electronics | 89.99 | 15 | LOWSTOCK | |
| Office Chair | Furniture | 199 | 0 | OUTOFSTOCK | |
| Noise Cancelling Headphones | Audio | 149.99 | 42 | INSTOCK | |
| Smart Watch | Wearables | 179.99 | 8 | LOWSTOCK | |
| Laptop Stand | Accessories | 39.99 | 65 | INSTOCK | |
| USB-C Hub | Accessories | 49.99 | 0 | OUTOFSTOCK | |
| In total there are 7 products. | |||||
1'use client'
2
3import React from 'react'
4import { RefreshCcwIcon } from 'lucide-react'
5
6import { Badge } from '@/components/ui/badge'
7import { Button } from '@/components/ui/button'
8import { DataTable } from '@/components/ui/data-table'
9import { ColumnDef } from '@tanstack/react-table'
10
11type Product = {
12 id: string
13 code: string
14 name: string
15 category: string
16 price: number
17 stock: number
18 status: 'INSTOCK' | 'LOWSTOCK' | 'OUTOFSTOCK'
19 rating: number
20}
21
22const statusVariantMap: Record<
23 Product['status'],
24 'success' | 'secondary' | 'error'
25> = {
26 INSTOCK: 'success',
27 LOWSTOCK: 'secondary',
28 OUTOFSTOCK: 'error',
29}
30
31const columns: ColumnDef<Product>[] = [
32 { accessorKey: 'name', header: 'Product' },
33 { accessorKey: 'category', header: 'Category' },
34 { accessorKey: 'price', header: 'Price' },
35 { accessorKey: 'stock', header: 'Stock' },
36 {
37 accessorKey: 'status',
38 header: 'Status',
39 cell: ({ row }) => {
40 const status = row.getValue<Product['status']>('status')
41
42 return <Badge variant={statusVariantMap[status]}>{status}</Badge>
43 },
44 },
45]
46
47const data: Product[] = [
48 {
49 id: '1001',
50 code: 'p1001',
51 name: 'Wireless Mouse',
52 category: 'Electronics',
53 price: 29.99,
54 stock: 120,
55 status: 'INSTOCK',
56 rating: 4.3,
57 },
58 {
59 id: '1002',
60 code: 'p1002',
61 name: 'Mechanical Keyboard',
62 category: 'Electronics',
63 price: 89.99,
64 stock: 15,
65 status: 'LOWSTOCK',
66 rating: 4.7,
67 },
68 {
69 id: '1003',
70 code: 'p1003',
71 name: 'Office Chair',
72 category: 'Furniture',
73 price: 199,
74 stock: 0,
75 status: 'OUTOFSTOCK',
76 rating: 4.1,
77 },
78 {
79 id: '1004',
80 code: 'p1004',
81 name: 'Noise Cancelling Headphones',
82 category: 'Audio',
83 price: 149.99,
84 stock: 42,
85 status: 'INSTOCK',
86 rating: 4.6,
87 },
88 {
89 id: '1005',
90 code: 'p1005',
91 name: 'Smart Watch',
92 category: 'Wearables',
93 price: 179.99,
94 stock: 8,
95 status: 'LOWSTOCK',
96 rating: 4.4,
97 },
98 {
99 id: '1006',
100 code: 'p1006',
101 name: 'Laptop Stand',
102 category: 'Accessories',
103 price: 39.99,
104 stock: 65,
105 status: 'INSTOCK',
106 rating: 4.2,
107 },
108 {
109 id: '1007',
110 code: 'p1007',
111 name: 'USB-C Hub',
112 category: 'Accessories',
113 price: 49.99,
114 stock: 0,
115 status: 'OUTOFSTOCK',
116 rating: 4.0,
117 },
118]
119
120export function DataTableCheckbox() {
121 const header = (
122 <div className="flex w-full items-center justify-between">
123 <h4 className="text-lg font-semibold">Products</h4>
124 <Button size="sm">
125 <RefreshCcwIcon className="h-4 w-4" />
126 </Button>
127 </div>
128 )
129
130 const footer = (
131 <span>
132 In total there are <strong>{data.length}</strong> products.
133 </span>
134 )
135
136 return (
137 <div className="space-y-6">
138 <DataTable
139 columns={columns}
140 data={data}
141 header={header}
142 footer={footer}
143 selectable={true}
144 selectAll
145 />
146 </div>
147 )
148}
149Products | ||||
|---|---|---|---|---|
Product | Category | Price | Stock | Status |
| Wireless Mouse | Electronics | 29.99 | 120 | INSTOCK |
| Mechanical Keyboard | Electronics | 89.99 | 15 | LOWSTOCK |
| Office Chair | Furniture | 199 | 0 | OUTOFSTOCK |
| Noise Cancelling Headphones | Audio | 149.99 | 42 | INSTOCK |
| Smart Watch | Wearables | 179.99 | 8 | LOWSTOCK |
| Laptop Stand | Accessories | 39.99 | 65 | INSTOCK |
| USB-C Hub | Accessories | 49.99 | 0 | OUTOFSTOCK |
| In total there are 7 products. | ||||
1'use client'
2
3import React from 'react'
4import { RefreshCcwIcon } from 'lucide-react'
5
6import { Badge } from '@/components/ui/badge'
7import { Button } from '@/components/ui/button'
8import { DataTable } from '@/components/ui/data-table'
9import { ColumnDef } from '@tanstack/react-table'
10
11type Product = {
12 id: string
13 code: string
14 name: string
15 category: string
16 price: number
17 stock: number
18 status: 'INSTOCK' | 'LOWSTOCK' | 'OUTOFSTOCK'
19 rating: number
20}
21
22const statusVariantMap: Record<
23 Product['status'],
24 'success' | 'secondary' | 'error'
25> = {
26 INSTOCK: 'success',
27 LOWSTOCK: 'secondary',
28 OUTOFSTOCK: 'error',
29}
30
31const columns: ColumnDef<Product>[] = [
32 { accessorKey: 'name', header: 'Product', enableSorting: true },
33 { accessorKey: 'category', header: 'Category' },
34 { accessorKey: 'price', header: 'Price', enableSorting: true },
35 { accessorKey: 'stock', header: 'Stock', enableSorting: true },
36 {
37 accessorKey: 'status',
38 header: 'Status',
39 cell: ({ row }) => {
40 const status = row.getValue<Product['status']>('status')
41
42 return <Badge variant={statusVariantMap[status]}>{status}</Badge>
43 },
44 },
45]
46
47const data: Product[] = [
48 {
49 id: '1001',
50 code: 'p1001',
51 name: 'Wireless Mouse',
52 category: 'Electronics',
53 price: 29.99,
54 stock: 120,
55 status: 'INSTOCK',
56 rating: 4.3,
57 },
58 {
59 id: '1002',
60 code: 'p1002',
61 name: 'Mechanical Keyboard',
62 category: 'Electronics',
63 price: 89.99,
64 stock: 15,
65 status: 'LOWSTOCK',
66 rating: 4.7,
67 },
68 {
69 id: '1003',
70 code: 'p1003',
71 name: 'Office Chair',
72 category: 'Furniture',
73 price: 199,
74 stock: 0,
75 status: 'OUTOFSTOCK',
76 rating: 4.1,
77 },
78 {
79 id: '1004',
80 code: 'p1004',
81 name: 'Noise Cancelling Headphones',
82 category: 'Audio',
83 price: 149.99,
84 stock: 42,
85 status: 'INSTOCK',
86 rating: 4.6,
87 },
88 {
89 id: '1005',
90 code: 'p1005',
91 name: 'Smart Watch',
92 category: 'Wearables',
93 price: 179.99,
94 stock: 8,
95 status: 'LOWSTOCK',
96 rating: 4.4,
97 },
98 {
99 id: '1006',
100 code: 'p1006',
101 name: 'Laptop Stand',
102 category: 'Accessories',
103 price: 39.99,
104 stock: 65,
105 status: 'INSTOCK',
106 rating: 4.2,
107 },
108 {
109 id: '1007',
110 code: 'p1007',
111 name: 'USB-C Hub',
112 category: 'Accessories',
113 price: 49.99,
114 stock: 0,
115 status: 'OUTOFSTOCK',
116 rating: 4.0,
117 },
118]
119
120export function DataTableSorting() {
121 const header = (
122 <div className="flex w-full items-center justify-between">
123 <h4 className="text-lg font-semibold">Products</h4>
124 <Button size="sm">
125 <RefreshCcwIcon className="h-4 w-4" />
126 </Button>
127 </div>
128 )
129
130 const footer = (
131 <span>
132 In total there are <strong>{data.length}</strong> products.
133 </span>
134 )
135
136 return (
137 <div className="space-y-6">
138 <DataTable
139 columns={columns}
140 data={data}
141 header={header}
142 footer={footer}
143 />
144 </div>
145 )
146}
147Products | ||||
|---|---|---|---|---|
Product | Category | Price | Stock | Status |
| Wireless Mouse | Electronics | 29.99 | 120 | INSTOCK |
| Mechanical Keyboard | Electronics | 89.99 | 15 | LOWSTOCK |
| Office Chair | Furniture | 199 | 0 | OUTOFSTOCK |
| Noise Cancelling Headphones | Audio | 149.99 | 42 | INSTOCK |
| Smart Watch | Wearables | 179.99 | 8 | LOWSTOCK |
| Laptop Stand | Accessories | 39.99 | 65 | INSTOCK |
| USB-C Hub | Accessories | 49.99 | 0 | OUTOFSTOCK |
| In total there are 7 products. | ||||
1'use client'
2
3import React from 'react'
4import { RefreshCcwIcon } from 'lucide-react'
5
6import { Badge } from '@/components/ui/badge'
7import { Button } from '@/components/ui/button'
8import { DataTable } from '@/components/ui/data-table'
9import { ColumnDef } from '@tanstack/react-table'
10
11type Product = {
12 id: string
13 code: string
14 name: string
15 category: string
16 price: number
17 stock: number
18 status: 'INSTOCK' | 'LOWSTOCK' | 'OUTOFSTOCK'
19 rating: number
20}
21
22const statusVariantMap: Record<
23 Product['status'],
24 'success' | 'secondary' | 'error'
25> = {
26 INSTOCK: 'success',
27 LOWSTOCK: 'secondary',
28 OUTOFSTOCK: 'error',
29}
30
31const columns: ColumnDef<Product>[] = [
32 {
33 accessorKey: 'name',
34 header: 'Product',
35 enableSorting: true,
36 enableColumnFilter: true,
37 },
38 { accessorKey: 'category', header: 'Category', enableColumnFilter: true },
39 { accessorKey: 'price', header: 'Price', enableSorting: true },
40 {
41 accessorKey: 'stock',
42 header: 'Stock',
43 enableSorting: true,
44 enableColumnFilter: true,
45 },
46 {
47 accessorKey: 'status',
48 header: 'Status',
49 cell: ({ row }) => {
50 const status = row.getValue<Product['status']>('status')
51
52 return <Badge variant={statusVariantMap[status]}>{status}</Badge>
53 },
54 },
55]
56
57const data: Product[] = [
58 {
59 id: '1001',
60 code: 'p1001',
61 name: 'Wireless Mouse',
62 category: 'Electronics',
63 price: 29.99,
64 stock: 120,
65 status: 'INSTOCK',
66 rating: 4.3,
67 },
68 {
69 id: '1002',
70 code: 'p1002',
71 name: 'Mechanical Keyboard',
72 category: 'Electronics',
73 price: 89.99,
74 stock: 15,
75 status: 'LOWSTOCK',
76 rating: 4.7,
77 },
78 {
79 id: '1003',
80 code: 'p1003',
81 name: 'Office Chair',
82 category: 'Furniture',
83 price: 199,
84 stock: 0,
85 status: 'OUTOFSTOCK',
86 rating: 4.1,
87 },
88 {
89 id: '1004',
90 code: 'p1004',
91 name: 'Noise Cancelling Headphones',
92 category: 'Audio',
93 price: 149.99,
94 stock: 42,
95 status: 'INSTOCK',
96 rating: 4.6,
97 },
98 {
99 id: '1005',
100 code: 'p1005',
101 name: 'Smart Watch',
102 category: 'Wearables',
103 price: 179.99,
104 stock: 8,
105 status: 'LOWSTOCK',
106 rating: 4.4,
107 },
108 {
109 id: '1006',
110 code: 'p1006',
111 name: 'Laptop Stand',
112 category: 'Accessories',
113 price: 39.99,
114 stock: 65,
115 status: 'INSTOCK',
116 rating: 4.2,
117 },
118 {
119 id: '1007',
120 code: 'p1007',
121 name: 'USB-C Hub',
122 category: 'Accessories',
123 price: 49.99,
124 stock: 0,
125 status: 'OUTOFSTOCK',
126 rating: 4.0,
127 },
128]
129
130export function DataTableFilter() {
131 const header = (
132 <div className="flex w-full items-center justify-between">
133 <h4 className="text-lg font-semibold">Products</h4>
134 <Button size="sm">
135 <RefreshCcwIcon className="h-4 w-4" />
136 </Button>
137 </div>
138 )
139
140 const footer = (
141 <span>
142 In total there are <strong>{data.length}</strong> products.
143 </span>
144 )
145
146 return (
147 <div className="space-y-6">
148 <DataTable
149 columns={columns}
150 data={data}
151 header={header}
152 footer={footer}
153 globalFiltering
154 />
155 </div>
156 )
157}
158Products | ||||
|---|---|---|---|---|
Product | Category | Price | Stock | Status |
| Wireless Mouse | Electronics | 29.99 | 120 | INSTOCK |
| Mechanical Keyboard | Electronics | 89.99 | 15 | LOWSTOCK |
| Office Chair | Furniture | 199 | 0 | OUTOFSTOCK |
| Noise Cancelling Headphones | Audio | 149.99 | 42 | INSTOCK |
| Smart Watch | Wearables | 179.99 | 8 | LOWSTOCK |
| In total there are 14 products. | ||||
1'use client'
2
3import React from 'react'
4import { RefreshCcwIcon } from 'lucide-react'
5
6import { Badge } from '@/components/ui/badge'
7import { Button } from '@/components/ui/button'
8import { DataTable } from '@/components/ui/data-table'
9import { ColumnDef } from '@tanstack/react-table'
10
11type Product = {
12 id: string
13 code: string
14 name: string
15 category: string
16 price: number
17 stock: number
18 status: 'INSTOCK' | 'LOWSTOCK' | 'OUTOFSTOCK'
19 rating: number
20}
21
22const statusVariantMap: Record<
23 Product['status'],
24 'success' | 'secondary' | 'error'
25> = {
26 INSTOCK: 'success',
27 LOWSTOCK: 'secondary',
28 OUTOFSTOCK: 'error',
29}
30
31const columns: ColumnDef<Product>[] = [
32 { accessorKey: 'name', header: 'Product', enableSorting: true },
33 { accessorKey: 'category', header: 'Category' },
34 { accessorKey: 'price', header: 'Price', enableSorting: true },
35 { accessorKey: 'stock', header: 'Stock', enableSorting: true },
36 {
37 accessorKey: 'status',
38 header: 'Status',
39 cell: ({ row }) => {
40 const status = row.getValue<Product['status']>('status')
41
42 return <Badge variant={statusVariantMap[status]}>{status}</Badge>
43 },
44 },
45]
46
47const data: Product[] = [
48 {
49 id: '1001',
50 code: 'p1001',
51 name: 'Wireless Mouse',
52 category: 'Electronics',
53 price: 29.99,
54 stock: 120,
55 status: 'INSTOCK',
56 rating: 4.3,
57 },
58 {
59 id: '1002',
60 code: 'p1002',
61 name: 'Mechanical Keyboard',
62 category: 'Electronics',
63 price: 89.99,
64 stock: 15,
65 status: 'LOWSTOCK',
66 rating: 4.7,
67 },
68 {
69 id: '1003',
70 code: 'p1003',
71 name: 'Office Chair',
72 category: 'Furniture',
73 price: 199,
74 stock: 0,
75 status: 'OUTOFSTOCK',
76 rating: 4.1,
77 },
78 {
79 id: '1004',
80 code: 'p1004',
81 name: 'Noise Cancelling Headphones',
82 category: 'Audio',
83 price: 149.99,
84 stock: 42,
85 status: 'INSTOCK',
86 rating: 4.6,
87 },
88 {
89 id: '1005',
90 code: 'p1005',
91 name: 'Smart Watch',
92 category: 'Wearables',
93 price: 179.99,
94 stock: 8,
95 status: 'LOWSTOCK',
96 rating: 4.4,
97 },
98 {
99 id: '1006',
100 code: 'p1006',
101 name: 'Laptop Stand',
102 category: 'Accessories',
103 price: 39.99,
104 stock: 65,
105 status: 'INSTOCK',
106 rating: 4.2,
107 },
108 {
109 id: '1007',
110 code: 'p1007',
111 name: 'USB-C Hub',
112 category: 'Accessories',
113 price: 49.99,
114 stock: 0,
115 status: 'OUTOFSTOCK',
116 rating: 4.0,
117 },
118 {
119 id: '1001',
120 code: 'p1001',
121 name: 'Wireless Mouse',
122 category: 'Electronics',
123 price: 29.99,
124 stock: 120,
125 status: 'INSTOCK',
126 rating: 4.3,
127 },
128 {
129 id: '1002',
130 code: 'p1002',
131 name: 'Mechanical Keyboard',
132 category: 'Electronics',
133 price: 89.99,
134 stock: 15,
135 status: 'LOWSTOCK',
136 rating: 4.7,
137 },
138 {
139 id: '1003',
140 code: 'p1003',
141 name: 'Office Chair',
142 category: 'Furniture',
143 price: 199,
144 stock: 0,
145 status: 'OUTOFSTOCK',
146 rating: 4.1,
147 },
148 {
149 id: '1004',
150 code: 'p1004',
151 name: 'Noise Cancelling Headphones',
152 category: 'Audio',
153 price: 149.99,
154 stock: 42,
155 status: 'INSTOCK',
156 rating: 4.6,
157 },
158 {
159 id: '1005',
160 code: 'p1005',
161 name: 'Smart Watch',
162 category: 'Wearables',
163 price: 179.99,
164 stock: 8,
165 status: 'LOWSTOCK',
166 rating: 4.4,
167 },
168 {
169 id: '1006',
170 code: 'p1006',
171 name: 'Laptop Stand',
172 category: 'Accessories',
173 price: 39.99,
174 stock: 65,
175 status: 'INSTOCK',
176 rating: 4.2,
177 },
178 {
179 id: '1007',
180 code: 'p1007',
181 name: 'USB-C Hub',
182 category: 'Accessories',
183 price: 49.99,
184 stock: 0,
185 status: 'OUTOFSTOCK',
186 rating: 4.0,
187 },
188]
189
190export function DataTablePagination() {
191 const header = (
192 <div className="flex w-full items-center justify-between">
193 <h4 className="text-lg font-semibold">Products</h4>
194 <Button size="sm">
195 <RefreshCcwIcon className="h-4 w-4" />
196 </Button>
197 </div>
198 )
199
200 const footer = (
201 <span>
202 In total there are <strong>{data.length}</strong> products.
203 </span>
204 )
205
206 return (
207 <div className="space-y-6">
208 <DataTable
209 columns={columns}
210 data={data}
211 header={header}
212 footer={footer}
213 pagination
214 pageSize={5}
215 />
216 </div>
217 )
218}
219Products | ||||
|---|---|---|---|---|
Product | Category | Price | Stock | Rating |
| Wireless Mouse | Electronics | 29.99 | 120 | 4.3 |
| Mechanical Keyboard | Electronics | 89.99 | 15 | 4.7 |
| Office Chair | Furniture | 199 | 0 | 4.1 |
| Noise Cancelling Headphones | Audio | 149.99 | 42 | 4.6 |
| Smart Watch | Wearables | 179.99 | 8 | 4.4 |
| Laptop Stand | Accessories | 39.99 | 65 | 4.2 |
| USB-C Hub | Accessories | 49.99 | 0 | 4 |
| In total there are 7 products. | ||||
1'use client'
2
3import React from 'react'
4import { RefreshCcwIcon } from 'lucide-react'
5
6import { Button } from '@/components/ui/button'
7import { DataTable } from '@/components/ui/data-table'
8import { ColumnDef } from '@tanstack/react-table'
9
10type Product = {
11 id: string
12 code: string
13 name: string
14 category: string
15 price: number
16 stock: number
17 status: 'INSTOCK' | 'LOWSTOCK' | 'OUTOFSTOCK'
18 rating: number
19}
20
21const columns: ColumnDef<Product>[] = [
22 { accessorKey: 'name', header: 'Product' },
23 { accessorKey: 'category', header: 'Category' },
24 { accessorKey: 'price', header: 'Price' },
25 { accessorKey: 'stock', header: 'Stock' },
26 { accessorKey: 'rating', header: 'Rating' },
27]
28
29const data: Product[] = [
30 {
31 id: '1001',
32 code: 'p1001',
33 name: 'Wireless Mouse',
34 category: 'Electronics',
35 price: 29.99,
36 stock: 120,
37 status: 'INSTOCK',
38 rating: 4.3,
39 },
40 {
41 id: '1002',
42 code: 'p1002',
43 name: 'Mechanical Keyboard',
44 category: 'Electronics',
45 price: 89.99,
46 stock: 15,
47 status: 'LOWSTOCK',
48 rating: 4.7,
49 },
50 {
51 id: '1003',
52 code: 'p1003',
53 name: 'Office Chair',
54 category: 'Furniture',
55 price: 199,
56 stock: 0,
57 status: 'OUTOFSTOCK',
58 rating: 4.1,
59 },
60 {
61 id: '1004',
62 code: 'p1004',
63 name: 'Noise Cancelling Headphones',
64 category: 'Audio',
65 price: 149.99,
66 stock: 42,
67 status: 'INSTOCK',
68 rating: 4.6,
69 },
70 {
71 id: '1005',
72 code: 'p1005',
73 name: 'Smart Watch',
74 category: 'Wearables',
75 price: 179.99,
76 stock: 8,
77 status: 'LOWSTOCK',
78 rating: 4.4,
79 },
80 {
81 id: '1006',
82 code: 'p1006',
83 name: 'Laptop Stand',
84 category: 'Accessories',
85 price: 39.99,
86 stock: 65,
87 status: 'INSTOCK',
88 rating: 4.2,
89 },
90 {
91 id: '1007',
92 code: 'p1007',
93 name: 'USB-C Hub',
94 category: 'Accessories',
95 price: 49.99,
96 stock: 0,
97 status: 'OUTOFSTOCK',
98 rating: 4.0,
99 },
100]
101
102export function DataTableSize() {
103 const [size, setSize] = React.useState<'small' | 'normal' | 'large'>(
104 'small',
105 )
106
107 const header = (
108 <div className="flex w-full items-center justify-between">
109 <h4 className="text-lg font-semibold">Products</h4>
110 <Button size="sm">
111 <RefreshCcwIcon className="h-4 w-4" />
112 </Button>
113 </div>
114 )
115
116 const footer = (
117 <span>
118 In total there are <strong>{data.length}</strong> products.
119 </span>
120 )
121
122 return (
123 <div className="space-y-6">
124 <div className="flex items-center justify-center gap-2">
125 <Button
126 variant={size === 'small' ? 'primary' : 'outline'}
127 size="sm"
128 onClick={() => setSize('small')}
129 >
130 Small
131 </Button>
132 <Button
133 variant={size === 'normal' ? 'primary' : 'outline'}
134 size="sm"
135 onClick={() => setSize('normal')}
136 >
137 Normal
138 </Button>
139 <Button
140 variant={size === 'large' ? 'primary' : 'outline'}
141 size="sm"
142 onClick={() => setSize('large')}
143 >
144 Large
145 </Button>
146 </div>
147 <DataTable
148 columns={columns}
149 data={data}
150 header={header}
151 footer={footer}
152 size={size}
153 />
154 </div>
155 )
156}
157Products | ||||
|---|---|---|---|---|
Product | Category | Price | Stock | Status |
| Wireless Mouse | Electronics | 29.99 | 120 | INSTOCK |
| Mechanical Keyboard | Electronics | 89.99 | 15 | LOWSTOCK |
| Office Chair | Furniture | 199 | 0 | OUTOFSTOCK |
| Noise Cancelling Headphones | Audio | 149.99 | 42 | INSTOCK |
| Smart Watch | Wearables | 179.99 | 8 | LOWSTOCK |
| Laptop Stand | Accessories | 39.99 | 65 | INSTOCK |
| USB-C Hub | Accessories | 49.99 | 0 | OUTOFSTOCK |
| In total there are 7 products. | ||||
1'use client'
2
3import React from 'react'
4import { RefreshCcwIcon } from 'lucide-react'
5
6import { Badge } from '@/components/ui/badge'
7import { Button } from '@/components/ui/button'
8import { DataTable } from '@/components/ui/data-table'
9import { ColumnDef } from '@tanstack/react-table'
10
11type Product = {
12 id: string
13 code: string
14 name: string
15 category: string
16 price: number
17 stock: number
18 status: 'INSTOCK' | 'LOWSTOCK' | 'OUTOFSTOCK'
19 rating: number
20}
21
22const statusVariantMap: Record<
23 Product['status'],
24 'success' | 'secondary' | 'error'
25> = {
26 INSTOCK: 'success',
27 LOWSTOCK: 'secondary',
28 OUTOFSTOCK: 'error',
29}
30
31const columns: ColumnDef<Product>[] = [
32 { accessorKey: 'name', header: 'Product' },
33 { accessorKey: 'category', header: 'Category' },
34 { accessorKey: 'price', header: 'Price' },
35 { accessorKey: 'stock', header: 'Stock' },
36 {
37 accessorKey: 'status',
38 header: 'Status',
39 cell: ({ row }) => {
40 const status = row.getValue<Product['status']>('status')
41
42 return <Badge variant={statusVariantMap[status]}>{status}</Badge>
43 },
44 },
45]
46
47const data: Product[] = [
48 {
49 id: '1001',
50 code: 'p1001',
51 name: 'Wireless Mouse',
52 category: 'Electronics',
53 price: 29.99,
54 stock: 120,
55 status: 'INSTOCK',
56 rating: 4.3,
57 },
58 {
59 id: '1002',
60 code: 'p1002',
61 name: 'Mechanical Keyboard',
62 category: 'Electronics',
63 price: 89.99,
64 stock: 15,
65 status: 'LOWSTOCK',
66 rating: 4.7,
67 },
68 {
69 id: '1003',
70 code: 'p1003',
71 name: 'Office Chair',
72 category: 'Furniture',
73 price: 199,
74 stock: 0,
75 status: 'OUTOFSTOCK',
76 rating: 4.1,
77 },
78 {
79 id: '1004',
80 code: 'p1004',
81 name: 'Noise Cancelling Headphones',
82 category: 'Audio',
83 price: 149.99,
84 stock: 42,
85 status: 'INSTOCK',
86 rating: 4.6,
87 },
88 {
89 id: '1005',
90 code: 'p1005',
91 name: 'Smart Watch',
92 category: 'Wearables',
93 price: 179.99,
94 stock: 8,
95 status: 'LOWSTOCK',
96 rating: 4.4,
97 },
98 {
99 id: '1006',
100 code: 'p1006',
101 name: 'Laptop Stand',
102 category: 'Accessories',
103 price: 39.99,
104 stock: 65,
105 status: 'INSTOCK',
106 rating: 4.2,
107 },
108 {
109 id: '1007',
110 code: 'p1007',
111 name: 'USB-C Hub',
112 category: 'Accessories',
113 price: 49.99,
114 stock: 0,
115 status: 'OUTOFSTOCK',
116 rating: 4.0,
117 },
118]
119
120export function DataTableGridStripedRow() {
121 const [size, setSize] = React.useState<'small' | 'normal' | 'large'>(
122 'normal',
123 )
124
125 const header = (
126 <div className="flex w-full items-center justify-between">
127 <h4 className="text-lg font-semibold">Products</h4>
128 <Button size="sm">
129 <RefreshCcwIcon className="h-4 w-4" />
130 </Button>
131 </div>
132 )
133
134 const footer = (
135 <span>
136 In total there are <strong>{data.length}</strong> products.
137 </span>
138 )
139
140 return (
141 <div className="space-y-6">
142 <div className="flex items-center justify-center gap-2">
143 <Button
144 variant={size === 'small' ? 'primary' : 'outline'}
145 size="sm"
146 onClick={() => setSize('small')}
147 >
148 Small
149 </Button>
150 <Button
151 variant={size === 'normal' ? 'primary' : 'outline'}
152 size="sm"
153 onClick={() => setSize('normal')}
154 >
155 Normal
156 </Button>
157 <Button
158 variant={size === 'large' ? 'primary' : 'outline'}
159 size="sm"
160 onClick={() => setSize('large')}
161 >
162 Large
163 </Button>
164 </div>
165 <DataTable
166 columns={columns}
167 data={data}
168 header={header}
169 footer={footer}
170 size={size}
171 showGridLines
172 stripedRows
173 />
174 </div>
175 )
176}
177| Prop | Type | Default |
|---|---|---|
| columns | ColumnDef<TData, TValue>[] | - |
| data | TData[] | - |
| header | React.ReactNode | - |
| footer | React.ReactNode | - |
| size | small,normal,large | normal |
| selectable | boolean | false |
| selectAll | boolean | false |
| showGridLines | boolean | false |
| stripedRows | boolean | false |
| pagination | boolean | false |
| pageSize | number | 5 |
| globalFiltering | boolean | false |