Add support for Material 3 Divider and VerticalDivider (#112655)
diff --git a/dev/tools/gen_defaults/bin/gen_defaults.dart b/dev/tools/gen_defaults/bin/gen_defaults.dart
index 9c24b27..dd716e5 100644
--- a/dev/tools/gen_defaults/bin/gen_defaults.dart
+++ b/dev/tools/gen_defaults/bin/gen_defaults.dart
@@ -24,6 +24,7 @@
import 'package:gen_defaults/card_template.dart';
import 'package:gen_defaults/checkbox_template.dart';
import 'package:gen_defaults/dialog_template.dart';
+import 'package:gen_defaults/divider_template.dart';
import 'package:gen_defaults/fab_template.dart';
import 'package:gen_defaults/filter_chip_template.dart';
import 'package:gen_defaults/icon_button_template.dart';
@@ -65,6 +66,7 @@
'date_picker_docked.json',
'date_picker_modal.json',
'dialog.json',
+ 'divider.json',
'dialog_fullscreen.json',
'elevation.json',
'fab_extended_primary.json',
@@ -122,6 +124,7 @@
CheckboxTemplate('Checkbox', '$materialLib/checkbox.dart', tokens).updateFile();
DialogFullscreenTemplate('DialogFullscreen', '$materialLib/dialog.dart', tokens).updateFile();
DialogTemplate('Dialog', '$materialLib/dialog.dart', tokens).updateFile();
+ DividerTemplate('Divider', '$materialLib/divider.dart', tokens).updateFile();
FABTemplate('FAB', '$materialLib/floating_action_button.dart', tokens).updateFile();
FilterChipTemplate('ChoiceChip', '$materialLib/choice_chip.dart', tokens).updateFile();
FilterChipTemplate('FilterChip', '$materialLib/filter_chip.dart', tokens).updateFile();
diff --git a/dev/tools/gen_defaults/lib/divider_template.dart b/dev/tools/gen_defaults/lib/divider_template.dart
new file mode 100644
index 0000000..03ed020
--- /dev/null
+++ b/dev/tools/gen_defaults/lib/divider_template.dart
@@ -0,0 +1,25 @@
+// 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 DividerTemplate extends TokenTemplate {
+ const DividerTemplate(super.blockName, super.fileName, super.tokens);
+
+ @override
+ String generate() => '''
+class _${blockName}DefaultsM3 extends DividerThemeData {
+ const _${blockName}DefaultsM3(this.context) : super(
+ space: 16,
+ thickness: ${tokens["md.comp.divider.thickness"]},
+ indent: 0,
+ endIndent: 0,
+ );
+
+ final BuildContext context;
+
+ @override Color? get color => ${componentColor("md.comp.divider")};
+}
+''';
+}
diff --git a/examples/api/lib/material/divider/divider.0.dart b/examples/api/lib/material/divider/divider.0.dart
index 5912c1f..6672379 100644
--- a/examples/api/lib/material/divider/divider.0.dart
+++ b/examples/api/lib/material/divider/divider.0.dart
@@ -11,22 +11,19 @@
class MyApp extends StatelessWidget {
const MyApp({super.key});
- static const String _title = 'Flutter Code Sample';
-
@override
Widget build(BuildContext context) {
return MaterialApp(
- title: _title,
home: Scaffold(
- appBar: AppBar(title: const Text(_title)),
- body: const MyStatelessWidget(),
+ appBar: AppBar(title: const Text('Divider Sample')),
+ body: const DividerExample(),
),
);
}
}
-class MyStatelessWidget extends StatelessWidget {
- const MyStatelessWidget({super.key});
+class DividerExample extends StatelessWidget {
+ const DividerExample({super.key});
@override
Widget build(BuildContext context) {
diff --git a/examples/api/lib/material/divider/divider.1.dart b/examples/api/lib/material/divider/divider.1.dart
new file mode 100644
index 0000000..708e642
--- /dev/null
+++ b/examples/api/lib/material/divider/divider.1.dart
@@ -0,0 +1,52 @@
+// 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.
+
+/// Flutter code sample for [Divider].
+
+import 'package:flutter/material.dart';
+
+void main() => runApp(const MyApp());
+
+class MyApp extends StatelessWidget {
+ const MyApp({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ theme: ThemeData(colorSchemeSeed: const Color(0xff6750a4), useMaterial3: true),
+ home: Scaffold(
+ appBar: AppBar(title: const Text('Divider Sample')),
+ body: const DividerExample(),
+ ),
+ );
+ }
+}
+
+class DividerExample extends StatelessWidget {
+ const DividerExample({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Center(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ children: const <Widget>[
+ Expanded(
+ child: Card(
+ child: SizedBox.expand(),
+ ),
+ ),
+ Divider(),
+ Expanded(
+ child: Card(
+ child: SizedBox.expand(),
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/examples/api/lib/material/divider/vertical_divider.0.dart b/examples/api/lib/material/divider/vertical_divider.0.dart
index 0a9a5cb..2bb5ad1 100644
--- a/examples/api/lib/material/divider/vertical_divider.0.dart
+++ b/examples/api/lib/material/divider/vertical_divider.0.dart
@@ -11,22 +11,19 @@
class MyApp extends StatelessWidget {
const MyApp({super.key});
- static const String _title = 'Flutter Code Sample';
-
@override
Widget build(BuildContext context) {
return MaterialApp(
- title: _title,
home: Scaffold(
- appBar: AppBar(title: const Text(_title)),
- body: const MyStatelessWidget(),
+ appBar: AppBar(title: const Text('VerticalDivider Sample')),
+ body: const DividerExample(),
),
);
}
}
-class MyStatelessWidget extends StatelessWidget {
- const MyStatelessWidget({super.key});
+class DividerExample extends StatelessWidget {
+ const DividerExample({super.key});
@override
Widget build(BuildContext context) {
diff --git a/examples/api/lib/material/divider/vertical_divider.1.dart b/examples/api/lib/material/divider/vertical_divider.1.dart
new file mode 100644
index 0000000..47a7b54
--- /dev/null
+++ b/examples/api/lib/material/divider/vertical_divider.1.dart
@@ -0,0 +1,52 @@
+// 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.
+
+/// Flutter code sample for [Divider].
+
+import 'package:flutter/material.dart';
+
+void main() => runApp(const MyApp());
+
+class MyApp extends StatelessWidget {
+ const MyApp({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ theme: ThemeData(colorSchemeSeed: const Color(0xff6750a4), useMaterial3: true),
+ home: Scaffold(
+ appBar: AppBar(title: const Text('Divider Sample')),
+ body: const DividerExample(),
+ ),
+ );
+ }
+}
+
+class DividerExample extends StatelessWidget {
+ const DividerExample({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Center(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Row(
+ children: const <Widget>[
+ Expanded(
+ child: Card(
+ child: SizedBox.expand(),
+ ),
+ ),
+ VerticalDivider(),
+ Expanded(
+ child: Card(
+ child: SizedBox.expand(),
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/examples/api/test/material/divider/divider.0_test.dart b/examples/api/test/material/divider/divider.0_test.dart
new file mode 100644
index 0000000..825f0cb
--- /dev/null
+++ b/examples/api/test/material/divider/divider.0_test.dart
@@ -0,0 +1,28 @@
+// 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_api_samples/material/divider/divider.0.dart' as example;
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+ testWidgets('Horizontal Divider', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ const MaterialApp(
+ home: Scaffold(
+ body: example.MyApp(),
+ ),
+ ),
+ );
+
+ expect(find.byType(Divider), findsOneWidget);
+
+ // Divider is positioned horizintally.
+ final Offset container = tester.getBottomLeft(find.byType(Container).first);
+ expect(container.dy, tester.getTopLeft(find.byType(Divider)).dy);
+
+ final Offset subheader = tester.getTopLeft(find.text('Subheader'));
+ expect(subheader.dy, tester.getBottomLeft(find.byType(Divider)).dy);
+ });
+}
diff --git a/examples/api/test/material/divider/divider.1_test.dart b/examples/api/test/material/divider/divider.1_test.dart
new file mode 100644
index 0000000..a0cedbb
--- /dev/null
+++ b/examples/api/test/material/divider/divider.1_test.dart
@@ -0,0 +1,28 @@
+// 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_api_samples/material/divider/divider.1.dart' as example;
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+ testWidgets('Horizontal Divider', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ const MaterialApp(
+ home: Scaffold(
+ body: example.MyApp(),
+ ),
+ ),
+ );
+
+ expect(find.byType(Divider), findsOneWidget);
+
+ // Divider is positioned horizontally.
+ Offset card = tester.getBottomLeft(find.byType(Card).first);
+ expect(card.dy, tester.getTopLeft(find.byType(Divider)).dy);
+
+ card = tester.getTopLeft(find.byType(Card).last);
+ expect(card.dy, tester.getBottomLeft(find.byType(Divider)).dy);
+ });
+}
diff --git a/examples/api/test/material/divider/vertical_divider.0_test.dart b/examples/api/test/material/divider/vertical_divider.0_test.dart
new file mode 100644
index 0000000..63c7513
--- /dev/null
+++ b/examples/api/test/material/divider/vertical_divider.0_test.dart
@@ -0,0 +1,28 @@
+// 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_api_samples/material/divider/vertical_divider.0.dart' as example;
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+ testWidgets('Vertical Divider', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ const MaterialApp(
+ home: Scaffold(
+ body: example.MyApp(),
+ ),
+ ),
+ );
+
+ expect(find.byType(VerticalDivider), findsOneWidget);
+
+ // Divider is positioned horizintally.
+ Offset expanded = tester.getTopRight(find.byType(Expanded).first);
+ expect(expanded.dx, tester.getTopLeft(find.byType(VerticalDivider)).dx);
+
+ expanded = tester.getTopLeft(find.byType(Expanded).last);
+ expect(expanded.dx, tester.getTopRight(find.byType(VerticalDivider)).dx);
+ });
+}
diff --git a/examples/api/test/material/divider/vertical_divider.1_test.dart b/examples/api/test/material/divider/vertical_divider.1_test.dart
new file mode 100644
index 0000000..8840fee
--- /dev/null
+++ b/examples/api/test/material/divider/vertical_divider.1_test.dart
@@ -0,0 +1,28 @@
+// 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_api_samples/material/divider/vertical_divider.1.dart' as example;
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+ testWidgets('Vertical Divider', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ const MaterialApp(
+ home: Scaffold(
+ body: example.MyApp(),
+ ),
+ ),
+ );
+
+ expect(find.byType(VerticalDivider), findsOneWidget);
+
+ // Divider is positioned vertically.
+ Offset card = tester.getTopRight(find.byType(Card).first);
+ expect(card.dx, tester.getTopLeft(find.byType(VerticalDivider)).dx);
+
+ card = tester.getTopLeft(find.byType(Card).last);
+ expect(card.dx, tester.getTopRight(find.byType(VerticalDivider)).dx);
+ });
+}
diff --git a/packages/flutter/lib/src/material/divider.dart b/packages/flutter/lib/src/material/divider.dart
index 44b3f66..f2d86bd 100644
--- a/packages/flutter/lib/src/material/divider.dart
+++ b/packages/flutter/lib/src/material/divider.dart
@@ -34,6 +34,13 @@
/// ** See code in examples/api/lib/material/divider/divider.0.dart **
/// {@end-tool}
///
+/// {@tool dartpad}
+/// This sample shows the creation of [Divider] widget, as described in:
+/// https://m3.material.io/components/divider/overview
+///
+/// ** See code in examples/api/lib/material/divider/divider.1.dart **
+/// {@end-tool}
+///
/// See also:
///
/// * [PopupMenuDivider], which is the equivalent but for popup menus.
@@ -106,7 +113,9 @@
/// Computes the [BorderSide] that represents a divider.
///
/// If [color] is null, then [DividerThemeData.color] is used. If that is also
- /// null, then [ThemeData.dividerColor] is used.
+ /// null, then if [ThemeData.useMaterial3] is true then it defaults to
+ /// [ThemeData.colorScheme]'s [ColorScheme.outlineVariant]. Otherwise
+ /// [ThemeData.dividerColor] is used.
///
/// If [width] is null, then [DividerThemeData.thickness] is used. If that is
/// also null, then this defaults to 0.0 (a hairline border).
@@ -133,11 +142,12 @@
/// ```
/// {@end-tool}
static BorderSide createBorderSide(BuildContext? context, { Color? color, double? width }) {
- final Color? effectiveColor = color
- ?? (context != null ? (DividerTheme.of(context).color ?? Theme.of(context).dividerColor) : null);
- final double effectiveWidth = width
- ?? (context != null ? DividerTheme.of(context).thickness : null)
- ?? 0.0;
+ final DividerThemeData? dividerTheme = context != null ? DividerTheme.of(context) : null;
+ final DividerThemeData? defaults = context != null
+ ? Theme.of(context).useMaterial3 ? _DividerDefaultsM3(context) : _DividerDefaultsM2(context)
+ : null;
+ final Color? effectiveColor = color ?? dividerTheme?.color ?? defaults?.color;
+ final double effectiveWidth = width ?? dividerTheme?.thickness ?? defaults?.thickness ?? 0.0;
// Prevent assertion since it is possible that context is null and no color
// is specified.
@@ -154,11 +164,13 @@
@override
Widget build(BuildContext context) {
+ final ThemeData theme = Theme.of(context);
final DividerThemeData dividerTheme = DividerTheme.of(context);
- final double height = this.height ?? dividerTheme.space ?? 16.0;
- final double thickness = this.thickness ?? dividerTheme.thickness ?? 0.0;
- final double indent = this.indent ?? dividerTheme.indent ?? 0.0;
- final double endIndent = this.endIndent ?? dividerTheme.endIndent ?? 0.0;
+ final DividerThemeData defaults = theme.useMaterial3 ? _DividerDefaultsM3(context) : _DividerDefaultsM2(context);
+ final double height = this.height ?? dividerTheme.space ?? defaults.space!;
+ final double thickness = this.thickness ?? dividerTheme.thickness ?? defaults.thickness!;
+ final double indent = this.indent ?? dividerTheme.indent ?? defaults.indent!;
+ final double endIndent = this.endIndent ?? dividerTheme.endIndent ?? defaults.endIndent!;
return SizedBox(
height: height,
@@ -195,6 +207,13 @@
/// ** See code in examples/api/lib/material/divider/vertical_divider.0.dart **
/// {@end-tool}
///
+/// {@tool dartpad}
+/// This sample shows the creation of [VerticalDivider] widget, as described in:
+/// https://m3.material.io/components/divider/overview
+///
+/// ** See code in examples/api/lib/material/divider/vertical_divider.1.dart **
+/// {@end-tool}
+///
/// See also:
///
/// * [ListView.separated], which can be used to generate vertical dividers.
@@ -264,11 +283,13 @@
@override
Widget build(BuildContext context) {
+ final ThemeData theme = Theme.of(context);
final DividerThemeData dividerTheme = DividerTheme.of(context);
- final double width = this.width ?? dividerTheme.space ?? 16.0;
- final double thickness = this.thickness ?? dividerTheme.thickness ?? 0.0;
- final double indent = this.indent ?? dividerTheme.indent ?? 0.0;
- final double endIndent = this.endIndent ?? dividerTheme.endIndent ?? 0.0;
+ final DividerThemeData defaults = theme.useMaterial3 ? _DividerDefaultsM3(context) : _DividerDefaultsM2(context);
+ final double width = this.width ?? dividerTheme.space ?? defaults.space!;
+ final double thickness = this.thickness ?? dividerTheme.thickness ?? defaults.thickness!;
+ final double indent = this.indent ?? dividerTheme.indent ?? defaults.indent!;
+ final double endIndent = this.endIndent ?? dividerTheme.endIndent ?? defaults.endIndent!;
return SizedBox(
width: width,
@@ -286,3 +307,40 @@
);
}
}
+
+class _DividerDefaultsM2 extends DividerThemeData {
+ const _DividerDefaultsM2(this.context) : super(
+ space: 16,
+ thickness: 0,
+ indent: 0,
+ endIndent: 0,
+ );
+
+ final BuildContext context;
+
+ @override Color? get color => Theme.of(context).dividerColor;
+}
+
+// BEGIN GENERATED TOKEN PROPERTIES - Divider
+
+// 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_132
+
+class _DividerDefaultsM3 extends DividerThemeData {
+ const _DividerDefaultsM3(this.context) : super(
+ space: 16,
+ thickness: 1.0,
+ indent: 0,
+ endIndent: 0,
+ );
+
+ final BuildContext context;
+
+ @override Color? get color => Theme.of(context).colorScheme.outlineVariant;
+}
+
+// END GENERATED TOKEN PROPERTIES - Divider
diff --git a/packages/flutter/test/material/divider_theme_test.dart b/packages/flutter/test/material/divider_theme_test.dart
index 4d34e28..29bfd81 100644
--- a/packages/flutter/test/material/divider_theme_test.dart
+++ b/packages/flutter/test/material/divider_theme_test.dart
@@ -59,8 +59,9 @@
group('Horizontal Divider', () {
testWidgets('Passing no DividerThemeData returns defaults', (WidgetTester tester) async {
- await tester.pumpWidget(const MaterialApp(
- home: Scaffold(
+ await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: const Scaffold(
body: Divider(),
),
));
@@ -70,10 +71,10 @@
final Container container = tester.widget(find.byType(Container));
final BoxDecoration decoration = container.decoration! as BoxDecoration;
- expect(decoration.border!.bottom.width, 0.0);
+ expect(decoration.border!.bottom.width, 1.0);
final ThemeData theme = ThemeData();
- expect(decoration.border!.bottom.color, theme.dividerColor);
+ expect(decoration.border!.bottom.color, theme.colorScheme.outlineVariant);
final Rect dividerRect = tester.getRect(find.byType(Divider));
final Rect lineRect = tester.getRect(find.byType(DecoratedBox));
@@ -84,7 +85,7 @@
testWidgets('Uses values from DividerThemeData', (WidgetTester tester) async {
final DividerThemeData dividerTheme = _dividerTheme();
await tester.pumpWidget(MaterialApp(
- theme: ThemeData(dividerTheme: dividerTheme),
+ theme: ThemeData(useMaterial3: true, dividerTheme: dividerTheme),
home: const Scaffold(
body: Divider(),
),
@@ -104,6 +105,24 @@
expect(lineRect.right, dividerRect.right - dividerTheme.endIndent!);
});
+ testWidgets('DividerTheme overrides defaults', (WidgetTester tester) async {
+ final DividerThemeData dividerTheme = _dividerTheme();
+ await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: Scaffold(
+ body: DividerTheme(
+ data: dividerTheme,
+ child: const Divider(),
+ ),
+ ),
+ ));
+
+ final Container container = tester.widget(find.byType(Container));
+ final BoxDecoration decoration = container.decoration! as BoxDecoration;
+ expect(decoration.border!.bottom.width, dividerTheme.thickness);
+ expect(decoration.border!.bottom.color, dividerTheme.color);
+ });
+
testWidgets('Widget properties take priority over theme', (WidgetTester tester) async {
const Color color = Colors.purple;
const double height = 10.0;
@@ -142,8 +161,9 @@
group('Vertical Divider', () {
testWidgets('Passing no DividerThemeData returns defaults', (WidgetTester tester) async {
- await tester.pumpWidget(const MaterialApp(
- home: Scaffold(
+ await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: const Scaffold(
body: VerticalDivider(),
),
));
@@ -154,10 +174,10 @@
final Container container = tester.widget(find.byType(Container));
final BoxDecoration decoration = container.decoration! as BoxDecoration;
final Border border = decoration.border! as Border;
- expect(border.left.width, 0.0);
+ expect(border.left.width, 1.0);
final ThemeData theme = ThemeData();
- expect(border.left.color, theme.dividerColor);
+ expect(border.left.color, theme.colorScheme.outlineVariant);
final Rect dividerRect = tester.getRect(find.byType(VerticalDivider));
final Rect lineRect = tester.getRect(find.byType(DecoratedBox));
@@ -189,6 +209,25 @@
expect(lineRect.bottom, dividerRect.bottom - dividerTheme.endIndent!);
});
+ testWidgets('DividerTheme overrides defaults', (WidgetTester tester) async {
+ final DividerThemeData dividerTheme = _dividerTheme();
+ await tester.pumpWidget(MaterialApp(
+ theme: ThemeData(useMaterial3: true),
+ home: Scaffold(
+ body: DividerTheme(
+ data: dividerTheme,
+ child: const VerticalDivider(),
+ ),
+ ),
+ ));
+
+ final Container container = tester.widget(find.byType(Container));
+ final BoxDecoration decoration = container.decoration! as BoxDecoration;
+ final Border border = decoration.border! as Border;
+ expect(border.left.width, dividerTheme.thickness);
+ expect(border.left.color, dividerTheme.color);
+ });
+
testWidgets('Widget properties take priority over theme', (WidgetTester tester) async {
const Color color = Colors.purple;
const double width = 10.0;
@@ -225,6 +264,79 @@
expect(lineRect.bottom, dividerRect.bottom - endIndent);
});
});
+
+ group('Material 2', () {
+ // Tests that are only relevant for Material 2. Once ThemeData.useMaterial3
+ // is turned on by default, these tests can be removed.
+
+ group('Horizontal Divider', () {
+ testWidgets('Passing no DividerThemeData returns defaults', (WidgetTester tester) async {
+ await tester.pumpWidget(const MaterialApp(
+ home: Scaffold(
+ body: Divider(),
+ ),
+ ));
+
+ final RenderBox box = tester.firstRenderObject(find.byType(Divider));
+ expect(box.size.height, 16.0);
+
+ final Container container = tester.widget(find.byType(Container));
+ final BoxDecoration decoration = container.decoration! as BoxDecoration;
+ expect(decoration.border!.bottom.width, 0.0);
+
+ final ThemeData theme = ThemeData();
+ expect(decoration.border!.bottom.color, theme.dividerColor);
+
+ final Rect dividerRect = tester.getRect(find.byType(Divider));
+ final Rect lineRect = tester.getRect(find.byType(DecoratedBox));
+ expect(lineRect.left, dividerRect.left);
+ expect(lineRect.right, dividerRect.right);
+ });
+
+ testWidgets('DividerTheme overrides defaults', (WidgetTester tester) async {
+ final DividerThemeData theme = _dividerTheme();
+ await tester.pumpWidget(MaterialApp(
+ home: Scaffold(
+ body: DividerTheme(
+ data: theme,
+ child: const Divider(),
+ ),
+ ),
+ ));
+
+ final Container container = tester.widget(find.byType(Container));
+ final BoxDecoration decoration = container.decoration! as BoxDecoration;
+ expect(decoration.border!.bottom.width, theme.thickness);
+ expect(decoration.border!.bottom.color, theme.color);
+ });
+ });
+
+ group('Vertical Divider', () {
+ testWidgets('Passing no DividerThemeData returns defaults', (WidgetTester tester) async {
+ await tester.pumpWidget(const MaterialApp(
+ home: Scaffold(
+ body: VerticalDivider(),
+ ),
+ ));
+
+ final RenderBox box = tester.firstRenderObject(find.byType(VerticalDivider));
+ expect(box.size.width, 16.0);
+
+ final Container container = tester.widget(find.byType(Container));
+ final BoxDecoration decoration = container.decoration! as BoxDecoration;
+ final Border border = decoration.border! as Border;
+ expect(border.left.width, 0.0);
+
+ final ThemeData theme = ThemeData();
+ expect(border.left.color, theme.dividerColor);
+
+ final Rect dividerRect = tester.getRect(find.byType(VerticalDivider));
+ final Rect lineRect = tester.getRect(find.byType(DecoratedBox));
+ expect(lineRect.top, dividerRect.top);
+ expect(lineRect.bottom, dividerRect.bottom);
+ });
+ });
+ });
}
DividerThemeData _dividerTheme() {