Sakuga Back to Sakuga
Theme
Sound
Jump to a component

Core · Content

ListRow

ListRow is one row of a List: a title and a quiet line under it, with an optional icon or image before it, a meta column (a timecode) and whatever sits at the end (a switch, a button, a check). selected marks the current row the way every list and nav does: its title in ink weight with the small state-dot beside it, no fill and no edge; href makes it a link; loose gives it more room (settings lists).

@anicanon/sakuga/uiv1.0Used onWeb · iOS · Android

Live, from @anicanon/sakuga 2.0.0

Sakuga for iOS and Android is coming

iOS

Coming soon

ListRow for iOS is in the roughs. The tokens it will read are the ones on this page, the same on every platform.

Android

Coming soon

ListRow for Android is in the roughs. The tokens it will read are the ones on this page, the same on every platform.

Use it for
One thing on one row of a List: a title and a quiet line, with what sits at the end (a switch, a button, a check); loose in settings lists.
Not for
  • A quiet action inside a line of textTextLink
  • A row on Story with a picture, a state and the work that told itEntityRow
  • Each kind of setting with its value, opening the full choicePropertyList
  • Measured facts, a name and its valueFactList
  • A cut on an ekonte sheetCutRow

Guidelines

  • A linked row sinks on press and its picture leans in on hover; rows never take a hover fill. onClick is for client-side navigation.
  • With sound on, a press on a linked row plays the press sound (README · Sound).
  • One row, one thing. A row never holds two actions of the same weight.
  • List wraps rows and names the list (label).
  • attention reads the quiet line in the text colour after the same state-dot: a take that waits for you, as MediaCard marks a production.
  • lightMap gives the image light on art, as on Thumb: its own highlights glow under the pointer, and at the centre when a linked row has keyboard focus. Never on muted.
  • slot="lead" replaces the icon or image (a play button); slot="main" replaces the title and quiet line (a sound's waveform and its length).
  • checked and onCheck give the row a Checkbox for bulk selection, named "Select" and the row's title; a checked row's title takes the ink weight. On a linked row the box sits beside the link, so the box chooses and the row still opens. It is not selected: that marks the current row.
  • chevron adds a trailing chevron when the row opens a page. List with surface sets the rows in a surface, as a phone groups them.
ListRowExample.jsxReact
import { Button, List, ListRow, Switch } from '@anicanon/sakuga/ui';

function stay(e) {
  e.preventDefault();
}

export default function ListRowExample() {
  return (
    <List label="Tracks">
      <ListRow
        icon="video"
        title="Takes’ own sound"
        sub="Voices and sound from each take"
      >
        <Switch on label="Takes’ own sound" />
      </ListRow>
      <ListRow icon="volume" title="Cue 2 · wind" sub="Music" selected>
        <Switch on label="Cue 2" />
      </ListRow>
      <ListRow
        image="/art/eba-cinema.webp"
        lightMap="/art/eba-cinema.light.webp"
        imageWidth={56}
        imageHeight={32}
        title="2C · take 3"
        sub="No lines yet"
      >
        <Button variant="secondary" size="sm">
          Caption
        </Button>
      </ListRow>
      <ListRow
        image="/art/eba-s1e1.webp"
        lightMap="/art/eba-s1e1.light.webp"
        imageWidth={56}
        imageHeight={32}
        title="2A · take 1"
        sub="Opens in Cut"
        href="#"
        onClick={stay}
      />
      <ListRow
        meta="2:23 + 00f"
        title="Just once more."
        sub="Lisa · 2A"
        href="#"
        onClick={stay}
      />
    </List>
  );
}

PropsListRowProps

titlerequired
ReactNode
sub
ReactNode
icon
IconName
image
string
imageStyle
string
imageWidth
number
imageHeight
number
lightMap
string
The image's baked light map, passed to its Thumb (light on art); a linked row under keyboard focus lights it at the centre.
light
boolean
muted
boolean
meta
string
A leading column, e.g. a timecode.
selected
boolean
attention
boolean
The quiet line waits for you: text colour with the accent dot. Slots: slot="lead" (in place of icon or image), slot="main" (in place of title and sub).
loose
boolean
checked
boolean
Bulk selection: a Checkbox named "Select" and the title, beside the link on a linked row. Not selected, which marks the current row.
onCheck
(checked: boolean) => void
Called with the box's new value.
label
string
Names the row's box ("Select …") when the title is markup; a text title names it by default.
chevron
boolean
A trailing chevron: the row opens something.
href
string
onClick
MouseEventHandler
With href, for client-side navigation.
children
ReactNode
What sits at the end: a switch, a button.
className
string

An IconName is any of the names Icon lists.

ListRowExample.swiftiOS · coming soon
ListRowExample.ktAndroid · coming soon

Each token reads a role, and the role lands on a value in each theme. Change the role and every component that reads it follows.

Colour

listrow-attentionListRow: a line that waits for you.
text-primaryneutral-925#0b0a10
text-primaryneutral-0#ffffff

Space and shape

list-row-icon-size
icon-size-sm
16px
list-row-chevron-icon-size
icon-size-sm
16px
list-row-gap
gap-md
8px
list-row-padding-y
inset-sm
8px
list-row-edge-bottom-width
its own value
1px
list-row-active-scale
scale-press-lg
.98
list-row-thumb-img-hover-scale
scale-zoom
1.04
list-row-loose-gap
gap-lg
12px
list-row-loose-padding-y
inset-md
12px
list-row-meta-width
its own value
64px
list-row-words-gap
gap-2xs
2px
list-row-end-gap
gap-sm
6px
list-row-main-gap
gap-md
8px
list-row-words-small-attention-gap
gap-sm
6px

Type

list-row-font
text-caption
500 13px/18px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
list-row-meta-font
text-small
500 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
list-row-words-b-font-weight
weight-strong
600
list-row-words-small-font
text-small
500 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
list-row-words-b-loose-font
text-label
600 14px/20px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
list-row-words-small-loose-font
text-caption
500 13px/18px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
list-row-words-small-attention-font-weight
weight-strong
600
list-row-words-b-selected-font-weight
weight-bold
700

Motion

list-row-duration
motion-fast
160ms
list-row-easing
ease-standard
cubic-bezier(0.2, 0, 0, 1)
list-row-active-duration
motion-instant
100ms
list-row-icon-duration
motion-fast
160ms
list-row-icon-easing
ease-standard
cubic-bezier(0.2, 0, 0, 1)
list-row-thumb-light-focus-duration
motion-slower
560ms
list-row-thumb-light-focus-easing
ease-standard
cubic-bezier(0.2, 0, 0, 1)

Checked automatically with axe-core 4.11.4 against WCAG 2.2 A and AA, on the live preview above, in light and dark, on 26 October 2026.

Result
No issues found, in light or in dark.
By design
Inside List (a list named by its label) each row is a list item read as its title, quiet line, meta and what sits at the end, marked "current" when selected and "waiting for you" with attention; with checked or onCheck its box comes first, a checkbox named "Select" and the title (label names it when the title is markup); pictures, icons and the chevron are hidden. With href the row is a link, with only onClick a link-role row, and either way Tab reaches it and Enter follows it.
Not tested
The automated check doesn't test keyboard use, focus order or what a screen reader says. The lines above are the design system's own account of them.