Menu
A dropdown menu component for displaying a list of actions or options
A dropdown menu component for displaying actions or options in an overlay.
When to use this
- Action menus: Show a list of available actions for a selected item
- Context menus: Provide contextual options based on user selection
- Navigation: Create dropdown navigation menus
- Settings: Display configuration options in a compact dropdown
Basic implementation
Basic implementation
import 'package:flutter/material.dart';
import 'package:remix/remix.dart';
class MenuExample extends StatefulWidget {
const MenuExample({super.key});
@override
State<MenuExample> createState() => _MenuExampleState();
}
class _MenuExampleState extends State<MenuExample> {
final controller = MenuController();
@override
Widget build(BuildContext context) {
return RemixMenu<String>(
trigger: const RemixMenuTrigger(label: 'Open Menu'),
items: [
RemixMenuItem(
value: 'History',
leadingIcon: Icons.history,
label: 'History',
style: menuItemStyle,
),
RemixMenuItem(
value: 'Settings',
leadingIcon: Icons.settings,
label: 'Settings',
style: menuItemStyle,
),
const RemixMenuDivider(),
RemixMenuItem(
value: 'Logout',
leadingIcon: Icons.logout,
label: 'Logout',
style: menuItemStyle.onHovered(
RemixMenuItemStyle()
.color(Colors.redAccent.withValues(alpha: 0.05))
.label(TextStyler().color(Colors.redAccent))
.leadingIcon(IconStyler().color(Colors.redAccent)),
),
),
],
positioning: const OverlayPositionConfig(
offset: Offset(0, 8),
followerAnchor: Alignment.topCenter,
targetAnchor: Alignment.bottomCenter,
),
style: menuStyle,
onSelected: (value) {
print('Selected: $value');
},
controller: controller,
);
}
RemixMenuStyle get menuStyle {
return RemixMenuStyle()
.trigger(
RemixMenuTriggerStyle()
.padding(EdgeInsetsMix.symmetric(horizontal: 14))
.decoration(
BoxDecorationMix()
.color(Colors.white)
.borderRadius(BorderRadiusMix.all(const Radius.circular(12)))
.border(BorderMix.all(BorderSideMix(color: Colors.blueGrey.shade100)))
.boxShadow([
BoxShadowMix(
color: Colors.blueGrey.withValues(alpha: 0.1),
blurRadius: 3,
offset: const Offset(0, 3),
),
]),
)
.constraints(BoxConstraintsMix(minHeight: 40))
.label(
TextStyler()
.color(Colors.blueGrey.shade700)
.fontWeight(FontWeight.w400),
),
)
.overlay(
FlexBoxStyler(
padding: EdgeInsetsMix.all(12),
decoration: BoxDecorationMix(
color: Colors.white,
borderRadius: BorderRadiusMix.all(const Radius.circular(12)),
border: BorderMix.all(BorderSideMix(color: Colors.blueGrey.shade100)),
boxShadow: [
BoxShadowMix(
color: Colors.blueGrey.withValues(alpha: 0.1),
blurRadius: 3,
offset: const Offset(0, 3),
),
],
),
),
);
}
RemixMenuItemStyle get menuItemStyle {
return RemixMenuItemStyle()
.paddingAll(6)
.leadingIcon(IconStyler().size(20).color(Colors.blueGrey.shade800))
.spacing(8)
.borderRadiusAll(const Radius.circular(8))
.label(TextStyler().color(Colors.blueGrey.shade800))
.onHovered(RemixMenuItemStyle().color(Colors.blueGrey.shade50));
}
}
Fortal styles
Remix includes Fortal-themed style helpers for this component:
Fortal base style
import 'package:flutter/material.dart';
import 'package:remix/remix.dart';
class FortalMenuExample extends StatelessWidget {
const FortalMenuExample({super.key});
@override
Widget build(BuildContext context) {
return RemixMenu<String>(
trigger: const RemixMenuTrigger(label: 'Options'),
items: [
RemixMenuItem(
value: 'edit',
label: 'Edit',
leadingIcon: Icons.edit,
style: FortalMenuItemStyle.base(),
),
RemixMenuItem(
value: 'delete',
label: 'Delete',
leadingIcon: Icons.delete,
style: FortalMenuItemStyle.base(),
),
],
style: FortalMenuStyle.base(),
onSelected: (value) => print(value),
);
}
}
See the FortalMenuStyle source code for all available options.
Constructor
Constructor
const RemixMenu({
Key? key,
required RemixMenuTrigger trigger,
required List<Widget> items,
required ValueChanged<T>? onSelected,
MenuController? controller,
OverlayPositionConfig positioning = const OverlayPositionConfig(),
RemixMenuStyle style = const RemixMenuStyle.create(),
RemixMenuSpec? styleSpec,
})
items → List<RemixMenuItemData<T>>
Required. The list of menu items and dividers. Use [RemixMenuItem] for selectable items and [RemixMenuDivider] for separators.
controller → MenuController?
Optional. Optional controller for programmatic control of the menu state. If not provided, an internal controller will be created automatically.
onOpenRequested → RawMenuAnchorOpenRequestedCallback?
Optional. Open/close interceptors (for example, to drive animations).

