1- import React , { ReactNode } from 'react'
1+ import React , { ReactNode , useMemo } from 'react'
22import { Placeholder } from 'src/components/placeholders'
33import { MAX_ITEMS_PER_CARD } from 'src/config'
44
@@ -9,15 +9,17 @@ type PlaceholdersProps = {
99const Placeholders = React . memo < PlaceholdersProps > ( ( { placeholder } ) => {
1010 return (
1111 < >
12- { [ ...Array ( 7 ) ] . map ( ( x , i ) => (
12+ { [ ...Array ( 7 ) ] . map ( ( _ , i ) => (
1313 < span key = { i } > { placeholder } </ span >
1414 ) ) }
1515 </ >
1616 )
1717} )
1818
1919export type ListComponentPropsType < T extends unknown > = {
20- items : T [ ]
20+ items ?: T [ ]
21+ sortBy ?: keyof T
22+ sortFn ?: ( a : T , b : T ) => number
2123 isLoading : boolean
2224 renderItem : ( item : T , index : number ) => React . ReactNode
2325 placeholder ?: React . ReactNode
@@ -27,11 +29,13 @@ export type ListComponentPropsType<T extends unknown> = {
2729 limit ?: number
2830}
2931
30- export function ListComponent < T extends unknown > ( props : ListComponentPropsType < T > ) {
32+ export function ListComponent < T extends any > ( props : ListComponentPropsType < T > ) {
3133 const {
3234 items,
35+ sortBy,
3336 isLoading,
3437 error,
38+ sortFn,
3539 renderItem,
3640 header,
3741 placeholder = < Placeholder /> ,
@@ -42,20 +46,49 @@ export function ListComponent<T extends unknown>(props: ListComponentPropsType<T
4246 return < p className = "errorMsg" > { error ?. message || error } </ p >
4347 }
4448
45- const renderItems = ( ) => {
46- if ( ! items ) {
47- return
49+ if ( items && items . length == 0 ) {
50+ return (
51+ < p className = "errorMsg" >
52+ No items found, try adjusting your filter or choosing a different tag.
53+ </ p >
54+ )
55+ }
56+
57+ const sortedData = useMemo ( ( ) => {
58+ if ( ! items || items . length == 0 ) return [ ]
59+ if ( ! sortBy ) return items
60+
61+ const result = sortFn
62+ ? [ ...items ] . sort ( sortFn )
63+ : [ ...items ] . sort ( ( a , b ) => {
64+ const aVal = a [ sortBy ]
65+ const bVal = b [ sortBy ]
66+ if ( typeof aVal === 'number' && typeof bVal === 'number' ) return bVal - aVal
67+ if ( typeof aVal === 'string' && typeof bVal === 'string' ) return bVal . localeCompare ( aVal )
68+ return 0
69+ } )
70+
71+ return result
72+ } , [ sortBy , sortFn , items ] )
73+
74+ const enrichedItems = useMemo ( ( ) => {
75+ if ( ! sortedData || sortedData . length === 0 ) {
76+ return [ ]
4877 }
4978
50- return items . slice ( 0 , limit ) . map ( ( item , index ) => {
51- let content : ReactNode [ ] = [ renderItem ( item , index ) ]
52- if ( header && index === 0 ) {
53- content . unshift ( header )
54- }
79+ try {
80+ return sortedData . slice ( 0 , limit ) . map ( ( item , index ) => {
81+ let content : ReactNode [ ] = [ renderItem ( item , index ) ]
82+ if ( header && index === 0 ) {
83+ content . unshift ( header )
84+ }
5585
56- return content
57- } )
58- }
86+ return content
87+ } )
88+ } catch ( e ) {
89+ return [ ]
90+ }
91+ } , [ sortedData ] )
5992
60- return < > { isLoading ? < Placeholders placeholder = { placeholder } /> : renderItems ( ) } </ >
93+ return < > { isLoading ? < Placeholders placeholder = { placeholder } /> : enrichedItems } </ >
6194}
0 commit comments