Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Annotated Invoice FAQ Block for React Aria

A FAQ that explains its own invoice: seven numbered questions beside a framed mock invoice, where opening a question rings the line it explains and mutes the rest.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

An annotated invoice FAQ for React with React Aria. The title and seven questions sit at the start; a framed mock invoice sits in the end column behind a split divider and stays in view while the questions scroll. Each question carries a number, and the same number sits on the invoice line it explains: open "Why is there a prorated line?" and that line gets a ring and a filled number while the others turn muted. The amounts, the prorated seats, the credit, the tax and the total, are worked out from a handful of typed prices, so the answers quote the same figures the invoice shows, and one quiet line says they are examples. On a phone the invoice sits between the title and the questions, small. It's built from Accordion and Guides, with CSS transitions and your theme's tokens for every colour. For billing pages, help centres and any product where the first support ticket is "what is this line?".

FAQ

How do I change the invoice and the questions?

Edit the constants at the top of the file: the seat price and count, the days in the cycle, the storage, the credit and the tax rate in basis points. LINES and the amounts are derived from them, and the answers quote them, so they never drift apart. Each entry in QUESTIONS names the invoice line it explains (line) and its number (n); the number appears on the question and on that line.

How does a question pick its line?

The open question's line decides which invoice row is ringed: the row gets a ring, a tint and a filled number, and the other rows turn muted. With every question closed nothing is ringed and the invoice reads normally. The ringed row also carries aria-current, so a screen reader can tell which line the open answer is about.

How are the amounts written, and what about right-to-left layouts?

Money is formatted by one Intl.NumberFormat for US dollars, and each amount sits in its own dir="ltr" span so "-$9.00" keeps its order in right-to-left layouts. Prorating is rounded to a whole cent, and tax is rounded once on the subtotal, so the lines always add up to the total.

Are the closed answers in the page's markup?

Yes. React Aria keeps every closed panel in the markup as hidden="until-found". One answer is open at a time.

How does it work with a keyboard and a screen reader?

Each question is a button inside its own h3 under the section's h2; Tab moves between them and Enter or Space opens one. The invoice is a list named "Invoice lines" that a screen reader can read at any time, and its decorative numbers are hidden, since each answer names its line in words.

How does it fit on a phone?

Below the lg breakpoint the title comes first, then the invoice, compact and without the sticky behaviour, and the questions follow, so the line that lights up is always on the screen with the question you opened. The visual order differs from the source order only for the invoice, which holds no controls. Nothing scrolls sideways at 320 pixels.