Revert "Adds support for the Material Badge widget, BadgeTheme, BadgeThemeData (#114560)" (#114819)

This reverts commit a6da1042a8.
This commit is contained in:
Hans Muller 2022-11-07 08:50:56 -08:00 committed by GitHub
parent 151c83191a
commit d6a8e92cd6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 0 additions and 796 deletions

View file

@ -19,7 +19,6 @@ import 'dart:io';
import 'package:gen_defaults/action_chip_template.dart';
import 'package:gen_defaults/app_bar_template.dart';
import 'package:gen_defaults/badge_template.dart';
import 'package:gen_defaults/banner_template.dart';
import 'package:gen_defaults/bottom_app_bar_template.dart';
import 'package:gen_defaults/bottom_sheet_template.dart';
@ -55,7 +54,6 @@ Future<void> main(List<String> args) async {
const List<String> tokenFiles = <String>[
'badge.json',
'banner.json',
'badge.json',
'bottom_app_bar.json',
'button_elevated.json',
'button_filled.json',
@ -127,8 +125,6 @@ Future<void> main(List<String> args) async {
ActionChipTemplate('Chip', '$materialLib/chip.dart', tokens).updateFile();
ActionChipTemplate('ActionChip', '$materialLib/action_chip.dart', tokens).updateFile();
AppBarTemplate('AppBar', '$materialLib/app_bar.dart', tokens).updateFile();
BottomAppBarTemplate('BottomAppBar', '$materialLib/bottom_app_bar.dart', tokens).updateFile();
BadgeTemplate('Badge', '$materialLib/badge.dart', tokens).updateFile();
BannerTemplate('Banner', '$materialLib/banner.dart', tokens).updateFile();
BottomAppBarTemplate('BottomAppBar', '$materialLib/bottom_app_bar.dart', tokens).updateFile();
BottomSheetTemplate('BottomSheet', '$materialLib/bottom_sheet.dart', tokens).updateFile();

View file

@ -1,36 +0,0 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'template.dart';
class BadgeTemplate extends TokenTemplate {
const BadgeTemplate(super.blockName, super.fileName, super.tokens, {
super.colorSchemePrefix = '_colors.',
});
@override
String generate() => '''
class _${blockName}DefaultsM3 extends BadgeThemeData {
_${blockName}DefaultsM3(this.context) : super(
smallSize: ${tokens["md.comp.badge.size"]},
largeSize: ${tokens["md.comp.badge.large.size"]},
padding: const EdgeInsets.symmetric(horizontal: 4),
alignment: const AlignmentDirectional(12, -4),
);
final BuildContext context;
late final ThemeData _theme = Theme.of(context);
late final ColorScheme _colors = _theme.colorScheme;
@override
Color? get backgroundColor => ${color("md.comp.badge.color")};
@override
Color? get foregroundColor => ${color("md.comp.badge.large.label-text.color")};
@override
TextStyle? get textStyle => ${textStyle("md.comp.badge.large.label-text")};
}
''';
}

View file

@ -30,8 +30,6 @@ export 'src/material/app_bar_theme.dart';
export 'src/material/arc.dart';
export 'src/material/autocomplete.dart';
export 'src/material/back_button.dart';
export 'src/material/badge.dart';
export 'src/material/badge_theme.dart';
export 'src/material/banner.dart';
export 'src/material/banner_theme.dart';
export 'src/material/bottom_app_bar.dart';

View file

@ -1,190 +0,0 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/widgets.dart';
import 'badge_theme.dart';
import 'color_scheme.dart';
import 'theme.dart';
/// A Material Design "badge".
///
/// A badge's [label] conveys a small amount of information about its
/// [child], like a count or status. If the label is null then this is
/// a "small" badge that's displayed as a [smallSize] diameter filled
/// circle. Otherwise this is a [StadiumBorder] shaped "large" badge
/// with height [largeSize].
///
/// Badges are typically used to decorate the icon within a
/// BottomNavigationBarItem] or a [NavigationRailDestination]
/// or a button's icon, as in [TextButton.icon]. The badges default
/// configuration is intended to work well with a default sized (24)
/// [Icon].
class Badge extends StatelessWidget {
/// Create a Badge that stacks [label] on top of [child].
///
/// If [label] is null then just a filled circle is displayed. Otherwise
/// the [label] is displayed within a [StadiumBorder] shaped area.
const Badge({
super.key,
this.backgroundColor,
this.foregroundColor,
this.smallSize,
this.largeSize,
this.textStyle,
this.padding,
this.alignment,
this.label,
this.child,
});
/// The badge's fill color.
///
/// Defaults to the [BadgeTheme]'s background color, or
/// [ColorScheme.errorColor] if the theme value is null.
final Color? backgroundColor;
/// The color of the badge's [label] text.
///
/// This color overrides the color of the label's [textStyle].
///
/// Defaults to the [BadgeTheme]'s foreground color, or
/// [ColorScheme.onError] if the theme value is null.
final Color? foregroundColor;
/// The diameter of the badge if [label] is null.
///
/// Defaults to the [BadgeTheme]'s small size, or 6 if the theme value
/// is null.
final double? smallSize;
/// The badge's height if [label] is non-null.
///
/// Defaults to the [BadgeTheme]'s large size, or 16 if the theme value
/// is null. If the default value is overridden then it may be useful to
/// also override [padding] and [alignment].
final double? largeSize;
/// The [DefaultTextStyle] for the badge's label.
///
/// The text style's color is overwritten by the [foregroundColor].
///
/// This value is only used if [label] is non-null.
///
/// Defaults to the [BadgeTheme]'s text style, or the overall theme's
/// [TextTheme.labelSmall] if the badge theme's value is null. If
/// the default text style is overridden then it may be useful to
/// also override [largeSize], [padding], and [alignment].
final TextStyle? textStyle;
/// The padding added to the badge's label.
///
/// This value is only used if [label] is non-null.
///
/// Defaults to the [BadgeTheme]'s padding, or 4 pixels on the
/// left and right if the theme's value is null.
final EdgeInsetsGeometry? padding;
/// The location of the [label] relative to the [child].
///
/// This value is only used if [label] is non-null.
///
/// Defaults to the [BadgeTheme]'s alignment, or `start = 12`
/// and `top = -4` if the theme's value is null.
final AlignmentDirectional? alignment;
/// The badge's content, typically a [Text] widget that contains 1 to 4
/// characters.
///
/// If the label is null then this is a "small" badge that's
/// displayed as a [smallSize] diameter filled circle. Otherwise
/// this is a [StadiumBorder] shaped "large" badge with height [largeSize].
final Widget? label;
/// The widget that the badge is stacked on top of.
///
/// Typically this is an default sized [Icon] that's part of a
/// [BottomNavigationBarItem] or a [NavigationRailDestination].
final Widget? child;
@override
Widget build(BuildContext context) {
final BadgeThemeData badgeTheme = BadgeTheme.of(context);
final BadgeThemeData defaults = _BadgeDefaultsM3(context);
final double effectiveSmallSize = smallSize ?? badgeTheme.smallSize ?? defaults.smallSize!;
final double effectiveLargeSize = largeSize ?? badgeTheme.largeSize ?? defaults.largeSize!;
final Widget badge = DefaultTextStyle(
style: (textStyle ?? badgeTheme.textStyle ?? defaults.textStyle!).copyWith(
color: foregroundColor ?? badgeTheme.foregroundColor ?? defaults.foregroundColor!,
),
child: IntrinsicWidth(
child: Container(
height: label == null ? effectiveSmallSize : effectiveLargeSize,
clipBehavior: Clip.antiAlias,
decoration: ShapeDecoration(
color: backgroundColor ?? badgeTheme.backgroundColor ?? defaults.backgroundColor!,
shape: const StadiumBorder(),
),
padding: label == null ? null : (padding ?? badgeTheme.padding ?? defaults.padding!),
alignment: label == null ? null : Alignment.center,
child: label ?? SizedBox(width: effectiveSmallSize, height: effectiveSmallSize),
),
),
);
if (child == null) {
return badge;
}
final AlignmentDirectional effectiveAlignment = alignment ?? badgeTheme.alignment ?? defaults.alignment!;
return
Stack(
clipBehavior: Clip.none,
children: <Widget>[
child!,
Positioned.directional(
textDirection: Directionality.of(context),
start: label == null ? null : effectiveAlignment.start,
end: label == null ? 0 : null,
top: label == null ? 0 : effectiveAlignment.y,
child: badge,
),
],
);
}
}
// BEGIN GENERATED TOKEN PROPERTIES - Badge
// 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_137
class _BadgeDefaultsM3 extends BadgeThemeData {
_BadgeDefaultsM3(this.context) : super(
smallSize: 6.0,
largeSize: 16.0,
padding: const EdgeInsets.symmetric(horizontal: 4),
alignment: const AlignmentDirectional(12, -4),
);
final BuildContext context;
late final ThemeData _theme = Theme.of(context);
late final ColorScheme _colors = _theme.colorScheme;
@override
Color? get backgroundColor => _colors.error;
@override
Color? get foregroundColor => _colors.onError;
@override
TextStyle? get textStyle => Theme.of(context).textTheme.labelSmall;
}
// END GENERATED TOKEN PROPERTIES - Badge

View file

@ -1,183 +0,0 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show lerpDouble;
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'theme.dart';
// Examples can assume:
// late BuildContext context;
/// Overrides the default properties values for descendant [Badge] widgets.
///
/// Descendant widgets obtain the current [BadgeThemeData] object
/// using `BadgeTheme.of(context)`. Instances of [BadgeThemeData] can
/// be customized with [BadgeThemeData.copyWith].
///
/// Typically a [BadgeThemeData] is specified as part of the
/// overall [Theme] with [ThemeData.badgeTheme].
///
/// All [BadgeThemeData] properties are `null` by default.
/// When null, the [Badge] will use the values from [ThemeData]
/// if they exist, otherwise it will provide its own defaults.
///
/// See also:
///
/// * [ThemeData], which describes the overall theme information for the
/// application.
@immutable
class BadgeThemeData with Diagnosticable {
/// Creates the set of color, style, and size properties used to configure [Badge].
const BadgeThemeData({
this.backgroundColor,
this.foregroundColor,
this.smallSize,
this.largeSize,
this.textStyle,
this.padding,
this.alignment,
});
/// Overrides the default value for [Badge.backgroundColor].
final Color? backgroundColor;
/// Overrides the default value for [Badge.foregroundColor].
final Color? foregroundColor;
/// Overrides the default value for [Badge.smallSize].
final double? smallSize;
/// Overrides the default value for [Badge.largeSize].
final double? largeSize;
/// Overrides the default value for [Badge.textStyle].
final TextStyle? textStyle;
/// Overrides the default value for [Badge.padding].
final EdgeInsetsGeometry? padding;
/// Overrides the default value for [Badge.alignment].
final AlignmentDirectional? alignment;
/// Creates a copy of this object but with the given fields replaced with the
/// new values.
BadgeThemeData copyWith({
Color? backgroundColor,
Color? foregroundColor,
double? smallSize,
double? largeSize,
TextStyle? textStyle,
EdgeInsetsGeometry? padding,
AlignmentDirectional? alignment,
}) {
return BadgeThemeData(
backgroundColor: backgroundColor ?? this.backgroundColor,
foregroundColor: foregroundColor ?? this.foregroundColor,
smallSize: smallSize ?? this.smallSize,
largeSize: largeSize ?? this.largeSize,
textStyle: textStyle ?? this.textStyle,
padding: padding ?? this.padding,
alignment: alignment ?? this.alignment,
);
}
/// Linearly interpolate between two [Badge] themes.
static BadgeThemeData lerp(BadgeThemeData? a, BadgeThemeData? b, double t) {
return BadgeThemeData(
backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t),
foregroundColor: Color.lerp(a?.foregroundColor, b?.foregroundColor, t),
smallSize: lerpDouble(a?.smallSize, b?.smallSize, t),
largeSize: lerpDouble(a?.largeSize, b?.largeSize, t),
textStyle: TextStyle.lerp(a?.textStyle, b?.textStyle, t),
padding: EdgeInsetsGeometry.lerp(a?.padding, b?.padding, t),
alignment: AlignmentDirectional.lerp(a?.alignment, b?.alignment, t),
);
}
@override
int get hashCode => Object.hash(
backgroundColor,
foregroundColor,
smallSize,
largeSize,
textStyle,
padding,
alignment,
);
@override
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}
if (other.runtimeType != runtimeType) {
return false;
}
return other is BadgeThemeData
&& other.backgroundColor == backgroundColor
&& other.foregroundColor == foregroundColor
&& other.smallSize == smallSize
&& other.largeSize == largeSize
&& other.textStyle == textStyle
&& other.padding == padding
&& other.alignment == alignment;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null));
properties.add(ColorProperty('foregroundColor', foregroundColor, defaultValue: null));
properties.add(DoubleProperty('smallSize', smallSize, defaultValue: null));
properties.add(DoubleProperty('largeSize', largeSize, defaultValue: null));
properties.add(DiagnosticsProperty<TextStyle>('textStyle', textStyle, defaultValue: null));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding, defaultValue: null));
properties.add(DiagnosticsProperty<AlignmentDirectional>('alignment', alignment, defaultValue: null));
}
}
/// An inherited widget that overrides the default color style, and size
/// parameters for [Badge]s in this widget's subtree.
///
/// Values specified here override the defaults for [Badge] properties which
/// are not given an explicit non-null value.
class BadgeTheme extends InheritedTheme {
/// Creates a theme that overrides the default color parameters for [Badge]s
/// in this widget's subtree.
const BadgeTheme({
super.key,
required this.data,
required super.child,
}) : assert(data != null);
/// Specifies the default color and size overrides for descendant [Badge] widgets.
final BadgeThemeData data;
/// The closest instance of this class that encloses the given context.
///
/// If there is no enclosing [BadgeTheme] widget, then
/// [ThemeData.badgeTheme] is used.
///
/// Typical usage is as follows:
///
/// ```dart
/// BadgeThemeData theme = BadgeTheme.of(context);
/// ```
static BadgeThemeData of(BuildContext context) {
final BadgeTheme? badgeTheme = context.dependOnInheritedWidgetOfExactType<BadgeTheme>();
return badgeTheme?.data ?? Theme.of(context).badgeTheme;
}
@override
Widget wrap(BuildContext context, Widget child) {
return BadgeTheme(data: data, child: child);
}
@override
bool updateShouldNotify(BadgeTheme oldWidget) => data != oldWidget.data;
}

View file

@ -8,7 +8,6 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'app_bar_theme.dart';
import 'badge_theme.dart';
import 'banner_theme.dart';
import 'bottom_app_bar_theme.dart';
import 'bottom_navigation_bar_theme.dart';
@ -332,7 +331,6 @@ class ThemeData with Diagnosticable {
Typography? typography,
// COMPONENT THEMES
AppBarTheme? appBarTheme,
BadgeThemeData? badgeTheme,
MaterialBannerThemeData? bannerTheme,
BottomAppBarTheme? bottomAppBarTheme,
BottomNavigationBarThemeData? bottomNavigationBarTheme,
@ -585,7 +583,6 @@ class ThemeData with Diagnosticable {
// COMPONENT THEMES
appBarTheme ??= const AppBarTheme();
badgeTheme ??= const BadgeThemeData();
bannerTheme ??= const MaterialBannerThemeData();
bottomAppBarTheme ??= const BottomAppBarTheme();
bottomNavigationBarTheme ??= const BottomNavigationBarThemeData();
@ -679,7 +676,6 @@ class ThemeData with Diagnosticable {
primaryIconTheme: primaryIconTheme,
// COMPONENT THEMES
appBarTheme: appBarTheme,
badgeTheme: badgeTheme,
bannerTheme: bannerTheme,
bottomAppBarTheme: bottomAppBarTheme,
bottomNavigationBarTheme: bottomNavigationBarTheme,
@ -790,7 +786,6 @@ class ThemeData with Diagnosticable {
required this.typography,
// COMPONENT THEMES
required this.appBarTheme,
required this.badgeTheme,
required this.bannerTheme,
required this.bottomAppBarTheme,
required this.bottomNavigationBarTheme,
@ -959,7 +954,6 @@ class ThemeData with Diagnosticable {
assert(typography != null),
// COMPONENT THEMES
assert(appBarTheme != null),
assert(badgeTheme != null),
assert(bannerTheme != null),
assert(bottomAppBarTheme != null),
assert(bottomNavigationBarTheme != null),
@ -1493,9 +1487,6 @@ class ThemeData with Diagnosticable {
/// textTheme of [AppBar]s.
final AppBarTheme appBarTheme;
/// A theme for customizing the color of [Badge]s.
final BadgeThemeData badgeTheme;
/// A theme for customizing the color and text style of a [MaterialBanner].
final MaterialBannerThemeData bannerTheme;
@ -1851,7 +1842,6 @@ class ThemeData with Diagnosticable {
Typography? typography,
// COMPONENT THEMES
AppBarTheme? appBarTheme,
BadgeThemeData? badgeTheme,
MaterialBannerThemeData? bannerTheme,
BottomAppBarTheme? bottomAppBarTheme,
BottomNavigationBarThemeData? bottomNavigationBarTheme,
@ -2013,7 +2003,6 @@ class ThemeData with Diagnosticable {
typography: typography ?? this.typography,
// COMPONENT THEMES
appBarTheme: appBarTheme ?? this.appBarTheme,
badgeTheme: badgeTheme ?? this.badgeTheme,
bannerTheme: bannerTheme ?? this.bannerTheme,
bottomAppBarTheme: bottomAppBarTheme ?? this.bottomAppBarTheme,
bottomNavigationBarTheme: bottomNavigationBarTheme ?? this.bottomNavigationBarTheme,
@ -2217,7 +2206,6 @@ class ThemeData with Diagnosticable {
typography: Typography.lerp(a.typography, b.typography, t),
// COMPONENT THEMES
appBarTheme: AppBarTheme.lerp(a.appBarTheme, b.appBarTheme, t),
badgeTheme: BadgeThemeData.lerp(a.badgeTheme, b.badgeTheme, t),
bannerTheme: MaterialBannerThemeData.lerp(a.bannerTheme, b.bannerTheme, t),
bottomAppBarTheme: BottomAppBarTheme.lerp(a.bottomAppBarTheme, b.bottomAppBarTheme, t),
bottomNavigationBarTheme: BottomNavigationBarThemeData.lerp(a.bottomNavigationBarTheme, b.bottomNavigationBarTheme, t),
@ -2323,7 +2311,6 @@ class ThemeData with Diagnosticable {
other.typography == typography &&
// COMPONENT THEMES
other.appBarTheme == appBarTheme &&
other.badgeTheme == badgeTheme &&
other.bannerTheme == bannerTheme &&
other.bottomAppBarTheme == bottomAppBarTheme &&
other.bottomNavigationBarTheme == bottomNavigationBarTheme &&
@ -2426,7 +2413,6 @@ class ThemeData with Diagnosticable {
typography,
// COMPONENT THEMES
appBarTheme,
badgeTheme,
bannerTheme,
bottomAppBarTheme,
bottomNavigationBarTheme,
@ -2531,7 +2517,6 @@ class ThemeData with Diagnosticable {
properties.add(DiagnosticsProperty<Typography>('typography', typography, defaultValue: defaultData.typography, level: DiagnosticLevel.debug));
// COMPONENT THEMES
properties.add(DiagnosticsProperty<AppBarTheme>('appBarTheme', appBarTheme, defaultValue: defaultData.appBarTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<BadgeThemeData>('badgeTheme', badgeTheme, defaultValue: defaultData.badgeTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<MaterialBannerThemeData>('bannerTheme', bannerTheme, defaultValue: defaultData.bannerTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<BottomAppBarTheme>('bottomAppBarTheme', bottomAppBarTheme, defaultValue: defaultData.bottomAppBarTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<BottomNavigationBarThemeData>('bottomNavigationBarTheme', bottomNavigationBarTheme, defaultValue: defaultData.bottomNavigationBarTheme, level: DiagnosticLevel.debug));

View file

@ -1,206 +0,0 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import '../rendering/mock_canvas.dart';
void main() {
testWidgets('Large Badge defaults', (WidgetTester tester) async {
late final ThemeData theme;
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.light(useMaterial3: true),
home: Align(
alignment: Alignment.topLeft,
child: Builder(
builder: (BuildContext context) {
// theme.textTtheme is updated when the MaterialApp is built.
theme = Theme.of(context);
return const Badge(
label: Text('0'),
child: Icon(Icons.add),
);
},
),
),
),
);
expect(
tester.renderObject<RenderParagraph>(find.text('0')).text.style,
theme.textTheme.labelSmall!.copyWith(color: theme.colorScheme.onError),
);
// default badge alignment = AlignmentDirectional(12, -4)
// default padding = EdgeInsets.symmetric(horizontal: 4)
// default largeSize = 16
// '0'.width = 12
// icon.width = 24
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
// x = alignment.start + padding.left
// y = alignment.top
expect(tester.getTopLeft(find.text('0')), const Offset(16, -4));
final RenderBox box = tester.renderObject(find.byType(Badge));
// '0'.width = 12
// L = alignment.start
// T = alignment.top
// R = L + '0'.width + padding.width
// B = T + largeSize, R = largeSize/2
expect(box, paints..rrect(rrect: RRect.fromLTRBR(12, -4, 32, 12, const Radius.circular(8)), color: theme.colorScheme.error));
});
testWidgets('Large Badge defaults with RTL', (WidgetTester tester) async {
late final ThemeData theme;
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.light(useMaterial3: true),
home: Directionality(
textDirection: TextDirection.rtl,
child: Align(
alignment: Alignment.topLeft,
child: Builder(
builder: (BuildContext context) {
// theme.textTtheme is updated when the MaterialApp is built.
theme = Theme.of(context);
return const Badge(
label: Text('0'),
child: Icon(Icons.add),
);
},
),
),
),
),
);
expect(
tester.renderObject<RenderParagraph>(find.text('0')).text.style,
theme.textTheme.labelSmall!.copyWith(color: theme.colorScheme.onError),
);
// default badge alignment = AlignmentDirectional(12, -4)
// default padding = EdgeInsets.symmetric(horizontal: 4)
// default largeSize = 16
// '0'.width = 12
// icon.width = 24
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
// x = icon.width - alignment.start - '0'.width - padding.right
// y = alignment.top
expect(tester.getTopLeft(find.text('0')), const Offset(-4, -4));
final RenderBox box = tester.renderObject(find.byType(Badge));
// L = icon.width - alignment.start - '0.width' - padding.width
// T = alignment.top
// R = L + '0.width' + padding.width
// B = T + largeSize
// R = largeSize/2
expect(box, paints..rrect(rrect: RRect.fromLTRBR(-8, -4, 12, 12, const Radius.circular(8)), color: theme.colorScheme.error));
});
testWidgets('Small Badge defaults', (WidgetTester tester) async {
final ThemeData theme = ThemeData.light(useMaterial3: true);
await tester.pumpWidget(
MaterialApp(
theme: theme,
home: const Align(
alignment: Alignment.topLeft,
child: Badge(
child: Icon(Icons.add),
),
),
),
);
// default badge location is end=0, top=0
// default padding = EdgeInsets.symmetric(horizontal: 4)
// default smallSize = 6
// icon.width = 24
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
final RenderBox box = tester.renderObject(find.byType(Badge));
// L = icon.size.width - smallSize
// T = 0
// R = icon.size.width
// B = smallSize
expect(box, paints..rrect(rrect: RRect.fromLTRBR(18, 0, 24, 6, const Radius.circular(3)), color: theme.colorScheme.error));
});
testWidgets('Small Badge RTL defaults', (WidgetTester tester) async {
final ThemeData theme = ThemeData.light(useMaterial3: true);
await tester.pumpWidget(
MaterialApp(
theme: theme,
home: const Directionality(
textDirection: TextDirection.rtl,
child: Align(
alignment: Alignment.topLeft,
child: Badge(
child: Icon(Icons.add),
),
),
),
),
);
// default badge location is end=0, top=0
// default smallSize = 6
// icon.width = 24
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
final RenderBox box = tester.renderObject(find.byType(Badge));
// L = 0
// T = 0
// R = smallSize
// B = smallSize
expect(box, paints..rrect(rrect: RRect.fromLTRBR(0, 0, 6, 6, const Radius.circular(3)), color: theme.colorScheme.error));
});
testWidgets('Large Badge textStyle and colors', (WidgetTester tester) async {
final ThemeData theme = ThemeData.light(useMaterial3: true);
const Color green = Color(0xff00ff00);
const Color black = Color(0xff000000);
await tester.pumpWidget(
MaterialApp(
theme: theme,
home: const Align(
alignment: Alignment.topLeft,
child: Badge(
foregroundColor: green,
backgroundColor: black,
textStyle: TextStyle(fontSize: 10),
label: Text('0'),
child: Icon(Icons.add),
),
),
),
);
final TextStyle textStyle = tester.renderObject<RenderParagraph>(find.text('0')).text.style!;
expect(textStyle.fontSize, 10);
expect(textStyle.color, green);
expect(tester.renderObject(find.byType(Badge)), paints..rrect(color: black));
});
}

View file

@ -1,155 +0,0 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import '../rendering/mock_canvas.dart';
void main() {
test('BadgeThemeData copyWith, ==, hashCode basics', () {
expect(const BadgeThemeData(), const BadgeThemeData().copyWith());
expect(const BadgeThemeData().hashCode, const BadgeThemeData().copyWith().hashCode);
});
test('BadgeThemeData defaults', () {
const BadgeThemeData themeData = BadgeThemeData();
expect(themeData.backgroundColor, null);
expect(themeData.foregroundColor, null);
expect(themeData.smallSize, null);
expect(themeData.largeSize, null);
expect(themeData.textStyle, null);
expect(themeData.padding, null);
expect(themeData.alignment, null);
});
testWidgets('Default BadgeThemeData debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
const BadgeThemeData().debugFillProperties(builder);
final List<String> description = builder.properties
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
.map((DiagnosticsNode node) => node.toString())
.toList();
expect(description, <String>[]);
});
testWidgets('BadgeThemeData implements debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
const BadgeThemeData(
backgroundColor: Color(0xfffffff0),
foregroundColor: Color(0xfffffff1),
smallSize: 1,
largeSize: 2,
textStyle: TextStyle(fontSize: 4),
padding: EdgeInsets.all(5),
alignment: AlignmentDirectional(6, 7),
).debugFillProperties(builder);
final List<String> description = builder.properties
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
.map((DiagnosticsNode node) => node.toString())
.toList();
expect(description, <String>[
'backgroundColor: Color(0xfffffff0)',
'foregroundColor: Color(0xfffffff1)',
'smallSize: 1.0',
'largeSize: 2.0',
'textStyle: TextStyle(inherit: true, size: 4.0)',
'padding: EdgeInsets.all(5.0)',
'alignment: AlignmentDirectional(6.0, 7.0)'
]);
});
testWidgets('Badge uses ThemeData badge theme', (WidgetTester tester) async {
const Color green = Color(0xff00ff00);
const Color black = Color(0xff000000);
const BadgeThemeData badgeTheme = BadgeThemeData(
backgroundColor: green,
foregroundColor: black,
smallSize: 5,
largeSize: 20,
textStyle: TextStyle(fontSize: 12),
padding: EdgeInsets.symmetric(horizontal: 5),
alignment: AlignmentDirectional(24, 0),
);
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.light(useMaterial3: true).copyWith(
badgeTheme: badgeTheme,
),
home: const Scaffold(
body: Badge(
label: Text('1234'),
child: Icon(Icons.add),
),
),
),
);
// text width = 48 = fontSize * 4, text height = fontSize
expect(tester.getSize(find.text('1234')), const Size(48, 12));
// x = 29 = alignment.start + padding.left, y = 4 = (largeSize - fontSize) / 2
expect(tester.getTopLeft(find.text('1234')), const Offset(29, 4));
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
final TextStyle textStyle = tester.renderObject<RenderParagraph>(find.text('1234')).text.style!;
expect(textStyle.fontSize, 12);
expect(textStyle.color, black);
final RenderBox box = tester.renderObject(find.byType(Badge));
// L = alignment.start, T = alignment.top, R = L + fontSize * 4 + padding.width, B = largeSize R = largeSize/2
expect(box, paints..rrect(rrect: RRect.fromLTRBR(24, 0, 82, 20, const Radius.circular(10)), color: green));
});
// This test is essentially the same as 'Badge uses ThemeData badge theme'. In
// this case the theme is introduced with the BadgeTheme widget instead of
// ThemeData.badgeTheme.
testWidgets('Badge uses BadgeTheme', (WidgetTester tester) async {
const Color green = Color(0xff00ff00);
const Color black = Color(0xff000000);
const BadgeThemeData badgeTheme = BadgeThemeData(
backgroundColor: green,
foregroundColor: black,
smallSize: 5,
largeSize: 20,
textStyle: TextStyle(fontSize: 12),
padding: EdgeInsets.symmetric(horizontal: 5),
alignment: AlignmentDirectional(24, 0),
);
await tester.pumpWidget(
const MaterialApp(
home: BadgeTheme(
data: badgeTheme,
child: Scaffold(
body: Badge(
label: Text('1234'),
child: Icon(Icons.add),
),
),
),
),
);
expect(tester.getSize(find.text('1234')), const Size(48, 12));
expect(tester.getTopLeft(find.text('1234')), const Offset(29, 4));
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
final TextStyle textStyle = tester.renderObject<RenderParagraph>(find.text('1234')).text.style!;
expect(textStyle.fontSize, 12);
expect(textStyle.color, black);
final RenderBox box = tester.renderObject(find.byType(Badge));
expect(box, paints..rrect(rrect: RRect.fromLTRBR(24, 0, 82, 20, const Radius.circular(10)), color: green));
});
}

View file

@ -770,7 +770,6 @@ void main() {
typography: Typography.material2018(),
// COMPONENT THEMES
appBarTheme: const AppBarTheme(backgroundColor: Colors.black),
badgeTheme: const BadgeThemeData(backgroundColor: Colors.black),
bannerTheme: const MaterialBannerThemeData(backgroundColor: Colors.black),
bottomAppBarTheme: const BottomAppBarTheme(color: Colors.black),
bottomNavigationBarTheme: const BottomNavigationBarThemeData(type: BottomNavigationBarType.fixed),
@ -888,7 +887,6 @@ void main() {
// COMPONENT THEMES
appBarTheme: const AppBarTheme(backgroundColor: Colors.white),
badgeTheme: const BadgeThemeData(backgroundColor: Colors.black),
bannerTheme: const MaterialBannerThemeData(backgroundColor: Colors.white),
bottomAppBarTheme: const BottomAppBarTheme(color: Colors.white),
bottomNavigationBarTheme: const BottomNavigationBarThemeData(type: BottomNavigationBarType.shifting),
@ -992,7 +990,6 @@ void main() {
// COMPONENT THEMES
appBarTheme: otherTheme.appBarTheme,
badgeTheme: otherTheme.badgeTheme,
bannerTheme: otherTheme.bannerTheme,
bottomAppBarTheme: otherTheme.bottomAppBarTheme,
bottomNavigationBarTheme: otherTheme.bottomNavigationBarTheme,
@ -1095,7 +1092,6 @@ void main() {
// COMPONENT THEMES
expect(themeDataCopy.appBarTheme, equals(otherTheme.appBarTheme));
expect(themeDataCopy.badgeTheme, equals(otherTheme.badgeTheme));
expect(themeDataCopy.bannerTheme, equals(otherTheme.bannerTheme));
expect(themeDataCopy.bottomAppBarTheme, equals(otherTheme.bottomAppBarTheme));
expect(themeDataCopy.bottomNavigationBarTheme, equals(otherTheme.bottomNavigationBarTheme));
@ -1234,7 +1230,6 @@ void main() {
'primaryIconTheme',
// COMPONENT THEMES
'appBarTheme',
'badgeTheme',
'bannerTheme',
'bottomAppBarTheme',
'bottomNavigationBarTheme',