Design System
Components

ActionBar

A 72px tappable bar — a leading visual, a title and description, and one trailing chevron, button or switch.

Figma description · action-barOpen in Figma ↗

Container that pairs with banners and cards. Holds an icon or image, title, description and a trailing action, giving context for that action.

Use for: an actionable row inside a section, card or banner.

Not for: standalone page rows — use list-item.

Choosing: default in light sections. Inverse when the surrounding surface is dark or glass.

Rules: always sits inside a parent container, never directly on a page.

Now playinge& podcast · Ep 12
Props
import SwiftUI
import EandTokens

// action-bar: 72pt, r20, padding 0/16, gap 12. 40pt r12 leading tile, title/xs over a
// body/md description (both the scheme ink), one trailing trigger: a button, a switcher
// or a 20pt chevron in a 24pt box.
struct ActionBar: View {
  let title: String; let subtitle: String
  var body: some View {
    HStack(spacing: EandSpacing.md) {
      Image(systemName: "headphones")
        .frame(width: EandScale.scale40, height: EandScale.scale40)
        .background(EandColor.surfaceBaseDefault, in: RoundedRectangle(cornerRadius: EandRadius.radius4))
      VStack(alignment: .leading, spacing: 0) {
        Text(title).font(.system(size: EandTypography.titleXs.size, weight: EandTypography.titleXs.weight))
        Text(subtitle).font(.system(size: EandTypography.bodyMd.size))
      }
      .lineLimit(1)
      Spacer(minLength: 0)
      Image(systemName: "chevron.right").font(.system(size: EandIcon.lg))
        .frame(width: EandIcon.xl, height: EandIcon.xl)
    }
    .foregroundColor(EandColor.textDefaultDefault)
    .padding(.horizontal, EandSpacing.lg).frame(height: EandScale.scale72)
    .background(EandColor.surfaceRaisedDefault)
    .clipShape(RoundedRectangle(cornerRadius: EandRadius.radius7))
  }
}

When to use

  • Use for a row the user acts on: a settings entry, a prompt to top up, a shortcut into a flow, a feature toggle. Figma points tappable rows here rather than to the list item.
  • Don't use for read-only data such as a balance or a price (use ListRow), or for a grid of shortcuts (use QuickAction).

Anatomy

  • Leading (optional) — icon, an icon or image in a 40px tile.
  • Text — title in title/xs and subtitle in body/md, both in the scheme ink, each a single line that truncates.
  • Trigger — one of:
    • chevron: a trailing chevron; the whole bar becomes the tap target, handled by onClick.
    • action: a trailing node, typically a Button.
    • switcher: a Switcher; pass true or the Switcher props.
  • Stack — stack adds two glass layers that peek out below the bar, for a pile of related prompts. It renders with the inverse scheme only.

Choosing a surface

colorScheme sets the ink. When it is unset, it follows the surface: the glass and midnight surfaces and white-transparent are inverse, the rest default.

Familysurface
Default inkdefault (surface/raised/default), subtle (surface/base/default), sunken (surface/sunken/default), glass with colorScheme="default"
Inverse inkglass (20% white with a blur), white-transparent (20% white), midnight-base, midnight-raised, midnight-transparent
<ActionBar
  surface="midnight-raised"
  title="Running low on data"
  subtitle="Add 5 GB for AED 25"
  action={<Button size="sm">Top up</Button>}
/>

<ActionBar title="Wi-Fi calling" subtitle="Call over any network" switcher={{ defaultChecked: true }} />

Deprecated and changed

inverse is deprecated; use colorScheme="inverse". white-transparent moved to the inverse family in V1.2, so it now renders white ink.

Props

PropTypeDefaultDescription
action?ReactNode—Trailing action — typically a <Button>. Only one trailing trigger; do not combine with chevron or switcher.
chevron?boolean—Show a trailing chevron instead of a button — the whole bar becomes the tap target.
colorScheme?'default' | 'inverse'—Figma color-scheme: the ink. Defaults from surface — inverse for the dark/glass surfaces, else default. Set default with surface="glass" for the light-family glass.
icon?ReactNode—Leading visual (icon or image) shown in a 40×40 tile. Omit for text at the leading edge.
inverse?boolean—Deprecated. Use colorScheme="inverse" (or surface="glass").
stack?boolean—Multiple-stack — layered "stacked cards" look. Inverse scheme only (Figma type=multiple).
subtitle?ReactNode—Secondary line — body.md, truncates with ellipsis (Figma limit ~21 chars).
surface?'default' | 'glass' | 'midnight-base' | 'midnight-raised' | 'subtle' | 'sunken' | 'white-transparent' | 'midnight-transparent'—Backing surface. Light family: default·subtle·sunken·glass; inverse family: glass·white-transparent·midnight-base·midnight-raised·midnight-transparent.
switcher?boolean | SwitcherProps—Trailing switcher (Figma trigger=switcher). true, or the Switcher props.
title?ReactNode—Primary line — title.xs (Figma limit ~18 chars).

Design

Figma source: action-bar — etisalat Consumer App DSL V1.2

  • 72px tall (scale/72), 16px side padding (spacing/lg), 20px radius (border-radius/7), 12px gap (spacing/md).
  • Leading tile: 40px at border-radius/4, on surface/base/default, or white/a15 on the inverse scheme.
  • The description binds text/default/default (or text/default/inverse), the same ink as the title, not a subtle step.
  • The chevron is a 20px glyph in a 24px box.
  • Stack: two 64px layers at a 16px radius (border-radius/6) on surface/glass/white/md with a blur, inset 6 and 12px, each peeking 10px below the one above, for a 92px total.

On this page