@@ -32,6 +32,7 @@ export default function DataGrid({
3232 rowStyle,
3333 onHeaderSelected,
3434 onRowSelected,
35+ slots : slotsProp ,
3536 children,
3637} : DataGridProps & { children ?: React . ReactNode } ) {
3738
@@ -43,16 +44,36 @@ export default function DataGrid({
4344 const metaType = useMemo ( ( ) => typeOf ( typeName ) , [ typeName , typeOf ] )
4445 const typeProps = useMemo ( ( ) => typeProperties ( metaType ) , [ metaType , typeProperties ] )
4546
46- // Extract slots from children
47+ // Extract slots from children or slots prop
4748 const slots = useMemo ( ( ) => {
48- const slotMap : { [ key : string ] : React . ReactNode } = { }
49- React . Children . forEach ( children , child => {
50- if ( React . isValidElement ( child ) && ( child . props as any ) . slot ) {
51- slotMap [ ( child . props as any ) . slot ] = child
49+ // If slots prop is provided, use it directly
50+ if ( slotsProp ) {
51+ return slotsProp as { [ key : string ] : React . ReactNode }
52+ }
53+
54+ // If children is an object (slot map), use it directly
55+ if ( children && typeof children === 'object' && ! React . isValidElement ( children ) && ! Array . isArray ( children ) ) {
56+ // Check if it's a plain object with string keys (not a Promise, not a React element)
57+ const obj = children as any
58+ // Plain objects have Object.prototype or null prototype
59+ const proto = Object . getPrototypeOf ( obj )
60+ if ( obj && typeof obj === 'object' && ( proto === Object . prototype || proto === null ) ) {
61+ return obj as { [ key : string ] : React . ReactNode }
5262 }
53- } )
63+ }
64+
65+ // Otherwise, extract slots from React children with slot prop
66+ const slotMap : { [ key : string ] : React . ReactNode } = { }
67+ // Only use React.Children if we have valid React children
68+ if ( children && ( React . isValidElement ( children ) || Array . isArray ( children ) ) ) {
69+ React . Children . forEach ( children , child => {
70+ if ( React . isValidElement ( child ) && ( child . props as any ) . slot ) {
71+ slotMap [ ( child . props as any ) . slot ] = child
72+ }
73+ } )
74+ }
5475 return slotMap
55- } , [ children ] )
76+ } , [ slotsProp , children ] )
5677
5778 const slotHeader = ( column : string ) => {
5879 const slotName = column . toLowerCase ( ) + '-header'
@@ -162,25 +183,34 @@ export default function DataGrid({
162183 const isOpen = false // You may want to pass this from parent or manage it
163184
164185 return (
165- < td
186+ < th
166187 key = { column }
167188 className = { `${ cellClass ( column ) } ${ theadCellClass } ${ isOpen ? 'text-gray-900 dark:text-gray-50' : 'text-gray-500 dark:text-gray-400' } ` }
189+ onClick = { ( e ) => handleHeaderSelected ( column , e ) }
168190 >
169- < div onClick = { ( e ) => handleHeaderSelected ( column , e ) } >
170- { slots [ column + '-header' ] ?
171- slots [ column + '-header' ] :
172- headerSlotName && slots [ headerSlotName ] ?
173- slots [ headerSlotName ] :
174- slots . header ?
175- React . cloneElement ( slots . header as React . ReactElement , { column, label : headerFormat ( column ) } as any ) :
176- < div className = "flex justify-between items-center" >
177- < span className = "mr-1 select-none" >
178- { headerFormat ( column ) }
179- </ span >
180- </ div >
191+ { ( ( ) => {
192+ const headerSlot = slots [ column + '-header' ] || ( headerSlotName && slots [ headerSlotName ] )
193+ if ( headerSlot ) {
194+ if ( typeof headerSlot === 'function' ) {
195+ return ( headerSlot as any ) ( { column, label : headerFormat ( column ) } )
196+ }
197+ return headerSlot
181198 }
182- </ div >
183- </ td >
199+ if ( slots . header ) {
200+ if ( typeof slots . header === 'function' ) {
201+ return ( slots . header as any ) ( { column, label : headerFormat ( column ) } )
202+ }
203+ return React . cloneElement ( slots . header as React . ReactElement , { column, label : headerFormat ( column ) } as any )
204+ }
205+ return (
206+ < div className = "flex justify-between items-center" >
207+ < span className = "mr-1 select-none" >
208+ { headerFormat ( column ) }
209+ </ span >
210+ </ div >
211+ )
212+ } ) ( ) }
213+ </ th >
184214 )
185215 } ) }
186216 </ tr >
@@ -201,14 +231,19 @@ export default function DataGrid({
201231 key = { column }
202232 className = { `${ cellClass ( column ) } ${ grid . tableCellClass } ` }
203233 >
204- { slots [ column ] ?
205- React . cloneElement ( slots [ column ] as React . ReactElement , item ) :
206- colSlotName && slots [ colSlotName ] ?
207- React . cloneElement ( slots [ colSlotName ] as React . ReactElement , item ) :
208- columnProp ( column ) ?
209- < CellFormat type = { metaType } propType = { columnProp ( column ) ! } value = { item } /> :
210- < PreviewFormat value = { mapGet ( item , column ) } format = { columnFormat ( column ) } />
211- }
234+ { ( ( ) => {
235+ const colSlot = slots [ column ] || ( colSlotName && slots [ colSlotName ] )
236+ if ( colSlot ) {
237+ if ( typeof colSlot === 'function' ) {
238+ return ( colSlot as any ) ( item )
239+ }
240+ return React . cloneElement ( colSlot as React . ReactElement , item )
241+ }
242+ if ( columnProp ( column ) ) {
243+ return < CellFormat type = { metaType } propType = { columnProp ( column ) ! } value = { item } />
244+ }
245+ return < PreviewFormat value = { mapGet ( item , column ) } format = { columnFormat ( column ) } />
246+ } ) ( ) }
212247 </ td >
213248 )
214249 } ) }
0 commit comments