KeepNeeds Refinement
Empty State Component link

A centred no-content surface — visual, header (title + description), and an action. 4 variants across Style (Default/Subtle) × VisualType (Icon/Asset), with a Visual Container, Action Container slot, and a token-bound header.

Rebuilt — schema and slots landed
The rebuild collapsed a 7-boolean, 256-combination mess into a clean 2 × 2 — Style (Default/Subtle) × VisualType (Icon/Asset). The duplicate header booleans merged into one header (title + description), color became Style, and the icon, asset, and action are all real Figma slots. The visual slot was unified to a single Visual Container so switching VisualType keeps its content, and visualType was recased to VisualType to match the enum convention. Only Code Connect registration remains.
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. Icon and Asset visual types cover both compact and illustrative empties.
Self-contained
Pass
Carries its own background, padding, and typography, all token-bound. Subtle ships #F6F9FD, Default white.
Consistent
Pass
Two orthogonal enums — Style × VisualType = a complete 2 × 2, replacing the old 7-boolean / 256-combination schema. Values match the token namespace (Default / Subtle), the duplicate header booleans are gone, and both enums are Title Case.
Composable
Pass
Three real Figma slots — a unified Visual Container for the icon or asset, and an Action Container holding a canonical Button instance. Switching VisualType preserves the visual slot content because both types share one slot name.
Behavior
State iOS Android Figma Property Notes
Default Yes Yes Style=Default White background — use when the empty state sits on a light-blue surface.
Subtle Yes Yes Style=Subtle Light-blue #F6F9FD background — use when sitting on a white surface.
Icon visual Yes Yes VisualType=Icon 64px icon in the Visual Container. Compact empties.
Asset visual Yes Yes VisualType=Asset 230px illustration in the Visual Container. Richer, first-run empties.
Pressed / Disabled N/A N/A Not modelled by design — Empty State is a display surface. Interactivity lives on the Button in the Action Container, which carries its own states.
Issues
  • Code Connect mappings not registered. The schema collapse, slot adoption, and naming are all resolved. Registration is unblocked but the SwiftUI / Compose mappings are not yet wired and the native component does not exist — snippets remain a Planned API. C7 · Code Connect Linkability
  • v2.0: 7-boolean schema collapsed to two enums — Style (Default/Subtle) × VisualType (Icon/Asset), a clean 2 × 2. The old 256-combination surface with mutually exclusive booleans is gone. (C2)
  • v2.0: Duplicate header / header1 booleans merged into a single header frame with #heading + #description. (C2)
  • v2.0: color=white/grey blue renamed Style=Default/Subtle, matching the token namespace and dropping the space-in-value. Subtle ships #F6F9FD. (C2)
  • v2.0: Icon placeholder replaced with a real Figma slot, and the flat coloured asset rectangle with an Asset slot wrapping an instance — both swappable. (C6)
  • v2.0: Action promoted to a slot too — Action Container holds a canonical Button instance rather than a drawn button. (C6)
  • v2.1: Visual slot unified to a single Visual Container across all four variants (was Icon Container / Asset Container). Switching VisualType on an instance now preserves the slot content, and Code Connect maps one slot instead of two. (C1)
  • v2.1: visualType recased to VisualType — Title Case, matching the enum convention (Style, Type, State) rather than the boolean camelCase style. (C2)
Recommendations
  • Register Code Connect mapping to EBEmptyState. Wire Style and VisualType to the SwiftUI / Compose API, and map the Visual Container and Action Container slots to @ViewBuilder / @Composable content slots. Docs
  • Collapse to one title + description. v2.0: Applied — the duplicate header booleans merged into a single header with #heading + #description. Property
  • Rename colorStyle with values Default / Subtle. v2.0: Applied — matches the token namespace and drops the space-in-value. Rename
  • Adopt Figma Slots for icon, asset, and action. v2.0: Applied — all three are real slots, and the visual slot was unified to a single Visual Container in v2.1. Slot
  • Document "icon vs asset". v2.0: Superseded by the schema — the choice is now an explicit VisualType enum (Icon / Asset) rather than a convention to document. 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