Skip to main content

Theming

Follow the host app's theme (automatic)

Every color the grid draws falls back to Theme.of(context).colorScheme when you leave the style config field null. So a grid inside another app's MaterialApp follows that app's ThemeData — including dark mode — with zero configuration.

MaterialApp(
theme: myAppTheme, // <-- the grid follows THIS
darkTheme: ThemeData.dark(),
home: BCellGrid(columns: cols, rows: rows),
)

Theme fallbacks:

Grid partColorScheme role
header backgroundsurfaceContainerHighest
row backgroundsurface
selectionprimaryContainer
grid borderoutline
cell borderoutlineVariant
header texttextTheme.titleSmall
cell texttextTheme.bodyMedium
sort iconambient IconTheme
fill handle (drag square)activatedColor
fill handle outlinesurface

Override specific colors

Pass a BCellGridStyleConfig only for the parts you want to pin; the rest still follow the theme.

BCellGrid(
columns: cols,
rows: rows,
configuration: BCellGridConfiguration(
style: BCellGridStyleConfig(
rowHeight: 44,
columnHeight: 48,
activatedColor: Colors.teal.shade100, // selection
oddRowColor: Theme.of(context).colorScheme // zebra striping (null = off)
.primary.withValues(alpha: 0.06),
// columnTextStyle / cellTextStyle: copyWith the theme style so text
// color + family keep following the theme.
columnTextStyle: Theme.of(context).textTheme.titleSmall
?.copyWith(fontWeight: FontWeight.bold),
// Metrics & small parts (defaults shown):
defaultColumnTitlePadding: EdgeInsets.symmetric(horizontal: 8),
defaultCellPadding: EdgeInsets.symmetric(horizontal: 8),
iconSize: 14, // header sort icon
iconColor: null, // null = inherit IconTheme
fillHandleSize: 8, // drag-fill square on the focused cell
fillHandleColor: null, // null = activatedColor
fillHandleBorderColor: null, // null = colorScheme.surface
),
),
)

Rows are fixed-extent: vertical defaultCellPadding must fit within rowHeight, or it squeezes the cell content instead of growing the row.

Per-column / per-cell color

Color one column's cells by value with cellStyle (lighter than a full renderer — use it when you only need color):

BCellColumn(
title: 'Amount', field: 'amount', type: BCellColumnType.number(),
cellStyle: (ctx) {
final v = ctx.cell.value as num? ?? 0;
if (v < 0) return const BCellStyle(textStyle: TextStyle(color: Colors.red));
return const BCellStyle(backgroundColor: Color(0xFFE8F5E9));
},
)

BCellStyle carries backgroundColor and/or textStyle. Return null for the default look. To use theme colors here, read Theme.of(context).colorScheme.* and pass them in.

For a full custom cell widget (icons, links, rich text), use renderer instead — see Cell renderers.

Data-driven color (conditional formatting)

Color-scale / data-bar / icon-set over a numeric column:

BCellColumn(
title: 'Score', field: 'score', type: BCellColumnType.number(),
renderer: BCellConditionalFormat.colorScale(stateManager, useMid: true).toRenderer(),
// also: .dataBar(stateManager).toRenderer(), .iconSet(stateManager).toRenderer()
)

Broadcast a font to many grids

BCellFontScope pushes one font to every BCell widget below it (grid + pager + tab bar) through a single controller:

final font = BCellFontController();

BCellFontScope(
controller: font,
child: Column(children: [
Expanded(child: BCellGrid(columns: cols, rows: rows)),
BCellPagination(stateManager),
]),
);

font.setFont(const TextStyle(fontFamily: 'serif')); // null = theme default