Skip to content
Navigation

Navigation

Every component, with its variants, sizes and states. Change the appearance here and every sample follows.

Tabs

Parts of one screen. The tab is in the URL, and the arrow keys move along the row.

Used in the demo at /settings

States

Selected
Focus
<!-- Links: the tab is in the URL. shared/ui/tabs.mjs moves between them. -->
<div class="or-tabs" role="tablist" aria-label="Settings">
  <a class="or-tabs__tab" role="tab" href="settings.html?tab=general" aria-selected="true" tabindex="0">General</a>
  <a class="or-tabs__tab" role="tab" href="settings.html?tab=billing" aria-selected="false" tabindex="-1">Billing</a>
</div>
<div className="or-tabs" role="tablist" aria-label={t('settings.title')} onKeyDown={onKeyDown}>
  {SETTINGS_TABS.map((name) => (
    <Link key={name} className="or-tabs__tab" role="tab" to={`?tab=${name}`}
      aria-selected={name === tab} tabIndex={name === tab ? 0 : -1}>
      {t(`settings.tabs.${name}`)}
    </Link>
  ))}
</div>
<div class="or-tabs" role="tablist" :aria-label="t('settings.title')" @keydown="onKeyDown">
  <RouterLink v-for="name in SETTINGS_TABS" :key="name" class="or-tabs__tab" role="tab"
    :to="{ query: { tab: name } }" :aria-selected="name === tab" :tabindex="name === tab ? 0 : -1">
    {{ t(`settings.tabs.${name}`) }}
  </RouterLink>
</div>
<div className="or-tabs" role="tablist" aria-label={t('settings.title')} onKeyDown={onKeyDown}>
  {SETTINGS_TABS.map((name) => (
    <Link key={name} className="or-tabs__tab" role="tab" href={`/settings?tab=${name}`}
      aria-selected={name === tab} tabIndex={name === tab ? 0 : -1}>
      {t(`settings.tabs.${name}`)}
    </Link>
  ))}
</div>
<div class="or-tabs" role="tablist" :aria-label="t('settings.title')" @keydown="onKeyDown">
  <NuxtLink v-for="name in SETTINGS_TABS" :key="name" class="or-tabs__tab" role="tab"
    :to="{ path: localePath('/settings'), query: { tab: name } }" :aria-selected="name === tab" :tabindex="name === tab ? 0 : -1">
    {{ t(`settings.tabs.${name}`) }}
  </NuxtLink>
</div>

Pagination

Where the reader is in a long list, and the rows per page.

Used in the demo at /orders

States

Showing 1–25 of 287
First page
Showing 126–150 of 287
A middle page
Showing 276–287 of 287
Last page
<!-- Rendered by page-orders.js from shared/ui/table.mjs pageWindow(). -->
<div class="or-pager" data-or-pager></div>
<Pager page={orders.data} onPage={(page) => table.patch({ page })} onPerPage={(perPage) => table.patch({ perPage })} />
<Pager :page="orders.data.value" @page="(page) => table.patch({ page })" @per-page="(perPage) => table.patch({ perPage })" />
{/* Links rather than buttons: every page is a URL the server renders. */}
<Link className="or-pager__page" href={hrefFor(path, query, { page: page + 1 }, keep)} aria-label={t('table.nextPage')}>
  <Icon name="chevron-right" size={16} />
</Link>
<TablePager :page="orders.data.value" @page="(page) => table.patch({ page })" @per-page="(perPage) => table.patch({ perPage })" />

Bulk action bar

Appears with the first selected row, in the flow rather than over the table.

Used in the demo at /orders

Variants

3 selected
With a selection
<div class="or-bulkbar" role="region" aria-live="polite" aria-label="3 selected">
  <span class="or-bulkbar__count">3 selected</span>
  <button type="button" class="or-btn or-btn--sm">Mark as shipped</button>
</div>
<BulkBar count={selection.selected.size} onClear={selection.clear}>
  <button type="button" className="or-btn or-btn--sm" onClick={() => bulk.mutate({ status: 'shipped', fulfilment: 'fulfilled' })}>{t('orders.bulkMarkShipped')}</button>
</BulkBar>
<BulkBar :count="selection.selected.value.size" @clear="selection.clear">
  <button type="button" class="or-btn or-btn--sm" @click="bulk.mutate({ status: 'shipped', fulfilment: 'fulfilled' })">{{ t('orders.bulkMarkShipped') }}</button>
</BulkBar>
{/* The selection is client state; the action is a server action. */}
<BulkBar>
  <BulkActions />
</BulkBar>
<TableBulkBar :count="selection.selected.value.size" @clear="selection.clear">
  <button type="button" class="or-btn or-btn--sm" @click="bulk.mutate({ status: 'shipped', fulfilment: 'fulfilled' })">{{ t('orders.bulkMarkShipped') }}</button>
</TableBulkBar>