Zostel
Navigation Pills

Pills

The site's filters: small pills, orange-ink when picked, Steel Grey for All. Toggle buttons (aria-pressed) in a named group. On a touch screen each small pill gets a 44 px target without looking bigger; with scroll, on a phone, they are 44 px tall.

Preview

Filter, with counts and an "All" tab

84 places: Agra, Alleppey, Bangalore, Banikhet…

One row on a phone (scroll)

A single pill: pillVariants

Usage

tsx
import { Pills, pillVariants } from "zostel-ui";

<Pills
  label="Landscape"
  options={[{ value: "all", label: "All", count: 84 }, { value: "waters", label: "Waters", count: 16 }]}
  value={family}
  onChange={setFamily}
  allValue="all"
  scroll
/>

// one pill on its own (a toggle, a sort, a link)
<button className={pillVariants({ state: on ? "on" : "off" })}>Name</button>

Pills

options
Type: { value: string; label: ReactNode; count?: number }[]
Default: —

The tabs. A count shows after the label, in a lighter weight.

value
Type: string
Default: —

The picked tab.

onChange
Type: (value: string) => void
Default: —

Called with the tab's value.

allValue
Type: string
Default: —

The value of the "All" tab: Steel Grey when picked, not orange-ink.

label
Type: string
Default: —

The group's accessible name (its aria-label).

scroll
Type: boolean
Default: false

On a phone: one row that scrolls sideways, edge to edge, each pill 44 px tall.

className
Type: string
Default: —

More classes for the row, added beside its own.

pillVariants

state
Type: "on" | "all" | "off"
Default: "off"

on = orange-ink under white text; all = Steel Grey (the "All" tab only); off = white, a Beige line, muted text, the orange line on hover.