A dark, translucent directional tooltip with a backdrop blur, for use over photographic or high-contrast content.
.background(.ultraThinMaterial) (or a tinted .regularMaterial); Compose does it with Modifier.blur() on an underlying layer (or a Haze library for true backdrop blur). Collapse this component into the unified Tooltip proposed on the V2 page as one of three appearance values (.default | .onboarding | .translucent). The translucent appearance binds to a main/nudge/color/secondary/* token set on the surface and swaps the label colors for the light-on-dark pair. No dedicated component; no "V2"-style duplicate.Used over photographic, gradient, or high-contrast imagery where an opaque white tooltip would feel heavy. The backdrop blur keeps the background legible while the dark surface carries white type with full contrast.
main/nudge/color/secondary/* tokens; spacing to space/*; radius to radius/radius-2. Blur amount (2.5 px) is a raw literal — no effect/blur-* token. Pointer is a raster. C6pointer enum here — which makes the 4-boolean shape on Tooltip V2 even harder to defend. C2| State | iOS | Android | Figma Property | Notes |
|---|---|---|---|---|
| Show / hide | Yes | Yes | Not annotated | Expected: fade + slight scale-in anchored on the pointer side. Under the unified schema, shared with other appearance values. |
| Backdrop blur | N/A | N/A | backdrop-blur 2.5 px | iOS: .background(.ultraThinMaterial) or a custom blurred UIVisualEffectView. Compose: Modifier.blur() or a Haze effect for true behind-content blur. |
| Tap outside | N/A | N/A | Not defined | Standard tooltip contract — tap-outside dismisses. Same as other Tooltip siblings. |
| Pressed / Focused | N/A | N/A | Not built | No interaction states modelled. No dismiss affordance at all — consumer must rely on tap-outside or a timer. |
| Reduce transparency | N/A | N/A | Not defined | iOS: respect UIAccessibility.isReduceTransparencyEnabled — fall back to an opaque #0A2757 surface. Android: same fallback when high-contrast mode is on. |
- Visual treatment shipped as a standalone component. "Blurred and Transparent" describes a surface material + opacity, not a component role. The reusable unit is an
appearanceflag on the canonical Tooltip, not a separate Figma component. iOS and Compose both model this as a modifier applied to an existing view — never as a distinct type. C1 · Layer Structure & Naming - Third sibling Tooltip for one primitive. Alongside
Tooltip V2(70:14908) andOnboarding - Tooltip(51:17066), this duplicates the tooltip primitive. Fold all three into one component withappearance: .default | .onboarding | .translucent. C1 · Layer Structure & Naming - Component name describes a visual effect, not a role. "Tooltip Blurred and Transparent" chains two adjectives instead of naming what the component does. Under the unified schema, this becomes
Tooltip / appearance=.translucent— the role stays "Tooltip", and the treatment is a property value. C2 · Variant & Property Naming - Backdrop blur is a platform material, not a Figma shape. The 2.5 px blur is modelled as a Figma layer effect, but native platforms provide this via
.ultraThinMaterial(SwiftUI),UIVisualEffectView(UIKit), andModifier.blur()/ Haze libraries (Compose). A 1:1 Code Connect mapping of today's shape would emit a drawn blur surface instead of calling the correct platform API. C4 · Native Mappability - No icon, close, or CTA support. Schema is a strict subset of Tooltip V2 (header + description only). Consumers needing a leading icon, dismiss X, or a CTA must abandon this component and switch to V2 — losing the translucent surface in the process. An
appearanceproperty on one unified component removes this forced trade-off. C4 · Native Mappability - Pointer triangle is a raster asset. 4 separate image fills (
imgPointer,imgPointer1,imgPointer2,imgPointer3) — one per edge — for what should be a single vector shape rotated by thepointerenum. Same anti-pattern as Tooltip V2. C6 · Asset & Icon Quality - No interaction states. No Pressed / Focused / Dismissing states modelled. There is no dismiss control at all — no close X, no tap-to-dismiss contract in the component, no lifecycle annotation. C5 · Interaction State Coverage
- Blur amount (2.5 px) is a raw literal. Not bound to an
effect/blur-*token. If the DS later introduces a translucent-surface token set, this component won't pick up the change automatically. C6 · Asset & Icon Quality - Code Connect mappings not registered. Blocked on the consolidation — mapping today's shape would cement a standalone "translucent tooltip" type that shouldn't exist. Map once as one of the
appearancevalues of the unified Tooltip. C7 · Code Connect Linkability
- Fold this component into the unified Tooltip as
appearance: .translucent. Deprecate the standalone "Tooltip Blurred and Transparent" node. The translucent appearance flips surface and label tokens (main/nudge/color/secondary/bg+main/nudge/color/secondary/label) and, on native, applies.background(.ultraThinMaterial)/Modifier.blur(). No new component; no schema duplication. Family - Drop the visual-effect name. Rename to — or merge away as —
Tooltipwithappearance=.translucent. Component names should describe roles, not treatments. Rename - Bind the translucent surface to a named token set. Today the surface is
main/nudge/color/secondary/bg(#0A2757raw) paired with an 80% group opacity. Move to a propermain/nudge/color/translucent/{bg,label,description}token set with the alpha baked in, so the.translucentappearance picks up theme updates automatically. Token - Tokenize the blur radius. Replace the raw
2.5px literal with aneffect/blur-tooltip(or similar) token. Any future translucent surface (Modal, Overlay, Sheet) can then reuse the same value. Token - Replace the raster pointer with a vector triangle shared across appearances. One vector shape, rotated per
placement, picks up the appearance's surface token automatically. Fixes the raster problem across all 3 siblings at once. Asset - Instance-swap (conceptually) to the canonical Tooltip. Consumers currently using this component should swap to
Tooltip / appearance=.translucentduring the migration; leave a short-lived alias variant if needed to avoid breaking existing instances. Composition - Document the reduce-transparency fallback. When iOS
isReduceTransparencyEnabledor Android high-contrast is on, fall back to a solid#0A2757surface (no blur). Write this on the unified Tooltip's accessibility section so all consumers see it. A11y - Document
.translucentas photography-only. Annotate on the unified Tooltip: "Use.translucentonly over photographic or gradient backgrounds; for flat UI backgrounds, prefer.default." Gives designers a clear usage rule. Docs
Pointer above the surface — anchors a target element below. 336 × 89.
| Role | Token | Default |
|---|---|---|
| Surface | main/nudge/color/secondary/bg | #0A2757 @ 80% group opacity |
| Backdrop blur | — (untokenized literal) | 2.5 px |
| Header label | main/nudge/color/secondary/label | #FFFFFF |
| Description | main/nudge/color/secondary/description | #F6F9FD @ 80% (#F6F9FDCC) |
| Pointer triangle | — (raster, 4 images) | #0A2757 (baked into raster) |
Pointer on the right — anchors a target element to the right of the surface. 348 × 77.
| Role | Token | Value |
|---|---|---|
| Surface width — top / bottom | — | 336 px |
| Surface width — left / right | — | 336 px (content) · 348 px (with pointer offset) |
| Surface corner radius | radius/radius-2 | 6 px |
| Surface padding | space/space-16 | 16 px all sides |
| Surface background alpha | — | 0.80 (group opacity) |
| Backdrop blur | — | 2.5 px (untokenized) |
| Header → description gap | space/space-4 | 4 px |
| Pointer width / height | — | 22 × 12 (top/bottom) · 20 × 12 (left/right) — raster |
| Pointer → surface gap | space/space-0 | 0 px (abutting) |
Pointer below the surface — anchors a target element above. 336 × 89.
| Role | Token | Spec |
|---|---|---|
| Header | Primary/Headlines/Block | Proxima Soft Bold · 18 / 23 · +0.25 |
| Description | Secondary/Bold/Caption | BarkAda Semibold · 12 / 18 · +0 |
Pointer on the left — anchors a target element to the left of the surface. 348 × 77.
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") }
| Figma Property | SwiftUI | Compose |
|---|---|---|
| Tooltip Blurred and Transparent | Tooltip (same component) | EBTooltip |
| (distinct sibling) | appearance: .translucent | .ebAppearance(.translucent) |
| pointer: top / right / bottom / left | placement: .top / .right / .bottom / .left | arrowEdge: Edge |
| header (baked text) | title: String? | title: String? |
| description (baked text) | body: String? | body: String? |
| backdrop-blur 2.5 px (raw) | (absorbed into .translucent appearance) | .background(.ultraThinMaterial) |
| surface @ 80% opacity | main/nudge/color/translucent/bg | Color.nudgeTranslucentBg |
| (not modelled — no close) | hasDismiss: Bool (inherited) | dismissible: Bool |
// Translucent tooltip over imagery EBTooltip( title: "Featured deal", body: "Limited-time discount on your next top-up.", placement: .top ) .ebAppearance(.translucent) // Under the hood, .translucent applies: // .background(.ultraThinMaterial) // .foregroundStyle(.white) // + respects UIAccessibility.isReduceTransparencyEnabled
// Translucent tooltip over imagery EBTooltip( title = "Featured deal", body = "Limited-time discount on your next top-up.", placement = EBTooltipPlacement.Top, appearance = EBTooltipAppearance.Translucent ) // Under the hood, .Translucent applies: // Modifier.blur(radius = 2.5.dp) on the backing layer // background = nudgeTranslucentBg (#0A2757 @ 80%) // + respects high-contrast settings (falls back to solid #0A2757)
| Requirement | iOS | Android |
|---|---|---|
| Reduce transparency | Respect UIAccessibility.isReduceTransparencyEnabled — fall back to an opaque #0A2757 surface with no blur. | Respect high-contrast text setting — fall back to an opaque #0A2757 surface with no blur. |
| Contrast | White-on-#0A2757 meets WCAG AA at both states. Over photographic backdrops, the 80% alpha + blur keeps contrast above 4.5:1 in the designer's tested scenes. | Same. Always test the .translucent appearance over real content; do not use it for critical error messaging. |
| Reduce motion | Respect UIAccessibility.isReduceMotionEnabled — fade only; skip scale-in. | Respect Settings.Global.TRANSITION_ANIMATION_SCALE — fade only when motion is reduced. |
| Role | Announce as tooltip; group title + body via .accessibilityElement(children: .combine). | semantics { role = Role.Popup; mergeDescendants = true }. |
| ID | Criterion | Status | Notes |
|---|---|---|---|
| C1 | Layer Structure & Naming | Requires Rework | Third sibling for one primitive. A visual treatment shipped as a discrete component. Consolidate into the canonical Tooltip. |
| C2 | Variant & Property Naming | Requires Rework | Component name is a visual-effect description ("Blurred and Transparent"). Should collapse into Tooltip / appearance=.translucent. |
| C3 | Token Coverage | Needs Refinement | Surface, label, description, radius, and spacing all bound to tokens. The blur amount (2.5 px) and the 80% group opacity are raw literals — move to a translucent-surface token set. |
| C4 | Native Mappability | Requires Rework | Backdrop-blur is a platform material (.ultraThinMaterial / Modifier.blur()), not a component shape. A 1:1 Figma→native mapping today would emit a drawn blur layer instead of calling the correct API. Fixes when consolidated as an appearance value. |
| C5 | Interaction State Coverage | Requires Rework | No Pressed / Focused / Dismissing states. No dismiss affordance at all (no close X). |
| C6 | Asset & Icon Quality | Requires Rework | Pointer triangle is 4 raster images (one per edge). Same anti-pattern as Tooltip V2. |
| C7 | Code Connect Linkability | Not Mapped | Blocked on consolidation — mapping today's shape would cement a duplicate component. Map once as one of the unified Tooltip's appearance values. |
One enum axis yields 4 variants — pointer: top / right / bottom / left. Header + description are present in all shipped variants. Under the unified Tooltip, these 4 collapse into the shared placement enum, and the distinguishing surface treatment moves to appearance=.translucent.
| # | Pointer | Dimensions | Node |
|---|---|---|---|
| 1 | top | 336 × 89 | 49:335345 |
| 2 | right | 348 × 77 | 49:335347 |
| 3 | bottom | 336 × 89 | 49:335348 |
| 4 | left | 348 × 77 | 49:335346 |
appearance: .translucent. Do not ship a separate "Tooltip Blurred and Transparent" component. Openappearance enum. OpenTooltip / appearance=.translucent. Open.ultraThinMaterial; Compose uses Modifier.blur(). A component can't model a native modifier 1:1. OpenTooltip V2's 4-boolean pointer shape, this sibling already uses a single pointer enum — the correct model. Notedmain/nudge/color/secondary/*. Spacing via space/*. Radius via radius/radius-2. Noted