All components (204)
Invoice lines
Management · InvoiceLinesEditor · .amset-invoice
What it is and when to use it
The lines of an invoice, editable: description, quantity, unit price, discount, VAT and income-tax withholding (IRPF) per line, with the amount of each one and the breakdown below: taxable base, VAT by rate, withholding by rate and total.
How it calculates (calculateInvoice, which is also exported on its own)
- Each line: quantity × price, minus the discount, rounded to the cent.
- VAT and withholding are calculated once per rate, on the sum of the bases of that rate: that way they match the breakdown printed on the invoice (calculating them line by line throws cents off).
- The equivalence surcharge (a customer under that regime, typical of retail) is added to the VAT according to its rate: 5.2% with 21%, 1.4% with 10% and 0.5% with 4% (article 161 of Law 37/1992). It has its own row in the breakdown, also once per rate.
- Total = base + VAT + surcharge − withholding. A negative quantity is a credit note.
When to use it
- Issuing invoices, quotes or credit notes.
onChangehands over the lines and the totals already calculated. equivalenceSurchargeputs the equivalence surcharge on the WHOLE invoice; withsurchargePerLineeach line gets its "Equivalence surcharge" checkbox and the line's overrides the invoice's.surchargeRateschanges the rates (for example the transitional 0.62% with 5%, which is not the default).withWithholding={false}removes the withholding column;vatRatesandwithholdingRateschange the rates offered (the Canary Islands' IGIC, another country);minLinesandmaxLinesbound how many lines there are.
When not to
- Just showing an invoice that has already been issued: a
TableorOrderSummary. - Several currencies on the same invoice or pro-rata: it does not cover them. Nor does it decide whether your customer is under the equivalence surcharge: you know that, and you tell it with
equivalenceSurcharge.
Keyboard: lines are walked with Tab. "Add line" leaves focus on the description of the new one; when one is removed, focus moves to the previous one.
Accessibility: each line is a group ("Line 2"); adding and removing are announced; the total is in role="status". On a wide screen the labels are shown only on the first line and remain present for the screen reader on the others.
What it looks like
- Taxable base
- €2,198.70
- VAT 21% on €2,124.00
- €446.04
- VAT 4% on €74.70
- €2.99
- Withholding 15% on €2,124.00
- -€318.60
- Invoice total
- Invoice total: €2,329.13
<InvoiceLinesEditor
label="Invoice lines"
initialValue={lineas}
onChange={setLineas}
/>Props
Import it with import { InvoiceLinesEditor } from '@amset/ui'. Required props are marked.
| Prop | Type | What it does |
|---|---|---|
labelrequired | string | Required: names the group of lines for the screen reader. |
className | string | Merged with the library classes; it does not replace them. |
currency | string | The currency. `EUR` by default. |
defaultVatRate | number | The VAT of a new line. By default, 21. |
disabled | boolean | — |
equivalenceSurcharge | boolean | Equivalence surcharge on the WHOLE invoice (a customer under that regime: retail). It is added to the VAT of each line according to its rate (5.2% with 21%, 1.4% with 10%, 0.5% with 4%) and appears in the breakdown. Defaults to `false`. |
error | string | Error from outside (from the server). |
hint | string | — |
initialValue | readonly InvoiceLine[] | The lines to start with, without controlling them from outside. Without them, one empty line. |
maxLines | number | The maximum number of lines. No limit by default. |
minLines | number | The minimum number of lines: you cannot remove below it. By default, 1. |
onChange | (lines: readonly InvoiceLine[], totals: InvoiceTotals) => void | Notifies with the lines and the totals already calculated each time something changes. |
readOnly | boolean | — |
surchargePerLine | boolean | An "Equivalence surcharge" checkbox on each line, to decide it line by line: the checkbox of a line overrides `equivalenceSurcharge`. Defaults to `false`. |
surchargeRates | Readonly<Record<number, number>> | The surcharge for each VAT rate, as a percentage. Defaults to the Spanish rates in force (`SPANISH_SURCHARGE_RATES`). |
value | readonly InvoiceLine[] | The lines, controlled from outside. |
vatRates | readonly number[] | The VAT rates offered. By default, the Spanish ones (21, 10, 4 and 0). |
withholdingRates | readonly number[] | The income-tax withholding rates (IRPF) offered. By default, 0, 7, 15 and 19. |
withWithholding | boolean | With `false` there is no withholding column. By default, `true`. |
It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.
CSS variables
These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.
| Variable | Default |
|---|---|
--amset-invoice-gap | var(--amset-space-3) |
How to change it
.amset-invoice {
--amset-invoice-gap: ...;
}In the test bench
Every state and variant, to try one at a time, on its page at ui.amset.tech:
