Live Preview
Mobile Quick Actions Grid
--- description: Quick Actions — grid of circular icon buttons with labels. Mobile-only pattern for home screen shortcuts.
Quick Actions Component
Grid of icon shortcut buttons — pattern mobile chính (Grab, MoMo, banking apps). Dùng trên home screen để truy cập nhanh các tính năng.
1. Khi nào dùng
| Tình huống | Component |
|---|---|
| Home screen shortcuts | Quick Actions ✅ |
| Transfer/pay/scan actions | Quick Actions ✅ |
| Navigation menu | Bottom Nav / Sidebar |
| Single action button | Button |
2. Platform: 📱 App only
3. Token Mapping
📦 Atomic Mapping: See
ATOMIC-MAPPING.mdfor complete token spec.
📦 UI Layer: Card (in-flow), Density Tier: comp
| Property | Token |
|---|---|
| Grid gap | var(--group-inline-gap-default) |
| Grid columns | repeat(4, 1fr) |
| Item text-align | center |
| Icon container size | 48×48px |
| Icon container bg | var(--primary-muted) |
| Icon container radius | var(--comp-radius-capsule) |
| Icon size | var(--icon-lg) |
| Icon color | var(--primary-muted-foreground) |
| Label font | var(--text-style-caption-font-size) |
| Label color | var(--muted-foreground) |
| Label margin-top | var(--comp-stack-gap-small) |
| Hover | var(--state-layer-hover) on icon container |
| Focus ring | 2px solid var(--ring) |
| Touch target | Min 48×48 icon + label area |
4. Variants
| Variant | Mô tả |
|---|---|
default |
Primary muted circle icons |
colorful |
Each icon has its own semantic color |
outlined |
Border instead of fill |
5. CSS Skeleton
css
.card-speed-dial {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: var(--group-inline-gap-default);
padding: var(--comp-padding-default) 0;
}
.card-quick-action {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--comp-stack-gap-small);
cursor: pointer;
background: none;
border: none;
font-family: inherit;
color: inherit;
}
.card-quick-action__icon {
width: 48px;
height: 48px;
border-radius: var(--comp-radius-capsule);
background: var(--primary-muted);
color: var(--primary-muted-foreground);
display: flex;
align-items: center;
justify-content: center;
transition: background var(--motion-preset-hover);
}
.card-quick-action__icon svg {
width: var(--icon-lg);
height: var(--icon-lg);
}
.card-quick-action:hover .card-quick-action__icon {
background: var(--state-layer-hover);
}
.card-quick-action:focus-visible {
outline: 2px solid var(--ring);
outline-offset: 2px;
border-radius: var(--comp-radius);
}
.card-quick-action__label {
font-size: var(--text-style-caption-font-size);
color: var(--muted-foreground);
}
/* Color variants */
.card-quick-action__icon--success { background: var(--success-muted); color: var(--success-muted-foreground); }
.card-quick-action__icon--warning { background: var(--warning-muted); color: var(--warning-muted-foreground); }
.card-quick-action__icon--info { background: var(--info-muted); color: var(--info-muted-foreground); }
.card-quick-action__icon--destructive { background: var(--destructive-muted); color: var(--destructive-muted-foreground); }
/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
.card-quick-action__icon { transition: none; }
}
6. HTML Example
html
<div class="card-speed-dial">
<button class="card-quick-action">
<div class="card-quick-action__icon">
<svg><!-- send icon --></svg>
</div>
<span class="card-quick-action__label">Transfer</span>
</button>
<button class="card-quick-action">
<div class="card-quick-action__icon card-quick-action__icon--success">
<svg><!-- wallet icon --></svg>
</div>
<span class="card-quick-action__label">Top Up</span>
</button>
<!-- ... more actions -->
</div>