Component: Button Group
Work Item: WI-2124
ViewModel: ButtonGroupViewModel : ContainerSurfaceViewModel
Figma Keys: card-btn + button-sm
Last Updated: 2026-06-02
Shows how ButtonGroupViewModel properties map to the rendered control.
Title (optional)
│
▼
┌────────────────────────────────────────────────────┐
│ │
│ ┌──────────────────┐ ┌──────────────────┐ ... │
Buttons ──────►│ │ [button-sm #0] │ │ [button-sm #1] │ │◄── ObservableCollection<ButtonViewModel>
│ │ ┌────────────┐ │ │ ┌────────────┐ │ │
│ │ │ Member │ │ │ │ Member │ │ │◄── ButtonViewModel.Text (#ffffff, Futura LT Pro Bold 12px)
│ │ │ Number │ │ │ │ Number │ │ │
│ │ └────────────┘ │ │ └────────────┘ │ │
│ │ fill=#007bc2 │ │ fill=#007bc2 │ ... │◄── color-token: alpa-blue (#007bc2)
│ └──────────────────┘ └──────────────────┘ │
│ │
└────────────────────────────────────────────────────┘
card-btn: 116×106px, fill=#ffffff, stroke=1px
button-sm: 151×36px, fill=#007bc2, corner-radius=4px
ButtonViewModel.TapCommand ──► Navigation / action per button ◄── ⚠️ TBD: destination source
IsLoading ──────────────► Default strategy — no skeleton/overlay
IsVisible ──────────────► Controls card-level visibility ◄── ⚠️ TBD: condition source
⚠ Data Gaps:
ButtonViewModel.TapCommand — navigation destination/route TBD at presentation layer
ButtonViewModel.Icon — ImageSource provider TBD (resource vs remote)
Title — optional header; source TBD
IsVisible — visibility condition TBD
Note: No existing
ButtonGroupViewModelwas found in the codebase at the time of this analysis.
The nearest patterns areMemberCardCarouselViewModel(for member-number display) and
JumpseatToolCardViewModel(for multi-step command-driven card flows).
This document serves as the reference spec for the implementation phase.
| Property | Status | Source | Notes |
|---|---|---|---|
| Buttons | ⚠️ TBD | ViewModel state / config | ObservableCollection<ButtonViewModel> — items defined by use case |
| ButtonViewModel.Text | ⚠️ TBD | Static label or localized resource | White text (#ffffff) on ALPA blue (#007bc2) |
| ButtonViewModel.Icon | ⚠️ TBD | App resource / ImageSource |
Optional — present in Figma layer tree |
| ButtonViewModel.TapCommand | ⚠️ TBD | ViewModel command / INavigation |
Destination route TBD per button |
| ButtonViewModel.Link | ⚠️ TBD | Navigation route string or URL | Resolved via SharedActionsService or Shell navigation |
| Title | ⚠️ TBD | Static label or IAuthentication |
Optional card header; may be omitted |
| IsLoading | ✅ Available | ViewModel state | Default strategy (no skeleton) |
| IsVisible | ⚠️ TBD | ViewModel state | Card-level visibility condition TBD |
| Token | Hex | Usage |
|---|---|---|
alpa-blue |
#007bc2 |
button-sm background fill |
white |
#ffffff |
button-sm text (Member Number label), card fill |
alpa-navy |
#05273e |
Card body text (from layer tree United Airlines TEXT node) |
Typography:
- button-sm label: Futura LT Pro Bold 12px — #ffffff on #007bc2
/// <summary>
/// ViewModel for the Button Group component.
/// Derives from CardViewModel. Each button is represented by a ButtonViewModel.
/// Populate Buttons in the concrete use-case subclass.
/// </summary>
public class ButtonGroupViewModel : ContainerSurfaceViewModel
{
private ObservableCollection<ButtonViewModel> buttons = new();
public ObservableCollection<ButtonViewModel> Buttons
{
get => buttons;
set
{
buttons = value;
OnPropertyChanged(nameof(Buttons));
}
}
/// <summary>Optional card header text.</summary>
// Title inherits from CardViewModel.HeaderText (⚠️ TBD: confirm base class field name)
}
/// <summary>
/// Represents a single button-sm instance within a Button Group.
/// </summary>
public class ButtonViewModel
{
/// <summary>Button label text. Rendered white on ALPA blue (#007bc2).</summary>
public string Text { get; set; } = string.Empty;
/// <summary>Optional icon above the label. Source TBD (app resource vs remote).</summary>
public ImageSource? Icon { get; set; }
/// <summary>Navigation route or URL. Resolved via SharedActionsService or Shell.Current.GoToAsync.</summary>
public string? Link { get; set; }
/// <summary>Tap command — wired in ViewModel, invokes Link navigation.</summary>
public ICommand? TapCommand { get; set; }
}
ObservableCollection<ButtonViewModel>AppResources)#ffffff) text, Futura LT Pro Bold 12px, on ALPA blue (#007bc2) backgroundMember Number TEXT node (127×12px) inside button-smImageSource.FromFile) or remote URLi-heart and circle-icon instances visible in Figma layer tree; concrete icons TBD per buttonLink navigationFTDTOperationTypeSelectionPageViewModel.NavigateCommand and BannerPageViewModel.PageBannerNavigateCommandSharedActionsServiceLink (PilotCardFactory) (FileID → SharedActionsService)IAuthentication.GetUserInfo() context or be staticcard-btn spec; confirm whether header is part of this component| Service | Interface | Notes |
|---|---|---|
| Authentication | IAuthentication |
May provide context for Title / user-specific button set |
| Navigation | Shell.Current / INavigation |
GoToAsync for button tap routing |
| SharedActionsService | SharedActionsService |
Resolves document FileIDs/URLs for Link navigation (if applicable) |
| AppResources | Static resources | Localized button label strings and icon assets |
docs/component-specifications/button-group/button-group-component.htmldocs/component-specifications/design-tokens.htmldocs/component-specifications/card/pilot-card-property-mapping.mddocs/component-specifications/button/button-component.htmldocs/component-specifications/button/button-component.htmlALPAMobile/ViewModels/MemberCardCarouselViewModel.cs — MemberNumber propertyALPAMobile/ViewModels/FTDTOperationTypeSelectionPageViewModel.csDocument Owner: ALPA Mobile Team
Work Item: WI-2124
Purpose: Data source analysis for Button Group — identifies ViewModel properties, color tokens, and data gaps prior to implementation