mirror of
https://github.com/flutter/samples.git
synced 2025-11-08 22:09:06 +00:00
Update Material 3 Demo App (#1530)
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -12,35 +12,45 @@ class ElevationScreen extends StatelessWidget {
|
|||||||
Color shadowColor = Theme.of(context).colorScheme.shadow;
|
Color shadowColor = Theme.of(context).colorScheme.shadow;
|
||||||
Color surfaceTint = Theme.of(context).colorScheme.primary;
|
Color surfaceTint = Theme.of(context).colorScheme.primary;
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: ListView(
|
child: CustomScrollView(
|
||||||
children: [
|
slivers: [
|
||||||
Padding(
|
SliverToBoxAdapter(
|
||||||
padding: const EdgeInsets.fromLTRB(16.0, 20, 16.0, 0),
|
child: Padding(
|
||||||
child: Text(
|
padding: const EdgeInsets.fromLTRB(16.0, 20, 16.0, 0),
|
||||||
'Surface Tint only',
|
child: Text(
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
'Surface Tint Color Only',
|
||||||
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ElevationGrid(surfaceTintColor: surfaceTint),
|
ElevationGrid(surfaceTintColor: surfaceTint),
|
||||||
const SizedBox(height: 10),
|
SliverList(
|
||||||
Padding(
|
delegate: SliverChildListDelegate(<Widget>[
|
||||||
padding: const EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 0),
|
const SizedBox(height: 10),
|
||||||
child: Text(
|
Padding(
|
||||||
'Surface Tint and Shadow',
|
padding: const EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 0),
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
child: Text(
|
||||||
),
|
'Surface Tint Color and Shadow Color',
|
||||||
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
ElevationGrid(
|
ElevationGrid(
|
||||||
shadowColor: shadowColor,
|
shadowColor: shadowColor,
|
||||||
surfaceTintColor: surfaceTint,
|
surfaceTintColor: surfaceTint,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
SliverList(
|
||||||
Padding(
|
delegate: SliverChildListDelegate(<Widget>[
|
||||||
padding: const EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 0),
|
const SizedBox(height: 10),
|
||||||
child: Text(
|
Padding(
|
||||||
'Shadow only',
|
padding: const EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 0),
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
child: Text(
|
||||||
),
|
'Shadow Color Only',
|
||||||
|
style: Theme.of(context).textTheme.titleLarge,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
ElevationGrid(shadowColor: shadowColor),
|
ElevationGrid(shadowColor: shadowColor),
|
||||||
],
|
],
|
||||||
@@ -72,18 +82,16 @@ class ElevationGrid extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return SliverPadding(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
child: LayoutBuilder(builder: (context, constraints) {
|
sliver: SliverLayoutBuilder(builder: (context, constraints) {
|
||||||
if (constraints.maxWidth < narrowScreenWidthThreshold) {
|
if (constraints.crossAxisExtent < narrowScreenWidthThreshold) {
|
||||||
return GridView.count(
|
return SliverGrid.count(
|
||||||
shrinkWrap: true,
|
|
||||||
crossAxisCount: 3,
|
crossAxisCount: 3,
|
||||||
children: elevationCards(shadowColor, surfaceTintColor),
|
children: elevationCards(shadowColor, surfaceTintColor),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return GridView.count(
|
return SliverGrid.count(
|
||||||
shrinkWrap: true,
|
|
||||||
crossAxisCount: 6,
|
crossAxisCount: 6,
|
||||||
children: elevationCards(shadowColor, surfaceTintColor),
|
children: elevationCards(shadowColor, surfaceTintColor),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ import 'elevation_screen.dart';
|
|||||||
import 'typography_screen.dart';
|
import 'typography_screen.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(const Material3Demo());
|
runApp(const MaterialApp(
|
||||||
|
debugShowCheckedModeBanner: false, home: Material3Demo()));
|
||||||
}
|
}
|
||||||
|
|
||||||
class Material3Demo extends StatefulWidget {
|
class Material3Demo extends StatefulWidget {
|
||||||
@@ -23,25 +24,23 @@ class Material3Demo extends StatefulWidget {
|
|||||||
// screenWidthThreshold; otherwise, NavigationBar is used for navigation.
|
// screenWidthThreshold; otherwise, NavigationBar is used for navigation.
|
||||||
const double narrowScreenWidthThreshold = 450;
|
const double narrowScreenWidthThreshold = 450;
|
||||||
|
|
||||||
const Color m3BaseColor = Color(0xff6750a4);
|
const double transitionLength = 500;
|
||||||
const List<Color> colorOptions = [
|
|
||||||
m3BaseColor,
|
enum ColorSeed {
|
||||||
Colors.blue,
|
baseColor('M3 Baseline', Color(0xff6750a4)),
|
||||||
Colors.teal,
|
indigo('Indigo', Colors.indigo),
|
||||||
Colors.green,
|
blue('Blue', Colors.blue),
|
||||||
Colors.yellow,
|
teal('Teal', Colors.teal),
|
||||||
Colors.orange,
|
green('Green', Colors.green),
|
||||||
Colors.pink
|
yellow('Yellow', Colors.yellow),
|
||||||
];
|
orange('Orange', Colors.orange),
|
||||||
const List<String> colorText = <String>[
|
deepOrange('Deep Orange', Colors.deepOrange),
|
||||||
'M3 Baseline',
|
pink('Pink', Colors.pink);
|
||||||
'Blue',
|
|
||||||
'Teal',
|
const ColorSeed(this.label, this.color);
|
||||||
'Green',
|
final String label;
|
||||||
'Yellow',
|
final Color color;
|
||||||
'Orange',
|
}
|
||||||
'Pink',
|
|
||||||
];
|
|
||||||
|
|
||||||
enum ScreenSelected {
|
enum ScreenSelected {
|
||||||
component(0),
|
component(0),
|
||||||
@@ -53,10 +52,17 @@ enum ScreenSelected {
|
|||||||
final int value;
|
final int value;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _Material3DemoState extends State<Material3Demo> {
|
class _Material3DemoState extends State<Material3Demo>
|
||||||
|
with SingleTickerProviderStateMixin {
|
||||||
|
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
|
late final AnimationController controller;
|
||||||
|
late final CurvedAnimation railAnimation;
|
||||||
|
bool controllerInitialized = false;
|
||||||
|
bool showMediumSizeLayout = false;
|
||||||
|
bool showLargeSizeLayout = false;
|
||||||
bool useMaterial3 = true;
|
bool useMaterial3 = true;
|
||||||
bool useLightMode = true;
|
bool useLightMode = true;
|
||||||
int colorSelected = 0;
|
ColorSeed colorSelected = ColorSeed.baseColor;
|
||||||
int screenIndex = ScreenSelected.component.value;
|
int screenIndex = ScreenSelected.component.value;
|
||||||
|
|
||||||
late ThemeData themeData;
|
late ThemeData themeData;
|
||||||
@@ -64,12 +70,61 @@ class _Material3DemoState extends State<Material3Demo> {
|
|||||||
@override
|
@override
|
||||||
initState() {
|
initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
themeData = updateThemes(colorSelected, useMaterial3, useLightMode);
|
themeData = updateThemes(colorSelected.color, useMaterial3, useLightMode);
|
||||||
|
|
||||||
|
controller = AnimationController(
|
||||||
|
duration: Duration(milliseconds: transitionLength.toInt() * 2),
|
||||||
|
value: 0,
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
railAnimation = CurvedAnimation(
|
||||||
|
parent: controller,
|
||||||
|
curve: const Interval(0.5, 1.0),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ThemeData updateThemes(int colorIndex, bool useMaterial3, bool useLightMode) {
|
@override
|
||||||
|
void dispose() {
|
||||||
|
controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
|
||||||
|
final double width = MediaQuery.of(context).size.width;
|
||||||
|
final AnimationStatus status = controller.status;
|
||||||
|
if (width > 1000) {
|
||||||
|
if (width > 1500) {
|
||||||
|
showMediumSizeLayout = false;
|
||||||
|
showLargeSizeLayout = true;
|
||||||
|
} else {
|
||||||
|
showMediumSizeLayout = true;
|
||||||
|
showLargeSizeLayout = false;
|
||||||
|
}
|
||||||
|
if (status != AnimationStatus.forward &&
|
||||||
|
status != AnimationStatus.completed) {
|
||||||
|
controller.forward();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showMediumSizeLayout = false;
|
||||||
|
showLargeSizeLayout = false;
|
||||||
|
if (status != AnimationStatus.reverse &&
|
||||||
|
status != AnimationStatus.dismissed) {
|
||||||
|
controller.reverse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!controllerInitialized) {
|
||||||
|
controllerInitialized = true;
|
||||||
|
controller.value = width > 1000 ? 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ThemeData updateThemes(
|
||||||
|
Color colorSelected, bool useMaterial3, bool useLightMode) {
|
||||||
return ThemeData(
|
return ThemeData(
|
||||||
colorSchemeSeed: colorOptions[colorSelected],
|
colorSchemeSeed: colorSelected,
|
||||||
useMaterial3: useMaterial3,
|
useMaterial3: useMaterial3,
|
||||||
brightness: useLightMode ? Brightness.light : Brightness.dark);
|
brightness: useLightMode ? Brightness.light : Brightness.dark);
|
||||||
}
|
}
|
||||||
@@ -83,21 +138,21 @@ class _Material3DemoState extends State<Material3Demo> {
|
|||||||
void handleBrightnessChange() {
|
void handleBrightnessChange() {
|
||||||
setState(() {
|
setState(() {
|
||||||
useLightMode = !useLightMode;
|
useLightMode = !useLightMode;
|
||||||
themeData = updateThemes(colorSelected, useMaterial3, useLightMode);
|
themeData = updateThemes(colorSelected.color, useMaterial3, useLightMode);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleMaterialVersionChange() {
|
void handleMaterialVersionChange() {
|
||||||
setState(() {
|
setState(() {
|
||||||
useMaterial3 = !useMaterial3;
|
useMaterial3 = !useMaterial3;
|
||||||
themeData = updateThemes(colorSelected, useMaterial3, useLightMode);
|
themeData = updateThemes(colorSelected.color, useMaterial3, useLightMode);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleColorSelect(int value) {
|
void handleColorSelect(int value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
colorSelected = value;
|
colorSelected = ColorSeed.values[value];
|
||||||
themeData = updateThemes(colorSelected, useMaterial3, useLightMode);
|
themeData = updateThemes(colorSelected.color, useMaterial3, useLightMode);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +160,15 @@ class _Material3DemoState extends State<Material3Demo> {
|
|||||||
ScreenSelected screenSelected, bool showNavBarExample) {
|
ScreenSelected screenSelected, bool showNavBarExample) {
|
||||||
switch (screenSelected) {
|
switch (screenSelected) {
|
||||||
case ScreenSelected.component:
|
case ScreenSelected.component:
|
||||||
return ComponentScreen(showNavBottomBar: showNavBarExample);
|
return Expanded(
|
||||||
|
child: OneTwoTransition(
|
||||||
|
animation: railAnimation,
|
||||||
|
one: FirstComponentList(
|
||||||
|
showNavBottomBar: showNavBarExample,
|
||||||
|
scaffoldKey: scaffoldKey,
|
||||||
|
showSecondList:
|
||||||
|
showMediumSizeLayout || showLargeSizeLayout),
|
||||||
|
two: const SecondComponentList()));
|
||||||
case ScreenSelected.color:
|
case ScreenSelected.color:
|
||||||
return const ColorPalettesScreen();
|
return const ColorPalettesScreen();
|
||||||
case ScreenSelected.typography:
|
case ScreenSelected.typography:
|
||||||
@@ -113,62 +176,140 @@ class _Material3DemoState extends State<Material3Demo> {
|
|||||||
case ScreenSelected.elevation:
|
case ScreenSelected.elevation:
|
||||||
return const ElevationScreen();
|
return const ElevationScreen();
|
||||||
default:
|
default:
|
||||||
return ComponentScreen(showNavBottomBar: showNavBarExample);
|
return FirstComponentList(
|
||||||
|
showNavBottomBar: showNavBarExample,
|
||||||
|
scaffoldKey: scaffoldKey,
|
||||||
|
showSecondList: showMediumSizeLayout || showLargeSizeLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PreferredSizeWidget createAppBar() {
|
Widget brightnessButton({bool showTooltipBelow = true}) => Tooltip(
|
||||||
return AppBar(
|
preferBelow: showTooltipBelow,
|
||||||
title: useMaterial3 ? const Text('Material 3') : const Text('Material 2'),
|
message: 'Toggle brightness',
|
||||||
actions: [
|
child: IconButton(
|
||||||
IconButton(
|
|
||||||
icon: useLightMode
|
icon: useLightMode
|
||||||
? const Icon(Icons.wb_sunny_outlined)
|
? const Icon(Icons.wb_sunny_outlined)
|
||||||
: const Icon(Icons.wb_sunny),
|
: const Icon(Icons.wb_sunny),
|
||||||
onPressed: handleBrightnessChange,
|
onPressed: handleBrightnessChange,
|
||||||
tooltip: 'Toggle brightness',
|
|
||||||
),
|
),
|
||||||
IconButton(
|
);
|
||||||
|
|
||||||
|
Widget material3Button({bool showTooltipBelow = true}) => Tooltip(
|
||||||
|
preferBelow: showTooltipBelow,
|
||||||
|
message: 'Switch to Material ${useMaterial3 ? 2 : 3}',
|
||||||
|
child: IconButton(
|
||||||
icon: useMaterial3
|
icon: useMaterial3
|
||||||
? const Icon(Icons.filter_3)
|
? const Icon(Icons.filter_3)
|
||||||
: const Icon(Icons.filter_2),
|
: const Icon(Icons.filter_2),
|
||||||
onPressed: handleMaterialVersionChange,
|
onPressed: handleMaterialVersionChange,
|
||||||
tooltip: 'Switch to Material ${useMaterial3 ? 2 : 3}',
|
|
||||||
),
|
),
|
||||||
PopupMenuButton(
|
);
|
||||||
icon: const Icon(Icons.more_vert),
|
|
||||||
shape:
|
Widget colorSeedButton(Icon icon) => PopupMenuButton(
|
||||||
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
icon: icon,
|
||||||
itemBuilder: (context) {
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
||||||
return List.generate(colorOptions.length, (index) {
|
itemBuilder: (context) {
|
||||||
return PopupMenuItem(
|
return List.generate(ColorSeed.values.length, (index) {
|
||||||
value: index,
|
ColorSeed currentColor = ColorSeed.values[index];
|
||||||
child: Wrap(
|
|
||||||
children: [
|
return PopupMenuItem(
|
||||||
Padding(
|
value: index,
|
||||||
padding: const EdgeInsets.only(left: 10),
|
child: Wrap(
|
||||||
child: Icon(
|
children: [
|
||||||
index == colorSelected
|
Padding(
|
||||||
? Icons.color_lens
|
padding: const EdgeInsets.only(left: 10),
|
||||||
: Icons.color_lens_outlined,
|
child: Icon(
|
||||||
color: colorOptions[index],
|
currentColor == colorSelected
|
||||||
),
|
? Icons.color_lens
|
||||||
|
: Icons.color_lens_outlined,
|
||||||
|
color: currentColor.color,
|
||||||
),
|
),
|
||||||
Padding(
|
),
|
||||||
padding: const EdgeInsets.only(left: 20),
|
Padding(
|
||||||
child: Text(colorText[index]),
|
padding: const EdgeInsets.only(left: 20),
|
||||||
),
|
child: Text(currentColor.label),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
);
|
),
|
||||||
});
|
);
|
||||||
},
|
});
|
||||||
onSelected: handleColorSelect,
|
},
|
||||||
),
|
onSelected: handleColorSelect,
|
||||||
],
|
);
|
||||||
|
|
||||||
|
PreferredSizeWidget createAppBar() {
|
||||||
|
return AppBar(
|
||||||
|
title: useMaterial3 ? const Text('Material 3') : const Text('Material 2'),
|
||||||
|
actions: !showMediumSizeLayout && !showLargeSizeLayout
|
||||||
|
? [
|
||||||
|
brightnessButton(),
|
||||||
|
material3Button(),
|
||||||
|
colorSeedButton(const Icon(Icons.more_vert)),
|
||||||
|
]
|
||||||
|
: [Container()],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _expandedTrailingActions() => Container(
|
||||||
|
constraints: const BoxConstraints.tightFor(width: 250),
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 30),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Text('Brightness'),
|
||||||
|
Expanded(child: Container()),
|
||||||
|
Switch(
|
||||||
|
value: useLightMode,
|
||||||
|
onChanged: (_) {
|
||||||
|
handleBrightnessChange();
|
||||||
|
})
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
useMaterial3
|
||||||
|
? const Text('Material 3')
|
||||||
|
: const Text('Material 2'),
|
||||||
|
Expanded(child: Container()),
|
||||||
|
Switch(
|
||||||
|
value: useMaterial3,
|
||||||
|
onChanged: (_) {
|
||||||
|
handleMaterialVersionChange();
|
||||||
|
})
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(maxHeight: 200.0),
|
||||||
|
child: GridView.count(
|
||||||
|
crossAxisCount: 3,
|
||||||
|
children: List.generate(
|
||||||
|
ColorSeed.values.length,
|
||||||
|
(i) => IconButton(
|
||||||
|
icon: const Icon(Icons.circle),
|
||||||
|
color: ColorSeed.values[i].color,
|
||||||
|
onPressed: () {
|
||||||
|
handleColorSelect(i);
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget _trailingActions() => Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Flexible(child: brightnessButton(showTooltipBelow: false)),
|
||||||
|
Flexible(child: material3Button(showTooltipBelow: false)),
|
||||||
|
Flexible(child: colorSeedButton(const Icon(Icons.more_horiz))),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
@@ -176,40 +317,337 @@ class _Material3DemoState extends State<Material3Demo> {
|
|||||||
title: 'Material 3',
|
title: 'Material 3',
|
||||||
themeMode: useLightMode ? ThemeMode.light : ThemeMode.dark,
|
themeMode: useLightMode ? ThemeMode.light : ThemeMode.dark,
|
||||||
theme: themeData,
|
theme: themeData,
|
||||||
home: LayoutBuilder(builder: (context, constraints) {
|
home: AnimatedBuilder(
|
||||||
if (constraints.maxWidth < narrowScreenWidthThreshold) {
|
animation: controller,
|
||||||
return Scaffold(
|
builder: (context, child) {
|
||||||
appBar: createAppBar(),
|
return NavigationTransition(
|
||||||
body: Row(children: <Widget>[
|
scaffoldKey: scaffoldKey,
|
||||||
createScreenFor(ScreenSelected.values[screenIndex], false),
|
animationController: controller,
|
||||||
]),
|
railAnimation: railAnimation,
|
||||||
bottomNavigationBar: NavigationBars(
|
appBar: createAppBar(),
|
||||||
onSelectItem: handleScreenChanged,
|
body: createScreenFor(
|
||||||
selectedIndex: screenIndex,
|
ScreenSelected.values[screenIndex], controller.value == 1),
|
||||||
isExampleBar: false,
|
navigationRail: NavigationRail(
|
||||||
),
|
extended: showLargeSizeLayout,
|
||||||
);
|
destinations: navRailDestinations,
|
||||||
} else {
|
selectedIndex: screenIndex,
|
||||||
return Scaffold(
|
onDestinationSelected: (index) {
|
||||||
appBar: createAppBar(),
|
setState(() {
|
||||||
body: SafeArea(
|
screenIndex = index;
|
||||||
bottom: false,
|
handleScreenChanged(screenIndex);
|
||||||
top: false,
|
});
|
||||||
child: Row(
|
},
|
||||||
children: <Widget>[
|
trailing: Expanded(
|
||||||
Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 5),
|
padding: const EdgeInsets.only(bottom: 20),
|
||||||
child: NavigationRailSection(
|
child: showLargeSizeLayout
|
||||||
onSelectItem: handleScreenChanged,
|
? _expandedTrailingActions()
|
||||||
selectedIndex: screenIndex)),
|
: _trailingActions(),
|
||||||
const VerticalDivider(thickness: 1, width: 1),
|
),
|
||||||
createScreenFor(ScreenSelected.values[screenIndex], true),
|
),
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
navigationBar: NavigationBars(
|
||||||
);
|
onSelectItem: (index) {
|
||||||
}
|
setState(() {
|
||||||
}),
|
screenIndex = index;
|
||||||
|
handleScreenChanged(screenIndex);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
selectedIndex: screenIndex,
|
||||||
|
isExampleBar: false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NavigationTransition extends StatefulWidget {
|
||||||
|
const NavigationTransition(
|
||||||
|
{super.key,
|
||||||
|
required this.scaffoldKey,
|
||||||
|
required this.animationController,
|
||||||
|
required this.railAnimation,
|
||||||
|
required this.navigationRail,
|
||||||
|
required this.navigationBar,
|
||||||
|
required this.appBar,
|
||||||
|
required this.body});
|
||||||
|
|
||||||
|
final GlobalKey<ScaffoldState> scaffoldKey;
|
||||||
|
final AnimationController animationController;
|
||||||
|
final CurvedAnimation railAnimation;
|
||||||
|
final Widget navigationRail;
|
||||||
|
final Widget navigationBar;
|
||||||
|
final PreferredSizeWidget appBar;
|
||||||
|
final Widget body;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<NavigationTransition> createState() => _NavigationTransitionState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NavigationTransitionState extends State<NavigationTransition> {
|
||||||
|
late final AnimationController controller;
|
||||||
|
late final CurvedAnimation railAnimation;
|
||||||
|
late final ReverseAnimation barAnimation;
|
||||||
|
bool controllerInitialized = false;
|
||||||
|
bool showDivider = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
controller = widget.animationController;
|
||||||
|
railAnimation = widget.railAnimation;
|
||||||
|
|
||||||
|
barAnimation = ReverseAnimation(
|
||||||
|
CurvedAnimation(
|
||||||
|
parent: controller,
|
||||||
|
curve: const Interval(0.0, 0.5),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final ColorScheme colorScheme = Theme.of(context).colorScheme;
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
key: widget.scaffoldKey,
|
||||||
|
appBar: widget.appBar,
|
||||||
|
body: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
RailTransition(
|
||||||
|
animation: railAnimation,
|
||||||
|
backgroundColor: colorScheme.surface,
|
||||||
|
child: widget.navigationRail,
|
||||||
|
),
|
||||||
|
railAnimation.isDismissed
|
||||||
|
? const SizedBox()
|
||||||
|
: const VerticalDivider(width: 1),
|
||||||
|
widget.body,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
bottomNavigationBar: BarTransition(
|
||||||
|
animation: barAnimation,
|
||||||
|
backgroundColor: colorScheme.surface,
|
||||||
|
child: widget.navigationBar,
|
||||||
|
),
|
||||||
|
endDrawer: const NavigationDrawerSection(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<NavigationRailDestination> navRailDestinations = appBarDestinations
|
||||||
|
.map(
|
||||||
|
(destination) => NavigationRailDestination(
|
||||||
|
icon: Tooltip(
|
||||||
|
message: destination.label,
|
||||||
|
child: destination.icon,
|
||||||
|
),
|
||||||
|
selectedIcon: Tooltip(
|
||||||
|
message: destination.label,
|
||||||
|
child: destination.selectedIcon,
|
||||||
|
),
|
||||||
|
label: Text(destination.label),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
class SizeAnimation extends CurvedAnimation {
|
||||||
|
SizeAnimation(Animation<double> parent)
|
||||||
|
: super(
|
||||||
|
parent: parent,
|
||||||
|
curve: const Interval(
|
||||||
|
0.2,
|
||||||
|
0.8,
|
||||||
|
curve: Curves.easeInOutCubicEmphasized,
|
||||||
|
),
|
||||||
|
reverseCurve: Interval(
|
||||||
|
0,
|
||||||
|
0.2,
|
||||||
|
curve: Curves.easeInOutCubicEmphasized.flipped,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class OffsetAnimation extends CurvedAnimation {
|
||||||
|
OffsetAnimation(Animation<double> parent)
|
||||||
|
: super(
|
||||||
|
parent: parent,
|
||||||
|
curve: const Interval(
|
||||||
|
0.4,
|
||||||
|
1.0,
|
||||||
|
curve: Curves.easeInOutCubicEmphasized,
|
||||||
|
),
|
||||||
|
reverseCurve: Interval(
|
||||||
|
0,
|
||||||
|
0.2,
|
||||||
|
curve: Curves.easeInOutCubicEmphasized.flipped,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class RailTransition extends StatefulWidget {
|
||||||
|
const RailTransition(
|
||||||
|
{super.key,
|
||||||
|
required this.animation,
|
||||||
|
required this.backgroundColor,
|
||||||
|
required this.child});
|
||||||
|
|
||||||
|
final Animation<double> animation;
|
||||||
|
final Widget child;
|
||||||
|
final Color backgroundColor;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<RailTransition> createState() => _RailTransition();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RailTransition extends State<RailTransition> {
|
||||||
|
late Animation<Offset> offsetAnimation;
|
||||||
|
late Animation<double> widthAnimation;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
|
||||||
|
// The animations are only rebuilt by this method when the text
|
||||||
|
// direction changes because this widget only depends on Directionality.
|
||||||
|
final bool ltr = Directionality.of(context) == TextDirection.ltr;
|
||||||
|
|
||||||
|
widthAnimation = Tween<double>(
|
||||||
|
begin: 0,
|
||||||
|
end: 1,
|
||||||
|
).animate(SizeAnimation(widget.animation));
|
||||||
|
|
||||||
|
offsetAnimation = Tween<Offset>(
|
||||||
|
begin: ltr ? const Offset(-1, 0) : const Offset(1, 0),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(OffsetAnimation(widget.animation));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ClipRect(
|
||||||
|
child: DecoratedBox(
|
||||||
|
decoration: BoxDecoration(color: widget.backgroundColor),
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
widthFactor: widthAnimation.value,
|
||||||
|
child: FractionalTranslation(
|
||||||
|
translation: offsetAnimation.value,
|
||||||
|
child: widget.child,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BarTransition extends StatefulWidget {
|
||||||
|
const BarTransition(
|
||||||
|
{super.key,
|
||||||
|
required this.animation,
|
||||||
|
required this.backgroundColor,
|
||||||
|
required this.child});
|
||||||
|
|
||||||
|
final Animation<double> animation;
|
||||||
|
final Color backgroundColor;
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<BarTransition> createState() => _BarTransition();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BarTransition extends State<BarTransition> {
|
||||||
|
late final Animation<Offset> offsetAnimation;
|
||||||
|
late final Animation<double> heightAnimation;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
offsetAnimation = Tween<Offset>(
|
||||||
|
begin: const Offset(0, 1),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(OffsetAnimation(widget.animation));
|
||||||
|
|
||||||
|
heightAnimation = Tween<double>(
|
||||||
|
begin: 0,
|
||||||
|
end: 1,
|
||||||
|
).animate(SizeAnimation(widget.animation));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ClipRect(
|
||||||
|
child: DecoratedBox(
|
||||||
|
decoration: BoxDecoration(color: widget.backgroundColor),
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
heightFactor: heightAnimation.value,
|
||||||
|
child: FractionalTranslation(
|
||||||
|
translation: offsetAnimation.value,
|
||||||
|
child: widget.child,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class OneTwoTransition extends StatefulWidget {
|
||||||
|
const OneTwoTransition({
|
||||||
|
super.key,
|
||||||
|
required this.animation,
|
||||||
|
required this.one,
|
||||||
|
required this.two,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Animation<double> animation;
|
||||||
|
final Widget one;
|
||||||
|
final Widget two;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<OneTwoTransition> createState() => _OneTwoTransitionState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _OneTwoTransitionState extends State<OneTwoTransition> {
|
||||||
|
late final Animation<Offset> offsetAnimation;
|
||||||
|
late final Animation<double> widthAnimation;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
offsetAnimation = Tween<Offset>(
|
||||||
|
begin: const Offset(1, 0),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(OffsetAnimation(widget.animation));
|
||||||
|
|
||||||
|
widthAnimation = Tween<double>(
|
||||||
|
begin: 0,
|
||||||
|
end: 1000,
|
||||||
|
).animate(SizeAnimation(widget.animation));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Flexible(
|
||||||
|
flex: 1000,
|
||||||
|
child: widget.one,
|
||||||
|
),
|
||||||
|
if (widthAnimation.value.toInt() > 0) ...[
|
||||||
|
Flexible(
|
||||||
|
flex: widthAnimation.value.toInt(),
|
||||||
|
child: FractionalTranslation(
|
||||||
|
translation: offsetAnimation.value,
|
||||||
|
child: widget.two,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -345,7 +345,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
@@ -424,7 +424,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
@@ -471,7 +471,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
|
|||||||
@@ -16,17 +16,25 @@ void main() {
|
|||||||
'on NavigationBar', (tester) async {
|
'on NavigationBar', (tester) async {
|
||||||
widgetSetup(tester, 449);
|
widgetSetup(tester, 449);
|
||||||
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
|
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
|
||||||
await tester.pumpWidget(const Material3Demo());
|
await tester.pumpWidget(const MaterialApp(home: Material3Demo()));
|
||||||
|
|
||||||
expect(find.text('Light Theme'), findsNothing);
|
expect(find.text('Light Theme'), findsNothing);
|
||||||
expect(find.text('Dark Theme'), findsNothing);
|
expect(find.text('Dark Theme'), findsNothing);
|
||||||
expect(find.byType(NavigationBar), findsOneWidget);
|
expect(find.byType(NavigationBar), findsOneWidget);
|
||||||
Finder colorIconOnBar = find.byIcon(Icons.format_paint_outlined);
|
Finder colorIconOnBar = find.descendant(
|
||||||
|
of: find.byType(NavigationBar),
|
||||||
|
matching: find.widgetWithIcon(
|
||||||
|
NavigationDestination, Icons.format_paint_outlined));
|
||||||
expect(colorIconOnBar, findsOneWidget);
|
expect(colorIconOnBar, findsOneWidget);
|
||||||
await tester.tap(colorIconOnBar);
|
await tester.tap(colorIconOnBar);
|
||||||
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
||||||
expect(colorIconOnBar, findsNothing);
|
expect(colorIconOnBar, findsNothing);
|
||||||
expect(find.byIcon(Icons.format_paint), findsOneWidget);
|
|
||||||
|
Finder selectedColorIconOnBar = find.descendant(
|
||||||
|
of: find.byType(NavigationBar),
|
||||||
|
matching:
|
||||||
|
find.widgetWithIcon(NavigationDestination, Icons.format_paint));
|
||||||
|
expect(selectedColorIconOnBar, findsOneWidget);
|
||||||
expect(find.text('Light Theme'), findsOneWidget);
|
expect(find.text('Light Theme'), findsOneWidget);
|
||||||
expect(find.text('Dark Theme'), findsOneWidget);
|
expect(find.text('Dark Theme'), findsOneWidget);
|
||||||
});
|
});
|
||||||
@@ -34,18 +42,25 @@ void main() {
|
|||||||
testWidgets(
|
testWidgets(
|
||||||
'Color palettes screen shows correctly when color icon is clicked '
|
'Color palettes screen shows correctly when color icon is clicked '
|
||||||
'on NavigationRail', (tester) async {
|
'on NavigationRail', (tester) async {
|
||||||
widgetSetup(tester, 450); // NavigationRail shows only when width is >= 450.
|
widgetSetup(
|
||||||
|
tester, 1200); // NavigationRail shows only when width is > 1000.
|
||||||
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
|
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
|
||||||
await tester.pumpWidget(const Material3Demo());
|
await tester.pumpWidget(const MaterialApp(home: Material3Demo()));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
expect(find.text('Light Theme'), findsNothing);
|
expect(find.text('Light Theme'), findsNothing);
|
||||||
expect(find.text('Dark Theme'), findsNothing);
|
expect(find.text('Dark Theme'), findsNothing);
|
||||||
expect(find.byType(NavigationRail), findsOneWidget);
|
expect(find.byType(NavigationRail), findsOneWidget);
|
||||||
Finder colorIconOnRail = find.byIcon(Icons.format_paint_outlined);
|
Finder colorIconOnRail = find.descendant(
|
||||||
|
of: find.byType(NavigationRail),
|
||||||
|
matching: find.byIcon(Icons.format_paint_outlined));
|
||||||
expect(colorIconOnRail, findsOneWidget);
|
expect(colorIconOnRail, findsOneWidget);
|
||||||
await tester.tap(colorIconOnRail);
|
await tester.tap(colorIconOnRail);
|
||||||
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
||||||
expect(colorIconOnRail, findsNothing);
|
expect(colorIconOnRail, findsNothing);
|
||||||
expect(find.byIcon(Icons.format_paint), findsOneWidget);
|
Finder selectedColorIconOnRail = find.descendant(
|
||||||
|
of: find.byType(NavigationRail),
|
||||||
|
matching: find.byIcon(Icons.format_paint));
|
||||||
|
expect(selectedColorIconOnRail, findsOneWidget);
|
||||||
expect(find.text('Light Theme'), findsOneWidget);
|
expect(find.text('Light Theme'), findsOneWidget);
|
||||||
expect(find.text('Dark Theme'), findsOneWidget);
|
expect(find.text('Dark Theme'), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,15 +10,15 @@ import 'package:material_3_demo/main.dart';
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('Default main page shows all M3 components', (tester) async {
|
testWidgets('Default main page shows all M3 components', (tester) async {
|
||||||
widgetSetup(tester, 800, windowHeight: 3500);
|
widgetSetup(tester, 800, windowHeight: 7000);
|
||||||
await tester.pumpWidget(const Material3Demo());
|
await tester.pumpWidget(const MaterialApp(home: Material3Demo()));
|
||||||
|
|
||||||
// Elements on the app bar
|
// Elements on the app bar
|
||||||
expect(find.text('Material 3'), findsOneWidget);
|
expect(find.text('Material 3'), findsOneWidget);
|
||||||
expect(find.widgetWithIcon(IconButton, Icons.wb_sunny_outlined),
|
expect(
|
||||||
findsOneWidget);
|
find.widgetWithIcon(AppBar, Icons.wb_sunny_outlined), findsOneWidget);
|
||||||
expect(find.widgetWithIcon(IconButton, Icons.filter_3), findsOneWidget);
|
expect(find.widgetWithIcon(AppBar, Icons.filter_3), findsOneWidget);
|
||||||
expect(find.widgetWithIcon(IconButton, Icons.more_vert), findsOneWidget);
|
expect(find.widgetWithIcon(AppBar, Icons.more_vert), findsOneWidget);
|
||||||
|
|
||||||
// Elements on the component screen
|
// Elements on the component screen
|
||||||
// Buttons
|
// Buttons
|
||||||
@@ -27,13 +27,14 @@ void main() {
|
|||||||
expect(find.widgetWithText(FilledButton, 'Filled Tonal'), findsNWidgets(2));
|
expect(find.widgetWithText(FilledButton, 'Filled Tonal'), findsNWidgets(2));
|
||||||
expect(find.widgetWithText(OutlinedButton, 'Outlined'), findsNWidgets(2));
|
expect(find.widgetWithText(OutlinedButton, 'Outlined'), findsNWidgets(2));
|
||||||
expect(find.widgetWithText(TextButton, 'Text'), findsNWidgets(2));
|
expect(find.widgetWithText(TextButton, 'Text'), findsNWidgets(2));
|
||||||
expect(find.text('Icon'), findsNWidgets(5));
|
expect(find.widgetWithText(Buttons, 'Icon'), findsNWidgets(5));
|
||||||
|
|
||||||
// IconButtons
|
// IconButtons
|
||||||
expect(find.byType(IconToggleButton), findsNWidgets(8));
|
expect(find.byType(IconToggleButton), findsNWidgets(8));
|
||||||
|
|
||||||
// FABs
|
// FABs
|
||||||
expect(find.byType(FloatingActionButton), findsNWidgets(4));
|
expect(find.byType(FloatingActionButton),
|
||||||
|
findsNWidgets(6)); // 2 more shows up in the bottom app bar.
|
||||||
expect(find.widgetWithText(FloatingActionButton, 'Create'), findsOneWidget);
|
expect(find.widgetWithText(FloatingActionButton, 'Create'), findsOneWidget);
|
||||||
|
|
||||||
// Chips
|
// Chips
|
||||||
@@ -43,9 +44,9 @@ void main() {
|
|||||||
expect(find.byType(InputChip), findsNWidgets(4));
|
expect(find.byType(InputChip), findsNWidgets(4));
|
||||||
|
|
||||||
// Cards
|
// Cards
|
||||||
expect(find.widgetWithText(Card, 'Filled'), findsOneWidget);
|
expect(find.widgetWithText(Cards, 'Elevated'), findsOneWidget);
|
||||||
expect(find.widgetWithText(Card, 'Filled'), findsOneWidget);
|
expect(find.widgetWithText(Cards, 'Filled'), findsOneWidget);
|
||||||
expect(find.widgetWithText(Card, 'Outlined'), findsOneWidget);
|
expect(find.widgetWithText(Cards, 'Outlined'), findsOneWidget);
|
||||||
|
|
||||||
// TextFields
|
// TextFields
|
||||||
expect(find.widgetWithText(TextField, 'Disabled'), findsNWidgets(2));
|
expect(find.widgetWithText(TextField, 'Disabled'), findsNWidgets(2));
|
||||||
@@ -76,68 +77,57 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'NavigationRail doesn\'t show when width value is small than 450 '
|
'NavigationRail doesn\'t show when width value is small than 1000 '
|
||||||
'(in Portrait mode or narrow screen)', (tester) async {
|
'(in Portrait mode or narrow screen)', (tester) async {
|
||||||
widgetSetup(tester, 449);
|
widgetSetup(tester, 999, windowHeight: 7000);
|
||||||
await tester.pumpWidget(const Material3Demo());
|
await tester.pumpWidget(const MaterialApp(home: Material3Demo()));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
// When screen width is less than 450, NavigationBar will show. At the same
|
// When screen width is less than 1000, NavigationBar will show. At the same
|
||||||
// time, the NavigationRail and the NavigationBar example will NOT show.
|
// time, the NavigationBar example still show up in the navigation group.
|
||||||
expect(find.byType(NavigationBars), findsOneWidget);
|
expect(find.byType(NavigationBars),
|
||||||
|
findsNWidgets(3)); // The real navBar, badges example and navBar example
|
||||||
expect(find.widgetWithText(NavigationBar, 'Components'), findsOneWidget);
|
expect(find.widgetWithText(NavigationBar, 'Components'), findsOneWidget);
|
||||||
expect(find.widgetWithText(NavigationBar, 'Color'), findsOneWidget);
|
expect(find.widgetWithText(NavigationBar, 'Color'), findsOneWidget);
|
||||||
expect(find.widgetWithText(NavigationBar, 'Typography'), findsOneWidget);
|
expect(find.widgetWithText(NavigationBar, 'Typography'), findsOneWidget);
|
||||||
expect(find.widgetWithText(NavigationBar, 'Elevation'), findsOneWidget);
|
expect(find.widgetWithText(NavigationBar, 'Elevation'), findsOneWidget);
|
||||||
|
|
||||||
expect(find.byType(NavigationRailSection), findsNothing);
|
expect(find.widgetWithText(NavigationBar, 'Explore'), findsOneWidget);
|
||||||
expect(find.widgetWithText(NavigationBar, 'Explore'), findsNothing);
|
expect(find.widgetWithText(NavigationBar, 'Pets'), findsOneWidget);
|
||||||
expect(find.widgetWithText(NavigationBar, 'Pets'), findsNothing);
|
expect(find.widgetWithText(NavigationBar, 'Account'), findsOneWidget);
|
||||||
expect(find.widgetWithText(NavigationBar, 'Account'), findsNothing);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'NavigationRail shows when width value is greater than or equal '
|
'NavigationRail shows when width value is greater than or equal '
|
||||||
'to 450 (in Landscape mode or wider screen)', (tester) async {
|
'to 1000 (in Landscape mode or wider screen)', (tester) async {
|
||||||
widgetSetup(tester, 450);
|
widgetSetup(tester, 1001, windowHeight: 3000);
|
||||||
await tester.pumpWidget(const Material3Demo());
|
await tester.pumpWidget(const MaterialApp(home: Material3Demo()));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
// When screen width is greater than or equal to 450, NavigationRail and
|
// When screen width is greater than or equal to 1000, NavigationRail will show.
|
||||||
// NavigationBar example will show. At the same time, the NavigationBar
|
// At the same time, the NavigationBar will NOT show.
|
||||||
// will NOT show.
|
expect(find.byType(NavigationRail), findsOneWidget);
|
||||||
expect(find.byType(NavigationRailSection), findsOneWidget);
|
|
||||||
expect(find.byType(Tooltip, skipOffstage: false), findsWidgets);
|
expect(find.byType(Tooltip, skipOffstage: false), findsWidgets);
|
||||||
expect(find.widgetWithText(NavigationRailSection, 'Components'),
|
expect(find.widgetWithText(NavigationRail, 'Components'), findsOneWidget);
|
||||||
findsOneWidget);
|
expect(find.widgetWithText(NavigationRail, 'Color'), findsOneWidget);
|
||||||
expect(find.widgetWithText(NavigationRailSection, 'Color'), findsOneWidget);
|
expect(find.widgetWithText(NavigationRail, 'Typography'), findsOneWidget);
|
||||||
expect(find.widgetWithText(NavigationRailSection, 'Typography'),
|
expect(find.widgetWithText(NavigationRail, 'Elevation'), findsOneWidget);
|
||||||
findsOneWidget);
|
|
||||||
expect(find.widgetWithText(NavigationRailSection, 'Elevation'),
|
|
||||||
findsOneWidget);
|
|
||||||
|
|
||||||
final navbarExample = find.byType(NavigationBars);
|
|
||||||
await tester.scrollUntilVisible(
|
|
||||||
scrollable: find.byType(Scrollable).first,
|
|
||||||
navbarExample,
|
|
||||||
500.0,
|
|
||||||
);
|
|
||||||
expect(find.byType(NavigationBars), findsOneWidget);
|
|
||||||
expect(find.widgetWithText(NavigationBar, 'Explore'), findsOneWidget);
|
expect(find.widgetWithText(NavigationBar, 'Explore'), findsOneWidget);
|
||||||
expect(find.widgetWithText(NavigationBar, 'Pets'), findsOneWidget);
|
expect(find.widgetWithText(NavigationBar, 'Pets'), findsOneWidget);
|
||||||
expect(find.widgetWithText(NavigationBar, 'Account'), findsOneWidget);
|
expect(find.widgetWithText(NavigationBar, 'Account'), findsOneWidget);
|
||||||
|
|
||||||
expect(find.widgetWithText(NavigationBar, 'Components'), findsNothing);
|
// the Navigation bar should be out of screen.
|
||||||
expect(find.widgetWithText(NavigationBar, 'Colors'), findsNothing);
|
final RenderBox box =
|
||||||
expect(find.widgetWithText(NavigationBar, 'Typography'), findsNothing);
|
tester.renderObject(find.widgetWithText(NavigationBar, 'Components'));
|
||||||
expect(find.widgetWithText(NavigationBar, 'Elevation'), findsNothing);
|
expect(box.localToGlobal(Offset.zero), const Offset(0.0, 3080.0));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'Material version switches between Material3 and Material2 when'
|
'Material version switches between Material3 and Material2 when'
|
||||||
'the version icon is clicked', (tester) async {
|
'the version icon is clicked', (tester) async {
|
||||||
widgetSetup(tester, 450, windowHeight: 3000);
|
widgetSetup(tester, 450, windowHeight: 7000);
|
||||||
await tester.pumpWidget(const Material3Demo());
|
await tester.pumpWidget(const MaterialApp(home: Material3Demo()));
|
||||||
Finder m3Icon = find.widgetWithIcon(IconButton, Icons.filter_3);
|
|
||||||
Finder m2Icon = find.widgetWithIcon(IconButton, Icons.filter_2);
|
|
||||||
BuildContext defaultElevatedButton =
|
BuildContext defaultElevatedButton =
|
||||||
tester.firstElement(find.byType(ElevatedButton));
|
tester.firstElement(find.byType(ElevatedButton));
|
||||||
BuildContext defaultIconButton =
|
BuildContext defaultIconButton =
|
||||||
@@ -157,8 +147,8 @@ void main() {
|
|||||||
await tester.tap(dismiss);
|
await tester.tap(dismiss);
|
||||||
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
||||||
|
|
||||||
expect(m3Icon, findsOneWidget);
|
expect(find.widgetWithIcon(AppBar, Icons.filter_3), findsOneWidget);
|
||||||
expect(m2Icon, findsNothing);
|
expect(find.widgetWithIcon(AppBar, Icons.filter_2), findsNothing);
|
||||||
expect(find.text('Material 3'), findsOneWidget);
|
expect(find.text('Material 3'), findsOneWidget);
|
||||||
expect(Theme.of(defaultElevatedButton).useMaterial3, true);
|
expect(Theme.of(defaultElevatedButton).useMaterial3, true);
|
||||||
expect(Theme.of(defaultIconButton).useMaterial3, true);
|
expect(Theme.of(defaultIconButton).useMaterial3, true);
|
||||||
@@ -166,7 +156,10 @@ void main() {
|
|||||||
expect(Theme.of(defaultCard).useMaterial3, true);
|
expect(Theme.of(defaultCard).useMaterial3, true);
|
||||||
expect(Theme.of(defaultChip).useMaterial3, true);
|
expect(Theme.of(defaultChip).useMaterial3, true);
|
||||||
|
|
||||||
await tester.tap(m3Icon);
|
Finder appbarM3Icon = find.descendant(
|
||||||
|
of: find.byType(AppBar),
|
||||||
|
matching: find.widgetWithIcon(IconButton, Icons.filter_3));
|
||||||
|
await tester.tap(appbarM3Icon);
|
||||||
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
||||||
BuildContext updatedElevatedButton =
|
BuildContext updatedElevatedButton =
|
||||||
tester.firstElement(find.byType(ElevatedButton));
|
tester.firstElement(find.byType(ElevatedButton));
|
||||||
@@ -187,8 +180,8 @@ void main() {
|
|||||||
await tester.tap(updatedDismiss);
|
await tester.tap(updatedDismiss);
|
||||||
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
||||||
|
|
||||||
expect(m3Icon, findsNothing);
|
expect(find.widgetWithIcon(AppBar, Icons.filter_2), findsOneWidget);
|
||||||
expect(m2Icon, findsOneWidget);
|
expect(find.widgetWithIcon(AppBar, Icons.filter_3), findsNothing);
|
||||||
expect(find.text('Material 2'), findsOneWidget);
|
expect(find.text('Material 2'), findsOneWidget);
|
||||||
expect(Theme.of(updatedElevatedButton).useMaterial3, false);
|
expect(Theme.of(updatedElevatedButton).useMaterial3, false);
|
||||||
expect(Theme.of(updatedIconButton).useMaterial3, false);
|
expect(Theme.of(updatedIconButton).useMaterial3, false);
|
||||||
@@ -200,17 +193,32 @@ void main() {
|
|||||||
testWidgets(
|
testWidgets(
|
||||||
'Other screens become Material2 mode after changing mode from '
|
'Other screens become Material2 mode after changing mode from '
|
||||||
'main screen', (tester) async {
|
'main screen', (tester) async {
|
||||||
await tester.pumpWidget(const Material3Demo());
|
await tester.pumpWidget(const MaterialApp(home: Material3Demo()));
|
||||||
await tester.tap(find.widgetWithIcon(IconButton, Icons.filter_3));
|
Finder appbarM3Icon = find.descendant(
|
||||||
await tester.tap(find.byIcon(Icons.format_paint_outlined));
|
of: find.byType(AppBar),
|
||||||
|
matching: find.widgetWithIcon(IconButton, Icons.filter_3));
|
||||||
|
await tester.tap(appbarM3Icon);
|
||||||
|
Finder secondScreenIcon = find.descendant(
|
||||||
|
of: find.byType(NavigationBar),
|
||||||
|
matching: find.widgetWithIcon(
|
||||||
|
NavigationDestination, Icons.format_paint_outlined));
|
||||||
|
await tester.tap(secondScreenIcon);
|
||||||
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
||||||
BuildContext lightThemeText = tester.element(find.text('Light Theme'));
|
BuildContext lightThemeText = tester.element(find.text('Light Theme'));
|
||||||
expect(Theme.of(lightThemeText).useMaterial3, false);
|
expect(Theme.of(lightThemeText).useMaterial3, false);
|
||||||
await tester.tap(find.byIcon(Icons.text_snippet_outlined));
|
Finder thirdScreenIcon = find.descendant(
|
||||||
|
of: find.byType(NavigationBar),
|
||||||
|
matching: find.widgetWithIcon(
|
||||||
|
NavigationDestination, Icons.text_snippet_outlined));
|
||||||
|
await tester.tap(thirdScreenIcon);
|
||||||
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
||||||
BuildContext displayLargeText = tester.element(find.text('Display Large'));
|
BuildContext displayLargeText = tester.element(find.text('Display Large'));
|
||||||
expect(Theme.of(displayLargeText).useMaterial3, false);
|
expect(Theme.of(displayLargeText).useMaterial3, false);
|
||||||
await tester.tap(find.byIcon(Icons.invert_colors_on_outlined));
|
Finder fourthScreenIcon = find.descendant(
|
||||||
|
of: find.byType(NavigationBar),
|
||||||
|
matching: find.widgetWithIcon(
|
||||||
|
NavigationDestination, Icons.invert_colors_on_outlined));
|
||||||
|
await tester.tap(fourthScreenIcon);
|
||||||
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
||||||
BuildContext material = tester.firstElement(find.byType(Material));
|
BuildContext material = tester.firstElement(find.byType(Material));
|
||||||
expect(Theme.of(material).useMaterial3, false);
|
expect(Theme.of(material).useMaterial3, false);
|
||||||
@@ -219,12 +227,17 @@ void main() {
|
|||||||
testWidgets(
|
testWidgets(
|
||||||
'Brightness mode switches between dark and light when'
|
'Brightness mode switches between dark and light when'
|
||||||
'the brightness icon is clicked', (tester) async {
|
'the brightness icon is clicked', (tester) async {
|
||||||
await tester.pumpWidget(const Material3Demo());
|
await tester.pumpWidget(const MaterialApp(home: Material3Demo()));
|
||||||
Finder lightIcon = find.widgetWithIcon(IconButton, Icons.wb_sunny_outlined);
|
Finder lightIcon = find.descendant(
|
||||||
Finder darkIcon = find.widgetWithIcon(IconButton, Icons.wb_sunny);
|
of: find.byType(AppBar),
|
||||||
BuildContext appBar = tester.element(find.byType(AppBar));
|
matching: find.widgetWithIcon(IconButton, Icons.wb_sunny_outlined));
|
||||||
BuildContext body = tester.element(find.byType(Scaffold));
|
Finder darkIcon = find.descendant(
|
||||||
BuildContext navigationRail = tester.element(find.byType(NavigationRail));
|
of: find.byType(AppBar),
|
||||||
|
matching: find.widgetWithIcon(IconButton, Icons.wb_sunny));
|
||||||
|
BuildContext appBar = tester.element(find.byType(AppBar).first);
|
||||||
|
BuildContext body = tester.firstElement(find.byType(Scaffold).first);
|
||||||
|
BuildContext navigationRail = tester.element(
|
||||||
|
find.widgetWithIcon(NavigationRail, Icons.format_paint_outlined));
|
||||||
expect(lightIcon, findsOneWidget);
|
expect(lightIcon, findsOneWidget);
|
||||||
expect(darkIcon, findsNothing);
|
expect(darkIcon, findsNothing);
|
||||||
expect(Theme.of(appBar).brightness, Brightness.light);
|
expect(Theme.of(appBar).brightness, Brightness.light);
|
||||||
@@ -233,8 +246,8 @@ void main() {
|
|||||||
await tester.tap(lightIcon);
|
await tester.tap(lightIcon);
|
||||||
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
||||||
|
|
||||||
BuildContext appBar2 = tester.element(find.byType(AppBar));
|
BuildContext appBar2 = tester.element(find.byType(AppBar).first);
|
||||||
BuildContext body2 = tester.element(find.byType(Scaffold));
|
BuildContext body2 = tester.element(find.byType(Scaffold).first);
|
||||||
BuildContext navigationRail2 = tester.element(find.byType(NavigationRail));
|
BuildContext navigationRail2 = tester.element(find.byType(NavigationRail));
|
||||||
expect(lightIcon, findsNothing);
|
expect(lightIcon, findsNothing);
|
||||||
expect(darkIcon, findsOneWidget);
|
expect(darkIcon, findsOneWidget);
|
||||||
@@ -245,10 +258,15 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('Color theme changes when a color is selected from menu',
|
testWidgets('Color theme changes when a color is selected from menu',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
await tester.pumpWidget(const Material3Demo());
|
Color m3BaseColor = const Color(0xff6750a4);
|
||||||
Finder menuIcon = find.widgetWithIcon(IconButton, Icons.more_vert);
|
await tester.pumpWidget(Container());
|
||||||
BuildContext appBar = tester.element(find.byType(AppBar));
|
await tester.pumpWidget(const MaterialApp(home: Material3Demo()));
|
||||||
BuildContext body = tester.element(find.byType(Scaffold));
|
await tester.pump();
|
||||||
|
Finder menuIcon = find.descendant(
|
||||||
|
of: find.byType(AppBar),
|
||||||
|
matching: find.widgetWithIcon(IconButton, Icons.more_vert));
|
||||||
|
BuildContext appBar = tester.element(find.byType(AppBar).first);
|
||||||
|
BuildContext body = tester.element(find.byType(Scaffold).first);
|
||||||
BuildContext navigationRail = tester.element(find.byType(NavigationRail));
|
BuildContext navigationRail = tester.element(find.byType(NavigationRail));
|
||||||
|
|
||||||
expect(Theme.of(appBar).primaryColor, m3BaseColor);
|
expect(Theme.of(appBar).primaryColor, m3BaseColor);
|
||||||
@@ -256,11 +274,11 @@ void main() {
|
|||||||
expect(Theme.of(navigationRail).primaryColor, m3BaseColor);
|
expect(Theme.of(navigationRail).primaryColor, m3BaseColor);
|
||||||
await tester.tap(menuIcon);
|
await tester.tap(menuIcon);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
await tester.tap(find.text('Blue'));
|
await tester.tap(find.text('Blue').last);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
BuildContext appBar2 = tester.element(find.byType(AppBar));
|
BuildContext appBar2 = tester.element(find.byType(AppBar).first);
|
||||||
BuildContext body2 = tester.element(find.byType(Scaffold));
|
BuildContext body2 = tester.element(find.byType(Scaffold).first);
|
||||||
BuildContext navigationRail2 = tester.element(find.byType(NavigationRail));
|
BuildContext navigationRail2 = tester.element(find.byType(NavigationRail));
|
||||||
ThemeData expectedTheme = ThemeData(colorSchemeSeed: Colors.blue);
|
ThemeData expectedTheme = ThemeData(colorSchemeSeed: Colors.blue);
|
||||||
expect(Theme.of(appBar2).primaryColor, expectedTheme.primaryColor);
|
expect(Theme.of(appBar2).primaryColor, expectedTheme.primaryColor);
|
||||||
|
|||||||
@@ -16,43 +16,54 @@ void main() {
|
|||||||
'selected on NavigationBar', (tester) async {
|
'selected on NavigationBar', (tester) async {
|
||||||
widgetSetup(tester, 449);
|
widgetSetup(tester, 449);
|
||||||
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
|
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
|
||||||
await tester.pumpWidget(const Material3Demo());
|
await tester.pumpWidget(const MaterialApp(home: Material3Demo()));
|
||||||
|
|
||||||
expect(find.text('Surface Tint only'), findsNothing);
|
expect(find.text('Surface Tint Color Only'), findsNothing);
|
||||||
expect(find.byType(NavigationBar), findsOneWidget);
|
expect(find.byType(NavigationBar), findsOneWidget);
|
||||||
Finder tintIconOnBar = find.byIcon(Icons.invert_colors_on_outlined);
|
Finder tintIconOnBar = find.descendant(
|
||||||
|
of: find.byType(NavigationBar),
|
||||||
|
matching: find.widgetWithIcon(
|
||||||
|
NavigationDestination, Icons.invert_colors_on_outlined));
|
||||||
expect(tintIconOnBar, findsOneWidget);
|
expect(tintIconOnBar, findsOneWidget);
|
||||||
await tester.tap(tintIconOnBar);
|
await tester.tap(tintIconOnBar);
|
||||||
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
||||||
expect(tintIconOnBar, findsNothing);
|
expect(tintIconOnBar, findsNothing);
|
||||||
expect(find.byIcon(Icons.opacity), findsOneWidget);
|
Finder selectedTintIconOnBar = find.descendant(
|
||||||
expect(find.text('Surface Tint only'), findsOneWidget);
|
of: find.byType(NavigationBar),
|
||||||
|
matching: find.widgetWithIcon(NavigationDestination, Icons.opacity));
|
||||||
|
expect(selectedTintIconOnBar, findsOneWidget);
|
||||||
|
expect(find.text('Surface Tint Color Only'), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'Surface Tones screen shows correctly when the corresponding icon is '
|
'Surface Tones screen shows correctly when the corresponding icon is '
|
||||||
'selected on NavigationRail', (tester) async {
|
'selected on NavigationRail', (tester) async {
|
||||||
widgetSetup(tester, 450); // NavigationRail shows only when width is >= 450.
|
widgetSetup(
|
||||||
|
tester, 1200); // NavigationRail shows only when width is > 1000.
|
||||||
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
|
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
|
||||||
await tester.pumpWidget(const Material3Demo());
|
await tester.pumpWidget(const MaterialApp(home: Material3Demo()));
|
||||||
expect(find.text('Surface Tint only'), findsNothing);
|
expect(find.text('Surface Tint Color Only'), findsNothing);
|
||||||
expect(find.byType(NavigationRail), findsOneWidget);
|
expect(find.byType(NavigationRail), findsOneWidget);
|
||||||
Finder tintIconOnRail = find.byIcon(Icons.invert_colors_on_outlined);
|
Finder tintIconOnRail = find.descendant(
|
||||||
|
of: find.byType(NavigationRail),
|
||||||
|
matching: find.byIcon(Icons.invert_colors_on_outlined));
|
||||||
expect(tintIconOnRail, findsOneWidget);
|
expect(tintIconOnRail, findsOneWidget);
|
||||||
await tester.tap(tintIconOnRail);
|
await tester.tap(tintIconOnRail);
|
||||||
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
||||||
expect(tintIconOnRail, findsNothing);
|
expect(tintIconOnRail, findsNothing);
|
||||||
expect(find.byIcon(Icons.opacity), findsOneWidget);
|
Finder selectedTintIconOnRail = find.descendant(
|
||||||
expect(find.text('Surface Tint only'), findsOneWidget);
|
of: find.byType(NavigationRail), matching: find.byIcon(Icons.opacity));
|
||||||
|
expect(selectedTintIconOnRail, findsOneWidget);
|
||||||
|
expect(find.text('Surface Tint Color Only'), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Surface Tones screen shows correct content', (tester) async {
|
testWidgets('Surface Tones screen shows correct content', (tester) async {
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
home: Scaffold(body: Row(children: const [ElevationScreen()])),
|
home: Scaffold(body: Row(children: const [ElevationScreen()])),
|
||||||
));
|
));
|
||||||
expect(find.text('Surface Tint only'), findsOneWidget);
|
expect(find.text('Surface Tint Color Only'), findsOneWidget);
|
||||||
expect(find.text('Surface Tint and Shadow'), findsOneWidget);
|
expect(find.text('Surface Tint Color and Shadow Color'), findsOneWidget);
|
||||||
expect(find.text('Shadow only'), findsOneWidget);
|
expect(find.text('Shadow Color Only'), findsOneWidget);
|
||||||
expect(find.byType(ElevationGrid), findsNWidgets(3));
|
expect(find.byType(ElevationGrid), findsNWidgets(3));
|
||||||
expect(find.byType(ElevationCard), findsNWidgets(18));
|
expect(find.byType(ElevationCard), findsNWidgets(18));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,33 +16,44 @@ void main() {
|
|||||||
'selected on NavigationBar', (tester) async {
|
'selected on NavigationBar', (tester) async {
|
||||||
widgetSetup(tester, 449);
|
widgetSetup(tester, 449);
|
||||||
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
|
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
|
||||||
await tester.pumpWidget(const Material3Demo());
|
await tester.pumpWidget(const MaterialApp(home: Material3Demo()));
|
||||||
|
|
||||||
expect(find.text('Display Large'), findsNothing);
|
expect(find.text('Display Large'), findsNothing);
|
||||||
expect(find.byType(NavigationBar), findsOneWidget);
|
expect(find.byType(NavigationBar), findsOneWidget);
|
||||||
Finder textIconOnBar = find.byIcon(Icons.text_snippet_outlined);
|
Finder textIconOnBar = find.descendant(
|
||||||
|
of: find.byType(NavigationBar),
|
||||||
|
matching: find.byIcon(Icons.text_snippet_outlined));
|
||||||
expect(textIconOnBar, findsOneWidget);
|
expect(textIconOnBar, findsOneWidget);
|
||||||
await tester.tap(textIconOnBar);
|
await tester.tap(textIconOnBar);
|
||||||
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
||||||
expect(textIconOnBar, findsNothing);
|
expect(textIconOnBar, findsNothing);
|
||||||
expect(find.byIcon(Icons.text_snippet), findsOneWidget);
|
Finder selectedTextIconOnBar = find.descendant(
|
||||||
|
of: find.byType(NavigationBar),
|
||||||
|
matching: find.byIcon(Icons.text_snippet));
|
||||||
|
expect(selectedTextIconOnBar, findsOneWidget);
|
||||||
expect(find.text('Display Large'), findsOneWidget);
|
expect(find.text('Display Large'), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'Typography screen shows correctly when the corresponding icon is '
|
'Typography screen shows correctly when the corresponding icon is '
|
||||||
'selected on NavigationRail', (tester) async {
|
'selected on NavigationRail', (tester) async {
|
||||||
widgetSetup(tester, 450); // NavigationRail shows only when width is >= 450.
|
widgetSetup(
|
||||||
|
tester, 1200); // NavigationRail shows only when width is > 1000.
|
||||||
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
|
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
|
||||||
await tester.pumpWidget(const Material3Demo());
|
await tester.pumpWidget(const MaterialApp(home: Material3Demo()));
|
||||||
expect(find.text('Display Large'), findsNothing);
|
expect(find.text('Display Large'), findsNothing);
|
||||||
expect(find.byType(NavigationRail), findsOneWidget);
|
expect(find.byType(NavigationRail), findsOneWidget);
|
||||||
Finder textIconOnRail = find.byIcon(Icons.text_snippet_outlined);
|
Finder textIconOnRail = find.descendant(
|
||||||
|
of: find.byType(NavigationRail),
|
||||||
|
matching: find.byIcon(Icons.text_snippet_outlined));
|
||||||
expect(textIconOnRail, findsOneWidget);
|
expect(textIconOnRail, findsOneWidget);
|
||||||
await tester.tap(textIconOnRail);
|
await tester.tap(textIconOnRail);
|
||||||
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
await tester.pumpAndSettle(const Duration(microseconds: 500));
|
||||||
expect(textIconOnRail, findsNothing);
|
expect(textIconOnRail, findsNothing);
|
||||||
expect(find.byIcon(Icons.text_snippet), findsOneWidget);
|
Finder selectedTextIconOnRail = find.descendant(
|
||||||
|
of: find.byType(NavigationRail),
|
||||||
|
matching: find.byIcon(Icons.text_snippet));
|
||||||
|
expect(selectedTextIconOnRail, findsOneWidget);
|
||||||
expect(find.text('Display Large'), findsOneWidget);
|
expect(find.text('Display Large'), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user