1
1
import { FC , useState } from 'react' ;
2
- import { Icon , Table } from "@trussworks/react-uswds" ;
2
+ import { Table } from "@trussworks/react-uswds" ;
3
3
import SortArrow from './sort-direction-arrow.svg'
4
4
import SortableIcon from './sortable-icon.svg'
5
5
import './SortableTable.scss'
6
6
7
7
interface SortableTableProps {
8
- data : Array < Map < string , any > > ,
8
+ data : Array < Map < string , object > > ,
9
9
sortableBy : Array < string > | undefined ,
10
10
defaultSort : string | undefined ,
11
11
defaultDescending : boolean | undefined ,
12
12
columns : Array < string > | undefined ,
13
13
columnNames : Map < string , string > | undefined ,
14
- formatters : Map < string , ( any ) => any > | undefined
14
+ formatters : Map < string , ( any ) => object > | undefined
15
15
}
16
16
17
17
const SORTS = {
@@ -23,17 +23,18 @@ const SORTS = {
23
23
24
24
export const SortableTable : FC < SortableTableProps > = ( {
25
25
data,
26
- sortableBy,
27
- defaultSort,
28
- defaultDescending = false ,
29
26
columns = Object . keys ( data [ 0 ] ) ,
27
+ sortableBy = columns ,
28
+ defaultSort = columns ?. [ 0 ] ,
29
+ defaultDescending = false ,
30
+
30
31
formatters = { } ,
31
32
columnNames = { } ,
32
33
} : SortableTableProps ) => {
33
34
34
- const [ sortBy , setSortBy ] = useState ( defaultSort || columns ?. [ 0 ] )
35
+ const [ sortBy , setSortBy ] = useState ( defaultSort )
35
36
const [ isDescending , setIsDescending ] = useState ( defaultDescending )
36
-
37
+ const sortableSet = new Set ( sortableBy || [ ] )
37
38
const updateSort = ( column : string ) => {
38
39
if ( column === sortBy ) {
39
40
setIsDescending ( ! isDescending )
@@ -45,6 +46,7 @@ export const SortableTable: FC<SortableTableProps> = ({
45
46
const columnData = data ?. [ 0 ] ?. [ sortBy ]
46
47
const columnType = Object . prototype . toString . call ( columnData )
47
48
const sortFunc = SORTS [ columnType ] || new Intl . Collator ( navigator . language ) . compare
49
+
48
50
const sortedData = data ?. toSorted ( ( a , b ) => sortFunc ( a [ sortBy ] , b [ sortBy ] ) ) || [ ]
49
51
50
52
if ( isDescending ) {
@@ -57,7 +59,8 @@ export const SortableTable: FC<SortableTableProps> = ({
57
59
< thead >
58
60
< tr >
59
61
{ columns . map ( ( c , idx ) => {
60
- return < SortableTableHeader key = { String ( idx ) } sortBy = { sortBy as string } column = { c } name = { columnNames ?. [ c ] || c }
62
+ return < SortableTableHeader key = { String ( idx ) } disabled = { ! sortableSet . has ( c ) }
63
+ sortBy = { sortBy as string } column = { c } name = { columnNames ?. [ c ] || c }
61
64
isDescending = { isDescending || false } onClick = { updateSort } />
62
65
} ) }
63
66
</ tr >
@@ -82,22 +85,24 @@ interface SortableTableHeaderProps {
82
85
column : string ,
83
86
isDescending : boolean ,
84
87
onClick : ( string ) => void ,
85
- key : string
88
+ key : string ,
89
+ disabled : boolean
86
90
}
87
91
88
92
const SortableTableHeader : FC < SortableTableHeaderProps > = ( {
89
93
sortBy,
90
94
name, column, isDescending,
91
- onClick
95
+ onClick,
96
+ disabled = false
92
97
} : SortableTableHeaderProps ) => {
93
98
94
99
const isSortedBy = sortBy === column
95
100
return (
96
- < th onClick = { ( ) => onClick ( column ) } >
101
+ < th onClick = { disabled ? ( ) => { } : ( ) => onClick ( column ) } >
97
102
< div className = "display-flex flex-row" >
98
103
< div > { name } </ div >
99
104
< div className = "flex-1" > </ div >
100
- { isSortedBy ? < SortOrderIcon isDescending = { isDescending } /> : < SortIcon /> }
105
+ { ! disabled && ( isSortedBy ? < SortOrderIcon isDescending = { isDescending } /> : < SortIcon /> ) }
101
106
</ div >
102
107
</ th >
103
108
)
0 commit comments