Orbex Sonar-DB Design system , home

Examples

Deliveries in size S: the day’s list scrolls

Deliveries

Tuesday, May 12

  • 04-118B 2 items · 40 pltDelivered
  • 04-121A 7 items · 150 pltDelayed
  • 04-127C 1 item · 15 pltDelayed
  • 04-130A 8 items · 210 pltDelivered
Code
tsx
import { Card, CardLink, CardScroll } from '@orbex/sonar-components/card'
import { Status } from '@orbex/sonar-components/status'

const deliveries = [
  { id: '04-118B', items: 2, pallets: 40, status: 'Delivered', tone: 'positive' },
  { id: '04-121A', items: 7, pallets: 150, status: 'Delayed', tone: 'warning' },
  { id: '04-127C', items: 1, pallets: 15, status: 'Delayed', tone: 'warning' },
  { id: '04-130A', items: 8, pallets: 210, status: 'Delivered', tone: 'positive' },
] as const

/* Size S leaves no room for the whole day: the list scrolls between the heading and the footer, which stay put */
export default function Scroll() {
  return (
    <Card titleAs="h3" title="Deliveries" size="s" footer={<CardLink href="/patterns/overview/#card-deliveries">Go to Deliveries</CardLink>}>
      <p style={{ margin: '0 0 8px', font: 'var(--sonar-type-label-md)' }}>Tuesday, May 12</p>
      <CardScroll label="Deliveries of May 12">
        <ul role="list" style={{ padding: 0 }}>
          {deliveries.map(({ id, items, pallets, status, tone }) => (
            <li key={id} style={{ display: 'flex', justifyContent: 'space-between', gap: 12, padding: '10px 0', borderBottom: '1px solid var(--sonar-color-divider)' }}>
              <span>
                {`${id} ${items} ${items === 1 ? 'item' : 'items'} · ${pallets} plt`}
              </span>
              <Status tone={tone}>{status}</Status>
            </li>
          ))}
        </ul>
      </CardScroll>
    </Card>
  )
}

Usage

  • Wrap the list that can give way: the deliveries of a day, the products to reorder. Never the summary or a chart.
  • One per card. If it is not enough, the card’s whole content scrolls as well.
  • No scrollbar: a fade at the edge that has more, and a thin indicator while scrolling.
  • Label it with what the list is: “Deliveries of May 12”.

Do and don’t

DoMark the list that should give way first; the summary and the footer stay in place.
Don’tContent cut at the card’s edge, with nothing to say there is more.
DoA label that names the list, read when it takes focus: “Deliveries of May 12”.
Don’tA generic label: “List”, “Scroll area”. Focus arrives and says nothing useful.

Accessibility

Keyboard

Key What it does
Tab Reaches the list only while it scrolls; when everything fits, focus goes straight to its controls.
Up and Down arrows, Page Up and Page Down Scroll the list once it has focus.

Roles and attributes

Element or attribute What it gives
role="group" while scrolling Named by label (“Deliveries of May 12”), so focus arriving on it says what it is.
Fade and indicator Drawn, aria-hidden; the list’s own scroll position is what assistive technology reads.

Notes

  • It takes focus only while it scrolls, so a list that fits adds no tab stop.

Use it

Card scroll shares its entry point and stylesheet with Card, Card link, Unit menu. The tokens and the cascade layers are set once for the app: see Installation.

tsx
import { CardScroll } from '@orbex/sonar-components/card'
import '@orbex/sonar-components/card.css'

API

Props of CardScroll
Prop Type Default
label Required

What the list is, read when it takes focus to scroll: “Deliveries of May 12”.

string —

Also takes every attribute of the native <div> , and a ref to it.