A display-style numeric input for PHP amount entry in Send Money, Cash-In, and top-up flows. Sits on a single underline — Large is a 53px headline, Default prefixes a peso glyph with a 35px amount.
label=yes/no needs Boolean naming (C2). Decide whether to keep as a standalone sibling or fold into Input Field as type: .currency.Contexts are illustrative. Final screens will reference actual GCash patterns (Send Money, Cash-In, Top-up).
label=yes/no instead of true/false — doesn't match isFilled=true/false on sibling fields. State set also differs from Input Field's 4-state model (Default/Active/Error/Disabled).| State | iOS | Android | Figma Property | Notes |
|---|---|---|---|---|
| Default (empty) | Yes | Yes | state=Default | Shows 0.00 in placeholder color #90A8D0. Border #ADBDDC. |
| Filled | Yes | Yes | state=Filled | Amount typed; navy #0A2757 text, border darkens to #445C85. |
| Error | Yes | Yes | state=Error | Red #D61B2C for amount, border, and subtext. Subtext becomes the validation message. |
| Active (focused) | No | No | — | Missing variant. Native field will show caret + keyboard; no DS-defined visual affordance. |
| Disabled | No | No | — | Missing variant. Top-up confirmations and locked amounts have no canonical appearance. |
- None yet — initial assessment.
- Peso Sign glyph is a raster image. The ₱ mark renders via an
<img>reference (imgShapeFull) rather than an instance of thePeso Sign - Proximavector icon. Raster assets can't be recolored with tokens, scale poorly on high-DPI screens, and block Code Connect asset mapping. C6 · Asset & Icon Quality - Missing Active (focused) state. The component exposes only Default / Filled / Error. Native keyboards surface a caret on focus, but the DS has no defined focused-border or amount color — devs have to invent one per flow. C5 · Interaction State Coverage
- Missing Disabled state. Amount confirmations, locked top-up amounts, and review screens use an inert version of this field. Without a
state=Disabledvariant there's no single source of truth for its appearance. C5 · Interaction State Coverage -
labelproperty usesyes/noinstead oftrue/false. Boolean naming.label=Yesdoesn't map cleanly to SwiftBool/ KotlinBoolean, and it diverges from sibling fields that were already migrated totrue/false(Input Field'sisFilled). Should also be renamed tohasLabelorshowLabel. C2 · Variant & Property Naming - Large variant drops the peso glyph. When
size=Largethe ₱ is removed entirely — the amount is just500.00. If this is intentional it's under-documented; if not, it's an inconsistency that users and devs will stumble on. No property controls it, so it can't be opted into. C2 · Variant & Property Naming - Code Connect mappings not registered. Blocked by the structural issues above — register after peso glyph is vectorized, states are added, and
labelis migrated to Boolean. C7 · Code Connect Linkability
- Replace the raster peso with a vector instance of
Peso Sign - Proxima. That library component already exists and is sized per font tier — swap the current<img>for an instance-swap slot so color can bind tomain/amount-text-field/{state}/icon-currencyand scale at any DPR. Asset - Add
state=Activeandstate=Disabledvariants. Extends the enum to the same 4-state model used by Input Field (Default / Active / Error / Disabled) plus aFilleddisplay-only state, or collapseFilledinto a derived-from-content view. Either way, lock the state axis to match siblings. State - Migrate
label=yes/noto a BooleanshowLabel=true/false. Matches the canonical naming used by Input Field'sisFilledand unlocks direct Code Connect mapping to SwiftBool/ KotlinBoolean. Consider splittingsubtextout as its own Boolean so error-copy and helper-copy can be toggled independently of label. Rename - Expose leading and trailing slots for the currency mark and unit suffix. Hard-coding the peso glyph ties the component to PHP. A
leadingCurrencyslot (₱, $, €) and an optionaltrailingUnitslot ("PHP") future-proofs the component for multi-currency flows without a per-country fork. Slot - Family decision — fold into Input Field as
type: .currency, or keep as EBAmountTextField sibling. Option A: Keep separate — Amount Text Field stays a display-style sibling of Input Field with its own underline anatomy; share tokens via a common text-field token tier. Option B (recommended): Fold into Input Field asEBInputField(type: .currency, …), using SwiftUI'sTextField(value:format:.currency(code:))+.keyboardType(.decimalPad)and Compose'sOutlinedTextField(keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal), leadingIcon = { Text("₱") }). Option B eliminates the duplicate peso glyph instance inside Dropdown's "Amount" variant and the Recipient Field's currency-prefix case. Family - Document locale and keyboard behavior in the component. Decimal separator, thousands separator, minimum/maximum, and zero-padding rules are product concerns today. Adding a short
Docsnote in Figma (or in this assessment's Code tab) gives implementers a single source of truth. Docs
53px amount headline, filled value, dark navy. No peso glyph — the Large tier is used as a hero-amount display.
All colors bind to the main/amount-text-field/{state}/{role} token family. No variable modes, so the table is a flat state matrix.
| Role | Token | DEFAULT | FILLED | ERROR |
|---|---|---|---|---|
| Border (underline) | amount-text-field/{state}/border | #ADBDDC | #445C85 | #D61B2C |
| Label (top) | amount-text-field/{state}/label | #0A2757 | #0A2757 | #0A2757 |
| Amount (body) | amount-text-field/{state}/label-amount | #90A8D0 | #0A2757 | #D61B2C |
| Peso glyph | amount-text-field/{state}/icon-currency | #D7E0EF | #0A2757 | #D61B2C |
| Subtext | amount-text-field/{state}/subtext | #0A2757 | #0A2757 | #D61B2C |
Empty state at 53px, muted placeholder color. Used before the user types in hero amount screens.
| Role | Token | Font | Size | Line-height | Tracking |
|---|---|---|---|---|---|
| Label (top) | Primary/Label/Light/Large | Proxima Soft Semibold | 18px | 18px | 0.25 |
| Amount — Large | Primary/Headlines/Epic | Proxima Soft Semibold | 53px | 58px | 0 |
| Amount — Default | Primary/Headlines/Spotlight | Proxima Soft Bold | 35px | 38px | 0 |
| Subtext | Primary/Multi-line Label/Light/Small | Proxima Soft Semibold | 14px | 16px | 0.25 |
Validation error — amount, border, and subtext all tint red #D61B2C. Subtext is the error message slot.
35px amount with leading peso glyph. Standard send/pay screens. Peso glyph is currently a raster image (see C6 open issue).
Empty state — both peso glyph and <code>0.00</code> render in the placeholder tint #90A8D0 / #D7E0EF.
Validation failed — peso glyph, amount, border, and subtext all tint red #D61B2C.
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:form-elements:1.0.0") }
Import
import EastBlueDS // SwiftUI import com.eastblue.ds.form.* // Compose
Package not yet published. These are the planned distribution paths.
| Figma Property | SwiftUI | Compose |
|---|---|---|
| size = Large / Default | .controlSize(.large / .regular) | size = EBAmountSize.Large / Default |
| state = Default | — | — |
| state = Filled | Derived from value > 0 | Derived from value > 0 |
| state = Error | .ebError(true) | isError = true |
| label = yes / no | label: String? | label: String? |
| subtext (copy) | subtext: String? | subtext: String? |
EBAmountTextField(value: $amount, label: "Add Your Label Here", subtext: "Add your subtext here") .keyboardType(.decimalPad)
EBAmountTextField( value = amount, onValueChange = { amount = it }, label = "Add Your Label Here", subtext = "Add your subtext here", keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal) )
EBAmountTextField(value: $amount) .ebAmountSize(.large) .keyboardType(.decimalPad)
EBAmountTextField( value = amount, onValueChange = { amount = it }, size = EBAmountSize.Large, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal) )
EBAmountTextField(value: $amount, subtext: "How much do you want to save?") .ebError(true)
EBAmountTextField( value = amount, onValueChange = { amount = it }, subtext = "How much do you want to save?", isError = true )
| Requirement | iOS | Android |
|---|---|---|
| Keyboard type | .keyboardType(.decimalPad) | KeyboardType.Decimal |
| Currency format | .currency(code: "PHP") | VisualTransformation + NumberFormat.getCurrencyInstance() |
| Accessibility label | .accessibilityLabel("Amount in pesos") | contentDescription = "Amount in pesos" |
| Error announcement | VoiceOver reads error via .accessibilityValue | TalkBack reads error via semantics { error() } |
| Minimum touch target | 44 x 44 pt | 48 x 48 dp |
Do
Use .decimalPad / KeyboardType.Decimal so users can enter fractional pesos without switching keyboards.
Don't
Use Amount Text Field for phone numbers, account numbers, or non-currency numerics — it hard-codes the peso glyph and currency formatting.
Do
Pair Large size with a label above and a hint subtext below for hero entry screens (Send Money, Cash-In).
Don't
Drop the peso glyph on Default size to "save space" — the glyph is the primary signal that the input expects currency.
| ID | Criterion | Status | Notes |
|---|---|---|---|
| C1 | Layer Structure & Naming | Ready | Semantic names: peso-offset, input, Peso Sign - Proxima. No Frame 42 artifacts. |
| C2 | Variant & Property Naming | Requires Rework | label=yes/no should be Boolean showLabel=true/false. Large variant's missing peso glyph isn't gated by a property. |
| C3 | Token Coverage | Ready | All colors bind to main/amount-text-field/{state}/{role}. Typography uses DS text styles. |
| C4 | Native Mappability | Needs Refinement | Maps to TextField + .keyboardType(.decimalPad) / OutlinedTextField + KeyboardType.Decimal. Display-style underline anatomy needs custom styling vs default framework chrome. |
| C5 | Interaction State Coverage | Requires Rework | Missing Active (focused) and Disabled states. Only Default / Filled / Error defined. |
| C6 | Asset & Icon Quality | Requires Rework | Peso Sign glyph is a raster <img> reference, not a vector instance. Can't be tint-bound to the icon-currency token. |
| C7 | Code Connect Linkability | Needs Refinement | No CLI mappings registered. Blocked by C2, C5, C6. |
| Aspect | Status | Notes |
|---|---|---|
| Property naming | Requires Rework | label=yes/no blocks Boolean mapping |
| State coverage | Requires Rework | Missing Active / Disabled |
| Asset linkability | Requires Rework | Raster peso glyph not mappable to a vector asset param |
| Native component file | Needs Refinement | EBAmountTextField.swift / EBAmountTextField.kt not yet created |
2 size × 3 state × 2 label = 12 variants.
| size | state | label | Node ID |
|---|---|---|---|
| Large | Filled | yes | 152:48113 |
| Large | Default | yes | 152:48116 |
| Large | Error | yes | 152:48120 |
| Large | Filled | no | 152:48111 |
| Large | Default | no | 152:48115 |
| Large | Error | no | 152:48110 |
| Default | Filled | yes | 152:48121 |
| Default | Default | yes | 152:48114 |
| Default | Error | yes | 152:48118 |
| Default | Filled | no | 152:48117 |
| Default | Default | no | 152:48119 |
| Default | Error | no | 152:48112 |
<img src={imgShapeFull}> rather than a vector instance of Peso Sign - Proxima. Blocks tint-color binding and Code Connect asset mapping.
Openlabel=yes/no instead of Boolean showLabel=true/false. Incompatible with Swift Bool / Kotlin Boolean for Code Connect mapping.
Open