Components
ActionBlock
The content of a CTA bar — status ribbon, price line, consent checkbox and actions — without its surface.
Figma description ·
.action-blockOpen in Figma ↗This component has no description in Figma yet.
Total amountAED 1,250.00
Props
import SwiftUI import EandTokens // .action-block payment=true: the payment summary and the lg primary button share one row // half and half (gap 2), padded 16/20/0. Without payment the button group pads 20/20/0. // PaymentRow: 40pt r8 tile on surface/base/default, body/md number over a tertiary "Change". struct ActionBlock: View { var body: some View { VStack(spacing: 0) { PriceLine(label: "Total amount", value: "AED 1,250") HStack(spacing: EandSpacing.spacing2xs) { HStack(spacing: EandSpacing.md) { Image("card-visa").resizable().scaledToFit() .frame(width: EandScale.scale40, height: EandScale.scale40) .background(EandColor.surfaceBaseDefault) .clipShape(RoundedRectangle(cornerRadius: EandRadius.radius3)) VStack(alignment: .leading, spacing: EandSpacing.xs) { Text("•••• 4326").font(.system(size: EandTypography.bodyMd.size)).lineLimit(1) Text("Change") .font(.system(size: EandTypography.buttonMd.size, weight: EandTypography.buttonMd.weight)) .foregroundColor(EandColor.buttonTertiaryTextBrandDefault) } } .frame(maxWidth: .infinity, alignment: .leading) EandButton(title: "Pay now") {}.frame(maxWidth: .infinity) } .padding(.top, EandSpacing.lg).padding(.horizontal, EandSpacing.xl) } } }
When to use
- Use when you need the closing actions of a flow step on a surface you already provide. For
the standard sticky footer, use the CTA Bar (
CtaFooter): it renders anActionBlockon its white surface with a shadow and the home indicator. - Don't use for actions inside page content; use a Button or a
ButtonGroupthere.
Anatomy
The slots stack top to bottom, as in Figma. Only actions is required.
ribbon— a full-widthStatusRibbon.price— the fields of a PriceLine:{ label, value, actionLabel?, onAction?, actionIcon? }.terms— a ConsentCheckbox. Its state stays with you.actions— aButtonGroupor a blockButton. Withpayment(aPaymentRow), the payment summary and the actions sit side by side, half the width each.
ActionBlock has no bottom padding. In the CTA Bar the 34px home indicator supplies it; on your
own surface, add the bottom spacing yourself.
import { useState } from 'react';
import { ActionBlock, Button, ButtonGroup, ConsentCheckbox } from '@eand/react-design-system';
function CheckoutActions() {
const [agreed, setAgreed] = useState(false);
return (
<ActionBlock
price={{ label: 'Total', value: 'AED 125.00' }}
terms={
<ConsentCheckbox
checked={agreed}
onChange={(e) => setAgreed(e.currentTarget.checked)}
prefix="Agree to the"
links={[{ label: 'Terms & Conditions', href: '/terms' }]}
/>
}
actions={<ButtonGroup primary={<Button size="lg" block disabled={!agreed}>Pay now</Button>} />}
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
actions | ReactNode | — | CTA buttons (use <ButtonGroup/> or a block <Button/>). |
payment? | ReactNode | — | Payment-method summary (use <PaymentRow/>); renders beside the actions, half each. |
price? | CtaFooterPrice | — | Price summary, rendered as a <PriceLine/>. |
ribbon? | ReactNode | — | Status strip across the very top (use <StatusRibbon/>). |
terms? | ReactNode | — | Checkbox line — pass a <ConsentCheckbox/> (or a <Checkbox/>) so state stays with the caller. |
Design
Figma source: .action-block — etisalat Consumer App DSL V1.2
- Order: status ribbon, price line, checkbox line, actions.
- Checkbox line: padding 16/20/0 (
spacing/lg,spacing/xl). - Actions without payment: padding 20/20/0 (
spacing/xl), the padding of.button-group-vertical. - Actions with payment: padding 16/20/0, gap 2 (
spacing/2xs); the payment row and the button take half each. - Every row is a flex row with symmetric or logical padding, so the block mirrors in RTL.