diff --git a/packages/flutter/lib/src/material/divider.dart b/packages/flutter/lib/src/material/divider.dart index c9229eb24c..35d2e8f56a 100644 --- a/packages/flutter/lib/src/material/divider.dart +++ b/packages/flutter/lib/src/material/divider.dart @@ -82,34 +82,44 @@ class Divider extends StatelessWidget { /// The thickness of the line drawn within the divider. /// + /// {@template flutter.material.Divider.thickness} /// A divider with a [thickness] of 0.0 is always drawn as a line with a /// height of exactly one device pixel. /// /// If this is null, then the [DividerThemeData.thickness] is used. If /// that is also null, then this defaults to 0.0. + /// {@endtemplate} final double? thickness; /// The amount of empty space to the leading edge of the divider. /// + /// {@template flutter.material.Divider.indent} /// If this is null, then the [DividerThemeData.indent] is used. If that is /// also null, then this defaults to 0.0. + /// {@endtemplate} final double? indent; /// The amount of empty space to the trailing edge of the divider. /// + /// {@template flutter.material.Divider.endIndent} /// If this is null, then the [DividerThemeData.endIndent] is used. If that is /// also null, then this defaults to 0.0. + /// {@endtemplate} final double? endIndent; /// The amount of radius for the border of the divider. /// + /// {@template flutter.material.Divider.radius} /// If this is null, then the default radius of [BoxDecoration] will be used. + /// {@endtemplate} final BorderRadiusGeometry? radius; + /// {@template flutter.material.Divider.color} /// The color to use when painting the line. /// /// If this is null, then the [DividerThemeData.color] is used. If that is /// also null, then [ThemeData.dividerColor] is used. + /// {@endtemplate} /// /// {@tool snippet} /// diff --git a/packages/flutter/lib/src/material/popup_menu.dart b/packages/flutter/lib/src/material/popup_menu.dart index 873cb1f510..93455a2dec 100644 --- a/packages/flutter/lib/src/material/popup_menu.dart +++ b/packages/flutter/lib/src/material/popup_menu.dart @@ -112,7 +112,15 @@ class PopupMenuDivider extends PopupMenuEntry { /// Creates a horizontal divider for a popup menu. /// /// By default, the divider has a height of 16 logical pixels. - const PopupMenuDivider({super.key, this.height = _kMenuDividerHeight}); + const PopupMenuDivider({ + super.key, + this.height = _kMenuDividerHeight, + this.thickness, + this.indent, + this.endIndent, + this.radius, + this.color, + }); /// The height of the divider entry. /// @@ -120,6 +128,38 @@ class PopupMenuDivider extends PopupMenuEntry { @override final double height; + /// The thickness of the line drawn within the [PopupMenuDivider]. + /// + /// {@macro flutter.material.Divider.thickness} + final double? thickness; + + /// The amount of empty space to the leading edge of the [PopupMenuDivider]. + /// + /// {@macro flutter.material.Divider.indent} + final double? indent; + + /// The amount of empty space to the trailing edge of the [PopupMenuDivider]. + /// + /// {@macro flutter.material.Divider.endIndent} + final double? endIndent; + + /// The amount of radius for the border of the [PopupMenuDivider]. + /// + /// {@macro flutter.material.Divider.radius} + final BorderRadiusGeometry? radius; + + /// {@macro flutter.material.Divider.color} + /// + /// {@tool snippet} + /// + /// ```dart + /// const PopupMenuDivider( + /// color: Colors.deepOrange, + /// ) + /// ``` + /// {@end-tool} + final Color? color; + @override bool represents(void value) => false; @@ -129,7 +169,16 @@ class PopupMenuDivider extends PopupMenuEntry { class _PopupMenuDividerState extends State { @override - Widget build(BuildContext context) => Divider(height: widget.height); + Widget build(BuildContext context) { + return Divider( + height: widget.height, + thickness: widget.thickness, + indent: widget.indent, + color: widget.color, + endIndent: widget.endIndent, + radius: widget.radius, + ); + } } // This widget only exists to enable _PopupMenuRoute to save the sizes of diff --git a/packages/flutter/test/material/popup_menu_test.dart b/packages/flutter/test/material/popup_menu_test.dart index 180888d4db..f51ab5ad78 100644 --- a/packages/flutter/test/material/popup_menu_test.dart +++ b/packages/flutter/test/material/popup_menu_test.dart @@ -4477,6 +4477,135 @@ void main() { await tester.binding.setSurfaceSize(null); }); + + testWidgets('PopupMenuDivider custom thickness', (WidgetTester tester) async { + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: PopupMenuButton( + onSelected: (String result) {}, + child: const Text('Menu Button'), + itemBuilder: + (BuildContext context) => >[ + const PopupMenuDivider(thickness: 5.0), + ], + ), + ), + ), + ), + ); + + await tester.tap(find.byType(PopupMenuButton)); + await tester.pump(); + final Container container = tester.widget(find.byType(Container)); + final BoxDecoration decoration = container.decoration! as BoxDecoration; + expect(decoration.border!.bottom.width, 5.0); + }); + + testWidgets('PopupMenuDivider custom indent', (WidgetTester tester) async { + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: PopupMenuButton( + onSelected: (String result) {}, + child: const Text('Menu Button'), + itemBuilder: + (BuildContext context) => >[ + const PopupMenuDivider(indent: 5.0), + ], + ), + ), + ), + ), + ); + + await tester.tap(find.byType(PopupMenuButton)); + await tester.pump(); + final Container container = tester.widget(find.byType(Container)); + final EdgeInsetsDirectional margin = container.margin! as EdgeInsetsDirectional; + expect(margin.start, 5.0); + }); + + testWidgets('PopupMenuDivider custom color', (WidgetTester tester) async { + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: PopupMenuButton( + onSelected: (String result) {}, + child: const Text('Menu Button'), + itemBuilder: + (BuildContext context) => >[ + const PopupMenuDivider(color: Colors.deepOrange), + ], + ), + ), + ), + ), + ); + + await tester.tap(find.byType(PopupMenuButton)); + await tester.pump(); + final Container container = tester.widget(find.byType(Container)); + final BoxDecoration decoration = container.decoration! as BoxDecoration; + expect(decoration.border!.bottom.color, Colors.deepOrange); + }); + + testWidgets('PopupMenuDivider custom end indent', (WidgetTester tester) async { + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: PopupMenuButton( + onSelected: (String result) {}, + child: const Text('Menu Button'), + itemBuilder: + (BuildContext context) => >[ + const PopupMenuDivider(endIndent: 5.0), + ], + ), + ), + ), + ), + ); + + await tester.tap(find.byType(PopupMenuButton)); + await tester.pump(); + final Container container = tester.widget(find.byType(Container)); + final EdgeInsetsDirectional margin = container.margin! as EdgeInsetsDirectional; + expect(margin.end, 5.0); + }); + + testWidgets('PopupMenuDivider custom radius', (WidgetTester tester) async { + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: PopupMenuButton( + onSelected: (String result) {}, + child: const Text('Menu Button'), + itemBuilder: + (BuildContext context) => >[ + PopupMenuDivider(radius: BorderRadius.circular(5)), + ], + ), + ), + ), + ), + ); + + await tester.tap(find.byType(PopupMenuButton)); + await tester.pump(); + final Container container = tester.widget(find.byType(Container)); + final BoxDecoration decoration = container.decoration! as BoxDecoration; + final BorderRadius borderRadius = decoration.borderRadius! as BorderRadius; + expect(borderRadius.bottomLeft, const Radius.circular(5)); + expect(borderRadius.bottomRight, const Radius.circular(5)); + expect(borderRadius.topLeft, const Radius.circular(5)); + expect(borderRadius.topRight, const Radius.circular(5)); + }); } Matcher overlaps(Rect other) => OverlapsMatcher(other);