ConsolidateRequires Rework
Vertical Voucher Component link

A 162-wide vertical voucher tile combining a Voucher Asset image with title, description, price, validity, and status badges.

Replaced by Voucher Card Horizontal
This component is consolidated into Voucher Card Horizontal — the canonical sibling. Use Voucher Card with orientation: vertical and the state axis instead. Once Figma usages migrate, this record will be deleted.
Live Preview
Food35% offFood35% off
LimitedExpiring
HotDiscounted
Buy Load Pre-seeded SKU Voucher Sample
This is the description of the voucher.
PHP 100.00
PHP 150.00
Validity: Dec 25 2022 - Jan 5 2023
Default (all props on)
Food35% off
LimitedExpiring
Buy Load Pre-seeded SKU Voucher Sample
This is the description of the voucher.
PHP 100.00
PHP 150.00
Validity: Dec 25 2022 - Jan 5 2023
Large asset only
Food35% off
HotDiscounted
Buy Load Pre-seeded SKU Voucher Sample
This is the description of the voucher.
Small asset minimal
Migration
DS Health
Reusable
Fail
All text content is hardcoded placeholder. Consumers cannot set a title, price, validity, or badge label without detaching. A "reusable" voucher component that can only render the sample "Buy Load Pre-seeded SKU Voucher Sample" string is not reusable.
Self-contained
Warn
The symbol does carry its own layout, spacing, and token-bound colors via main/vouchers/color/default/*. But it ships two asset frames bundled together, assuming consumers will turn one off — nothing enforces the mutual exclusion.
Consistent
Fail
Parallel to Horizontal Voucher and Voucher Card Horizontal — three components for one concept. Voucher Card Horizontal ships a proper state axis (Default/Limited/Expiring/Used/Expired); Vertical Voucher ships none. Property shape diverges across the family.
Composable
Warn
Nests a Voucher Asset instance (composition works) and Badge instances (composition works). But since the voucher content is locked placeholder, a parent screen cannot actually compose real voucher data into this component.
Behavior
State iOS Android Figma Property Notes
Asset size N/A N/A largeAsset + smallAsset booleans Two booleans for a mutually exclusive choice. Should be a single enum.
Title N/A N/A header boolean (string hardcoded) String is frozen in the symbol. Boolean only toggles visibility.
Price / original N/A N/A amount boolean (strings hardcoded) "PHP 100.00" and "PHP 150.00" frozen; one boolean toggles both.
Validity N/A N/A validityPeriod boolean (string hardcoded) "Validity: Dec 25 2022 - Jan 5 2023" frozen.
Status badges N/A N/A prop1stRowBadges + prop2ndRowBadges Two fixed rows of 2 fixed badge labels each. Row-level visibility only — consumers can't pick which badges to render.
State N/A N/A Not modelled Absent entirely. Voucher Card Horizontal has it; Vertical Voucher does not.
Tap target N/A N/A Not modelled Vouchers are always tappable; current symbol has no pressed/disabled states.
Resolved Issues
  • Voucher content tokens exist. Background (main/vouchers/color/default/bg), title (label-title), description (label-description), amount (label-amount), strikethrough amount (label-amount-original), and metadata (label-metadata) are all bound to the voucher component's variable collection. C3 · Token Coverage
Open Issues
  • Three parallel components for one concept. Vertical Voucher, Horizontal Voucher (5121:4533), and Voucher Card Horizontal (5119:1786) share the same anatomy — voucher asset image + title + description + price + validity + status badges — but ship as three separate components with divergent property shapes. This is a family-level consolidation, not a single-component fix. C4 · Native Mappability
  • No state axis. Voucher Card Horizontal ships Default / Limited / Expiring / Used / Expired as a proper state variant that drives background, label colors, and badge treatment. Vertical Voucher has no state concept — a used or expired vertical voucher cannot be rendered in greyed-out treatment. C5 · Interaction State Coverage
  • All text content is hardcoded placeholder. Title "Buy Load Pre-seeded SKU Voucher Sample", description "This is the description of the voucher.", price "PHP 100.00", original price "PHP 150.00", and validity "Validity: Dec 25 2022 - Jan 5 2023" are all frozen strings inside the symbol. Booleans toggle visibility but not content. Consumers cannot render a real voucher without detaching. C2 · Variant & Property Naming
  • Two asset sizes bundled in one symbol. The symbol contains both the large (153h) and the small (100h) Voucher Asset instances stacked; largeAsset and smallAsset booleans turn them on/off. The default 465h render shows both. This is a single enum (assetSize: large | small) masquerading as two booleans with implied mutual exclusion. C2 · Variant & Property Naming
  • Badges are row-level, not array-level. prop1stRowBadges and prop2ndRowBadges toggle rows of two hardcoded badges each ("Limited" + "Expiring" / "Hot" + "Discounted"). A real voucher with one "Limited" badge and nothing else cannot be rendered. Badges should be a composable array, not fixed rows. C2 · Variant & Property Naming
  • Layer structure is flat and unlabeled. large asset, small asset, content, badges, badges (duplicate), price. Two layers named badges, no semantic names for the title/description/validity text nodes. Consumers inspecting the Dev Mode output see anonymous text layers. C1 · Layer Structure & Naming
  • Voucher Asset nested image is raster with hardcoded "35% off" Badge. Inherits all the issues of Voucher Asset (5119:1664) — the discount amount is baked into the image-frame variant, not a property on the parent. A voucher offering "50% off" or "BUY1 TAKE1" cannot be rendered. C6 · Asset & Icon Quality
  • No native component maps to this shape. 8 booleans with hardcoded content do not map to any reasonable native API. A proper EBVoucherCard takes title, price, validity, badges array, and image as parameters — not eight visibility toggles. Code Connect has no 1:1 target. C4 · Native Mappability
  • Code Connect cannot link an 8-boolean symbol with frozen strings. Even if a mapping existed, swapping the "title" string or the badge labels would require detaching the component. Linkability requires real string/array properties first. C7 · Code Connect Linkability
Design Recommendations
  • Merge the three voucher cards into a single Voucher Card component. Vertical Voucher + Horizontal Voucher + Voucher Card Horizontal become one component with orientation: vertical | horizontal (swaps the layout axis) and state: default | limited | expiring | used | expired (borrowed from Voucher Card Horizontal). Target shape: 2 orientations × 5 states = 10 variants instead of three separate components with divergent schemas. Family
  • Promote every text string to a property. Add title: String, description: String, price: String, originalPrice: String?, validity: String?. Retire the header / amount / description / validityPeriod booleans — visibility falls out of whether the string is empty. Property
  • Replace the two asset-size booleans with one assetSize enum. largeAsset + smallAsset become assetSize: large | small | none. Nothing currently prevents both being on simultaneously (which is the default render). A single enum makes the choice explicit and mutually exclusive. Property
  • Adopt a Figma Slot for the voucher image. Replace the hardcoded Voucher Asset nested instance with a Slot that accepts any Voucher Asset variant (or a partner brand illustration). The discount badge should be composed on top of the slot, not baked into the asset. Slot
  • Replace fixed badge rows with a composable badges array. Drop prop1stRowBadges / prop2ndRowBadges. Expose a badges Slot that accepts 0..n Badge instances, wraps when it runs out of width. Consumers choose which badges apply ("Limited" alone, "Hot" + "Discounted" + "New", etc.). Slot
  • Add the state axis missing from Vertical Voucher. Used and Expired vouchers render in greyed-out treatment with muted labels and a dim asset overlay — a pattern Voucher Card Horizontal already ships. Port the same 5-state treatment to the unified Voucher Card. State
  • Rename duplicated badges layers. The two badge-row frames are both named badges. After the consolidation above they should collapse into a single badges-slot layer; until then, name them badges-row-1 / badges-row-2 to disambiguate. Rename
  • Document that Voucher Card is the tap target. Vouchers are always tappable entry points to the voucher detail screen. The unified component should ship a pressed/focused state on the card frame; the handoff is an onTap closure, not an internal CTA button. Docs
Styles
Vertical Voucher
DES DEV

Legacy 162-wide vertical voucher tile. Migrate to <a href="/components/voucher-card-horizontal">Voucher Card Horizontal</a> with <code>orientation: vertical</code>.

Food35% off
LimitedExpiring
Buy Load Pre-seeded SKU Voucher Sample
This is the description of the voucher.
PHP 100.00
PHP 150.00
Validity: Dec 25 2022 - Jan 5 2023
Properties
Orientation vertical
Width 162
Colors
Surface bg #FFFFFF
Title #0A2757
Description #445C85
Amount #005CE5
Original price #90A8D0
Validity #6780A9
Layout
Width 162
Image area 162 × 153
Body padding 8 12 12 12
Corner radius 4
Border 1px solid #E6EAF2
Typography
Title Proxima Soft Bold · 14 / 18 · +0.25
Amount Proxima Soft Bold · 14 · +0.25
Original price Proxima Soft Semibold · 12 (strike)
Validity BarkAda Semibold · 10 / 15
Property Mapping

The current 8 booleans do not map cleanly to native. The table below shows the target shape after the family consolidation — each row captures what the proposed EBVoucherCard replaces from the current Vertical Voucher.

Figma PropertySwiftUICompose
orientation orientation: EBVoucherOrientation
state state: EBVoucherState
largeAsset + smallAsset assetSize assetSize: .large | .small | .none
header (boolean, string frozen) title (string) title: String
description (boolean, string frozen) description (string) description: String?
amount (boolean, PHP 100 / PHP 150 frozen) price + originalPrice price: String, originalPrice: String?
validityPeriod (boolean, string frozen) validity (string) validity: String?
prop1stRowBadges + prop2ndRowBadges badges Slot badges: [EBBadge]
nested Voucher Asset Image Slot trailing closure
onTap: () -> Void
Criteria Scorecard
ID Criterion Status Notes
C1 Layer Structure & Naming Requires Rework Two frames both named badges. Text layers are unnamed. Asset frames large asset / small asset should be one frame with an assetSize property.
C2 Variant & Property Naming Requires Rework 8 booleans where most should be strings (title, price, validity) or a Slot (badges). largeAsset + smallAsset should be one enum. All content is frozen placeholder.
C3 Token Coverage Ready Background, title, description, amount, strikethrough amount, and metadata are all bound to main/vouchers/color/default/*. Typography uses named text styles (Primary/Multi-line Label/Base, Primary/Label/Small, Secondary/Default/Caption, Secondary/Default/Fine).
C4 Native Mappability Requires Rework Parallel to 2 other voucher components with divergent schemas. Native has one EBVoucherCard, not three. 8 booleans with frozen strings have no native analog.
C5 Interaction State Coverage Requires Rework No state axis at all. Voucher Card Horizontal ships Default/Limited/Expiring/Used/Expired; Vertical Voucher has none. No pressed/focused/disabled on the card frame either.
C6 Asset & Icon Quality Requires Rework Inherits Voucher Asset's raster + hardcoded "35% off" badge. The discount amount is not a property on the parent Voucher.
C7 Code Connect Linkability Requires Rework Cannot map. Frozen strings, row-level badge toggles, and two-boolean asset size do not have 1:1 native parameters. Linkability requires the family consolidation first.
Variants Inventory (1 total)

Single symbol, no variant axes declared. All configurability is through 8 boolean property toggles on the lone instance.

Node IDNameDimensionsProperty toggles
5119:1635Vertical Voucher162 × 465 (with both assets + all content on)amount, description, header, largeAsset, prop1stRowBadges, prop2ndRowBadges, smallAsset, validityPeriod — all boolean, all default true
1.0.0 — April 2026Major
Initial Assessment · node 5119:1635
Assessed with Consolidate verdict. Single symbol with no variants, 8 boolean toggles, and entirely hardcoded content. Parallel to Horizontal Voucher (5121:4533) and Voucher Card Horizontal (5119:1786). Open
Design Decision
Proposed family-level merge. Collapse the 3 voucher components into one Voucher Card with orientation + state axes, text slots (title, description, price, originalPrice, validity), a badges array, and a voucher image Slot. Target: 2 × 5 = 10 variants instead of 3 divergent components. Open
Design Decision