Introduce MaterialState color
property for chips (#128584)
fixes https://github.com/flutter/flutter/issues/115827 fixes https://github.com/flutter/flutter/issues/101325 ### Description 1. This PR adds a new MaterialState `color` property to all the chips (this makes it possible to customize chips in all states from the M3 specs). 2. Updated defaults to use the new MaterialState `color` property. 3. Updated and added new tests to all the chip test classes. <details> <summary>code sample</summary> ```dart import 'package:flutter/material.dart'; const Color disabledColor = Colors.black26; const Color backgroundColor = Colors.cyan; final Color disabledSelectedColor = Colors.red.shade100; const Color selectedColor = Colors.amber; final MaterialStateProperty<Color> color = MaterialStateProperty.resolveWith((Set<MaterialState> states) { if (states.contains(MaterialState.disabled) && states.contains(MaterialState.selected)) { return disabledSelectedColor; } if (states.contains(MaterialState.disabled)) { return disabledColor; } if (states.contains(MaterialState.selected)) { return selectedColor; } return backgroundColor; }); void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData( useMaterial3: true, // chipTheme: ChipThemeData(color: color), ), home: const Example(), ); } } class Example extends StatefulWidget { const Example({super.key}); @override State<Example> createState() => _ExampleState(); } class _ExampleState extends State<Example> { bool enabled = false; bool selected = true; @override Widget build(BuildContext context) { const Widget verticalSpace = SizedBox(height: 20); return Scaffold( body: Center( child: Column( children: <Widget>[ const SizedBox(height: 25), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ const Card( elevation: 0.0, color: disabledColor, child: Padding( padding: EdgeInsets.all(8.0), child: Text('disabledColor'), ), ), const Card( elevation: 0.0, color: backgroundColor, child: Padding( padding: EdgeInsets.all(8.0), child: Text('backgroundColor'), ), ), Card( elevation: 0.0, color: disabledSelectedColor, child: const Padding( padding: EdgeInsets.all(8.0), child: Text('disabledSelectedColor'), ), ), const Card( elevation: 0.0, color: selectedColor, child: Padding( padding: EdgeInsets.all(8.0), child: Text('selectedColor'), ), ), ], ), const Spacer(), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ RawChip( selected: selected, selectedColor: selectedColor, color: color, label: const Text('RawChip'), isEnabled: enabled, onSelected: enabled ? (bool value) {} : null, ), verticalSpace, InputChip( isEnabled: enabled, selected: selected, selectedColor: selectedColor, color: color, label: const Text('InputChip'), onSelected: enabled ? (bool value) {} : null, ), ], ), Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ FilterChip( selected: selected, selectedColor: selectedColor, color: color, label: const Text('FilterChip'), onSelected: enabled ? (bool value) {} : null, ), verticalSpace, FilterChip.elevated( selected: selected, selectedColor: selectedColor, color: color, label: const Text('FilterChip.elevated'), onSelected: enabled ? (bool value) {} : null, ), ], ), Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ ChoiceChip( selected: selected, selectedColor: selectedColor, color: color, label: const Text('ChoiceChip'), onSelected: enabled ? (bool value) {} : null, ), verticalSpace, ChoiceChip.elevated( selected: selected, selectedColor: selectedColor, color: color, label: const Text('ChoiceChip.elevated'), onSelected: enabled ? (bool value) {} : null, ), ], ), ], ), const Spacer(), Row( children: <Widget>[ Flexible( child: SwitchListTile( title: const Text('Enabled'), value: enabled, onChanged: (bool value) { setState(() => enabled = value); }, ), ), Flexible( child: SwitchListTile( title: const Text('Selected'), value: selected, onChanged: (bool value) { setState(() => selected = value); }, ), ), ], ) ], ), ), ); } } ``` </details> ### Before (not possible to customize disabled and selected chips)  ### After (using disabled and selected chips using the new MaterialState `color` property) 
This commit is contained in:
parent
62a1c8ee62
commit
467c970bfb
@ -41,7 +41,15 @@ class _${blockName}DefaultsM3 extends ChipThemeData {
|
|||||||
TextStyle? get labelStyle => ${textStyle("$tokenGroup.label-text")};
|
TextStyle? get labelStyle => ${textStyle("$tokenGroup.label-text")};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get backgroundColor => ${componentColor("$tokenGroup$flatVariant.container")};
|
MaterialStateProperty<Color?>? get color =>
|
||||||
|
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||||
|
if (states.contains(MaterialState.disabled)) {
|
||||||
|
return _chipVariant == _ChipVariant.flat
|
||||||
|
? ${componentColor("$tokenGroup$flatVariant.disabled.container")}
|
||||||
|
: ${componentColor("$tokenGroup$elevatedVariant.disabled.container")};
|
||||||
|
}
|
||||||
|
return ${componentColor("$tokenGroup$flatVariant.container")};
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get shadowColor => _chipVariant == _ChipVariant.flat
|
Color? get shadowColor => _chipVariant == _ChipVariant.flat
|
||||||
@ -51,17 +59,9 @@ class _${blockName}DefaultsM3 extends ChipThemeData {
|
|||||||
@override
|
@override
|
||||||
Color? get surfaceTintColor => ${colorOrTransparent("$tokenGroup.container.surface-tint-layer.color")};
|
Color? get surfaceTintColor => ${colorOrTransparent("$tokenGroup.container.surface-tint-layer.color")};
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get selectedColor => ${componentColor("$tokenGroup$flatVariant.selected.container")};
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get checkmarkColor => ${color("$tokenGroup.with-icon.selected.icon.color")};
|
Color? get checkmarkColor => ${color("$tokenGroup.with-icon.selected.icon.color")};
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get disabledColor => _chipVariant == _ChipVariant.flat
|
|
||||||
? ${componentColor("$tokenGroup$flatVariant.disabled.container")}
|
|
||||||
: ${componentColor("$tokenGroup$elevatedVariant.disabled.container")};
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get deleteIconColor => ${color("$tokenGroup.with-icon.selected.icon.color")};
|
Color? get deleteIconColor => ${color("$tokenGroup.with-icon.selected.icon.color")};
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ class _${blockName}DefaultsM3 extends ChipThemeData {
|
|||||||
TextStyle? get labelStyle => ${textStyle("$tokenGroup.label-text")};
|
TextStyle? get labelStyle => ${textStyle("$tokenGroup.label-text")};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get backgroundColor => ${componentColor("$tokenGroup$variant.container")};
|
MaterialStateProperty<Color?>? get color => null; // Subclasses override this getter
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get shadowColor => ${colorOrTransparent("$tokenGroup.container.shadow-color")};
|
Color? get shadowColor => ${colorOrTransparent("$tokenGroup.container.shadow-color")};
|
||||||
@ -40,15 +40,9 @@ class _${blockName}DefaultsM3 extends ChipThemeData {
|
|||||||
@override
|
@override
|
||||||
Color? get surfaceTintColor => ${colorOrTransparent("$tokenGroup.container.surface-tint-layer.color")};
|
Color? get surfaceTintColor => ${colorOrTransparent("$tokenGroup.container.surface-tint-layer.color")};
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get selectedColor => ${componentColor("$tokenGroup$variant.selected.container")};
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get checkmarkColor => ${color("$tokenGroup.with-icon.selected.icon.color")};
|
Color? get checkmarkColor => ${color("$tokenGroup.with-icon.selected.icon.color")};
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get disabledColor => ${componentColor("$tokenGroup$variant.disabled.container")};
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get deleteIconColor => ${color("$tokenGroup.with-icon.selected.icon.color")};
|
Color? get deleteIconColor => ${color("$tokenGroup.with-icon.selected.icon.color")};
|
||||||
|
|
||||||
|
@ -46,7 +46,27 @@ class _${blockName}DefaultsM3 extends ChipThemeData {
|
|||||||
TextStyle? get labelStyle => ${textStyle("$tokenGroup.label-text")};
|
TextStyle? get labelStyle => ${textStyle("$tokenGroup.label-text")};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get backgroundColor => ${componentColor("$tokenGroup$flatVariant.container")};
|
MaterialStateProperty<Color?>? get color =>
|
||||||
|
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||||
|
if (states.contains(MaterialState.selected) && states.contains(MaterialState.disabled)) {
|
||||||
|
return _chipVariant == _ChipVariant.flat
|
||||||
|
? ${componentColor("$tokenGroup$flatVariant.disabled.selected.container")}
|
||||||
|
: ${componentColor("$tokenGroup$elevatedVariant.disabled.container")};
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.disabled)) {
|
||||||
|
return _chipVariant == _ChipVariant.flat
|
||||||
|
? ${componentColor("$tokenGroup$flatVariant.disabled.unselected.container")}
|
||||||
|
: ${componentColor("$tokenGroup$elevatedVariant.disabled.container")};
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.selected)) {
|
||||||
|
return _chipVariant == _ChipVariant.flat
|
||||||
|
? ${componentColor("$tokenGroup$flatVariant.selected.container")}
|
||||||
|
: ${componentColor("$tokenGroup$elevatedVariant.selected.container")};
|
||||||
|
}
|
||||||
|
return _chipVariant == _ChipVariant.flat
|
||||||
|
? ${componentColor("$tokenGroup$flatVariant.container")}
|
||||||
|
: ${componentColor("$tokenGroup$elevatedVariant.container")};
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get shadowColor => _chipVariant == _ChipVariant.flat
|
Color? get shadowColor => _chipVariant == _ChipVariant.flat
|
||||||
@ -56,25 +76,9 @@ class _${blockName}DefaultsM3 extends ChipThemeData {
|
|||||||
@override
|
@override
|
||||||
Color? get surfaceTintColor => ${colorOrTransparent("$tokenGroup.container.surface-tint-layer.color")};
|
Color? get surfaceTintColor => ${colorOrTransparent("$tokenGroup.container.surface-tint-layer.color")};
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get selectedColor => _chipVariant == _ChipVariant.flat
|
|
||||||
? isEnabled
|
|
||||||
? ${componentColor("$tokenGroup$flatVariant.selected.container")}
|
|
||||||
: ${componentColor("$tokenGroup$flatVariant.disabled.selected.container")}
|
|
||||||
: isEnabled
|
|
||||||
? ${componentColor("$tokenGroup$elevatedVariant.selected.container")}
|
|
||||||
: ${componentColor("$tokenGroup$elevatedVariant.disabled.container")};
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get checkmarkColor => ${color("$tokenGroup.with-leading-icon.selected.leading-icon.color")};
|
Color? get checkmarkColor => ${color("$tokenGroup.with-leading-icon.selected.leading-icon.color")};
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get disabledColor => _chipVariant == _ChipVariant.flat
|
|
||||||
? isSelected
|
|
||||||
? ${componentColor("$tokenGroup$flatVariant.disabled.selected.container")}
|
|
||||||
: ${componentColor("$tokenGroup$flatVariant.disabled.unselected.container")}
|
|
||||||
: ${componentColor("$tokenGroup$elevatedVariant.disabled.container")};
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get deleteIconColor => ${color("$tokenGroup.with-trailing-icon.selected.trailing-icon.color")};
|
Color? get deleteIconColor => ${color("$tokenGroup.with-trailing-icon.selected.trailing-icon.color")};
|
||||||
|
|
||||||
|
@ -33,7 +33,19 @@ class _${blockName}DefaultsM3 extends ChipThemeData {
|
|||||||
TextStyle? get labelStyle => ${textStyle("$tokenGroup.label-text")};
|
TextStyle? get labelStyle => ${textStyle("$tokenGroup.label-text")};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get backgroundColor => ${componentColor("$tokenGroup$variant.container")};
|
MaterialStateProperty<Color?>? get color =>
|
||||||
|
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||||
|
if (states.contains(MaterialState.selected) && states.contains(MaterialState.disabled)) {
|
||||||
|
return ${componentColor("$tokenGroup$variant.disabled.selected.container")};
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.disabled)) {
|
||||||
|
return ${componentColor("$tokenGroup$variant.disabled.container")};
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.selected)) {
|
||||||
|
return ${componentColor("$tokenGroup$variant.selected.container")};
|
||||||
|
}
|
||||||
|
return ${componentColor("$tokenGroup$variant.container")};
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get shadowColor => ${colorOrTransparent("$tokenGroup.container.shadow-color")};
|
Color? get shadowColor => ${colorOrTransparent("$tokenGroup.container.shadow-color")};
|
||||||
@ -41,17 +53,9 @@ class _${blockName}DefaultsM3 extends ChipThemeData {
|
|||||||
@override
|
@override
|
||||||
Color? get surfaceTintColor => ${colorOrTransparent("$tokenGroup.container.surface-tint-layer.color")};
|
Color? get surfaceTintColor => ${colorOrTransparent("$tokenGroup.container.surface-tint-layer.color")};
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get selectedColor => isEnabled
|
|
||||||
? ${componentColor("$tokenGroup$variant.selected.container")}
|
|
||||||
: ${componentColor("$tokenGroup$variant.disabled.selected.container")};
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get checkmarkColor => ${color("$tokenGroup.with-icon.selected.icon.color")};
|
Color? get checkmarkColor => ${color("$tokenGroup.with-icon.selected.icon.color")};
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get disabledColor => ${componentColor("$tokenGroup$variant.disabled.container")};
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get deleteIconColor => ${color("$tokenGroup.with-trailing-icon.selected.trailing-icon.color")};
|
Color? get deleteIconColor => ${color("$tokenGroup.with-trailing-icon.selected.trailing-icon.color")};
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import 'chip_theme.dart';
|
|||||||
import 'color_scheme.dart';
|
import 'color_scheme.dart';
|
||||||
import 'colors.dart';
|
import 'colors.dart';
|
||||||
import 'debug.dart';
|
import 'debug.dart';
|
||||||
|
import 'material_state.dart';
|
||||||
import 'text_theme.dart';
|
import 'text_theme.dart';
|
||||||
import 'theme.dart';
|
import 'theme.dart';
|
||||||
import 'theme_data.dart';
|
import 'theme_data.dart';
|
||||||
@ -81,6 +82,7 @@ class ActionChip extends StatelessWidget implements ChipAttributes, TappableChip
|
|||||||
this.clipBehavior = Clip.none,
|
this.clipBehavior = Clip.none,
|
||||||
this.focusNode,
|
this.focusNode,
|
||||||
this.autofocus = false,
|
this.autofocus = false,
|
||||||
|
this.color,
|
||||||
this.backgroundColor,
|
this.backgroundColor,
|
||||||
this.disabledColor,
|
this.disabledColor,
|
||||||
this.padding,
|
this.padding,
|
||||||
@ -113,6 +115,7 @@ class ActionChip extends StatelessWidget implements ChipAttributes, TappableChip
|
|||||||
this.clipBehavior = Clip.none,
|
this.clipBehavior = Clip.none,
|
||||||
this.focusNode,
|
this.focusNode,
|
||||||
this.autofocus = false,
|
this.autofocus = false,
|
||||||
|
this.color,
|
||||||
this.backgroundColor,
|
this.backgroundColor,
|
||||||
this.disabledColor,
|
this.disabledColor,
|
||||||
this.padding,
|
this.padding,
|
||||||
@ -151,6 +154,8 @@ class ActionChip extends StatelessWidget implements ChipAttributes, TappableChip
|
|||||||
@override
|
@override
|
||||||
final bool autofocus;
|
final bool autofocus;
|
||||||
@override
|
@override
|
||||||
|
final MaterialStateProperty<Color?>? color;
|
||||||
|
@override
|
||||||
final Color? backgroundColor;
|
final Color? backgroundColor;
|
||||||
@override
|
@override
|
||||||
final Color? disabledColor;
|
final Color? disabledColor;
|
||||||
@ -188,6 +193,7 @@ class ActionChip extends StatelessWidget implements ChipAttributes, TappableChip
|
|||||||
pressElevation: pressElevation,
|
pressElevation: pressElevation,
|
||||||
tooltip: tooltip,
|
tooltip: tooltip,
|
||||||
labelStyle: labelStyle,
|
labelStyle: labelStyle,
|
||||||
|
color: color,
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
side: side,
|
side: side,
|
||||||
shape: shape,
|
shape: shape,
|
||||||
@ -239,7 +245,15 @@ class _ActionChipDefaultsM3 extends ChipThemeData {
|
|||||||
TextStyle? get labelStyle => _textTheme.labelLarge;
|
TextStyle? get labelStyle => _textTheme.labelLarge;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get backgroundColor => null;
|
MaterialStateProperty<Color?>? get color =>
|
||||||
|
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||||
|
if (states.contains(MaterialState.disabled)) {
|
||||||
|
return _chipVariant == _ChipVariant.flat
|
||||||
|
? null
|
||||||
|
: _colors.onSurface.withOpacity(0.12);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get shadowColor => _chipVariant == _ChipVariant.flat
|
Color? get shadowColor => _chipVariant == _ChipVariant.flat
|
||||||
@ -249,17 +263,9 @@ class _ActionChipDefaultsM3 extends ChipThemeData {
|
|||||||
@override
|
@override
|
||||||
Color? get surfaceTintColor => _colors.surfaceTint;
|
Color? get surfaceTintColor => _colors.surfaceTint;
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get selectedColor => null;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get checkmarkColor => null;
|
Color? get checkmarkColor => null;
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get disabledColor => _chipVariant == _ChipVariant.flat
|
|
||||||
? null
|
|
||||||
: _colors.onSurface.withOpacity(0.12);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get deleteIconColor => null;
|
Color? get deleteIconColor => null;
|
||||||
|
|
||||||
|
@ -137,6 +137,13 @@ abstract interface class ChipAttributes {
|
|||||||
/// {@macro flutter.widgets.Focus.autofocus}
|
/// {@macro flutter.widgets.Focus.autofocus}
|
||||||
bool get autofocus;
|
bool get autofocus;
|
||||||
|
|
||||||
|
/// The color that fills the chip, in all [MaterialState]s.
|
||||||
|
///
|
||||||
|
/// Resolves in the following states:
|
||||||
|
/// * [MaterialState.selected].
|
||||||
|
/// * [MaterialState.disabled].
|
||||||
|
MaterialStateProperty<Color?>? get color;
|
||||||
|
|
||||||
/// Color to be used for the unselected, enabled chip's background.
|
/// Color to be used for the unselected, enabled chip's background.
|
||||||
///
|
///
|
||||||
/// The default is light grey.
|
/// The default is light grey.
|
||||||
@ -561,6 +568,7 @@ class Chip extends StatelessWidget implements ChipAttributes, DeletableChipAttri
|
|||||||
this.clipBehavior = Clip.none,
|
this.clipBehavior = Clip.none,
|
||||||
this.focusNode,
|
this.focusNode,
|
||||||
this.autofocus = false,
|
this.autofocus = false,
|
||||||
|
this.color,
|
||||||
this.backgroundColor,
|
this.backgroundColor,
|
||||||
this.padding,
|
this.padding,
|
||||||
this.visualDensity,
|
this.visualDensity,
|
||||||
@ -595,6 +603,8 @@ class Chip extends StatelessWidget implements ChipAttributes, DeletableChipAttri
|
|||||||
@override
|
@override
|
||||||
final bool autofocus;
|
final bool autofocus;
|
||||||
@override
|
@override
|
||||||
|
final MaterialStateProperty<Color?>? color;
|
||||||
|
@override
|
||||||
final Color? backgroundColor;
|
final Color? backgroundColor;
|
||||||
@override
|
@override
|
||||||
final EdgeInsetsGeometry? padding;
|
final EdgeInsetsGeometry? padding;
|
||||||
@ -644,6 +654,7 @@ class Chip extends StatelessWidget implements ChipAttributes, DeletableChipAttri
|
|||||||
clipBehavior: clipBehavior,
|
clipBehavior: clipBehavior,
|
||||||
focusNode: focusNode,
|
focusNode: focusNode,
|
||||||
autofocus: autofocus,
|
autofocus: autofocus,
|
||||||
|
color: color,
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
padding: padding,
|
padding: padding,
|
||||||
visualDensity: visualDensity,
|
visualDensity: visualDensity,
|
||||||
@ -729,6 +740,7 @@ class RawChip extends StatefulWidget
|
|||||||
this.clipBehavior = Clip.none,
|
this.clipBehavior = Clip.none,
|
||||||
this.focusNode,
|
this.focusNode,
|
||||||
this.autofocus = false,
|
this.autofocus = false,
|
||||||
|
this.color,
|
||||||
this.backgroundColor,
|
this.backgroundColor,
|
||||||
this.materialTapTargetSize,
|
this.materialTapTargetSize,
|
||||||
this.elevation,
|
this.elevation,
|
||||||
@ -798,6 +810,8 @@ class RawChip extends StatefulWidget
|
|||||||
@override
|
@override
|
||||||
final bool autofocus;
|
final bool autofocus;
|
||||||
@override
|
@override
|
||||||
|
final MaterialStateProperty<Color?>? color;
|
||||||
|
@override
|
||||||
final Color? backgroundColor;
|
final Color? backgroundColor;
|
||||||
@override
|
@override
|
||||||
final EdgeInsetsGeometry? padding;
|
final EdgeInsetsGeometry? padding;
|
||||||
@ -987,23 +1001,47 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
|
|||||||
return resolvedShape.copyWith(side: resolvedSide);
|
return resolvedShape.copyWith(side: resolvedSide);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Color? resolveColor({
|
||||||
|
MaterialStateProperty<Color?>? color,
|
||||||
|
Color? selectedColor,
|
||||||
|
Color? backgroundColor,
|
||||||
|
Color? disabledColor,
|
||||||
|
MaterialStateProperty<Color?>? defaultColor,
|
||||||
|
}) {
|
||||||
|
return _IndividualOverrides(
|
||||||
|
color: color,
|
||||||
|
selectedColor: selectedColor,
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
disabledColor: disabledColor,
|
||||||
|
).resolve(materialStates) ?? defaultColor?.resolve(materialStates);
|
||||||
|
}
|
||||||
|
|
||||||
/// 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(ThemeData theme, ChipThemeData chipTheme, ChipThemeData chipDefaults) {
|
Color? _getBackgroundColor(ThemeData theme, ChipThemeData chipTheme, ChipThemeData chipDefaults) {
|
||||||
if (theme.useMaterial3) {
|
if (theme.useMaterial3) {
|
||||||
|
final Color? disabledColor = resolveColor(
|
||||||
|
color: widget.color ?? chipTheme.color,
|
||||||
|
disabledColor: widget.disabledColor ?? chipTheme.disabledColor,
|
||||||
|
defaultColor: chipDefaults.color,
|
||||||
|
);
|
||||||
|
final Color? backgroundColor = resolveColor(
|
||||||
|
color: widget.color ?? chipTheme.color,
|
||||||
|
backgroundColor: widget.backgroundColor ?? chipTheme.backgroundColor,
|
||||||
|
defaultColor: chipDefaults.color,
|
||||||
|
);
|
||||||
|
final Color? selectedColor = resolveColor(
|
||||||
|
color: widget.color ?? chipTheme.color,
|
||||||
|
selectedColor: widget.selectedColor ?? chipTheme.selectedColor,
|
||||||
|
defaultColor: chipDefaults.color,
|
||||||
|
);
|
||||||
final ColorTween backgroundTween = ColorTween(
|
final ColorTween backgroundTween = ColorTween(
|
||||||
begin: widget.disabledColor
|
begin: disabledColor,
|
||||||
?? chipTheme.disabledColor
|
end: backgroundColor,
|
||||||
?? chipDefaults.disabledColor,
|
|
||||||
end: widget.backgroundColor
|
|
||||||
?? chipTheme.backgroundColor
|
|
||||||
?? chipDefaults.backgroundColor,
|
|
||||||
);
|
);
|
||||||
final ColorTween selectTween = ColorTween(
|
final ColorTween selectTween = ColorTween(
|
||||||
begin: backgroundTween.evaluate(enableController),
|
begin: backgroundTween.evaluate(enableController),
|
||||||
end: widget.selectedColor
|
end: selectedColor,
|
||||||
?? chipTheme.selectedColor
|
|
||||||
?? chipDefaults.selectedColor,
|
|
||||||
);
|
);
|
||||||
return selectTween.evaluate(selectionFade);
|
return selectTween.evaluate(selectionFade);
|
||||||
} else {
|
} else {
|
||||||
@ -1295,6 +1333,37 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _IndividualOverrides extends MaterialStateProperty<Color?> {
|
||||||
|
_IndividualOverrides({
|
||||||
|
this.color,
|
||||||
|
this.backgroundColor,
|
||||||
|
this.selectedColor,
|
||||||
|
this.disabledColor,
|
||||||
|
});
|
||||||
|
|
||||||
|
final MaterialStateProperty<Color?>? color;
|
||||||
|
final Color? backgroundColor;
|
||||||
|
final Color? selectedColor;
|
||||||
|
final Color? disabledColor;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color? resolve(Set<MaterialState> states) {
|
||||||
|
if (color != null) {
|
||||||
|
return color!.resolve(states);
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.selected) && states.contains(MaterialState.disabled)) {
|
||||||
|
return selectedColor;
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.disabled)) {
|
||||||
|
return disabledColor;
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.selected)) {
|
||||||
|
return selectedColor;
|
||||||
|
}
|
||||||
|
return backgroundColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Redirects the [buttonRect.dy] passed to [RenderBox.hitTest] to the vertical
|
/// Redirects the [buttonRect.dy] passed to [RenderBox.hitTest] to the vertical
|
||||||
/// center of the widget.
|
/// center of the widget.
|
||||||
///
|
///
|
||||||
@ -2176,7 +2245,7 @@ class _ChipDefaultsM3 extends ChipThemeData {
|
|||||||
TextStyle? get labelStyle => _textTheme.labelLarge;
|
TextStyle? get labelStyle => _textTheme.labelLarge;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get backgroundColor => null;
|
MaterialStateProperty<Color?>? get color => null; // Subclasses override this getter
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get shadowColor => Colors.transparent;
|
Color? get shadowColor => Colors.transparent;
|
||||||
@ -2184,15 +2253,9 @@ class _ChipDefaultsM3 extends ChipThemeData {
|
|||||||
@override
|
@override
|
||||||
Color? get surfaceTintColor => _colors.surfaceTint;
|
Color? get surfaceTintColor => _colors.surfaceTint;
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get selectedColor => null;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get checkmarkColor => null;
|
Color? get checkmarkColor => null;
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get disabledColor => null;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get deleteIconColor => null;
|
Color? get deleteIconColor => null;
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import 'package:flutter/rendering.dart';
|
|||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
import 'colors.dart';
|
import 'colors.dart';
|
||||||
|
import 'material_state.dart';
|
||||||
import 'theme.dart';
|
import 'theme.dart';
|
||||||
|
|
||||||
/// Applies a chip theme to descendant [RawChip]-based widgets, like [Chip],
|
/// Applies a chip theme to descendant [RawChip]-based widgets, like [Chip],
|
||||||
@ -178,6 +179,7 @@ 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({
|
||||||
|
this.color,
|
||||||
this.backgroundColor,
|
this.backgroundColor,
|
||||||
this.deleteIconColor,
|
this.deleteIconColor,
|
||||||
this.disabledColor,
|
this.disabledColor,
|
||||||
@ -268,6 +270,12 @@ class ChipThemeData with Diagnosticable {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Overrides the default for [ChipAttributes.color].
|
||||||
|
///
|
||||||
|
/// This property applies to [ActionChip], [Chip], [ChoiceChip],
|
||||||
|
/// [FilterChip], [InputChip], [RawChip].
|
||||||
|
final MaterialStateProperty<Color?>? color;
|
||||||
|
|
||||||
/// Overrides the default for [ChipAttributes.backgroundColor]
|
/// Overrides the default for [ChipAttributes.backgroundColor]
|
||||||
/// which is used for unselected, enabled chip backgrounds.
|
/// which is used for unselected, enabled chip backgrounds.
|
||||||
///
|
///
|
||||||
@ -433,6 +441,7 @@ class ChipThemeData with Diagnosticable {
|
|||||||
/// 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
|
||||||
/// new values.
|
/// new values.
|
||||||
ChipThemeData copyWith({
|
ChipThemeData copyWith({
|
||||||
|
MaterialStateProperty<Color?>? color,
|
||||||
Color? backgroundColor,
|
Color? backgroundColor,
|
||||||
Color? deleteIconColor,
|
Color? deleteIconColor,
|
||||||
Color? disabledColor,
|
Color? disabledColor,
|
||||||
@ -455,6 +464,7 @@ class ChipThemeData with Diagnosticable {
|
|||||||
IconThemeData? iconTheme,
|
IconThemeData? iconTheme,
|
||||||
}) {
|
}) {
|
||||||
return ChipThemeData(
|
return ChipThemeData(
|
||||||
|
color: color ?? this.color,
|
||||||
backgroundColor: backgroundColor ?? this.backgroundColor,
|
backgroundColor: backgroundColor ?? this.backgroundColor,
|
||||||
deleteIconColor: deleteIconColor ?? this.deleteIconColor,
|
deleteIconColor: deleteIconColor ?? this.deleteIconColor,
|
||||||
disabledColor: disabledColor ?? this.disabledColor,
|
disabledColor: disabledColor ?? this.disabledColor,
|
||||||
@ -488,6 +498,7 @@ class ChipThemeData with Diagnosticable {
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
return ChipThemeData(
|
return ChipThemeData(
|
||||||
|
color: MaterialStateProperty.lerp<Color?>(a?.color, b?.color, t, Color.lerp),
|
||||||
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),
|
||||||
@ -537,6 +548,7 @@ class ChipThemeData with Diagnosticable {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hashAll(<Object?>[
|
int get hashCode => Object.hashAll(<Object?>[
|
||||||
|
color,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
deleteIconColor,
|
deleteIconColor,
|
||||||
disabledColor,
|
disabledColor,
|
||||||
@ -568,6 +580,7 @@ class ChipThemeData with Diagnosticable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return other is ChipThemeData
|
return other is ChipThemeData
|
||||||
|
&& other.color == color
|
||||||
&& other.backgroundColor == backgroundColor
|
&& other.backgroundColor == backgroundColor
|
||||||
&& other.deleteIconColor == deleteIconColor
|
&& other.deleteIconColor == deleteIconColor
|
||||||
&& other.disabledColor == disabledColor
|
&& other.disabledColor == disabledColor
|
||||||
@ -593,6 +606,7 @@ class ChipThemeData with Diagnosticable {
|
|||||||
@override
|
@override
|
||||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
super.debugFillProperties(properties);
|
super.debugFillProperties(properties);
|
||||||
|
properties.add(DiagnosticsProperty<MaterialStateProperty<Color?>>('color', color, defaultValue: null));
|
||||||
properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null));
|
properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null));
|
||||||
properties.add(ColorProperty('deleteIconColor', deleteIconColor, defaultValue: null));
|
properties.add(ColorProperty('deleteIconColor', deleteIconColor, defaultValue: null));
|
||||||
properties.add(ColorProperty('disabledColor', disabledColor, defaultValue: null));
|
properties.add(ColorProperty('disabledColor', disabledColor, defaultValue: null));
|
||||||
|
@ -10,6 +10,7 @@ import 'chip_theme.dart';
|
|||||||
import 'color_scheme.dart';
|
import 'color_scheme.dart';
|
||||||
import 'colors.dart';
|
import 'colors.dart';
|
||||||
import 'debug.dart';
|
import 'debug.dart';
|
||||||
|
import 'material_state.dart';
|
||||||
import 'text_theme.dart';
|
import 'text_theme.dart';
|
||||||
import 'theme.dart';
|
import 'theme.dart';
|
||||||
import 'theme_data.dart';
|
import 'theme_data.dart';
|
||||||
@ -78,6 +79,7 @@ class ChoiceChip extends StatelessWidget
|
|||||||
this.clipBehavior = Clip.none,
|
this.clipBehavior = Clip.none,
|
||||||
this.focusNode,
|
this.focusNode,
|
||||||
this.autofocus = false,
|
this.autofocus = false,
|
||||||
|
this.color,
|
||||||
this.backgroundColor,
|
this.backgroundColor,
|
||||||
this.padding,
|
this.padding,
|
||||||
this.visualDensity,
|
this.visualDensity,
|
||||||
@ -116,6 +118,7 @@ class ChoiceChip extends StatelessWidget
|
|||||||
this.clipBehavior = Clip.none,
|
this.clipBehavior = Clip.none,
|
||||||
this.focusNode,
|
this.focusNode,
|
||||||
this.autofocus = false,
|
this.autofocus = false,
|
||||||
|
this.color,
|
||||||
this.backgroundColor,
|
this.backgroundColor,
|
||||||
this.padding,
|
this.padding,
|
||||||
this.visualDensity,
|
this.visualDensity,
|
||||||
@ -163,6 +166,8 @@ class ChoiceChip extends StatelessWidget
|
|||||||
@override
|
@override
|
||||||
final bool autofocus;
|
final bool autofocus;
|
||||||
@override
|
@override
|
||||||
|
final MaterialStateProperty<Color?>? color;
|
||||||
|
@override
|
||||||
final Color? backgroundColor;
|
final Color? backgroundColor;
|
||||||
@override
|
@override
|
||||||
final EdgeInsetsGeometry? padding;
|
final EdgeInsetsGeometry? padding;
|
||||||
@ -218,6 +223,7 @@ class ChoiceChip extends StatelessWidget
|
|||||||
autofocus: autofocus,
|
autofocus: autofocus,
|
||||||
disabledColor: disabledColor,
|
disabledColor: disabledColor,
|
||||||
selectedColor: selectedColor ?? chipTheme.secondarySelectedColor,
|
selectedColor: selectedColor ?? chipTheme.secondarySelectedColor,
|
||||||
|
color: color,
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
padding: padding,
|
padding: padding,
|
||||||
visualDensity: visualDensity,
|
visualDensity: visualDensity,
|
||||||
@ -270,7 +276,27 @@ class _ChoiceChipDefaultsM3 extends ChipThemeData {
|
|||||||
TextStyle? get labelStyle => _textTheme.labelLarge;
|
TextStyle? get labelStyle => _textTheme.labelLarge;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get backgroundColor => null;
|
MaterialStateProperty<Color?>? get color =>
|
||||||
|
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||||
|
if (states.contains(MaterialState.selected) && states.contains(MaterialState.disabled)) {
|
||||||
|
return _chipVariant == _ChipVariant.flat
|
||||||
|
? _colors.onSurface.withOpacity(0.12)
|
||||||
|
: _colors.onSurface.withOpacity(0.12);
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.disabled)) {
|
||||||
|
return _chipVariant == _ChipVariant.flat
|
||||||
|
? null
|
||||||
|
: _colors.onSurface.withOpacity(0.12);
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.selected)) {
|
||||||
|
return _chipVariant == _ChipVariant.flat
|
||||||
|
? _colors.secondaryContainer
|
||||||
|
: _colors.secondaryContainer;
|
||||||
|
}
|
||||||
|
return _chipVariant == _ChipVariant.flat
|
||||||
|
? null
|
||||||
|
: null;
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get shadowColor => _chipVariant == _ChipVariant.flat
|
Color? get shadowColor => _chipVariant == _ChipVariant.flat
|
||||||
@ -280,25 +306,9 @@ class _ChoiceChipDefaultsM3 extends ChipThemeData {
|
|||||||
@override
|
@override
|
||||||
Color? get surfaceTintColor => _colors.surfaceTint;
|
Color? get surfaceTintColor => _colors.surfaceTint;
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get selectedColor => _chipVariant == _ChipVariant.flat
|
|
||||||
? isEnabled
|
|
||||||
? _colors.secondaryContainer
|
|
||||||
: _colors.onSurface.withOpacity(0.12)
|
|
||||||
: isEnabled
|
|
||||||
? _colors.secondaryContainer
|
|
||||||
: _colors.onSurface.withOpacity(0.12);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get checkmarkColor => _colors.onSecondaryContainer;
|
Color? get checkmarkColor => _colors.onSecondaryContainer;
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get disabledColor => _chipVariant == _ChipVariant.flat
|
|
||||||
? isSelected
|
|
||||||
? _colors.onSurface.withOpacity(0.12)
|
|
||||||
: null
|
|
||||||
: _colors.onSurface.withOpacity(0.12);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get deleteIconColor => _colors.onSecondaryContainer;
|
Color? get deleteIconColor => _colors.onSecondaryContainer;
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import 'chip_theme.dart';
|
|||||||
import 'color_scheme.dart';
|
import 'color_scheme.dart';
|
||||||
import 'colors.dart';
|
import 'colors.dart';
|
||||||
import 'debug.dart';
|
import 'debug.dart';
|
||||||
|
import 'material_state.dart';
|
||||||
import 'text_theme.dart';
|
import 'text_theme.dart';
|
||||||
import 'theme.dart';
|
import 'theme.dart';
|
||||||
import 'theme_data.dart';
|
import 'theme_data.dart';
|
||||||
@ -80,6 +81,7 @@ class FilterChip extends StatelessWidget
|
|||||||
this.clipBehavior = Clip.none,
|
this.clipBehavior = Clip.none,
|
||||||
this.focusNode,
|
this.focusNode,
|
||||||
this.autofocus = false,
|
this.autofocus = false,
|
||||||
|
this.color,
|
||||||
this.backgroundColor,
|
this.backgroundColor,
|
||||||
this.padding,
|
this.padding,
|
||||||
this.visualDensity,
|
this.visualDensity,
|
||||||
@ -118,6 +120,7 @@ class FilterChip extends StatelessWidget
|
|||||||
this.clipBehavior = Clip.none,
|
this.clipBehavior = Clip.none,
|
||||||
this.focusNode,
|
this.focusNode,
|
||||||
this.autofocus = false,
|
this.autofocus = false,
|
||||||
|
this.color,
|
||||||
this.backgroundColor,
|
this.backgroundColor,
|
||||||
this.padding,
|
this.padding,
|
||||||
this.visualDensity,
|
this.visualDensity,
|
||||||
@ -165,6 +168,8 @@ class FilterChip extends StatelessWidget
|
|||||||
@override
|
@override
|
||||||
final bool autofocus;
|
final bool autofocus;
|
||||||
@override
|
@override
|
||||||
|
final MaterialStateProperty<Color?>? color;
|
||||||
|
@override
|
||||||
final Color? backgroundColor;
|
final Color? backgroundColor;
|
||||||
@override
|
@override
|
||||||
final EdgeInsetsGeometry? padding;
|
final EdgeInsetsGeometry? padding;
|
||||||
@ -215,6 +220,7 @@ class FilterChip extends StatelessWidget
|
|||||||
clipBehavior: clipBehavior,
|
clipBehavior: clipBehavior,
|
||||||
focusNode: focusNode,
|
focusNode: focusNode,
|
||||||
autofocus: autofocus,
|
autofocus: autofocus,
|
||||||
|
color: color,
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
disabledColor: disabledColor,
|
disabledColor: disabledColor,
|
||||||
selectedColor: selectedColor,
|
selectedColor: selectedColor,
|
||||||
@ -270,7 +276,27 @@ class _FilterChipDefaultsM3 extends ChipThemeData {
|
|||||||
TextStyle? get labelStyle => _textTheme.labelLarge;
|
TextStyle? get labelStyle => _textTheme.labelLarge;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get backgroundColor => null;
|
MaterialStateProperty<Color?>? get color =>
|
||||||
|
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||||
|
if (states.contains(MaterialState.selected) && states.contains(MaterialState.disabled)) {
|
||||||
|
return _chipVariant == _ChipVariant.flat
|
||||||
|
? _colors.onSurface.withOpacity(0.12)
|
||||||
|
: _colors.onSurface.withOpacity(0.12);
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.disabled)) {
|
||||||
|
return _chipVariant == _ChipVariant.flat
|
||||||
|
? null
|
||||||
|
: _colors.onSurface.withOpacity(0.12);
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.selected)) {
|
||||||
|
return _chipVariant == _ChipVariant.flat
|
||||||
|
? _colors.secondaryContainer
|
||||||
|
: _colors.secondaryContainer;
|
||||||
|
}
|
||||||
|
return _chipVariant == _ChipVariant.flat
|
||||||
|
? null
|
||||||
|
: null;
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get shadowColor => _chipVariant == _ChipVariant.flat
|
Color? get shadowColor => _chipVariant == _ChipVariant.flat
|
||||||
@ -280,25 +306,9 @@ class _FilterChipDefaultsM3 extends ChipThemeData {
|
|||||||
@override
|
@override
|
||||||
Color? get surfaceTintColor => _colors.surfaceTint;
|
Color? get surfaceTintColor => _colors.surfaceTint;
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get selectedColor => _chipVariant == _ChipVariant.flat
|
|
||||||
? isEnabled
|
|
||||||
? _colors.secondaryContainer
|
|
||||||
: _colors.onSurface.withOpacity(0.12)
|
|
||||||
: isEnabled
|
|
||||||
? _colors.secondaryContainer
|
|
||||||
: _colors.onSurface.withOpacity(0.12);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get checkmarkColor => _colors.onSecondaryContainer;
|
Color? get checkmarkColor => _colors.onSecondaryContainer;
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get disabledColor => _chipVariant == _ChipVariant.flat
|
|
||||||
? isSelected
|
|
||||||
? _colors.onSurface.withOpacity(0.12)
|
|
||||||
: null
|
|
||||||
: _colors.onSurface.withOpacity(0.12);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get deleteIconColor => _colors.onSecondaryContainer;
|
Color? get deleteIconColor => _colors.onSecondaryContainer;
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import 'color_scheme.dart';
|
|||||||
import 'colors.dart';
|
import 'colors.dart';
|
||||||
import 'debug.dart';
|
import 'debug.dart';
|
||||||
import 'icons.dart';
|
import 'icons.dart';
|
||||||
|
import 'material_state.dart';
|
||||||
import 'text_theme.dart';
|
import 'text_theme.dart';
|
||||||
import 'theme.dart';
|
import 'theme.dart';
|
||||||
import 'theme_data.dart';
|
import 'theme_data.dart';
|
||||||
@ -99,6 +100,7 @@ class InputChip extends StatelessWidget
|
|||||||
this.clipBehavior = Clip.none,
|
this.clipBehavior = Clip.none,
|
||||||
this.focusNode,
|
this.focusNode,
|
||||||
this.autofocus = false,
|
this.autofocus = false,
|
||||||
|
this.color,
|
||||||
this.backgroundColor,
|
this.backgroundColor,
|
||||||
this.padding,
|
this.padding,
|
||||||
this.visualDensity,
|
this.visualDensity,
|
||||||
@ -162,6 +164,8 @@ class InputChip extends StatelessWidget
|
|||||||
@override
|
@override
|
||||||
final bool autofocus;
|
final bool autofocus;
|
||||||
@override
|
@override
|
||||||
|
final MaterialStateProperty<Color?>? color;
|
||||||
|
@override
|
||||||
final Color? backgroundColor;
|
final Color? backgroundColor;
|
||||||
@override
|
@override
|
||||||
final EdgeInsetsGeometry? padding;
|
final EdgeInsetsGeometry? padding;
|
||||||
@ -223,6 +227,7 @@ class InputChip extends StatelessWidget
|
|||||||
clipBehavior: clipBehavior,
|
clipBehavior: clipBehavior,
|
||||||
focusNode: focusNode,
|
focusNode: focusNode,
|
||||||
autofocus: autofocus,
|
autofocus: autofocus,
|
||||||
|
color: color,
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
padding: padding,
|
padding: padding,
|
||||||
visualDensity: visualDensity,
|
visualDensity: visualDensity,
|
||||||
@ -264,7 +269,19 @@ class _InputChipDefaultsM3 extends ChipThemeData {
|
|||||||
TextStyle? get labelStyle => _textTheme.labelLarge;
|
TextStyle? get labelStyle => _textTheme.labelLarge;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get backgroundColor => null;
|
MaterialStateProperty<Color?>? get color =>
|
||||||
|
MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||||
|
if (states.contains(MaterialState.selected) && states.contains(MaterialState.disabled)) {
|
||||||
|
return _colors.onSurface.withOpacity(0.12);
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.disabled)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.selected)) {
|
||||||
|
return _colors.secondaryContainer;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get shadowColor => Colors.transparent;
|
Color? get shadowColor => Colors.transparent;
|
||||||
@ -272,17 +289,9 @@ class _InputChipDefaultsM3 extends ChipThemeData {
|
|||||||
@override
|
@override
|
||||||
Color? get surfaceTintColor => Colors.transparent;
|
Color? get surfaceTintColor => Colors.transparent;
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get selectedColor => isEnabled
|
|
||||||
? _colors.secondaryContainer
|
|
||||||
: _colors.onSurface.withOpacity(0.12);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get checkmarkColor => null;
|
Color? get checkmarkColor => null;
|
||||||
|
|
||||||
@override
|
|
||||||
Color? get disabledColor => null;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Color? get deleteIconColor => _colors.onSecondaryContainer;
|
Color? get deleteIconColor => _colors.onSecondaryContainer;
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
import '../foundation/leak_tracking.dart';
|
import '../foundation/leak_tracking.dart';
|
||||||
|
import '../rendering/mock_canvas.dart';
|
||||||
|
|
||||||
/// Adds the basic requirements for a Chip.
|
/// Adds the basic requirements for a Chip.
|
||||||
Widget wrapForChip({
|
Widget wrapForChip({
|
||||||
@ -13,9 +14,10 @@ Widget wrapForChip({
|
|||||||
TextDirection textDirection = TextDirection.ltr,
|
TextDirection textDirection = TextDirection.ltr,
|
||||||
double textScaleFactor = 1.0,
|
double textScaleFactor = 1.0,
|
||||||
Brightness brightness = Brightness.light,
|
Brightness brightness = Brightness.light,
|
||||||
|
bool? useMaterial3,
|
||||||
}) {
|
}) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
theme: ThemeData(brightness: brightness),
|
theme: ThemeData(brightness: brightness, useMaterial3: useMaterial3),
|
||||||
home: Directionality(
|
home: Directionality(
|
||||||
textDirection: textDirection,
|
textDirection: textDirection,
|
||||||
child: MediaQuery(
|
child: MediaQuery(
|
||||||
@ -26,6 +28,15 @@ Widget wrapForChip({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RenderBox getMaterialBox(WidgetTester tester, Finder type) {
|
||||||
|
return tester.firstRenderObject<RenderBox>(
|
||||||
|
find.descendant(
|
||||||
|
of: type,
|
||||||
|
matching: find.byType(CustomPaint),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Material getMaterial(WidgetTester tester) {
|
Material getMaterial(WidgetTester tester) {
|
||||||
return tester.widget<Material>(
|
return tester.widget<Material>(
|
||||||
find.descendant(
|
find.descendant(
|
||||||
@ -196,6 +207,120 @@ void main() {
|
|||||||
expect(decoration.color, theme.colorScheme.onSurface.withOpacity(0.12));
|
expect(decoration.color, theme.colorScheme.onSurface.withOpacity(0.12));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('ActionChip.color resolves material states', (WidgetTester tester) async {
|
||||||
|
const Color disabledColor = Color(0xff00ff00);
|
||||||
|
const Color backgroundColor = Color(0xff0000ff);
|
||||||
|
final MaterialStateProperty<Color?> color = MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||||
|
if (states.contains(MaterialState.disabled)) {
|
||||||
|
return disabledColor;
|
||||||
|
}
|
||||||
|
return backgroundColor;
|
||||||
|
});
|
||||||
|
Widget buildApp({ required bool enabled, required bool selected }) {
|
||||||
|
return wrapForChip(
|
||||||
|
useMaterial3: true,
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
ActionChip(
|
||||||
|
onPressed: enabled ? () { } : null,
|
||||||
|
color: color,
|
||||||
|
label: const Text('ActionChip'),
|
||||||
|
),
|
||||||
|
ActionChip.elevated(
|
||||||
|
onPressed: enabled ? () { } : null,
|
||||||
|
color: color,
|
||||||
|
label: const Text('ActionChip.elevated'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test enabled state.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: false));
|
||||||
|
|
||||||
|
// Enabled ActionChip should have the provided backgroundColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: backgroundColor),
|
||||||
|
);
|
||||||
|
// Enabled elevated ActionChip should have the provided backgroundColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: backgroundColor),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test disabled state.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: false));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled ActionChip should have the provided disabledColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: disabledColor),
|
||||||
|
);
|
||||||
|
// Disabled elevated ActionChip should have the provided disabledColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: disabledColor),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('ActionChip uses provided state color properties', (WidgetTester tester) async {
|
||||||
|
const Color disabledColor = Color(0xff00ff00);
|
||||||
|
const Color backgroundColor = Color(0xff0000ff);
|
||||||
|
Widget buildApp({ required bool enabled, required bool selected }) {
|
||||||
|
return wrapForChip(
|
||||||
|
useMaterial3: true,
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
ActionChip(
|
||||||
|
onPressed: enabled ? () { } : null,
|
||||||
|
disabledColor: disabledColor,
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
label: const Text('ActionChip'),
|
||||||
|
),
|
||||||
|
ActionChip.elevated(
|
||||||
|
onPressed: enabled ? () { } : null,
|
||||||
|
disabledColor: disabledColor,
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
label: const Text('ActionChip.elevated'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test enabled state.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: false));
|
||||||
|
|
||||||
|
// Enabled ActionChip should have the provided backgroundColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: backgroundColor),
|
||||||
|
);
|
||||||
|
// Enabled elevated ActionChip should have the provided backgroundColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: backgroundColor),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test disabled state.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: false));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled ActionChip should have the provided disabledColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: disabledColor),
|
||||||
|
);
|
||||||
|
// Disabled elevated ActionChip should have the provided disabledColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: disabledColor),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgetsWithLeakTracking('ActionChip can be tapped', (WidgetTester tester) async {
|
testWidgetsWithLeakTracking('ActionChip can be tapped', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
|
@ -74,9 +74,10 @@ Widget wrapForChip({
|
|||||||
TextDirection textDirection = TextDirection.ltr,
|
TextDirection textDirection = TextDirection.ltr,
|
||||||
double textScaleFactor = 1.0,
|
double textScaleFactor = 1.0,
|
||||||
Brightness brightness = Brightness.light,
|
Brightness brightness = Brightness.light,
|
||||||
|
bool? useMaterial3,
|
||||||
}) {
|
}) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
theme: ThemeData(brightness: brightness, useMaterial3: false),
|
theme: ThemeData(brightness: brightness, useMaterial3: useMaterial3),
|
||||||
home: Directionality(
|
home: Directionality(
|
||||||
textDirection: textDirection,
|
textDirection: textDirection,
|
||||||
child: MediaQuery(
|
child: MediaQuery(
|
||||||
@ -3341,6 +3342,338 @@ void main() {
|
|||||||
..rect(color: const Color(0x1f000000)),
|
..rect(color: const Color(0x1f000000)),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('RawChip.color resolves material states', (WidgetTester tester) async {
|
||||||
|
const Color disabledSelectedColor = Color(0xffffff00);
|
||||||
|
const Color disabledColor = Color(0xff00ff00);
|
||||||
|
const Color backgroundColor = Color(0xff0000ff);
|
||||||
|
const Color selectedColor = Color(0xffff0000);
|
||||||
|
Widget buildApp({ required bool enabled, required bool selected }) {
|
||||||
|
return wrapForChip(
|
||||||
|
useMaterial3: true,
|
||||||
|
child: RawChip(
|
||||||
|
isEnabled: enabled,
|
||||||
|
selected: selected,
|
||||||
|
color: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||||
|
if (states.contains(MaterialState.disabled) && states.contains(MaterialState.selected)) {
|
||||||
|
return disabledSelectedColor;
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.disabled)) {
|
||||||
|
return disabledColor;
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.selected)) {
|
||||||
|
return selectedColor;
|
||||||
|
}
|
||||||
|
return backgroundColor;
|
||||||
|
}),
|
||||||
|
label: const Text('RawChip'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test enabled chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: false));
|
||||||
|
|
||||||
|
// Enabled chip should have the provided backgroundColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: backgroundColor));
|
||||||
|
|
||||||
|
// Test disabled chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: false));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled chip should have the provided disabledColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: disabledColor));
|
||||||
|
|
||||||
|
// Test enabled & selected chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: true));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Enabled & selected chip should have the provided selectedColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: selectedColor));
|
||||||
|
|
||||||
|
// Test disabled & selected chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: true));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled & selected chip should have the provided disabledSelectedColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: disabledSelectedColor));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('RawChip uses provided state color properties', (WidgetTester tester) async {
|
||||||
|
const Color disabledColor = Color(0xff00ff00);
|
||||||
|
const Color backgroundColor = Color(0xff0000ff);
|
||||||
|
const Color selectedColor = Color(0xffff0000);
|
||||||
|
Widget buildApp({ required bool enabled, required bool selected }) {
|
||||||
|
return wrapForChip(
|
||||||
|
useMaterial3: true,
|
||||||
|
child: RawChip(
|
||||||
|
isEnabled: enabled,
|
||||||
|
selected: selected,
|
||||||
|
disabledColor: disabledColor,
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
selectedColor: selectedColor,
|
||||||
|
label: const Text('RawChip'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test enabled chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: false));
|
||||||
|
|
||||||
|
// Enabled chip should have the provided backgroundColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: backgroundColor));
|
||||||
|
|
||||||
|
// Test disabled chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: false));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled chip should have the provided disabledColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: disabledColor));
|
||||||
|
|
||||||
|
// Test enabled & selected chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: true));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Enabled & selected chip should have the provided selectedColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: selectedColor));
|
||||||
|
});
|
||||||
|
|
||||||
|
group('Material 2', () {
|
||||||
|
// These tests are only relevant for Material 2. Once Material 2
|
||||||
|
// support is deprecated and the APIs are removed, these tests
|
||||||
|
// can be deleted.
|
||||||
|
|
||||||
|
testWidgets('M2 Chip defaults', (WidgetTester tester) async {
|
||||||
|
late TextTheme textTheme;
|
||||||
|
|
||||||
|
Widget buildFrame(Brightness brightness) {
|
||||||
|
return MaterialApp(
|
||||||
|
theme: ThemeData(brightness: brightness, useMaterial3: false),
|
||||||
|
home: Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: Builder(
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
textTheme = Theme.of(context).textTheme;
|
||||||
|
return Chip(
|
||||||
|
avatar: const CircleAvatar(child: Text('A')),
|
||||||
|
label: const Text('Chip A'),
|
||||||
|
onDeleted: () { },
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await tester.pumpWidget(buildFrame(Brightness.light));
|
||||||
|
expect(getMaterialBox(tester), paints..rrect()..circle(color: const Color(0xff1976d2)));
|
||||||
|
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);
|
||||||
|
|
||||||
|
TextStyle labelStyle = getLabelStyle(tester, 'Chip A').style;
|
||||||
|
expect(labelStyle.color?.value, 0xde000000);
|
||||||
|
expect(labelStyle.fontFamily, textTheme.bodyLarge?.fontFamily);
|
||||||
|
expect(labelStyle.fontFamilyFallback, textTheme.bodyLarge?.fontFamilyFallback);
|
||||||
|
expect(labelStyle.fontFeatures, textTheme.bodyLarge?.fontFeatures);
|
||||||
|
expect(labelStyle.fontSize, textTheme.bodyLarge?.fontSize);
|
||||||
|
expect(labelStyle.fontStyle, textTheme.bodyLarge?.fontStyle);
|
||||||
|
expect(labelStyle.fontWeight, textTheme.bodyLarge?.fontWeight);
|
||||||
|
expect(labelStyle.height, textTheme.bodyLarge?.height);
|
||||||
|
expect(labelStyle.inherit, textTheme.bodyLarge?.inherit);
|
||||||
|
expect(labelStyle.leadingDistribution, textTheme.bodyLarge?.leadingDistribution);
|
||||||
|
expect(labelStyle.letterSpacing, textTheme.bodyLarge?.letterSpacing);
|
||||||
|
expect(labelStyle.overflow, textTheme.bodyLarge?.overflow);
|
||||||
|
expect(labelStyle.textBaseline, textTheme.bodyLarge?.textBaseline);
|
||||||
|
expect(labelStyle.wordSpacing, textTheme.bodyLarge?.wordSpacing);
|
||||||
|
|
||||||
|
await tester.pumpWidget(buildFrame(Brightness.dark));
|
||||||
|
await tester.pumpAndSettle(); // Theme transition animation
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(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);
|
||||||
|
|
||||||
|
labelStyle = getLabelStyle(tester, 'Chip A').style;
|
||||||
|
expect(labelStyle.color?.value, 0xdeffffff);
|
||||||
|
expect(labelStyle.fontFamily, textTheme.bodyLarge?.fontFamily);
|
||||||
|
expect(labelStyle.fontFamilyFallback, textTheme.bodyLarge?.fontFamilyFallback);
|
||||||
|
expect(labelStyle.fontFeatures, textTheme.bodyLarge?.fontFeatures);
|
||||||
|
expect(labelStyle.fontSize, textTheme.bodyLarge?.fontSize);
|
||||||
|
expect(labelStyle.fontStyle, textTheme.bodyLarge?.fontStyle);
|
||||||
|
expect(labelStyle.fontWeight, textTheme.bodyLarge?.fontWeight);
|
||||||
|
expect(labelStyle.height, textTheme.bodyLarge?.height);
|
||||||
|
expect(labelStyle.inherit, textTheme.bodyLarge?.inherit);
|
||||||
|
expect(labelStyle.leadingDistribution, textTheme.bodyLarge?.leadingDistribution);
|
||||||
|
expect(labelStyle.letterSpacing, textTheme.bodyLarge?.letterSpacing);
|
||||||
|
expect(labelStyle.overflow, textTheme.bodyLarge?.overflow);
|
||||||
|
expect(labelStyle.textBaseline, textTheme.bodyLarge?.textBaseline);
|
||||||
|
expect(labelStyle.wordSpacing, textTheme.bodyLarge?.wordSpacing);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Chip uses the right theme colors for the right components', (WidgetTester tester) async {
|
||||||
|
final ThemeData themeData = ThemeData(
|
||||||
|
platform: TargetPlatform.android,
|
||||||
|
primarySwatch: Colors.blue,
|
||||||
|
useMaterial3: false,
|
||||||
|
);
|
||||||
|
final ChipThemeData defaultChipTheme = ChipThemeData.fromDefaults(
|
||||||
|
brightness: themeData.brightness,
|
||||||
|
secondaryColor: Colors.blue,
|
||||||
|
labelStyle: themeData.textTheme.bodyLarge!,
|
||||||
|
);
|
||||||
|
bool value = false;
|
||||||
|
Widget buildApp({
|
||||||
|
ChipThemeData? chipTheme,
|
||||||
|
Widget? avatar,
|
||||||
|
Widget? deleteIcon,
|
||||||
|
bool isSelectable = true,
|
||||||
|
bool isPressable = false,
|
||||||
|
bool isDeletable = true,
|
||||||
|
bool showCheckmark = true,
|
||||||
|
}) {
|
||||||
|
chipTheme ??= defaultChipTheme;
|
||||||
|
return wrapForChip(
|
||||||
|
child: Theme(
|
||||||
|
data: themeData,
|
||||||
|
child: ChipTheme(
|
||||||
|
data: chipTheme,
|
||||||
|
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
|
||||||
|
return RawChip(
|
||||||
|
showCheckmark: showCheckmark,
|
||||||
|
onDeleted: isDeletable ? () { } : null,
|
||||||
|
avatar: avatar,
|
||||||
|
deleteIcon: deleteIcon,
|
||||||
|
isEnabled: isSelectable || isPressable,
|
||||||
|
shape: chipTheme?.shape,
|
||||||
|
selected: isSelectable && value,
|
||||||
|
label: Text('$value'),
|
||||||
|
onSelected: isSelectable
|
||||||
|
? (bool newValue) {
|
||||||
|
setState(() {
|
||||||
|
value = newValue;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
onPressed: isPressable
|
||||||
|
? () {
|
||||||
|
setState(() {
|
||||||
|
value = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await tester.pumpWidget(buildApp());
|
||||||
|
|
||||||
|
RenderBox materialBox = getMaterialBox(tester);
|
||||||
|
IconThemeData iconData = getIconData(tester);
|
||||||
|
DefaultTextStyle labelStyle = getLabelStyle(tester, 'false');
|
||||||
|
|
||||||
|
// Check default theme for enabled chip.
|
||||||
|
expect(materialBox, paints..rrect(color: defaultChipTheme.backgroundColor));
|
||||||
|
expect(iconData.color, equals(const Color(0xde000000)));
|
||||||
|
expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
|
||||||
|
|
||||||
|
// Check default theme for disabled chip.
|
||||||
|
await tester.pumpWidget(buildApp(isSelectable: false));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
materialBox = getMaterialBox(tester);
|
||||||
|
labelStyle = getLabelStyle(tester, 'false');
|
||||||
|
expect(materialBox, paints..rrect(color: defaultChipTheme.disabledColor));
|
||||||
|
expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
|
||||||
|
|
||||||
|
// Check default theme for enabled and selected chip.
|
||||||
|
await tester.pumpWidget(buildApp());
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await tester.tap(find.byType(RawChip));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
materialBox = getMaterialBox(tester);
|
||||||
|
expect(materialBox, paints..rrect(color: defaultChipTheme.selectedColor));
|
||||||
|
|
||||||
|
// Check default theme for disabled and selected chip.
|
||||||
|
await tester.pumpWidget(buildApp(isSelectable: false));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
materialBox = getMaterialBox(tester);
|
||||||
|
labelStyle = getLabelStyle(tester, 'true');
|
||||||
|
expect(materialBox, paints..rrect(color: defaultChipTheme.disabledColor));
|
||||||
|
expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
|
||||||
|
|
||||||
|
// Enable the chip again.
|
||||||
|
await tester.pumpWidget(buildApp());
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
// Tap to unselect the chip.
|
||||||
|
await tester.tap(find.byType(RawChip));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Apply a custom theme.
|
||||||
|
const Color customColor1 = Color(0xcafefeed);
|
||||||
|
const Color customColor2 = Color(0xdeadbeef);
|
||||||
|
const Color customColor3 = Color(0xbeefcafe);
|
||||||
|
const Color customColor4 = Color(0xaddedabe);
|
||||||
|
final ChipThemeData customTheme = defaultChipTheme.copyWith(
|
||||||
|
brightness: Brightness.dark,
|
||||||
|
backgroundColor: customColor1,
|
||||||
|
disabledColor: customColor2,
|
||||||
|
selectedColor: customColor3,
|
||||||
|
deleteIconColor: customColor4,
|
||||||
|
);
|
||||||
|
await tester.pumpWidget(buildApp(chipTheme: customTheme));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
materialBox = getMaterialBox(tester);
|
||||||
|
iconData = getIconData(tester);
|
||||||
|
labelStyle = getLabelStyle(tester, 'false');
|
||||||
|
|
||||||
|
// Check custom theme for enabled chip.
|
||||||
|
expect(materialBox, paints..rrect(color: customTheme.backgroundColor));
|
||||||
|
expect(iconData.color, equals(customTheme.deleteIconColor));
|
||||||
|
expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
|
||||||
|
|
||||||
|
// Check custom theme with disabled widget.
|
||||||
|
await tester.pumpWidget(buildApp(
|
||||||
|
chipTheme: customTheme,
|
||||||
|
isSelectable: false,
|
||||||
|
));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
materialBox = getMaterialBox(tester);
|
||||||
|
labelStyle = getLabelStyle(tester, 'false');
|
||||||
|
expect(materialBox, paints..rrect(color: customTheme.disabledColor));
|
||||||
|
expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
|
||||||
|
|
||||||
|
// Check custom theme for enabled and selected chip.
|
||||||
|
await tester.pumpWidget(buildApp(chipTheme: customTheme));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await tester.tap(find.byType(RawChip));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
materialBox = getMaterialBox(tester);
|
||||||
|
expect(materialBox, paints..rrect(color: customTheme.selectedColor));
|
||||||
|
|
||||||
|
// Check custom theme for disabled and selected chip.
|
||||||
|
await tester.pumpWidget(buildApp(
|
||||||
|
chipTheme: customTheme,
|
||||||
|
isSelectable: false,
|
||||||
|
));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
materialBox = getMaterialBox(tester);
|
||||||
|
labelStyle = getLabelStyle(tester, 'true');
|
||||||
|
expect(materialBox, paints..rrect(color: customTheme.disabledColor));
|
||||||
|
expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MaterialStateOutlinedBorder extends StadiumBorder implements MaterialStateOutlinedBorder {
|
class _MaterialStateOutlinedBorder extends StadiumBorder implements MaterialStateOutlinedBorder {
|
||||||
|
@ -50,6 +50,7 @@ void main() {
|
|||||||
|
|
||||||
test('ChipThemeData defaults', () {
|
test('ChipThemeData defaults', () {
|
||||||
const ChipThemeData themeData = ChipThemeData();
|
const ChipThemeData themeData = ChipThemeData();
|
||||||
|
expect(themeData.color, null);
|
||||||
expect(themeData.backgroundColor, null);
|
expect(themeData.backgroundColor, null);
|
||||||
expect(themeData.deleteIconColor, null);
|
expect(themeData.deleteIconColor, null);
|
||||||
expect(themeData.disabledColor, null);
|
expect(themeData.disabledColor, null);
|
||||||
@ -86,16 +87,17 @@ void main() {
|
|||||||
testWidgets('ChipThemeData implements debugFillProperties', (WidgetTester tester) async {
|
testWidgets('ChipThemeData implements debugFillProperties', (WidgetTester tester) async {
|
||||||
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
||||||
const ChipThemeData(
|
const ChipThemeData(
|
||||||
backgroundColor: Color(0xfffffff0),
|
color: MaterialStatePropertyAll<Color>(Color(0xfffffff0)),
|
||||||
deleteIconColor: Color(0xfffffff1),
|
backgroundColor: Color(0xfffffff1),
|
||||||
disabledColor: Color(0xfffffff2),
|
deleteIconColor: Color(0xfffffff2),
|
||||||
selectedColor: Color(0xfffffff3),
|
disabledColor: Color(0xfffffff3),
|
||||||
secondarySelectedColor: Color(0xfffffff4),
|
selectedColor: Color(0xfffffff4),
|
||||||
shadowColor: Color(0xfffffff5),
|
secondarySelectedColor: Color(0xfffffff5),
|
||||||
surfaceTintColor: Color(0xfffffff8),
|
shadowColor: Color(0xfffffff6),
|
||||||
selectedShadowColor: Color(0xfffffff6),
|
surfaceTintColor: Color(0xfffffff7),
|
||||||
|
selectedShadowColor: Color(0xfffffff8),
|
||||||
showCheckmark: true,
|
showCheckmark: true,
|
||||||
checkmarkColor: Color(0xfffffff7),
|
checkmarkColor: Color(0xfffffff9),
|
||||||
labelPadding: EdgeInsets.all(1),
|
labelPadding: EdgeInsets.all(1),
|
||||||
padding: EdgeInsets.all(2),
|
padding: EdgeInsets.all(2),
|
||||||
side: BorderSide(width: 10),
|
side: BorderSide(width: 10),
|
||||||
@ -113,16 +115,17 @@ void main() {
|
|||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
expect(description, <String>[
|
expect(description, <String>[
|
||||||
'backgroundColor: Color(0xfffffff0)',
|
'color: MaterialStatePropertyAll(Color(0xfffffff0))',
|
||||||
'deleteIconColor: Color(0xfffffff1)',
|
'backgroundColor: Color(0xfffffff1)',
|
||||||
'disabledColor: Color(0xfffffff2)',
|
'deleteIconColor: Color(0xfffffff2)',
|
||||||
'selectedColor: Color(0xfffffff3)',
|
'disabledColor: Color(0xfffffff3)',
|
||||||
'secondarySelectedColor: Color(0xfffffff4)',
|
'selectedColor: Color(0xfffffff4)',
|
||||||
'shadowColor: Color(0xfffffff5)',
|
'secondarySelectedColor: Color(0xfffffff5)',
|
||||||
'surfaceTintColor: Color(0xfffffff8)',
|
'shadowColor: Color(0xfffffff6)',
|
||||||
'selectedShadowColor: Color(0xfffffff6)',
|
'surfaceTintColor: Color(0xfffffff7)',
|
||||||
|
'selectedShadowColor: Color(0xfffffff8)',
|
||||||
'showCheckmark: true',
|
'showCheckmark: true',
|
||||||
'checkMarkColor: Color(0xfffffff7)',
|
'checkMarkColor: Color(0xfffffff9)',
|
||||||
'labelPadding: EdgeInsets.all(1.0)',
|
'labelPadding: EdgeInsets.all(1.0)',
|
||||||
'padding: EdgeInsets.all(2.0)',
|
'padding: EdgeInsets.all(2.0)',
|
||||||
'side: BorderSide(width: 10.0)',
|
'side: BorderSide(width: 10.0)',
|
||||||
@ -330,7 +333,6 @@ void main() {
|
|||||||
expect(chipTheme.pressElevation, 8.0);
|
expect(chipTheme.pressElevation, 8.0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
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);
|
||||||
@ -760,6 +762,111 @@ void main() {
|
|||||||
await tester.pumpWidget(chipWidget(selected: true));
|
await tester.pumpWidget(chipWidget(selected: true));
|
||||||
expect(getMaterial(tester).shape, isA<RoundedRectangleBorder>());
|
expect(getMaterial(tester).shape, isA<RoundedRectangleBorder>());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('RawChip uses material state color from ChipTheme', (WidgetTester tester) async {
|
||||||
|
const Color disabledSelectedColor = Color(0xffffff00);
|
||||||
|
const Color disabledColor = Color(0xff00ff00);
|
||||||
|
const Color backgroundColor = Color(0xff0000ff);
|
||||||
|
const Color selectedColor = Color(0xffff0000);
|
||||||
|
Widget buildApp({ required bool enabled, required bool selected }) {
|
||||||
|
return MaterialApp(
|
||||||
|
theme: ThemeData(
|
||||||
|
chipTheme: ChipThemeData(
|
||||||
|
color: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||||
|
if (states.contains(MaterialState.disabled)
|
||||||
|
&& states.contains(MaterialState.selected)) {
|
||||||
|
return disabledSelectedColor;
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.disabled)) {
|
||||||
|
return disabledColor;
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.selected)) {
|
||||||
|
return selectedColor;
|
||||||
|
}
|
||||||
|
return backgroundColor;
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
useMaterial3: true,
|
||||||
|
),
|
||||||
|
home: Material(
|
||||||
|
child: RawChip(
|
||||||
|
isEnabled: enabled,
|
||||||
|
selected: selected,
|
||||||
|
label: const Text('RawChip'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check theme color for enabled chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: false));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Enabled chip should have the provided backgroundColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: backgroundColor));
|
||||||
|
|
||||||
|
// Check theme color for disabled chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: false));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled chip should have the provided disabledColor.
|
||||||
|
expect(getMaterialBox(tester),paints..rrect(color: disabledColor));
|
||||||
|
|
||||||
|
// Check theme color for enabled and selected chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: true));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Enabled & selected chip should have the provided selectedColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: selectedColor));
|
||||||
|
|
||||||
|
// Check theme color for disabled & selected chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: true));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled & selected chip should have the provided disabledSelectedColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: disabledSelectedColor));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('RawChip uses state colors from ChipTheme', (WidgetTester tester) async {
|
||||||
|
const ChipThemeData chipTheme = ChipThemeData(
|
||||||
|
disabledColor: Color(0xadfefafe),
|
||||||
|
backgroundColor: Color(0xcafefeed),
|
||||||
|
selectedColor: Color(0xbeefcafe),
|
||||||
|
);
|
||||||
|
Widget buildApp({ required bool enabled, required bool selected }) {
|
||||||
|
return MaterialApp(
|
||||||
|
theme: ThemeData(chipTheme: chipTheme, useMaterial3: true),
|
||||||
|
home: Material(
|
||||||
|
child: RawChip(
|
||||||
|
isEnabled: enabled,
|
||||||
|
selected: selected,
|
||||||
|
label: const Text('RawChip'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check theme color for enabled chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: false));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Enabled chip should have the provided backgroundColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: chipTheme.backgroundColor));
|
||||||
|
|
||||||
|
// Check theme color for disabled chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: false));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled chip should have the provided disabledColor.
|
||||||
|
expect(getMaterialBox(tester),paints..rrect(color: chipTheme.disabledColor));
|
||||||
|
|
||||||
|
// Check theme color for enabled and selected chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: true));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Enabled & selected chip should have the provided selectedColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: chipTheme.selectedColor));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MaterialStateOutlinedBorder extends StadiumBorder implements MaterialStateOutlinedBorder {
|
class _MaterialStateOutlinedBorder extends StadiumBorder implements MaterialStateOutlinedBorder {
|
||||||
|
@ -7,10 +7,10 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
|
|
||||||
import '../rendering/mock_canvas.dart';
|
import '../rendering/mock_canvas.dart';
|
||||||
|
|
||||||
RenderBox getMaterialBox(WidgetTester tester) {
|
RenderBox getMaterialBox(WidgetTester tester, Finder type) {
|
||||||
return tester.firstRenderObject<RenderBox>(
|
return tester.firstRenderObject<RenderBox>(
|
||||||
find.descendant(
|
find.descendant(
|
||||||
of: find.byType(RawChip),
|
of: type,
|
||||||
matching: find.byType(CustomPaint),
|
matching: find.byType(CustomPaint),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -19,7 +19,7 @@ RenderBox getMaterialBox(WidgetTester tester) {
|
|||||||
Material getMaterial(WidgetTester tester) {
|
Material getMaterial(WidgetTester tester) {
|
||||||
return tester.widget<Material>(
|
return tester.widget<Material>(
|
||||||
find.descendant(
|
find.descendant(
|
||||||
of: find.byType(RawChip),
|
of: find.byType(ChoiceChip),
|
||||||
matching: find.byType(Material),
|
matching: find.byType(Material),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -40,9 +40,10 @@ Widget wrapForChip({
|
|||||||
TextDirection textDirection = TextDirection.ltr,
|
TextDirection textDirection = TextDirection.ltr,
|
||||||
double textScaleFactor = 1.0,
|
double textScaleFactor = 1.0,
|
||||||
Brightness brightness = Brightness.light,
|
Brightness brightness = Brightness.light,
|
||||||
|
bool? useMaterial3,
|
||||||
}) {
|
}) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
theme: ThemeData(brightness: brightness),
|
theme: ThemeData(brightness: brightness, useMaterial3: useMaterial3),
|
||||||
home: Directionality(
|
home: Directionality(
|
||||||
textDirection: textDirection,
|
textDirection: textDirection,
|
||||||
child: MediaQuery(
|
child: MediaQuery(
|
||||||
@ -327,6 +328,180 @@ void main() {
|
|||||||
expect(decoration.color, theme.colorScheme.onSurface.withOpacity(0.12));
|
expect(decoration.color, theme.colorScheme.onSurface.withOpacity(0.12));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('ChoiceChip.color resolves material states', (WidgetTester tester) async {
|
||||||
|
const Color disabledSelectedColor = Color(0xffffff00);
|
||||||
|
const Color disabledColor = Color(0xff00ff00);
|
||||||
|
const Color backgroundColor = Color(0xff0000ff);
|
||||||
|
const Color selectedColor = Color(0xffff0000);
|
||||||
|
final MaterialStateProperty<Color?> color = MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||||
|
if (states.contains(MaterialState.disabled) && states.contains(MaterialState.selected)) {
|
||||||
|
return disabledSelectedColor;
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.disabled)) {
|
||||||
|
return disabledColor;
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.selected)) {
|
||||||
|
return selectedColor;
|
||||||
|
}
|
||||||
|
return backgroundColor;
|
||||||
|
});
|
||||||
|
Widget buildApp({ required bool enabled, required bool selected }) {
|
||||||
|
return wrapForChip(
|
||||||
|
useMaterial3: true,
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
ChoiceChip(
|
||||||
|
onSelected: enabled ? (bool value) { } : null,
|
||||||
|
selected: selected,
|
||||||
|
color: color,
|
||||||
|
label: const Text('ChoiceChip'),
|
||||||
|
),
|
||||||
|
ChoiceChip.elevated(
|
||||||
|
onSelected: enabled ? (bool value) { } : null,
|
||||||
|
selected: selected,
|
||||||
|
color: color,
|
||||||
|
label: const Text('ChoiceChip.elevated'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test enabled state.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: false));
|
||||||
|
|
||||||
|
// Enabled ChoiceChip should have the provided backgroundColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: backgroundColor),
|
||||||
|
);
|
||||||
|
// Enabled elevated ChoiceChip should have the provided backgroundColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: backgroundColor),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test disabled state.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: false));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled ChoiceChip should have the provided disabledColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: disabledColor),
|
||||||
|
);
|
||||||
|
// Disabled elevated ChoiceChip should have the provided disabledColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: disabledColor),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test enabled & selected state.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: true));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Enabled & selected ChoiceChip should have the provided selectedColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: selectedColor),
|
||||||
|
);
|
||||||
|
// Enabled & selected elevated ChoiceChip should have the provided selectedColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: selectedColor),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test disabled & selected state.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: true));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled & selected ChoiceChip should have the provided disabledSelectedColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: disabledSelectedColor),
|
||||||
|
);
|
||||||
|
// Disabled & selected elevated ChoiceChip should have the provided disabledSelectedColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: disabledSelectedColor),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('ChoiceChip uses provided state color properties', (WidgetTester tester) async {
|
||||||
|
const Color disabledColor = Color(0xff00ff00);
|
||||||
|
const Color backgroundColor = Color(0xff0000ff);
|
||||||
|
const Color selectedColor = Color(0xffff0000);
|
||||||
|
Widget buildApp({ required bool enabled, required bool selected }) {
|
||||||
|
return wrapForChip(
|
||||||
|
useMaterial3: true,
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
ChoiceChip(
|
||||||
|
onSelected: enabled ? (bool value) { } : null,
|
||||||
|
selected: selected,
|
||||||
|
disabledColor: disabledColor,
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
selectedColor: selectedColor,
|
||||||
|
label: const Text('ChoiceChip'),
|
||||||
|
),
|
||||||
|
ChoiceChip.elevated(
|
||||||
|
onSelected: enabled ? (bool value) { } : null,
|
||||||
|
selected: selected,
|
||||||
|
disabledColor: disabledColor,
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
selectedColor: selectedColor,
|
||||||
|
label: const Text('ChoiceChip.elevated'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test enabled chips.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: false));
|
||||||
|
|
||||||
|
// Enabled ChoiceChip should have the provided backgroundColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: backgroundColor),
|
||||||
|
);
|
||||||
|
// Enabled elevated ChoiceChip should have the provided backgroundColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: backgroundColor),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test disabled chips.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: false));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled ChoiceChip should have the provided disabledColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: disabledColor),
|
||||||
|
);
|
||||||
|
// Disabled elevated ChoiceChip should have the provided disabledColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: disabledColor),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test enabled & selected chips.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: true));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Enabled & selected ChoiceChip should have the provided selectedColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: selectedColor),
|
||||||
|
);
|
||||||
|
// Enabled & selected elevated ChoiceChip should have the provided selectedColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: selectedColor),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('ChoiceChip can be tapped', (WidgetTester tester) async {
|
testWidgets('ChoiceChip can be tapped', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
const MaterialApp(
|
const MaterialApp(
|
||||||
@ -416,7 +591,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await tester.pumpWidget(buildFrame(Brightness.light));
|
await tester.pumpWidget(buildFrame(Brightness.light));
|
||||||
expect(getMaterialBox(tester), paints..rrect(color: const Color(0x3d000000)));
|
expect(getMaterialBox(tester, find.byType(RawChip)), paints..rrect(color: const Color(0x3d000000)));
|
||||||
expect(tester.getSize(find.byType(ChoiceChip)), const Size(108.0, 48.0));
|
expect(tester.getSize(find.byType(ChoiceChip)), const Size(108.0, 48.0));
|
||||||
expect(getMaterial(tester).color, null);
|
expect(getMaterial(tester).color, null);
|
||||||
expect(getMaterial(tester).elevation, 0);
|
expect(getMaterial(tester).elevation, 0);
|
||||||
@ -425,7 +600,7 @@ void main() {
|
|||||||
|
|
||||||
await tester.pumpWidget(buildFrame(Brightness.dark));
|
await tester.pumpWidget(buildFrame(Brightness.dark));
|
||||||
await tester.pumpAndSettle(); // Theme transition animation
|
await tester.pumpAndSettle(); // Theme transition animation
|
||||||
expect(getMaterialBox(tester), paints..rrect(color: const Color(0x3dffffff)));
|
expect(getMaterialBox(tester, find.byType(RawChip)), paints..rrect(color: const Color(0x3dffffff)));
|
||||||
expect(tester.getSize(find.byType(ChoiceChip)), const Size(108.0, 48.0));
|
expect(tester.getSize(find.byType(ChoiceChip)), const Size(108.0, 48.0));
|
||||||
expect(getMaterial(tester).color, null);
|
expect(getMaterial(tester).color, null);
|
||||||
expect(getMaterial(tester).elevation, 0);
|
expect(getMaterial(tester).elevation, 0);
|
||||||
|
@ -78,6 +78,15 @@ void expectCheckmarkColor(Finder finder, Color color) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RenderBox getMaterialBox(WidgetTester tester, Finder type) {
|
||||||
|
return tester.firstRenderObject<RenderBox>(
|
||||||
|
find.descendant(
|
||||||
|
of: type,
|
||||||
|
matching: find.byType(CustomPaint),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void checkChipMaterialClipBehavior(WidgetTester tester, Clip clipBehavior) {
|
void checkChipMaterialClipBehavior(WidgetTester tester, Clip clipBehavior) {
|
||||||
final Iterable<Material> materials = tester.widgetList<Material>(find.byType(Material));
|
final Iterable<Material> materials = tester.widgetList<Material>(find.byType(Material));
|
||||||
// There should be two Material widgets, first Material is from the "_wrapForChip" and
|
// There should be two Material widgets, first Material is from the "_wrapForChip" and
|
||||||
@ -370,6 +379,181 @@ void main() {
|
|||||||
expect(decoration.color, theme.colorScheme.onSurface.withOpacity(0.12));
|
expect(decoration.color, theme.colorScheme.onSurface.withOpacity(0.12));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('FilterChip.color resolves material states', (WidgetTester tester) async {
|
||||||
|
const Color disabledSelectedColor = Color(0xffffff00);
|
||||||
|
const Color disabledColor = Color(0xff00ff00);
|
||||||
|
const Color backgroundColor = Color(0xff0000ff);
|
||||||
|
const Color selectedColor = Color(0xffff0000);
|
||||||
|
final MaterialStateProperty<Color?> color = MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||||
|
if (states.contains(MaterialState.disabled) && states.contains(MaterialState.selected)) {
|
||||||
|
return disabledSelectedColor;
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.disabled)) {
|
||||||
|
return disabledColor;
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.selected)) {
|
||||||
|
return selectedColor;
|
||||||
|
}
|
||||||
|
return backgroundColor;
|
||||||
|
});
|
||||||
|
Widget buildApp({ required bool enabled, required bool selected }) {
|
||||||
|
return wrapForChip(
|
||||||
|
useMaterial3: true,
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
FilterChip(
|
||||||
|
onSelected: enabled ? (bool value) { } : null,
|
||||||
|
selected: selected,
|
||||||
|
color: color,
|
||||||
|
label: const Text('FilterChip'),
|
||||||
|
),
|
||||||
|
FilterChip.elevated(
|
||||||
|
onSelected: enabled ? (bool value) { } : null,
|
||||||
|
selected: selected,
|
||||||
|
color: color,
|
||||||
|
label: const Text('FilterChip.elevated'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test enabled state.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: false));
|
||||||
|
|
||||||
|
// Enabled FilterChip should have the provided backgroundColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: backgroundColor),
|
||||||
|
);
|
||||||
|
// Enabled elevated FilterChip should have the provided backgroundColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: backgroundColor),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test disabled state.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: false));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled FilterChip should have the provided disabledColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: disabledColor),
|
||||||
|
);
|
||||||
|
// Disabled elevated FilterChip should have the provided disabledColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: disabledColor),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test enabled & selected state.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: true));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Enabled & selected FilterChip should have the provided selectedColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: selectedColor),
|
||||||
|
);
|
||||||
|
// Enabled & selected elevated FilterChip should have the provided selectedColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: selectedColor),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test disabled & selected state.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: true));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled & selected FilterChip should have the provided disabledSelectedColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: disabledSelectedColor),
|
||||||
|
);
|
||||||
|
// Disabled & selected elevated FilterChip should have the
|
||||||
|
// provided disabledSelectedColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: disabledSelectedColor),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('FilterChip uses provided state color properties', (WidgetTester tester) async {
|
||||||
|
const Color disabledColor = Color(0xff00ff00);
|
||||||
|
const Color backgroundColor = Color(0xff0000ff);
|
||||||
|
const Color selectedColor = Color(0xffff0000);
|
||||||
|
Widget buildApp({ required bool enabled, required bool selected }) {
|
||||||
|
return wrapForChip(
|
||||||
|
useMaterial3: true,
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
FilterChip(
|
||||||
|
onSelected: enabled ? (bool value) { } : null,
|
||||||
|
selected: selected,
|
||||||
|
disabledColor: disabledColor,
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
selectedColor: selectedColor,
|
||||||
|
label: const Text('FilterChip'),
|
||||||
|
),
|
||||||
|
FilterChip.elevated(
|
||||||
|
onSelected: enabled ? (bool value) { } : null,
|
||||||
|
selected: selected,
|
||||||
|
disabledColor: disabledColor,
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
selectedColor: selectedColor,
|
||||||
|
label: const Text('FilterChip.elevated'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test enabled state.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: false));
|
||||||
|
|
||||||
|
// Enabled FilterChip should have the provided backgroundColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: backgroundColor),
|
||||||
|
);
|
||||||
|
// Enabled elevated FilterChip should have the provided backgroundColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: backgroundColor),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test disabled state.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: false));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled FilterChip should have the provided disabledColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: disabledColor),
|
||||||
|
);
|
||||||
|
// Disabled elevated FilterChip should have the provided disabledColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: disabledColor),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test enabled & selected state.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: true));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Enabled & selected FilterChip should have the provided selectedColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).first),
|
||||||
|
paints..rrect(color: selectedColor),
|
||||||
|
);
|
||||||
|
// Enabled & selected elevated FilterChip should have the provided selectedColor.
|
||||||
|
expect(
|
||||||
|
getMaterialBox(tester, find.byType(RawChip).last),
|
||||||
|
paints..rrect(color: selectedColor),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('FilterChip can be tapped', (WidgetTester tester) async {
|
testWidgets('FilterChip can be tapped', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
|
@ -13,7 +13,7 @@ Widget wrapForChip({
|
|||||||
TextDirection textDirection = TextDirection.ltr,
|
TextDirection textDirection = TextDirection.ltr,
|
||||||
double textScaleFactor = 1.0,
|
double textScaleFactor = 1.0,
|
||||||
Brightness brightness = Brightness.light,
|
Brightness brightness = Brightness.light,
|
||||||
bool useMaterial3 = false,
|
bool? useMaterial3,
|
||||||
}) {
|
}) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
theme: ThemeData(brightness: brightness, useMaterial3: useMaterial3),
|
theme: ThemeData(brightness: brightness, useMaterial3: useMaterial3),
|
||||||
@ -101,6 +101,101 @@ void checkChipMaterialClipBehavior(WidgetTester tester, Clip clipBehavior) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
testWidgets('InputChip.color resolves material states', (WidgetTester tester) async {
|
||||||
|
const Color disabledSelectedColor = Color(0xffffff00);
|
||||||
|
const Color disabledColor = Color(0xff00ff00);
|
||||||
|
const Color backgroundColor = Color(0xff0000ff);
|
||||||
|
const Color selectedColor = Color(0xffff0000);
|
||||||
|
Widget buildApp({ required bool enabled, required bool selected }) {
|
||||||
|
return wrapForChip(
|
||||||
|
useMaterial3: true,
|
||||||
|
child: InputChip(
|
||||||
|
onSelected: enabled ? (bool value) { } : null,
|
||||||
|
selected: selected,
|
||||||
|
color: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||||
|
if (states.contains(MaterialState.disabled) && states.contains(MaterialState.selected)) {
|
||||||
|
return disabledSelectedColor;
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.disabled)) {
|
||||||
|
return disabledColor;
|
||||||
|
}
|
||||||
|
if (states.contains(MaterialState.selected)) {
|
||||||
|
return selectedColor;
|
||||||
|
}
|
||||||
|
return backgroundColor;
|
||||||
|
}),
|
||||||
|
label: const Text('InputChip'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test enabled chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: false));
|
||||||
|
|
||||||
|
// Enabled chip should have the provided backgroundColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: backgroundColor));
|
||||||
|
|
||||||
|
// Test disabled chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: false));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled chip should have the provided disabledColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: disabledColor));
|
||||||
|
|
||||||
|
// Test enabled & selected chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: true));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Enabled & selected chip should have the provided selectedColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: selectedColor));
|
||||||
|
|
||||||
|
// Test disabled & selected chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: true));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled & selected chip should have the provided disabledSelectedColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: disabledSelectedColor));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('InputChip uses provided state color properties', (WidgetTester tester) async {
|
||||||
|
const Color disabledColor = Color(0xff00ff00);
|
||||||
|
const Color backgroundColor = Color(0xff0000ff);
|
||||||
|
const Color selectedColor = Color(0xffff0000);
|
||||||
|
Widget buildApp({ required bool enabled, required bool selected }) {
|
||||||
|
return wrapForChip(
|
||||||
|
useMaterial3: true,
|
||||||
|
child: InputChip(
|
||||||
|
onSelected: enabled ? (bool value) { } : null,
|
||||||
|
selected: selected,
|
||||||
|
disabledColor: disabledColor,
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
selectedColor: selectedColor,
|
||||||
|
label: const Text('InputChip'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test enabled chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: false));
|
||||||
|
|
||||||
|
// Enabled chip should have the provided backgroundColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: backgroundColor));
|
||||||
|
|
||||||
|
// Test disabled chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: false, selected: false));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Disabled chip should have the provided disabledColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: disabledColor));
|
||||||
|
|
||||||
|
// Test enabled & selected chip.
|
||||||
|
await tester.pumpWidget(buildApp(enabled: true, selected: true));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
// Enabled & selected chip should have the provided selectedColor.
|
||||||
|
expect(getMaterialBox(tester), paints..rrect(color: selectedColor));
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('InputChip can be tapped', (WidgetTester tester) async {
|
testWidgets('InputChip can be tapped', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
const MaterialApp(
|
const MaterialApp(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user