@@ -68,6 +68,20 @@ const TABLE_DEFAULT_TRANSLATIONS: Record<string, string> = {
6868 'table.rowsPerPage' : 'Rows per page' ,
6969 'table.pageInfo' : 'Page {{current}} of {{total}}' ,
7070 'table.totalRecords' : '{{count}} total' ,
71+ 'table.noResults' : 'No results found' ,
72+ 'table.noResultsHint' : 'Try adjusting your filters or search query.' ,
73+ 'table.sortAsc' : 'Sort ascending' ,
74+ 'table.sortDesc' : 'Sort descending' ,
75+ 'table.hideColumn' : 'Hide column' ,
76+ 'table.cancelAll' : 'Cancel All' ,
77+ 'table.saveAll' : 'Save All ({{count}})' ,
78+ 'table.exportCSV' : 'Export CSV' ,
79+ 'table.addRecord' : 'Add record' ,
80+ 'table.open' : 'Open' ,
81+ 'table.search' : 'Search...' ,
82+ 'table.modified' : '{{count}} row(s) modified' ,
83+ 'table.selected' : '{{count}} selected' ,
84+ 'common.actions' : 'Actions' ,
7185} ;
7286
7387/**
@@ -650,7 +664,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
650664 < div className = "relative w-full sm:max-w-sm flex-1" >
651665 < Search className = "absolute left-2 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground" />
652666 < Input
653- placeholder = "Search..."
667+ placeholder = { t ( 'table.search' ) }
654668 value = { searchQuery }
655669 onChange = { ( e ) => {
656670 setSearchQuery ( e . target . value ) ;
@@ -666,7 +680,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
666680 { hasPendingChanges && (
667681 < >
668682 < div className = "text-sm text-muted-foreground" >
669- { pendingChanges . size } row { pendingChanges . size > 1 ? 's' : '' } modified
683+ { t ( 'table.modified' , { count : pendingChanges . size } ) }
670684 </ div >
671685 < Button
672686 variant = "outline"
@@ -675,7 +689,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
675689 disabled = { isSaving }
676690 >
677691 < X className = "h-4 w-4 mr-2" />
678- Cancel All
692+ { t ( 'table.cancelAll' ) }
679693 </ Button >
680694 < Button
681695 variant = "default"
@@ -684,7 +698,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
684698 disabled = { isSaving }
685699 >
686700 < Save className = "h-4 w-4 mr-2" />
687- Save All ( { pendingChanges . size } )
701+ { t ( 'table.saveAll' , { count : pendingChanges . size } ) }
688702 </ Button >
689703 </ >
690704 ) }
@@ -697,13 +711,13 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
697711 disabled = { sortedData . length === 0 }
698712 >
699713 < Download className = "h-4 w-4 mr-2" />
700- Export CSV
714+ { t ( 'table.exportCSV' ) }
701715 </ Button >
702716 ) }
703717
704718 { selectable && selectedRowIds . size > 0 && (
705719 < div className = "text-sm text-muted-foreground" >
706- { selectedRowIds . size } selected
720+ { t ( 'table.selected' , { count : selectedRowIds . size } ) }
707721 </ div >
708722 ) }
709723 </ div >
@@ -717,15 +731,15 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
717731 < TableHeader className = "sticky top-0 bg-muted/30 z-10" >
718732 < TableRow >
719733 { selectable && (
720- < TableHead className = { cn ( "w-12 bg-muted/30" , frozenColumns > 0 && "sticky left-0 z-20" ) } >
734+ < TableHead className = { cn ( "w-10 bg-muted/30" , frozenColumns > 0 && "sticky left-0 z-20" ) } >
721735 < Checkbox
722736 checked = { allPageRowsSelected ? true : somePageRowsSelected ? 'indeterminate' : false }
723737 onCheckedChange = { handleSelectAll }
724738 />
725739 </ TableHead >
726740 ) }
727741 { showRowNumbers && (
728- < TableHead className = { cn ( "w-12 bg-muted/30 text-center" , frozenColumns > 0 && "sticky z-20" ) } style = { frozenColumns > 0 ? { left : selectable ? 48 : 0 } : undefined } >
742+ < TableHead className = { cn ( "w-10 bg-muted/30 text-center" , frozenColumns > 0 && "sticky z-20" ) } style = { frozenColumns > 0 ? { left : selectable ? 40 : 0 } : undefined } >
729743 < span className = "text-xs text-muted-foreground" > #</ span >
730744 </ TableHead >
731745 ) }
@@ -741,7 +755,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
741755 return sum + ( typeof w === 'number' ? w : w ? parseInt ( String ( w ) , 10 ) || 150 : 150 ) ;
742756 }
743757 return sum ;
744- } , ( selectable ? 48 : 0 ) + ( showRowNumbers ? 48 : 0 ) )
758+ } , ( selectable ? 40 : 0 ) + ( showRowNumbers ? 40 : 0 ) )
745759 : undefined ;
746760
747761 return (
@@ -797,7 +811,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
797811 ) ;
798812 } ) }
799813 { rowActions && (
800- < TableHead className = "w-24 text-right bg-muted/30" > Actions </ TableHead >
814+ < TableHead className = "w-24 text-right bg-muted/30" > { t ( 'common.actions' ) } </ TableHead >
801815 ) }
802816 </ TableRow >
803817 </ TableHeader >
@@ -811,8 +825,8 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
811825 >
812826 < div className = "flex flex-col items-center justify-center gap-2" >
813827 < Search className = "h-8 w-8 text-muted-foreground/50" />
814- < p > No results found </ p >
815- < p className = "text-xs text-muted-foreground/50" > Try adjusting your filters or search query. </ p >
828+ < p > { t ( 'table.noResults' ) } </ p >
829+ < p className = "text-xs text-muted-foreground/50" > { t ( 'table.noResultsHint' ) } </ p >
816830 </ div >
817831 </ TableCell >
818832 </ TableRow >
@@ -844,7 +858,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
844858 key = { rowId }
845859 data-state = { isSelected ? 'selected' : undefined }
846860 className = { cn (
847- "bg-background border-b border-border/50 hover:bg-muted/30 group/row" ,
861+ "bg-background border-b border-border hover:bg-muted/30 group/row" ,
848862 schema . onRowClick && "cursor-pointer" ,
849863 rowHasChanges && "bg-amber-50 dark:bg-amber-950/20" ,
850864 rowClassName && rowClassName ( row , rowIndex )
@@ -879,7 +893,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
879893 </ TableCell >
880894 ) }
881895 { showRowNumbers && (
882- < TableCell className = { cn ( "text-center w-12 relative" , frozenColumns > 0 && "sticky z-10 bg-background" ) } style = { frozenColumns > 0 ? { left : selectable ? 48 : 0 } : undefined } >
896+ < TableCell className = { cn ( "text-center w-10 relative" , frozenColumns > 0 && "sticky z-10 bg-background" ) } style = { frozenColumns > 0 ? { left : selectable ? 40 : 0 } : undefined } >
883897 < span className = { cn ( "text-xs text-muted-foreground tabular-nums select-none" , selectable ? "group-hover/row:hidden" : "group-hover/row:invisible" ) } >
884898 { globalIndex + 1 }
885899 </ span >
@@ -902,7 +916,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
902916 } }
903917 title = "Open record"
904918 >
905- < span > Open </ span >
919+ < span > { t ( 'table.open' ) } </ span >
906920 < ChevronRight className = "h-3 w-3" />
907921 </ button >
908922 ) }
@@ -923,7 +937,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
923937 return sum + ( typeof w === 'number' ? w : w ? parseInt ( String ( w ) , 10 ) || 150 : 150 ) ;
924938 }
925939 return sum ;
926- } , ( selectable ? 48 : 0 ) + ( showRowNumbers ? 48 : 0 ) )
940+ } , ( selectable ? 40 : 0 ) + ( showRowNumbers ? 40 : 0 ) )
927941 : undefined ;
928942
929943 return (
@@ -1016,7 +1030,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
10161030 { /* Add record row (Airtable-style) */ }
10171031 { showAddRow && (
10181032 < TableRow
1019- className = "hover:bg-muted/30 cursor-pointer border-b border-border/50 "
1033+ className = "hover:bg-muted/30 cursor-pointer border-b border-border"
10201034 data-testid = "add-record-row"
10211035 onClick = { ( ) => schema . onAddRecord ?.( ) }
10221036 >
@@ -1026,15 +1040,15 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
10261040 >
10271041 < span className = "flex items-center gap-1.5 text-muted-foreground text-sm hover:text-foreground transition-colors" >
10281042 < Plus className = "h-3.5 w-3.5" />
1029- Add record
1043+ { t ( 'table.addRecord' ) }
10301044 </ span >
10311045 </ TableCell >
10321046 </ TableRow >
10331047 ) }
10341048 { /* Filler rows to maintain height consistency (only when pagination is enabled) */ }
10351049 { pagination && paginatedData . length > 0 && Array . from ( { length : Math . max ( 0 , pageSize - paginatedData . length ) } ) . map ( ( _ , i ) => (
10361050 < TableRow key = { `empty-${ i } ` } className = "hover:bg-transparent" >
1037- < TableCell colSpan = { columns . length + ( selectable ? 1 : 0 ) + ( rowActions ? 1 : 0 ) } className = "h-[52px] p-0" />
1051+ < TableCell colSpan = { columns . length + ( selectable ? 1 : 0 ) + ( showRowNumbers ? 1 : 0 ) + ( rowActions ? 1 : 0 ) } className = "h-[52px] p-0" />
10381052 </ TableRow >
10391053 ) ) }
10401054 </ >
@@ -1130,7 +1144,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
11301144 } }
11311145 >
11321146 < ChevronUp className = "h-3.5 w-3.5" />
1133- Sort ascending
1147+ { t ( 'table.sortAsc' ) }
11341148 </ button >
11351149 < button
11361150 type = "button"
@@ -1142,7 +1156,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
11421156 } }
11431157 >
11441158 < ChevronDown className = "h-3.5 w-3.5" />
1145- Sort descending
1159+ { t ( 'table.sortDesc' ) }
11461160 </ button >
11471161 < div className = "my-1 h-px bg-border" />
11481162 </ >
@@ -1153,7 +1167,7 @@ const DataTableRenderer = ({ schema }: { schema: DataTableSchema }) => {
11531167 onClick = { ( ) => hideColumn ( contextMenu . columnKey ) }
11541168 >
11551169 < X className = "h-3.5 w-3.5" />
1156- Hide column
1170+ { t ( 'table.hideColumn' ) }
11571171 </ button >
11581172 </ div >
11591173 ) }
0 commit comments