import 'package:flutter/material.dart'; class ContextualActions extends InheritedWidget { final ContextualActionState _state = ContextualActionState(); ContextualActions({Key? key, required Widget child}) : super(key: key, child: child); static ContextualActions of(BuildContext context) { final ContextualActions? result = context.dependOnInheritedWidgetOfExactType(); assert(result != null, 'No ContextualActions found in context'); return result!; } Set get actions => _state.actions; set actions(Set actions) => _state.actions = actions; List buildAppBar() => _state.buildAppBar(); List buildContextMenu(BuildContext context) => _state.buildContextMenu(context); @override bool updateShouldNotify(covariant ContextualActions oldWidget) => _state != oldWidget._state; } class ContextualActionState { /// the currently set [ContextualActions] /// /// use [replace] instead of `=` operator Set actions = {}; Set contextMenuOnly = {}; /// unregisters all present actions and adds riven [newActions] void replace(Iterable newActions) { actions.removeWhere((element) => true); actions.addAll(newActions); } /// buildseach item of [actions] as [IconButton] for use in AppBar List buildAppBar() { return actions .map( (action) => IconButton( icon: action.icon, tooltip: action.label, onPressed: action.action, ), ) .toList(); } /// builds each item of [actions] as [ListTile] for use in a [ContextMenuArea] List buildContextMenu(BuildContext context) { return actions .map( (action) => ListTile( leading: action.icon, title: Text(action.label), onTap: () { Navigator.of(context).pop(); action.action.call(); }, ), ) .toList(); } } class ContextualAction { final VoidCallback action; final Widget icon; final String label; const ContextualAction( {required this.action, required this.icon, required this.label}); }