DynamicDataTable
A production-grade, highly customizable Flutter data table widget with sorting, filtering, pagination, row selection, and pluggable export formats. 100% pub.dev ready with zero app-level dependencies.
Features
✅ Row Selection - Checkboxes with select-all functionality
✅ Loading & Error States - Spinner overlay & error messaging
✅ Sort Indicators - Visual arrows with hover tooltips
✅ Search & Filter - Local & remote search support
✅ Pagination - Page navigation with size selection
✅ Export System - Pluggable Excel/CSV/custom formats
✅ i18n Ready - All strings in TableConfig
✅ Accessibility - Semantic widgets & ARIA labels
✅ Custom Builders - Cell, filter, & export value builders
✅ Date Filter - Calendar picker UI
Demo

Customers table built with DynamicDataTable featuring search, filtering, sorting, row selection, and bulk actions.
Quick Start
import 'package:dynamic_data_table/dynamic_data_table.dart';
class MyTable extends StatefulWidget {
@override
State<MyTable> createState() => _MyTableState();
}
class _MyTableState extends State<MyTable> {
@override
Widget build(BuildContext context) {
return DynamicDataTable<Item>(
data: items,
columns: [
ColumnDef<Item>(
id: 'name',
label: 'Product Name',
sortable: true,
cellBuilder: (item) => DataCell(Text(item.name)),
),
ColumnDef<Item>(
id: 'price',
label: 'Price',
sortable: true,
cellBuilder: (item) => DataCell(Text('\$${item.price}')),
),
],
config: TableConfig(
searchHint: 'Search products...',
enableRowSelection: true,
),
);
}
}
Core Features
1. Row Selection
Enable bulk operations with checkbox column:
DynamicDataTable<Item>(
enableRowSelection: true,
onRowSelectionChanged: (selectedItems) {
setState(() => selected = selectedItems);
},
config: TableConfig(selectAllLabel: 'Select All Items'),
)
2. Loading & Error States
Show spinners and error messages:
DynamicDataTable<Item>(
loadingState: isLoading ? TableLoadingState.loading : TableLoadingState.idle,
errorMessage: error?.message,
)
3. Sort Indicators
Visual sorting with column clicks:
ColumnDef<Item>(
id: 'name',
label: 'Name',
sortable: true, // Show up/down arrow
onSort: (index, ascending) => fetchSorted(ascending),
)
4. Search & Filter
Local and remote search:
DynamicDataTable<Item>(
onSearch: (term) => fetchRemoteData(term),
searchStringBuilder: (item) => '${item.name} ${item.id}',
)
5. Pagination
Navigate large datasets:
DynamicDataTable<Item>(
pagination: Pagination(page: 1, limit: 25, totalPages: 10),
onPageChanged: (newPage, pageSize) => fetchPage(newPage),
)
6. Custom Export
Pluggable export formats:
class CsvExporter extends TableExporter {
@override
String get format => 'csv';
@override
Future<void> export<T>({...}) async { ... }
}
7. i18n Configuration
All strings centralized in TableConfig:
config: TableConfig(
searchHint: context.l10n.search,
filterLabel: context.l10n.filter,
exportLabel: context.l10n.export,
)
8. Date Filtering
Calendar-based filtering:
DynamicDataTable<Item>(
enableDateFilter: true,
onDateFilterChanged: (filter) => refetch(filter),
)
API Reference
DynamicDataTable
Main widget class.
Parameters:
data- List of items to displaycolumns- List ofColumnDef<T>column definitionsconfig-TableConfigwith settings & i18n stringsenableRowSelection- Show checkbox column (default: false)onRowSelectionChanged- Callback with selected itemsloadingState-TableLoadingState.idle,.loading, or.errorerrorMessage- Error text to display when state is.errorpagination-Paginationobject for page infoonPageChanged- Callback on page/size changeonSearch- Remote search callbacksearchStringBuilder- Build searchable text per itemenableDateFilter- Show date filter (default: false)onDateFilterChanged- Date range selection callbackonRowTap- Row click handleremptyState- Custom empty state widget
ColumnDef
Column configuration.
Parameters:
id- Unique column identifierlabel- Display namesortable- Enable sort UI (default: true)exportable- Include in exports (default: true)filterable- Show filter button (default: true)cellBuilder- Custom cell widgetfilterValueBuilder- Extract filter valueexportValueBuilder- Custom export valueresizable- Allow width changes (default: true)flexFactor- Column flex allocation (default: 1)size- ColumnSize.S, .M, .LonSort- Sort callback
TableConfig
Configuration object with strings & flags.
Parameters:
searchHint- Placeholder textfilterLabel- Filter button labelexportLabel- Export button labelselectAllLabel- Select all checkbox labelapplyLabel- Dialog apply buttoncancelLabel- Dialog cancel buttonenableRowSelection- Feature flagenableLoadingState- Feature flagenableSortIndicators- Feature flagenableKeyboardNavigation- Feature flagcanExport- Permission callback:() => bool
Advanced Usage
Custom Cell Builder
ColumnDef<Item>(
id: 'status',
label: 'Status',
cellBuilder: (item) => DataCell(
Container(
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: item.status == 'Active' ? Colors.green : Colors.red,
borderRadius: BorderRadius.circular(4),
),
child: Text(item.status),
),
),
)
Remote Search with Debounce
DynamicDataTable<Item>(
onSearch: (term) {
if (term.isEmpty) {
fetchAllItems();
} else {
searchRemote(term);
}
},
)
Bulk Actions on Selection
if (selectedItems.isNotEmpty) {
ElevatedButton(
onPressed: () => bulkDelete(selectedItems),
child: Text('Delete ${selectedItems.length}'),
)
}
Testing
testWidgets('selects rows', (tester) async {
final items = [Item(id: '1', name: 'Test')];
await tester.pumpWidget(
MaterialApp(
home: DynamicDataTable<Item>(
data: items,
columns: [...],
enableRowSelection: true,
config: TableConfig(),
),
),
);
expect(find.byType(Checkbox), findsWidgets);
});
FAQ
Q: How do I add custom export formats?
A: Extend TableExporter and pass to the config.
Q: Is this i18n compatible?
A: Yes, all strings are in TableConfig. Pass localized strings per language.
Q: Does it support infinite scroll?
A: Not yet, but pagination works for large datasets.
Q: Can I customize colors/theme?
A: Yes, use Flutter's Theme data and custom cell builders.
Troubleshooting
Empty table shows no data?
Check data is populated and columns have cellBuilder.
Sort not working?
Ensure column has sortable: true and onSort callback.
Export button not showing?
Check canExport() returns true in TableConfig.
Performance slow with large datasets?
Use pagination or implement virtual scrolling with the custom builder.
License
MIT
Contributing
Contributions welcome! File issues or PRs at the repo.
Support
For issues, questions, or feature requests, visit the GitHub repository.
Libraries
- dynamic_data_table
- A production-grade Flutter data table widget with sorting, filtering, pagination, row selection, and pluggable export formats.