ConsolidateRequires Rework
Onboarding - Tooltip Component link

A directional tooltip used in onboarding overlays, with a pointer, header, description, and dismiss control.

Fold into the unified Tooltip; "Onboarding -" prefix is misleading (no walkthrough content)
This component, Tooltip V2, and Tooltip Blurred and Transparent model the same primitive with slightly different shapes. Merge into one Tooltip with placement: .top | .right | .bottom | .left (the only axis this sibling ships), appearance: .default | .onboarding | .translucent, hasDismiss, and an optional content/CTA body. Replace the 4 raster pointers with one vector and the raw close image with an icon/close instance. Once merged, rename the sibling that truly supports walkthroughs (with step indicator + Next/Skip) to carry the .onboarding appearance — or drop the name entirely.
In Context

A dismissible tip anchored to a feature element — commonly rendered during first-time user education, feature discovery, and coach-mark flows.

Wallet
Live Preview
Header
Description goes here
Placement
pointer
DS Health
Reusable
Warn
Works as a dismissible tip anchored to any target. But the "Onboarding -" prefix steers consumers toward walkthroughs it can't support (no step indicator, no Next/Skip). Misleading name fragments the primitive. C1
Self-contained
Warn
Surface, type, and spacing bind to main/nudge/* + space/* tokens — shares the collection with Tooltip V2. But the pointer arrow is 4 raster copies of one shape, and the close is an image asset rather than a DS icon instance. C6
Consistent
Warn
Pointer is modeled as a single enum here, but Tooltip V2 models the same concept as 4 booleans. Siblings should not disagree on the shape of a shared axis. C2
Composable
Fail
No Figma Slot for body content. No way to add an icon, an avatar, or a CTA — consumers who need those must switch components entirely. The primitive is closed. C4
Behavior
State iOS Android Figma Property Notes
Show / hide Yes Yes Not annotated Expected: fade + slight scale-in anchored on the pointer side.
Tap close (X) Yes Yes Close layer Dismiss icon is present but not wired to an interactive property. Close is an image asset, not a button instance.
Tap outside N/A N/A Not defined Standard tooltip contract — tap-outside dismisses. Should be documented on the component.
Primary CTA N/A N/A Not built Despite the "Onboarding" name, no CTA is provided. Consumers must switch to Tooltip V2 for any advance/skip control.
Pressed / Focused on close N/A N/A Not built Close is a raw image; no pressed / focused treatment and no hit target metadata.
Open Issues
  • Name implies walkthrough content that isn't shipped. Onboarding - Tooltip has no step indicator, no Next/Skip/Back CTAs, no progress dots, no illustration slot — it's just header + description + close. The prefix misleads consumers. Either rename to Tooltip / Placement and fold into the unified Tooltip, or add the actual onboarding axes (step indicator, Next/Skip) before keeping the name. C1 · Layer Structure & Naming
  • Three sibling Tooltip components for one primitive. Tooltip V2 (70:14908), this component (51:17066), and Tooltip Blurred and Transparent (49:335349) all model the same floating popover with slightly different shapes. Collapse into one Tooltip with appearance + placement. C1 · Layer Structure & Naming
  • Pointer schema disagrees with sibling. Onboarding - Tooltip models pointer direction as one pointer enum (correct), but Tooltip V2 models the same concept as 4 independent booleans. Siblings in the same family should never disagree on the shape of a shared axis. C2 · Variant & Property Naming
  • Pointer triangle is a raster asset. 4 separate image fills (imgPointer, imgPointer1, imgPointer2, imgPointer3) for what should be one vector shape rotated per direction. Replace with a single vector triangle; rotation handled by the placement enum. C6 · Asset & Icon Quality
  • Close (X) is an image asset, not a DS icon instance. The dismiss control uses imgShapeFull inside a generic "Close" frame rather than an instance of the DS's icon/close. Hides the icon from a11y labeling and token updates, blocks Code Connect from seeing it as a real control. C1 · Layer Structure & Naming
  • No body or CTA slot. There is no way to add a leading icon, an illustration, a step indicator, or a CTA. Any consumer that needs those must abandon this component for Tooltip V2 — defeating the point of a dedicated "Onboarding" sibling. C4 · Native Mappability
  • No dismiss / show states modeled. Close button is decorative; no Pressed / Focused state on the dismiss control. No appearing / dismissing lifecycle documented. C5 · Interaction State Coverage
  • Code Connect mappings not registered. Blocked on the family consolidation. Mapping today's 3-sibling shape to native would cement the wrong schema. C7 · Code Connect Linkability
Design Recommendations
  • Fold the 3 Tooltip siblings into one component. New schema: placement: .top | .right | .bottom | .left (this sibling's only axis), appearance: .default | .onboarding | .translucent, hasArrow: Bool, hasDismiss: Bool, cta: .none | .primary | .primaryAndSecondary, and a leading slot. This sibling's 4 variants collapse into the placement axis of the .default appearance — no dedicated component needed. Family
  • Rename or retire the "Onboarding -" prefix. The prefix should either be reserved for a sibling that actually ships onboarding affordances (step indicator, Next/Skip, Back) — in which case this component doesn't qualify — or dropped entirely in favor of an appearance: .onboarding enum on the unified Tooltip. Today's name promises content it doesn't deliver. Rename
  • Replace the 4 raster pointers with one vector triangle. Today there are 4 separate rasters (top/right/bottom/left). One vector shape, rotated per placement, fills the same role with zero asset burden, scales cleanly, and picks up surface + border token updates automatically. Asset
  • Instance-swap the close to icon/close. Use the canonical DS close-icon instance rather than an inline imgShapeFull. Gets you token-driven color, a11y labeling, and press-state handling for free. Composition
  • Adopt a content slot for body + optional CTA. The current closed shape (header + description + close, nothing else) is the reason this sibling exists. Adopt the unified Tooltip's content slot and this component disappears into the single source of truth. Slot
  • Add Pressed / Focused on the close control. Once the close becomes an icon-button instance rather than an image, states follow the canonical Button/Icon pattern. State
  • Document the dismiss contract + lifecycle. Add a description on the component: "Tap the close X or tap outside to dismiss. Tooltip appears with fade + slight scale from the pointer anchor; dismisses with reverse." Close the gap between designer intent and dev implementation. Docs
Styles
Pointers
DES DEV

Pointer triangle indicates target placement. Flip the pointer control in the demo panel to see top / right / bottom / left positions.

Header
Description goes here
Properties
pointer
Properties
pointer top
Colors
Surface #FFFFFF
Border #E5EBF4
Header #0A2757
Description #6780A9
Close icon #0A2757
Layout
Width 296px (max)
Padding 16 × 12
Border radius 6px
Pointer size 12 × 8
Typography
Header style Primary/Headlines/Block
Header font Proxima Soft Bold · 18 / 23 · +0.25
Description style Secondary/Bold/Caption
Description font BarkAda Semibold · 12 / 18
Colors by State
Role Token Default
Surface main/nudge/color/primary/bg #FFFFFF
Border main/nudge/color/primary/border #E5EBF4
Header label main/nudge/color/primary/label #0A2757
Description main/nudge/color/primary/description #6780A9
Close icon main/nudge/color/primary/icon-close #0A2757
Shadow elevation/app/shadow-low #020E22 · 6 %
Pointer triangle raster (4 images)
Installation Planned API

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:tooltip:1.0.0")
}
Property Mapping
Figma PropertySwiftUICompose
Onboarding - Tooltip (this) Tooltip · appearance: .default EBTooltip().ebAppearance(.default)
pointer: top / right / bottom / left placement: .top / .right / .bottom / .left arrowEdge: Edge
header (baked text) title: String? title: String?
description (baked text) body: String? (or content slot) body: String?
close (image asset, always shown) hasDismiss: Bool dismissible: Bool
(not modeled) cta: .none / .primary / .pair primary / secondary: TooltipAction?
(not modeled) leading (Slot) @ViewBuilder leading
(not modeled) onDismiss onDismiss: () -> Void
SwiftUI
ios/Components/Tooltip/EBTooltip.swift
Jetpack Compose
android/components/tooltip/EBTooltip.kt
Usage Snippets Planned API
Usage
// Equivalent of today's "Onboarding - Tooltip · pointer=bottom"
EBTooltip(
    title: "Quick transfers",
    body: "Tap here to send money to recent contacts.",
    placement: .bottom
)
.onDismiss { showTip = false }

// pointer=right · same appearance, placement flipped
EBTooltip(
    title: "Your balance",
    body: "Tap to reveal or hide.",
    placement: .right
)
// Equivalent of today's "Onboarding - Tooltip · pointer=bottom"
EBTooltip(
    title = "Quick transfers",
    body = "Tap here to send money to recent contacts.",
    placement = EBTooltipPlacement.Bottom,
    onDismiss = { showTip = false }
)

// pointer=right
EBTooltip(
    title = "Your balance",
    body = "Tap to reveal or hide.",
    placement = EBTooltipPlacement.Right
)
Accessibility
RequirementiOSAndroid
Role + focus Announce as .accessibilityAddTraits(.isModal) when dismissible; VoiceOver moves focus to the tooltip on appear. semantics { role = Role.Popup }; TalkBack focuses the tooltip container on appear.
Close control Wrap close as a Button with accessibilityLabel "Dismiss tip" and 44×44 hit target (current 24 × 24 is below minimum). IconButton with contentDescription = "Dismiss tip"; 48×48 dp minimum (current hit area is ~24 × 24 dp).
Dismiss-outside Do not auto-dismiss while VoiceOver is active — hold until user explicitly moves on. Do not auto-dismiss while TalkBack is active.
Reduce motion Respect UIAccessibility.isReduceMotionEnabled — fade only, skip scale-in. Respect Settings.Global.TRANSITION_ANIMATION_SCALE — fade only when motion reduced.
Combined label Read title + body + "Dismiss" as one phrase; avoid reading pointer. mergeDescendants = true on the container.
Criteria Scorecard
ID Criterion Status Notes
C1 Layer Structure & Naming Requires Rework "Onboarding -" prefix misleads — component ships no walkthrough content. 3 sibling Tooltip components for one primitive. Close uses a raw image inside a generic "Close" frame.
C2 Variant & Property Naming Needs Refinement Pointer is correctly modeled as one enum here (cleaner than Tooltip V2's 4 booleans) — but siblings should agree on the shape of the shared axis.
C3 Token Coverage Ready Surface, border, label, description, close icon, shadow all bound to main/nudge/* / elevation/*. Spacing via space/*. Radius via radius/radius-2.
C4 Native Mappability Requires Rework Closed shape — no slot for body content or CTA. Maps cleanly to native only after consolidation into the unified Tooltip with content slot + cta axis.
C5 Interaction State Coverage Requires Rework No Pressed / Focused on close. No appearing / dismissing lifecycle annotated. Close isn't wired to a dismiss property.
C6 Asset & Icon Quality Requires Rework Pointer is 4 raster images (one per direction). Close is an image asset (imgShapeFull) rather than an icon/close instance.
C7 Code Connect Linkability Not Mapped Blocked on consolidation. Mapping today's sibling component would cement the wrong schema.
Variants Inventory (4 total)

One axis: pointer (4 values) = 4 variants. Content (header / description / close) is fixed across all variants.

#PointerDimensionsPointer assetNode
1top336 × 90imgPointer51:17065
2bottom336 × 89imgPointer151:17063
3left348 × 78imgPointer251:17062
4right348 × 78imgPointer351:17064
1.0.0 — April 2026Major
Initial Assessment · node 51:17066
Verdict: Consolidate — Fold into the unified Tooltip as appearance: .default with the placement axis. The "Onboarding -" prefix is misleading (no walkthrough content ships). Open
Architecture
C1 — Misleading name — No step indicator, no Next/Skip/Back CTAs, no progress dots. Component is not onboarding-specific. Open
C1
C1 — 3 siblings for 1 primitive — Tooltip V2, Onboarding - Tooltip, Tooltip Blurred and Transparent. Merge via appearance + placement. Open
C1
C2 — Pointer schema disagrees with sibling — This sibling uses one enum; Tooltip V2 uses 4 booleans. Family members should agree on the shape of a shared axis. Open
C2
C4 — No slot for body or CTA — Closed shape forces consumers to switch to Tooltip V2 for anything richer than header + description. Open
C4
C5 — No dismiss/focus states — Close is a raw image; Pressed / Focused / Lifecycle not modeled. Open
C5
C6 — Raster pointer + raw close — 4 raster images (one per direction). Close is an image asset rather than icon/close. Vector + icon instance. Open
C6
C7 — Code Connect — Blocked on consolidation. Open
C7
Tokens ✓ — Surface / border / label / description / close / shadow all bound to main/nudge/* and elevation/*. Spacing via space/*. Noted
Praise