A read-only form field showing a label and value; non-interactive.
4996:25507 in the 2026 Working File. TrailingContent = None | Badge | Link | Icon × Size = SM | LG × Status = Default | Error | Warning ships all 24 combinations with no gaps, layer naming follows the §3 vocabulary and the trailing containers are kebab-case per §4. The axis rename from State to Status settles the last divergence: a display-only field has no interaction states to describe, so the form-field exception in §6 did not apply and the property now says what it actually carries. 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.
Label and Value, the trailing containers are kebab-case per §4, and the 24-variant matrix is complete with no gaps. The axis now reads Status = Default | Error | Warning, which is correct for a display-only component: it reports what the system knows about the value rather than describing an interaction that cannot occur.| State | iOS | Android | Figma Property | Notes |
|---|---|---|---|---|
| Default | Yes | Yes | TrailingContent=None | Label + value only, no trailing slot. |
| Trailing badge | Yes | Yes | TrailingContent=Badge | Badge instance in the trailing slot (e.g. "Change" status chip). |
| Trailing link | Yes | Yes | TrailingContent=Link | Text link in the trailing slot (e.g. "What is this?" contextual help). |
| Trailing icon | Yes | Yes | TrailingContent=Icon | Edit icon (pencil) in the trailing slot — typically navigates to an editable state. |
| Checkmark | Yes | Yes | hasCheckmark=true | Displays a 13×13 checkmark next to the value (e.g. verified status). |
| Description | Yes | Yes | hasDescription=true | Shows a subtext message below the value (e.g. "Message content" helper text). |
- 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
- Overloaded
variantproperty renamed. v2.0: Rebuilt on node4996:25507in the 2026 Working File. The catch-allvariantenum is nowTrailingContent = None | Badge | Link | Icon— PascalCase per §1, semantic values, and a clean 1:1 native enum mapping. (C2 · Rename) C2 · Variant & Property Naming - Size values aligned to the standard scale. v2.0:
Size=Default— which described a starting state rather than a size — is nowSize = SM | LG, matching §5'sXS · SM · MD · LG · XLset and the values Amount Text Field uses. (C2 · Rename) C2 · Variant & Property Naming - Checkmark converted to a vector. v2.0: The
imgCheckCDN raster is gone. The checkmark still exists as acheckvector group inside aCheckmarkframe (4996:25514), hidden by default — so it renders crisply at any density when shown. (C6 · Asset) C6 · Asset & Icon Quality - Error and Warning states added and made selectable. v2.1:
State = Default | Error | Warningis now a real third axis, givingTrailingContent(4) ×Size(2) ×State(3) = 24 uniquely-named variants. An intermediate pass had all 24 authored but only 8 distinct names — three groups shared identicalTrailingContent × Sizenames and differed only by theirSubtext Messagestate, so Figma treated them as conflicts and consumers had no way to select Error or Warning. Naming the axis made two-thirds of the component reachable. (C2 · State) C2 · Variant & Property Naming - Text layers renamed to
LabelandValue. v2.2:#label→Labeland#text→Value, matching §3 Form-content definitions exactly. Sampled across four variants spanning all three State groups and both sizes. Sets up the text properties, whose names default from the layer names. (C1 · Rename) C1 · Layer Structure & Naming -
LabelandValueconfirmed exposed as text properties. v2.2: Closed on owner confirmation — both are exposed, so consumers set copy from the instance panel without detaching. Not independently verifiable from the assessment tooling, which cannot read component property definitions. (C2 · Property) C2 · Variant & Property Naming - Wrapper frame names confirmed intentional. v2.2: Closed by owner decision —
content-containerandtext-containerstay as they are. They are internal auto-layout wrappers with no property or override surface, so their names never reach a consumer or a Code Connect mapping; the guidelines govern property names rather than layer names. (C1) C1 · Layer Structure & Naming -
containerrenamed toFieldRow. v2.1: Verified by exact string match across all 24 variants — no trailing whitespace and no leftovers. (C1) C1 · Layer Structure & Naming - Composes the shared
Subtext Messageinstance. v2.0: Every variant carries aSubtext Messageinstance for its helper, error and warning copy, so that anatomy propagates from one source rather than being re-authored. Same pattern as Text Area and Upload File. (Composition) C1 · Layer Structure & Naming - Variant matrix verified complete at 24. v2.4: Re-read on the live node.
TrailingContent = None | Badge | Link | Icon×Size = SM | LG×State = Default | Error | Warningships all 24 combinations with no gaps — SM at 55–56px and LG at 72px throughout.LabelandValuecarry the §3 vocabulary, and the trailing containers are kebab-case (badge-container,icon-container,text-link-container) per §4. (C1) C1 · Layer Structure & Naming -
Stateaxis renamed toStatus. v2.5: Verified on the live node — all 24 variants now readTrailingContent×Size×Status = Default | Error | Warning. The axis was carrying three statuses and no interaction values on a component that is display-only and can never be focused, pressed or disabled, so the form-field exception in §6 of the Property Naming Guidelines did not reach it. The rename cost nothing structurally — same three values, same 24 variants — and the component now reads correctly against the guideline the rest of the family is measured by. (C2 · Rename) C2 · Variant & Property Naming -
Subtext Messagecopy exposed via nested instance properties. v2.5: The message and its trailing label can be set from the parent without detaching. Attested rather than verified — nested-instance property exposure is not readable through the review tooling, so this is recorded on the owner’s confirmation. (C1 · Slot) C1 · Layer Structure & Naming
Label + value only. Used for plain read-only information display.
Display-only component — no interaction states. All colors token-bound.
| Role | Token | Value |
|---|---|---|
| Label | main/view-only-field/color/label | #6780A9 |
| Value text | main/view-only-field/color/text | #0A2757 |
| Text link | main/view-only-field/color/label-link | #005CE5 |
| Edit icon | main/view-only-field/color/icon | #005CE5 |
| Subtext description | main/subtext-message/primary/label | #6780A9 |
| Badge bg (default) | main/badge/information/light/background | #E5F1FF |
| Badge label | main/badge/information/light/label | #005CE5 |
Label + value + Badge instance in the trailing slot. Uses Badge component (layout=overflow or similar) for status indicators.
| Role | Token | Large |
|---|---|---|
| Height | 57px | 71px |
| Width | 360px | 360px |
| Label-value gap | 8px | 8px |
| Subtext top padding | 4px | 4px |
| Trailing icon size | 24 × 24 | 24 × 24 |
| Checkmark size | 13 × 13 | 13 × 13 |
Label + value + contextual text link (e.g. "What is this?"). Used for helper/learn-more navigation.
| Role | Token | Large Size |
|---|---|---|
| Label | Primary/Label/Light/Small — 14px Semibold | Primary/Label/Light/Base — 16px Semibold |
| Value text | Primary/Label/Light/Base — 16px Semibold | Primary/Headlines/Section — 22px Bold |
| Subtext description | Secondary/Bold/Small Caption — 10px Semibold (BarkAda) | Secondary/Bold/Caption — 12px Semibold (BarkAda) |
| Text link | 12px Semibold (BarkAda) | 12px Semibold (BarkAda) |
| Badge label | Primary/Label/Fine — 12px Bold | Primary/Label/Fine — 12px Bold |
Label + value + 24×24 icon (typically Edit pencil) in the trailing slot. Icon typically navigates to an editable state.
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") }
Package not yet published. These are the planned distribution paths.
| Figma Property | SwiftUI | Compose |
|---|---|---|
| variant=Default | (default — no trailing) | trailing = null |
| variant=with Badge rename | trailing: { EBBadge(...) } | trailing = { EBBadge(...) } |
| variant=with Text Link rename | trailing: { Button("...") {} } | trailing = { TextButton(...) } |
| variant=with Icon rename | trailing: { Image(...) } | trailing = { Icon(...) } |
| Size=Default rename | .controlSize(.regular) | size = EBFieldSize.Regular |
| Size=Large | .controlSize(.large) | size = EBFieldSize.Large |
| hasCheckmark (boolean) | isVerified: Bool | isVerified: Boolean |
| hasDescription (boolean) | description: String? | description: String? |
EBViewOnlyField( label: "Mobile Number", value: "+63 917 123 4567", description: "This is your verified number" )
EBViewOnlyField( label = "Mobile Number", value = "+63 917 123 4567", description = "This is your verified number" )
EBViewOnlyField( label: "Account Status", value: "Active", trailing: { EBBadge("Change", state: .information, level: .light) } )
EBViewOnlyField( label = "Account Status", value = "Active", trailing = { EBBadge( text = "Change", state = BadgeState.Information, level = BadgeLevel.Light ) } )
EBViewOnlyField( label: "Email Address", value: "dhar@frostdesigngroup.com", trailing: { Button(action: { /* navigate to edit */ }) { Image(systemName: "pencil") } } )
EBViewOnlyField( label = "Email Address", value = "dhar@frostdesigngroup.com", trailing = { IconButton(onClick = { /* navigate to edit */ }) { Icon(Icons.Default.Edit, contentDescription = "Edit") } } )
| Requirement | iOS | Android |
|---|---|---|
| Accessibility label | .accessibilityLabel("\(label): \(value)") | contentDescription = "$label: $value" |
| Trailing action (with Icon) | Button with .accessibilityLabel("Edit \(label)") | IconButton with contentDescription = "Edit $label" |
| Text link | Button with .accessibilityHint("Opens help") | TextButton with semantics { role = Role.Button } |
| Min touch target (trailing action) | 44 × 44 pt | 48 × 48 dp |
Do
Use View Only Field to display verified or system-set data (phone number, email, account status) where the user shouldn't edit directly.
Don't
Use for editable input — use Input Field, Labeled Field, or Select Field instead. Read-only fields imply the value is final or managed elsewhere.
Do
Use the with Icon variant with a pencil to indicate the field can be edited in a separate screen — provides a clear tap target.
Don't
Rely on the icon alone without an accessibility label — screen readers need to announce the trailing action's purpose.
| ID | Criterion | Status | Notes |
|---|---|---|---|
| C1 | Layer Structure & Naming | Ready | Semantic names: container, content-container, text-container, badge-container, text-link-container, icon-container. Clean hierarchy. |
| C2 | Variant & Property Naming | Needs Refinement | Property variant is overloaded (4 trailing content types as one enum). Size=Default isn't a size name — should be Regular. |
| C3 | Token Coverage | Ready | All colors bound to design tokens. Space, typography, and badge tokens all present. |
| C4 | Native Mappability | Ready | Maps cleanly to SwiftUI VStack / Compose Column with label + value + optional trailing closure. |
| C5 | Interaction State Coverage | Ready | Display-only component — no interaction states expected. Trailing actions (icon/text link) handle their own tap states. |
| C6 | Asset & Icon Quality | Needs Refinement | Checkmark uses a raster IMG from Figma CDN. Edit icon is a clean vector. Replace checkmark with an icon component instance. |
| C7 | Code Connect Linkability | Needs Refinement | No CLI mappings registered yet. |
4 variant values × 2 Size values. Two booleans (hasCheckmark, hasDescription) apply to all variants.
| variant | Size | Height | Node ID |
|---|---|---|---|
| Default | Default | 57 | 18403:4521 |
| with Badge | Default | 57 | 18403:4533 |
| with Text Link | Default | 57 | 18403:4547 |
| with Icon | Default | 57 | 18403:4561 |
| Default | Large | 71 | 18403:4575 |
| with Badge | Large | 71 | 18403:4587 |
| with Text Link | Large | 71 | 18403:4601 |
| with Icon | Large | 71 | 18403:4615 |
variant conflates 4 different trailing content types into one enum. Should be renamed to trailingContent or split into semantic properties.
Open