Action List
List what needs doing, one row each, with why, by when and the action that fixes it.
import { ActionList, ActionListItem } from '@youj/react'
Installation & usage
npm i @youj/reactFor an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.
Use an action list where a screen asks someone to do things: alerts that need a decision, setup steps, renewals coming due, reviews waiting. Each row is an icon tile, a title, one line of detail, an optional chip and the row's own action. For a stream of events that only informs, use a Notification Center; for one record's fields, a Property List.
import { CalendarIcon, ShieldAlertIcon } from '@youj/icons'
import { ActionList, ActionListItem, Button } from '@youj/react'
<ActionList title="Waiting on you" count={9} action={<Button variant="ghost" size="sm">View all</Button>}>
{alerts.map((alert) => (
<ActionListItem
key={alert.id}
icon={<ShieldAlertIcon />}
tone="danger"
title={alert.title}
detail={alert.detail}
meta={<><CalendarIcon /> {alert.due}</>}
action={<Button variant="secondary" size="sm" onClick={() => resolve(alert.id)}>Resolve</Button>}
/>
))}
</ActionList>tone colors the icon tile (neutral, accent, info, success, warning or danger); the chip takes the same tone unless you pass metaTone. count sits in a chip beside the title and can be larger than the rows you show, with the header action linking to the rest. Key every row by a stable id: the rows are a PresenceList, so removing one when it is done fades it out and closes the gap.
Below 20rem of its own width, the chip and the action wrap under the text instead of squeezing it.
Description
A workspace's open problems, most urgent first: each row says why, carries the date or amount that makes it urgent, and offers the one fix.
Setup steps with the first set apart as the one to do now.
emphasis draws a row as a tinted panel in its tone, with the icon on a plain tile. Use it for one row at most: the point is that one thing comes first.
Code
action-list-demo.tsx, the Demo story. The component itself comes from the package.
Reference
PropsActionList, ActionListItem
Props
| Prop | Type | |
|---|---|---|
title | ReactNodeWhat the list is: "Waiting on you". Names the section. | – |
description | ReactNodeA muted line under the title: where the rows came from, how they're sorted. | – |
count | numberHow many there are, in a chip beside the title. It can be more than the rows shown. | – |
action | ReactNodeAt the end of the header: a "View all" link or button. | – |
headingLevel | 2 | 3 | 4 | 5 | 6The title's heading level. default 3 | 3 |
children | ReactNodeActionListItems, each keyed by a stable id. | – |
Other props pass through: extends ComponentProps<'section'>. | ||
ActionListItem
| Prop | Type | |
|---|---|---|
icon | ReactNodeThe row's icon, drawn in a tile in the row's tone. | – |
tone | ActionListTone'neutral''accent''info''success''warning''danger'The tile's (and, with default 'neutral' | 'neutral' |
titleRequired | ReactNodeWhat to act on: "Contract renews in 12 days". | – |
detail | ReactNodeOne line of why: who, how much, by when. | – |
meta | ReactNodeA chip before the action: the date, amount or state that makes it urgent. Text, optionally led by a small icon. | – |
metaTone | ActionListTone'neutral''accent''info''success''warning''danger'The chip's tone. Default: the row's. | – |
action | ReactNodeAt the row's end: the row's own action, usually a small Button. | – |
emphasis | booleanSets this row apart as the one to do first: a tinted panel in its tone. default false | false |
Other props pass through: extends ComponentProps<'li'>. | ||
StylingParts and data attributes
Styling
Parts: action-list, action-list-header, action-list-title, action-list-count, action-list-description, action-list-action, action-list-items, action-list-item (with data-tone and data-variant: default or emphasis), action-list-icon, action-list-item-title, action-list-item-detail, action-list-meta (with data-tone) and action-list-item-action.
MotionAdd, remove · reduced motion
Motion
| Moment | Tokens | ||
|---|---|---|---|
| Row addeddrops in and fades up | duration.baseease.enter220ms · cubic-bezier(0.16, 1, 0.3, 1) | 220mscubic-bezier(0.16, 1, 0.3, 1) | |
| Row removedfades out; the rows below close the gap | duration.fastease.exitspring.smooth140ms · cubic-bezier(0.4, 0, 1, 1) · 0.36s, bounce 0 | 140mscubic-bezier(0.4, 0, 1, 1)0.36s, bounce 0 |
Reduced motion
Rows come and go at once.
Reduced motion
Rows are added and removed at once, with no fade or slide.
AccessibilityRegion, list
Accessibility
- With a
titleit is asectionnamed by its heading (headingLevel, 3 by default), so it is a landmark region; the rows are a list. - The icon tile is decorative (
aria-hidden); the title and detail carry the meaning, and the chip is plain text. - Name each row's action for what it does ("Rotate key", not "Go"), since a screen reader may reach it out of its row.
- A row on its way out is inert, so focus can't land on it.