组件 · 收件箱
InboxItem
The row for something that happened elsewhere and that the person should see — a mention, an approval, a hand-off — with an attention dot while it is unread and its actions in the row.
import { InboxItem } from "@botiverse/raft-ui";An InboxItem is one thing that happened elsewhere and that the person should see: someone mentioned them, an agent waits for their approval, work was handed to them. An unread item has a bold title and a pink attention dot; an action it needs sits in the row. It is the row of ActivityInbox.
When to use
| Situation | Use |
|---|---|
| Something happened elsewhere that the person should see | InboxItem, in Activity (ActivityInbox) |
| The state of the whole server: a computer offline, a quota nearly full | A notification (NotificationCenter) |
| The result of an action the person took | Toast |
| Something to read before acting, in a dialog or form | Banner |
| A channel, a direct message or a member in a list | The sidebar row (Sidebar) |
Which message goes where is in Choosing a component.
Anatomy
InboxItem: the row. Required.InboxItemTrigger: an invisible button that covers the whole row and opens the item. Required.InboxItemSelection: a Checkbox for selecting several items. Optional.InboxItemLeading: a 36px leading visual before the text: the person's or agent's avatar, or a channel's IconTile. The divider starts after it. Optional.InboxItemLeadingBadge: the thread badge, in the bottom-right corner of the avatar or tile, holding one icon,ThreadIcon(Icons). Only on a thread row (The leading image). Optional; experimental, from@botiverse/raft-ui/wip.
InboxItemContent: the text column. Required.InboxItemContext: where it happened: a channel, a task, a computer.InboxItemHeadingwithInboxItemTitle: what happened, with an optional 14px icon before it.InboxItemSubtitle: a second line of context, such as "Thread in #launch-week".InboxItemBodyorInboxItemMessage: the excerpt, starting withInboxItemSender.InboxItemMetadata: chips for the task, replies and mentions.InboxItemHoverTarget: wraps a badge that has a tooltip, so the pointer reaches it (the rest of the text lets the pointer through to the trigger). A click on it still opens the item.
InboxItemTrailing:InboxItemTimestamp,InboxItemActionsand, while unread, the attention dot.InboxItemMarks: marks at the end of the excerpt's line: a mention, muted, an unread count. Optional.
The leading image
The leading image shows the conversation the item lives in. A thread is not a conversation of its own, so its row shows the conversation the thread lives in, with the thread badge in the corner:
| Row | Leading image | Second line |
|---|---|---|
| A channel | The channel's IconTile (hash) | The latest message: "Avery: …" |
| A direct message | The other person's or agent's avatar; an agent's with its presence light | The latest message |
| A thread in a channel | The channel's IconTile, with the thread badge | "#launch-week · Mira: …" |
| A thread in a direct message | The other person's or agent's avatar, with the thread badge and no presence light | "Lagoon: …", without "@Lagoon ·" |
- Show the conversation, not a channel shape. A
#tile on a thread in a direct message would say the thread lives in a channel. The avatar says who the conversation is with, and it is the face the person already knows from that direct message. - The badge is the same on a tile and on an avatar: the same size, in the same corner, so "this is a thread" reads the same in both columns of the list.
- On an avatar, the badge takes the presence light's corner. One corner holds one mark (Avatar). The row is about the thread, not about how the agent is doing now, so the badge wins and the thread row shows no presence light. The light stays on the direct message's own row.
- The second line doesn't repeat the leading image. In a direct message the avatar already names the other side, so "@Lagoon · Lagoon: …" says the name twice; the line starts with the latest message. A tile doesn't name its channel, so a channel thread keeps "#channel ·" before it.
- A screen reader still hears where the thread is. The row's trigger
aria-labelkeeps the conversation's name ("Thread in a direct message with Lagoon: …") even though "@Lagoon ·" is no longer on screen, so someone who doesn't see the avatar still knows which direct message the thread belongs to. - Until the direct message has loaded, lead with an
IconTileholdingDirectMessageIcon, never a#tile: the row must not claim a channel it isn't in, even for a moment. - The thread follows its conversation's settings. A thread in a muted direct message is muted too, the same as a thread in a muted channel.
Variants
| Variant | Use for |
|---|---|
| Default | Items to read: up to 2 lines each for the title and the excerpt, with metadata chips |
density="compact" | A conversation list: one line each for the title and the latest message, next to an InboxItemLeading |
In density="compact" the timestamp and InboxItemMarks sit in InboxItemTrailing, one beside each line. The unread count there says the row is unread, so data-unread only makes the title bold and there is no attention dot. Leave data-unread off a muted conversation and show a muted mark in place of its count.
States
| State | Look |
|---|---|
Unread (data-unread on InboxItem) | The title in foreground at weight 700, and a pink attention dot on the right |
| Read | The title in foreground-muted at weight 600; no dot |
active | The item open beside the list: an info-soft wash |
| Menu open | data-popup-open on InboxItem, or a menu open from a button in it: fill-subtle, the same subtle tier as the hover; an active item keeps info-soft (Hover and press) |
disabled | No hover, no press; the trigger can't be pressed |
Behavior
-
The trigger covers the whole row. Buttons in the row sit above it, and each one can be pressed on its own.
-
Divide items with
line-hairline, starting at the text, or afterInboxItemLeadingwhen there is one. -
With a mouse, show Mark as Done only while the row is hovered, holds focus, is
activeor has a menu open: giveInboxItemActionsreveal="hover". A list where every row shows its button reads as a wall of buttons, and the row itself is the main target. While the actions show they take the place of the rest ofInboxItemTrailing: the timestamp, the marks and the attention dot step aside. -
On a touch screen, show Mark as Done at rest and put it in the press-and-hold menu too; a swipe may add a shortcut but never replace it (Responsive layout).
reveal="hover"does this: the rest ofInboxItemTrailingmoves over to make room for it. -
In the default density
InboxItemTrailingtakes room only beside the first two lines ofInboxItemContent(the context line and the title, or the title and the excerpt); the lines after them run the full width, under it. The column is about two lines tall (the timestamp and the dot, or the 32px Mark as Done), so taking room beside every line would only make a phone's narrow rows wrap more and grow taller. Indensity="compact"it stays beside both lines. -
data-unreadturns on both the bold title and the attention dot. In the default density the dot is how an unread item reads; keep it. Indensity="compact"the unread count inInboxItemMarkstakes its place, so the dot is off. -
The text lets the pointer through to the trigger, so a badge there gets no hover. Wrap a badge that has a tooltip in
InboxItemHoverTarget. -
On a touch screen (
pointer: coarse, at any width) each action inInboxItemActionskeeps a 44px target and the actions spread 12px apart so their targets don't overlap; with a mouse they stay 32px, 2px apart.
Content
- Write the context line as where it happened: #launch-week · task #25.
- Write the title as who did what, with a teammate verb: "Martin needs your OK", "Bugen handed off #25" (Writing).
- Keep the excerpt to at most 2 lines.
- On a thread row, start the second line with the channel only when the leading image is a channel's tile: "#launch-week · Mira: …". In a direct message, start it with the latest message: "Lagoon: …" (The leading image).
Accessibility
- The parts render native elements through Base UI's
useRender.InboxItemTriggeris a nativebutton; withdisabledit getsaria-disabledand ignores clicks. - Give the trigger an accessible name that names the item:
aria-label="Open Martin needs your OK". Setaria-currenton the trigger of the open item. - Name the selection checkbox and every icon-only action:
aria-label="Select activity item",aria-label="Mark as done". - Actions with
reveal="hover"stay in the tab order while hidden, and show as soon as focus reaches the row or them. - The attention dot is drawn in CSS and isn't announced. Say "unread" in the trigger's name, or add a visually hidden word.
InboxItemLeadingBadgeis hidden from assistive technology. Say "thread" in the trigger's name:aria-label="Open thread with Lagoon".
Rules
- Use ink-outline small buttons for actions in the row, never pink: a list can hold several items that wait for the person at once (Button).
- Lead with who, when there is a who: the person's or agent's avatar. A notice from the system has no who; see NotificationCenter.
- Lead a thread row with the conversation it lives in: the channel's tile, or in a direct message the other side's avatar, each with the thread badge in its corner. Never give a thread in a direct message a
#tile, and never show a presence light on a thread row (The leading image).
API
InboxItem
| Prop | 类型 | 默认值 |
|---|---|---|
| boolean | false | |
| "compact" | ||
| boolean | false | |
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) |
Also takes the attributes of its element.
InboxItemActions
| Prop | 类型 | 默认值 |
|---|---|---|
| `hover`: with a mouse, the actions stay hidden until the row is hovered, holds focus, is `active` or has a menu open, and then take the place of the rest of `InboxItemTrailing` (the timestamp, the marks, the attention dot), which steps aside. On a touch screen (`pointer: coarse`) they show at rest and the rest of the trailing column moves over to make room. | "hover" | |
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) |
Also takes the attributes of its element.
InboxItemBody, InboxItemContent, InboxItemContext, InboxItemHeading, InboxItemHoverTarget, InboxItemLeading, InboxItemMarks, InboxItemMessage, InboxItemMetadata, InboxItemSelection, InboxItemSender, InboxItemSubtitle, InboxItemTimestamp, InboxItemTitle, InboxItemTrailing, InboxItemTrigger, InboxItemLeadingBadge
| Prop | 类型 | 默认值 |
|---|---|---|
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) |
Also takes the attributes of its element.
相关组件
改动
- 0.9.5 · FixedOn a touch screen, a tap no longer leaves a hover highlight on:
TableBodyrows, anInboxItem's pressed toggle action, the Activity inbox sort button and aFileRow(when itsFileRowOpenis hovered) now only show their hover on devices that can hover. With a mouse they look and behave as before. - 0.9.2 · FixedOn an
InboxItemcard row,InboxItemTrailing(the timestamp, and on a touch screen the room forreveal="hover"actions) takes width only beside the first two content lines; the body, message and chips below run the full width. Before, every line was narrowed, so phone cards wrapped more and grew taller. Compact rows and rows without a trailing column are unchanged. - 0.9.1 · Added
InboxItemActions reveal="hover": with a mouse, the actions stay hidden (still reachable by Tab) until the row is hovered, focused, active or has a menu open, and the timestamp, marks and dot step aside while they show. On a touch screen they show at rest and the trailing column makes room. - 0.9.1 · Added
InboxItemLeading: a 36px leading visual (an avatar or channel tile); the divider starts after it. - 0.9.1 · Added
InboxItem density="compact": a one-line title and excerpt for a conversation list, with the timestamp beside the title andInboxItemMarks(mention, muted, unread count, draft) beside the excerpt. In a compact rowdata-unreadbolds the title without the pink dot. - 0.9.1 · Added
InboxItemHoverTarget: lets a badge inside the row take the pointer so its tooltip opens; a click on it still opens the row. - 0.8.2 · FixedOn a touch screen (
pointer: coarse, at any width), each action inInboxItemActionskeeps a 44px target and the actions sit 12px apart, so their targets don't overlap. With a mouse they stay 32px. - 0.5.0 · AddedGraduated the composable
ActivityInboxshell, sidebar, selection toolbar, and standaloneInboxItemparts to the stable package entry point.