customCellsDataGrid function
- @Preview(name: 'Custom Cells Data Grid')
Widget
customCellsDataGrid(
)
Implementation
@Preview(name: 'Custom Cells Data Grid')
Widget customCellsDataGrid() {
final employees = List.generate(
30,
(index) => {
'id': index + 1,
'name': ['John Doe', 'Jane Smith', 'Bob Johnson', 'Alice Brown'][index % 4],
'department': ['Engineering', 'Sales', 'HR', 'Marketing'][index % 4],
'salary': 50000 + (index * 2500),
'performance': (index % 5) * 20 + 20,
'active': index % 3 != 0,
},
);
final dataSource = _LocalDataGridSource(data: employees);
final controller = VooDataGridController(
dataSource: dataSource,
columns: [
VooDataColumn<dynamic>(
field: 'name',
label: 'Employee',
flex: 2,
cellBuilder: (context, value, row) {
final name = value as String;
final initials = name.split(' ').map((e) => e.isNotEmpty ? e[0] : '').take(2).join();
return Row(
children: [
CircleAvatar(
radius: 14,
backgroundColor: Colors.blue.withValues(alpha: 0.2),
child: Text(initials, style: const TextStyle(fontSize: 10, color: Colors.blue)),
),
const SizedBox(width: 8),
Text(name),
],
);
},
),
VooDataColumn<dynamic>(
field: 'department',
label: 'Department',
width: 120,
cellBuilder: (context, value, row) {
final dept = value as String;
final colors = {'Engineering': Colors.blue, 'Sales': Colors.green, 'HR': Colors.orange, 'Marketing': Colors.purple};
return Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
decoration: BoxDecoration(
color: (colors[dept] ?? Colors.grey).withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: (colors[dept] ?? Colors.grey).withValues(alpha: 0.3)),
),
child: Text(dept, style: TextStyle(color: colors[dept] ?? Colors.grey, fontSize: 12)),
);
},
),
VooDataColumn<dynamic>(field: 'salary', label: 'Salary', width: 100, valueFormatter: (value) => '\$${(value / 1000).toStringAsFixed(0)}k'),
VooDataColumn<dynamic>(
field: 'performance',
label: 'Performance',
width: 120,
cellBuilder: (context, value, row) {
final performance = value as int;
final color = performance >= 80
? Colors.green
: performance >= 60
? Colors.orange
: Colors.red;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('$performance%', style: const TextStyle(fontSize: 10)),
const SizedBox(height: 2),
LinearProgressIndicator(
value: performance / 100,
backgroundColor: Colors.grey.withValues(alpha: 0.2),
valueColor: AlwaysStoppedAnimation(color),
minHeight: 3,
),
],
);
},
),
VooDataColumn<dynamic>(
field: 'active',
label: 'Status',
width: 80,
cellBuilder: (context, value, row) {
final active = value as bool;
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 8,
height: 8,
decoration: BoxDecoration(color: active ? Colors.green : Colors.grey, shape: BoxShape.circle),
),
const SizedBox(width: 4),
Text(active ? 'Active' : 'Inactive', style: TextStyle(fontSize: 11, color: active ? Colors.green : Colors.grey)),
],
);
},
),
],
);
dataSource.loadData();
return Material(
child: SizedBox(height: 450, child: VooDataGrid(controller: controller)),
);
}