Skip to content

OList ​

OList renders an array of items as an accessible native list, with one scoped slot for the item content and optional built-in pagination.

Usage ​

Step by step ​

  1. Import OList from the ooko-ui/list public subpath.
  2. Pass the array to items and render each item in the default slot, which receives item and its index. Name the list with aria-label or aria-labelledby.
  3. Set pageSize to paginate the items locally. Bind v-model:page only when the page must be read or restored; the list otherwise keeps its own page.

Example ​

The rendered example and its source come from the same Vue single-file component.

  • Draft the release notes
  • Review the pull request
  • Update the changelog

Interactive playground ​

Change the number of items, toggle pagination, and edit the page size to see the list and its pagination update. Set the item count to zero to show the empty slot.

  • Item 1
  • Item 2
  • Item 3

Props ​

PropTypeDefaultDescription
itemsreadonly T[]undefinedItems to render, one list item each.
getItemKey((item: T, index: number) => PropertyKey)undefinedReturns a stable, unique key for an item; the item index is used when omitted.
pageSizenumberundefinedNumber of items per page; shows the built-in pagination when the items exceed one page.
pagenumberundefinedCurrent page, starting at one; the list keeps its own page when omitted.

Events ​

EventPayloadDescription
update:pagenumberRequests a new current page.

Slots ​

SlotPropsDescription
default{ /** Item being rendered. */ item: T; /** Index of the item in items, across pages. */ index: number; }Renders the content of one list item.
emptynoneContent displayed instead of the list when items is empty.

CSS custom properties ​

Custom propertyDefaultDescription
--o-list-item-paddingvar(--o-space-2) var(--o-space-3)Sets the padding inside each list item.
--o-list-divider1px solid var(--o-border-color-subtle)Sets the border shorthand drawn between list items.

Override example ​

css
:root {
  --o-list-item-padding: var(--o-space-3) var(--o-space-4);
  --o-list-divider: 0;
}

Define the same custom properties on a container instead of :root to limit an override to one part of an application.

Accessibility ​

  • Items render as li elements inside a native ul. The ul restates role="list" because Safari drops list semantics from lists without bullets.
  • Every attribute except class and style is forwarded to the ul, so aria-label, aria-labelledby, and id name and identify the list itself. class and style stay on the root wrapper.
  • The built-in pagination is an OPagination navigation placed after the list, with its accessible name, keyboard behavior, and polite page status. Focus stays on the pagination control after a page change.
  • The empty slot replaces the list, so assistive technologies do not announce an empty list.
  • Items are not interactive by themselves. Put native links or buttons in the slot when an item triggers an action.

Behavior and edge cases ​

  • Without pageSize, every item renders and no pagination is shown. With pageSize, the pagination appears only when the items exceed one page.
  • A pageSize below one or not finite disables pagination. A page outside the available pages is clamped, without emitting update:page, for example after items shrinks.
  • page is optional: when bound, the list shows that page and emits update:page on requests; when omitted, the list stores the page itself.
  • The slot index is the item's index in items, across pages. Items are keyed by that index unless getItemKey returns a stable key, which is recommended when items can be reordered, inserted, or removed.
  • For server-side pages, pass only the current page to items, leave pageSize unset, and place an OPagination bound to the server page next to the list.
  • The built-in pagination uses the compact OPagination preset unless an app default selects another preset. OList itself exposes no app defaults.
  • Without an empty slot, an empty items array renders an empty list.