Skip to content

Commit 6fdcb0a

Browse files
authored
feat: Add alignmentOffset to DropdownMenu (flutter#151731)
Changes: - Introduced `alignmentOffset` property to `DropdownMenu` to allow adjustment of menu alignment. - Updated the `MenuAnchor` widget to utilize the new `alignmentOffset` property. - Default value for `alignmentOffset` is `Offset.zero`, meaning no additional spacing by default. Motivation: - This PR closes flutter#151524 - @nate-thegrate, please let me know if I need to make changes in order for this PR to be merged The motivation behind this change is to provide developers with more control over the spacing between the `MenuAnchor` and `dropdownMenuEntries` in the `DropdownMenu` widget. This enhancement allows for better alignment and customization of the dropdown menu appearance. | before | after | | :---: | :---: | | <img width="372" alt="Screenshot 2024-07-14 at 8 03 14�PM" src="https://github.com/user-attachments/assets/4a45b843-7fa4-44fd-843c-c7209c6f57ae"> | <img width="364" alt="Screenshot 2024-07-14 at 8 03 27�PM" src="https://github.com/user-attachments/assets/12e8b857-aefb-4aaf-a310-4a002abcbc2f"> | Initially, it was suggested to use a `SizedBox` to introduce spacing. However, upon further examination of the source code, it was discovered that the `DropdownMenuEntries` are rendered on the screen via an `OverlayPortal`. This necessitated leveraging the existing `alignmentOffset` property within the `MenuAnchor` for a more seamless and effective alignment adjustment.
1 parent f060312 commit 6fdcb0a

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

packages/flutter/lib/src/material/dropdown_menu.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ class DropdownMenu<T> extends StatefulWidget {
175175
this.expandedInsets,
176176
this.filterCallback,
177177
this.searchCallback,
178+
this.alignmentOffset,
178179
required this.dropdownMenuEntries,
179180
this.inputFormatters,
180181
}) : assert(filterCallback == null || enableFilter);
@@ -475,6 +476,9 @@ class DropdownMenu<T> extends StatefulWidget {
475476
/// and notifies its listeners on [TextEditingValue] changes.
476477
final List<TextInputFormatter>? inputFormatters;
477478

479+
/// {@macro flutter.material.MenuAnchor.alignmentOffset}
480+
final Offset? alignmentOffset;
481+
478482
@override
479483
State<DropdownMenu<T>> createState() => _DropdownMenuState<T>();
480484
}
@@ -784,6 +788,7 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
784788

785789
Widget menuAnchor = MenuAnchor(
786790
style: effectiveMenuStyle,
791+
alignmentOffset: widget.alignmentOffset,
787792
controller: _controller,
788793
menuChildren: menu,
789794
crossAxisUnconstrained: false,

packages/flutter/lib/src/material/menu_anchor.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ class MenuAnchor extends StatefulWidget {
181181
/// Defaults to the ambient [MenuThemeData.style].
182182
final MenuStyle? style;
183183

184+
/// {@template flutter.material.MenuAnchor.alignmentOffset}
184185
/// The offset of the menu relative to the alignment origin determined by
185186
/// [MenuStyle.alignment] on the [style] attribute and the ambient
186187
/// [Directionality].
@@ -201,6 +202,7 @@ class MenuAnchor extends StatefulWidget {
201202
/// [alignmentOffset] move the menu position to the left.
202203
///
203204
/// Defaults to [Offset.zero].
205+
/// {@endtemplate}
204206
final Offset? alignmentOffset;
205207

206208
/// {@macro flutter.material.Material.clipBehavior}

packages/flutter/test/material/dropdown_menu_test.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2432,6 +2432,28 @@ void main() {
24322432
final TextField textField = tester.widget(find.byType(TextField));
24332433
expect(textField.keyboardType, TextInputType.text);
24342434
});
2435+
2436+
testWidgets('DropdownMenu passes an alignmentOffset to MenuAnchor', (WidgetTester tester) async {
2437+
const Offset alignmentOffset = Offset(0, 16);
2438+
2439+
await tester.pumpWidget(
2440+
const MaterialApp(
2441+
home: Scaffold(
2442+
body: DropdownMenu<String>(
2443+
alignmentOffset: alignmentOffset,
2444+
dropdownMenuEntries: <DropdownMenuEntry<String>>[
2445+
DropdownMenuEntry<String>(value: '1', label: 'One'),
2446+
DropdownMenuEntry<String>(value: '2', label: 'Two'),
2447+
],
2448+
),
2449+
),
2450+
),
2451+
);
2452+
2453+
final MenuAnchor menuAnchor = tester.widget<MenuAnchor>(find.byType(MenuAnchor));
2454+
2455+
expect(menuAnchor.alignmentOffset, alignmentOffset);
2456+
});
24352457
}
24362458

24372459
enum TestMenu {

0 commit comments

Comments
 (0)