Provide Material 3 defaults for vanilla Chip
widget. (#111597)
This commit is contained in:
parent
d0a1e9e343
commit
df110ef020
@ -104,6 +104,7 @@ Future<void> main(List<String> args) async {
|
||||
tokens['colorsLight'] = _readTokenFile('color_light.json');
|
||||
tokens['colorsDark'] = _readTokenFile('color_dark.json');
|
||||
|
||||
ActionChipTemplate('Chip', '$materialLib/chip.dart', tokens).updateFile();
|
||||
ActionChipTemplate('ActionChip', '$materialLib/action_chip.dart', tokens).updateFile();
|
||||
AppBarTemplate('AppBar', '$materialLib/app_bar.dart', tokens).updateFile();
|
||||
BannerTemplate('Banner', '$materialLib/banner.dart', tokens).updateFile();
|
||||
|
@ -170,6 +170,13 @@ abstract class TokenTemplate {
|
||||
final Map<String, dynamic> shape = tokens[tokens['$componentToken.shape']!]! as Map<String, dynamic>;
|
||||
switch (shape['family']) {
|
||||
case 'SHAPE_FAMILY_ROUNDED_CORNERS':
|
||||
final double topLeft = shape['topLeft'] as double;
|
||||
final double topRight = shape['topRight'] as double;
|
||||
final double bottomLeft = shape['bottomLeft'] as double;
|
||||
final double bottomRight = shape['bottomRight'] as double;
|
||||
if (topLeft == topRight && topLeft == bottomLeft && topLeft == bottomRight) {
|
||||
return '${prefix}RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular($topLeft)))';
|
||||
}
|
||||
return '${prefix}RoundedRectangleBorder(borderRadius: '
|
||||
'BorderRadius.only('
|
||||
'topLeft: Radius.circular(${shape['topLeft']}), '
|
||||
|
@ -184,7 +184,7 @@ class _ActionChipDefaultsM3 extends ChipThemeData {
|
||||
const _ActionChipDefaultsM3(this.context, this.isEnabled)
|
||||
: super(
|
||||
elevation: 0.0,
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.only(topLeft: Radius.circular(8.0), topRight: Radius.circular(8.0), bottomLeft: Radius.circular(8.0), bottomRight: Radius.circular(8.0))),
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
|
||||
showCheckmark: true,
|
||||
);
|
||||
|
||||
|
@ -223,7 +223,7 @@ class _CardDefaultsM3 extends CardTheme {
|
||||
clipBehavior: Clip.none,
|
||||
elevation: 1.0,
|
||||
margin: const EdgeInsets.all(4.0),
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.only(topLeft: Radius.circular(12.0), topRight: Radius.circular(12.0), bottomLeft: Radius.circular(12.0), bottomRight: Radius.circular(12.0))),
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12.0))),
|
||||
);
|
||||
|
||||
final BuildContext context;
|
||||
|
@ -1164,11 +1164,15 @@ class _RawChipState extends State<RawChip> with MaterialStateMixin, TickerProvid
|
||||
final ThemeData theme = Theme.of(context);
|
||||
final ChipThemeData chipTheme = ChipTheme.of(context);
|
||||
final Brightness brightness = chipTheme.brightness ?? theme.brightness;
|
||||
final ChipThemeData chipDefaults = widget.defaultProperties ?? ChipThemeData.fromDefaults(
|
||||
brightness: brightness,
|
||||
secondaryColor: brightness == Brightness.dark ? Colors.tealAccent[200]! : theme.primaryColor,
|
||||
labelStyle: theme.textTheme.bodyLarge!,
|
||||
);
|
||||
final ChipThemeData chipDefaults = widget.defaultProperties ??
|
||||
(theme.useMaterial3
|
||||
? _ChipDefaultsM3(context, widget.isEnabled)
|
||||
: ChipThemeData.fromDefaults(
|
||||
brightness: brightness,
|
||||
secondaryColor: brightness == Brightness.dark ? Colors.tealAccent[200]! : theme.primaryColor,
|
||||
labelStyle: theme.textTheme.bodyLarge!,
|
||||
)
|
||||
);
|
||||
final TextDirection? textDirection = Directionality.maybeOf(context);
|
||||
final OutlinedBorder resolvedShape = _getShape(theme, chipTheme, chipDefaults);
|
||||
|
||||
@ -2184,3 +2188,77 @@ bool _hitIsOnDeleteIcon({
|
||||
return adjustedPosition.dx <= accessibleDeleteButtonWidth;
|
||||
}
|
||||
}
|
||||
|
||||
// BEGIN GENERATED TOKEN PROPERTIES - Chip
|
||||
|
||||
// Do not edit by hand. The code between the "BEGIN GENERATED" and
|
||||
// "END GENERATED" comments are generated from data in the Material
|
||||
// Design token database by the script:
|
||||
// dev/tools/gen_defaults/bin/gen_defaults.dart.
|
||||
|
||||
// Token database version: v0_127
|
||||
|
||||
class _ChipDefaultsM3 extends ChipThemeData {
|
||||
const _ChipDefaultsM3(this.context, this.isEnabled)
|
||||
: super(
|
||||
elevation: 0.0,
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
|
||||
showCheckmark: true,
|
||||
);
|
||||
|
||||
final BuildContext context;
|
||||
final bool isEnabled;
|
||||
|
||||
@override
|
||||
TextStyle? get labelStyle => Theme.of(context).textTheme.labelLarge;
|
||||
|
||||
@override
|
||||
Color? get backgroundColor => null;
|
||||
|
||||
@override
|
||||
Color? get shadowColor => Colors.transparent;
|
||||
|
||||
@override
|
||||
Color? get surfaceTintColor => Theme.of(context).colorScheme.surfaceTint;
|
||||
|
||||
@override
|
||||
Color? get selectedColor => null;
|
||||
|
||||
@override
|
||||
Color? get checkmarkColor => null;
|
||||
|
||||
@override
|
||||
Color? get disabledColor => null;
|
||||
|
||||
@override
|
||||
Color? get deleteIconColor => null;
|
||||
|
||||
@override
|
||||
BorderSide? get side => isEnabled
|
||||
? BorderSide(color: Theme.of(context).colorScheme.outline)
|
||||
: BorderSide(color: Theme.of(context).colorScheme.onSurface.withOpacity(0.12));
|
||||
|
||||
@override
|
||||
IconThemeData? get iconTheme => IconThemeData(
|
||||
color: isEnabled
|
||||
? Theme.of(context).colorScheme.primary
|
||||
: Theme.of(context).colorScheme.onSurface,
|
||||
size: 18.0,
|
||||
);
|
||||
|
||||
@override
|
||||
EdgeInsetsGeometry? get padding => const EdgeInsets.all(8.0);
|
||||
|
||||
/// The chip at text scale 1 starts with 8px on each side and as text scaling
|
||||
/// gets closer to 2 the label padding is linearly interpolated from 8px to 4px.
|
||||
/// Once the widget has a text scaling of 2 or higher than the label padding
|
||||
/// remains 4px.
|
||||
@override
|
||||
EdgeInsetsGeometry? get labelPadding => EdgeInsets.lerp(
|
||||
const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
const EdgeInsets.symmetric(horizontal: 4.0),
|
||||
clampDouble(MediaQuery.of(context).textScaleFactor - 1.0, 0.0, 1.0),
|
||||
)!;
|
||||
}
|
||||
|
||||
// END GENERATED TOKEN PROPERTIES - Chip
|
||||
|
@ -195,7 +195,7 @@ class _FilterChipDefaultsM3 extends ChipThemeData {
|
||||
const _FilterChipDefaultsM3(this.context, this.isEnabled, this.isSelected)
|
||||
: super(
|
||||
elevation: 0.0,
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.only(topLeft: Radius.circular(8.0), topRight: Radius.circular(8.0), bottomLeft: Radius.circular(8.0), bottomRight: Radius.circular(8.0))),
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
|
||||
showCheckmark: true,
|
||||
);
|
||||
|
||||
|
@ -1396,7 +1396,7 @@ class _DialogDefaultsM3 extends DialogTheme {
|
||||
: super(
|
||||
alignment: Alignment.center,
|
||||
elevation: 6.0,
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.only(topLeft: Radius.circular(28.0), topRight: Radius.circular(28.0), bottomLeft: Radius.circular(28.0), bottomRight: Radius.circular(28.0))),
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(28.0))),
|
||||
);
|
||||
|
||||
final BuildContext context;
|
||||
|
@ -204,7 +204,7 @@ class _FilterChipDefaultsM3 extends ChipThemeData {
|
||||
const _FilterChipDefaultsM3(this.context, this.isEnabled, this.isSelected)
|
||||
: super(
|
||||
elevation: 0.0,
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.only(topLeft: Radius.circular(8.0), topRight: Radius.circular(8.0), bottomLeft: Radius.circular(8.0), bottomRight: Radius.circular(8.0))),
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
|
||||
showCheckmark: true,
|
||||
);
|
||||
|
||||
|
@ -850,13 +850,13 @@ class _FABDefaultsM3 extends FloatingActionButtonThemeData {
|
||||
ShapeBorder? get shape {
|
||||
switch (type) {
|
||||
case _FloatingActionButtonType.regular:
|
||||
return const RoundedRectangleBorder(borderRadius: BorderRadius.only(topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0), bottomLeft: Radius.circular(16.0), bottomRight: Radius.circular(16.0)));
|
||||
return const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0)));
|
||||
case _FloatingActionButtonType.small:
|
||||
return const RoundedRectangleBorder(borderRadius: BorderRadius.only(topLeft: Radius.circular(12.0), topRight: Radius.circular(12.0), bottomLeft: Radius.circular(12.0), bottomRight: Radius.circular(12.0)));
|
||||
return const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12.0)));
|
||||
case _FloatingActionButtonType.large:
|
||||
return const RoundedRectangleBorder(borderRadius: BorderRadius.only(topLeft: Radius.circular(28.0), topRight: Radius.circular(28.0), bottomLeft: Radius.circular(28.0), bottomRight: Radius.circular(28.0)));
|
||||
return const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(28.0)));
|
||||
case _FloatingActionButtonType.extended:
|
||||
return const RoundedRectangleBorder(borderRadius: BorderRadius.only(topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0), bottomLeft: Radius.circular(16.0), bottomRight: Radius.circular(16.0)));
|
||||
return const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,7 @@ class _InputChipDefaultsM3 extends ChipThemeData {
|
||||
const _InputChipDefaultsM3(this.context, this.isEnabled)
|
||||
: super(
|
||||
elevation: 0.0,
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.only(topLeft: Radius.circular(8.0), topRight: Radius.circular(8.0), bottomLeft: Radius.circular(8.0), bottomRight: Radius.circular(8.0))),
|
||||
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
|
||||
showCheckmark: true,
|
||||
);
|
||||
|
||||
|
@ -215,7 +215,7 @@ Finder findTooltipContainer(String tooltipText) {
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('Chip defaults', (WidgetTester tester) async {
|
||||
testWidgets('M2 Chip defaults', (WidgetTester tester) async {
|
||||
late TextTheme textTheme;
|
||||
|
||||
Widget buildFrame(Brightness brightness) {
|
||||
@ -292,6 +292,87 @@ void main() {
|
||||
expect(labelStyle.wordSpacing, textTheme.bodyLarge?.wordSpacing);
|
||||
});
|
||||
|
||||
testWidgets('M3 Chip defaults', (WidgetTester tester) async {
|
||||
late TextTheme textTheme;
|
||||
final ThemeData lightTheme = ThemeData.light(useMaterial3: true);
|
||||
final ThemeData darkTheme = ThemeData.dark(useMaterial3: true);
|
||||
|
||||
Widget buildFrame(ThemeData theme) {
|
||||
return MaterialApp(
|
||||
theme: theme,
|
||||
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(lightTheme));
|
||||
expect(getMaterial(tester).color, null);
|
||||
expect(getMaterial(tester).elevation, 0);
|
||||
expect(getMaterial(tester).shape, RoundedRectangleBorder(
|
||||
side: BorderSide(color: lightTheme.colorScheme.outline),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
));
|
||||
expect(getIconData(tester).color, lightTheme.colorScheme.primary);
|
||||
expect(getIconData(tester).opacity, null);
|
||||
expect(getIconData(tester).size, 18);
|
||||
|
||||
TextStyle labelStyle = getLabelStyle(tester, 'Chip A').style;
|
||||
expect(labelStyle.color, textTheme.labelLarge?.color);
|
||||
expect(labelStyle.fontFamily, textTheme.labelLarge?.fontFamily);
|
||||
expect(labelStyle.fontFamilyFallback, textTheme.labelLarge?.fontFamilyFallback);
|
||||
expect(labelStyle.fontFeatures, textTheme.labelLarge?.fontFeatures);
|
||||
expect(labelStyle.fontSize, textTheme.labelLarge?.fontSize);
|
||||
expect(labelStyle.fontStyle, textTheme.labelLarge?.fontStyle);
|
||||
expect(labelStyle.fontWeight, textTheme.labelLarge?.fontWeight);
|
||||
expect(labelStyle.height, textTheme.labelLarge?.height);
|
||||
expect(labelStyle.inherit, textTheme.labelLarge?.inherit);
|
||||
expect(labelStyle.leadingDistribution, textTheme.labelLarge?.leadingDistribution);
|
||||
expect(labelStyle.letterSpacing, textTheme.labelLarge?.letterSpacing);
|
||||
expect(labelStyle.overflow, textTheme.labelLarge?.overflow);
|
||||
expect(labelStyle.textBaseline, textTheme.labelLarge?.textBaseline);
|
||||
expect(labelStyle.wordSpacing, textTheme.labelLarge?.wordSpacing);
|
||||
|
||||
await tester.pumpWidget(buildFrame(darkTheme));
|
||||
await tester.pumpAndSettle(); // Theme transition animation
|
||||
expect(getMaterial(tester).color, null);
|
||||
expect(getMaterial(tester).elevation, 0);
|
||||
expect(getMaterial(tester).shape, RoundedRectangleBorder(
|
||||
side: BorderSide(color: darkTheme.colorScheme.outline),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
));
|
||||
expect(getIconData(tester).color, darkTheme.colorScheme.primary);
|
||||
expect(getIconData(tester).opacity, null);
|
||||
expect(getIconData(tester).size, 18);
|
||||
|
||||
labelStyle = getLabelStyle(tester, 'Chip A').style;
|
||||
expect(labelStyle.color, textTheme.labelLarge?.color);
|
||||
expect(labelStyle.fontFamily, textTheme.labelLarge?.fontFamily);
|
||||
expect(labelStyle.fontFamilyFallback, textTheme.labelLarge?.fontFamilyFallback);
|
||||
expect(labelStyle.fontFeatures, textTheme.labelLarge?.fontFeatures);
|
||||
expect(labelStyle.fontSize, textTheme.labelLarge?.fontSize);
|
||||
expect(labelStyle.fontStyle, textTheme.labelLarge?.fontStyle);
|
||||
expect(labelStyle.fontWeight, textTheme.labelLarge?.fontWeight);
|
||||
expect(labelStyle.height, textTheme.labelLarge?.height);
|
||||
expect(labelStyle.inherit, textTheme.labelLarge?.inherit);
|
||||
expect(labelStyle.leadingDistribution, textTheme.labelLarge?.leadingDistribution);
|
||||
expect(labelStyle.letterSpacing, textTheme.labelLarge?.letterSpacing);
|
||||
expect(labelStyle.overflow, textTheme.labelLarge?.overflow);
|
||||
expect(labelStyle.textBaseline, textTheme.labelLarge?.textBaseline);
|
||||
expect(labelStyle.wordSpacing, textTheme.labelLarge?.wordSpacing);
|
||||
});
|
||||
|
||||
testWidgets('Chip control test', (WidgetTester tester) async {
|
||||
final FeedbackTester feedback = FeedbackTester();
|
||||
final List<String> deletedChipLabels = <String>[];
|
||||
|
Loading…
x
Reference in New Issue
Block a user