RestructureNeeds Refinement
Empty State Component link

A full-frame empty-state pattern — illustration or icon, title, description, and optional CTA.

Prop schema + slot restructure
Collapse the two title/description surfaces into one (there's no reason to have both "top header" and "bottom header"). Rename color=white/grey bluestyle=default/subtle to match token naming. Replace icon and asset placeholders with Figma Slots. Resulting prop set: style, title, description, optional slots for icon / asset / action.
In Context

Contexts are illustrative. Final screens will reference actual GCash patterns. Empty State fills a surface where content would normally sit — empty transaction lists, no search results, first-run tabs.

Transactions No transactions yet Your transactions will show here. Cash In
Live Preview
HeaderDescription goes hereHeaderDescription goes hereLabel
Current properties
color
hasIcon
hasAsset
hasButton
DS Health
Reusable
Pass
Used for any "no content" surface — empty transaction lists, no search results, first-run inbox, unfilled saved contacts.
Self-contained
Pass
Carries bg, padding, typography — all token-bound.
Consistent
Fail
color="white" / color="grey blue" (space in value) doesn't match token namespace default / subtle. Two booleans header + header1 are impossible to distinguish. Duplicate top/bottom header surfaces add structural complexity. C2
Composable
Warn
Button composes the canonical Button instance ✓. But icon and asset are hardcoded placeholder shapes — should be Figma Slots for swappable content. C6
Behavior
State iOS Android Figma Property Notes
Default (white) Yes Yes color=white White bg — use when sitting on a light-blue surface
Subtle (grey blue) Yes Yes color=grey blue Light-blue bg — use when sitting on a white surface
Pressed / Disabled N/A N/A Display surface — interactivity lives on the child Button.
Open Issues
  • Property values don't match token namespacecolor="white" / color="grey blue" (with space) should be style=default / style=subtle matching main/empty-state/color/default/* and main/empty-state/color/subtle/*. C2
  • Duplicate header / header1 booleans — unreadable in the Figma property panel. And the underlying structure (top heading+description, then bottom heading+description) is unusual — most empty states have one title+description. C2
  • 7 boolean props = 256 prop combinations — many are semantically invalid (e.g. hasIcon=true + hasAsset=true together is redundant). Collapse into meaningful configurations. C2
  • Icon is a hardcoded gray circle placeholder — should be a Figma Slot so consumers can drop in any 64 × 64 icon. C6
  • Asset is a flat colored rectangle — should be a Figma Slot for the real illustration. C6
  • Code Connect CLI mappings not registered. C7
Design Recommendations
  • Collapse to one title + description. Drop the top-heading/bottom-heading duplication — most empty states have a single title/description pair. The header / header1 / topHeading / topDescription booleans all go away. Docs
  • Rename colorstyle with values default / subtle to match token namespace. Clean enum values, no space characters. Rename
  • Adopt Figma Slots for icon, asset, and action Icon slot accepts 64 × 64 icons. Asset slot accepts any 360 × 230 illustration. Action slot accepts any Button configuration (not just primary). Maps cleanly to @ViewBuilder / @Composable slots. Docs
  • Document "icon vs asset" — both appear to serve the same purpose (visual anchor above the headline). Pick one convention: either icon (compact 64px) OR illustration (full-width 230px), not both simultaneously. Docs
Styles
White
DES DEV

White background — use when the surface behind is dark or tinted. Asset placeholder uses <code>#EEF2F9</code>.

Properties
hasIcon
hasAsset
hasButton
Properties
Variant White
Style Default
Colors
Surface #FFFFFF
Title #0A2757
Description #6780A9
Placeholder #EEF2F9
CTA bg #005CE5
Layout
Width 328px
Padding 16 horizontal · 24 vertical
Illustration size 120 × 120
Gap (illus ↔ title) 16px
Typography
Title style Primary/Headlines/Block
Title font Proxima Soft Bold · 18 / 23 · +0.25
Description style Secondary/Bold/Caption
Description font BarkAda Semibold · 12 / 18
Colors by Style
Role Token TokenValue
Default (white) bg main/empty-state/color/default/bg #FFFFFF
title main/empty-state/color/default/label-title #0A2757
description main/empty-state/color/default/description #6780A9
asset placeholder main/empty-state/color/default/placeholder #EEF2F9
Subtle (grey blue) bg main/empty-state/color/subtle/bg #F6F9FD
title main/empty-state/color/subtle/label-title #0A2757
description main/empty-state/color/subtle/description #6780A9
asset placeholder main/empty-state/color/subtle/placeholder #D7E0EF
Grey Blue
DES DEV

Light blue-grey background (<code>#F6F9FD</code>) — use when the surface behind is white. Asset placeholder uses <code>#D7E0EF</code>.

Properties
hasIcon
hasAsset
hasButton
Properties
Variant Grey Blue
Style Default
Colors
Surface #FFFFFF
Title #0A2757
Description #6780A9
Placeholder #EEF2F9
CTA bg #005CE5
Layout
Width 328px
Padding 16 horizontal · 24 vertical
Illustration size 120 × 120
Gap (illus ↔ title) 16px
Typography
Title style Primary/Headlines/Block
Title font Proxima Soft Bold · 18 / 23 · +0.25
Description style Secondary/Bold/Caption
Description font BarkAda Semibold · 12 / 18
Layout
Role Token Value
Container width 360px
Top padding 16px
Bottom padding space/space-24 24px
Top header padding space/space-16 + space/space-24 24h / 16b
Content padding space/space-24 24h / 16t
Content gap (title ↔ description) 10px
Button top padding space/space-24 24px
Icon slot size 64 × 64
Asset size 360 × 230
Installation Planned API

iOS — Swift Package Manager

// In Xcode: File → Add Package Dependencies
"https://github.com/AY-Org/eb-ds-ios"

Android — Gradle (Kotlin DSL)

dependencies {
    implementation("com.eastblue.ds:empty-state:1.0.0")
}
Property Mapping
Figma PropertySwiftUICompose
color=white/grey blue style: EBEmptyStateStyle .ebStyle(.default/.subtle)
header1 / topHeading title: String title: String
topDescription / description description: String? description: String?
hasIcon + icon placeholder Figma Slot → ViewBuilder @ViewBuilder icon
hasAsset + asset placeholder Figma Slot → ViewBuilder @ViewBuilder asset
hasButton + buttonInstance Figma Slot → ViewBuilder @ViewBuilder action
SwiftUI
ios/Components/EmptyState/EBEmptyState.swift
Jetpack Compose
android/components/emptystate/EBEmptyState.kt
Usage Snippets Planned API
Usage
// Empty transaction list — icon + title + description + action
EBEmptyState(
    title: "No transactions yet",
    description: "Your transactions will show up here.",
    icon: { Image(systemName: "tray") },
    action: { EBButton("Cash In") { /* ... */ } }
)
.ebStyle(.default)

// Full illustration — asset slot instead of icon
EBEmptyState(
    title: "No favorites added",
    description: "Tap the heart on any contact to save them here.",
    asset: { Image("empty-favorites").resizable().scaledToFit() }
)
.ebStyle(.subtle)
// Empty transaction list — icon + title + description + action
EBEmptyState(
    title = "No transactions yet",
    description = "Your transactions will show up here.",
    style = EBEmptyStateStyle.Default,
    icon = { Icon(painterResource(R.drawable.tray), contentDescription = null) },
    action = { EBButton("Cash In", onClick = { /* ... */ }) }
)

// Full illustration — asset slot instead of icon
EBEmptyState(
    title = "No favorites added",
    description = "Tap the heart on any contact to save them here.",
    style = EBEmptyStateStyle.Subtle,
    asset = { Image(painterResource(R.drawable.empty_favorites), contentDescription = null) }
)
Accessibility
RequirementiOSAndroid
Role Group as a single accessibility element with combined label mergeDescendants = true on the container
Decorative icon / asset .accessibilityHidden(true) contentDescription = null
Action button Separate accessibility element with its own label Standard Button semantics
Live region Announce when empty state appears (e.g. after filtering returns 0 results) liveRegion = LiveRegionMode.Polite
Usage Guidelines

Do

Use for first-run, no-results, and "nothing here yet" surfaces. Always include a primary action when the user can take a step to fill the empty state.

Don't

Use as an error surface — use Inline Message (error type) or a Toast. Empty State assumes the absence of content is expected, not a failure.

Do

Pick either icon or illustration. Don't stack both — the duplication adds visual noise without adding meaning.

Don't

Leave the description blank — a one-line context sentence ("Your transactions will show up here") teaches the user what the feature does.

Criteria Scorecard
ID Criterion Status Notes
C1 Layer Structure & Naming Ready Semantic: header, content, asset-container, button-container, Icon-Slot.
C2 Variant & Property Naming Requires Rework Color values don't match tokens; duplicate header/header1; 7 booleans = 256 combos.
C3 Token Coverage Ready All colors bound — just mismatched in the property names.
C4 Native Mappability Ready VStack / Column with slots — straightforward native builds.
C5 Interaction State Coverage Ready Display-only surface.
C6 Asset & Icon Quality Requires Rework Icon + asset are placeholders. Should be slots.
C7 Code Connect Linkability Needs Refinement Blocked by C2 restructure.
Variants Inventory (2 total)

Boolean props (hasIcon, hasAsset, hasButton, header, header1, topDescription, topHeading) multiply the effective prop combinations to 256. After restructure to slot-based API, this collapses to 2 style variants × optional slots — unlimited configurations without variant explosion.

color (current)Proposed styleNode ID
whitedefault27:169326
grey bluesubtle27:169339
1.0.0 — April 2026Major
Initial Assessment · node 27:169325
Component assessed — 2 color variants + 7 boolean props. Icon + asset placeholders. Documented
Initial
Property naming mismatchcolor values don't match token namespace (default/subtle). Open
C2 Open
Duplicate header/header1 booleans + duplicate top/bottom heading surfaces. Open
C2 Open
Icon + asset are placeholders — should be Figma Slots. Open
C6 Open
Code Connect mappings — Not registered. Open
C7 Open