Unverified Commit 8612f80a authored by Hans Muller's avatar Hans Muller Committed by GitHub

ChipThemeData is now conventional (#93452)

parent 297a7c75
...@@ -225,8 +225,15 @@ abstract class DeletableChipAttributes { ...@@ -225,8 +225,15 @@ abstract class DeletableChipAttributes {
/// {@end-tool} /// {@end-tool}
VoidCallback? get onDeleted; VoidCallback? get onDeleted;
/// The [Color] for the delete icon. The default is based on the ambient /// Used to define the delete icon's color with an [IconTheme] that
/// [IconThemeData.color]. /// contains the icon.
///
/// The default is `Color(0xde000000)`
/// (slightly transparent black) for light themes, and `Color(0xdeffffff)`
/// (slightly transparent white) for dark themes.
///
/// The delete icon appears if [DeletableChipAttributes.onDeleted] is
/// non-null.
Color? get deleteIconColor; Color? get deleteIconColor;
/// Whether to use a tooltip on the chip's delete button showing the /// Whether to use a tooltip on the chip's delete button showing the
...@@ -423,7 +430,8 @@ abstract class DisabledChipAttributes { ...@@ -423,7 +430,8 @@ abstract class DisabledChipAttributes {
/// Defaults to true. Cannot be null. /// Defaults to true. Cannot be null.
bool get isEnabled; bool get isEnabled;
/// Color to be used for the chip's background indicating that it is disabled. /// The color used for the chip's background to indicate that it is not
/// enabled.
/// ///
/// The chip is disabled when [isEnabled] is false, or all three of /// The chip is disabled when [isEnabled] is false, or all three of
/// [SelectableChipAttributes.onSelected], [TappableChipAttributes.onPressed], /// [SelectableChipAttributes.onSelected], [TappableChipAttributes.onPressed],
...@@ -1708,25 +1716,35 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid ...@@ -1708,25 +1716,35 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
widget.onPressed?.call(); widget.onPressed?.call();
} }
OutlinedBorder _getShape(ChipThemeData theme) { OutlinedBorder _getShape(ThemeData theme, ChipThemeData chipTheme, ChipThemeData chipDefaults) {
final BorderSide? resolvedSide = MaterialStateProperty.resolveAs<BorderSide?>(widget.side, materialStates) final BorderSide? resolvedSide = MaterialStateProperty.resolveAs<BorderSide?>(widget.side, materialStates)
?? MaterialStateProperty.resolveAs<BorderSide?>(theme.side, materialStates); ?? MaterialStateProperty.resolveAs<BorderSide?>(chipTheme.side, materialStates)
?? MaterialStateProperty.resolveAs<BorderSide?>(chipDefaults.side, materialStates);
final OutlinedBorder resolvedShape = MaterialStateProperty.resolveAs<OutlinedBorder?>(widget.shape, materialStates) final OutlinedBorder resolvedShape = MaterialStateProperty.resolveAs<OutlinedBorder?>(widget.shape, materialStates)
?? MaterialStateProperty.resolveAs<OutlinedBorder?>(theme.shape, materialStates) ?? MaterialStateProperty.resolveAs<OutlinedBorder?>(chipTheme.shape, materialStates)
?? MaterialStateProperty.resolveAs<OutlinedBorder?>(chipDefaults.shape, materialStates)
?? const StadiumBorder(); ?? const StadiumBorder();
return resolvedShape.copyWith(side: resolvedSide); return resolvedShape.copyWith(side: resolvedSide);
} }
/// Picks between three different colors, depending upon the state of two /// Picks between three different colors, depending upon the state of two
/// different animations. /// different animations.
Color? getBackgroundColor(ChipThemeData theme) { Color? _getBackgroundColor(ThemeData theme, ChipThemeData chipTheme, ChipThemeData chipDefaults) {
final ColorTween backgroundTween = ColorTween( final ColorTween backgroundTween = ColorTween(
begin: widget.disabledColor ?? theme.disabledColor, begin: widget.disabledColor
end: widget.backgroundColor ?? theme.backgroundColor, ?? chipTheme.disabledColor
?? theme.disabledColor,
end: widget.backgroundColor
?? chipTheme.backgroundColor
?? theme.chipTheme.backgroundColor
?? chipDefaults.backgroundColor,
); );
final ColorTween selectTween = ColorTween( final ColorTween selectTween = ColorTween(
begin: backgroundTween.evaluate(enableController), begin: backgroundTween.evaluate(enableController),
end: widget.selectedColor ?? theme.selectedColor, end: widget.selectedColor
?? chipTheme.selectedColor
?? theme.chipTheme.selectedColor
?? chipDefaults.selectedColor,
); );
return selectTween.evaluate(selectionFade); return selectTween.evaluate(selectionFade);
} }
...@@ -1788,6 +1806,7 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid ...@@ -1788,6 +1806,7 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
BuildContext context, BuildContext context,
ThemeData theme, ThemeData theme,
ChipThemeData chipTheme, ChipThemeData chipTheme,
ChipThemeData chipDefaults,
) { ) {
if (!hasDeleteButton) { if (!hasDeleteButton) {
return null; return null;
...@@ -1796,7 +1815,9 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid ...@@ -1796,7 +1815,9 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
container: true, container: true,
button: true, button: true,
child: _wrapWithTooltip( child: _wrapWithTooltip(
tooltip: widget.useDeleteButtonTooltip ? widget.deleteButtonTooltipMessage ?? MaterialLocalizations.of(context).deleteButtonTooltip : null, tooltip: widget.useDeleteButtonTooltip
? widget.deleteButtonTooltipMessage ?? MaterialLocalizations.of(context).deleteButtonTooltip
: null,
enabled: widget.onDeleted != null, enabled: widget.onDeleted != null,
child: InkWell( child: InkWell(
// Radius should be slightly less than the full size of the chip. // Radius should be slightly less than the full size of the chip.
...@@ -1806,7 +1827,10 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid ...@@ -1806,7 +1827,10 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
onTap: widget.isEnabled ? widget.onDeleted : null, onTap: widget.isEnabled ? widget.onDeleted : null,
child: IconTheme( child: IconTheme(
data: theme.iconTheme.copyWith( data: theme.iconTheme.copyWith(
color: widget.deleteIconColor ?? chipTheme.deleteIconColor, color: widget.deleteIconColor
?? chipTheme.deleteIconColor
?? theme.chipTheme.deleteIconColor
?? chipDefaults.deleteIconColor,
), ),
child: widget.deleteIcon, child: widget.deleteIcon,
), ),
...@@ -1838,19 +1862,53 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid ...@@ -1838,19 +1862,53 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
final ThemeData theme = Theme.of(context); final ThemeData theme = Theme.of(context);
final ChipThemeData chipTheme = ChipTheme.of(context); final ChipThemeData chipTheme = ChipTheme.of(context);
final Brightness brightness = chipTheme.brightness ?? theme.brightness;
final ChipThemeData chipDefaults = ChipThemeData.fromDefaults(
brightness: brightness,
secondaryColor: brightness == Brightness.dark ? Colors.tealAccent[200]! : theme.primaryColor,
labelStyle: theme.textTheme.bodyText1!,
);
final TextDirection? textDirection = Directionality.maybeOf(context); final TextDirection? textDirection = Directionality.maybeOf(context);
final OutlinedBorder resolvedShape = _getShape(chipTheme); final OutlinedBorder resolvedShape = _getShape(theme, chipTheme, chipDefaults);
final double elevation = widget.elevation ?? chipTheme.elevation ?? _defaultElevation;
final double pressElevation = widget.pressElevation ?? chipTheme.pressElevation ?? _defaultPressElevation; final double elevation = widget.elevation
final Color shadowColor = widget.shadowColor ?? chipTheme.shadowColor ?? _defaultShadowColor; ?? chipTheme.elevation
final Color selectedShadowColor = widget.selectedShadowColor ?? chipTheme.selectedShadowColor ?? _defaultShadowColor; ?? theme.chipTheme.elevation
final Color? checkmarkColor = widget.checkmarkColor ?? chipTheme.checkmarkColor; ?? _defaultElevation;
final bool showCheckmark = widget.showCheckmark ?? chipTheme.showCheckmark ?? true; final double pressElevation = widget.pressElevation
?? chipTheme.pressElevation
final TextStyle effectiveLabelStyle = chipTheme.labelStyle.merge(widget.labelStyle); ?? theme.chipTheme.pressElevation
?? _defaultPressElevation;
final Color shadowColor = widget.shadowColor
?? chipTheme.shadowColor
?? theme.chipTheme.shadowColor
?? _defaultShadowColor;
final Color selectedShadowColor = widget.selectedShadowColor
?? chipTheme.selectedShadowColor
?? theme.chipTheme.selectedShadowColor
?? _defaultShadowColor;
final Color? checkmarkColor = widget.checkmarkColor
?? chipTheme.checkmarkColor
?? theme.chipTheme.checkmarkColor;
final bool showCheckmark = widget.showCheckmark
?? chipTheme.showCheckmark
?? theme.chipTheme.showCheckmark
?? true;
final EdgeInsetsGeometry padding = widget.padding
?? chipTheme.padding
?? theme.chipTheme.padding
?? chipDefaults.padding!;
final TextStyle? labelStyle = widget.labelStyle
?? chipTheme.labelStyle
?? theme.chipTheme.labelStyle;
final EdgeInsetsGeometry labelPadding = widget.labelPadding
?? chipTheme.labelPadding
?? theme.chipTheme.labelPadding
?? _defaultLabelPadding;
final TextStyle effectiveLabelStyle = chipDefaults.labelStyle!.merge(labelStyle);
final Color? resolvedLabelColor = MaterialStateProperty.resolveAs<Color?>(effectiveLabelStyle.color, materialStates); final Color? resolvedLabelColor = MaterialStateProperty.resolveAs<Color?>(effectiveLabelStyle.color, materialStates);
final TextStyle resolvedLabelStyle = effectiveLabelStyle.copyWith(color: resolvedLabelColor); final TextStyle resolvedLabelStyle = effectiveLabelStyle.copyWith(color: resolvedLabelColor);
final EdgeInsetsGeometry labelPadding = widget.labelPadding ?? chipTheme.labelPadding ?? _defaultLabelPadding;
Widget result = Material( Widget result = Material(
elevation: isTapping ? pressElevation : elevation, elevation: isTapping ? pressElevation : elevation,
...@@ -1874,7 +1932,7 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid ...@@ -1874,7 +1932,7 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
return Container( return Container(
decoration: ShapeDecoration( decoration: ShapeDecoration(
shape: resolvedShape, shape: resolvedShape,
color: getBackgroundColor(chipTheme), color: _getBackgroundColor(theme, chipTheme, chipDefaults),
), ),
child: child, child: child,
); );
...@@ -1900,10 +1958,10 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid ...@@ -1900,10 +1958,10 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
deleteIcon: AnimatedSwitcher( deleteIcon: AnimatedSwitcher(
duration: _kDrawerDuration, duration: _kDrawerDuration,
switchInCurve: Curves.fastOutSlowIn, switchInCurve: Curves.fastOutSlowIn,
child: _buildDeleteIcon(context, theme, chipTheme), child: _buildDeleteIcon(context, theme, chipTheme, chipDefaults),
), ),
brightness: chipTheme.brightness, brightness: brightness,
padding: (widget.padding ?? chipTheme.padding).resolve(textDirection), padding: padding.resolve(textDirection),
visualDensity: widget.visualDensity ?? theme.visualDensity, visualDensity: widget.visualDensity ?? theme.visualDensity,
labelPadding: labelPadding.resolve(textDirection), labelPadding: labelPadding.resolve(textDirection),
showAvatar: hasAvatar, showAvatar: hasAvatar,
...@@ -2572,6 +2630,7 @@ class _RenderChip extends RenderBox { ...@@ -2572,6 +2630,7 @@ class _RenderChip extends RenderBox {
overallSize.width + theme.padding.horizontal, overallSize.width + theme.padding.horizontal,
overallSize.height + theme.padding.vertical, overallSize.height + theme.padding.vertical,
); );
return _ChipSizes( return _ChipSizes(
size: constraints.constrain(paddedSize), size: constraints.constrain(paddedSize),
overall: overallSize, overall: overallSize,
......
...@@ -179,32 +179,25 @@ class ChipThemeData with Diagnosticable { ...@@ -179,32 +179,25 @@ class ChipThemeData with Diagnosticable {
/// This will rarely be used directly. It is used by [lerp] to /// This will rarely be used directly. It is used by [lerp] to
/// create intermediate themes based on two themes. /// create intermediate themes based on two themes.
const ChipThemeData({ const ChipThemeData({
required this.backgroundColor, this.backgroundColor,
this.deleteIconColor, this.deleteIconColor,
required this.disabledColor, this.disabledColor,
required this.selectedColor, this.selectedColor,
required this.secondarySelectedColor, this.secondarySelectedColor,
this.shadowColor, this.shadowColor,
this.selectedShadowColor, this.selectedShadowColor,
this.showCheckmark, this.showCheckmark,
this.checkmarkColor, this.checkmarkColor,
this.labelPadding, this.labelPadding,
required this.padding, this.padding,
this.side, this.side,
this.shape, this.shape,
required this.labelStyle, this.labelStyle,
required this.secondaryLabelStyle, this.secondaryLabelStyle,
required this.brightness, this.brightness,
this.elevation, this.elevation,
this.pressElevation, this.pressElevation,
}) : assert(backgroundColor != null), });
assert(disabledColor != null),
assert(selectedColor != null),
assert(secondarySelectedColor != null),
assert(padding != null),
assert(labelStyle != null),
assert(secondaryLabelStyle != null),
assert(brightness != null);
/// Generates a ChipThemeData from a brightness, a primary color, and a text /// Generates a ChipThemeData from a brightness, a primary color, and a text
/// style. /// style.
...@@ -267,91 +260,87 @@ class ChipThemeData with Diagnosticable { ...@@ -267,91 +260,87 @@ class ChipThemeData with Diagnosticable {
padding: padding, padding: padding,
labelStyle: labelStyle, labelStyle: labelStyle,
secondaryLabelStyle: secondaryLabelStyle, secondaryLabelStyle: secondaryLabelStyle,
brightness: brightness!, brightness: brightness,
); );
} }
/// Color to be used for the unselected, enabled chip's background. /// Overrides the default for [ChipAttributes.backgroundColor]
/// which is used for unselected, enabled chip backgrounds.
/// ///
/// The default is light grey. /// This property applies to [ActionChip], [Chip], [ChoiceChip],
final Color backgroundColor; /// [FilterChip], [InputChip], [RawChip].
final Color? backgroundColor;
/// The [Color] for the delete icon. The default is Color(0xde000000) /// Overrides the default for [DeletableChipAttributes.deleteIconColor].
/// (slightly transparent black) for light themes, and Color(0xdeffffff)
/// (slightly transparent white) for dark themes.
/// ///
/// May be set to null, in which case the ambient [IconThemeData.color] is used. /// This property applies to [Chip], [InputChip], [RawChip].
final Color? deleteIconColor; final Color? deleteIconColor;
/// Color to be used for the chip's background indicating that it is disabled. /// Overrides the default for
/// [DisabledChipAttributes.disabledColor], the background color
/// which indicates that the chip is not enabled.
/// ///
/// The chip is disabled when [DisabledChipAttributes.isEnabled] is false, or /// This property applies to [ChoiceChip], [FilterChip],
/// all three of [SelectableChipAttributes.onSelected], /// [InputChip], [RawChip].
/// [TappableChipAttributes.onPressed], and final Color? disabledColor;
/// [DeletableChipAttributes.onDeleted] are null.
///
/// It defaults to [Colors.black38].
final Color disabledColor;
/// Color to be used for the chip's background, indicating that it is /// Overrides the default for
/// selected. /// [SelectableChipAttributes.selectedColor], the background color
/// that indicates that the chip is selected.
/// ///
/// The chip is selected when [SelectableChipAttributes.selected] is true. /// This property applies to [ChoiceChip], [FilterChip],
final Color selectedColor; /// [InputChip], [RawChip].
final Color? selectedColor;
/// An alternate color to be used for the chip's background, indicating that /// Overrides the default for [ChoiceChip.selectedColor], the
/// it is selected. For example, this color is used by [ChoiceChip] when the /// background color that indicates that the chip is selected.
/// choice is selected. final Color? secondarySelectedColor;
///
/// The chip is selected when [SelectableChipAttributes.selected] is true.
final Color secondarySelectedColor;
/// Color of the chip's shadow when the elevation is greater than 0. /// Overrides the default for [ChipAttributes.shadowColor], the
/// /// Color of the chip's shadow when its elevation is greater than 0.
/// If null, the chip defaults to [Colors.black].
///
/// See also:
/// ///
/// * [selectedShadowColor] /// This property applies to [ActionChip], [Chip], [ChoiceChip],
/// [FilterChip], [InputChip], [RawChip].
final Color? shadowColor; final Color? shadowColor;
/// Color of the chip's shadow when the elevation is greater than 0 and the /// Overrides the default for
/// chip is selected. /// [SelectableChipAttributes.selectedShadowColor], the Color of the
/// /// chip's shadow when its elevation is greater than 0 and the chip
/// If null, the chip defaults to [Colors.black]. /// is selected.
///
/// See also:
/// ///
/// * [shadowColor] /// This property applies to [ChoiceChip], [FilterChip],
/// [InputChip], [RawChip].
final Color? selectedShadowColor; final Color? selectedShadowColor;
/// Whether or not to show a check mark when [SelectableChipAttributes.selected] is true. /// Overrides the default for
/// [CheckmarkableChipAttributes.showCheckmark], which indicates if
/// a check mark should be shown.
/// ///
/// For instance, the [ChoiceChip] sets this to false so that it can be /// This property applies to [FilterChip], [InputChip], [RawChip].
/// selected without showing the check mark.
///
/// Defaults to true.
final bool? showCheckmark; final bool? showCheckmark;
/// Color of the chip's check mark when a check mark is visible. /// Overrides the default for
/// [CheckmarkableChipAttributes.checkmarkColor].
/// ///
/// This will override the color set by the platform's brightness setting. /// This property applies to [FilterChip], [InputChip], [RawChip].
final Color? checkmarkColor; final Color? checkmarkColor;
/// The padding around the [Chip.label] widget. /// Overrides the default for [ChipAttributes.labelPadding],
/// the padding around the chip's label widget.
/// ///
/// By default, this is 4 logical pixels at the beginning and the end of the /// This property applies to [ActionChip], [Chip], [ChoiceChip],
/// label, and zero on top and bottom. /// [FilterChip], [InputChip], [RawChip].
final EdgeInsetsGeometry? labelPadding; final EdgeInsetsGeometry? labelPadding;
/// The padding between the contents of the chip and the outside [shape]. /// Overrides the default for [ChipAttributes.padding],
/// the padding between the contents of the chip and the outside [shape].
/// ///
/// Defaults to 4 logical pixels on all sides. /// This property applies to [ActionChip], [Chip], [ChoiceChip],
final EdgeInsetsGeometry padding; /// [FilterChip], [InputChip], [RawChip].
final EdgeInsetsGeometry? padding;
/// The color and weight of the chip's outline. /// Overrides the default for [ChipAttributes.side],
/// /// the color and weight of the chip's outline.
/// If null, the chip defaults to the border side of [shape].
/// ///
/// This value is combined with [shape] to create a shape decorated with an /// This value is combined with [shape] to create a shape decorated with an
/// outline. If it is a [MaterialStateBorderSide], /// outline. If it is a [MaterialStateBorderSide],
...@@ -363,11 +352,13 @@ class ChipThemeData with Diagnosticable { ...@@ -363,11 +352,13 @@ class ChipThemeData with Diagnosticable {
/// * [MaterialState.hovered]. /// * [MaterialState.hovered].
/// * [MaterialState.focused]. /// * [MaterialState.focused].
/// * [MaterialState.pressed]. /// * [MaterialState.pressed].
///
/// This property applies to [ActionChip], [Chip], [ChoiceChip],
/// [FilterChip], [InputChip], [RawChip].
final BorderSide? side; final BorderSide? side;
/// The border to draw around the chip. /// Overrides the default for [ChipAttributes.shape],
/// /// the shape of border to draw around the chip.
/// If null, the chip defaults to a [StadiumBorder].
/// ///
/// This shape is combined with [side] to create a shape decorated with an /// This shape is combined with [side] to create a shape decorated with an
/// outline. If it is a [MaterialStateOutlinedBorder], /// outline. If it is a [MaterialStateOutlinedBorder],
...@@ -379,34 +370,45 @@ class ChipThemeData with Diagnosticable { ...@@ -379,34 +370,45 @@ class ChipThemeData with Diagnosticable {
/// * [MaterialState.hovered]. /// * [MaterialState.hovered].
/// * [MaterialState.focused]. /// * [MaterialState.focused].
/// * [MaterialState.pressed]. /// * [MaterialState.pressed].
///
/// This property applies to [ActionChip], [Chip], [ChoiceChip],
/// [FilterChip], [InputChip], [RawChip].
final OutlinedBorder? shape; final OutlinedBorder? shape;
/// The style to be applied to the chip's label. /// Overrides the default for [ChipAttributes.labelStyle],
/// the style of the [DefaultTextStyle] that contains the
/// chip's label.
/// ///
/// This only has an effect on label widgets that respect the /// This only has an effect on label widgets that respect the
/// [DefaultTextStyle], such as [Text]. /// [DefaultTextStyle], such as [Text].
final TextStyle labelStyle; ///
/// This property applies to [ActionChip], [Chip],
/// [FilterChip], [InputChip], [RawChip].
final TextStyle? labelStyle;
/// An alternate style to be applied to the chip's label. For example, this /// Overrides the default for [ChoiceChip.labelStyle],
/// style is applied to the text of a selected [ChoiceChip]. /// the style of the [DefaultTextStyle] that contains the
/// chip's label.
/// ///
/// This only has an effect on label widgets that respect the /// This only has an effect on label widgets that respect the
/// [DefaultTextStyle], such as [Text]. /// [DefaultTextStyle], such as [Text].
final TextStyle secondaryLabelStyle; final TextStyle? secondaryLabelStyle;
/// The brightness setting for this theme. /// Overrides the default value for all chips which affects various base
/// /// material color choices in the chip rendering.
/// This affects various base material color choices in the chip rendering. final Brightness? brightness;
final Brightness brightness;
/// The elevation to be applied to the chip. /// Overrides the default for [ChipAttributes.elevation],
/// the elevation of the chip's [Material].
/// ///
/// If null, the chip defaults to 0. /// This property applies to [ActionChip], [Chip], [ChoiceChip],
/// [FilterChip], [InputChip], [RawChip].
final double? elevation; final double? elevation;
/// The elevation to be applied to the chip during the press motion. /// Overrides the default for [TappableChipAttributes.pressElevation],
/// the elevation of the chip's [Material] during a "press" or tap down.
/// ///
/// If null, the chip defaults to 8. /// This property applies to [ActionChip], [InputChip], [RawChip].
final double? pressElevation; final double? pressElevation;
/// Creates a copy of this object but with the given fields replaced with the /// Creates a copy of this object but with the given fields replaced with the
...@@ -461,20 +463,20 @@ class ChipThemeData with Diagnosticable { ...@@ -461,20 +463,20 @@ class ChipThemeData with Diagnosticable {
if (a == null && b == null) if (a == null && b == null)
return null; return null;
return ChipThemeData( return ChipThemeData(
backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t)!, backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t),
deleteIconColor: Color.lerp(a?.deleteIconColor, b?.deleteIconColor, t), deleteIconColor: Color.lerp(a?.deleteIconColor, b?.deleteIconColor, t),
disabledColor: Color.lerp(a?.disabledColor, b?.disabledColor, t)!, disabledColor: Color.lerp(a?.disabledColor, b?.disabledColor, t),
selectedColor: Color.lerp(a?.selectedColor, b?.selectedColor, t)!, selectedColor: Color.lerp(a?.selectedColor, b?.selectedColor, t),
secondarySelectedColor: Color.lerp(a?.secondarySelectedColor, b?.secondarySelectedColor, t)!, secondarySelectedColor: Color.lerp(a?.secondarySelectedColor, b?.secondarySelectedColor, t),
shadowColor: Color.lerp(a?.shadowColor, b?.shadowColor, t), shadowColor: Color.lerp(a?.shadowColor, b?.shadowColor, t),
selectedShadowColor: Color.lerp(a?.selectedShadowColor, b?.selectedShadowColor, t), selectedShadowColor: Color.lerp(a?.selectedShadowColor, b?.selectedShadowColor, t),
checkmarkColor: Color.lerp(a?.checkmarkColor, b?.checkmarkColor, t), checkmarkColor: Color.lerp(a?.checkmarkColor, b?.checkmarkColor, t),
labelPadding: EdgeInsetsGeometry.lerp(a?.labelPadding, b?.labelPadding, t), labelPadding: EdgeInsetsGeometry.lerp(a?.labelPadding, b?.labelPadding, t),
padding: EdgeInsetsGeometry.lerp(a?.padding, b?.padding, t)!, padding: EdgeInsetsGeometry.lerp(a?.padding, b?.padding, t),
side: _lerpSides(a?.side, b?.side, t), side: _lerpSides(a?.side, b?.side, t),
shape: _lerpShapes(a?.shape, b?.shape, t), shape: _lerpShapes(a?.shape, b?.shape, t),
labelStyle: TextStyle.lerp(a?.labelStyle, b?.labelStyle, t)!, labelStyle: TextStyle.lerp(a?.labelStyle, b?.labelStyle, t),
secondaryLabelStyle: TextStyle.lerp(a?.secondaryLabelStyle, b?.secondaryLabelStyle, t)!, secondaryLabelStyle: TextStyle.lerp(a?.secondaryLabelStyle, b?.secondaryLabelStyle, t),
brightness: t < 0.5 ? a?.brightness ?? Brightness.light : b?.brightness ?? Brightness.light, brightness: t < 0.5 ? a?.brightness ?? Brightness.light : b?.brightness ?? Brightness.light,
elevation: lerpDouble(a?.elevation, b?.elevation, t), elevation: lerpDouble(a?.elevation, b?.elevation, t),
pressElevation: lerpDouble(a?.pressElevation, b?.pressElevation, t), pressElevation: lerpDouble(a?.pressElevation, b?.pressElevation, t),
...@@ -553,28 +555,22 @@ class ChipThemeData with Diagnosticable { ...@@ -553,28 +555,22 @@ class ChipThemeData with Diagnosticable {
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties); super.debugFillProperties(properties);
final ThemeData defaultTheme = ThemeData.fallback(); properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null));
final ChipThemeData defaultData = ChipThemeData.fromDefaults( properties.add(ColorProperty('deleteIconColor', deleteIconColor, defaultValue: null));
secondaryColor: defaultTheme.primaryColor, properties.add(ColorProperty('disabledColor', disabledColor, defaultValue: null));
brightness: defaultTheme.brightness, properties.add(ColorProperty('selectedColor', selectedColor, defaultValue: null));
labelStyle: defaultTheme.textTheme.bodyText1!, properties.add(ColorProperty('secondarySelectedColor', secondarySelectedColor, defaultValue: null));
); properties.add(ColorProperty('shadowColor', shadowColor, defaultValue: null));
properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: defaultData.backgroundColor)); properties.add(ColorProperty('selectedShadowColor', selectedShadowColor, defaultValue: null));
properties.add(ColorProperty('deleteIconColor', deleteIconColor, defaultValue: defaultData.deleteIconColor)); properties.add(ColorProperty('checkMarkColor', checkmarkColor, defaultValue: null));
properties.add(ColorProperty('disabledColor', disabledColor, defaultValue: defaultData.disabledColor)); properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('labelPadding', labelPadding, defaultValue: null));
properties.add(ColorProperty('selectedColor', selectedColor, defaultValue: defaultData.selectedColor)); properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null));
properties.add(ColorProperty('secondarySelectedColor', secondarySelectedColor, defaultValue: defaultData.secondarySelectedColor)); properties.add(DiagnosticsProperty<BorderSide>('side', side, defaultValue: null));
properties.add(ColorProperty('shadowColor', shadowColor, defaultValue: defaultData.shadowColor)); properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
properties.add(ColorProperty('selectedShadowColor', selectedShadowColor, defaultValue: defaultData.selectedShadowColor)); properties.add(DiagnosticsProperty<TextStyle>('labelStyle', labelStyle, defaultValue: null));
properties.add(ColorProperty('checkMarkColor', checkmarkColor, defaultValue: defaultData.checkmarkColor)); properties.add(DiagnosticsProperty<TextStyle>('secondaryLabelStyle', secondaryLabelStyle, defaultValue: null));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('labelPadding', labelPadding, defaultValue: defaultData.labelPadding)); properties.add(EnumProperty<Brightness>('brightness', brightness, defaultValue: null));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: defaultData.padding)); properties.add(DoubleProperty('elevation', elevation, defaultValue: null));
properties.add(DiagnosticsProperty<BorderSide>('side', side, defaultValue: defaultData.side)); properties.add(DoubleProperty('pressElevation', pressElevation, defaultValue: null));
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: defaultData.shape));
properties.add(DiagnosticsProperty<TextStyle>('labelStyle', labelStyle, defaultValue: defaultData.labelStyle));
properties.add(DiagnosticsProperty<TextStyle>('secondaryLabelStyle', secondaryLabelStyle, defaultValue: defaultData.secondaryLabelStyle));
properties.add(EnumProperty<Brightness>('brightness', brightness, defaultValue: defaultData.brightness));
properties.add(DoubleProperty('elevation', elevation, defaultValue: defaultData.elevation));
properties.add(DoubleProperty('pressElevation', pressElevation, defaultValue: defaultData.pressElevation));
} }
} }
...@@ -466,11 +466,7 @@ class ThemeData with Diagnosticable { ...@@ -466,11 +466,7 @@ class ThemeData with Diagnosticable {
bottomSheetTheme ??= const BottomSheetThemeData(); bottomSheetTheme ??= const BottomSheetThemeData();
buttonBarTheme ??= const ButtonBarThemeData(); buttonBarTheme ??= const ButtonBarThemeData();
cardTheme ??= const CardTheme(); cardTheme ??= const CardTheme();
chipTheme ??= ChipThemeData.fromDefaults( chipTheme ??= const ChipThemeData();
secondaryColor: isDark ? Colors.tealAccent[200]! : primaryColor,
brightness: colorScheme.brightness,
labelStyle: textTheme.bodyText1!,
);
checkboxTheme ??= const CheckboxThemeData(); checkboxTheme ??= const CheckboxThemeData();
dataTableTheme ??= const DataTableThemeData(); dataTableTheme ??= const DataTableThemeData();
dialogTheme ??= const DialogTheme(); dialogTheme ??= const DialogTheme();
......
...@@ -270,6 +270,80 @@ Finder findTooltipContainer(String tooltipText) { ...@@ -270,6 +270,80 @@ Finder findTooltipContainer(String tooltipText) {
} }
void main() { void main() {
testWidgets('Chip defaults', (WidgetTester tester) async {
Widget buildFrame(Brightness brightness) {
return MaterialApp(
theme: ThemeData(brightness: brightness),
home: Scaffold(
body: Center(
child: Chip(
avatar: const CircleAvatar(child: Text('A')),
label: const Text('Chip A'),
onDeleted: () { },
),
),
),
);
}
await tester.pumpWidget(buildFrame(Brightness.light));
expect(getMaterialBox(tester), paints..path(color: const Color(0x1f000000)));
expect(tester.getSize(find.byType(Chip)), const Size(156.0, 48.0));
expect(getMaterial(tester).color, null);
expect(getMaterial(tester).elevation, 0);
expect(getMaterial(tester).shape, const StadiumBorder());
expect(getIconData(tester).color?.value, 0xffffffff);
expect(getIconData(tester).opacity, null);
expect(getIconData(tester).size, null);
expect(getLabelStyle(tester).style.color?.value, 0xde000000);
await tester.pumpWidget(buildFrame(Brightness.dark));
await tester.pumpAndSettle(); // Theme transition animation
expect(getMaterialBox(tester), paints..path(color: const Color(0x1fffffff)));
expect(tester.getSize(find.byType(Chip)), const Size(156.0, 48.0));
expect(getMaterial(tester).color, null);
expect(getMaterial(tester).elevation, 0);
expect(getMaterial(tester).shape, const StadiumBorder());
expect(getIconData(tester).color?.value, 0xffffffff);
expect(getIconData(tester).opacity, null);
expect(getIconData(tester).size, null);
expect(getLabelStyle(tester).style.color?.value, 0xffffffff);
});
testWidgets('ChoiceChip defaults', (WidgetTester tester) async {
Widget buildFrame(Brightness brightness) {
return MaterialApp(
theme: ThemeData(brightness: brightness),
home: const Scaffold(
body: Center(
child: ChoiceChip(
label: Text('Chip A'),
selected: true,
),
),
),
);
}
await tester.pumpWidget(buildFrame(Brightness.light));
expect(getMaterialBox(tester), paints..path(color: const Color(0x3d000000)));
expect(tester.getSize(find.byType(ChoiceChip)), const Size(108.0, 48.0));
expect(getMaterial(tester).color, null);
expect(getMaterial(tester).elevation, 0);
expect(getMaterial(tester).shape, const StadiumBorder());
expect(getLabelStyle(tester).style.color?.value, 0xde000000);
await tester.pumpWidget(buildFrame(Brightness.dark));
await tester.pumpAndSettle(); // Theme transition animation
expect(getMaterialBox(tester), paints..path(color: const Color(0x3dffffff)));
expect(tester.getSize(find.byType(ChoiceChip)), const Size(108.0, 48.0));
expect(getMaterial(tester).color, null);
expect(getMaterial(tester).elevation, 0);
expect(getMaterial(tester).shape, const StadiumBorder());
expect(getLabelStyle(tester).style.color?.value, 0xdeffffff);
});
testWidgets('Chip control test', (WidgetTester tester) async { testWidgets('Chip control test', (WidgetTester tester) async {
final FeedbackTester feedback = FeedbackTester(); final FeedbackTester feedback = FeedbackTester();
final List<String> deletedChipLabels = <String>[]; final List<String> deletedChipLabels = <String>[];
...@@ -1697,7 +1771,11 @@ void main() { ...@@ -1697,7 +1771,11 @@ void main() {
platform: TargetPlatform.android, platform: TargetPlatform.android,
primarySwatch: Colors.blue, primarySwatch: Colors.blue,
); );
final ChipThemeData defaultChipTheme = themeData.chipTheme; final ChipThemeData defaultChipTheme = ChipThemeData.fromDefaults(
brightness: themeData.brightness,
secondaryColor: Colors.blue,
labelStyle: themeData.textTheme.bodyText1!,
);
bool value = false; bool value = false;
Widget buildApp({ Widget buildApp({
ChipThemeData? chipTheme, ChipThemeData? chipTheme,
......
...@@ -39,130 +39,267 @@ IconThemeData getIconData(WidgetTester tester) { ...@@ -39,130 +39,267 @@ IconThemeData getIconData(WidgetTester tester) {
DefaultTextStyle getLabelStyle(WidgetTester tester) { DefaultTextStyle getLabelStyle(WidgetTester tester) {
return tester.widget( return tester.widget(
find find.descendant(
.descendant( of: find.byType(RawChip),
of: find.byType(RawChip), matching: find.byType(DefaultTextStyle),
matching: find.byType(DefaultTextStyle), ).last,
)
.last,
); );
} }
void main() { void main() {
testWidgets('Chip theme is built by ThemeData', (WidgetTester tester) async { test('ChipThemeData copyWith, ==, hashCode basics', () {
final ThemeData theme = ThemeData( expect(const ChipThemeData(), const ChipThemeData().copyWith());
platform: TargetPlatform.android, expect(const ChipThemeData().hashCode, const ChipThemeData().copyWith().hashCode);
primarySwatch: Colors.red, });
);
final ChipThemeData chipTheme = theme.chipTheme;
expect(chipTheme.backgroundColor, equals(Colors.black.withAlpha(0x1f))); test('ChipThemeData defaults', () {
expect(chipTheme.selectedColor, equals(Colors.black.withAlpha(0x3d))); const ChipThemeData themeData = ChipThemeData();
expect(chipTheme.secondarySelectedColor, equals(Colors.red.withAlpha(0x3d))); expect(themeData.backgroundColor, null);
expect(chipTheme.deleteIconColor, equals(Colors.black.withAlpha(0xde))); expect(themeData.deleteIconColor, null);
expect(themeData.disabledColor, null);
expect(themeData.selectedColor, null);
expect(themeData.secondarySelectedColor, null);
expect(themeData.shadowColor, null);
expect(themeData.selectedShadowColor, null);
expect(themeData.showCheckmark, null);
expect(themeData.checkmarkColor, null);
expect(themeData.labelPadding, null);
expect(themeData.padding, null);
expect(themeData.side, null);
expect(themeData.shape, null);
expect(themeData.labelStyle, null);
expect(themeData.secondaryLabelStyle, null);
expect(themeData.brightness, null);
expect(themeData.elevation, null);
expect(themeData.pressElevation, null);
}); });
testWidgets('Chip theme is built by ThemeData with dark mode enabled', (WidgetTester tester) async { testWidgets('Default ChipThemeData debugFillProperties', (WidgetTester tester) async {
final ThemeData theme = ThemeData( final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
platform: TargetPlatform.android, const ChipThemeData().debugFillProperties(builder);
brightness: Brightness.dark,
);
final ChipThemeData chipTheme = theme.chipTheme;
expect(chipTheme.backgroundColor, equals(Colors.white.withAlpha(0x1f))); final List<String> description = builder.properties
expect(chipTheme.selectedColor, equals(Colors.white.withAlpha(0x3d))); .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
expect(chipTheme.secondarySelectedColor, equals(Colors.tealAccent[200]!.withAlpha(0x3d))); .map((DiagnosticsNode node) => node.toString())
expect(chipTheme.deleteIconColor, equals(Colors.white.withAlpha(0xde))); .toList();
expect(description, <String>[]);
}); });
testWidgets('Chip uses ThemeData chip theme if present', (WidgetTester tester) async { testWidgets('ChipThemeData implements debugFillProperties', (WidgetTester tester) async {
final ThemeData theme = ThemeData( final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
platform: TargetPlatform.android, const ChipThemeData(
primarySwatch: Colors.red, backgroundColor: Color(0xfffffff0),
backgroundColor: Colors.blue, deleteIconColor: Color(0xfffffff1),
disabledColor: Color(0xfffffff2),
selectedColor: Color(0xfffffff3),
secondarySelectedColor: Color(0xfffffff4),
shadowColor: Color(0xfffffff5),
selectedShadowColor: Color(0xfffffff6),
showCheckmark: true,
checkmarkColor: Color(0xfffffff7),
labelPadding: EdgeInsets.all(1),
padding: EdgeInsets.all(2),
side: BorderSide(width: 10),
shape: RoundedRectangleBorder(),
labelStyle: TextStyle(fontSize: 10),
secondaryLabelStyle: TextStyle(fontSize: 20),
brightness: Brightness.dark,
elevation: 5,
pressElevation: 6,
).debugFillProperties(builder);
final List<String> description = builder.properties
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
.map((DiagnosticsNode node) => node.toString())
.toList();
expect(description, <String>[
'backgroundColor: Color(0xfffffff0)',
'deleteIconColor: Color(0xfffffff1)',
'disabledColor: Color(0xfffffff2)',
'selectedColor: Color(0xfffffff3)',
'secondarySelectedColor: Color(0xfffffff4)',
'shadowColor: Color(0xfffffff5)',
'selectedShadowColor: Color(0xfffffff6)',
'checkMarkColor: Color(0xfffffff7)',
'labelPadding: EdgeInsets.all(1.0)',
'padding: EdgeInsets.all(2.0)',
'side: BorderSide(Color(0xff000000), 10.0, BorderStyle.solid)',
'shape: RoundedRectangleBorder(BorderSide(Color(0xff000000), 0.0, BorderStyle.none), BorderRadius.zero)',
'labelStyle: TextStyle(inherit: true, size: 10.0)',
'secondaryLabelStyle: TextStyle(inherit: true, size: 20.0)',
'brightness: dark',
'elevation: 5.0',
'pressElevation: 6.0',
]);
});
testWidgets('Chip uses ThemeData chip theme', (WidgetTester tester) async {
const ChipThemeData chipTheme = ChipThemeData(
backgroundColor: Color(0xff112233),
elevation: 4,
padding: EdgeInsets.all(50),
labelPadding: EdgeInsets.all(25),
shape: RoundedRectangleBorder(),
labelStyle: TextStyle(fontSize: 32),
); );
final ChipThemeData chipTheme = theme.chipTheme;
Widget buildChip(ChipThemeData data) { await tester.pumpWidget(
return MaterialApp( MaterialApp(
locale: const Locale('en', 'us'), theme: ThemeData.light().copyWith(
chipTheme: chipTheme,
),
home: Directionality( home: Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: Material( child: Material(
child: Center( child: Center(
child: Theme( child: RawChip(
data: theme, label: const SizedBox(width: 100, height: 100),
child: RawChip( onSelected: (bool newValue) { },
onDeleted: () { },
avatar: const Placeholder(),
deleteIcon: const Placeholder(),
label: const Text('Chip'),
onSelected: (bool newValue) { },
),
), ),
), ),
), ),
), ),
); ),
} );
await tester.pumpWidget(buildChip(chipTheme));
await tester.pumpAndSettle();
final RenderBox materialBox = getMaterialBox(tester); final RenderBox materialBox = getMaterialBox(tester);
expect(materialBox, paints..path(color: chipTheme.backgroundColor)); expect(materialBox, paints..path(color: chipTheme.backgroundColor));
expect(getMaterial(tester).elevation, chipTheme.elevation);
expect(tester.getSize(find.byType(RawChip)), const Size(250, 250)); // label + padding + labelPadding
expect(getMaterial(tester).shape, chipTheme.shape);
expect(getLabelStyle(tester).style.fontSize, 32);
}); });
testWidgets('Chip overrides ThemeData theme if ChipTheme present', (WidgetTester tester) async { testWidgets('Chip uses ChipTheme', (WidgetTester tester) async {
final ThemeData theme = ThemeData( const ChipThemeData chipTheme = ChipThemeData(
platform: TargetPlatform.android, backgroundColor: Color(0xff112233),
primarySwatch: Colors.red, elevation: 4,
padding: EdgeInsets.all(50),
labelPadding: EdgeInsets.all(25),
labelStyle: TextStyle(fontSize: 32),
shape: RoundedRectangleBorder(),
); );
final ChipThemeData chipTheme = theme.chipTheme;
final ChipThemeData customTheme = chipTheme.copyWith( const ChipThemeData shadowedChipTheme = ChipThemeData(
backgroundColor: Colors.purple, backgroundColor: Color(0xff332211),
deleteIconColor: Colors.purple.withAlpha(0x3d), elevation: 3,
elevation: 3.0, padding: EdgeInsets.all(5),
shadowColor: Colors.pink, labelPadding: EdgeInsets.all(10),
labelStyle: TextStyle(fontSize: 64),
shape: CircleBorder(),
); );
const bool value = false;
Widget buildChip(ChipThemeData data) { await tester.pumpWidget(
return MaterialApp( MaterialApp(
home: Directionality( theme: ThemeData.light().copyWith(
textDirection: TextDirection.ltr, chipTheme: shadowedChipTheme,
child: Material( ),
child: Center( home: ChipTheme(
child: Theme( data: chipTheme,
data: theme, child: Builder(
child: ChipTheme( builder: (BuildContext context) {
data: customTheme, return Directionality(
child: RawChip( textDirection: TextDirection.ltr,
onDeleted: () { }, child: Material(
avatar: const Placeholder(), child: Center(
deleteIcon: const Placeholder(), child: RawChip(
label: const Text('$value'), label: const SizedBox(width: 100, height: 100),
onSelected: (bool newValue) { }, onSelected: (bool newValue) { },
),
), ),
), ),
), );
), },
), ),
), ),
); ),
} );
await tester.pumpWidget(buildChip(chipTheme)); final RenderBox materialBox = getMaterialBox(tester);
await tester.pumpAndSettle(); expect(materialBox, paints..path(color: chipTheme.backgroundColor));
expect(tester.getSize(find.byType(RawChip)), const Size(250, 250)); // label + padding + labelPadding
expect(getMaterial(tester).elevation, chipTheme.elevation);
expect(getMaterial(tester).shape, chipTheme.shape);
expect(getLabelStyle(tester).style.fontSize, 32);
});
testWidgets('Chip uses constructor parameters', (WidgetTester tester) async {
const ChipThemeData shadowedChipTheme = ChipThemeData(
backgroundColor: Color(0xff112233),
elevation: 4,
padding: EdgeInsets.all(5),
labelPadding: EdgeInsets.all(2),
labelStyle: TextStyle(),
shape: RoundedRectangleBorder(),
);
const Color backgroundColor = Color(0xff332211);
const double elevation = 3;
const double fontSize = 32;
const OutlinedBorder shape = CircleBorder();
await tester.pumpWidget(
MaterialApp(
home: ChipTheme(
data: shadowedChipTheme,
child: Builder(
builder: (BuildContext context) {
return Directionality(
textDirection: TextDirection.ltr,
child: Material(
child: Center(
child: RawChip(
backgroundColor: backgroundColor,
elevation: elevation,
padding: const EdgeInsets.all(50),
labelPadding:const EdgeInsets.all(25),
labelStyle: const TextStyle(fontSize: fontSize),
shape: shape,
label: const SizedBox(width: 100, height: 100),
onSelected: (bool newValue) { },
),
),
),
);
},
),
),
),
);
final RenderBox materialBox = getMaterialBox(tester); final RenderBox materialBox = getMaterialBox(tester);
final Material material = getMaterial(tester); expect(materialBox, paints..path(color: backgroundColor));
expect(tester.getSize(find.byType(RawChip)), const Size(250, 250)); // label + padding + labelPadding
expect(getMaterial(tester).elevation, elevation);
expect(getMaterial(tester).shape, shape);
expect(getLabelStyle(tester).style.fontSize, 32);
});
testWidgets('ChipTheme.fromDefaults', (WidgetTester tester) async {
ChipThemeData chipTheme = ChipThemeData.fromDefaults(
brightness: Brightness.light,
secondaryColor: Colors.red,
labelStyle: const TextStyle(),
);
expect(chipTheme.backgroundColor, equals(Colors.black.withAlpha(0x1f)));
expect(chipTheme.selectedColor, equals(Colors.black.withAlpha(0x3d)));
expect(chipTheme.secondarySelectedColor, equals(Colors.red.withAlpha(0x3d)));
expect(chipTheme.deleteIconColor, equals(Colors.black.withAlpha(0xde)));
expect(materialBox, paints..path(color: Color(customTheme.backgroundColor.value))); chipTheme = ChipThemeData.fromDefaults(
expect(material.elevation, customTheme.elevation); brightness: Brightness.dark,
expect(material.shadowColor, customTheme.shadowColor); secondaryColor: Colors.tealAccent[200]!,
labelStyle: const TextStyle(),
);
expect(chipTheme.backgroundColor, equals(Colors.white.withAlpha(0x1f)));
expect(chipTheme.selectedColor, equals(Colors.white.withAlpha(0x3d)));
expect(chipTheme.secondarySelectedColor, equals(Colors.tealAccent[200]!.withAlpha(0x3d)));
expect(chipTheme.deleteIconColor, equals(Colors.white.withAlpha(0xde)));
}); });
testWidgets('ChipThemeData generates correct opacities for defaults', (WidgetTester tester) async { testWidgets('ChipThemeData generates correct opacities for defaults', (WidgetTester tester) async {
const Color customColor1 = Color(0xcafefeed); const Color customColor1 = Color(0xcafefeed);
const Color customColor2 = Color(0xdeadbeef); const Color customColor2 = Color(0xdeadbeef);
...@@ -183,8 +320,8 @@ void main() { ...@@ -183,8 +320,8 @@ void main() {
expect(lightTheme.padding, equals(const EdgeInsets.all(4.0))); expect(lightTheme.padding, equals(const EdgeInsets.all(4.0)));
expect(lightTheme.side, isNull); expect(lightTheme.side, isNull);
expect(lightTheme.shape, isNull); expect(lightTheme.shape, isNull);
expect(lightTheme.labelStyle.color, equals(Colors.black.withAlpha(0xde))); expect(lightTheme.labelStyle?.color, equals(Colors.black.withAlpha(0xde)));
expect(lightTheme.secondaryLabelStyle.color, equals(customColor1.withAlpha(0xde))); expect(lightTheme.secondaryLabelStyle?.color, equals(customColor1.withAlpha(0xde)));
expect(lightTheme.brightness, equals(Brightness.light)); expect(lightTheme.brightness, equals(Brightness.light));
final ChipThemeData darkTheme = ChipThemeData.fromDefaults( final ChipThemeData darkTheme = ChipThemeData.fromDefaults(
...@@ -202,8 +339,8 @@ void main() { ...@@ -202,8 +339,8 @@ void main() {
expect(darkTheme.padding, equals(const EdgeInsets.all(4.0))); expect(darkTheme.padding, equals(const EdgeInsets.all(4.0)));
expect(darkTheme.side, isNull); expect(darkTheme.side, isNull);
expect(darkTheme.shape, isNull); expect(darkTheme.shape, isNull);
expect(darkTheme.labelStyle.color, equals(Colors.white.withAlpha(0xde))); expect(darkTheme.labelStyle?.color, equals(Colors.white.withAlpha(0xde)));
expect(darkTheme.secondaryLabelStyle.color, equals(customColor1.withAlpha(0xde))); expect(darkTheme.secondaryLabelStyle?.color, equals(customColor1.withAlpha(0xde)));
expect(darkTheme.brightness, equals(Brightness.dark)); expect(darkTheme.brightness, equals(Brightness.dark));
final ChipThemeData customTheme = ChipThemeData.fromDefaults( final ChipThemeData customTheme = ChipThemeData.fromDefaults(
...@@ -212,7 +349,7 @@ void main() { ...@@ -212,7 +349,7 @@ void main() {
labelStyle: customStyle, labelStyle: customStyle,
); );
expect(customTheme.backgroundColor, equals(customColor1.withAlpha(0x1f))); //expect(customTheme.backgroundColor, equals(customColor1.withAlpha(0x1f)));
expect(customTheme.deleteIconColor, equals(customColor1.withAlpha(0xde))); expect(customTheme.deleteIconColor, equals(customColor1.withAlpha(0xde)));
expect(customTheme.disabledColor, equals(customColor1.withAlpha(0x0c))); expect(customTheme.disabledColor, equals(customColor1.withAlpha(0x0c)));
expect(customTheme.selectedColor, equals(customColor1.withAlpha(0x3d))); expect(customTheme.selectedColor, equals(customColor1.withAlpha(0x3d)));
...@@ -221,8 +358,8 @@ void main() { ...@@ -221,8 +358,8 @@ void main() {
expect(customTheme.padding, equals(const EdgeInsets.all(4.0))); expect(customTheme.padding, equals(const EdgeInsets.all(4.0)));
expect(customTheme.side, isNull); expect(customTheme.side, isNull);
expect(customTheme.shape, isNull); expect(customTheme.shape, isNull);
expect(customTheme.labelStyle.color, equals(customColor1.withAlpha(0xde))); expect(customTheme.labelStyle?.color, equals(customColor1.withAlpha(0xde)));
expect(customTheme.secondaryLabelStyle.color, equals(customColor2.withAlpha(0xde))); expect(customTheme.secondaryLabelStyle?.color, equals(customColor2.withAlpha(0xde)));
expect(customTheme.brightness, equals(Brightness.light)); expect(customTheme.brightness, equals(Brightness.light));
}); });
...@@ -270,8 +407,8 @@ void main() { ...@@ -270,8 +407,8 @@ void main() {
expect(lerp.padding, equals(const EdgeInsets.all(3.0))); expect(lerp.padding, equals(const EdgeInsets.all(3.0)));
expect(lerp.side!.color, equals(middleGrey)); expect(lerp.side!.color, equals(middleGrey));
expect(lerp.shape, isA<BeveledRectangleBorder>()); expect(lerp.shape, isA<BeveledRectangleBorder>());
expect(lerp.labelStyle.color, equals(middleGrey.withAlpha(0xde))); expect(lerp.labelStyle?.color, equals(middleGrey.withAlpha(0xde)));
expect(lerp.secondaryLabelStyle.color, equals(middleGrey.withAlpha(0xde))); expect(lerp.secondaryLabelStyle?.color, equals(middleGrey.withAlpha(0xde)));
expect(lerp.brightness, equals(Brightness.light)); expect(lerp.brightness, equals(Brightness.light));
expect(lerp.elevation, 3.0); expect(lerp.elevation, 3.0);
expect(lerp.pressElevation, 7.0); expect(lerp.pressElevation, 7.0);
...@@ -291,8 +428,8 @@ void main() { ...@@ -291,8 +428,8 @@ void main() {
expect(lerpANull25.padding, equals(const EdgeInsets.all(0.5))); expect(lerpANull25.padding, equals(const EdgeInsets.all(0.5)));
expect(lerpANull25.side!.color, equals(Colors.white.withAlpha(0x3f))); expect(lerpANull25.side!.color, equals(Colors.white.withAlpha(0x3f)));
expect(lerpANull25.shape, isA<BeveledRectangleBorder>()); expect(lerpANull25.shape, isA<BeveledRectangleBorder>());
expect(lerpANull25.labelStyle.color, equals(Colors.black.withAlpha(0x38))); expect(lerpANull25.labelStyle?.color, equals(Colors.black.withAlpha(0x38)));
expect(lerpANull25.secondaryLabelStyle.color, equals(Colors.white.withAlpha(0x38))); expect(lerpANull25.secondaryLabelStyle?.color, equals(Colors.white.withAlpha(0x38)));
expect(lerpANull25.brightness, equals(Brightness.light)); expect(lerpANull25.brightness, equals(Brightness.light));
expect(lerpANull25.elevation, 1.25); expect(lerpANull25.elevation, 1.25);
expect(lerpANull25.pressElevation, 2.5); expect(lerpANull25.pressElevation, 2.5);
...@@ -310,8 +447,8 @@ void main() { ...@@ -310,8 +447,8 @@ void main() {
expect(lerpANull75.padding, equals(const EdgeInsets.all(1.5))); expect(lerpANull75.padding, equals(const EdgeInsets.all(1.5)));
expect(lerpANull75.side!.color, equals(Colors.white.withAlpha(0xbf))); expect(lerpANull75.side!.color, equals(Colors.white.withAlpha(0xbf)));
expect(lerpANull75.shape, isA<BeveledRectangleBorder>()); expect(lerpANull75.shape, isA<BeveledRectangleBorder>());
expect(lerpANull75.labelStyle.color, equals(Colors.black.withAlpha(0xa7))); expect(lerpANull75.labelStyle?.color, equals(Colors.black.withAlpha(0xa7)));
expect(lerpANull75.secondaryLabelStyle.color, equals(Colors.white.withAlpha(0xa7))); expect(lerpANull75.secondaryLabelStyle?.color, equals(Colors.white.withAlpha(0xa7)));
expect(lerpANull75.brightness, equals(Brightness.light)); expect(lerpANull75.brightness, equals(Brightness.light));
expect(lerpANull75.elevation, 3.75); expect(lerpANull75.elevation, 3.75);
expect(lerpANull75.pressElevation, 7.5); expect(lerpANull75.pressElevation, 7.5);
...@@ -329,8 +466,8 @@ void main() { ...@@ -329,8 +466,8 @@ void main() {
expect(lerpBNull25.padding, equals(const EdgeInsets.all(3.0))); expect(lerpBNull25.padding, equals(const EdgeInsets.all(3.0)));
expect(lerpBNull25.side!.color, equals(Colors.black.withAlpha(0x3f))); expect(lerpBNull25.side!.color, equals(Colors.black.withAlpha(0x3f)));
expect(lerpBNull25.shape, isA<StadiumBorder>()); expect(lerpBNull25.shape, isA<StadiumBorder>());
expect(lerpBNull25.labelStyle.color, equals(Colors.white.withAlpha(0xa7))); expect(lerpBNull25.labelStyle?.color, equals(Colors.white.withAlpha(0xa7)));
expect(lerpBNull25.secondaryLabelStyle.color, equals(Colors.black.withAlpha(0xa7))); expect(lerpBNull25.secondaryLabelStyle?.color, equals(Colors.black.withAlpha(0xa7)));
expect(lerpBNull25.brightness, equals(Brightness.dark)); expect(lerpBNull25.brightness, equals(Brightness.dark));
expect(lerpBNull25.elevation, 0.75); expect(lerpBNull25.elevation, 0.75);
expect(lerpBNull25.pressElevation, 3.0); expect(lerpBNull25.pressElevation, 3.0);
...@@ -348,8 +485,8 @@ void main() { ...@@ -348,8 +485,8 @@ void main() {
expect(lerpBNull75.padding, equals(const EdgeInsets.all(1.0))); expect(lerpBNull75.padding, equals(const EdgeInsets.all(1.0)));
expect(lerpBNull75.side!.color, equals(Colors.black.withAlpha(0xbf))); expect(lerpBNull75.side!.color, equals(Colors.black.withAlpha(0xbf)));
expect(lerpBNull75.shape, isA<StadiumBorder>()); expect(lerpBNull75.shape, isA<StadiumBorder>());
expect(lerpBNull75.labelStyle.color, equals(Colors.white.withAlpha(0x38))); expect(lerpBNull75.labelStyle?.color, equals(Colors.white.withAlpha(0x38)));
expect(lerpBNull75.secondaryLabelStyle.color, equals(Colors.black.withAlpha(0x38))); expect(lerpBNull75.secondaryLabelStyle?.color, equals(Colors.black.withAlpha(0x38)));
expect(lerpBNull75.brightness, equals(Brightness.light)); expect(lerpBNull75.brightness, equals(Brightness.light));
expect(lerpBNull75.elevation, 0.25); expect(lerpBNull75.elevation, 0.25);
expect(lerpBNull75.pressElevation, 1.0); expect(lerpBNull75.pressElevation, 1.0);
...@@ -495,20 +632,22 @@ void main() { ...@@ -495,20 +632,22 @@ void main() {
BorderSide getBorderSide(Set<MaterialState> states) { BorderSide getBorderSide(Set<MaterialState> states) {
Color color = defaultColor; Color color = defaultColor;
if (states.contains(MaterialState.selected)) if (states.contains(MaterialState.selected))
color = selectedColor; color = selectedColor;
return BorderSide(color: color); return BorderSide(color: color);
} }
final ChipThemeData chipTheme = ChipThemeData.fromDefaults(
brightness: Brightness.light,
secondaryColor: Colors.blue,
labelStyle: const TextStyle(),
).copyWith(
side: _MaterialStateBorderSide(getBorderSide),
);
Widget chipWidget({ bool selected = false }) { Widget chipWidget({ bool selected = false }) {
return MaterialApp( return MaterialApp(
theme: ThemeData( theme: ThemeData(chipTheme: chipTheme),
chipTheme: ThemeData.light().chipTheme.copyWith(
side: _MaterialStateBorderSide(getBorderSide),
),
),
home: Scaffold( home: Scaffold(
body: ChoiceChip( body: ChoiceChip(
label: const Text('Chip'), label: const Text('Chip'),
...@@ -536,13 +675,18 @@ void main() { ...@@ -536,13 +675,18 @@ void main() {
return null; return null;
} }
final ChipThemeData chipTheme = ChipThemeData.fromDefaults(
brightness: Brightness.light,
secondaryColor: Colors.blue,
labelStyle: const TextStyle(),
).copyWith(
shape: _MaterialStateOutlinedBorder(getShape),
);
Widget chipWidget({ bool selected = false }) { Widget chipWidget({ bool selected = false }) {
return MaterialApp( return MaterialApp(
theme: ThemeData( theme: ThemeData(chipTheme: chipTheme),
chipTheme: ThemeData.light().chipTheme.copyWith(
shape: _MaterialStateOutlinedBorder(getShape),
),
),
home: Scaffold( home: Scaffold(
body: ChoiceChip( body: ChoiceChip(
label: const Text('Chip'), label: const Text('Chip'),
......
...@@ -51,16 +51,6 @@ void main() { ...@@ -51,16 +51,6 @@ void main() {
expect(darkTheme.primaryTextTheme.headline6!.color, typography.white.headline6!.color); expect(darkTheme.primaryTextTheme.headline6!.color, typography.white.headline6!.color);
}); });
test('Default chip label style gets a default bodyText1 if textTheme.bodyText1 is null', () {
const TextTheme noBodyText1TextTheme = TextTheme();
final ThemeData lightTheme = ThemeData(brightness: Brightness.light, textTheme: noBodyText1TextTheme);
final ThemeData darkTheme = ThemeData(brightness: Brightness.dark, textTheme: noBodyText1TextTheme);
final Typography typography = Typography.material2018(platform: lightTheme.platform);
expect(lightTheme.chipTheme.labelStyle.color, equals(typography.black.bodyText1!.color!.withAlpha(0xde)));
expect(darkTheme.chipTheme.labelStyle.color, equals(typography.white.bodyText1!.color!.withAlpha(0xde)));
});
test('Default icon theme contrasts with brightness', () { test('Default icon theme contrasts with brightness', () {
final ThemeData lightTheme = ThemeData(brightness: Brightness.light); final ThemeData lightTheme = ThemeData(brightness: Brightness.light);
final ThemeData darkTheme = ThemeData(brightness: Brightness.dark); final ThemeData darkTheme = ThemeData(brightness: Brightness.dark);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment