Tray
StableA soft panel with a short list of things to look at, and an optional message box under it.
Also known as sidebar list, navigation list, panel list
Install with npm install @tattva/ui (setup), or copy the code from the kit in Downloads.
Rows that need attention
Needs you
4 running →<div className="max-w-xl">
<Tray label="Needs you" action="4 running →">
<TrayRow attention title="Quarterly report" detail="Approval pending for 6 days" trailing="Open →" />
<TrayRow attention title="Customer survey" detail="Missing 2 answers, due in 2 days" trailing="Open →" />
<TrayRow icon={<FileIcon />} title="Launch plan" detail="On track" trailing="Open →" />
</Tray>
</div>A row marked as needing attention gets an amber dot. Use it only when a person has to act.
When to use it
A soft panel that gathers the few things a person should look at now. The message box can sit underneath, so the list and the input share one edge.
Made of: Panel · Heading · Heading link · Rows · Footer (message box)
Use it for
- A short list of tasks that need a person, on a landing screen.
- A few suggested starting points with a message box under them.
- A small group of open items that all fit without scrolling.
Not for
- A long list that has to scroll.
- Past chats in the side panel: use ConversationList.
- Progress of a running task, with finished work folded away: use Checklist.
Do and avoid
Needs a look
Everything
Do
- Keep the list to a few rows so it can be read at a glance.
- Put the message box in the footer so it lines up with the list.
- Mark a row as needing attention only when a person has to act.
- Give the panel a heading so screen readers can name it.
Avoid
- Do not use it for long lists. Use a full list page instead.
- Do not add a border or a second panel inside it.
- Only put list rows inside it. Other content will not display correctly.
- Do not mark every row. When everything is amber, nothing stands out.
On a phone
- Fills the width of its container, and the rows inside it keep their size and have a tap area at least 44px tall on a touch screen.
- Each row stacks its title above its detail on a phone, and the detail wraps instead of being cut off.
- A row's trailing text, which shows only on hover on a desktop, is always visible on a touch screen.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | none | Small uppercase heading rendered with SectionLabel. Also becomes the aria-label of the section. |
| action | ReactNode | none | Right-aligned text beside the label, such as a count or a link. Only rendered when label is set. |
| childrenrequired | ReactNode | none | The rows. Rendered inside a ul, so pass li elements such as TrayRow. |
| footer | ReactNode | none | Rendered below the list, inside the sand surface. Intended for a Composer. |
| className | string | none | Extra classes merged onto the section, for width or spacing. |
"Show code under the preview gives the code for the example on the stage."
Tokens
Change one of these and every part that uses it follows.
--surface-sunken (bg-sunken)--shadow-sm--fg-muted--attention (via TrayRow)--radius-card
Built in
- With a label, screen readers can find the panel by that name.
- Rows sit in a real list, so screen readers say how many items there are.
- The label is plain text, so it does not add a level to the page outline.
What you need to do
- Give it a label unless a nearby heading already names the list.
- Put only list rows, such as TrayRow, inside it.
- Give each row that needs a person a detail that says what is needed, not just the amber dot.
Built toward WCAG 2.2 AA and checked automatically; no independent audit yet. Read the accessibility guide