Invoice & Credit Note
An invoice and its credit note stacked like paper – switch between them, pick lines to credit, adjust amounts and issue.
Part of affectUI Pro. Install: npx shadcn@latest add https://www.affectui.com/r/invoice-credit.json · Import from @/components/ui/invoice-credit
When to use
- Billing portals and admin tools that show an invoice and let a team credit it
- Product pages for invoicing software – a document that looks real and can be tried
When not to use
- Printing or PDF generation – render a dedicated print layout instead
- Invoices with dozens of lines – the credit tray is built for a handful
Usage
import { InvoiceCredit } from "@/components/ui/invoice-credit";
export function Billing() {
return (
<InvoiceCredit
invoiceNo="INV-2041"
creditNo="CN-0117"
lines={[
{ id: "plan", name: "Growth plan", qty: 1, rate: 1250, tax: 0.2 },
{ id: "api", name: "API calls (per 1k)", qty: 18420, rate: 0.42, tax: 0.2, group: "Metered usage" },
]}
onIssue={(credits, total) => api.issueCreditNote(credits, total)}
/>
);
}Props
| Name | Type | Default | Description |
|---|---|---|---|
seller / buyer | { name, lines: string[] } | From and To blocks on the invoice | |
invoiceNo / creditNo | string | Document numbers shown under Terms | |
invoiceDate / dueDate / period | string | Dates shown on both documents | |
lines | InvoiceLine[] | Each { id, name, qty, rate, tax, group? } – lines with a group are listed under a heading | |
currency | string | "$" | Currency symbol |
onIssue | (credits, total) => void | Called when the credit note is issued, with the credited amount per line and the total incl. tax | |
className | string | Extra class on the root |
Keyboard
- Tab: Moves through the switch, the actions, every line and amount
- Enter: Confirms an amount
Accessibility
- The switch is a tablist; the sheet in the back is hidden from screen readers and can't be focused
- Credit lines are checkboxes with labels; amounts are labelled per line and stay within the line total
Responsive
- Follows its own width: below 560px the parties stack, the rate and tax columns hide and the credit tray drops the total column
- Dark mode built in: switches when an ancestor (usually <html>) has the class dark or data-theme="dark"
Requirements
- React 19