Files
2026-07-27 14:42:23 +02:00

89 lines
3.0 KiB
Dart

import 'package:flutter/material.dart';
import '../theme/status_colors.dart';
import '../theme/theme_x.dart';
/// A dashboard summary tile: an uppercase label, a large tabular-nums value
/// (with an optional muted trailing qualifier, e.g. "7 / 9"), a caption, and
/// a left severity stripe communicating worst-case state at a glance —
/// severity is a first-class visual channel here, not just the number.
class StatTile extends StatelessWidget {
const StatTile({
super.key,
required this.label,
required this.value,
this.valueQualifier,
this.caption,
this.severity = Severity.good,
});
final String label;
final String value;
final String? valueQualifier;
final String? caption;
final Severity severity;
@override
Widget build(BuildContext context) {
final stripeColor = severity.resolve(context.status, muted: context.colors.outline);
return Container(
decoration: BoxDecoration(
color: context.colors.surface,
borderRadius: BorderRadius.circular(9),
border: Border.all(color: context.colors.outlineVariant),
boxShadow: [
BoxShadow(color: Colors.black.withValues(alpha: 0.04), blurRadius: 2, offset: const Offset(0, 1)),
],
),
clipBehavior: Clip.antiAlias,
child: IntrinsicHeight(
child: Row(
children: [
Container(width: 3, color: stripeColor),
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(13, 14, 13, 14),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(label, style: context.text.titleSmall),
const SizedBox(height: 8),
Text.rich(
TextSpan(
style: context.dataStyles.numericTabular.copyWith(
fontSize: 24,
fontWeight: FontWeight.w700,
letterSpacing: -0.3,
),
children: [
TextSpan(text: value),
if (valueQualifier != null)
TextSpan(
text: ' $valueQualifier',
style: context.text.bodyMedium?.copyWith(fontWeight: FontWeight.w500),
),
],
),
),
if (caption != null) ...[
const SizedBox(height: 4),
Text(
caption!,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: context.text.bodySmall,
),
],
],
),
),
),
],
),
),
);
}
}