import 'package:flutter/material.dart'; import 'package:tatlock_ui/shared/components/data_grid/data_grid_column.dart'; import 'package:tatlock_ui/shared/components/data_grid/data_grid_config.dart'; import 'package:tatlock_ui/shared/components/data_grid/widgets/data_grid_actions_menu.dart'; /// A single data row in the DataGrid. class DataGridRow extends StatelessWidget { const DataGridRow({ super.key, required this.item, required this.index, required this.config, this.isSelected = false, this.onSelect, this.onTap, this.backgroundColor, }); final T item; final int index; final DataGridConfig config; final bool isSelected; final VoidCallback? onSelect; final VoidCallback? onTap; final Color? backgroundColor; @override Widget build(BuildContext context) { final colorScheme = Theme.of(context).colorScheme; final columns = config.visibleColumns; // Determine row background color Color? bgColor = backgroundColor; if (bgColor == null && config.alternatingRowColors) { bgColor = index.isOdd ? colorScheme.surfaceContainerLowest : colorScheme.surface; } if (isSelected) { bgColor = colorScheme.primaryContainer.withValues(alpha: 0.3); } final rowContent = Container( height: config.rowHeight, constraints: config.rowHeight == null ? const BoxConstraints(minHeight: 48) : null, decoration: BoxDecoration( color: bgColor, border: Border( bottom: BorderSide( color: colorScheme.outlineVariant.withValues(alpha: 0.5), ), ), ), child: Row( children: [ if (config.rowsSelectable) SizedBox( width: 56, child: Center( child: Checkbox( value: isSelected, onChanged: (_) => onSelect?.call(), ), ), ), ...columns.map((column) => _buildCell(context, column)), if (config.actions.isNotEmpty) SizedBox( width: 56, child: DataGridActionsMenu( item: item, actions: config.actions, ), ), ], ), ); if (onTap != null) { return InkWell( onTap: onTap, child: rowContent, ); } return rowContent; } Widget _buildCell(BuildContext context, DataGridColumn column) { Widget content; if (column.cellBuilder != null) { content = column.cellBuilder!(context, item); } else { content = Text( column.valueBuilder(item), textAlign: column.textAlign, overflow: TextOverflow.ellipsis, ); } // Wrap with controls if provided if (column.cellControlsBuilder != null) { content = Row( mainAxisSize: MainAxisSize.min, children: [ Flexible(child: content), const SizedBox(width: 8), column.cellControlsBuilder!(context, item), ], ); } // Wrap with tooltip if provided if (column.tooltip != null) { content = Tooltip( message: column.tooltip!(item), child: content, ); } final cell = Padding( padding: config.cellPadding, child: Align( alignment: switch (column.alignment) { DataGridColumnAlignment.start => Alignment.centerLeft, DataGridColumnAlignment.center => Alignment.center, DataGridColumnAlignment.end => Alignment.centerRight, }, child: content, ), ); return _wrapWithWidth(column.width, cell); } Widget _wrapWithWidth(DataGridColumnWidth width, Widget child) { return switch (width) { GridFixedWidth(:final width) => SizedBox(width: width, child: child), GridFlexWidth(:final flex) => Expanded(flex: flex, child: child), GridFractionWidth(:final fraction) => FractionallySizedBox( widthFactor: fraction, child: child, ), }; } }