A display-style numeric input for PHP amount entry in Send Money, Cash-In, and top-up flows. Sits on a single underline, with a label above and supporting text below. Two sizes × four interaction states.
4602:18144 in the 2026 Working File. Size = LG | MD × State = Default | Focused | Disabled | Error gives eight variants, and every one carries the same five semantic names — Label, AmountRow wrapping CurrencySymbol · Value · CurrencyCode, and HelperText — with no legacy prefix and no cross-variant mismatch. The Error state colors the border, the full amount row and the helper text, which is the family reference treatment. Keeping Label and HelperText local rather than composing the shared form scaffolding is a recorded decision: this is a centered, large-type standalone field, not a form row. Locale, currency-code and keyboard behavior are documented. All four DS Health traits pass; the only item still open is Code Connect, blocked until the native library exists.Contexts are illustrative. Final screens will reference actual GCash patterns (Send Money, Cash-In, Top-up).
CurrencySymbol and CurrencyCode are editable text layers, so switching ₱ to another currency is a text edit — not a fork.Size = LG | MD and State = Default | Focused | Disabled | Error both follow the Property Naming Guidelines and match the siblings. Every layer carries a correct semantic name — Label, AmountRow, CurrencySymbol, Value, CurrencyCode, HelperText — and Error on the State axis is the confirmed family-level exception.AmountRow composes cleanly and CurrencySymbol · Value · CurrencyCode are independently addressable, so a locale can drop the code without restructuring. Label and HelperText stay local by design — the shared FormGroup Header and Subtext Message instances are built for left-aligned form rows and would need overriding in every variant of this centered, large-type field.| State | iOS | Android | Figma Property | Notes |
|---|---|---|---|---|
| Default | Yes | Yes | State=Default | Shows ₱ 0.00 Php in navy. Underline #E5EBF4. |
| Active (focused) | Yes | Yes | State=Active | Underline darkens to #183462; amount shown at full navy. Named Active here but Focused on Search Field — see open issues. |
| Disabled | Yes | Yes | State=Disabled | Amount mutes. Label and supporting text keep their default colors — see open issues. |
| Error | Yes | Yes | State=Error | Red #D61B2C for amount, underline, and supporting text, which becomes the validation message. |
| Size | Yes | Yes | Size=Large | Medium | Large uses a 70px input row, Medium 50px. Both carry the peso glyph. |
- Code Connect mappings not registered. Blocked — no native library exists yet. The property schema is clean and every layer is semantically named, so mapping is a mechanical step once the library lands. C7 · Code Connect Linkability
- Peso glyph is no longer a raster image. v2.0: Rebuilt on node
4602:18144. The ₱ now renders as a text glyph inside the input row rather than an<img>reference, restoring token-based coloring and clean scaling. Applied by a different route than the recommended icon instance-swap, but it resolves the C6 finding. (C6 · Asset) C6 · Asset & Icon Quality - Active and Disabled states added. v2.0: The state axis is now
Default | Active | Disabled | Error, matching Input Field's 4-state model, and every state ships in both sizes. Closes both C5 findings. (C5 · State) C5 · Interaction State Coverage - Large variant now carries the peso glyph. v2.0: Both
Size=LargeandSize=Mediumrender₱ 0.00 Php. The inconsistency where Large dropped the currency mark is gone. (C2) C2 · Variant & Property Naming -
State=Errorexception confirmed. v2.1: Closed by owner decision at family level —Errorstays on theStateaxis across Form Elements as a deliberate exception to the State/Status rule, matching how most design systems model form-field validation. Applies equally to Search Field and Text Area. (C2 · Property) C2 · Variant & Property Naming -
label=yes/noproperty removed. v2.0: The property is gone from the variant axes, which are nowSize×State; the label is always present. This resolves the boolean-naming finding, though by removal rather than the recommended migration toshowLabel=true/false— so the ability to hide the label no longer exists. Confirm that was deliberate rather than dropped in the rebuild. (C2 · Rename) C2 · Variant & Property Naming - Amount layers renamed to describe their content. v2.2: The three
#amountnodes in everyinputframe are nowCurrencySymbol(₱),Value(the number) andCurrencyCode(Php), and the title layer isLabel. The duplicate-name collisions are gone andValuematches §3's Form-content definition exactly. (C1 · Rename) C1 · Layer Structure & Naming - Size values aligned to the standard scale. v2.2:
Size = Large | Medium→LG | MD, matching theXS · SM · MD · LG · XLset in §5 of the Property Naming Guidelines. (C2 · Rename) C2 · Variant & Property Naming - Layer and property naming completed. v2.3:
Focussed→Focused, matching the guidelines and both siblings;SupportText→HelperTextacross all eight variants, resolving the term §6 explicitly forbids and picking up the one Error-variant layer the previous sweep missed; andinput→AmountRow. Every layer and property value in the set now follows the Property Naming Guidelines. (C1 · C2 · Rename) C2 · Variant & Property Naming - Disabled treatment confirmed intentional. v2.3: Closed by owner decision —
LabelandHelperTextsit outside the enclosed input element, so they deliberately keep their default colours while only the amount insideAmountRowmutes. The disabled affordance belongs to the control, not to the surrounding copy. Differs from Text Area and Search Field, which mute the whole field, because those components enclose their text within the input container. (C5) C5 · Interaction State Coverage - Currency slots ruled unnecessary. v2.3: Closed by owner decision —
CurrencySymbolandCurrencyCodeare already text layers, so switching ₱ to $ or € is a text edit rather than an instance swap. That is more flexible than a slot for a glyph, and it means the component is not in fact hard-coded to PHP. (Slot) C4 · Native Mappability - Confirmed as a standalone component. v2.3: Closed by owner decision — Amount Text Field stays its own component rather than folding into Input Field as
type: .currency. Its display-style anatomy, 53px numeral and currency-triplet row are distinct enough from a standard field to justify separation, and the decision matches Search Field and Text Area. (Family) C4 · Native Mappability - Fractional widths corrected. v2.2: Variants went 384.75 →
360and inner rows 336.75 →312; the set narrowed 424.75 → 400. All dimensions are now whole numbers that map cleanly to native layout values. (C4) C4 · Native Mappability - Layer naming verified complete across all eight variants. v2.4: Re-read on the live node. Every variant carries the same five semantic names —
Label,AmountRowwrappingCurrencySymbol·Value·CurrencyCode, andHelperText— with no legacy prefix, no duplicate siblings and no cross-variant mismatch. Each text layer can therefore expose as a single property across the set. (C1) C1 · Layer Structure & Naming - Error state colors the full amount row and its helper text. v2.4: In
State=Errorthe border,CurrencySymbol,Value,CurrencyCodeandHelperTextall move to#D61B2C. The validation message is carried by color as well as position, which is the stronger of the two treatments in Form Elements — Text Area leaves its subtext neutral, and that difference is now tracked on Text Area rather than here. (C5) C5 · Interaction State Coverage - Local
LabelandHelperTextconfirmed intentional. v2.5: Amount Text Field deliberately does not composeFormGroup HeaderandSubtext Message. Those instances are built for left-aligned form rows sitting above a bordered input; this component is a centered, standalone amount entry whose label and helper text are centered on the amount at 18px and 14px, sized against a 53pt value rather than a 14px one. Adopting the shared scaffolding would mean overriding its alignment, sizing and spacing in every variant — inheriting the maintenance cost without the benefit. Recorded as a deliberate divergence so the odd one out in Form Elements reads as a decision. (C4 · Composition) C4 · Native Mappability - Locale and keyboard behavior documented. v2.5: The component shows
₱andPhptogether because it is used where the amount must be unambiguous — a transfer confirmation, not a price. Where the surrounding screen already establishes currency,CurrencyCodeis omitted and the symbol carries it alone. Locale drives the symbol, the code, and the grouping and decimal separators together, never independently; implementations should format through the platform’s currency formatter rather than string-concatenating a symbol onto a number. Keyboard: decimal pad on both platforms (.keyboardType(.decimalPad)/KeyboardType.Decimal), no locale-switching mid-entry, a hard cap of two fraction digits, and pasted input stripped to digits and a single separator rather than rejected outright — a user pasting₱1,000.00should land on1000.00, not an empty field. (Docs) C4 · Native Mappability
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 | Requires Rework | Two layers named #label and three named #amount in every variant — the property surface can't distinguish them. |
| C2 | Variant & Property Naming | Needs Refinement | label=yes/no is gone and the state axis matches Input Field. Remaining: Active should be Focused, Error is a Status on the State axis, and Large|Medium diverges from LG|MD. |
| 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 | Needs Refinement | All four states ship in both sizes. Remaining: label and supporting text don't mute in Disabled. |
| C6 | Asset & Icon Quality | Ready | Peso glyph is now a text glyph, not a raster reference — colors with the rest of the amount. |
| C7 | Code Connect Linkability | Not Mapped | Blocked — no native library exists yet. The structural blockers are cleared. |
| 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