Action Tile
Large tappable choice card with an icon, title, and supporting description. Built for decision moments — onboarding flows, empty states, "pick one to continue" screens — where each option needs more explanation than a button label allows.
Action Tiles
Import
typescript
import { DsActionTile } from '@verkview/design-system'Usage
vue
<template>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<DsActionTile
emoji="📁"
title="Create a project"
description="Group jobs by site or client"
@click="openProjectModal"
/>
</div>
</template>Props
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | required | Tile heading |
description | string | undefined | Supporting copy under the title |
emoji | string | undefined | Emoji rendered as the icon (takes precedence over icon) |
icon | Component | undefined | Lucide icon component rendered as the icon |
loading | boolean | false | Replaces the icon with a spinner (after a 100ms delay) and dims the tile |
disabled | boolean | false | Disables interaction |
ariaLabel | string | auto | Defaults to "{title} — {description}" |
Events
| Event | Payload | Description |
|---|---|---|
click | MouseEvent | Emitted when the tile is activated |
Loading State
The spinner only appears after 100ms, so instantaneous actions never flash it. While loading, the tile drops to 70% opacity and ignores pointer events — set loading on all sibling tiles at once to prevent double-taps during navigation.
Loading
Accessibility
- Renders as a native
<button>— Enter/Space activation and Tab focus for free. aria-labelcombines title and description so screen readers announce the full meaning.- Focus ring uses
focus-visible— visible for keyboard users, silent on tap. min-h-[120px]with full-width layout comfortably exceeds the 44px touch-target minimum.- Hover/press transitions respect
prefers-reduced-motion.
Used By
OnboardingModal.vue— the three welcome-modal choices shown on first login.