Raft 设计系统

组件 · 数据展示

ListRow

The row for the people and agents on a detail page, settings and shortcuts — a leading block, a title and a preview, the time and a badge.

稳定也叫 AvatarListRow
import { ListRow } from "@botiverse/raft-ui";
本页尚未翻译
译文完成之前,这里显示英文原文。 阅读英文版

A ListRow is one row of a list: a person, an agent, a setting or a shortcut into another page. The whole row is the target. Use it for the agents and people on a detail or profile page, and for settings. Raft Chat's phone lists of places (Home, Members, the Settings list) use the sidebar row instead (Choosing a component).

list-row/compositions/conversations

When to use

SituationUse
Channels, direct messages and members in a phone listThe sidebar row (Sidebar), as in Raft Chat
Channels and people among search resultsListRow, through the search result row (Search)
Agents and people on a profile or detail page, such as a computer's detailsListRow in a ListRowGroup (Identity and presence)
A row of the desktop sidebarThe sidebar row (Sidebar)
Activity and notificationsInboxItem
A taskTaskCard

Anatomy

  • ListRow: the row. A button by default; render a link for a row that goes somewhere.
  • Leading block: an Avatar, a channel tile (IconTile) or a 20px ListRowIcon. Optional.
  • ListRowBody: the text column. Required.
    • ListRowTop: ListRowTitle, then the time in ListRowMeta.
    • ListRowBottom: the preview in ListRowDescription, then at most one badge.
  • Trailing: a setting's ListRowValue and ListRowChevron, or a Switch. Optional.
  • ListRowGroup: an inset group that wraps rows in a card. Optional.

In a plain row with a description, both ends center on the title's first line instead of the middle of the title and description: the leading icon, avatar or tile, and the trailing value, chevron, switch, checkbox or radio. Each keeps its size, so the row still accounts for a 30px switch. With a title alone, the title is the whole block and everything stays centered at the row's height, 54px on a phone with a switch (Alignment).

Variants

VariantUse for
variant="default"A conversation, a person or an agent: leading block, title, preview, time and badge. At least 64px tall
variant="plain"A setting: an optional icon, a title (and its consequence), then the current value and a chevron, or a switch. 48px tall with one line of text
variant="entry"A shortcut into another page at the top of a list (Saved on phone Home): a 20px icon and a name, with a badge or a gray count on the right. 48px tall
list-row/compositions/settings
list-row/compositions/entries

States

tone says what the place is to the person. The shared states are in States.

StateUse for
tone="unread"Something waits here: bold title, the preview in foreground, and a pink count in ListRowBottom. When someone mentions the person, the yellow @ marker replaces the count (Badge)
tone="muted"The person muted it: the title in foreground-muted. Add a bell-off icon after the title, and show unread as a gray count in ListRowMeta instead of a pink badge
tone="away"The person hasn't joined yet: title and preview in foreground-hint
selectedThe item open beside the list: an info-soft wash, and no hover
disabledEvery part in foreground-disabled; no tone, no unread or muted marks, no hover or press, and the fill doesn't change
list-row/compositions/tones

Behavior

  • Divide rows with line-hairline. In the default variant the line starts where the text starts; in a settings list it starts at the row's edge (16px); entry rows have no lines between them, because they are a set of buttons, not a list of content.
  • The whole row is the target: hover lays the subtle tier, fill-subtle, over all of it and press the medium tier (Hover and press). While a menu it opened is up (data-popup-open: a context menu, or press and hold on a phone), it lays fill-subtle too, hovered or not; a selected row keeps its selection.
  • A row whose only targets are its own controls (a setting with a switch) takes interactive={false}: it renders a plain element with no hover or press. See States.

Content

  • Start a preview with who spoke: "Wug: Release notes are drafted."
  • Show at most one badge in a row.
  • Set the time and counts in Space Mono; ListRowMeta does this.
  • Write a setting's consequence in ListRowDescription with wrap, so it isn't cut off.

Group headings

A group of rows can have a heading above it, such as Channels.

  • Write it in sentence case, in text-footnote at weight 700 and foreground-hint (Typography).
  • Make the heading a button with aria-expanded when the group can collapse, and show the number of rows when it is collapsed.
  • Put the group's action on the right as an ink text button that underlines on hover (TextLink): Browse.

raft-ui has no exported heading part for these lists yet.

Accessibility

  • ListRow uses Base UI's useRender and renders a native button (or the link you pass with render), so the row is reached with Tab and activated with Enter or Space. With interactive={false} it is a div and only its controls are focusable.
  • The accessible name is the row's text. Add an accessible name to a badge that is only a number or an icon: aria-label="3 unread", aria-label="Mentions you".
  • selected is visual only. Set aria-current or aria-selected on the row yourself.
  • Label a switch in a settings row with the row's title (aria-labelledby).
  • ListRowIcon and ListRowChevron are hidden from assistive technology.

Rules

  • Don't add an ink border or a shadow to a row or a group: a list is content, and an ink border means a control (Color).

API

ListRow

One row of a list. It renders a `button` by default; pass `render={<a />}` (or a router link) for a row that goes somewhere. Children are the leading block (an avatar, a channel or icon tile, `ListRowIcon`), `ListRowBody`, and anything trailing (a value, a badge, a switch, `ListRowChevron`).
Prop类型默认值
interactive`false` renders a display-only row: a `div` with no hover or press, for a row whose controls (a switch, a button) are its only targets.booleantrue
selectedThe item open beside the list: the row takes the cyan wash and stops reacting to hover. Say why it is selected with `aria-current` or `aria-selected` yourself.booleanfalse
toneSomething waits for you here (bold title, ink preview), the place is muted (ink-2 title), or you are not in it yet (ink-3 title and preview). A disabled row ignores it: everything is ink-disabled.RowTone"default"
variant"default" | "plain" | "entry""default"
renderAllows 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.

ListRowBody, ListRowBottom, ListRowChevron

The text column: the title and the preview, or a `ListRowTop` and a `ListRowBottom`.
Prop类型默认值
renderAllows 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.

ListRowDescription

The preview (who spoke first: "Wug: …") or a setting's consequence, 14/20 ink-2.
Prop类型默认值
wrapLet the text run onto more lines instead of truncating: a setting's consequence.booleanfalse
renderAllows 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.

ListRowGroup, ListRowIcon, ListRowMeta, ListRowTitle, ListRowTop, ListRowValue

An inset group: rows wrapped in a card (surface, hairline, radius-lg).
Prop类型默认值
renderAllows 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.6.1 · AddedListRow, the Design System list row (rf-row): ListRowGroup (the inset card), ListRowIcon, ListRowBody / ListRowTop / ListRowBottom, ListRowTitle, ListRowDescription, ListRowMeta, ListRowValue, ListRowChevron. Variants default (64, hairline from the text), plain (setting row, 48) and entry (48, no hairlines); tone (unread / muted / away), selected (cyan-soft), disabled, and interactive={false} for a display-only row.