@@ -259,7 +259,7 @@ class _AnimatedScaleOnTapState extends State<AnimatedScaleOnTap> {
259259 }
260260}
261261
262- /// The rounded-rectangle shape and 1-pixel spacing for a run of [MenuButton ] s.
262+ /// The rounded-rectangle shape and 1-pixel spacing for a run of [ZulipMenuItemButton ] s.
263263class MenuButtonsShape extends StatelessWidget {
264264 const MenuButtonsShape ({
265265 super .key,
@@ -277,21 +277,25 @@ class MenuButtonsShape extends StatelessWidget {
277277 }
278278}
279279
280- /// The "menu button" component in Figma.
280+ /// The "menu button" or "list button" component in Figma.
281+ ///
282+ /// Use [ZulipMenuItemButtonStyle] to choose between components.
281283///
282284/// Must have a [MenuButtonsShape] ancestor.
283285///
284286/// See Figma:
285287/// https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=6070-60681&m=dev
286- class MenuButton extends StatelessWidget {
287- const MenuButton ({
288+ class ZulipMenuItemButton extends StatelessWidget {
289+ const ZulipMenuItemButton ({
288290 super .key,
291+ this .style = ZulipMenuItemButtonStyle .menu,
289292 required this .label,
290293 required this .onPressed,
291294 this .icon,
292295 this .toggle,
293296 });
294297
298+ final ZulipMenuItemButtonStyle style;
295299 final String label;
296300 final VoidCallback onPressed;
297301 final IconData ? icon;
@@ -300,22 +304,63 @@ class MenuButton extends StatelessWidget {
300304 ///
301305 /// See Figma:
302306 /// https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=6070-60682&m=dev
307+ // TODO(design) Is the toggle option meant only for
308+ // [ZulipMenuItemButtonStyle.menu]?
303309 final Widget ? toggle;
304310
305- static double itemSpacing = 16 ;
311+ double get itemSpacingAndEndPadding => switch (style) {
312+ ZulipMenuItemButtonStyle .menu => 16 ,
313+ ZulipMenuItemButtonStyle .list => 12 ,
314+ };
306315
307316 static bool _debugCheckShapeAncestor (BuildContext context) {
308317 final ancestor = context.findAncestorWidgetOfExactType <MenuButtonsShape >();
309318 assert (() {
310319 if (ancestor != null ) return true ;
311320 throw FlutterError .fromParts ([
312321 ErrorSummary ('No MenuButtonsShape ancestor found.' ),
313- ErrorDescription ('MenuButton widgets require a MenuButtonsShape ancestor.' ),
322+ ErrorDescription ('ZulipMenuItemButton widgets require a MenuButtonsShape ancestor.' ),
314323 ]);
315324 }());
316325 return true ;
317326 }
318327
328+ WidgetStateColor _backgroundColor (DesignVariables designVariables) {
329+ switch (style) {
330+ case ZulipMenuItemButtonStyle .menu:
331+ return WidgetStateColor .fromMap ({
332+ WidgetState .pressed: designVariables.contextMenuItemBg.withFadedAlpha (0.20 ),
333+ ~ WidgetState .pressed: designVariables.contextMenuItemBg.withFadedAlpha (0.12 ),
334+ });
335+ case ZulipMenuItemButtonStyle .list:
336+ return WidgetStateColor .fromMap ({
337+ WidgetState .pressed: designVariables.listMenuItemBg.withFadedAlpha (0.7 ),
338+ ~ WidgetState .pressed: designVariables.listMenuItemBg.withFadedAlpha (0.35 ),
339+ });
340+ }
341+ }
342+
343+ Color _labelColor (DesignVariables designVariables) {
344+ return switch (style) {
345+ ZulipMenuItemButtonStyle .menu => designVariables.contextMenuItemText,
346+ ZulipMenuItemButtonStyle .list => designVariables.listMenuItemText,
347+ };
348+ }
349+
350+ double _labelWght () {
351+ return switch (style) {
352+ ZulipMenuItemButtonStyle .menu => 600 ,
353+ ZulipMenuItemButtonStyle .list => 500 ,
354+ };
355+ }
356+
357+ Color _iconColor (DesignVariables designVariables) {
358+ return switch (style) {
359+ ZulipMenuItemButtonStyle .menu => designVariables.contextMenuItemIcon,
360+ ZulipMenuItemButtonStyle .list => designVariables.listMenuItemIcon,
361+ };
362+ }
363+
319364 @override
320365 Widget build (BuildContext context) {
321366 _debugCheckShapeAncestor (context);
@@ -331,35 +376,48 @@ class MenuButton extends StatelessWidget {
331376 // This Material widget gives us 12px padding before the icon --
332377 // or more or less, depending on Theme.of(context).visualDensity,
333378 // hence the `assert` above.
334- padding: EdgeInsetsDirectional .only (start: itemSpacing - 12 ),
379+ padding: EdgeInsetsDirectional .only (start: itemSpacingAndEndPadding - 12 ),
335380
336381 child: Row (
337382 mainAxisSize: MainAxisSize .min,
338383 crossAxisAlignment: CrossAxisAlignment .center,
339- spacing: itemSpacing ,
384+ spacing: itemSpacingAndEndPadding ,
340385 children: [
341386 if (toggle != null ) toggle! ,
342- if (icon != null ) Icon (icon! , color: designVariables.contextMenuItemIcon ),
387+ if (icon != null ) Icon (icon! , color: _iconColor ( designVariables) ),
343388 ]))
344389 : null ,
345390 style: MenuItemButton .styleFrom (
346391 minimumSize: Size .fromHeight (48 ),
347- padding: const EdgeInsets . symmetric (horizontal : 16 ),
348- foregroundColor: designVariables.contextMenuItemText ,
392+ padding: EdgeInsetsDirectional . only (start : 16 , end : itemSpacingAndEndPadding ),
393+ foregroundColor: _labelColor ( designVariables) ,
349394 splashFactory: NoSplash .splashFactory,
350- ).copyWith (backgroundColor: WidgetStateColor .resolveWith ((states) =>
351- designVariables.contextMenuItemBg.withFadedAlpha (
352- states.contains (WidgetState .pressed) ? 0.20 : 0.12 ))),
395+ ).copyWith (backgroundColor: _backgroundColor (designVariables)),
353396 onPressed: onPressed,
354397 child: Padding (
355398 padding: const EdgeInsets .symmetric (vertical: 4 ),
399+ // TODO sublabel, for [ZulipMenuItemButtonStyle.list]
356400 child: Text (label,
357401 style: const TextStyle (fontSize: 20 , height: 24 / 20 )
358- .merge (weightVariableTextStyle (context, wght: 600 ))),
359- ));
402+ .merge (weightVariableTextStyle (context, wght: _labelWght ())))));
360403 }
361404}
362405
406+ /// The style of a [ZulipMenuItemButton] .
407+ enum ZulipMenuItemButtonStyle {
408+ /// The purple "menu button" component in Figma, with 16px end padding.
409+ ///
410+ /// See Figma:
411+ /// https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=3302-20443&m=dev
412+ menu,
413+
414+ /// The gray "list button" component in Figma, with 12px end padding.
415+ ///
416+ /// See Figma:
417+ /// https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=5000-52868&m=dev
418+ list,
419+ }
420+
363421/// The "toggle" component in Figma.
364422///
365423/// See Figma:
0 commit comments