@@ -768,6 +768,58 @@ describe('localStorage persistence', () => {
768768 } ) ;
769769} ) ;
770770
771+ // ---------- global search — nullable searchable column (regression) ----------
772+ //
773+ // Root cause: TanStack's default getColumnCanGlobalFilter sniffs the first row's
774+ // value type (string|number). When the first row has externalId=null, typeof null
775+ // === 'object', so TanStack silently excludes the column from global filter for
776+ // the entire table — even rows with a real string value are never matched.
777+ // Fix: override getColumnCanGlobalFilter in useReactTable to return true always,
778+ // relying on enableGlobalFilter (set by searchable:true/false) instead of sniffing.
779+
780+ describe ( 'global search — searchable column whose first row is null' , ( ) => {
781+ interface StudentRow {
782+ id : number ;
783+ name : string ;
784+ externalId : string | null ;
785+ }
786+
787+ const nullFirstData : StudentRow [ ] = [
788+ { id : 1 , name : 'Alice' , externalId : null } ,
789+ { id : 2 , name : 'Bob' , externalId : 'EXT001' } ,
790+ ] ;
791+
792+ const searchColumns : ColumnTemplate < StudentRow > [ ] = [
793+ { of : 'name' , title : 'Name' , cell : ( r ) => r . name , searchable : true } ,
794+ {
795+ of : 'externalId' ,
796+ title : 'External ID' ,
797+ cell : ( r ) => r . externalId ?? '' ,
798+ searchable : true ,
799+ } ,
800+ ] ;
801+
802+ it ( 'finds rows by a searchable column value even when the first row has null for that column' , ( ) => {
803+ const { result } = renderHook (
804+ ( ) =>
805+ useTanStackTableBuilder < StudentRow > ( {
806+ data : nullFirstData ,
807+ columns : searchColumns ,
808+ getRowId : ( r ) => r . id . toString ( ) ,
809+ search : { searchPlaceholder : 'Search' } ,
810+ } ) ,
811+ { wrapper : withStore ( ) } ,
812+ ) ;
813+
814+ act ( ( ) => result . current . toolbar ! . onSearchKeywordChange ?.( 'EXT001' ) ) ;
815+
816+ expect ( result . current . body . rows ) . toHaveLength ( 1 ) ;
817+ expect (
818+ ( result . current . body . rows [ 0 ] as { original : StudentRow } ) . original . name ,
819+ ) . toBe ( 'Bob' ) ;
820+ } ) ;
821+ } ) ;
822+
771823describe ( 'useTanStackTableBuilder onDirectExport' , ( ) => {
772824 beforeEach ( ( ) => {
773825 mockedDownloadFile . mockClear ( ) ;
0 commit comments