Rebar UI

1.0

synthetic

List

One row family for phone screens: thumbnail rows, settings rows and navigation cards.

List, ListItem, ListSectionCards and grouped variants; try a row, the switch, or Delete

variant="cards"

variant="grouped"

Default

Just added (highlight, pinned)

Selected (open item)

Busy (deleting)

  • Why do Catholics confess to a priest?2 hours ago

Long title wraps

Skeleton

Disabled

  • Explain todayΓÇÖs Gospel3 days ago

Trailing: chevron

Trailing: Switch, loading

  • Remind me dailyTurning on…

Trailing: value

  • Time
    8:00 AM
  • Language
    English

Leading icon tile (nav card)

Empty

No discussions yet

Ask a question and it will appear here.

Card rows from --rebar-list-* properties, custom moreIcon

  • Why do Catholics confess to a priest?2 hours ago

Compact rows on a dark scope (--rebar-list-item-background, -selected-background)

  • Why do Catholics confess to a priest?2 hours ago
  • Is it a sin to miss Mass when I am sick, or when I am up all night caring for a newborn?Yesterday

In context

Ask, Profile and LibraryJust added and busy rows, settings groups, navigation cards and skeletons

Ask

  • Is Mary really sinless? Where is that in Scripture?NewJust now
  • Why do Catholics confess to a priest?2 hours ago

Your Profile

Account

Bible translation

List props

PropTypeRequiredDefault
variantListVariant | undefinedNocards
emptyReactNodeNo—
loadingboolean | undefinedNo—

ListItem props

PropTypeRequiredDefault
titleReactNodeYes—
titleStyle"serif" | "sans" | undefinedNo—
descriptionReactNodeNo—
metaReactNodeNo—
mediaReactNodeNo—
leadingReactNode | { icon: ReactNode; tone?: 1 | 2 | 3 | 4 | undefined; }No—
leadingControlReactNodeNo—
editingboolean | undefinedNo—
onEdit(() => void) | undefinedNo—
renderEditor(() => ReactNode) | undefinedNo—
trailingReactNodeNo—
onMore(() => void) | undefinedNo—
moreLabelstring | undefinedNoMore actions
moreIconReactNodeNo—
hrefstring | undefinedNo—
targetstring | undefinedNo—
renderLinkRenderLink | undefinedNo—
onClick((event: MouseEvent<HTMLElement, MouseEvent>) => void) | undefinedNo—
selectedboolean | undefinedNo—
highlightboolean | "new" | undefinedNo—
highlightPinnedboolean | undefinedNo—
onHighlightEnd(() => void) | undefinedNo—
loadingboolean | undefinedNo—
skeletonboolean | undefinedNo—
disabledboolean | undefinedNo—

ListSection props

PropTypeRequiredDefault
titleReactNodeNo—
footerReactNodeNo—
gapstring | number | undefinedNo—

Accessibility

A real <ul> of <li> rows. The media and text area of a row is the one link or button (href or onClick); trailing controls sit beside it, never inside, so a Switch or a menu button is never nested in an interactive element and never triggers the row. selected sets aria-current; loading sets aria-busy and a labelled spinner; skeleton rows are aria-hidden; a disabled row has no focusable control. A ListSection is a labelled region named by its eyebrow.

data-rebar-* attributes

data-rebar-component="list" | "list-item" | "list-section", data-rebar-variant on the list and its rows, data-rebar-title-style, data-rebar-selected, data-rebar-highlight, data-rebar-state="loading" | "skeleton" | "disabled"; parts main, media, leading, body, title, description, meta, chip, chevron, trailing.

Leading control, inline edit and section spacing

leadingControl puts an independent control (a round check button) before the main area, beside the row link or button and never inside it, so pressing it does not trigger the row. For inline renaming set editing with a renderEditor that returns an Input: the title is replaced by the editor and the main area becomes a plain element, so the row semantics stay valid (onEdit fires on F2 or a double-click of the title; the app owns the value and commits on Enter or blur). Consecutive ListSections are spaced by --rebar-list-section-gap (24px), or a section's gap prop.

<ListItem title={task.title} leadingControl={<CheckButton aria-label="Done" />} editing={editingId === task.id} onEdit={() => setEditingId(task.id)} renderEditor={() => <Input aria-label="Rename" defaultValue={task.title} onBlur={commit} />} />