Skip to the object
Tactile UI

FAQ Index

An FAQ as a card-index drawer. Each question is typed along a card’s edge with its subject on a staggered tab; pull one and it lifts out to show the answer. An accordion underneath.

What it is for

The questions section of an agent-infrastructure, devtools or IoT product (pricing, data retention, SSO, uptime, rate limits, self-hosting) filed where they can be found, with one contrast key to ask a person.

Installnpx shadcn add https://tactileui.dev/r/faq-drawer.json

Controls

Typed on the card in the label holder.

The card that is out of the drawer when the page opens.

Native: the cards share a <details name>.

A page, a path, mailto: or tel:.

Finish

Auto follows the page’s data-finish, then the visitor’s system. The cards stay paper.

Everything you set here is what the Code and Prompt tabs give you.

Seats open in 11 days. Want one email that morning?

Datasheet

Mechanism
Native details accordion, Exclusive details name, Details content interpolate size, Card lift transform, Depth shaded stack, Staggered tabs, Container query layout, Finish following, Sticky head
Stack
Vanilla ES modules, CSS
Needs
Nothing, no dependencies
States
10 documented
Version
0.1.0
Licence
Free, source open to everyone

States

  1. At restSeven cards standing in the tray, the first pulled; tabs at three stations; the back cards a shade darker and a hair narrower; nothing runs.
  2. HoverA closed card rises 3px, as a card in an index does under a finger.
  3. PulledClick, Enter or Space: the card lifts 12px above the rest with a deeper shadow and its face opens (the platform's details-content transition, 320 ms) to the answer typed on ruled stock under a double rule, with its filing line.
  4. One at a timePulling another card puts the first back (native <details name>); switchable to several at once.
  5. FocusA 2px ring in the ribbon's ink inside the card's edge, visible on paper in both finishes.
  6. AluminiumA bead-blasted drawer box and front, the tray lit from above.
  7. GraphiteA soft-touch black drawer; the cards stay paper.
  8. TabletThe head above, the drawer full width.
  9. PhoneTighter metal and tray, no card numbers, smaller tabs, the answer from the card's edge, the Ask key full width.
  10. Reduced motionThe card opens at once, lifted; no transition; hover does not lift.

Notes

It is an accordion underneath (native details and summary, one at a time via the shared name), so keyboard and screen reader behave exactly as they expect, while the page shows a drawer of cards. Free with an account: CSS and a few lines of DOM, no dependency, both finishes.

Original composition. The product (Lode), its prices, limits and answers are invented. The drawer and cards are CSS drawn here; no image. Faces: Instrument Sans and Geist Mono, both the kit's own, SIL OFL 1.1.

Using it

Copy the faq-drawer folder from its package next to your page, link the stylesheets and mount it on an element. The Code tab above writes the example at any settings, and for React, Vue, Svelte or a custom element (Using a framework).

Options

OptionTypeDefaultWhat it does
labeltext'Questions'Label
titletext'Asked before you sign.'Headline
leadtext'The questions every platform team asks in its first week, filed where you can find them. Pull a card to read it.'Lead
drawertext'Lode · Q–Z'Typed on the card in the label holder.
countnumber, 3 to 77Cards
opennone · 1 · 2 · 3 · 4 · 5 · 6 · 7'1'The card that is out of the drawer when the page opens.
singlebooleantrueNative: the cards share a <details name>.
askNotetext'Not in the drawer? A person answers, usually within the hour.'Beside the key
askLabeltext'Ask us'Key
askHreftext'mailto:hello@lode.example'A page, a path, mailto: or tel:.
finishauto · aluminium · graphite'auto'Auto follows the page’s data-finish, then the visitor’s system. The cards stay paper.

Methods

mount(element, options)
Builds the block inside the element and returns its handle.
handle.open(i)
Open card i (0-based), as a click would.
handle.update(next = {})
Change options in place.
handle.destroy()
Stops it and cleans up after it.