Add styling parameters in PopupMenuDivider (#164790)

Fixes https://github.com/flutter/flutter/issues/68176

- Add thickness, indent, endIndent and radius option on PopupMenuDivider
- Test coverage

<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
Dimil Kalathiya
2025-04-03 06:03:58 +05:30
committed by GitHub
parent 997f742ac5
commit 1e63b20d48
3 changed files with 190 additions and 2 deletions

View File

@@ -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}
///

View File

@@ -112,7 +112,15 @@ class PopupMenuDivider extends PopupMenuEntry<Never> {
/// 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<Never> {
@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<Never> {
class _PopupMenuDividerState extends State<PopupMenuDivider> {
@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

View File

@@ -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<String>(
onSelected: (String result) {},
child: const Text('Menu Button'),
itemBuilder:
(BuildContext context) => <PopupMenuEntry<String>>[
const PopupMenuDivider(thickness: 5.0),
],
),
),
),
),
);
await tester.tap(find.byType(PopupMenuButton<String>));
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<String>(
onSelected: (String result) {},
child: const Text('Menu Button'),
itemBuilder:
(BuildContext context) => <PopupMenuEntry<String>>[
const PopupMenuDivider(indent: 5.0),
],
),
),
),
),
);
await tester.tap(find.byType(PopupMenuButton<String>));
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<String>(
onSelected: (String result) {},
child: const Text('Menu Button'),
itemBuilder:
(BuildContext context) => <PopupMenuEntry<String>>[
const PopupMenuDivider(color: Colors.deepOrange),
],
),
),
),
),
);
await tester.tap(find.byType(PopupMenuButton<String>));
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<String>(
onSelected: (String result) {},
child: const Text('Menu Button'),
itemBuilder:
(BuildContext context) => <PopupMenuEntry<String>>[
const PopupMenuDivider(endIndent: 5.0),
],
),
),
),
),
);
await tester.tap(find.byType(PopupMenuButton<String>));
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<String>(
onSelected: (String result) {},
child: const Text('Menu Button'),
itemBuilder:
(BuildContext context) => <PopupMenuEntry<String>>[
PopupMenuDivider(radius: BorderRadius.circular(5)),
],
),
),
),
),
);
await tester.tap(find.byType(PopupMenuButton<String>));
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);