build method
Describes the part of the UI represented by this widget.
Implementation
@override
Widget build(BuildContext context) {
final theme = ThemeScope.of(context);
final bg = background ?? theme.surface;
final accent = _accentColor(theme);
final badgeStyle = _copyStyle(theme.labelMedium)
..foreground(_badgeFgColor(theme))
..background(_badgeBgColor(theme))
..bold();
final titleStyle = _copyStyle(theme.titleSmall)
..foreground(theme.onSurface)
..bold();
final dimStyle = _copyStyle(theme.bodySmall)..foreground(theme.muted);
final headerStyle = _copyStyle(theme.labelSmall)
..foreground(theme.border)
..bold();
final detailStyle = _copyStyle(theme.bodySmall)..foreground(theme.border);
final children = <Widget>[];
// Row 1: traffic-light badge + action label
children.add(
Row(
gap: 1,
children: [
Text(' ${data.signal.label} ', style: badgeStyle),
Text(data.actionLabel, style: titleStyle),
],
),
);
// Row 2: explanation (level >= plainEnglish)
if (data.level.index >= DisclosureLevel.plainEnglish.index &&
data.explanation != null) {
children.add(Text(data.explanation!, style: dimStyle));
}
// Evidence terms (level >= evidenceTerms)
if (data.level.index >= DisclosureLevel.evidenceTerms.index &&
data.evidence != null &&
data.evidence!.isNotEmpty) {
children.add(Text('Evidence:', style: headerStyle));
for (final term in data.evidence!) {
final dirChar = switch (term.direction) {
EvidenceDirection.supporting => '+',
EvidenceDirection.opposing => '-',
EvidenceDirection.neutral => '~',
};
final dirStyle = _copyStyle(theme.bodySmall)
..foreground(_evidenceFgColor(theme, term.direction));
children.add(
Text(
' $dirChar ${term.label}: BF=${term.factor.toStringAsFixed(2)}',
style: dirStyle,
),
);
}
}
// Full details (level >= fullDetails)
if (data.level.index >= DisclosureLevel.fullDetails.index &&
data.details != null) {
final d = data.details!;
children.add(Text('─' * 20, style: dimStyle));
final lossStr = d.lossAvoided != null
? ' loss=${d.expectedLoss.toStringAsFixed(4)} avoided=${d.lossAvoided!.toStringAsFixed(4)}'
: ' loss=${d.expectedLoss.toStringAsFixed(4)}';
children.add(
Text(
'log_post=${d.logPosterior.toStringAsFixed(3)} CI=[${d.confidenceLow.toStringAsFixed(3)},${d.confidenceHigh.toStringAsFixed(3)}]$lossStr',
style: detailStyle,
),
);
}
return Frame(
padding: padding ?? const EdgeInsets.all(1),
background: bg,
border: border ?? Border.rounded,
borderColor: accent,
child: Column(gap: 0, children: children),
);
}