FixNeeds Refinement
Select Item Component link

A single selectable row inside a Dropdown popover — label, optional leading icon, and selected/disabled states.

Fix required before handoff
Enum value typo disabeld (C2). Country variant uses a raster PNG flag (C6). No pressed/focused state variants (C5). Disabled is modeled as a type value rather than an orthogonal state (C4).

Dropdown Item is the row primitive consumed by the Dropdown overlay and by Dropdown Item Group. Not used standalone.

Dropdown Item
Properties
type
selected
Reusable
Pass
Single row primitive powering every Select Group and Dropdown overlay. One component covers Icon, Peso Sign, and Flag leading content across three densities (Compact 40 / Default 48 / Comfortable 56), with named Leading / Content / Trailing slots taking anything else.
Self-contained
Pass
Ships its own padding, label + supporting text styling, and slot scaffolding. Colors are token-bound across Default, Pressed, and Disabled; the Flag type resolves through the shared Flags Library rather than baking in an asset.
Consistent
Pass
The disabeld typo is gone — disabled is now an orthogonal State value (Default / Pressed / Disabled) that composes with any Type. isSelected is a clean two-value boolean on true/false, matching the C2 rule and Radio Button.
Composable
Pass
Nests inside Select Group via a Figma Slot. The Flag type is a swappable vector instance (Flags Library - 16px) rather than a hardcoded raster, so any locale works, and the three named element slots let consumers compose badges, checkmarks, or values without forking the component.
State iOS Android Figma Property Notes
Default (unselected) Yes Yes selected=false Label #0A2757, bottom border #E5EBF4.
Selected Yes Yes selected=true Label #005CE5 (brand), same divider. No background highlight — relies on text color alone.
Disabled Yes Yes type=disabeld Soft fill #F6F9FD, label #C2CFE5. Modeled as a content type rather than a state (C4).
Pressed No No Not defined. iOS highlight and Android ripple will have to be improvised at instance level.
Focused No No Not defined. Required for keyboard / D-pad navigation in dropdown overlays.
  • Code Connect mappings not registered. Previously blocked by the enum typo, missing states, and raster flag — all resolved in the Select Item rebuild. Registration is now unblocked, but the SwiftUI / Compose mappings are not yet wired. C7 · Code Connect Linkability
  • v2.0: Enum typo disabeld fixed — disabled is now a correctly-spelled State value, not a misspelled content type. (C2)
  • v2.0: Disabled promoted to an orthogonal State axis (Default / Pressed / Disabled) — composes with any Type, so "Peso Sign + Disabled" and "Flag + Disabled" are now expressible. (C4)
  • v2.0: Country flag replaced with a vector instance — now maps to Flags Library - 16px in the Leading slot, locale-swappable rather than a baked-in Philippines PNG. (C6)
  • v2.0: Pressed state added — State=Pressed covers touch feedback (iOS highlight / Android ripple). Focused is N/A on mobile. (C5)
  • v2.0: Selected affordance added — isSelected=Yes flips the label to brand #005CE5 and exposes a checkmark via the Trailing icon slot, no longer relying on label color alone. (C5)
  • v2.1: isSelected collapsed to a clean two-value boolean — the ambiguous third Default value was removed and the prop now applies uniformly across all three Types. Coverage is consistent at 9 × unselected + 3 × selected per Type, and the selection prop maps 1:1 to a native Bool. (C2)
  • v2.1: isSelected values renamed Yes/Notrue/false across all 36 variants — Select Item now matches the documented C2 rule and the rebuilt Radio Button. The system is on a single boolean vocabulary. (C2)
  • v2.1: State=Disabled + isSelected=true deliberately omitted — reviewed and confirmed intentional. A disabled row offers the user no action, and when the parent Select is disabled the menu never opens, so the combination is unreachable. (C5)
  • v2.1: State=Pressed + isSelected=true deliberately not modelled — reviewed and confirmed correct. Pressed is the act of choosing, so the meaningful case is pressing an unselected row, which ships. On native, pressed is not an authored state but an overlay the platform applies (SwiftUI configuration.isPressed, Compose InteractionSource), so pressed-over-selected composes at runtime without a dedicated variant. Authoring the 9 would specify nothing a developer does not already get. (C5)
  • Register Code Connect mapping to EBSelectItem. With the rename, orthogonal state axis, and vector flag all shipped, wire the Figma properties (Type, Density, State, isSelected + the Leading / Content / Trailing slots) 1:1 to the SwiftUI / Compose API. Docs
  • Renamed disabelddisabled. v2.0: Applied — disabled is now a correctly-spelled State value. Rename
  • Promoted disabled to its own axis. v2.0: Applied — State (Default / Pressed / Disabled) is orthogonal to Type, so disabled composes with Icon / Peso Sign / Flag. Property
  • Replaced the raster flag with a vector flag slot. v2.0: Applied — the Leading slot now carries a Flags Library - 16px vector instance, locale-swappable. Slot
  • Added a pressed state. v2.0: Applied — State=Pressed maps touch feedback to a tokenized background. Focused is N/A on mobile. State
  • Added an explicit selected-visual affordance. v2.0: Applied — brand-color label plus a checkmark via the Trailing icon slot on isSelected=Yes. State
  • Generalized the amount variant around slots. v2.0: Applied — the peso sign is a Leading vector slot (Peso Sign - Proxima) with the value in Content and a free Trailing slot for a badge or value. Slot
  • Collapsed isSelected to a clean boolean. v2.1: Applied — the third Default value is gone; isSelected is a true two-value boolean across every Type, with consistent coverage. Property
  • Standardise the boolean vocabulary on true/false. v2.1: Applied — isSelected values renamed Yes/Notrue/false across all 36 variants, matching the C2 rule and Radio Button. The system is now on one boolean vocabulary. Rename
Styles
Text
DES DEV

Plain text row. Default content type used by Dropdown. Label switches from neutral #0A2757 (default) to brand #005CE5 (selected).

Dropdown Item
Properties
type
selected
Properties
state Default
Variant Text
Colors
Bg #FFFFFF
Label #0A2757
Border #E5EBF4
Layout
Row height 48px
Padding H 16px
Padding V 12px
Divider 1px bottom border
Typography
Label style Primary/Label/Light/Small
Label font Proxima Soft Semibold · 18 / 18
Colors by State

All color roles are bound to the main/dropdown-item/color/* token family. Dropdown Item has no variable modes — colors are keyed by state only.

Role Token DEFAULTSELECTEDDISABLED
Row bg main/dropdown-item/color/{state}/bg transparent transparent #F6F9FD
Label main/dropdown-item/color/{state}/label #0A2757 #005CE5 #C2CFE5
Bottom border main/dropdown-item/color/{state}/border #E5EBF4 #E5EBF4 #E5EBF4
Peso sign (amount) main/dropdown-item/color/{state}/icon-currency #0A2757 #005CE5
Badge bg (text with tag) main/badge/negative/heavy/background #D61B2C #D61B2C
Badge label (text with tag) main/badge/negative/heavy/label #FFFFFF #FFFFFF
Text with tag
DES DEV

Row with a trailing Badge instance (Negative/Heavy variant in stock). Used when an option needs an inline status label.

Dropdown ItemLabel
Properties
type
selected
Properties
state Default
Variant Text with tag
Colors
Bg #FFFFFF
Label #0A2757
Border #E5EBF4
Layout
Row height 48px
Padding H 16px
Padding V 12px
Divider 1px bottom border
Typography
Label style Primary/Label/Light/Small
Label font Proxima Soft Semibold · 18 / 18
Layout
Role Token Token
Row width 366px (fill)
Row height 50px (text / text with tag) · 51.2–52px (amount / country)
Padding top/bottom 16px space/space-16
Padding left 12px space/space-12
Padding right 16px space/space-16
Gap (country / text with tag) 8px space/space-8
Flag size (country) 25 × 16
Flag radius 2px radius/radius-1 (approx)
Peso sign size (amount) 18 × 18
Bottom border 1px solid main/dropdown-item/color/{state}/border
Row corner radius 0 radius/radius-0
Amount
DES DEV

Peso sign (vector, Proxima-sized) + amount text. Icon currency token flips to brand on selected.

X,XXX.XX
Properties
type
selected
Properties
state Default
Variant Amount
Colors
Bg #FFFFFF
Label #0A2757
Border #E5EBF4
Layout
Row height 48px
Padding H 16px
Padding V 12px
Divider 1px bottom border
Typography
Label style Primary/Label/Light/Small
Label font Proxima Soft Semibold · 18 / 18
Typography
Role Token FontSizeTrackingLine-height
Label (all types) Primary/Label/Light/Large Proxima Soft Semibold 18px 0.25px 18px
Amount text Primary/Label/Light/Large Proxima Soft Semibold 18px 0.25px 18px
Badge label (text with tag) Primary/Label/Fine Proxima Soft Bold 12px 0.5px 12px
Country
DES DEV

Leading flag (25 × 16, 2px radius) + country name and dial code. <strong>Flag is a raster PNG</strong>, not a vector instance — open issue (C6).

Philippines +63
Properties
type
selected
Properties
state Default
Variant Country
Colors
Bg #FFFFFF
Label #0A2757
Border #E5EBF4
Layout
Row height 48px
Padding H 16px
Padding V 12px
Divider 1px bottom border
Typography
Label style Primary/Label/Light/Small
Label font Proxima Soft Semibold · 18 / 18
Disabeld Typo
DES DEV

Soft fill row with muted label. Currently only exists at <code>selected=false</code>. <strong>Enum value is misspelled (<code>disabeld</code>)</strong> — open issue (C2).

Dropdown Item
Properties
type
selected
Properties
state Disabled
Variant Disabeld Typo
Colors
Bg #FFFFFF
Label #0A2757
Border #E5EBF4
Layout
Row height 48px
Padding H 16px
Padding V 12px
Divider 1px bottom border
Typography
Label style Primary/Label/Light/Small
Label font Proxima Soft Semibold · 18 / 18

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:dropdown:1.0.0")
}

Import

import EastBlueDS  // SwiftUI
import com.eastblue.ds.dropdown.*  // Compose

Dropdown Item is bundled with the Dropdown package. The planned SwiftUI API exposes it as EBDropdownItem; on Compose it maps to Material 3's DropdownMenuItem with EB-styled content.

Figma PropertySwiftUICompose
type = text EBDropdownItem(label:) DropdownMenuItem(text = { Text(label) })
type = text with tag EBDropdownItem(label:tag:) trailing = { EBBadge(…) }
type = amount .ebStyle(.amount) style = EBDropdownItemStyle.Amount
type = country EBDropdownItem(flag:name:dialCode:) leadingIcon = { FlagIcon(…) }
type = disabeld Typo .disabled(true) enabled = false
selected = true isSelected: Bool selected: Boolean
selected = false isSelected: Bool (default) selected: Boolean (default)
SwiftUI
ios/Components/Dropdown/EBDropdownItem.swift
Jetpack Compose
android/components/dropdown/EBDropdownItem.kt
EBDropdownItem("Dropdown Item")
    .isSelected(category == "item")
    .onTap { category = "item" }
EBDropdownItem(
    label = "Dropdown Item",
    selected = selected == "item",
    onClick = { selected = "item" }
)
EBDropdownItem("Dropdown Item") {
    EBBadge("Label", level: .heavy, state: .negative)
}
EBDropdownItem(
    label = "Dropdown Item",
    trailing = { EBBadge("Label", level = EBBadgeLevel.Heavy, state = EBBadgeState.Negative) }
)
EBDropdownItem(amount: "1,000.00")
    .ebStyle(.amount)
EBDropdownItem(
    label = "1,000.00",
    style = EBDropdownItemStyle.Amount
)
EBDropdownItem(
    flag: Image("flag_ph"),
    name: "Philippines",
    dialCode: "+63"
)
EBDropdownItem(
    label = "Philippines +63",
    leadingIcon = { FlagIcon(CountryCode.PH) }
)
RequirementiOSAndroid
Minimum touch target 44 × 44 pt (row is 50pt tall) 48 × 48 dp
Accessibility label .accessibilityLabel("Philippines, +63") contentDescription = "Philippines, +63"
Role .accessibilityAddTraits(.isButton) Role.Button
Selected announcement .accessibilityAddTraits(.isSelected) selected = true in semantics
Disabled announcement .disabled(true) → VoiceOver says "dimmed" enabled = false → TalkBack says "disabled"

Do

Consume Dropdown Item through Dropdown or Dropdown Item Group. Keep labels short — 18px Semibold is the only supported text size.

Don't

Don't use Dropdown Item outside a dropdown overlay. For standalone list rows, use the List Item component instead.

Do

Pair selected state with a trailing checkmark (once added) so the picked item is unambiguous, especially on the country and amount variants.

Don't

Don't rely on the disabeld type to build disabled versions of amount or country — it only ships for the text content type. Use the planned disabled state axis instead.

ID Criterion Status Notes
C1 Layer Structure & Naming Ready Semantic names: container, name, offset, Peso Sign - Proxima, Field Trailing Flag, philippines.
C2 Variant & Property Naming Requires Rework Enum value disabeld is misspelled and ships into the generated TS type.
C3 Token Coverage Ready All colors bound to main/dropdown-item/color/*; space + radius + typography tokens all present.
C4 Native Mappability Needs Refinement Maps to a custom SwiftUI row / Material 3 DropdownMenuItem. Disabled should be an orthogonal prop, not a type value.
C5 Interaction State Coverage Requires Rework No pressed or focused variants. Selected state relies on label color alone — no checkmark or background fill.
C6 Asset & Icon Quality Requires Rework Country variant uses a raster PNG flag, not a vector instance. Peso sign is a vector via Peso Sign - Proxima.
C7 Code Connect Linkability Needs Refinement No CLI mappings registered yet; blocked by C2, C5, C6.
Aspect Status Notes
Property naming Requires Rework Rename disabelddisabled before registering
Asset quality Requires Rework Replace raster PH flag with vector flag slot
State coverage Requires Rework Pressed / focused variants missing
Native component file Needs Refinement EBDropdownItem.swift / EBDropdownItem.kt not yet created

5 type values × 2 selected values = 10 theoretical slots, but disabeld only ships with selected=false, giving 9 actual variants.

typeselectedNode IDNotes
textfalse23:199454Neutral label
texttrue23:199456Brand label
text with tagfalse883:29328Trailing Badge instance
text with tagtrue883:30370Brand label + Badge
amountfalse23:199458Peso sign + "X,XXX.XX"
amounttrue23:199465Brand peso + brand label
countryfalse23:199472Raster flag + "Philippines +63"
countrytrue23:199476Brand "Philippines +63"
disabeld Typofalse883:30386Soft fill + muted label
isSelected normalised · node 25689:371384
isSelected collapsed to two values — the ambiguous third Default value was removed; the prop now applies uniformly across Icon, Peso Sign, and Flag. Coverage is consistent at 9 × unselected + 3 × selected per Type, and selection maps 1:1 to a native Bool. Resolved
C2 Resolved
Boolean vocabulary standardisedisSelected values renamed Yes/Notrue/false across all 36 variants. Select Item now matches the documented C2 rule and the rebuilt Radio Button; the system is on a single boolean vocabulary. Resolved
C2 Resolved
Rebuilt as Select Item · node 25689:371384
Component rebuilt and renamed Dropdown Item → Select Item — new slot-based architecture: Type (Icon / Peso Sign / Flag) × Density (Compact / Default / Comfortable) × State (Default / Pressed / Disabled) × isSelected (No / Yes / Default), with named Leading / Content / Trailing element slots. Restructured
Rebuild
Enum typo disabeld resolved — disabled is now a correctly-spelled orthogonal State value, not a misspelled content type. Composes with any Type (e.g. Peso Sign + Disabled), resolving the earlier C2 + C4 issues. Resolved
C2 · C4 Resolved
Raster flag replaced with a vector instance — the country flag now maps to Flags Library - 16px in the Leading slot, locale-swappable rather than a baked-in Philippines PNG. Resolved
C6 Resolved
Pressed state + selected affordance addedState=Pressed covers touch feedback (focused is N/A on mobile), and isSelected=Yes flips the label to brand color plus exposes a checkmark via the Trailing icon slot. Resolved
C5 Resolved
Amount variant generalized — the peso sign is now a Leading vector slot (Peso Sign - Proxima) with the value in Content; the trailing slot stays free for a badge or value. Resolved
Slot
isSelected exposes three values (No / Yes / Default) — ambiguous for a boolean and inconsistent across Types. Collapse to Yes/No. Open
C2 Open
Code Connect mappings — now unblocked by the rebuild; SwiftUI / Compose mappings not yet registered. Open
C7 Open
Initial Assessment · node 18577:13033
Component assessed — 9 variants documented across type (text / amount / country / text with tag / disabeld) × selected (true/false). Row primitive for Dropdown overlay. Documented
Initial
Enum value disabeld misspelled — ships into the generated TS type. Rename to disabled. Open
C2 Open
Country variant uses a raster PNG flag — Philippines image is bitmap, not a vector flag instance. Blocks reuse and native handoff. Open
C6 Open
No pressed or focused state variants — only selected on/off and a pseudo-disabled content type. Touch/keyboard feedback unmodeled. Open
C5 Open
Disabled modeled as type value — collides with content types (text / amount / country). Should be an orthogonal disabled axis. Open
C4 Open
Code Connect mappings — no CLI mappings registered yet; blocked by C2, C5, C6. Open
C7 Open