PriceLine
The total row of a checkout — a label with an optional action on one side, the price on the other.
price-lineOpen in Figma ↗Use for: displaying the price summary within a plan card or CTA Bar when the customer must compare an original price with a discounted price.
Not for: standalone page content or non-price information.
Choosing: use the content and pricing state supplied by the parent plan or purchase context; show the original-price treatment only when both original and discounted values are valid.
Rules: keep inside its parent card or CTA Bar; never invent pricing; never show a strikethrough without a verified replacement price.
import SwiftUI import EandTokens // price-line: padding 12 top / 20 sides, gap 12, top-aligned. Label body/md subtle with // an optional tertiary md action under it (gap 2); the value is title/xs, end-aligned. struct PriceLine: View { let label: String; let value: String var actionLabel: String? = nil var onAction: () -> Void = {} var body: some View { HStack(alignment: .top, spacing: EandSpacing.md) { VStack(alignment: .leading, spacing: EandSpacing.spacing2xs) { Text(label).font(.system(size: EandTypography.bodyMd.size)) .foregroundColor(EandColor.textDefaultSubtle) if let actionLabel { Button(action: onAction) { // tertiary hugs: no padding Text(actionLabel) .font(.system(size: EandTypography.buttonMd.size, weight: EandTypography.buttonMd.weight)) .foregroundColor(EandColor.buttonTertiaryTextBrandDefault) } } } Spacer(minLength: 0) Text(value) .font(.system(size: EandTypography.titleXs.size, weight: EandTypography.titleXs.weight)) .foregroundColor(EandColor.textDefaultDefault) .multilineTextAlignment(.trailing) } .padding(.top, EandSpacing.md).padding(.horizontal, EandSpacing.xl) } }
When to use
- Use for the price summary above the actions at the end of a purchase flow. Inside
ActionBlock or the CTA Bar, pass the same fields as
pricerather than rendering aPriceLineyourself. - Don't use for itemised charges or detail rows; use ListRow. Not for prices on plan or product cards, which carry their own.
Anatomy
- Label —
body/md, subtle, for example "Total". - Action — optional.
actionLabeladds a tertiary button under the label, such as "View breakdown", withonActionand an optional trailingactionIcon. A directional glyph is not mirrored for you; adddata-rtl-flipto it. - Value — the price in
title/xs, end-aligned.
The published symbol has no layer for an original, struck-through price. If a screen needs one,
compose it inside value. note is deprecated: it has no Figma counterpart and is kept only so
existing screens keep rendering.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | — | |
value | ReactNode | — | |
actionIcon? | ReactNode | — | Trailing icon inside the tertiary button (Figma's 20px .button-icon). |
actionLabel? | ReactNode | — | Tertiary button under the label (Figma button type=tertiary size=md). |
note? | ReactNode | — | Deprecated. Code-only: price-line 33496:60459 has no note under the value. Still
renders (body.sm, muted) so existing screens keep working; prefer actionLabel. |
onAction? | (() => void) | — |
Design
Figma source: price-line — etisalat Consumer App DSL V1.2
- Padding 12 at the top (
spacing/md) and 20 at the sides (spacing/xl); gap 12 (spacing/md); both columns top-aligned. - Label
body/mdintext/default/subtle; the tertiary md button sits 2 below it (spacing/2xs), with a 20px trailing icon. - Value
title/xsintext/default/default. - Every row is a flex row with logical padding, so the line mirrors in RTL.