Skip to content
This repository was archived by the owner on May 20, 2023. It is now read-only.

Commit 9cfe369

Browse files
rkjnshahan
authored andcommitted
Add a way to pass context to the MenuItem action.
This is needed to pass the HTML element triggering menu interaction for a11y in the datepicker. Remove nullAwareAction, it is a relic from the past. PiperOrigin-RevId: 259777943
1 parent 66e9984 commit 9cfe369

File tree

4 files changed

+82
-21
lines changed

4 files changed

+82
-21
lines changed

angular_components/lib/material_menu/menu_item_groups.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ class MenuItemGroupsComponent
271271
}
272272

273273
void select(MenuItem item, MenuItemGroup group) {
274-
item.nullAwareActionHandler();
274+
item.action?.call();
275275

276276
// Fire the event for activating the menu item. This does not mean the item
277277
// is selected, but merely that it was triggered (by mouse, keyboard, w/e).

angular_components/lib/model/menu/delegating_menu_item.dart

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,21 @@ class DelegatingMenuItem<SubMenuType> implements MenuItem<SubMenuType> {
1515
DelegatingMenuItem(this._delegate);
1616

1717
@override
18-
Function get action => _delegate.action;
18+
MenuAction get action => _delegate.action;
1919

2020
@override
21-
set action(Function action) {
21+
set action(MenuAction action) {
2222
_delegate.action = action;
2323
}
2424

25+
@override
26+
ActionWithContext get actionWithContext => _delegate.actionWithContext;
27+
28+
@override
29+
set actionWithContext(ActionWithContext actionWithContext) {
30+
_delegate.actionWithContext = actionWithContext;
31+
}
32+
2533
@override
2634
bool get enabled => _delegate.enabled;
2735

@@ -51,9 +59,6 @@ class DelegatingMenuItem<SubMenuType> implements MenuItem<SubMenuType> {
5159
@override
5260
String get ariaLabel => _delegate.ariaLabel;
5361

54-
@override
55-
Function get nullAwareActionHandler => _delegate.nullAwareActionHandler;
56-
5762
@override
5863
bool get showTooltip => _delegate.showTooltip;
5964

angular_components/lib/model/menu/menu.dart

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,26 @@ class MenuItem<T> with MenuItemMixin implements HasUIDisplayName, HasIcon {
153153
final String labelAnnotation;
154154
final MenuModel<T> subMenu;
155155

156-
Function action;
156+
// This should be final as all the other state in this class, but needs
157+
// to first migrate clients.
158+
ActionWithContext _actionWithContext;
159+
160+
/// Action to perform when user select an item in the menu.
161+
ActionWithContext get actionWithContext => _actionWithContext;
162+
@Deprecated('This should be final.')
163+
set actionWithContext(ActionWithContext value) {
164+
_actionWithContext = value;
165+
_action = () => value(null);
166+
}
167+
168+
MenuAction _action;
169+
170+
@Deprecated('Use actionWithContext')
171+
MenuAction get action => _action;
172+
set action(MenuAction value) {
173+
_action = value;
174+
_actionWithContext = (_) => value();
175+
}
157176

158177
final Icon icon;
159178

@@ -185,7 +204,8 @@ class MenuItem<T> with MenuItemMixin implements HasUIDisplayName, HasIcon {
185204
MenuItem(this.label,
186205
{this.enabled = true,
187206
this.tooltip,
188-
this.action,
207+
@Deprecated('Use ActionWithContext') MenuAction action,
208+
ActionWithContext actionWithContext,
189209
this.icon,
190210
this.labelAnnotation,
191211
Iterable<String> cssClasses,
@@ -201,6 +221,13 @@ class MenuItem<T> with MenuItemMixin implements HasUIDisplayName, HasIcon {
201221
ariaLabel = ariaLabel ?? label {
202222
assert(itemSuffix == null || itemSuffixes == null,
203223
'Only one of itemSuffix or itemSuffixes should be provided');
224+
assert(action == null || actionWithContext == null,
225+
'Only one of action or actionWithContext should be provided');
226+
if (action != null) {
227+
this.action = action;
228+
} else if (actionWithContext != null) {
229+
this.actionWithContext = actionWithContext;
230+
}
204231
}
205232

206233
@override
@@ -216,19 +243,24 @@ class MenuItem<T> with MenuItemMixin implements HasUIDisplayName, HasIcon {
216243

217244
/// Required members to use [MenuItemMixin].
218245
abstract class _MenuItemBase {
219-
Function get action;
246+
ActionWithContext get actionWithContext;
220247
Icon get icon;
221248
String get label;
222249
String get secondaryLabel;
223250
String get tooltip;
224251
MenuModel get subMenu;
225252
}
226253

254+
/// Action triggered by interaction with the menu.
255+
typedef MenuAction = void Function();
256+
257+
/// Action triggered by interaction with the menu.
258+
///
259+
/// For web menus `context` should be the UIEvent.
260+
typedef ActionWithContext = void Function(dynamic context);
261+
227262
/// Mixin to implement trivial getters on [MenuItem].
228263
abstract class MenuItemMixin implements _MenuItemBase {
229-
void _noop() {}
230-
Function get nullAwareActionHandler => action != null ? action : _noop;
231-
232264
bool get hasIcon => icon != null;
233265

234266
String get uiDisplayName => label;

angular_components/lib/model/menu/selectable_menu.dart

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ class MenuItemGroupWithSelection<SelectionItemType>
6868
/// A selectable [MenuItem].
6969
class SelectableMenuItem<ItemType> extends PropertyChangeNotifier
7070
implements MenuItem {
71-
Function _action;
71+
MenuAction _action;
72+
ActionWithContext _actionWithContext;
7273
SelectableOption _selectableState;
7374
String ariaChecked;
7475

@@ -132,20 +133,32 @@ class SelectableMenuItem<ItemType> extends PropertyChangeNotifier
132133
this.secondaryLabel,
133134
this.labelAnnotation,
134135
Iterable<String> cssClasses,
135-
Function action = _noOp,
136+
MenuAction action,
137+
ActionWithContext actionWithContext,
136138
SelectableOption selectableState = SelectableOption.Selectable,
137139
bool shouldSelectOnItemClick,
138140
MenuItemAffix itemSuffix,
139141
ObservableList<MenuItemAffix> itemSuffixes})
140-
: _action = action,
141-
_selectableState = selectableState,
142+
: _selectableState = selectableState,
142143
shouldSelectOnItemClick = shouldSelectOnItemClick ?? subMenu == null,
143144
itemSuffixes = itemSuffixes ??
144145
ObservableList<MenuItemAffix>.from(
145146
Optional.fromNullable(itemSuffix)),
146147
cssClasses = BuiltList<String>(cssClasses ?? const []) {
147148
assert(itemSuffix == null || itemSuffixes == null,
148149
'Only one of itemSuffix or itemSuffixes should be provided');
150+
assert(action == null || actionWithContext == null,
151+
'Only one of action or actionWithContext should be provided');
152+
if (action != null) {
153+
_action = action;
154+
_actionWithContext = (_) => action();
155+
} else if (actionWithContext != null) {
156+
_action = () => actionWithContext(null);
157+
_actionWithContext = actionWithContext;
158+
} else {
159+
_action = _noOp;
160+
_actionWithContext = _noOp2;
161+
}
149162
}
150163

151164
@override
@@ -154,9 +167,6 @@ class SelectableMenuItem<ItemType> extends PropertyChangeNotifier
154167
@override
155168
String get ariaLabel => label;
156169

157-
@override
158-
Function get nullAwareActionHandler => _action ?? _noOp;
159-
160170
@override
161171
bool get hasIcon => icon != null;
162172

@@ -182,16 +192,29 @@ class SelectableMenuItem<ItemType> extends PropertyChangeNotifier
182192
}
183193

184194
@override
185-
Function get action => _action;
195+
MenuAction get action => _action;
186196

187197
@override
188-
set action(Function value) {
198+
set action(MenuAction value) {
189199
if (value == _action) return;
190200

191201
_action = value;
202+
_actionWithContext = (_) => value();
192203
notifyPropertyChange(#action, _action, value);
193204
}
194205

206+
@override
207+
ActionWithContext get actionWithContext => _actionWithContext;
208+
209+
@override
210+
set actionWithContext(ActionWithContext value) {
211+
if (value == _actionWithContext) return;
212+
213+
_actionWithContext = value;
214+
_action = () => value(null);
215+
notifyPropertyChange(#actionWithContext, _actionWithContext, value);
216+
}
217+
195218
@override
196219
bool get hasSecondaryLabel => secondaryLabel != null;
197220

@@ -207,3 +230,4 @@ class SelectableMenuItem<ItemType> extends PropertyChangeNotifier
207230
}
208231

209232
void _noOp() {}
233+
void _noOp2(_) {}

0 commit comments

Comments
 (0)