Skip to content

Instantly share code, notes, and snippets.

@rydmike
Last active July 8, 2022 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rydmike/946d29aa48e8ec3446281acaab61e4c5 to your computer and use it in GitHub Desktop.
Save rydmike/946d29aa48e8ec3446281acaab61e4c5 to your computer and use it in GitHub Desktop.
Demo app for Flutter issue #107305: M3 AppBarTheme icon theme regression demo
// MIT License
//
// Copyright (c) 2022 Mike Rydstrom
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
import 'package:flutter/material.dart';
// Light M3 ColorScheme.
const ColorScheme mySchemeLight = ColorScheme(
brightness: Brightness.light,
primary: Color(0xff386a20),
onPrimary: Color(0xffffffff),
primaryContainer: Color(0xffc0f0a4),
onPrimaryContainer: Color(0xff042100),
secondary: Color(0xff55624c),
onSecondary: Color(0xffffffff),
secondaryContainer: Color(0xffd9e7cb),
onSecondaryContainer: Color(0xff131f0d),
tertiary: Color(0xff386667),
onTertiary: Color(0xffffffff),
tertiaryContainer: Color(0xffbbebeb),
onTertiaryContainer: Color(0xff002021),
error: Color(0xffba1b1b),
onError: Color(0xffffffff),
errorContainer: Color(0xffffdad4),
onErrorContainer: Color(0xff410001),
outline: Color(0xff74796e),
background: Color(0xfffdfdf6),
onBackground: Color(0xff1a1c18),
surface: Color(0xfffdfdf6),
onSurface: Color(0xff1a1c18),
surfaceVariant: Color(0xffdfe4d6),
onSurfaceVariant: Color(0xff43493e),
inverseSurface: Color(0xff2f312c),
onInverseSurface: Color(0xfff1f1ea),
inversePrimary: Color(0xff9cd67d),
shadow: Color(0xff000000),
surfaceTint: Color(0xff386a20),
);
// Dark M3 ColorScheme.
const ColorScheme mySchemeDark = ColorScheme(
brightness: Brightness.dark,
primary: Color(0xff9cd67d),
onPrimary: Color(0xff0c3900),
primaryContainer: Color(0xff205107),
onPrimaryContainer: Color(0xffc0f0a4),
secondary: Color(0xffbdcbb0),
onSecondary: Color(0xff273420),
secondaryContainer: Color(0xff3e4a36),
onSecondaryContainer: Color(0xffd9e7cb),
tertiary: Color(0xffa0cfcf),
onTertiary: Color(0xff003738),
tertiaryContainer: Color(0xff1e4e4e),
onTertiaryContainer: Color(0xffbbebeb),
error: Color(0xffffb4a9),
onError: Color(0xff680003),
errorContainer: Color(0xff930006),
onErrorContainer: Color(0xffffb4a9),
outline: Color(0xff8d9286),
background: Color(0xff1a1c18),
onBackground: Color(0xffe3e3dc),
surface: Color(0xff1a1c18),
onSurface: Color(0xffe3e3dc),
surfaceVariant: Color(0xff43493e),
onSurfaceVariant: Color(0xffc4c8bb),
inverseSurface: Color(0xffe3e3dc),
onInverseSurface: Color(0xff2f312c),
inversePrimary: Color(0xff386a20),
shadow: Color(0xff000000),
surfaceTint: Color(0xff9cd67d),
);
const myAppBarTheme = AppBarTheme(
iconTheme: IconThemeData(color: Colors.deepOrange, size: 32.0),
actionsIconTheme: IconThemeData(color: Colors.yellow, size: 32.0),
);
// Example theme -
ThemeData demoTheme(Brightness mode, bool useMaterial3) =>
mode == Brightness.light
? ThemeData(
colorScheme: mySchemeLight,
toggleableActiveColor:
useMaterial3 ? mySchemeLight.primary : mySchemeLight.secondary,
primaryColor: mySchemeLight.primary,
primaryColorLight: Color.alphaBlend(
Colors.white.withAlpha(0x66), mySchemeLight.primary),
primaryColorDark: Color.alphaBlend(
Colors.black.withAlpha(0x66), mySchemeLight.primary),
secondaryHeaderColor: Color.alphaBlend(
Colors.white.withAlpha(0xCC), mySchemeLight.primary),
scaffoldBackgroundColor: mySchemeLight.background,
canvasColor: mySchemeLight.background,
backgroundColor: mySchemeLight.background,
cardColor: mySchemeLight.surface,
bottomAppBarColor: mySchemeLight.surface,
dialogBackgroundColor: mySchemeLight.surface,
indicatorColor: mySchemeLight.onPrimary,
dividerColor: mySchemeLight.onSurface.withOpacity(0.12),
errorColor: mySchemeLight.error,
applyElevationOverlayColor: false,
useMaterial3: useMaterial3,
visualDensity: VisualDensity.standard,
appBarTheme: myAppBarTheme,
)
: ThemeData(
colorScheme: mySchemeDark,
toggleableActiveColor:
useMaterial3 ? mySchemeDark.primary : mySchemeDark.secondary,
primaryColor: mySchemeDark.primary,
primaryColorLight: Color.alphaBlend(
Colors.white.withAlpha(0x59), mySchemeDark.primary),
primaryColorDark: Color.alphaBlend(
Colors.black.withAlpha(0x72), mySchemeDark.primary),
secondaryHeaderColor: Color.alphaBlend(
Colors.black.withAlpha(0x99), mySchemeDark.primary),
scaffoldBackgroundColor: mySchemeDark.background,
canvasColor: mySchemeDark.background,
backgroundColor: mySchemeDark.background,
cardColor: mySchemeDark.surface,
bottomAppBarColor: mySchemeDark.surface,
dialogBackgroundColor: mySchemeDark.surface,
indicatorColor: mySchemeDark.onBackground,
dividerColor: mySchemeDark.onSurface.withOpacity(0.12),
errorColor: mySchemeDark.error,
applyElevationOverlayColor: true,
useMaterial3: useMaterial3,
visualDensity: VisualDensity.standard,
appBarTheme: myAppBarTheme,
);
void main() {
runApp(const IssueDemoApp());
}
class IssueDemoApp extends StatefulWidget {
const IssueDemoApp({super.key});
@override
State<IssueDemoApp> createState() => _IssueDemoAppState();
}
class _IssueDemoAppState extends State<IssueDemoApp> {
bool useMaterial3 = false;
ThemeMode themeMode = ThemeMode.light;
// ThemingWay themingWay = ThemingWay.road10;
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
themeMode: themeMode,
theme: demoTheme(Brightness.light, useMaterial3),
darkTheme: demoTheme(Brightness.dark, useMaterial3),
home: Scaffold(
appBar: AppBar(
title: const Text(('M3 AppBar Theme Issue')),
actions: [
IconButton(
icon: useMaterial3
? const Icon(Icons.filter_3)
: const Icon(Icons.filter_2),
onPressed: () {
setState(() {
useMaterial3 = !useMaterial3;
});
},
tooltip: "Switch to Material ${useMaterial3 ? 2 : 3}",
),
IconButton(
icon: themeMode == ThemeMode.dark
? const Icon(Icons.wb_sunny_outlined)
: const Icon(Icons.wb_sunny),
onPressed: () {
setState(() {
if (themeMode == ThemeMode.light) {
themeMode = ThemeMode.dark;
} else {
themeMode = ThemeMode.light;
}
});
},
tooltip: "Toggle brightness",
),
],
),
body: const HomePage(),
drawer: const Drawer(),
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
final String materialType =
Theme.of(context).useMaterial3 ? "Material 3" : "Material 2";
return ListView(
padding: const EdgeInsets.symmetric(horizontal: 16),
children: [
const SizedBox(height: 8),
Text(
'Theme Demo - $materialType',
style: Theme.of(context).textTheme.headlineSmall,
),
const Divider(),
const ShowColorSchemeColors(),
const Divider(),
const ShowThemeDataColors(),
const Divider(),
const ShowAppBarThemeColors(),
const Divider(),
],
);
}
}
/// Draw a number of boxes showing the colors of key AppBar theme color
/// properties of the inherited ThemeData
class ShowAppBarThemeColors extends StatelessWidget {
const ShowAppBarThemeColors({super.key, this.onBackgroundColor});
/// The color of the background the color widget are being drawn on.
///
/// Some of the theme colors may have semi transparent fill color. To compute
/// a legible text color for the sum when it shown on a background color, we
/// need to alpha merge it with background and we need the exact background
/// color it is drawn on for that. If not passed in from parent, it is
/// assumed to be drawn on card color, which usually is close enough.
final Color? onBackgroundColor;
// Return true if the color is light, meaning it needs dark text for contrast.
static bool _isLight(final Color color) =>
ThemeData.estimateBrightnessForColor(color) == Brightness.light;
// On color used when a theme color property does not have a theme onColor.
static Color _onColor(final Color color, final Color bg) =>
_isLight(Color.alphaBlend(color, bg)) ? Colors.black : Colors.white;
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final AppBarTheme appBarTheme = theme.appBarTheme;
final bool useMaterial3 = theme.useMaterial3;
// Get effective background color.
final Color background =
onBackgroundColor ?? theme.cardTheme.color ?? theme.cardColor;
// Grab the card border from the theme card shape
ShapeBorder? border = theme.cardTheme.shape;
// If we had one, copy in a border side to it.
if (border is RoundedRectangleBorder) {
border = border.copyWith(
side: BorderSide(
color: theme.dividerColor,
width: 1,
),
);
// If
} else {
// If border was null, make one matching Card default, but with border
// side, if it was not null, we leave it as it was.
border ??= RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(useMaterial3 ? 12 : 4)),
side: BorderSide(
color: theme.dividerColor,
width: 1,
),
);
}
// Wrap this widget branch in a custom theme where card has a border outline
// if it did not have one, but retains in ambient themed border radius.
return Theme(
data: Theme.of(context).copyWith(
cardTheme: CardTheme.of(context).copyWith(
elevation: 0,
shape: border,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Text(
'Assigned AppBar Theme Colors',
style: theme.textTheme.titleMedium,
),
),
Wrap(
alignment: WrapAlignment.start,
crossAxisAlignment: WrapCrossAlignment.center,
spacing: 6,
runSpacing: 6,
children: <Widget>[
ColorCard(
label: 'AppBar\nicon',
color: appBarTheme.iconTheme!.color!,
textColor: _onColor(appBarTheme.iconTheme!.color!, background),
),
ColorCard(
label: 'AppBar\nactionIcon',
color: appBarTheme.actionsIconTheme!.color!,
textColor:
_onColor(appBarTheme.actionsIconTheme!.color!, background),
),
],
),
],
),
);
}
}
/// Draw a number of boxes showing the colors of key theme color properties
/// in the ColorScheme of the inherited ThemeData and its color properties.
class ShowColorSchemeColors extends StatelessWidget {
const ShowColorSchemeColors({super.key, this.onBackgroundColor});
/// The color of the background the color widget are being drawn on.
///
/// Some of the theme colors may have semi transparent fill color. To compute
/// a legible text color for the sum when it shown on a background color, we
/// need to alpha merge it with background and we need the exact background
/// color it is drawn on for that. If not passed in from parent, it is
/// assumed to be drawn on card color, which usually is close enough.
final Color? onBackgroundColor;
// Return true if the color is light, meaning it needs dark text for contrast.
static bool _isLight(final Color color) =>
ThemeData.estimateBrightnessForColor(color) == Brightness.light;
// Return true if the color is dark, meaning it needs light text for contrast.
static bool _isDark(final Color color) =>
ThemeData.estimateBrightnessForColor(color) == Brightness.dark;
// On color used when a theme color property does not have a theme onColor.
static Color _onColor(final Color color, final Color bg) =>
_isLight(Color.alphaBlend(color, bg)) ? Colors.black : Colors.white;
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final ColorScheme colorScheme = theme.colorScheme;
final bool isDark = colorScheme.brightness == Brightness.dark;
final bool useMaterial3 = theme.useMaterial3;
// Grab the card border from the theme card shape
ShapeBorder? border = theme.cardTheme.shape;
// If we had one, copy in a border side to it.
if (border is RoundedRectangleBorder) {
border = border.copyWith(
side: BorderSide(
color: theme.dividerColor,
width: 1,
),
);
// If
} else {
// If border was null, make one matching Card default, but with border
// side, if it was not null, we leave it as it was.
border ??= RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(useMaterial3 ? 12 : 4)),
side: BorderSide(
color: theme.dividerColor,
width: 1,
),
);
}
// Get effective background color.
final Color background =
onBackgroundColor ?? theme.cardTheme.color ?? theme.cardColor;
// Warning label for scaffold background when it uses to much blend.
final String surfaceTooHigh = isDark
? _isLight(theme.colorScheme.surface)
? '\nTOO HIGH'
: ''
: _isDark(theme.colorScheme.surface)
? '\nTOO HIGH'
: '';
// Warning label for scaffold background when it uses to much blend.
final String backTooHigh = isDark
? _isLight(theme.colorScheme.background)
? '\nTOO HIGH'
: ''
: _isDark(theme.colorScheme.background)
? '\nTOO HIGH'
: '';
// Wrap this widget branch in a custom theme where card has a border outline
// if it did not have one, but retains in ambient themed border radius.
return Theme(
data: Theme.of(context).copyWith(
cardTheme: CardTheme.of(context).copyWith(
elevation: 0,
shape: border,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Text(
'ColorScheme Colors',
style: theme.textTheme.titleMedium,
),
),
Wrap(
alignment: WrapAlignment.start,
crossAxisAlignment: WrapCrossAlignment.center,
spacing: 6,
runSpacing: 6,
children: <Widget>[
ColorCard(
label: 'Primary',
color: colorScheme.primary,
textColor: colorScheme.onPrimary,
),
ColorCard(
label: 'on\nPrimary',
color: colorScheme.onPrimary,
textColor: colorScheme.primary,
),
ColorCard(
label: 'Primary\nContainer',
color: colorScheme.primaryContainer,
textColor: colorScheme.onPrimaryContainer,
),
ColorCard(
label: 'onPrimary\nContainer',
color: colorScheme.onPrimaryContainer,
textColor: colorScheme.primaryContainer,
),
ColorCard(
label: 'Secondary',
color: colorScheme.secondary,
textColor: colorScheme.onSecondary,
),
ColorCard(
label: 'on\nSecondary',
color: colorScheme.onSecondary,
textColor: colorScheme.secondary,
),
ColorCard(
label: 'Secondary\nContainer',
color: colorScheme.secondaryContainer,
textColor: colorScheme.onSecondaryContainer,
),
ColorCard(
label: 'on\nSecondary\nContainer',
color: colorScheme.onSecondaryContainer,
textColor: colorScheme.secondaryContainer,
),
ColorCard(
label: 'Tertiary',
color: colorScheme.tertiary,
textColor: colorScheme.onTertiary,
),
ColorCard(
label: 'on\nTertiary',
color: colorScheme.onTertiary,
textColor: colorScheme.tertiary,
),
ColorCard(
label: 'Tertiary\nContainer',
color: colorScheme.tertiaryContainer,
textColor: colorScheme.onTertiaryContainer,
),
ColorCard(
label: 'on\nTertiary\nContainer',
color: colorScheme.onTertiaryContainer,
textColor: colorScheme.tertiaryContainer,
),
ColorCard(
label: 'Error',
color: colorScheme.error,
textColor: colorScheme.onError,
),
ColorCard(
label: 'on\nError',
color: colorScheme.onError,
textColor: colorScheme.error,
),
ColorCard(
label: 'Error\nContainer',
color: colorScheme.errorContainer,
textColor: colorScheme.onErrorContainer,
),
ColorCard(
label: 'onError\nContainer',
color: colorScheme.onErrorContainer,
textColor: colorScheme.errorContainer,
),
ColorCard(
label: 'Background$backTooHigh',
color: colorScheme.background,
textColor: colorScheme.onBackground,
),
ColorCard(
label: 'on\nBackground',
color: colorScheme.onBackground,
textColor: colorScheme.background,
),
ColorCard(
label: 'Surface$surfaceTooHigh',
color: colorScheme.surface,
textColor: colorScheme.onSurface,
),
ColorCard(
label: 'on\nSurface',
color: colorScheme.onSurface,
textColor: colorScheme.surface,
),
ColorCard(
label: 'Surface\nVariant',
color: colorScheme.surfaceVariant,
textColor: colorScheme.onSurfaceVariant,
),
ColorCard(
label: 'onSurface\nVariant',
color: colorScheme.onSurfaceVariant,
textColor: colorScheme.surfaceVariant,
),
ColorCard(
label: 'Outline',
color: colorScheme.outline,
textColor: colorScheme.background,
),
ColorCard(
label: 'Shadow',
color: colorScheme.shadow,
textColor: _onColor(colorScheme.shadow, background),
),
ColorCard(
label: 'Inverse\nSurface',
color: colorScheme.inverseSurface,
textColor: colorScheme.onInverseSurface,
),
ColorCard(
label: 'onInverse\nSurface',
color: colorScheme.onInverseSurface,
textColor: colorScheme.inverseSurface,
),
ColorCard(
label: 'Inverse\nPrimary',
color: colorScheme.inversePrimary,
textColor: colorScheme.primary,
),
ColorCard(
label: 'Surface\nTint',
color: colorScheme.surfaceTint,
textColor: colorScheme.onPrimary,
),
],
),
],
),
);
}
}
/// Draw a number of boxes showing the colors of key theme color properties
/// in the ColorScheme of the inherited ThemeData and some of its key color
/// properties.
class ShowThemeDataColors extends StatelessWidget {
const ShowThemeDataColors({
super.key,
this.onBackgroundColor,
});
/// The color of the background the color widget are being drawn on.
///
/// Some of the theme colors may have semi-transparent fill color. To compute
/// a legible text color for the sum when it shown on a background color, we
/// need to alpha merge it with background and we need the exact background
/// color it is drawn on for that. If not passed in from parent, it is
/// assumed to be drawn on card color, which usually is close enough.
final Color? onBackgroundColor;
// Return true if the color is light, meaning it needs dark text for contrast.
static bool _isLight(final Color color) =>
ThemeData.estimateBrightnessForColor(color) == Brightness.light;
// Return true if the color is dark, meaning it needs light text for contrast.
static bool _isDark(final Color color) =>
ThemeData.estimateBrightnessForColor(color) == Brightness.dark;
// On color used when a theme color property does not have a theme onColor.
static Color _onColor(final Color color, final Color background) =>
_isLight(Color.alphaBlend(color, background))
? Colors.black
: Colors.white;
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final ColorScheme colorScheme = theme.colorScheme;
final bool isDark = colorScheme.brightness == Brightness.dark;
final bool useMaterial3 = theme.useMaterial3;
// Grab the card border from the theme card shape
ShapeBorder? border = theme.cardTheme.shape;
// If we had one, copy in a border side to it.
if (border is RoundedRectangleBorder) {
border = border.copyWith(
side: BorderSide(
color: theme.dividerColor,
width: 1,
),
);
} else {
// If border was null, make one matching Card default, but with border
// side, if it was not null, we leave it as it was.
border ??= RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(useMaterial3 ? 12 : 4)),
side: BorderSide(
color: theme.dividerColor,
width: 1,
),
);
}
// Get effective background color.
final Color background =
onBackgroundColor ?? theme.cardTheme.color ?? theme.cardColor;
// Warning label for scaffold background when it uses to much blend.
final String scaffoldTooHigh = isDark
? _isLight(theme.scaffoldBackgroundColor)
? '\nTOO HIGH'
: ''
: _isDark(theme.scaffoldBackgroundColor)
? '\nTOO HIGH'
: '';
// Warning label for scaffold background when it uses to much blend.
final String surfaceTooHigh = isDark
? _isLight(theme.colorScheme.surface)
? '\nTOO HIGH'
: ''
: _isDark(theme.colorScheme.surface)
? '\nTOO HIGH'
: '';
// Warning label for scaffold background when it uses to much blend.
final String backTooHigh = isDark
? _isLight(theme.colorScheme.background)
? '\nTOO HIGH'
: ''
: _isDark(theme.colorScheme.background)
? '\nTOO HIGH'
: '';
// Wrap this widget branch in a custom theme where card has a border outline
// if it did not have one, but retains in ambient themed border radius.
return Theme(
data: Theme.of(context).copyWith(
cardTheme: CardTheme.of(context).copyWith(
elevation: 0,
shape: border,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 8),
child: Text(
'ThemeData Colors',
style: theme.textTheme.titleMedium,
),
),
const SizedBox(height: 8),
Wrap(
spacing: 6,
runSpacing: 6,
crossAxisAlignment: WrapCrossAlignment.center,
children: <Widget>[
ColorCard(
label: 'Primary\nColor',
color: theme.primaryColor,
textColor: _onColor(theme.primaryColor, background),
),
ColorCard(
label: 'Primary\nDark',
color: theme.primaryColorDark,
textColor: _onColor(theme.primaryColorDark, background),
),
ColorCard(
label: 'Primary\nLight',
color: theme.primaryColorLight,
textColor: _onColor(theme.primaryColorLight, background),
),
ColorCard(
label: 'Secondary\nHeader',
color: theme.secondaryHeaderColor,
textColor: _onColor(theme.secondaryHeaderColor, background),
),
ColorCard(
label: 'Toggleable\nActive',
color: theme.toggleableActiveColor,
textColor: _onColor(theme.toggleableActiveColor, background),
),
ColorCard(
label: 'Bottom\nAppBar',
color: theme.bottomAppBarColor,
textColor: _onColor(theme.bottomAppBarColor, background),
),
ColorCard(
label: 'Error\nColor',
color: theme.errorColor,
textColor: colorScheme.onError,
),
ColorCard(
label: 'Canvas$backTooHigh',
color: theme.canvasColor,
textColor: _onColor(theme.canvasColor, background),
),
ColorCard(
label: 'Card$surfaceTooHigh',
color: theme.cardColor,
textColor: _onColor(theme.cardColor, background),
),
ColorCard(
label: 'Scaffold\nBackground$scaffoldTooHigh',
color: theme.scaffoldBackgroundColor,
textColor: _onColor(theme.scaffoldBackgroundColor, background),
),
ColorCard(
label: 'Dialog',
color: theme.dialogBackgroundColor,
textColor: _onColor(theme.dialogBackgroundColor, background),
),
ColorCard(
label: 'Indicator\nColor',
color: theme.indicatorColor,
textColor: _onColor(theme.indicatorColor, background),
),
ColorCard(
label: 'Divider\nColor',
color: theme.dividerColor,
textColor: _onColor(theme.dividerColor, background),
),
ColorCard(
label: 'Disabled\nColor',
color: theme.disabledColor,
textColor: _onColor(theme.disabledColor, background),
),
ColorCard(
label: 'Hover\nColor',
color: theme.hoverColor,
textColor: _onColor(theme.hoverColor, background),
),
ColorCard(
label: 'Focus\nColor',
color: theme.focusColor,
textColor: _onColor(theme.focusColor, background),
),
ColorCard(
label: 'Highlight\nColor',
color: theme.highlightColor,
textColor: _onColor(theme.highlightColor, background),
),
ColorCard(
label: 'Splash\nColor',
color: theme.splashColor,
textColor: _onColor(theme.splashColor, background),
),
ColorCard(
label: 'Shadow\nColor',
color: theme.shadowColor,
textColor: _onColor(theme.shadowColor, background),
),
ColorCard(
label: 'Hint\nColor',
color: theme.hintColor,
textColor: _onColor(theme.hintColor, background),
),
ColorCard(
label: 'Selected\nRow',
color: theme.selectedRowColor,
textColor: _onColor(theme.selectedRowColor, background),
),
ColorCard(
label: 'Unselected\nWidget',
color: theme.unselectedWidgetColor,
textColor: _onColor(theme.unselectedWidgetColor, background),
),
],
),
],
),
);
}
}
class ColorCard extends StatelessWidget {
const ColorCard({
super.key,
required this.label,
required this.color,
required this.textColor,
this.size,
});
final String label;
final Color color;
final Color textColor;
final Size? size;
@override
Widget build(BuildContext context) {
return SizedBox(
width: 86,
height: 58,
child: Card(
margin: EdgeInsets.zero,
clipBehavior: Clip.antiAlias,
color: color,
child: Center(
child: Text(
label,
style: TextStyle(color: textColor, fontSize: 11),
textAlign: TextAlign.center,
),
),
),
);
}
}
@rydmike
Copy link
Author

rydmike commented Jul 8, 2022

Demo code for Flutter issue:
flutter/flutter#107305

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment