1
1
import React , { useState } from 'react' ;
2
- import { useReactTable , flexRender , getCoreRowModel , getPaginationRowModel } from '@tanstack/react-table' ;
3
- import { Table , TableHead , TableRow , TableCell , TableBody , Pagination } from '@cmsgov/design-system' ;
2
+ import { useReactTable , flexRender , getCoreRowModel , getPaginationRowModel , getSortedRowModel , SortingState , getFilteredRowModel , ColumnFiltersState } from '@tanstack/react-table' ;
3
+ import { useMediaQuery } from 'react-responsive' ;
4
+ import { Table , TableHead , TableRow , TableCell , TableBody , Pagination , Dropdown , DropdownChangeObject } from '@cmsgov/design-system' ;
4
5
import HeaderResizeElement from '../Datatable/HeaderResizeElement' ;
5
6
import './dataDictionaryTable.scss' ;
6
7
7
- const DataDictionaryTable = ( { tableColumns, tableData, count , pageSize } :
8
- { tableColumns : Array < any > , tableData : Array < any > , count : number , pageSize : number }
8
+ const DataDictionaryTable = ( { tableColumns, tableData, pageSize , columnFilters } :
9
+ { tableColumns : Array < any > , tableData : Array < any > , pageSize : number , columnFilters ?: ColumnFiltersState }
9
10
) => {
10
- const [ pagination , setPagination ] = useState ( {
11
- pageIndex : 1 ,
12
- pageSize : pageSize ,
13
- } ) ;
14
- const [ ariaLiveFeedback , setAriaLiveFeedback ] = useState ( '' )
11
+ const [ sorting , setSorting ] = useState < SortingState > ( [ ] )
12
+ const [ ariaLiveFeedback , setAriaLiveFeedback ] = useState ( '' ) ;
13
+
14
+ const mobile = useMediaQuery ( { minWidth : 0 , maxWidth : 544 } ) ;
15
+
16
+ const sortElement = ( isSorted : string ) => {
17
+ if ( isSorted === 'asc' ) {
18
+ return 'dc-c-sort--asc'
19
+ }
20
+ if ( isSorted === 'desc' ) {
21
+ return 'dc-c-sort--desc'
22
+ }
23
+ return 'dc-c-sort--default'
24
+ }
15
25
16
26
const table = useReactTable ( {
17
27
data : tableData ,
18
28
columns : tableColumns ,
19
29
columnResizeMode : 'onChange' ,
20
30
getCoreRowModel : getCoreRowModel ( ) ,
31
+ getFilteredRowModel : getFilteredRowModel ( ) ,
21
32
getPaginationRowModel : getPaginationRowModel ( ) ,
22
- onPaginationChange : setPagination ,
33
+ getSortedRowModel : getSortedRowModel ( ) ,
34
+ onSortingChange : setSorting ,
23
35
state : {
24
- pagination : pagination
36
+ sorting,
37
+ columnFilters
25
38
}
26
39
} ) ;
27
40
41
+ const sortOptions = [
42
+ { value : 'default' , label : 'No Sort' } ,
43
+ { value : 'titleasc' , label : 'Title A-Z' } ,
44
+ { value : 'titledesc' , label : 'Title Z-A' } ,
45
+ { value : 'typeasc' , label : 'Type A-Z' } ,
46
+ { value : 'typedesc' , label : 'Type Z-A' } ,
47
+ ] ;
48
+
49
+ const sortStatesLookup : { [ key : string ] : Array < any > } = {
50
+ default : [ ] ,
51
+ titleasc : [ { id : 'titleResizable' , desc : false } ] ,
52
+ titledesc : [ { id : 'titleResizable' , desc : true } ] ,
53
+ typeasc : [ { id : 'type' , desc : false } ] ,
54
+ typedesc : [ { id : 'type' , desc : true } ]
55
+ }
28
56
return (
29
57
< div >
58
+ { mobile && (
59
+ < div className = "ds-u-margin-bottom--3 ds-l-col--12 ds-l-sm-col--6" >
60
+ < Dropdown
61
+ labelClassName = "ds-u-margin-top--1 ds-u-sm-margin-top--0"
62
+ options = { sortOptions }
63
+ label = "Sort"
64
+ value = { Object . keys ( sortStatesLookup ) . find ( key => {
65
+ return JSON . stringify ( sortStatesLookup [ key ] ) == JSON . stringify ( sorting ) ;
66
+ } ) }
67
+ name = "dc-data-dictionary-type"
68
+ onChange = { ( e : DropdownChangeObject ) => {
69
+ setSorting ( sortStatesLookup [ e . target . value ] )
70
+ } }
71
+ />
72
+ </ div >
73
+ ) }
30
74
< div className = "dc-c-datadictionary-table" >
31
- < Table className = "dc-c-datatable" { ...{ style :{ width : '100%' } } } >
75
+ < Table className = "dc-c-datatable" { ...{ style :{ width : '100%' } } } stackable >
32
76
< TableHead className = "dc-thead--truncated dc-thead--resizeable" >
33
77
{ table . getHeaderGroups ( ) . map ( headerGroup => (
34
78
< TableRow key = { "header" + headerGroup . id } >
35
79
{ headerGroup . headers . map ( header => {
36
80
return ( header . id === "titleResizable" ) ? (
37
- < HeaderResizeElement key = { header . id + "_resize" } table = { table } header = { header } setAriaLiveFeedback = { setAriaLiveFeedback } />
81
+ < HeaderResizeElement key = { header . id + "_resize" } table = { table } header = { header } setAriaLiveFeedback = { setAriaLiveFeedback } sortElement = { sortElement } />
38
82
) : (
39
83
< TableCell
40
84
{ ...{
41
85
key : header . id
42
86
} }
43
- className = "ds-u-border-y--2 ds-u-border--dark ds-u-border-x--0"
87
+ className = { `ds-u-border-y--2 ds-u-border--dark ds-u-border-x--0` }
88
+ id = { 'dataDictionary_' + header . id }
44
89
>
45
90
{ flexRender ( header . column . columnDef . header , header . getContext ( ) ) as React . ReactNode }
91
+ { header . id === 'type' && (
92
+ < button
93
+ onClick = { header . column . getToggleSortingHandler ( ) }
94
+ { ...{
95
+ className : header . column . getCanSort ( )
96
+ ? `cursor-pointer select-none ds-u-focus-visible ${ sortElement ( header . column . getIsSorted ( ) as string ) } `
97
+ : '' ,
98
+ } }
99
+ aria-label = { `${ header . column . columnDef . header } sort order` }
100
+ />
101
+ ) }
46
102
</ TableCell >
47
103
)
48
104
} ) }
@@ -60,10 +116,13 @@ const DataDictionaryTable = ({tableColumns, tableData, count, pageSize} :
60
116
{ ...{
61
117
key : cell . id ,
62
118
style : {
63
- maxWidth : cell . column . getSize ( ) ,
119
+ maxWidth : mobile ? '100%' : cell . column . getSize ( ) ,
120
+ whiteSpace : cell . column . id === "description" ? 'pre-wrap' : 'normal'
64
121
} ,
65
122
} }
66
123
className = { `${ cell . column . id === 'titleResizable' ? 'ds-u-word-break' : '' } ` }
124
+ headers = { 'dataDictionary_' + cell . column . id }
125
+ stackedTitle = { cell . column . id === 'titleResizable' ? 'Title' : cell . column . columnDef . header as string }
67
126
>
68
127
{ flexRender ( cell . column . columnDef . cell , cell . getContext ( ) ) as React . ReactNode }
69
128
</ TableCell >
@@ -76,16 +135,13 @@ const DataDictionaryTable = ({tableColumns, tableData, count, pageSize} :
76
135
</ Table >
77
136
< div className = 'sr-only' aria-live = 'assertive' aria-atomic = 'true' > { ariaLiveFeedback } </ div >
78
137
</ div >
79
- { count > pageSize ? (
138
+ { table . getRowCount ( ) > pageSize ? (
80
139
< Pagination
81
- totalPages = { Math . ceil ( count / pagination . pageSize ) }
82
- currentPage = { pagination . pageIndex + 1 }
140
+ totalPages = { table . getPageCount ( ) }
141
+ currentPage = { table . getState ( ) . pagination . pageIndex + 1 }
83
142
onPageChange = { ( evt , page ) => {
84
143
evt . preventDefault ( ) ;
85
- setPagination ( {
86
- pageIndex : page - 1 ,
87
- pageSize : pageSize
88
- } )
144
+ table . setPageIndex ( page - 1 )
89
145
} }
90
146
renderHref = { ( page ) => {
91
147
return '' ;
0 commit comments