2
2
3
3
import { Cross2Icon } from "@radix-ui/react-icons" ;
4
4
import { Button } from "@stackframe/stack-ui" ;
5
- import { Table } from "@tanstack/react-table" ;
5
+ import { Cell , Table } from "@tanstack/react-table" ;
6
6
import { DataTableViewOptions } from "./view-options" ;
7
+ import { DownloadIcon } from "lucide-react" ;
8
+ import { mkConfig , generateCsv , download } from 'export-to-csv' ;
7
9
8
10
interface DataTableToolbarProps < TData > {
9
11
table : Table < TData > ,
@@ -19,7 +21,7 @@ export function DataTableToolbar<TData>({
19
21
20
22
return (
21
23
< div className = "flex items-center justify-between" >
22
- < div className = "flex flex-1 items-center gap-2 flex-wrap" >
24
+ < div className = "flex items-center gap-2 flex-wrap" >
23
25
{ toolbarRender ?.( table ) }
24
26
{ ( isFiltered || isSorted ) && (
25
27
< Button
@@ -35,7 +37,54 @@ export function DataTableToolbar<TData>({
35
37
</ Button >
36
38
) }
37
39
</ div >
38
- < DataTableViewOptions table = { table } />
40
+ < div className = "flex-1" />
41
+ < div className = "flex items-center gap-2 flex-wrap" >
42
+ < DataTableViewOptions table = { table } />
43
+ < Button
44
+ variant = "outline"
45
+ size = "sm"
46
+ className = "ml-auto hidden h-8 lg:flex"
47
+ onClick = { ( ) => {
48
+ const csvConfig = mkConfig ( {
49
+ fieldSeparator : ',' ,
50
+ filename : 'data' ,
51
+ decimalSeparator : '.' ,
52
+ useKeysAsHeaders : true ,
53
+ } ) ;
54
+
55
+ const renderCellValue = ( cell : Cell < TData , unknown > ) => {
56
+ const rendered = cell . renderValue ( ) ;
57
+ if ( rendered === null ) {
58
+ return undefined ;
59
+ }
60
+ if ( [ 'string' , 'number' , 'boolean' , 'undefined' ] . includes ( typeof rendered ) ) {
61
+ return rendered ;
62
+ }
63
+ if ( rendered instanceof Date ) {
64
+ return rendered . toISOString ( ) ;
65
+ }
66
+ if ( typeof rendered === 'object' ) {
67
+ return JSON . stringify ( rendered ) ;
68
+ }
69
+ } ;
70
+
71
+
72
+ const rowModel = table . getRowModel ( ) ;
73
+ const rows = rowModel . rows . map ( row => Object . fromEntries ( row . getAllCells ( ) . map ( c => [ c . column . id , renderCellValue ( c ) ] ) . filter ( ( [ _ , v ] ) => v !== undefined ) ) ) ;
74
+ console . log ( table . getAllColumns ( ) ) ;
75
+ if ( rows . length === 0 ) {
76
+ alert ( "No data to export" ) ;
77
+ return ;
78
+ }
79
+ console . log ( rows ) ;
80
+ const csv = generateCsv ( csvConfig ) ( rows as any ) ;
81
+ download ( csvConfig ) ( csv ) ;
82
+ } }
83
+ >
84
+ < DownloadIcon className = "mr-2 h-4 w-4" />
85
+ Export CSV
86
+ </ Button >
87
+ </ div >
39
88
</ div >
40
89
) ;
41
90
}
0 commit comments