East Blue
KeepReady
Modal - Transaction Receipt Entry Component link

One label-and-value row inside a transaction receipt. Two layouts: stacked when the value runs long, inline when it is short.

Keep — the smallest piece of the receipt, and it behaves like one
Two text layers, one setting, no wrapper. Modal - Transaction Receipt instances it three times through ⤷ TransactionSlot, which is the test a primitive has to pass. The inline layout is built the way it should be — #label fills the slack and #value hugs — so a long label pushes the value rather than clipping it. Nothing is outstanding on the component itself; Code Connect stays open because the native library does not exist yet.
In Context

Contexts are illustrative. Final screens will reference actual GCash patterns.

Live Preview
Label
Put content here
Properties
Layout
Content
#label
#value
DS Health
Reusable
Pass
Nothing in it is receipt-specific — it is a label and a value. Any surface that lists paired data can drop it in, and the two layouts cover both the short-value and long-value cases.
Self-contained
Pass
Carries its own type styles and colours, both bound to library variables. It deliberately carries no padding, because the slot it sits in owns the spacing between rows.
Consistent
Pass
Layout = Stacked | Inline matches Countdown - Unit, which uses the same property name for the same idea. #label and #value come from the design system's form vocabulary rather than being invented here.
Composable
Pass
Built to be instanced. Modal - Transaction Receipt stacks three of them inside ⤷ TransactionSlot, and the renames made during this assessment propagated straight through to all three.
Behavior
State iOS Android Figma Property Notes
Layout=Stacked N/A N/A 272 × 34 Label above value, both left-aligned and full width. The value's 16px line-height gives it room to wrap onto a second line.
Layout=Inline N/A N/A 272 × 24 Label left, value right, one line each at 14/14. The value truncates rather than wraps — this is the default the receipt uses.
Long label N/A N/A fill / hug Inline only. #label takes the slack at 164 and #value hugs at 108, so a longer label pushes the value instead of overlapping it.
Issues
  • The layout setting is named the way the rest of the system names it. It was Orientation = Inline | Stacked, which collided twice over: Countdown - Unit already used Layout for these exact values, and Voucher already used Orientation to mean Vertical or Horizontal. Now Layout = Stacked | Inline. The property name becomes the native parameter, so this was worth settling before Code Connect. C2 · Variant & Property Naming
  • The text layers say what they hold. #name and #text became #label and #value, matching the form vocabulary used elsewhere in the design system. The rename propagated to all three instances inside the receipt's slot. C2 · Variant & Property Naming
  • The line-height difference between layouts is deliberate. #value is 14/16 stacked but 14/14 inline, while #label stays 14/14 in both. Confirmed as intended rather than drift: the stacked layout exists for values that wrap onto a second line and needs the extra leading, and the inline value is a single truncating line that does not. C1 · Layer Structure & Naming
  • Having no container is deliberate. Both layouts are bare text layers directly under the component, where most components in the system wrap in a Container. Confirmed as intended: ⤷ TransactionSlot owns the gap between rows, so a container here would only add a level and a second place to set spacing. C1 · Layer Structure & Naming
Recommendations
  • Write down what the inline value does when it overflows. Inline gives the value 108px and one line. Whether a long reference number truncates at the tail, truncates in the middle, or forces the row to stacked is a decision the native implementation has to make, and it is not visible from the component. Middle truncation is usually right for identifiers, tail truncation for everything else. Docs
  • Publish the token names once Dev Mode is read. Both fills resolve to library variables — verified on the component's own text nodes — but the read-only tools return variable IDs rather than names, so the spec tables carry hex values only. A single Dev Mode pass would let the token paths be printed alongside them. Token
  • Read the pair as one thing for assistive tech. A screen reader stepping through the receipt should hear "Reference number, 165A25912345" as a single utterance rather than two disconnected fragments. Group the label and value and expose the label as the accessibility label of the value. A11y
  • See siblings: Modal - Transaction Receipt is the only consumer today, holding three of these in ⤷ TransactionSlot. Modal is the third component in the family and does not use this row. Family
Layout
Stacked
Label
Put content here
Properties
Layout Stacked
Shape Value under the label, free to wrap onto a second line
#label Text layer — "Label" is placeholder copy
#value Text layer — "Put content here" is placeholder copy
Versions 2
Colors
#label #6780A9
#value #0A2757
Background None — inherits the receipt surface
Typography
#label Primary/Label/Light/Small
#value Primary/Multi-line Label/Light/Small
Layout
Height 34 — Hug
Width 272
Radius 0
Padding H 0
Padding V 0
Gap 4
Alignment Top left
Colors by Layout

Two text colours and nothing else — the entry paints no surface of its own, so the receipt behind it shows through. Both layouts use the same pair; what changes between them is the arrangement and the value's text style, not the palette.

Role Token Value
#label text/color-text-weaker #6780A9
#value text/color-text #0A2757
Background none — inherits the receipt surface —
Inline
Label
Put content here
Properties
Layout Inline
Shape Value to the right on one line — the label fills the slack and the value hugs
#label Text layer — "Label" is placeholder copy
#value Text layer — "Put content here" is placeholder copy
Versions 2
Colors
#label #6780A9
#value #0A2757
Background None — inherits the receipt surface
Typography
#label Primary/Label/Light/Small
#value Primary/Label/Light/Small
Layout
Height 24 — Hug
Width 272
Radius 0
Padding H 0
Padding V 5
Gap 0
Alignment Left, centred
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:modal:1.0.0")

Import

import EastBlueDS
import com.eastblue.ds.modal.*

Planned API — the native library does not exist yet. The artifact is the Modal family: Modal, Modal - Transaction Receipt and this entry all ship in <code>com.eastblue.ds:modal</code> and import <code>com.eastblue.ds.modal.*</code>.

Property Mapping

One property. label and value are the two native parameters with no row here, because #label and #value are text layers rather than component properties — Figma exposes no way to set them but overriding the layer, which is also why Code Connect will have nothing to bind them to. layout is a parameter in both languages rather than a SwiftUI modifier: it decides the arrangement of the two children, not the component's appearance, and the modifier form would have read differently from the Compose signature for no gain.

Figma PropertySwiftUICompose
Layout — Stacked, Inline layout: EBEntryLayout = .stacked layout: EBEntryLayout = Stacked
Usage Snippets Planned API
Stacked — a value that needs to wrap
EBTransactionReceiptEntry(
    label: "Recipient",
    value: "Juan dela Cruz · 0917 123 4567",
    layout: .stacked
)
EBTransactionReceiptEntry(
    label = "Recipient",
    value = "Juan dela Cruz · 0917 123 4567",
    layout = EBEntryLayout.Stacked
)
Inline — a value that fits on one line
EBTransactionReceiptEntry(
    label: "Reference no.",
    value: "0091 2345 6789",
    layout: .inline
)
EBTransactionReceiptEntry(
    label = "Reference no.",
    value = "0091 2345 6789",
    layout = EBEntryLayout.Inline
)
Accessibility
RequirementiOSAndroid
Label and value read as one unit .accessibilityElement(children: .combine) Modifier.semantics(mergeDescendants = true)
Label is not announced as a separate control No traits added — it is static text No role assigned
Truncated inline values stay reachable Full value in accessibilityValue, not the truncated string Full value in contentDescription
Layout follows the text size setting Switch to stacked when Dynamic Type would truncate the inline value Switch to stacked at large font scales
Usage Guidelines

Do

Use inline for short, scannable values — amounts, dates, reference numbers.

Don't

Don't use inline for names or addresses that will truncate at 108px.

Do

Let the label take the slack so a longer label pushes the value.

Don't

Don't set a fixed width on the label to force a column — it clips the moment the copy changes.

Do

Keep spacing between rows on the slot that holds them.

Don't

Don't add padding inside the row; it will double up with the slot's gap.

Criteria Scorecard
ID Criterion Status Notes
C1 Layer Structure & Naming Ready Two text layers, no wrapper. Both differences between the layouts are confirmed intentional: the missing container, and the fact that #value carries a different text style in each — Primary/Multi-line Label/Light/Small stacked so it can wrap, Primary/Label/Light/Small inline so it stays on one line.
C2 Variant & Property Naming Ready Layout = Stacked | Inline matches Countdown - Unit. #label and #value come from the form vocabulary.
C3 Token Coverage Ready Both fills are bound and named: #label on text/color-text-weaker at #6780A9, #value on text/color-text at #0A2757. All four text layers resolve to shared library styles. The entry paints no surface, so the receipt behind it shows through.
C4 Native Mappability Ready A label and a value in a row or a column. Maps to an HStack with a Spacer or a VStack, with no web-only pattern in the way. layout is a parameter rather than a SwiftUI modifier because it arranges the children rather than styling them. The one gap is that neither piece of content is a Figma property — see C7.
C5 Interaction State Coverage Not Applicable Display only — the row is not tappable. In the receipt, the tap target belongs to the copy control on the reference row.
C6 Asset & Icon Quality Not Applicable No icons or assets — text only.
Variants Inventory (2 total)

1 component set × 2 Layout values = 2 variants. Content is set by overriding the two text layers, not through a variant, so nothing multiplies the set.

LayoutSize#value text styleNode
Stacked272 × 34Primary/Multi-line Label/Light/Small5947:181502
Inline272 × 24Primary/Label/Light/Small5947:181503
1.0.2 — September 2026Patch
Preview typeface corrected — node 5947:181504
The preview drew in the documentation font. .eb-preview-mtre-shell declared font-family: inherit, which resolves to the site’s --font-body — BarkAda. Both text layers carry Primary/* styles and are Proxima Soft in Figma, so every label and value on the page was rendered in the wrong face. The root now names Proxima Soft; no per-layer override is needed, because nothing in this component is Secondary.
Docs
1.0.1 — September 2026Patch
Style and Code tabs rebuilt to the content guides — node 5947:181504
One card became two. Layout is the driving property, so Stacked and Inline each get a card, in the panel’s order. The single card was titled with the component’s own name and specified Stacked only.
Docs
The four spec sections were in the wrong order. Properties, Colors, Layout, Typography; the order is Properties, Colors, Typography, Layout.
Docs
Layout carried one set of values for two variants that do not share them. The page said Gap 4, Padding 0, which can only ever have described Stacked. Read off both auto-layout panels: Stacked is 34 tall, gap 4, no padding, top left; Inline is 24 tall, gap 0, 5px above and below, left and centred. The old rows also used #label width and #value width in place of the seven canonical keys.
Docs
#value uses a different text style in each layout. Primary/Multi-line Label/Light/Small stacked, so long content wraps; Primary/Label/Light/Small inline, so it stays on one line. The page recorded this only as a line-height difference of 16 against 14, which is the consequence rather than the cause. #label is Primary/Label/Light/Small in both.
C3 resolved
Typography was two font specs, an IOU and a row that belonged elsewhere. Proxima Soft SemiBold · 14 / 14 · +0.25, "shared library style · name pending Dev Mode read", and an Alignment row that is a Layout key. All four text layers now resolve.
C3 resolved
Both fills are named. #label on text/color-text-weaker at #6780A9, #value on text/color-text at #0A2757, both matching the node fills exactly. A Colors by Layout table carries them, and states that the entry paints no surface of its own.
C3 resolved
Both cards declare an empty control panel. Layout was a control; it is the driving property, so it becomes the cards. Nothing else in the panel is switchable, which leaves the explicit empty array.
Docs
The install block pointed at coordinates that will never exist. gcash/east-blue-ios and com.gcash.eastblue:components:1.0.0, with no Import line. It now cites the Modal family artifact com.eastblue.ds:modal:1.0.0 and imports com.eastblue.ds.modal.*.
Docs
Property Mapping listed three rows for one property. #label and #value are text layers; the Figma panel exposes only Layout. One row now, with both strings named in the description instead.
Docs
Neither piece of content is bindable. Because #label and #value are layers rather than component properties, Code Connect will have nothing to attach the entry’s two strings to when the native library lands. Recorded against C7, which was already open on registration.
C7 open
The two tabs declared different APIs. The mapping had .ebLayout(.stacked / .inline) — a SwiftUI modifier — against its own Compose column’s layout: EBEntryLayout parameter, while the Style tab used a parameter in both. Settled on the parameter: layout arranges the two children rather than styling the component, so the modifier form would have diverged from Compose for no gain.
Docs
The variants table described a consequence, and asserted something unread. Its #value line-height column read "16 — wraps" and "14 — truncates". The line-heights follow from the text styles, and the truncation is preview CSS rather than anything Figma states. The column now carries the two resolved style names.
Docs
A snippet claimed a default that could not be read. "Inline — short values (receipt default)"; the property panel lists Stacked first, so naming Inline the default was a guess. The two snippets are now keyed plainly to the values and ordered to match the panel and the cards.
Docs
Three scorecard notes were stale or vague. C1 described "the line-height difference between layouts" and now names both text styles; C3 said the fills "resolve to library variables" without naming them and now carries both tokens and hexes; C4 gained the reasoning for layout being a parameter rather than a modifier.
Docs
DEV code is live for the first time, and Code Connect is emptied. The demo script had no getSnippet, so both language tabs were frozen on a static string.
Docs
1.0.0 — August 2026Initial
First assessment · node 5947:181504
New component. Extracted as the row primitive when the old Modal was split into Modal and Modal - Transaction Receipt.
Added
Orientation renamed to Layout, matching Countdown - Unit, which already used that name for the same Stacked and Inline values.
C2 resolved
#name and #text renamed to #label and #value; the rename propagated to all three instances in the receipt's slot.
C2 resolved
The 14/16 line-height on the stacked value confirmed intentional — stacked wraps, inline truncates.
C1 resolved
Having no Container confirmed intentional — ⤷ TransactionSlot owns the spacing between rows.
C1 resolved
Renamed from Transaction Entry to Modal - Transaction Receipt Entry to place it in the Modal family.
C2 resolved