East Blue
FixReady
Badge Component link

A small label used to flag status, counts, or category — supports multiple intents and densities.

Fix — Consistent is partial
Consistent is partial: the Negative and Muted Heavy Dashboard containers carry a hardcoded 0.9 opacity instead of a token. Bind it to close. The State values now match the token names.
In Context

How the badge appears in real product screens — status labels on loan accounts (Late, Due Today, Almost Due), Paid markers on a payment history, and small labels in the app (Update PIN, HELP, New).

Badge component shown across four GCash screens: Late, Due Today and Almost Due status badges on loan accounts, Paid badges on a payment history, an Update PIN badge in card settings, and HELP and New badges on the home dashboard
Live Preview
Label
Properties
State
Level
Type
DS Health
Reusable
Pass
Universal status indicator used across transaction lists, vouchers, dashboards, and notifications. 7 semantic states and 3 emphasis levels cover all common badge use cases.
Self-contained
Pass
Pure display component. Carries its own background, label color, padding, and border-radius per variant. No external dependencies or slots.
Consistent
Partial
Token naming follows DS convention (main/badge/{semantic}/{level}/), and the State values match the token names (Information, Positive, Notice, Negative, Muted). One issue: the Negative/Heavy and Muted/Heavy Dashboard containers have a hardcoded opacity: 0.9.
Composable
Pass
Simple leaf component. Nests cleanly in list rows, card headers, table cells, and notification banners. No child slots or complex nesting.
Behavior
State iOS Android Figma Property Notes
Default Yes Yes State + Level + Type Display-only. All 7 states x 3 levels fully defined per type.
Issues
  • Hardcoded opacity: 0.90 removed from Danger/Heavy Transaction (21:111576) and Disabled/Heavy Transaction (3714:3863) inner containers. Both now at opacity 1, consistent with the other 66 variants. C3 Fixed
  • State property values renamed to match token semantic names across all 60 affected variants: Info → Information, Success → Positive, Warning → Notice, Danger → Negative, Disabled → Muted. Figma State values now align 1:1 with token namespace — cleaner native mapping, no translation layer needed. C2 Fixed
Recommendations
  • Add a leading icon slot. Common pattern in fintech status badges (warning triangle, check circle, info icon). Today consumers can't pair an icon with a badge without detaching. Slot
  • Consider Medium / Light levels for Primary and Brand. These states only support Heavy today — if lower-emphasis variants are needed (subtle pill, ghost badge), add them now rather than waiting for a future break. Property
  • Numeric count variant. Notification badges (inbox unread count, cart count) overlap Badge's visual space but aren't formalized here. Either document that consumers use Counter instead, or add a count variant with overflow handling ("99+"). Property

Component Playground

Layout

Typography

Colors

Installation Planned API

iOS — Swift Package Manager

.package(url: "https://github.com/AY-Org/eb-ds-ios", from: "1.0.0")

Android — Gradle (Kotlin DSL)

implementation("com.eastblue.ds:badge:1.0.0")

Import

import EastBlueDS
import com.eastblue.ds.badge.*
Property Mapping

Every row maps a Figma component property to its native equivalent.

Figma PropertySwiftUICompose
State — Primary, Brand, Information, Positive, Notice, Negative, Muted state: .primary / .brand / .information / .positive / .notice / .negative / .muted BadgeState.Primary / Brand / Information / Positive / Notice / Negative / Muted
Level — Heavy, Light, Medium level: .heavy / .light / .medium BadgeLevel.Heavy / Light / Medium
Type — Voucher, Transaction, Default, Dashboard type: .voucher / .transaction / .default / .dashboard BadgeType.Voucher / Transaction / Default / Dashboard
SwiftUI
ios/Components/Badge/EBBadge.swift
Jetpack Compose
android/components/badge/EBBadge.kt
Usage Snippets Planned API
Default (Pill)
// Positive badge -- heavy level
EBBadge("Completed", state: .positive, level: .heavy)

// Information badge -- light level
EBBadge("Pending", state: .information, level: .light)
// Positive badge -- heavy level
EBBadge(
    text = "Completed",
    state = BadgeState.Positive,
    level = BadgeLevel.Heavy
)

// Information badge -- light level
EBBadge(
    text = "Pending",
    state = BadgeState.Information,
    level = BadgeLevel.Light
)
Voucher
EBBadge("50% OFF", state: .negative, level: .heavy, type: .voucher)
EBBadge(
    text = "50% OFF",
    state = BadgeState.Negative,
    level = BadgeLevel.Heavy,
    type = BadgeType.Voucher
)
Transaction
EBBadge("Failed", state: .negative, level: .heavy, type: .transaction)
EBBadge(
    text = "Failed",
    state = BadgeState.Negative,
    level = BadgeLevel.Heavy,
    type = BadgeType.Transaction
)
Dashboard
EBBadge("Active", state: .positive, level: .light, type: .dashboard)
EBBadge(
    text = "Active",
    state = BadgeState.Positive,
    level = BadgeLevel.Light,
    type = BadgeType.Dashboard
)
Accessibility
RequirementiOSAndroid
Accessibility label accessibilityLabel("Status: Completed") contentDescription = "Status: Completed"
Decorative mode isAccessibilityElement = false (when status is conveyed elsewhere) importantForAccessibility = no
Color contrast Heavy levels meet WCAG AA (4.5:1+) Heavy levels meet WCAG AA (4.5:1+)
Non-color indicator Badge text conveys meaning alongside color Badge text conveys meaning alongside color
Usage Guidelines

Do

Use semantic states that match the content meaning (Positive for completed, Negative for failed, Notice for pending).

Don't

Use badges for interactive elements -- badges are display-only status indicators.

Do

Use Heavy level for primary status indicators and Light/Medium for secondary or supporting context.

Don't

Use multiple Heavy badges in the same row -- visual noise. Use one Heavy + rest Light/Medium.

Do

Match badge Type to context: Default for general, Voucher for promos, Transaction for history, Dashboard for summaries.

Don't

Mix badge Types within the same list or group.

Criteria Scorecard
ID Criterion Status Notes
C1 Layer Structure & Naming Ready Simple single-layer structure: container with text child. Semantic naming.
C2 Variant & Property Naming Ready Clean enum properties: State, Level, Type. Minor: State names don't match token semantic names.
C3 Token Coverage Ready All colors bound to main/badge/ tokens. Note: 2 variants have hardcoded opacity: 0.90.
C4 Native Mappability Ready Maps to custom EBBadge on both platforms. Simple text + background shape.
C5 Interaction State Coverage Not Applicable Display-only component. No interactive states needed.
C6 Asset & Icon Quality Not Applicable No icons or assets. Text-only component.
Variants Inventory (68 total)

7 State values x 3 Level values x 4 Type values = 84 theoretical. Primary and Brand only support Heavy level, so actual count is (2 x 1 x 4) + (5 x 3 x 4) = 8 + 60 = 68 variants.

StateLevelTypesNotes
PrimaryHeavyDefault, Voucher, Transaction, Dashboard4 variants
BrandHeavyDefault, Voucher, Transaction, Dashboard4 variants
InformationLight / Medium / HeavyDefault, Voucher, Transaction, Dashboard12 variants
PositiveLight / Medium / HeavyDefault, Voucher, Transaction, Dashboard12 variants
NoticeLight / Medium / HeavyDefault, Voucher, Transaction, Dashboard12 variants
NegativeLight / Medium / HeavyDefault, Voucher, Transaction, Dashboard12 variants
MutedLight / Medium / HeavyDefault, Voucher, Transaction, Dashboard12 variants
View full State × Level × Type breakdown (68 rows)
StateLevelTypeNode
PrimaryHeavyDefault18482:28973
BrandHeavyDefault18482:28975
InformationLightDefault18482:28977
InformationMediumDefault18482:28979
InformationHeavyDefault18482:28981
PositiveLightDefault18482:28983
PositiveMediumDefault18482:28985
PositiveHeavyDefault18482:28987
NoticeLightDefault18482:28989
NoticeMediumDefault18482:28991
NoticeHeavyDefault18482:28993
NegativeLightDefault18482:28995
NegativeMediumDefault18482:28997
NegativeHeavyDefault18482:28999
MutedLightDefault18482:29001
MutedMediumDefault18482:29003
MutedHeavyDefault18482:29005
PrimaryHeavyVoucher18482:29007
BrandHeavyVoucher18482:29009
InformationLightVoucher18482:29011
InformationMediumVoucher18482:29013
InformationHeavyVoucher18482:29015
PositiveLightVoucher18482:29017
PositiveMediumVoucher18482:29019
PositiveHeavyVoucher18482:29021
NoticeLightVoucher18482:29023
NoticeMediumVoucher18482:29025
NoticeHeavyVoucher18482:29027
NegativeLightVoucher18482:29029
NegativeMediumVoucher18482:29031
NegativeHeavyVoucher18482:29033
MutedLightVoucher18482:29035
MutedMediumVoucher18482:29037
MutedHeavyVoucher18482:29039
PrimaryHeavyTransaction18482:29041
PrimaryHeavyDashboard18482:29044
BrandHeavyTransaction18482:29047
BrandHeavyDashboard18482:29050
InformationLightTransaction18482:29053
InformationLightDashboard18482:29056
InformationMediumTransaction18482:29059
InformationMediumDashboard18482:29062
InformationHeavyTransaction18482:29065
InformationHeavyDashboard18482:29068
PositiveLightTransaction18482:29071
PositiveLightDashboard18482:29074
PositiveMediumTransaction18482:29077
PositiveMediumDashboard18482:29080
PositiveHeavyTransaction18482:29083
PositiveHeavyDashboard18482:29086
NoticeLightTransaction18482:29089
NoticeLightDashboard18482:29092
NoticeMediumTransaction18482:29095
NoticeMediumDashboard18482:29098
NoticeHeavyTransaction18482:29101
NoticeHeavyDashboard18482:29104
NegativeLightTransaction18482:29107
NegativeLightDashboard18482:29110
NegativeMediumTransaction18482:29113
NegativeMediumDashboard18482:29116
NegativeHeavyTransaction18482:29119
NegativeHeavyDashboard18482:29122
MutedLightTransaction18482:29125
MutedLightDashboard18482:29128
MutedMediumTransaction18482:29131
MutedMediumDashboard18482:29134
MutedHeavyTransaction18482:29137
MutedHeavyDashboard18482:29140
1.1.0 — April 2026Minor
Structural closure -- node 18482:28972
Opacity normalized -- Hardcoded opacity: 0.90 removed from Danger/Heavy Transaction (21:111576) and Disabled/Heavy Transaction (3714:3863) inner containers. Both now at opacity 1, consistent with the other 66 variants. Fixed
C3 Fixed
State values renamed to match token semantics -- 60 variants renamed: Info -> Information, Success -> Positive, Warning -> Notice, Danger -> Negative, Disabled -> Muted. Figma State property now aligns 1:1 with token namespace (main/badge/{information|positive|notice|negative|muted}/{level}/). Cleaner Code Connect mapping with no translation layer. Fixed
C2 Fixed
1.0.0 — April 2026Major
Initial Assessment -- node 18482:28972
Component assessed -- 68 variants documented across State (Primary/Brand/Info/Success/Warning/Danger/Disabled) x Level (Heavy/Medium/Light) x Type (Default/Voucher/Transaction/Dashboard). Token audit confirms all colors bound to main/badge/{semantic}/{level}/ tokens. Documented
Initial
Hardcoded opacity on 2 variants -- Danger/Heavy and Disabled/Heavy Transaction variants have opacity: 0.90 on container instead of using token-driven values. Inconsistent with other variants. Fixed in 1.1.0
C3 Fixed
State-to-token name mismatch -- Figma property names (Info, Success, Warning, Danger, Disabled) don't match token semantic names (information, positive, notice, negative, muted). Minor friction for automated Code Connect mapping. Fixed in 1.1.0
C2 Fixed
Code Connect mappings -- No CLI mappings registered yet. Property naming is clean and ready for mapping. Open
C7 Open