Skip to content

Commit 5b33d14

Browse files
committed
home: Tweak main-menu buttons to follow Figma
The buttons were 48px instead of 44px tall, and the label's line height was 26px instead of 23px.
1 parent 381b1f6 commit 5b33d14

File tree

2 files changed

+56
-28
lines changed

2 files changed

+56
-28
lines changed

lib/widgets/home.dart

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,13 @@ void _showMainMenu(BuildContext context, {
399399
});
400400
}
401401

402-
abstract class _MenuButton extends StatelessWidget {
403-
const _MenuButton();
402+
/// A button in the main menu.
403+
///
404+
/// See Figma:
405+
/// https://www.figma.com/design/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?node-id=2037-243759&m=dev
406+
@visibleForTesting
407+
abstract class MenuButton extends StatelessWidget {
408+
const MenuButton({super.key});
404409

405410
String label(ZulipLocalizations zulipLocalizations);
406411

@@ -437,11 +442,20 @@ abstract class _MenuButton extends StatelessWidget {
437442
final designVariables = DesignVariables.of(context);
438443
final zulipLocalizations = ZulipLocalizations.of(context);
439444

445+
// Make [TextButton] set 44 instead of 48 for the height.
446+
final visualDensity = VisualDensity(vertical: -1);
447+
// A value that [TextButton] adds to some of its layout parameters;
448+
// we can cancel out those adjustments by subtracting it.
449+
final densityVerticalAdjustment = visualDensity.baseSizeAdjustment.dy;
450+
440451
final borderSideSelected = BorderSide(width: 1,
441452
strokeAlign: BorderSide.strokeAlignOutside,
442453
color: designVariables.borderMenuButtonSelected);
443454
final buttonStyle = TextButton.styleFrom(
444-
padding: const EdgeInsets.symmetric(vertical: 9, horizontal: 8),
455+
// Make the button 44px instead of 48px tall, to match the Figma.
456+
visualDensity: visualDensity,
457+
padding: EdgeInsets.symmetric(
458+
vertical: 10 - densityVerticalAdjustment, horizontal: 8),
445459
foregroundColor: designVariables.labelMenuButton,
446460
// This has a default behavior of affecting the background color of the
447461
// button for states including "hovered", "focused" and "pressed".
@@ -467,26 +481,24 @@ abstract class _MenuButton extends StatelessWidget {
467481
return AnimatedScaleOnTap(
468482
duration: const Duration(milliseconds: 100),
469483
scaleEnd: 0.95,
470-
child: ConstrainedBox(
471-
constraints: const BoxConstraints(minHeight: 44),
472-
child: TextButton(
473-
onPressed: () => _handlePress(context),
474-
style: buttonStyle,
475-
child: Row(spacing: 8, children: [
476-
SizedBox.square(dimension: _iconSize,
477-
child: buildLeading(context)),
478-
Expanded(child: Text(label(zulipLocalizations),
479-
// TODO(design): determine if we prefer to wrap
480-
overflow: TextOverflow.ellipsis,
481-
style: const TextStyle(fontSize: 19, height: 26 / 19)
482-
.merge(weightVariableTextStyle(context, wght: selected ? 600 : 400)))),
483-
?trailing,
484-
]))));
484+
child: TextButton(
485+
onPressed: () => _handlePress(context),
486+
style: buttonStyle,
487+
child: Row(spacing: 8, children: [
488+
SizedBox.square(dimension: _iconSize,
489+
child: buildLeading(context)),
490+
Expanded(child: Text(label(zulipLocalizations),
491+
// TODO(design): determine if we prefer to wrap
492+
overflow: TextOverflow.ellipsis,
493+
style: const TextStyle(fontSize: 19, height: 23 / 19)
494+
.merge(weightVariableTextStyle(context, wght: selected ? 600 : 400)))),
495+
?trailing,
496+
])));
485497
}
486498
}
487499

488500
/// A menu button controlling the selected [_HomePageTab] on the bottom nav bar.
489-
abstract class _NavigationBarMenuButton extends _MenuButton {
501+
abstract class _NavigationBarMenuButton extends MenuButton {
490502
const _NavigationBarMenuButton({required this.tabNotifier});
491503

492504
final ValueNotifier<_HomePageTab> tabNotifier;
@@ -502,7 +514,7 @@ abstract class _NavigationBarMenuButton extends _MenuButton {
502514
}
503515
}
504516

505-
class _SearchButton extends _MenuButton {
517+
class _SearchButton extends MenuButton {
506518
const _SearchButton();
507519

508520
@override
@@ -547,7 +559,7 @@ class _InboxButton extends _NavigationBarMenuButton {
547559
_HomePageTab get navigationTarget => _HomePageTab.inbox;
548560
}
549561

550-
class _MentionsButton extends _MenuButton {
562+
class _MentionsButton extends MenuButton {
551563
const _MentionsButton();
552564

553565
@override
@@ -577,7 +589,7 @@ class _MentionsButton extends _MenuButton {
577589
}
578590
}
579591

580-
class _StarredMessagesButton extends _MenuButton {
592+
class _StarredMessagesButton extends MenuButton {
581593
const _StarredMessagesButton();
582594

583595
@override
@@ -595,7 +607,7 @@ class _StarredMessagesButton extends _MenuButton {
595607
}
596608
}
597609

598-
class _CombinedFeedButton extends _MenuButton {
610+
class _CombinedFeedButton extends MenuButton {
599611
const _CombinedFeedButton();
600612

601613
@override
@@ -655,7 +667,7 @@ class _DirectMessagesButton extends _NavigationBarMenuButton {
655667
_HomePageTab get navigationTarget => _HomePageTab.directMessages;
656668
}
657669

658-
class _MyProfileButton extends _MenuButton {
670+
class _MyProfileButton extends MenuButton {
659671
const _MyProfileButton();
660672

661673
@override
@@ -666,7 +678,7 @@ class _MyProfileButton extends _MenuButton {
666678
final store = PerAccountStoreWidget.of(context);
667679
return Avatar(
668680
userId: store.selfUserId,
669-
size: _MenuButton._iconSize,
681+
size: MenuButton._iconSize,
670682
borderRadius: 4,
671683
showPresence: false,
672684
);
@@ -685,7 +697,7 @@ class _MyProfileButton extends _MenuButton {
685697
}
686698
}
687699

688-
class _SwitchAccountButton extends _MenuButton {
700+
class _SwitchAccountButton extends MenuButton {
689701
const _SwitchAccountButton();
690702

691703
@override
@@ -702,7 +714,7 @@ class _SwitchAccountButton extends _MenuButton {
702714
}
703715
}
704716

705-
class _SettingsButton extends _MenuButton {
717+
class _SettingsButton extends MenuButton {
706718
const _SettingsButton();
707719

708720
@override
@@ -719,7 +731,7 @@ class _SettingsButton extends _MenuButton {
719731
}
720732
}
721733

722-
class _AboutZulipButton extends _MenuButton {
734+
class _AboutZulipButton extends MenuButton {
723735
const _AboutZulipButton();
724736

725737
@override

test/widgets/home_test.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,22 @@ void main () {
255255
.isSameColorAs(designVariables.icon);
256256
}
257257

258+
testWidgets('buttons are 44px tall', (tester) async {
259+
await prepare(tester);
260+
261+
await tapOpenMenuAndAwait(tester);
262+
checkIconSelected(tester, inboxMenuIconFinder);
263+
checkIconNotSelected(tester, channelsMenuIconFinder);
264+
265+
final inboxElement = tester.element(
266+
find.ancestor(of: inboxMenuIconFinder, matching: find.bySubtype<MenuButton>()));
267+
check((inboxElement.renderObject as RenderBox).size).height.equals(44);
268+
269+
final channelsElement = tester.element(
270+
find.ancestor(of: inboxMenuIconFinder, matching: find.bySubtype<MenuButton>()));
271+
check((channelsElement.renderObject as RenderBox).size).height.equals(44);
272+
});
273+
258274
testWidgets('navigation states reflect on navigation bar menu buttons', (tester) async {
259275
await prepare(tester);
260276

0 commit comments

Comments
 (0)