twelfth

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.

@twelfth/tax-basisuitooltip@twelfth/retail-format
$136.35excluding GST$149.99including GST

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.

GSTincluding GSTexcluding GST
VATincluding VATexcluding VAT
GST/HSTincluding GST/HSTexcluding GST/HST
SSTincluding SSTexcluding SST
Sales taxincluding Sales taxexcluding Sales tax

show, both, hide

both needs a rate. Without one it shows the one figure; without a basis it shows no mark at all.

$136.35excluding GST$136.35excluding GST$149.99including GST$136.35$136.35excluding GST$136.35

Named once, in a header

A column on one basis names it in the header and hides it in the cells.

Our price excluding GST
$21.35
$136.35
$8.95

Both, stacked, in a list

£22.72including VAT£18.93excluding VAT

Installation

  1. 1. Add the block. It brings what it builds on (tooltip, retail-format) with it.

    terminal
    npx shadcn@latest add https://ui.twelfth.ai/r/tax-basis.json
  2. 2. Optional: register the namespace in components.json to write npx shadcn add @twelfth/tax-basis from then on.

    components.json
    {
      "registries": {
        "@twelfth": "https://ui.twelfth.ai/r/{name}.json"
      }
    }

API reference

PriceFigure

PropTypeDefaultDescription
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.
taxLabelstring"GST"GST, VAT, GST/HST, Sales tax…
taxRatePctnumber | nullnullThe rate behind both, in percent. Outside 0–30 counts as unknown.
shortbooleanfalseBadges print inc / ex without the label.
explain"focus" | "hover" | false"focus"How the badge explains the tax.
noteReactNode—A further line for the hover, e.g. how it was converted.
stackedbooleanfalseWith both, the second figure goes underneath.
format(value: number) => string—Formats each figure; defaults to formatMoney.
locale / currencystring"en-AU" / "AUD"For the default format.

TaxBasisMark

PropTypeDefaultDescription
basis*"inclusive" | "exclusive"—Filled for inclusive, hollow for exclusive.
taxLabelstring"GST"The tax's name.
shortbooleanfalseinc / ex only, where width is tight.
childrenReactNode—The figure the badge holds; omit for the basis alone.
taxRatePct / other / notenumber | 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

PropTypeDefaultDescription
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.

No bad cookies on these shelves.

Essential cookies keep the store running. Analytics only if you choose.