Skip to content
ssntl/ui

Pill accordion

Pills that grow into cards over a product photo, on a CSS-only glass material: one open at a time, stepped with Previous and Next.

  • Orders. Take an order at the table and it reaches the kitchen before you do.

  • Kitchen screen. Every ticket in the order it came in, with a timer that turns orange when a dish runs late.

  • Tables. See which tables are free, waiting or ready to pay, from any device.

  • Payments. Split the bill, take cards and cash, and close the day in one tap.

  • Reports. Know what sold, when, and by whom, without a spreadsheet.

Installation

Add it with the shadcn CLI, or copy the source by hand.

$ pnpm dlx shadcn@latest add @ssntl/pill-accordion

API reference

PillAccordion

  • value?Type: string | nullThe open item's value, or null when every item is a pill.Default:—
  • defaultValue?Type: string | nullThe item open on mount, when uncontrolled.Default:null
  • onValueChange?Type: (value: string | null) => voidDefault:—

Also takes every prop of <div>.

PillAccordionList

  • aria-labelrequiredType: stringNames the set: “Features of the studio plan”.Default:—

Also takes every prop of <ul>.

PillAccordionItem

  • valuerequiredType: stringA unique value for the item.Default:—

Also takes every prop of <li>.

No props of their own: each passes every prop to the element on the right.

  • PillAccordionTrigger<button>
  • PillAccordionTriggerIcon<span>
  • PillAccordionContent<div>
  • PillAccordionPrevious<button>
  • PillAccordionNext<button>
  • PillAccordionClose<button>

Rules

What this component expects from you, as it ships in components/ui/pill-accordion.md next to the code. The full file adds when to use it, keyboard, the UI foundations it applies and every shared rule.

components/ui/pill-accordion.md
## Rules for Pill accordion

- **One open at a time.** The pill grows into a card while the others make room; focus moves into the card, and Escape or Close returns it to the pill.
- Previous and Next step between cards without closing; at the ends they stay focusable (`aria-disabled`) so focus never drops to the page.
- The morph animates the item's size over 400ms on `--ease-in-out`; the label leaves at once, and the text arrives only once the card is two-thirds grown, lifting 8px, so it never shows clipped. Reduced motion: the size changes at once and the text only fades.
- **Glass.** The glass utility, clear enough to see the photo through and measured at 4.5:1 or more with pure black or white behind it, in both themes; with reduced transparency it turns solid.
- **Hit areas.** Pills are 56px tall; the round buttons are 40px discs inside a 48px target.
- Name the buttons for what they step through (“Next feature”), and keep each card to a sentence or two.
- Drive a photo beside it with value and `onValueChange`; cross-fade with opacity, keeping every photo mounted.
Open the full rules file (opens in a new tab)