@@ -438,11 +438,32 @@ export function UserCellRenderer({ value }: CellRendererProps): React.ReactEleme
438438 ) ;
439439}
440440
441+ /**
442+ * Field Registry
443+ * Stores mapping between field types and their renderers.
444+ */
445+ const fieldRegistry = new Map < string , React . FC < CellRendererProps > > ( ) ;
446+
447+ /**
448+ * Register a custom field renderer
449+ * @param type Field type (e.g. 'text', 'location', 'my-custom-type')
450+ * @param renderer React component to render the field
451+ */
452+ export function registerFieldRenderer ( type : string , renderer : React . FC < CellRendererProps > ) {
453+ fieldRegistry . set ( type , renderer ) ;
454+ }
455+
441456/**
442457 * Get the appropriate cell renderer for a field type
443458 */
444459export function getCellRenderer ( fieldType : string ) : React . FC < CellRendererProps > {
445- const rendererMap : Record < string , React . FC < CellRendererProps > > = {
460+ // 1. Try exact match in registry
461+ if ( fieldRegistry . has ( fieldType ) ) {
462+ return fieldRegistry . get ( fieldType ) ! ;
463+ }
464+
465+ // 2. Fallback to standard mappings if not overridden
466+ const standardMap : Record < string , React . FC < CellRendererProps > > = {
446467 text : TextCellRenderer ,
447468 textarea : TextCellRenderer ,
448469 markdown : TextCellRenderer ,
@@ -455,28 +476,38 @@ export function getCellRenderer(fieldType: string): React.FC<CellRendererProps>
455476 datetime : DateTimeCellRenderer ,
456477 time : TextCellRenderer ,
457478 select : SelectCellRenderer ,
479+ lookup : SelectCellRenderer , // Default fallback
480+ master_detail : SelectCellRenderer , // Default fallback
458481 email : EmailCellRenderer ,
459482 url : UrlCellRenderer ,
460483 phone : PhoneCellRenderer ,
461484 file : FileCellRenderer ,
462485 image : ImageCellRenderer ,
463- lookup : LookupCellRenderer ,
464- master_detail : LookupCellRenderer ,
465486 formula : FormulaCellRenderer ,
466487 summary : FormulaCellRenderer ,
467488 auto_number : TextCellRenderer ,
468489 user : UserCellRenderer ,
469490 owner : UserCellRenderer ,
470491 password : ( ) => < span > ••••••</ span > ,
471- location : TextCellRenderer ,
492+ location : TextCellRenderer , // Default fallback
472493 object : ( ) => < span className = "text-gray-500 italic" > [Object]</ span > ,
473494 vector : ( ) => < span className = "text-gray-500 italic" > [Vector]</ span > ,
474495 grid : ( ) => < span className = "text-gray-500 italic" > [Grid]</ span > ,
475496 } ;
476-
477- return rendererMap [ fieldType ] || TextCellRenderer ;
497+
498+ // 3. Register standard renderers implicitly if not present
499+ // This ensures that if we call registerFieldRenderer('text', Custom), it works,
500+ // but if we don't, we get the standard one.
501+ return standardMap [ fieldType ] || TextCellRenderer ;
478502}
479503
504+ // Register standard renderers immediately
505+ registerFieldRenderer ( 'lookup' , LookupCellRenderer ) ;
506+ registerFieldRenderer ( 'master_detail' , LookupCellRenderer ) ;
507+ registerFieldRenderer ( 'select' , SelectCellRenderer ) ;
508+
509+
510+
480511/**
481512 * Map field type to form component type
482513 *
0 commit comments