Skip to content

Commit

Permalink
Add a simplified SimpleCascadingMenuApp example (flutter#149147)
Browse files Browse the repository at this point in the history
The current MenuAnchor example in the API Docs is comprehensive and complicated for beginners. I have added a simple bare bone example without shortcuts, enums, etc in examples/api/lib/material/menu_anchor/ as `menu_anchor.3.dart`. The example is contributed by @mafreud

Fixes flutter#148104
  • Loading branch information
kaljitism authored Jun 3, 2024
1 parent 8e15e56 commit 0e7295f
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 0 deletions.
81 changes: 81 additions & 0 deletions examples/api/lib/material/menu_anchor/menu_anchor.3.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// 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';

/// Flutter code sample for [SimpleCascadingMenuApp].
void main() => runApp(const SimpleCascadingMenuApp());

/// A Simple Cascading Menu example using the [MenuAnchor] Widget.
class MyCascadingMenu extends StatefulWidget {
const MyCascadingMenu({super.key});

@override
State<MyCascadingMenu> createState() => _MyCascadingMenuState();
}

class _MyCascadingMenuState extends State<MyCascadingMenu> {
final FocusNode _buttonFocusNode = FocusNode(debugLabel: 'Menu Button');

@override
void dispose() {
_buttonFocusNode.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return MenuAnchor(
childFocusNode: _buttonFocusNode,
menuChildren: <Widget>[
MenuItemButton(
onPressed: () {},
child: const Text('Revert'),
),
MenuItemButton(
onPressed: () {},
child: const Text('Setting'),
),
MenuItemButton(
onPressed: () {},
child: const Text('Send Feedback'),
),
],
builder: (_, MenuController controller, Widget? child) {
return IconButton(
focusNode: _buttonFocusNode,
onPressed: () {
if (controller.isOpen) {
controller.close();
} else {
controller.open();
}
},
icon: const Icon(Icons.more_vert),
);
},
);
}
}

/// Top Level Application Widget.
class SimpleCascadingMenuApp extends StatelessWidget {
const SimpleCascadingMenuApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: const Text('MenuAnchor Simple Example'),
actions: const <Widget>[
MyCascadingMenu(),
],
),
),
);
}
}
36 changes: 36 additions & 0 deletions examples/api/test/material/menu_anchor/menu_anchor.3_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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/menu_anchor/menu_anchor.3.dart' as example;
import 'package:flutter_test/flutter_test.dart';

void main() {
testWidgets('Menu button opens and closes the menu', (WidgetTester tester) async {
await tester.pumpWidget(const example.SimpleCascadingMenuApp());

// Find the menu button.
final Finder menuButton = find.byType(IconButton);
expect(menuButton, findsOneWidget);

// Tap the menu button to open the menu.
await tester.tap(menuButton);
await tester.pumpAndSettle();

// Verify that the menu is open.
expect(find.text('Revert'), findsOneWidget);

// Tap the menu button again to close the menu.
await tester.tap(menuButton);
await tester.pumpAndSettle();

// Verify that the menu is closed.
expect(find.text('Revert'), findsNothing);
});

testWidgets('Does not show debug banner', (WidgetTester tester) async {
await tester.pumpWidget(const example.SimpleCascadingMenuApp());
expect(find.byType(CheckedModeBanner), findsNothing);
});
}
7 changes: 7 additions & 0 deletions packages/flutter/lib/src/material/menu_anchor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ typedef MenuAnchorChildBuilder = Widget Function(
///
/// ** See code in examples/api/lib/material/menu_anchor/menu_anchor.1.dart **
/// {@end-tool}
///
/// {@tool dartpad}
/// This example demonstrates a simplified cascading menu using the [MenuAnchor]
/// widget.
///
/// ** See code in examples/api/lib/material/menu_anchor/menu_anchor.3.dart **
/// {@end-tool}
class MenuAnchor extends StatefulWidget {
/// Creates a const [MenuAnchor].
///
Expand Down

0 comments on commit 0e7295f

Please sign in to comment.