Pricing
Tax basis
Whether a price includes tax, as a badge the price sits inside: filled when the tax is in the figure, hollow when it is left out. Hover explains the tax, its rate and the price on the other basis. Use it on a figure, alone in a column header, or show a price on both bases at once so an ex-tax figure can be checked against the shelf.
Examples
Inc and ex, any tax label
Short single-word labels print as they are; longer ones print as "tax" and keep the full label in the title and spoken text.
show, both, hide
both needs a rate. Without one it shows the one figure; without a basis it shows no mark at all.
Named once, in a header
A column on one basis names it in the header and hides it in the cells.
Both, stacked, in a list
Installation
1. Add the block. It brings what it builds on (
tooltip,retail-format) with it.terminalnpx shadcn@latest add https://ui.twelfth.ai/r/tax-basis.json2. Optional: register the namespace in
components.jsonto writenpx shadcn add @twelfth/tax-basisfrom then on.components.json{ "registries": { "@twelfth": "https://ui.twelfth.ai/r/{name}.json" } }
API reference
PriceFigure
| Prop | Type | Default | Description |
|---|---|---|---|
| value* | number | null | — | The price, on basis. null prints —. |
| basis* | "inclusive" | "exclusive" | null | — | The basis value is on. null when the source did not say: no mark, nothing converted. |
| taxBasis | "show" | "hide" | "both" | "show" | The figure with its mark, the figure alone, or the price on both bases. |
| taxLabel | string | "GST" | GST, VAT, GST/HST, Sales tax… |
| taxRatePct | number | null | null | The rate behind both, in percent. Outside 0–30 counts as unknown. |
| short | boolean | false | Badges print inc / ex without the label. |
| explain | "focus" | "hover" | false | "focus" | How the badge explains the tax. |
| note | ReactNode | — | A further line for the hover, e.g. how it was converted. |
| stacked | boolean | false | With both, the second figure goes underneath. |
| format | (value: number) => string | — | Formats each figure; defaults to formatMoney. |
| locale / currency | string | "en-AU" / "AUD" | For the default format. |
TaxBasisMark
| Prop | Type | Default | Description |
|---|---|---|---|
| basis* | "inclusive" | "exclusive" | — | Filled for inclusive, hollow for exclusive. |
| taxLabel | string | "GST" | The tax's name. |
| short | boolean | false | inc / ex only, where width is tight. |
| children | ReactNode | — | The figure the badge holds; omit for the basis alone. |
| taxRatePct / other / note | number | string | ReactNode | — | Rate, other-basis price and a further line for the hover. |
| explain | "focus" | "hover" | false | "focus" | Tooltip on hover and focus, hover only (inside a link), or none. |
otherBasisPrice / taxBasisWords
| Prop | Type | Default | Description |
|---|---|---|---|
| otherBasisPrice(value, basis, taxRatePct) | number | null | — | The price on the other basis; null without a basis or a plausible rate. |
| taxBasisWords(basis, taxLabel) | string | — | "including GST" / "excluding GST". |
Notes
- Screen readers hear "including GST" / "excluding GST". Hover or focus explains the tax in full (GST: Goods and Services Tax), with the rate and the other-basis price when known. Use explain="hover" inside a link or button, explain={false} inside a tooltip.
- The badge takes its colours from the text around it, so it reads on a card, in a header and in an inverted tooltip without a variant.
- Never guesses: no basis means no badge, and no rate means no second figure and no rate in the hover.
