← Back to Index

Empty State Code-first dedupe, WI-2255 scaffold/atom

Updated: 2026-07-14 10:53 ET

Audited: 2026-07-14 10:53 ET

Centered placeholder for empty lists — icon + title + subtitle, with an optional CTA slot.
Tier per D40 ("compose shared atoms — StatusBadge, EmptyState"): scaffold/atom, not primitive. Implementation decision D51 (2026-07-14).
Shared atom — composed, not extended. Empty State is one of the two shared atoms named in D40. List-bearing screens compose it when their collection is empty; there is no shared base class. It is intentionally domain-free — the icon glyph, copy, and optional CTA are passed in by the host screen.
D51 corrects this page's original 2026-06-29 spec-only draft against the 4 real consumers found during implementation. Three shape changes from the original draft:

Live CSS Preview

Favorites — with icon (real usage)
No Favorites Yet
Bookmark flights, airlines, and resources for quick access
Documents List — no icon (real usage)
No Documents
Nothing is published for this scope right now.
CTA slot — illustrative, not a current consumer
🔍
No Saved Searches
Save a search to find it quickly next time

Design Tokens

Layout

Direction
column · centered
Padding
64px 32px
Text align
center

Icon

Size
48 px
Colour
gray #9ba1a8 · opacity 0.4
Margin-bottom
16 px

Title

Font
Body · 18px · weight 600
Colour
navy #05273e
Margin-bottom
8 px

Subtitle & CTA

Subtitle font
Body · 13px · lh 1.5
Subtitle colour
gray #9ba1a8
CTA (optional)
Generic ChildContent slot — arbitrary markup, not a fixed button composition

Layer Tree

└── .alpa-empty-state · flex column · centered · padding:64px 32px
    ├── .alpa-empty-state-icon [optional] · 48px · gray · opacity 0.4
    ├── .alpa-empty-state-title · TEXT · Body 18px/600 · navy
    ├── .alpa-empty-state-sub [optional] · TEXT · Body 13px · gray · lh 1.5
    └── .alpa-empty-state-cta [optional] · ChildContent slot

ViewModel

Tier: scaffold/atom (per D40's own wording). Implemented in both namespace copies per the current dual-write convention — see Component Library Reconciliation Procedure / WI-2253 for the open question about whether that convention should continue.

└── EmptyStateViewModel : ComponentViewModel
    ├── Icon : string? — optional glyph/icon name, collapses the icon slot when null
    ├── Title : string — primary line, always rendered
    └── Subtitle : string? — optional helper line

Blazor Component API

Actual home: ALPAMobile.Presentation/Components/Library/EmptyState.razor (migrated 2026-07-15, WI-2254/D61; globally imported via _Imports.razor).

ParameterTypeRequiredDescription
VmEmptyStateViewModelYesIcon/Title/Subtitle state.
Idstring?NoOptional DOM id on the wrapper — preserves pre-existing UI-test automation hooks (e.g. Favorites' favorites.emptyState1).
ChildContentRenderFragment?NoOptional CTA slot rendered below the subtitle.

Razor Usage (actual)

@if (Vm.IsEmpty)
{
    <EmptyState Id="favorites.emptyState1"
                Vm="@(new EmptyStateViewModel { Icon = "♡", Title = "No Favorites Yet",
                       Subtitle = "Bookmark flights, airlines, and resources for quick access" })" />
}

CSS Class Reference (actual)

Classes live in ALPAMobile/wwwroot/css/alpa-components.css under the alpa-empty-state block (renamed from the scaffold's Favorites-specific alpa-fav-empty*, which was shared vocabulary hand-copied across 4 pages before this atom existed).

ClassScopeKey rules
.alpa-empty-stateContainerdisplay:flex; flex-direction:column; align-items:center; padding:64px 32px; text-align:center
.alpa-empty-state-iconIconfont-size:48px; color:var(--alpa-gray); margin-bottom:16px; opacity:0.4
.alpa-empty-state-titleTitlefont-family:var(--alpa-body); font-size:18px; font-weight:600; color:var(--alpa-navy); margin-bottom:8px
.alpa-empty-state-subSubtitlefont-family:var(--alpa-body); font-size:13px; color:var(--alpa-gray); line-height:1.5
.alpa-empty-state-ctaOptional CTAmargin-top:16px — wraps arbitrary ChildContent

Usage Context (actual, all 4 real consumers)

ScreenIconTitleSubtitle
Favorites — load failedheart ♡Couldn't Load FavoritesSomething went wrong reaching your favorites. Please try again later.
Favorites — emptyheart ♡No Favorites YetBookmark flights, airlines, and resources for quick access
Saved Searchessearch 🔍No Saved SearchesSave a search to find it quickly next time
Saved Flightsplane ✈No Saved FlightsSave flights from the results list to track them here
Documents List (2 usages)noneNo DocumentsNothing is published for this scope/category right now.

Developer Notes