1515
1616import React from 'react' ;
1717import type { FieldMetadata , SelectOptionMetadata } from '@object-ui/types' ;
18+ import { Badge } from '@object-ui/components' ;
19+ import { Avatar , AvatarFallback } from '@object-ui/components' ;
20+ import { Button } from '@object-ui/components' ;
21+ import { Check , X } from 'lucide-react' ;
1822
1923/**
2024 * Cell renderer props
@@ -133,13 +137,15 @@ export function BooleanCellRenderer({ value }: CellRendererProps): React.ReactEl
133137 return (
134138 < div className = "flex items-center" >
135139 { value ? (
136- < span className = "inline-flex items-center justify-center w-5 h-5 rounded bg-green-100 text-green-600" >
137- ✓
138- </ span >
140+ < Badge variant = "outline" className = "bg-green-50 text-green-700 border-green-200 gap-1" >
141+ < Check className = "size-3" />
142+ True
143+ </ Badge >
139144 ) : (
140- < span className = "inline-flex items-center justify-center w-5 h-5 rounded bg-gray-100 text-gray-400" >
141- ✗
142- </ span >
145+ < Badge variant = "outline" className = "bg-gray-50 text-gray-500 border-gray-200 gap-1" >
146+ < X className = "size-3" />
147+ False
148+ </ Badge >
143149 ) }
144150 </ div >
145151 ) ;
@@ -173,17 +179,20 @@ export function SelectCellRenderer({ value, field }: CellRendererProps): React.R
173179
174180 if ( ! value ) return < span > -</ span > ;
175181
176- // Color mapping for Tailwind CSS (to avoid dynamic class names)
177- const colorClasses : Record < string , { bg : string ; text : string } > = {
178- gray : { bg : 'bg-gray-100' , text : 'text-gray-800' } ,
179- red : { bg : 'bg-red-100' , text : 'text-red-800' } ,
180- orange : { bg : 'bg-orange-100' , text : 'text-orange-800' } ,
181- yellow : { bg : 'bg-yellow-100' , text : 'text-yellow-800' } ,
182- green : { bg : 'bg-green-100' , text : 'text-green-800' } ,
183- blue : { bg : 'bg-blue-100' , text : 'text-blue-800' } ,
184- indigo : { bg : 'bg-indigo-100' , text : 'text-indigo-800' } ,
185- purple : { bg : 'bg-purple-100' , text : 'text-purple-800' } ,
186- pink : { bg : 'bg-pink-100' , text : 'text-pink-800' } ,
182+ // Color to Tailwind class mapping for custom Badge styling
183+ const getColorClasses = ( color ?: string ) => {
184+ const colorMap : Record < string , string > = {
185+ gray : 'bg-gray-100 text-gray-800 border-gray-300' ,
186+ red : 'bg-red-100 text-red-800 border-red-300' ,
187+ orange : 'bg-orange-100 text-orange-800 border-orange-300' ,
188+ yellow : 'bg-yellow-100 text-yellow-800 border-yellow-300' ,
189+ green : 'bg-green-100 text-green-800 border-green-300' ,
190+ blue : 'bg-blue-100 text-blue-800 border-blue-300' ,
191+ indigo : 'bg-indigo-100 text-indigo-800 border-indigo-300' ,
192+ purple : 'bg-purple-100 text-purple-800 border-purple-300' ,
193+ pink : 'bg-pink-100 text-pink-800 border-pink-300' ,
194+ } ;
195+ return colorMap [ color || 'blue' ] || colorMap . blue ;
187196 } ;
188197
189198 // Handle multiple values
@@ -193,16 +202,16 @@ export function SelectCellRenderer({ value, field }: CellRendererProps): React.R
193202 { value . map ( ( val , idx ) => {
194203 const option = options . find ( opt => opt . value === val ) ;
195204 const label = option ?. label || val ;
196- const color = option ?. color || 'gray' ;
197- const classes = colorClasses [ color ] || colorClasses . gray ;
205+ const colorClasses = getColorClasses ( option ?. color ) ;
198206
199207 return (
200- < span
208+ < Badge
201209 key = { idx }
202- className = { `inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${ classes . bg } ${ classes . text } ` }
210+ variant = "outline"
211+ className = { colorClasses }
203212 >
204213 { label }
205- </ span >
214+ </ Badge >
206215 ) ;
207216 } ) }
208217 </ div >
@@ -212,15 +221,15 @@ export function SelectCellRenderer({ value, field }: CellRendererProps): React.R
212221 // Handle single value
213222 const option = options . find ( opt => opt . value === value ) ;
214223 const label = option ?. label || value ;
215- const color = option ?. color || 'blue' ;
216- const classes = colorClasses [ color ] || colorClasses . blue ;
224+ const colorClasses = getColorClasses ( option ?. color ) ;
217225
218226 return (
219- < span
220- className = { `inline-flex items-center px-2 py-1 rounded text-xs font-medium ${ classes . bg } ${ classes . text } ` }
227+ < Badge
228+ variant = "outline"
229+ className = { colorClasses }
221230 >
222231 { label }
223- </ span >
232+ </ Badge >
224233 ) ;
225234}
226235
@@ -231,13 +240,18 @@ export function EmailCellRenderer({ value }: CellRendererProps): React.ReactElem
231240 if ( ! value ) return < span > -</ span > ;
232241
233242 return (
234- < a
235- href = { `mailto: ${ value } ` }
236- className = "text-blue-600 hover:text-blue-800 underline truncate "
237- onClick = { ( e ) => e . stopPropagation ( ) }
243+ < Button
244+ variant = "link"
245+ className = "p-0 h-auto font-normal text-blue-600 hover:text-blue-800"
246+ asChild
238247 >
239- { value }
240- </ a >
248+ < a
249+ href = { `mailto:${ value } ` }
250+ onClick = { ( e ) => e . stopPropagation ( ) }
251+ >
252+ { value }
253+ </ a >
254+ </ Button >
241255 ) ;
242256}
243257
@@ -248,15 +262,20 @@ export function UrlCellRenderer({ value }: CellRendererProps): React.ReactElemen
248262 if ( ! value ) return < span > -</ span > ;
249263
250264 return (
251- < a
252- href = { value }
253- target = "_blank"
254- rel = "noopener noreferrer"
255- className = "text-blue-600 hover:text-blue-800 underline truncate"
256- onClick = { ( e ) => e . stopPropagation ( ) }
265+ < Button
266+ variant = "link"
267+ className = "p-0 h-auto font-normal text-blue-600 hover:text-blue-800"
268+ asChild
257269 >
258- { value }
259- </ a >
270+ < a
271+ href = { value }
272+ target = "_blank"
273+ rel = "noopener noreferrer"
274+ onClick = { ( e ) => e . stopPropagation ( ) }
275+ >
276+ { value }
277+ </ a >
278+ </ Button >
260279 ) ;
261280}
262281
@@ -313,11 +332,11 @@ export function ImageCellRenderer({ value }: CellRendererProps): React.ReactElem
313332 key = { idx }
314333 src = { img . url || '' }
315334 alt = { img . name || `Image ${ idx + 1 } ` }
316- className = "w -8 h-8 rounded border-2 border-white object-cover"
335+ className = "size -8 rounded-md border-2 border-white object-cover"
317336 />
318337 ) ) }
319338 { value . length > 3 && (
320- < div className = "w -8 h-8 rounded border-2 border-white bg-gray-100 flex items-center justify-center text-xs" >
339+ < div className = "size -8 rounded-md border-2 border-white bg-gray-100 flex items-center justify-center text-xs font-medium text-gray-600 " >
321340 +{ value . length - 3 }
322341 </ div >
323342 ) }
@@ -329,7 +348,7 @@ export function ImageCellRenderer({ value }: CellRendererProps): React.ReactElem
329348 < img
330349 src = { value . url || '' }
331350 alt = { value . name || 'Image' }
332- className = "w -10 h-10 rounded object-cover"
351+ className = "size -10 rounded-md object-cover"
333352 />
334353 ) ;
335354}
@@ -391,19 +410,23 @@ export function UserCellRenderer({ value }: CellRendererProps): React.ReactEleme
391410 const initials = name . split ( ' ' ) . map ( ( n : string ) => n [ 0 ] ) . join ( '' ) . toUpperCase ( ) . slice ( 0 , 2 ) ;
392411
393412 return (
394- < div
413+ < Avatar
395414 key = { idx }
396- className = "w-8 h-8 rounded-full bg-blue-500 text-white flex items-center justify-center text-xs font-medium border-2 border-white"
415+ className = "size-8 border-2 border-white"
397416 title = { name }
398417 >
399- { initials }
400- </ div >
418+ < AvatarFallback className = "bg-blue-500 text-white text-xs" >
419+ { initials }
420+ </ AvatarFallback >
421+ </ Avatar >
401422 ) ;
402423 } ) }
403424 { value . length > 3 && (
404- < div className = "w-8 h-8 rounded-full bg-gray-200 flex items-center justify-center text-xs border-2 border-white" >
405- +{ value . length - 3 }
406- </ div >
425+ < Avatar className = "size-8 border-2 border-white" >
426+ < AvatarFallback className = "bg-gray-200 text-gray-600 text-xs" >
427+ +{ value . length - 3 }
428+ </ AvatarFallback >
429+ </ Avatar >
407430 ) }
408431 </ div >
409432 ) ;
@@ -414,9 +437,11 @@ export function UserCellRenderer({ value }: CellRendererProps): React.ReactEleme
414437
415438 return (
416439 < div className = "flex items-center gap-2" >
417- < div className = "w-8 h-8 rounded-full bg-blue-500 text-white flex items-center justify-center text-xs font-medium" >
418- { initials }
419- </ div >
440+ < Avatar className = "size-8" >
441+ < AvatarFallback className = "bg-blue-500 text-white text-xs" >
442+ { initials }
443+ </ AvatarFallback >
444+ </ Avatar >
420445 < span className = "truncate" > { name } </ span >
421446 </ div >
422447 ) ;
0 commit comments