M3 Overhaul
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// M3 Expressive Card variants.
|
||||
///
|
||||
/// Use these factory constructors to build semantically correct cards:
|
||||
/// - [M3Card.elevated] — default, uses tonal surface tint (no hard shadow).
|
||||
/// - [M3Card.filled] — uses surfaceContainerHighest for emphasis.
|
||||
/// - [M3Card.outlined] — transparent fill with a subtle outline border.
|
||||
|
||||
class M3Card extends StatelessWidget {
|
||||
const M3Card._({
|
||||
required this.child,
|
||||
this.color,
|
||||
this.elevation,
|
||||
this.shadowColor,
|
||||
this.surfaceTintColor,
|
||||
this.shape,
|
||||
this.margin,
|
||||
this.clipBehavior = Clip.none,
|
||||
this.onTap,
|
||||
});
|
||||
|
||||
/// Elevated card — tonal surface tint, minimal shadow.
|
||||
/// Best for primary content surfaces (metric cards, detail panels).
|
||||
factory M3Card.elevated({
|
||||
required Widget child,
|
||||
Color? color,
|
||||
ShapeBorder? shape,
|
||||
EdgeInsetsGeometry? margin,
|
||||
Clip clipBehavior = Clip.none,
|
||||
VoidCallback? onTap,
|
||||
}) {
|
||||
return M3Card._(
|
||||
color: color,
|
||||
elevation: 1,
|
||||
shadowColor: Colors.transparent,
|
||||
shape: shape,
|
||||
margin: margin,
|
||||
clipBehavior: clipBehavior,
|
||||
onTap: onTap,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
/// Filled card — uses surfaceContainerHighest for high emphasis.
|
||||
/// Best for summary cards, status counts, callout panels.
|
||||
factory M3Card.filled({
|
||||
required Widget child,
|
||||
Color? color,
|
||||
ShapeBorder? shape,
|
||||
EdgeInsetsGeometry? margin,
|
||||
Clip clipBehavior = Clip.none,
|
||||
VoidCallback? onTap,
|
||||
}) {
|
||||
return M3Card._(
|
||||
color: color, // caller passes surfaceContainerHighest or semantic color
|
||||
elevation: 0,
|
||||
shadowColor: Colors.transparent,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
shape: shape,
|
||||
margin: margin,
|
||||
clipBehavior: clipBehavior,
|
||||
onTap: onTap,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
/// Outlined card — transparent fill with outline border.
|
||||
/// Best for list items, form sections, grouped content.
|
||||
factory M3Card.outlined({
|
||||
required Widget child,
|
||||
Color? color,
|
||||
ShapeBorder? shape,
|
||||
EdgeInsetsGeometry? margin,
|
||||
Clip clipBehavior = Clip.none,
|
||||
VoidCallback? onTap,
|
||||
}) {
|
||||
return M3Card._(
|
||||
color: color,
|
||||
elevation: 0,
|
||||
shadowColor: Colors.transparent,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
shape: shape,
|
||||
margin: margin,
|
||||
clipBehavior: clipBehavior,
|
||||
onTap: onTap,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
final Widget child;
|
||||
final Color? color;
|
||||
final double? elevation;
|
||||
final Color? shadowColor;
|
||||
final Color? surfaceTintColor;
|
||||
final ShapeBorder? shape;
|
||||
final EdgeInsetsGeometry? margin;
|
||||
final Clip clipBehavior;
|
||||
final VoidCallback? onTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final cs = Theme.of(context).colorScheme;
|
||||
|
||||
// For outlined, we need the border side
|
||||
final resolvedShape =
|
||||
shape ??
|
||||
(elevation == 0 && surfaceTintColor == Colors.transparent
|
||||
? RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
side: (shadowColor == Colors.transparent && color == null)
|
||||
? BorderSide(color: cs.outlineVariant)
|
||||
: BorderSide.none,
|
||||
)
|
||||
: null);
|
||||
|
||||
final card = Card(
|
||||
color: color,
|
||||
elevation: elevation,
|
||||
shadowColor: shadowColor,
|
||||
surfaceTintColor: surfaceTintColor,
|
||||
shape: resolvedShape,
|
||||
margin: margin ?? EdgeInsets.zero,
|
||||
clipBehavior: clipBehavior,
|
||||
child: onTap != null
|
||||
? InkWell(
|
||||
onTap: onTap,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
child: child,
|
||||
)
|
||||
: child,
|
||||
);
|
||||
|
||||
return card;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user