Skip to main content

Item

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

In Dense data

See it live​

Start Storybook to see it live: npm run storybook

When to use it​

In Dense data: Short lists such as users or settings, each with a few actions. Not for records analysts compare; those go in a table.

  • 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 Dense data decided and why. Each sample is the live story with that variant set.

defaultvariantUsed in Dense data
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 Dense data

Users and settings in a panel or menu, with no border, quiet beside the data.

outlinevariantNot used in Dense data
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 Dense data

Borders on every row would compete with the data; hairlines between sections do that work.

mutedvariantUsed in Dense data
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 Dense data

The current user or setting, with a soft fill so people keep their place.

defaultsizeUsed in Dense data
Start Storybook to see it live

What it is for

Comfortable padding.

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

In Dense data

Settings and user lists outside the table, at the standard row.

smsizeUsed in Dense data
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 Dense data

Long lists in a side panel, at the denser size. It still fits a mouse.

Why it works this way​

Item looks the way it does because of 6 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 is the main content?content.q1
1The answer
Numbers and records

Most of the screen is numbers and records.

2So Item
  • ✓uses default: Users and settings in a panel or menu, with no border, quiet beside the data.
  • –does not use outline: Borders on every row would compete with the data; hairlines between sections do that work.
It also shapes Badge: neutral Badge: info Badge: success Badge: warning Badge: danger Sidebar: default Sidebar: outline Empty: default Toggle: default Toggle: outline
3If it changed
5
Item decisions would reopen

and 44 answers that follow from it: A lot, Scan and compare, People keep their place, and 41 more.

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

Thin lines guide the eye along rows.

2So Item
  • –does not use outline: Borders on every row would compete with the data; hairlines between sections do that work.
3If it changed
1
Item decision would reopen

and 3 answers that follow from it: Only what floats, One, Menus and dialogs.

What is the main task?tasks.q1
1The answer
Scan and compare

People scan rows and compare values.

2So Item
  • ✓uses muted: The current user or setting, with a soft fill so people keep their place.
It also shapes Field: vertical
3If it changed
4
Item decisions would reopen

and 20 answers that follow from it: People keep their place, Acting on the wrong record, Core and data, and 17 more.

What must the interface protect?human.q1
1The answer
People keep their place

Losing your place in a long table costs time and errors.

2So Item
  • ✓uses muted: The current user or setting, with a soft fill so people keep their place.
3If it changed
2
Item decisions would reopen

and 8 answers that follow from it: Lines, Feedback only, One, and 5 more.

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

A second, denser size serves tables and toolbars.

2So Item
  • ✓uses default: Settings and user lists outside the table, at the standard row.
  • ✓uses sm: Long lists in a side panel, at the denser size. It still fits a mouse.
It also shapes Field: horizontal Sidebar: sm
3If it changed
2
Item decisions would reopen

No other answer follows from it.

What is the smallest target?accessibility.values
1The answer
Compact, for a pointer

Mouse and keyboard; compact targets are enough.

2So Item
  • ✓uses sm: Long lists in a side panel, at the denser size. It still fits a mouse.
It also shapes Button: default Button: compact Toggle: sm
3If it changed
1
Item decision would reopen

No other answer follows from it.

Words​

  • Lead with the object, then the state: "Alert 2041 contained."
  • Use numbers, not words for numbers.
  • One verb per button. No "please", no exclamation marks.
  • Use: Investigate, Filter, Assign, Escalated, Resolved. Avoid: Oops, Awesome, Please, Simply.

The labels components use, from the voice tokens:

  • content.action.commit: Save
  • content.action.cancel: Cancel
  • content.action.destroy: Delete
  • content.action.retry: Retry
  • content.action.empty-action: Change filters

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

Dense data 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.2:0.125rem
Text sizecomponent.item.font-sizetype.body.font-sizevar(--item-font-size)font.size.14:0.875rem
Speedcomponent.item.durationmotion.duration.feedbackvar(--item-duration)duration.fast:120ms
Border focus
Changes with theme
on focus
component.item.border-focuscolor.border.focusvar(--item-border-focus)Lightviolet.light.600:#4B3FD9Darkviolet.dark.600:#A9A3F6
Background hover
Changes with theme
on hover
component.item.background-hovercolor.surface.sunkenvar(--item-background-hover)Lightslate.light.100:#EEF1F5Darkslate.dark.100:#262D38
Focus
on focus
component.item.focusborder-width.focusvar(--item-focus)border-width.2:2px
Focus ring focus
Changes with theme
on focus
component.item.focus-ring-focuscolor.border.focusvar(--item-focus-ring-focus)Lightviolet.light.600:#4B3FD9Darkviolet.dark.600:#A9A3F6
Focus ring offset focus
Changes with theme
on focus
component.item.focus-ring-offset-focuscolor.surface.canvasvar(--item-focus-ring-offset-focus)Lightslate.light.50:#F7F8FADarkslate.dark.0:#0D1117
Gapcomponent.item.gapspace.gap.defaultvar(--item-gap)space.8:0.5rem
Outline
Border
Changes with theme
component.item.outline.bordercolor.border.defaultvar(--item-outline-border)Lightslate.light.200:#DDE2EADarkslate.dark.100:#262D38
Muted
Fill
Changes with theme
component.item.muted.backgroundcolor.surface.sunkenvar(--item-muted-background)Lightslate.light.100:#EEF1F5Darkslate.dark.100:#262D38
Default
Gapcomponent.item.default.gapspace.gap.groupvar(--item-default-gap)space.16:1rem
Paddingcomponent.item.default.paddingspace.inset.containervar(--item-default-padding)space.16:1rem
Sm
Gapcomponent.item.sm.gapcomponent-spacing-map.x3var(--item-sm-gap)space.12:0.75rem
Padding, left and rightcomponent.item.sm.padding-xspace.inset.containervar(--item-sm-padding-x)space.16:1rem
Padding, top and bottomcomponent.item.sm.padding-ycomponent-spacing-map.x3var(--item-sm-padding-y)space.12:0.75rem
Icon
Sizecomponent.item.icon.sizesize.control.defaultvar(--item-icon-size)size.32:2rem
Cornercomponent.item.icon.radiusradius.badgevar(--item-icon-radius)radius.0:0rem
Fill
Changes with theme
component.item.icon.backgroundcolor.surface.sunkenvar(--item-icon-background)Lightslate.light.100:#EEF1F5Darkslate.dark.100:#262D38
Icon sizecomponent.item.icon.icon-sizesize.iconvar(--item-icon-icon-size)size.16:1rem
Image
Cornercomponent.item.image.radiusradius.badgevar(--item-image-radius)radius.0:0rem
Content
Gapcomponent.item.content.gapspace.gap.tightvar(--item-content-gap)space.4:0.25rem
Title
Gapcomponent.item.title.gapspace.gap.defaultvar(--item-title-gap)space.8:0.5rem
Text sizecomponent.item.title.font-sizetype.body.font-sizevar(--item-title-font-size)font.size.14:0.875rem
Weightcomponent.item.title.font-weighttype.label.font-weightvar(--item-title-font-weight)font.weight.500:500
Description
Text sizecomponent.item.description.font-sizetype.body.font-sizevar(--item-description-font-size)font.size.14:0.875rem
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)Lightslate.light.600:#535D6DDarkslate.dark.400:#969FAD
Label 2
Changes with theme
component.item.description.label-2color.action.primaryvar(--item-description-label-2)Lightviolet.light.600:#4B3FD9Darkviolet.dark.600:#A9A3F6
Actions
Gapcomponent.item.actions.gapspace.gap.defaultvar(--item-actions-gap)space.8:0.5rem
Header
Gapcomponent.item.header.gapspace.gap.defaultvar(--item-header-gap)space.8:0.5rem
Footer
Gapcomponent.item.footer.gapspace.gap.defaultvar(--item-footer-gap)space.8:0.5rem
From the system
Edge
Changes with theme
color.border.default
straight from the system, through --border
Lightslate.light.200 · #DDE2EADarkslate.dark.100 · #262D38