Skip to main content

Item

A row with media, a title, a description and actions.

In Accessible first

See it live​

Start Storybook to see it live: npm run storybook

When to use it​

In Accessible first: A list such as saved applications, each with worded secondary buttons. Not records compared cell by cell.

  • Use it when: Lists of things such as people, files or settings, each with a few actions.
  • Not when: Records people compare cell by cell (a table).

Instead:

  • Card: A larger unit with more content.
  • Table: Records compared across columns.

Variants​

What each variant is for in any design system, then what Accessible first decided and why. Each sample is the live story with that variant set.

defaultvariantNot used in Accessible first
Start Storybook to see it live

What it is for

No border and no fill: the row sits on the surface around it.

✓Lists inside a card, panel or menu that already has a frame.
✕Rows that stand alone on the page and need edges.

In Accessible first

A row with no border is hard to see at high zoom; borders do the work.

outlinevariantUsed in Accessible first
Start Storybook to see it live

What it is for

A border around each row.

✓Rows that stand alone on the page, such as a list of settings.
✕Long lists inside a framed panel, where borders add noise.

In Accessible first

Each saved application, with a strong border that separates it at any zoom.

mutedvariantNot used in Accessible first
Start Storybook to see it live

What it is for

A soft fill behind the row.

✓A row that should stand out quietly, such as the current one.
✕Every row in a long list.

In Accessible first

A fill alone marks a row by color; status goes in a badge with an icon and a word.

defaultsizeUsed in Accessible first
Start Storybook to see it live

What it is for

Comfortable padding.

✓Most lists.
✕Dense panels with many short rows.

In Accessible first

Every row. Large targets help people with motor needs.

smsizeNot used in Accessible first
Start Storybook to see it live

What it is for

Tighter padding.

✓Dense panels and short rows.
✕Touch screens and lists people read slowly.

In Accessible first

Large targets help people with motor needs; nothing smaller.

Why it works this way​

Item looks the way it does because of 5 answers about this product. Each card is one answer, in three steps: the answer, what it decided for Item, and what would move if it changed.

What separates groups on the page?elevation.definition
1The answer
Lines

Strong borders separate groups at any zoom.

2So Item
  • –does not use default: A row with no border is hard to see at high zoom; borders do the work.
  • ✓uses outline: Each saved application, with a strong border that separates it at any zoom.
It also shapes Toggle: default Toggle: outline
3If it changed
2
Item decisions would reopen

No other answer follows from it.

How soft are shadows?elevation.values
1The answer
No shadows

No shadows; borders do the work.

2So Item
  • –does not use default: A row with no border is hard to see at high zoom; borders do the work.
  • ✓uses outline: Each saved application, with a strong border that separates it at any zoom.
3If it changed
2
Item decisions would reopen

No other answer follows from it.

How many signals carry each meaning?accessibility.count
1The answer
Three: color, icon and word

Never color alone.

2So Item
  • –does not use muted: A fill alone marks a row by color; status goes in a badge with an icon and a word.
It also shapes Alert: destructive Badge: neutral Badge: success Badge: warning Badge: danger
3If it changed
1
Item decision would reopen

and 1 answer that follow from it: Status and messages.

What is the smallest target?accessibility.values
1The answer
Large

Large targets for tremor and touch.

2So Item
  • ✓uses default: Every row. Large targets help people with motor needs.
  • –does not use sm: Large targets help people with motor needs; nothing smaller.
It also shapes Button: default Button: compact Button: large Toggle: default Toggle: sm Toggle: lg
3If it changed
2
Item decisions would reopen

No other answer follows from it.

How many densities exist?spacing.count
1The answer
One

One density; no compact mode to fail people.

2So Item
  • –does not use sm: Large targets help people with motor needs; nothing smaller.
3If it changed
1
Item decision would reopen

No other answer follows from it.

Words​

  • Use common words. Explain any term you must use.
  • One idea per sentence. Put the action first.
  • Never blame the person.
  • Use: Continue, Change, Start, You. Avoid: Invalid, Utilise, Submit, Error code.

The labels components use, from the voice tokens:

  • content.action.commit: Continue
  • content.action.cancel: Go back
  • content.action.destroy: Delete
  • content.action.retry: Try again
  • content.action.empty-action: Start a new application

See Voice and tone for the whole voice.

Use it in code​

npx open-ds add item

The component reads only component keys and semantic tokens, so it follows the brand and mode on <html>.

Tokens it reads​

Item reads 32 tokens of its own, each an alias of a semantic token. Each row is one part: its own token, the semantic it aliases, and the value it ends at. Change a semantic and every component that reads it follows; override one of Item's tokens to change Item alone.

Changes with theme

Accessible first decides what changes when you switch theme. Here a switch changes colors only, so the marked rows differ between light and dark; everything else holds steady.

PartIts token and the semantic it aliasesValue
Item
Cornercomponent.item.radiusradius.controlvar(--item-radius)radius.6:0.375rem
Text sizecomponent.item.font-sizetype.body.font-sizevar(--item-font-size)font.size.19:1.1875rem
Speedcomponent.item.durationmotion.duration.feedbackvar(--item-duration)duration.moderate:200ms
Border focus
Changes with theme
on focus
component.item.border-focuscolor.border.focusvar(--item-border-focus)Lightblue.light.600:#0B4FC0Darkblue.dark.600:#8AB4F8
Background hover
Changes with theme
on hover
component.item.background-hovercolor.surface.sunkenvar(--item-background-hover)Lightgray.light.100:#EDEDEDDarkgray.dark.100:#222222
Focus
on focus
component.item.focusborder-width.focusvar(--item-focus)border-width.3:3px
Focus ring focus
Changes with theme
on focus
component.item.focus-ring-focuscolor.border.focusvar(--item-focus-ring-focus)Lightblue.light.600:#0B4FC0Darkblue.dark.600:#8AB4F8
Focus ring offset focus
Changes with theme
on focus
component.item.focus-ring-offset-focuscolor.surface.canvasvar(--item-focus-ring-offset-focus)Lightgray.light.50:#F7F7F7Darkgray.dark.0:#0A0A0A
Gapcomponent.item.gapspace.gap.defaultvar(--item-gap)space.16:1rem
Outline
Border
Changes with theme
component.item.outline.bordercolor.border.defaultvar(--item-outline-border)Lightgray.light.200:#D6D6D6Darkgray.dark.100:#222222
Muted
Fill
Changes with theme
component.item.muted.backgroundcolor.surface.sunkenvar(--item-muted-background)Lightgray.light.100:#EDEDEDDarkgray.dark.100:#222222
Default
Gapcomponent.item.default.gapspace.gap.groupvar(--item-default-gap)space.32:2rem
Paddingcomponent.item.default.paddingspace.inset.containervar(--item-default-padding)space.24:1.5rem
Sm
Gapcomponent.item.sm.gapcomponent-spacing-map.x3var(--item-sm-gap)space.20:1.25rem
Padding, left and rightcomponent.item.sm.padding-xspace.inset.containervar(--item-sm-padding-x)space.24:1.5rem
Padding, top and bottomcomponent.item.sm.padding-ycomponent-spacing-map.x3var(--item-sm-padding-y)space.20:1.25rem
Icon
Sizecomponent.item.icon.sizesize.control.defaultvar(--item-icon-size)size.52:3.25rem
Cornercomponent.item.icon.radiusradius.badgevar(--item-icon-radius)radius.4:0.25rem
Fill
Changes with theme
component.item.icon.backgroundcolor.surface.sunkenvar(--item-icon-background)Lightgray.light.100:#EDEDEDDarkgray.dark.100:#222222
Icon sizecomponent.item.icon.icon-sizesize.iconvar(--item-icon-icon-size)size.20:1.25rem
Image
Cornercomponent.item.image.radiusradius.badgevar(--item-image-radius)radius.4:0.25rem
Content
Gapcomponent.item.content.gapspace.gap.tightvar(--item-content-gap)space.12:0.75rem
Title
Gapcomponent.item.title.gapspace.gap.defaultvar(--item-title-gap)space.16:1rem
Text sizecomponent.item.title.font-sizetype.body.font-sizevar(--item-title-font-size)font.size.19:1.1875rem
Weightcomponent.item.title.font-weighttype.label.font-weightvar(--item-title-font-weight)font.weight.700:700
Description
Text sizecomponent.item.description.font-sizetype.body.font-sizevar(--item-description-font-size)font.size.19:1.1875rem
Weightcomponent.item.description.font-weighttype.body.font-weightvar(--item-description-font-weight)font.weight.400:400
Text
Changes with theme
component.item.description.labelcolor.text.mutedvar(--item-description-label)Lightgray.light.500:#595959Darkgray.dark.500:#949494
Label 2
Changes with theme
component.item.description.label-2color.action.primaryvar(--item-description-label-2)Lightblue.light.600:#0B4FC0Darkblue.dark.600:#8AB4F8
Actions
Gapcomponent.item.actions.gapspace.gap.defaultvar(--item-actions-gap)space.16:1rem
Header
Gapcomponent.item.header.gapspace.gap.defaultvar(--item-header-gap)space.16:1rem
Footer
Gapcomponent.item.footer.gapspace.gap.defaultvar(--item-footer-gap)space.16:1rem
From the system
Edge
Changes with theme
color.border.default
straight from the system, through --border
Lightgray.light.200 · #D6D6D6Darkgray.dark.100 · #222222