@@ -12,11 +12,33 @@ export const useSorting = <T extends Record<string, any>>( data: T[] ) => {
1212 } ) ;
1313
1414 const handleSort = ( key : string ) => {
15- let direction = 'ascending' ;
16- if ( sortConfig . key === key && sortConfig . direction === 'ascending' ) {
17- direction = 'descending' ;
15+ const isSameKey = sortConfig . key === key ;
16+ const nextDirection =
17+ isSameKey && sortConfig . direction === 'ascending' ? 'descending' : 'ascending' ;
18+ setSortConfig ( { key, direction : nextDirection } ) ;
19+ } ;
20+
21+ const parseNumericValue = ( value : unknown ) => {
22+ if ( typeof value === 'number' && Number . isFinite ( value ) ) {
23+ return value ;
24+ }
25+
26+ if ( value === null || value === undefined ) {
27+ return null ;
28+ }
29+
30+ const text = String ( value ) . trim ( ) ;
31+ if ( ! text ) {
32+ return null ;
1833 }
19- setSortConfig ( { key, direction : "descending" } ) ;
34+
35+ const normalized = text . replace ( / [ ^ 0 - 9 . - ] + / g, '' ) ;
36+ if ( ! normalized || normalized === '-' || normalized === '.' ) {
37+ return null ;
38+ }
39+
40+ const parsed = Number ( normalized ) ;
41+ return Number . isFinite ( parsed ) ? parsed : null ;
2042 } ;
2143
2244 const sortedData = useMemo ( ( ) => {
@@ -25,34 +47,33 @@ export const useSorting = <T extends Record<string, any>>( data: T[] ) => {
2547 return [ ...data ] . sort ( ( a , b ) => {
2648 const valueA = a [ sortConfig . key ! ] ;
2749 const valueB = b [ sortConfig . key ! ] ;
28-
29- const isNumericA = ! isNaN ( parseFloat ( valueA ) ) ;
30- const isNumericB = ! isNaN ( parseFloat ( valueB ) ) ;
50+ const numericA = parseNumericValue ( valueA ) ;
51+ const numericB = parseNumericValue ( valueB ) ;
52+ const isNumericA = numericA !== null ;
53+ const isNumericB = numericB !== null ;
3154
3255 if ( isNumericA && isNumericB ) {
33- const numericA = parseFloat ( valueA ) ;
34- const numericB = parseFloat ( valueB ) ;
3556 return sortConfig . direction === 'ascending'
3657 ? numericA - numericB
3758 : numericB - numericA ;
3859 }
3960
40- if ( isNumericA ) return sortConfig . direction === 'ascending' ? - 1 : 1 ;
41- if ( isNumericB ) return sortConfig . direction === 'descending' ? 1 : - 1 ;
61+ if ( isNumericA && ! isNumericB ) return - 1 ;
62+ if ( ! isNumericA && isNumericB ) return 1 ;
4263
43- const result = String ( valueA || '' ) . localeCompare ( String ( valueB || '' ) ) ;
64+ const result = String ( valueA ?? '' ) . localeCompare ( String ( valueB ?? '' ) ) ;
4465 return sortConfig . direction === 'ascending' ? result : - result ;
4566 } ) ;
4667 } , [ data , sortConfig ] ) ;
4768
4869 const getSortIcon = ( key : string ) => {
4970 if ( sortConfig . key !== key ) return null ;
50- return sortConfig . direction === 'ascending' ? '▲ ' : '▼ ' ;
71+ return sortConfig . direction === 'ascending' ? '^ ' : 'v ' ;
5172 } ;
5273
5374 return {
5475 sortedData,
5576 handleSort,
5677 getSortIcon
5778 } ;
58- } ;
79+ } ;
0 commit comments