@umriss-ui/calculation 0.5.3 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/llms-full.md CHANGED
@@ -1,4 +1,4 @@
1
- # @umriss-ui/calculation 0.5.3
1
+ # @umriss-ui/calculation 0.6.1
2
2
 
3
3
  > React calculation view for data-dense applications - a derivation written as it is shown, evaluated by the library, folded and read line by line.
4
4
 
@@ -1114,7 +1114,7 @@ Demo page: https://romanhaendler.github.io/umriss-ui/calculation/calculation/
1114
1114
 
1115
1115
  There is no prop for a result. Every derived number is computed with the operator its line names, at full precision; only the screen rounds.
1116
1116
 
1117
- The nesting is the fold structure and the child order is the operand order. What TypeScript cannot check – a `Ref` to nothing, a circle through references, a wrong operand count, a duplicate id, a component of your own wrapping `Given` – fails on the first render with a message saying which ([ADR-0027](https://github.com/romanhaendler/umriss-ui/blob/main/docs/adr/0027-a-calculation-is-written-as-it-is-shown.md)).
1117
+ The nesting is the fold structure and the child order is the operand order. What TypeScript cannot check – a `Ref` to nothing, a circle through references, a wrong operand count, a duplicate id, a component of your own wrapping `Given`, `emphasis` or `rule` on the Result – fails on the first render with a message saying which ([ADR-0027](https://github.com/romanhaendler/umriss-ui/blob/main/docs/adr/0027-a-calculation-is-written-as-it-is-shown.md)). `emphasis` and `rule` set any other line apart without CSS ([ADR-0049](https://github.com/romanhaendler/umriss-ui/blob/main/docs/adr/0049-a-sum-takes-rows-from-data.md)).
1118
1118
 
1119
1119
  Every line is read as one sentence by a screen reader, and every derivation is a disclosure: its button says whether it shows or hides how the line is derived.
1120
1120
 
@@ -1378,6 +1378,120 @@ export default function Invoice() {
1378
1378
  }
1379
1379
  ```
1380
1380
 
1381
+ ##### A stronger line
1382
+
1383
+ `emphasis="strong"` sets a line apart to be read first – here the production cost, the figure a costing sheet is usually questioned on. It changes how the line looks, never what it says: its sentence for a screen reader stays the same. Any quantity takes it but the Result, which is already the heaviest line; there it fails on the first render.
1384
+
1385
+ ```tsx
1386
+ import { Calculation, Chain, Given, Interim, Minus, Plus, Times } from "@umriss-ui/calculation";
1387
+
1388
+ export default function AStrongerLine() {
1389
+ return (
1390
+ <Calculation aria-label="Offer price A-2041">
1391
+ <Chain>
1392
+ <Given label="Direct material" value={1840} unit="€" decimals={2} />
1393
+ <Plus label="Material overhead" value={220.8} unit="€" decimals={2} />
1394
+ <Plus label="Direct labour" value={960} unit="€" decimals={2} />
1395
+ <Plus label="Production overhead" value={432} unit="€" decimals={2} />
1396
+ <Interim label="Production cost" unit="€" decimals={2} emphasis="strong" />
1397
+ <Minus label="Customer discount" value={86.4} unit="€" decimals={2} />
1398
+ <Interim label="Net cost" unit="€" decimals={2} />
1399
+ <Times label="Profit mark-up" value={1.08} />
1400
+ <Interim label="Net offer price" unit="€" decimals={2} />
1401
+ </Chain>
1402
+ </Calculation>
1403
+ );
1404
+ }
1405
+ ```
1406
+
1407
+ ##### A quieter line
1408
+
1409
+ `emphasis="muted"` lets a line recede – a small position the reader may skip. It still counts in full: the interim below includes it, and a reader who redoes the sum needs it.
1410
+
1411
+ ```tsx
1412
+ import { Calculation, Chain, Given, Interim, Plus } from "@umriss-ui/calculation";
1413
+
1414
+ export default function AQuieterLine() {
1415
+ return (
1416
+ <Calculation aria-label="Tour cost, 17 March">
1417
+ <Chain>
1418
+ <Given label="Driver, 8.5 h" value={340} unit="€" decimals={2} />
1419
+ <Plus label="Diesel, 212 km" value={98.6} unit="€" decimals={2} />
1420
+ <Plus label="Vehicle, day rate" value={145} unit="€" decimals={2} />
1421
+ <Plus label="Tolls" value={4.2} unit="€" decimals={2} emphasis="muted" />
1422
+ <Plus label="Parking" value={3.5} unit="€" decimals={2} emphasis="muted" />
1423
+ <Interim label="Cost of the tour" unit="€" decimals={2} />
1424
+ </Chain>
1425
+ </Calculation>
1426
+ );
1427
+ }
1428
+ ```
1429
+
1430
+ ##### A rule above
1431
+
1432
+ `rule="above"` rules a line off from the ones before it, where a new section starts that needs no interim of its own: here the deductions after the earnings. An interim draws its rule across the figures only; this one runs across the whole row.
1433
+
1434
+ ```tsx
1435
+ import { Calculation, Chain, Given, Interim, Minus, Plus } from "@umriss-ui/calculation";
1436
+
1437
+ export default function ARuleAbove() {
1438
+ return (
1439
+ <Calculation aria-label="Payslip, March">
1440
+ <Chain>
1441
+ <Given label="Gross salary" value={4200} unit="€" decimals={2} />
1442
+ <Plus label="Night work bonus" value={84} unit="€" decimals={2} />
1443
+ <Plus label="Travel allowance" value={60} unit="€" decimals={2} />
1444
+ <Minus label="Income tax" value={640.2} unit="€" decimals={2} rule="above" />
1445
+ <Minus label="Church tax" value={51.2} unit="€" decimals={2} />
1446
+ <Minus label="Social security contributions" value={889.6} unit="€" decimals={2} />
1447
+ <Interim label="Net salary" unit="€" decimals={2} />
1448
+ </Chain>
1449
+ </Calculation>
1450
+ );
1451
+ }
1452
+ ```
1453
+
1454
+ ##### Emphasis inside a group
1455
+
1456
+ Emphasis and rule work inside an opened derivation too. Its numbers already recede, so a muted line there recedes one step further; a strong one stands out from the group, and a rule parts the group where its rows do not.
1457
+
1458
+ ```tsx
1459
+ import { Calculation, Chain, Given, Interim, Plus, Sum } from "@umriss-ui/calculation";
1460
+
1461
+ /* Cost centres from the controlling system. */
1462
+ const CENTRES = [
1463
+ { id: "4100", name: "4100 Assembly", amount: 18400, emphasis: "strong" as const },
1464
+ { id: "4200", name: "4200 Paint shop", amount: 9200 },
1465
+ { id: "4300", name: "4300 Quality", amount: 6100 },
1466
+ { id: "9900", name: "9900 Allocations", amount: 740, emphasis: "muted" as const, rule: "above" as const },
1467
+ ];
1468
+
1469
+ export default function EmphasisInsideAGroup() {
1470
+ return (
1471
+ <Calculation aria-label="Production cost, March">
1472
+ <Chain>
1473
+ <Given label="Material" value={52800} unit="€" />
1474
+ <Plus>
1475
+ <Sum label="Cost centres" unit="€">
1476
+ {CENTRES.map((centre) => (
1477
+ <Given
1478
+ key={centre.id}
1479
+ label={centre.name}
1480
+ value={centre.amount}
1481
+ unit="€"
1482
+ emphasis={centre.emphasis}
1483
+ rule={centre.rule}
1484
+ />
1485
+ ))}
1486
+ </Sum>
1487
+ </Plus>
1488
+ <Interim label="Production cost" unit="€" />
1489
+ </Chain>
1490
+ </Calculation>
1491
+ );
1492
+ }
1493
+ ```
1494
+
1381
1495
  #### When to use something else
1382
1496
 
1383
1497
  - A single figure with its verdict, without the working → `Stat` from @umriss-ui/core
@@ -1404,8 +1518,8 @@ Name the calculation with `aria-label`, which lands on the list; without it a re
1404
1518
 
1405
1519
  | Prop | Type | Default | Description |
1406
1520
  |---|---|---|---|
1407
- | `children` *required* | `ReactNode` | — | The result: exactly one quantity - a tree (`<Sum>`, `<Difference>`, `<Product>`, `<Quotient>` with their operands, `<Given>` as leaves) or a `<Chain>`, the two mixing freely; `<Ref>` for a quantity defined elsewhere.<br>Shown in: [Two numbers and a sum](#/calculation/first-sum), [Write a tree](#/calculation/oee), [Write a chain](#/calculation/invoice) and 34 more |
1408
- | `metrics` | `readonly `[`Metric`](#/metrics/type-Metric)`[]` | — | Several numbers per quantity, side by side - headcount and full-time equivalents of the same teams ([ADR-0038](https://github.com/romanhaendler/umriss-ui/blob/main/docs/adr/0038-a-calculation-can-carry-several-metrics.md)). Every `value` is then an object with a number for each metric id; unit and places are the metric's. A calculation with metrics only adds and subtracts, and assesses no target or limits.<br>Shown in: [Headcount and full-time equivalents (Metrics)](#/metrics/two-teams), [A number one metric does not have (Metrics)](#/metrics/not-recorded), [Team, cost centre, business line (Metrics)](#/metrics/business-line) and 3 more |
1521
+ | `children` *required* | `ReactNode` | — | The result: exactly one quantity - a tree (`<Sum>`, `<Difference>`, `<Product>`, `<Quotient>` with their operands, `<Given>` as leaves) or a `<Chain>`, the two mixing freely; `<Ref>` for a quantity defined elsewhere.<br>Shown in: [Two numbers and a sum](#/calculation/first-sum), [Write a tree](#/calculation/oee), [Write a chain](#/calculation/invoice) and 48 more |
1522
+ | `metrics` | `readonly `[`Metric`](#/metrics/type-Metric)`[]` | — | Several numbers per quantity, side by side - headcount and full-time equivalents of the same teams ([ADR-0038](https://github.com/romanhaendler/umriss-ui/blob/main/docs/adr/0038-a-calculation-can-carry-several-metrics.md)). Every `value` is then an object with a number for each metric id; unit and places are the metric's. A calculation with metrics only adds and subtracts, and assesses no target or limits.<br>Shown in: [Rows of both signs with metrics (Rows from data)](#/rows-from-data/rows-of-both-signs-with-metrics), [Headcount and full-time equivalents (Metrics)](#/metrics/two-teams), [A number one metric does not have (Metrics)](#/metrics/not-recorded) and 4 more |
1409
1523
 
1410
1524
  Also takes every attribute of the rendered element – without `children`.
1411
1525
 
@@ -1426,7 +1540,7 @@ import { Sum, Difference, Product, Quotient, Ref } from "@umriss-ui/calculation"
1426
1540
 
1427
1541
  Demo page: https://romanhaendler.github.io/umriss-ui/calculation/tree/
1428
1542
 
1429
- `Sum`, `Product` and `Difference` (a − b − c) take two or more operands, `Quotient` exactly two. A quantity used twice is defined once with an `id` and stands elsewhere as a `Ref`, which shows its name and number but never its derivation again.
1543
+ `Product` and `Difference` (a − b − c) take two or more operands, `Quotient` exactly two, and `Sum` any number – rows from data, one or none included (see [Rows from data](#/rows-from-data)). A quantity used twice is defined once with an `id` and stands elsewhere as a `Ref`, which shows its name and number but never its derivation again.
1430
1544
 
1431
1545
  #### Examples
1432
1546
 
@@ -1633,22 +1747,24 @@ The keys of [Calculation](#/calculation/keyboard-calculation) apply here.
1633
1747
 
1634
1748
  | Prop | Type | Default | Description |
1635
1749
  |---|---|---|---|
1636
- | `children` | `ReactNode` | — | The operands, in order: quantities, givens and references.<br>Shown in: [Show a share against a target](#/tree/share-with-target), [Take several amounts away](#/tree/difference-of-three), [Multiply quantities with units](#/tree/product-with-units) and 29 more |
1637
- | `label` *required* | `string` | — | What the quantity is called. It stands on its line, wherever it is an operand, and in the accessible sentence. From `QuantityProps`.<br>Shown in: [Show a share against a target](#/tree/share-with-target), [Take several amounts away](#/tree/difference-of-three), [Multiply quantities with units](#/tree/product-with-units) and 34 more |
1638
- | `id` | `string` | — | Makes the quantity referable: `<Ref to>` stands for it elsewhere. Needed only for a quantity used more than once. From `QuantityProps`.<br>Shown in: [Use a quantity twice](#/tree/used-twice), [The availability of a service (Installation)](#/installation/availability), [Write a tree (Calculation)](#/calculation/oee) and 9 more |
1639
- | `unit` | `string` | — | A label written after the number - "min", "pcs", "€". Never converted and never checked; the calculation does no unit algebra. From `QuantityProps`.<br>Shown in: [Show a share against a target](#/tree/share-with-target), [Take several amounts away](#/tree/difference-of-three), [Multiply quantities with units](#/tree/product-with-units) and 28 more |
1640
- | `format` | `"percent"` | — | `percent` presents a plain ratio as per cent: 0.916 is shown as 91.6 %. The quantity stays a ratio in every operation. From `QuantityProps`.<br>Shown in: [Show a share against a target](#/tree/share-with-target), [Use a quantity twice](#/tree/used-twice), [Build operands from data](#/tree/from-data) and 16 more |
1641
- | `decimals` | `number` | one digit for a percentage, at most two for a derived number, a given as it was given | Fixed number of fraction digits as shown. Rounding happens only in presentation; every operation uses the full value. From `QuantityProps`.<br>Shown in: [Multiply quantities with units](#/tree/product-with-units), [Build operands from data](#/tree/from-data), [Hold a figure to its limits](#/tree/limits) and 18 more |
1750
+ | `children` | `ReactNode` | — | The operands, in order: quantities, givens and references.<br>Shown in: [Show a share against a target](#/tree/share-with-target), [Take several amounts away](#/tree/difference-of-three), [Multiply quantities with units](#/tree/product-with-units) and 40 more |
1751
+ | `label` *required* | `string` | — | What the quantity is called. It stands on its line, wherever it is an operand, and in the accessible sentence. From `QuantityProps`.<br>Shown in: [Show a share against a target](#/tree/share-with-target), [Take several amounts away](#/tree/difference-of-three), [Multiply quantities with units](#/tree/product-with-units) and 48 more |
1752
+ | `id` | `string` | — | Makes the quantity referable: `<Ref to>` stands for it elsewhere. Needed only for a quantity used more than once. From `QuantityProps`.<br>Shown in: [Use a quantity twice](#/tree/used-twice), [The availability of a service (Installation)](#/installation/availability), [Write a tree (Calculation)](#/calculation/oee) and 10 more |
1753
+ | `unit` | `string` | — | A label written after the number - "min", "pcs", "€". Never converted and never checked; the calculation does no unit algebra. From `QuantityProps`.<br>Shown in: [Show a share against a target](#/tree/share-with-target), [Take several amounts away](#/tree/difference-of-three), [Multiply quantities with units](#/tree/product-with-units) and 41 more |
1754
+ | `format` | `"percent"` | — | `percent` presents a plain ratio as per cent: 0.916 is shown as 91.6 %. The quantity stays a ratio in every operation. From `QuantityProps`.<br>Shown in: [Show a share against a target](#/tree/share-with-target), [Use a quantity twice](#/tree/used-twice), [Build operands from data](#/tree/from-data) and 17 more |
1755
+ | `decimals` | `number` | one digit for a percentage, at most two for a derived number, a given as it was given | Fixed number of fraction digits as shown. Rounding happens only in presentation; every operation uses the full value. From `QuantityProps`.<br>Shown in: [Multiply quantities with units](#/tree/product-with-units), [Build operands from data](#/tree/from-data), [Hold a figure to its limits](#/tree/limits) and 29 more |
1642
1756
  | `target` | `number` | — | The value this quantity is meant to reach - missed, never violated. From `QuantityProps`.<br>Shown in: [Show a share against a target](#/tree/share-with-target), [The availability of a service (Installation)](#/installation/availability), [Write a tree (Calculation)](#/calculation/oee) and 5 more |
1643
1757
  | `limits` | `readonly `[`Limit`](#type-Limit)`[]` | — | Bounds the quantity is assessed against, through core's `assess()`. From `QuantityProps`.<br>Shown in: [Hold a figure to its limits](#/tree/limits), [Hold an interim to its limits (Chain)](#/chain/error-budget), [Say where a number came from (Given)](#/given/where-it-came-from) and 4 more |
1644
1758
  | `explanation` | `string` | — | A sentence of plain text beside the line: why the quantity is here, or what it means. From `QuantityProps`.<br>Shown in: [Say where a number came from (Given)](#/given/where-it-came-from), [A number one metric does not have (Metrics)](#/metrics/not-recorded), [Staff movement as a chain (Metrics)](#/metrics/staff-movement) and 1 more |
1645
1759
  | `aside` | `ReactNode` | — | Content of the caller's own beside the line - a sparkline, a link. It never takes part in the calculation. From `QuantityProps`.<br>Shown in: [Say where a number came from (Given)](#/given/where-it-came-from) |
1760
+ | `emphasis` | `"strong" \| "muted"` | — | How much the line stands out among the others ([ADR-0049](https://github.com/romanhaendler/umriss-ui/blob/main/docs/adr/0049-a-sum-takes-rows-from-data.md)): `strong` to be read first, `muted` to recede - a muted line still counts in full. Not on the Result, which is already the heaviest line. From `QuantityProps`.<br>Shown in: [A stronger line (Calculation)](#/calculation/a-stronger-line), [A quieter line (Calculation)](#/calculation/a-quieter-line), [Emphasis inside a group (Calculation)](#/calculation/emphasis-inside-a-group) |
1761
+ | `rule` | `"above"` | — | `above` rules the line off from the ones before it, where a section starts that is not an interim. Not on the Result. From `QuantityProps`.<br>Shown in: [A rule above (Calculation)](#/calculation/a-rule-above), [Emphasis inside a group (Calculation)](#/calculation/emphasis-inside-a-group) |
1646
1762
 
1647
1763
  ##### `RefProps`
1648
1764
 
1649
1765
  | Prop | Type | Default | Description |
1650
1766
  |---|---|---|---|
1651
- | `to` *required* | `string` | — | The `id` of the quantity this reference stands for.<br>Shown in: [Use a quantity twice](#/tree/used-twice), [The availability of a service (Installation)](#/installation/availability), [Write a tree (Calculation)](#/calculation/oee) and 9 more |
1767
+ | `to` *required* | `string` | — | The `id` of the quantity this reference stands for.<br>Shown in: [Use a quantity twice](#/tree/used-twice), [The availability of a service (Installation)](#/installation/availability), [Write a tree (Calculation)](#/calculation/oee) and 10 more |
1652
1768
 
1653
1769
  ##### Types on this page
1654
1770
 
@@ -1787,7 +1903,7 @@ export default function MarkUpAndVat() {
1787
1903
 
1788
1904
  ##### Fold a group of lines into one
1789
1905
 
1790
- A chain in view never folds; to show items only on request, put them into one line as a tree: a `Sum` held by a `Minus`.
1906
+ A chain in view never folds; to show items only on request, put them into one line as a tree: a `Sum` held by a `Minus` – a `Minus`, because contributions are positive by nature. Rows of either sign from data go into a `Plus` instead; the page Rows from data shows every case.
1791
1907
 
1792
1908
  ```tsx
1793
1909
  import { Calculation, Chain, Given, Interim, Minus, Plus, Product, Ref, Sum } from "@umriss-ui/calculation";
@@ -1939,40 +2055,44 @@ The keys of [Calculation](#/calculation/keyboard-calculation) apply here.
1939
2055
 
1940
2056
  | Prop | Type | Default | Description |
1941
2057
  |---|---|---|---|
1942
- | `children` | `ReactNode` | — | The operands, top to bottom: a first quantity with no operator, then `Plus`, `Minus`, `Times` and `DividedBy` with their operands and `Interim`s naming the value where they stand. The last line is an `Interim`; a `Times` or `DividedBy` stands alone between two named values.<br>Shown in: [Take amounts away from a first quantity](#/chain/net-weight), [Mix additions and deductions](#/chain/tour-cost), [Multiply between two interims](#/chain/mark-up-and-vat) and 10 more |
2058
+ | `children` | `ReactNode` | — | The operands, top to bottom: a first quantity with no operator, then `Plus`, `Minus`, `Times` and `DividedBy` with their operands and `Interim`s naming the value where they stand. The last line is an `Interim`; a `Times` or `DividedBy` stands alone between two named values.<br>Shown in: [Take amounts away from a first quantity](#/chain/net-weight), [Mix additions and deductions](#/chain/tour-cost), [Multiply between two interims](#/chain/mark-up-and-vat) and 22 more |
1943
2059
 
1944
2060
  ##### `ChainOperandProps`
1945
2061
 
1946
2062
  | Prop | Type | Default | Description |
1947
2063
  |---|---|---|---|
1948
- | `label` | `string` | — | The operand's name, where the line is a given written in place. Left out where the line holds a quantity as its child.<br>Shown in: [Take amounts away from a first quantity](#/chain/net-weight), [Mix additions and deductions](#/chain/tour-cost), [Multiply between two interims](#/chain/mark-up-and-vat) and 7 more |
1949
- | `value` | `number \| null \| `[`MetricValues`](#type-MetricValues) | — | The operand's number, where the line is a given written in place. Absent as for a `Given`: the line and every interim after it are absent, with the reason. With `metrics`, an object by metric id, as on a `Given`.<br>Shown in: [Take amounts away from a first quantity](#/chain/net-weight), [Mix additions and deductions](#/chain/tour-cost), [Multiply between two interims](#/chain/mark-up-and-vat) and 7 more |
1950
- | `children` | `ReactNode` | — | Instead of `label` and `value`: exactly one quantity - a tree, a `<Ref>` or a `<Chain>`.<br>Shown in: [Fold a group of lines into one](#/chain/payslip), [Write a chain (Calculation)](#/calculation/invoice), [Read in German (Given)](#/given/in-german) and 3 more |
2064
+ | `label` | `string` | — | The operand's name, where the line is a given written in place. Left out where the line holds a quantity as its child.<br>Shown in: [Take amounts away from a first quantity](#/chain/net-weight), [Mix additions and deductions](#/chain/tour-cost), [Multiply between two interims](#/chain/mark-up-and-vat) and 17 more |
2065
+ | `value` | `number \| null \| `[`MetricValues`](#type-MetricValues) | — | The operand's number, where the line is a given written in place. Absent as for a `Given`: the line and every interim after it are absent, with the reason. With `metrics`, an object by metric id, as on a `Given`.<br>Shown in: [Take amounts away from a first quantity](#/chain/net-weight), [Mix additions and deductions](#/chain/tour-cost), [Multiply between two interims](#/chain/mark-up-and-vat) and 17 more |
2066
+ | `children` | `ReactNode` | — | Instead of `label` and `value`: exactly one quantity - a tree, a `<Ref>` or a `<Chain>`.<br>Shown in: [Fold a group of lines into one](#/chain/payslip), [Write a chain (Calculation)](#/calculation/invoice), [Emphasis inside a group (Calculation)](#/calculation/emphasis-inside-a-group) and 12 more |
1951
2067
  | `source` | `string` | — | Where the number came from: a system, a report, a person. From `GivenProps`.<br>Shown in: [Say where a number came from (Given)](#/given/where-it-came-from), [State when a number was true (Given)](#/given/as-of), [Staff movement as a chain (Metrics)](#/metrics/staff-movement) and 7 more |
1952
2068
  | `asOf` | `Date \| number` | — | When the number was true - not when it was fetched. From `GivenProps`.<br>Shown in: [Say where a number came from (Given)](#/given/where-it-came-from), [State when a number was true (Given)](#/given/as-of), [The cost per stop of a day's tours (Worked examples)](#/worked-examples/cost-per-tour) |
1953
2069
  | `ages` | [`FreshnessAges`](#type-FreshnessAges) | — | The ages at which `asOf` turns stale and lost. With both, the given carries a freshness through core; with `asOf` alone, only the time. From `GivenProps`.<br>Shown in: [Say where a number came from (Given)](#/given/where-it-came-from), [The cost per stop of a day's tours (Worked examples)](#/worked-examples/cost-per-tour) |
1954
- | `id` | `string` | — | Makes the quantity referable: `<Ref to>` stands for it elsewhere. Needed only for a quantity used more than once. From `QuantityProps`.<br>Shown in: [Fold a group of lines into one](#/chain/payslip), [Put a chain inside a tree](#/chain/chain-in-a-tree), [The availability of a service (Installation)](#/installation/availability) and 9 more |
1955
- | `unit` | `string` | — | A label written after the number - "min", "pcs", "€". Never converted and never checked; the calculation does no unit algebra. From `QuantityProps`.<br>Shown in: [Take amounts away from a first quantity](#/chain/net-weight), [Mix additions and deductions](#/chain/tour-cost), [Multiply between two interims](#/chain/mark-up-and-vat) and 28 more |
1956
- | `format` | `"percent"` | — | `percent` presents a plain ratio as per cent: 0.916 is shown as 91.6 %. The quantity stays a ratio in every operation. From `QuantityProps`.<br>Shown in: [Fold a group of lines into one](#/chain/payslip), [Put a chain inside a tree](#/chain/chain-in-a-tree), [Hold an interim to its limits](#/chain/error-budget) and 16 more |
1957
- | `decimals` | `number` | one digit for a percentage, at most two for a derived number, a given as it was given | Fixed number of fraction digits as shown. Rounding happens only in presentation; every operation uses the full value. From `QuantityProps`.<br>Shown in: [Take amounts away from a first quantity](#/chain/net-weight), [Mix additions and deductions](#/chain/tour-cost), [Multiply between two interims](#/chain/mark-up-and-vat) and 18 more |
2070
+ | `id` | `string` | — | Makes the quantity referable: `<Ref to>` stands for it elsewhere. Needed only for a quantity used more than once. From `QuantityProps`.<br>Shown in: [Fold a group of lines into one](#/chain/payslip), [Put a chain inside a tree](#/chain/chain-in-a-tree), [The availability of a service (Installation)](#/installation/availability) and 10 more |
2071
+ | `unit` | `string` | — | A label written after the number - "min", "pcs", "€". Never converted and never checked; the calculation does no unit algebra. From `QuantityProps`.<br>Shown in: [Take amounts away from a first quantity](#/chain/net-weight), [Mix additions and deductions](#/chain/tour-cost), [Multiply between two interims](#/chain/mark-up-and-vat) and 41 more |
2072
+ | `format` | `"percent"` | — | `percent` presents a plain ratio as per cent: 0.916 is shown as 91.6 %. The quantity stays a ratio in every operation. From `QuantityProps`.<br>Shown in: [Fold a group of lines into one](#/chain/payslip), [Put a chain inside a tree](#/chain/chain-in-a-tree), [Hold an interim to its limits](#/chain/error-budget) and 17 more |
2073
+ | `decimals` | `number` | one digit for a percentage, at most two for a derived number, a given as it was given | Fixed number of fraction digits as shown. Rounding happens only in presentation; every operation uses the full value. From `QuantityProps`.<br>Shown in: [Take amounts away from a first quantity](#/chain/net-weight), [Mix additions and deductions](#/chain/tour-cost), [Multiply between two interims](#/chain/mark-up-and-vat) and 29 more |
1958
2074
  | `target` | `number` | — | The value this quantity is meant to reach - missed, never violated. From `QuantityProps`.<br>Shown in: [Put a chain inside a tree](#/chain/chain-in-a-tree), [The availability of a service (Installation)](#/installation/availability), [Write a tree (Calculation)](#/calculation/oee) and 5 more |
1959
2075
  | `limits` | `readonly `[`Limit`](#type-Limit)`[]` | — | Bounds the quantity is assessed against, through core's `assess()`. From `QuantityProps`.<br>Shown in: [Hold an interim to its limits](#/chain/error-budget), [Hold a figure to its limits (Tree)](#/tree/limits), [Say where a number came from (Given)](#/given/where-it-came-from) and 4 more |
1960
2076
  | `explanation` | `string` | — | A sentence of plain text beside the line: why the quantity is here, or what it means. From `QuantityProps`.<br>Shown in: [Say where a number came from (Given)](#/given/where-it-came-from), [A number one metric does not have (Metrics)](#/metrics/not-recorded), [Staff movement as a chain (Metrics)](#/metrics/staff-movement) and 1 more |
1961
2077
  | `aside` | `ReactNode` | — | Content of the caller's own beside the line - a sparkline, a link. It never takes part in the calculation. From `QuantityProps`.<br>Shown in: [Say where a number came from (Given)](#/given/where-it-came-from) |
2078
+ | `emphasis` | `"strong" \| "muted"` | — | How much the line stands out among the others ([ADR-0049](https://github.com/romanhaendler/umriss-ui/blob/main/docs/adr/0049-a-sum-takes-rows-from-data.md)): `strong` to be read first, `muted` to recede - a muted line still counts in full. Not on the Result, which is already the heaviest line. From `QuantityProps`.<br>Shown in: [A stronger line (Calculation)](#/calculation/a-stronger-line), [A quieter line (Calculation)](#/calculation/a-quieter-line), [Emphasis inside a group (Calculation)](#/calculation/emphasis-inside-a-group) |
2079
+ | `rule` | `"above"` | — | `above` rules the line off from the ones before it, where a section starts that is not an interim. Not on the Result. From `QuantityProps`.<br>Shown in: [A rule above (Calculation)](#/calculation/a-rule-above), [Emphasis inside a group (Calculation)](#/calculation/emphasis-inside-a-group) |
1962
2080
 
1963
2081
  ##### `QuantityProps`
1964
2082
 
1965
2083
  | Prop | Type | Default | Description |
1966
2084
  |---|---|---|---|
1967
- | `label` *required* | `string` | — | What the quantity is called. It stands on its line, wherever it is an operand, and in the accessible sentence.<br>Shown in: [Take amounts away from a first quantity](#/chain/net-weight), [Mix additions and deductions](#/chain/tour-cost), [Multiply between two interims](#/chain/mark-up-and-vat) and 34 more |
1968
- | `id` | `string` | — | Makes the quantity referable: `<Ref to>` stands for it elsewhere. Needed only for a quantity used more than once.<br>Shown in: [Fold a group of lines into one](#/chain/payslip), [Put a chain inside a tree](#/chain/chain-in-a-tree), [The availability of a service (Installation)](#/installation/availability) and 9 more |
1969
- | `unit` | `string` | — | A label written after the number - "min", "pcs", "€". Never converted and never checked; the calculation does no unit algebra.<br>Shown in: [Take amounts away from a first quantity](#/chain/net-weight), [Mix additions and deductions](#/chain/tour-cost), [Multiply between two interims](#/chain/mark-up-and-vat) and 28 more |
1970
- | `format` | `"percent"` | — | `percent` presents a plain ratio as per cent: 0.916 is shown as 91.6 %. The quantity stays a ratio in every operation.<br>Shown in: [Fold a group of lines into one](#/chain/payslip), [Put a chain inside a tree](#/chain/chain-in-a-tree), [Hold an interim to its limits](#/chain/error-budget) and 16 more |
1971
- | `decimals` | `number` | one digit for a percentage, at most two for a derived number, a given as it was given | Fixed number of fraction digits as shown. Rounding happens only in presentation; every operation uses the full value.<br>Shown in: [Take amounts away from a first quantity](#/chain/net-weight), [Mix additions and deductions](#/chain/tour-cost), [Multiply between two interims](#/chain/mark-up-and-vat) and 18 more |
2085
+ | `label` *required* | `string` | — | What the quantity is called. It stands on its line, wherever it is an operand, and in the accessible sentence.<br>Shown in: [Take amounts away from a first quantity](#/chain/net-weight), [Mix additions and deductions](#/chain/tour-cost), [Multiply between two interims](#/chain/mark-up-and-vat) and 48 more |
2086
+ | `id` | `string` | — | Makes the quantity referable: `<Ref to>` stands for it elsewhere. Needed only for a quantity used more than once.<br>Shown in: [Fold a group of lines into one](#/chain/payslip), [Put a chain inside a tree](#/chain/chain-in-a-tree), [The availability of a service (Installation)](#/installation/availability) and 10 more |
2087
+ | `unit` | `string` | — | A label written after the number - "min", "pcs", "€". Never converted and never checked; the calculation does no unit algebra.<br>Shown in: [Take amounts away from a first quantity](#/chain/net-weight), [Mix additions and deductions](#/chain/tour-cost), [Multiply between two interims](#/chain/mark-up-and-vat) and 41 more |
2088
+ | `format` | `"percent"` | — | `percent` presents a plain ratio as per cent: 0.916 is shown as 91.6 %. The quantity stays a ratio in every operation.<br>Shown in: [Fold a group of lines into one](#/chain/payslip), [Put a chain inside a tree](#/chain/chain-in-a-tree), [Hold an interim to its limits](#/chain/error-budget) and 17 more |
2089
+ | `decimals` | `number` | one digit for a percentage, at most two for a derived number, a given as it was given | Fixed number of fraction digits as shown. Rounding happens only in presentation; every operation uses the full value.<br>Shown in: [Take amounts away from a first quantity](#/chain/net-weight), [Mix additions and deductions](#/chain/tour-cost), [Multiply between two interims](#/chain/mark-up-and-vat) and 29 more |
1972
2090
  | `target` | `number` | — | The value this quantity is meant to reach - missed, never violated.<br>Shown in: [Put a chain inside a tree](#/chain/chain-in-a-tree), [The availability of a service (Installation)](#/installation/availability), [Write a tree (Calculation)](#/calculation/oee) and 5 more |
1973
2091
  | `limits` | `readonly `[`Limit`](#type-Limit)`[]` | — | Bounds the quantity is assessed against, through core's `assess()`.<br>Shown in: [Hold an interim to its limits](#/chain/error-budget), [Hold a figure to its limits (Tree)](#/tree/limits), [Say where a number came from (Given)](#/given/where-it-came-from) and 4 more |
1974
2092
  | `explanation` | `string` | — | A sentence of plain text beside the line: why the quantity is here, or what it means.<br>Shown in: [Say where a number came from (Given)](#/given/where-it-came-from), [A number one metric does not have (Metrics)](#/metrics/not-recorded), [Staff movement as a chain (Metrics)](#/metrics/staff-movement) and 1 more |
1975
2093
  | `aside` | `ReactNode` | — | Content of the caller's own beside the line - a sparkline, a link. It never takes part in the calculation.<br>Shown in: [Say where a number came from (Given)](#/given/where-it-came-from) |
2094
+ | `emphasis` | `"strong" \| "muted"` | — | How much the line stands out among the others ([ADR-0049](https://github.com/romanhaendler/umriss-ui/blob/main/docs/adr/0049-a-sum-takes-rows-from-data.md)): `strong` to be read first, `muted` to recede - a muted line still counts in full. Not on the Result, which is already the heaviest line.<br>Shown in: [A stronger line (Calculation)](#/calculation/a-stronger-line), [A quieter line (Calculation)](#/calculation/a-quieter-line), [Emphasis inside a group (Calculation)](#/calculation/emphasis-inside-a-group) |
2095
+ | `rule` | `"above"` | — | `above` rules the line off from the ones before it, where a section starts that is not an interim. Not on the Result.<br>Shown in: [A rule above (Calculation)](#/calculation/a-rule-above), [Emphasis inside a group (Calculation)](#/calculation/emphasis-inside-a-group) |
1976
2096
 
1977
2097
  ##### Types on this page
1978
2098
 
@@ -2047,6 +2167,448 @@ type Severity = "warning" | "alarm";
2047
2167
 
2048
2168
  What umriss deliberately does not build, and why: [ADR-0032](https://romanhaendler.github.io/umriss-ui/what-umriss-ui-is-not/).
2049
2169
 
2170
+ ### Rows from data
2171
+
2172
+ Rows that come from data (line items, corrections, allowances), however many there are, as one line that folds: a payslip's corrections, an invoice's surcharges, a team's movements.
2173
+
2174
+ ```ts
2175
+ import { Sum, Plus, Minus } from "@umriss-ui/calculation";
2176
+ ```
2177
+
2178
+ Demo page: https://romanhaendler.github.io/umriss-ui/calculation/rows-from-data/
2179
+
2180
+ A `Sum` takes the rows of an array as they come: many, one, or none. With one it still folds and opens onto that one; with none it is worth zero, has nothing to open, and says "no entries" where its formula would stand. The line keeps its place either way, so the statement does not change shape with the data ([ADR-0049](https://github.com/romanhaendler/umriss-ui/blob/main/docs/adr/0049-a-sum-takes-rows-from-data.md)).
2181
+
2182
+ Rows of both signs go into the sum as they come. A line that adds or takes away shows its contribution: the direction as its operator, the number without a sign – "− Overpaid travel 120.00", never "+ -120.00". The quantity itself keeps its sign where its derivation closes, as an interim, as the result and wherever it is referenced. A factor keeps its sign; a line worth zero or missing keeps the operator it is written with.
2183
+
2184
+ `Plus` and `Minus` say how a quantity enters, the number its sign. Signed rows from data go into `Plus`; a quantity that is positive by nature and taken away – income tax, a sum of contributions – into `Minus`, so that it is never quoted as negative.
2185
+
2186
+ #### Examples
2187
+
2188
+ ##### Rows of any count
2189
+
2190
+ Hand a `Sum` the rows of an array, as they come from the data, and hold it in a `Plus` or `Minus`: the rows fold into one line, and the interim after it takes their total.
2191
+
2192
+ ```tsx
2193
+ import { Calculation, Chain, Given, Interim, Minus, Plus, Sum } from "@umriss-ui/calculation";
2194
+
2195
+ /* Data from a payroll system, written out here so the example runs on its own. */
2196
+ const ALLOWANCES = [
2197
+ { id: "night", name: "Night work bonus", amount: 84 },
2198
+ { id: "holiday", name: "Holiday pay", amount: 120 },
2199
+ { id: "on-call", name: "On-call allowance", amount: 45 },
2200
+ ];
2201
+
2202
+ export default function RowsOfAnyCount() {
2203
+ return (
2204
+ <Calculation aria-label="Payslip, March">
2205
+ <Chain>
2206
+ <Given label="Gross salary" value={4200} unit="€" decimals={2} />
2207
+ <Plus>
2208
+ <Sum label="Allowances" unit="€" decimals={2}>
2209
+ {ALLOWANCES.map((allowance) => (
2210
+ <Given key={allowance.id} label={allowance.name} value={allowance.amount} unit="€" decimals={2} />
2211
+ ))}
2212
+ </Sum>
2213
+ </Plus>
2214
+ <Minus label="Income tax" value={668.4} unit="€" decimals={2} />
2215
+ <Interim label="Net salary" unit="€" decimals={2} />
2216
+ </Chain>
2217
+ </Calculation>
2218
+ );
2219
+ }
2220
+ ```
2221
+
2222
+ ##### No rows
2223
+
2224
+ When the data holds no rows, the sum is zero and its line stays where it was: it has nothing to open and says "no entries" where its formula would stand, so a reader sees that there were none rather than wondering whether a line is missing.
2225
+
2226
+ ```tsx
2227
+ import { Calculation, Chain, Given, Interim, Minus, Plus, Sum } from "@umriss-ui/calculation";
2228
+
2229
+ /* A month without allowances: the payroll system returns an empty list. */
2230
+ const ALLOWANCES: readonly { id: string; name: string; amount: number }[] = [];
2231
+
2232
+ export default function NoRows() {
2233
+ return (
2234
+ <Calculation aria-label="Payslip, April">
2235
+ <Chain>
2236
+ <Given label="Gross salary" value={4200} unit="€" decimals={2} />
2237
+ <Plus>
2238
+ <Sum label="Allowances" unit="€" decimals={2}>
2239
+ {ALLOWANCES.map((allowance) => (
2240
+ <Given key={allowance.id} label={allowance.name} value={allowance.amount} unit="€" decimals={2} />
2241
+ ))}
2242
+ </Sum>
2243
+ </Plus>
2244
+ <Minus label="Income tax" value={612.5} unit="€" decimals={2} />
2245
+ <Interim label="Net salary" unit="€" decimals={2} />
2246
+ </Chain>
2247
+ </Calculation>
2248
+ );
2249
+ }
2250
+ ```
2251
+
2252
+ ##### One row
2253
+
2254
+ A sum of one row is still a group: its line keeps its name and folds, and opens onto that one row, closing with "= Allowances". The statement keeps its shape as the data changes, and an opened group stays open.
2255
+
2256
+ ```tsx
2257
+ import { Calculation, Chain, Given, Interim, Minus, Plus, Sum } from "@umriss-ui/calculation";
2258
+
2259
+ /* A month with a single allowance. */
2260
+ const ALLOWANCES = [{ id: "night", name: "Night work bonus", amount: 84 }];
2261
+
2262
+ export default function OneRow() {
2263
+ return (
2264
+ <Calculation aria-label="Payslip, May">
2265
+ <Chain>
2266
+ <Given label="Gross salary" value={4200} unit="€" decimals={2} />
2267
+ <Plus>
2268
+ <Sum label="Allowances" unit="€" decimals={2}>
2269
+ {ALLOWANCES.map((allowance) => (
2270
+ <Given key={allowance.id} label={allowance.name} value={allowance.amount} unit="€" decimals={2} />
2271
+ ))}
2272
+ </Sum>
2273
+ </Plus>
2274
+ <Minus label="Income tax" value={631.9} unit="€" decimals={2} />
2275
+ <Interim label="Net salary" unit="€" decimals={2} />
2276
+ </Chain>
2277
+ </Calculation>
2278
+ );
2279
+ }
2280
+ ```
2281
+
2282
+ ##### Rows of both signs
2283
+
2284
+ Rows that add and rows that take away go into one `Sum` as they come, each with its own sign. Every line shows its contribution: the direction as its operator, the number without a sign – a correction of −120 stands as "− 120.00", never as "+ -120.00".
2285
+
2286
+ ```tsx
2287
+ import { Calculation, Chain, Given, Interim, Minus, Plus, Sum } from "@umriss-ui/calculation";
2288
+
2289
+ /* Corrections from a payroll system: positive adds to the pay, negative takes from it. */
2290
+ const CORRECTIONS = [
2291
+ { id: "night", name: "Night work bonus, February", amount: 84 },
2292
+ { id: "travel", name: "Overpaid travel, February", amount: -120 },
2293
+ { id: "rounding", name: "Rounding", amount: 0.03 },
2294
+ ];
2295
+
2296
+ export default function RowsOfBothSigns() {
2297
+ return (
2298
+ <Calculation aria-label="Payslip, March">
2299
+ <Chain>
2300
+ <Given label="Gross salary" value={4200} unit="€" decimals={2} />
2301
+ <Minus label="Income tax" value={612.5} unit="€" decimals={2} />
2302
+ <Plus>
2303
+ <Sum label="Corrections" unit="€" decimals={2}>
2304
+ {CORRECTIONS.map((correction) => (
2305
+ <Given key={correction.id} label={correction.name} value={correction.amount} unit="€" decimals={2} />
2306
+ ))}
2307
+ </Sum>
2308
+ </Plus>
2309
+ <Interim label="Net salary" unit="€" decimals={2} />
2310
+ </Chain>
2311
+ </Calculation>
2312
+ );
2313
+ }
2314
+ ```
2315
+
2316
+ ##### A group that turns negative
2317
+
2318
+ Held by a `Plus`, a group whose total is negative stands as a minus with its number unsigned: "− Corrections 36.00". Opened, its derivation closes with the quantity itself, sign and all: "= Corrections -36.00". The line says what it does to the pay, the closing row what the corrections amount to.
2319
+
2320
+ ```tsx
2321
+ import { Calculation, Chain, Given, Interim, Minus, Plus, Sum } from "@umriss-ui/calculation";
2322
+
2323
+ const CORRECTIONS = [
2324
+ { id: "night", name: "Night work bonus, February", amount: 84 },
2325
+ { id: "travel", name: "Overpaid travel, February", amount: -120 },
2326
+ ];
2327
+
2328
+ export default function AGroupThatTurnsNegative() {
2329
+ return (
2330
+ <Calculation aria-label="Payslip, March">
2331
+ <Chain>
2332
+ <Given label="Gross salary" value={4200} unit="€" decimals={2} />
2333
+ <Minus label="Income tax" value={612.5} unit="€" decimals={2} />
2334
+ <Plus>
2335
+ <Sum label="Corrections" unit="€" decimals={2}>
2336
+ {CORRECTIONS.map((correction) => (
2337
+ <Given key={correction.id} label={correction.name} value={correction.amount} unit="€" decimals={2} />
2338
+ ))}
2339
+ </Sum>
2340
+ </Plus>
2341
+ <Interim label="Net salary" unit="€" decimals={2} />
2342
+ </Chain>
2343
+ </Calculation>
2344
+ );
2345
+ }
2346
+ ```
2347
+
2348
+ ##### Plus or Minus
2349
+
2350
+ `Plus` and `Minus` say how a quantity enters, the number says its sign. Signed rows from data go into `Plus`: their signs do the rest. A quantity that is positive by nature and taken away here – income tax, a sum of contributions – goes into `Minus`, so that it keeps its sign where it closes and wherever it is referenced.
2351
+
2352
+ ```tsx
2353
+ import { Calculation, Chain, Given, Interim, Minus, Plus, Product, Ref, Sum } from "@umriss-ui/calculation";
2354
+
2355
+ const CONTRIBUTIONS = [
2356
+ { name: "Pension insurance", rate: 0.093 },
2357
+ { name: "Health insurance", rate: 0.082 },
2358
+ ];
2359
+
2360
+ const CORRECTIONS = [
2361
+ { id: "night", name: "Night work bonus, February", amount: 84 },
2362
+ { id: "travel", name: "Overpaid travel, February", amount: -120 },
2363
+ ];
2364
+
2365
+ export default function PlusOrMinus() {
2366
+ return (
2367
+ <Calculation aria-label="Payslip, March">
2368
+ <Chain>
2369
+ <Given id="gross" label="Gross salary" value={4200} unit="€" decimals={2} />
2370
+ <Minus label="Income tax" value={612.5} unit="€" decimals={2} />
2371
+ <Minus>
2372
+ <Sum label="Social security contributions" unit="€" decimals={2}>
2373
+ {CONTRIBUTIONS.map((contribution) => (
2374
+ <Product key={contribution.name} label={contribution.name} unit="€" decimals={2}>
2375
+ <Given label={`Rate, ${contribution.name.toLowerCase()}`} value={contribution.rate} format="percent" />
2376
+ <Ref to="gross" />
2377
+ </Product>
2378
+ ))}
2379
+ </Sum>
2380
+ </Minus>
2381
+ <Plus>
2382
+ <Sum label="Corrections" unit="€" decimals={2}>
2383
+ {CORRECTIONS.map((correction) => (
2384
+ <Given key={correction.id} label={correction.name} value={correction.amount} unit="€" decimals={2} />
2385
+ ))}
2386
+ </Sum>
2387
+ </Plus>
2388
+ <Interim label="Net salary" unit="€" decimals={2} />
2389
+ </Chain>
2390
+ </Calculation>
2391
+ );
2392
+ }
2393
+ ```
2394
+
2395
+ ##### A deduction first
2396
+
2397
+ The first operand of a sum stands without an operator – unless it lowers the sum: then it carries a minus like every other deduction. A folded line's formula starts with that minus too – "A sum from data in a tree" below shows one.
2398
+
2399
+ ```tsx
2400
+ import { Calculation, Given, Sum } from "@umriss-ui/calculation";
2401
+
2402
+ const ROWS = [
2403
+ { id: "refund", name: "Refund, order 1184", amount: -30 },
2404
+ { id: "bonus", name: "Loyalty bonus", amount: 12 },
2405
+ { id: "voucher", name: "Voucher", amount: 5 },
2406
+ ];
2407
+
2408
+ export default function ADeductionFirst() {
2409
+ return (
2410
+ <Calculation aria-label="Customer account, March">
2411
+ <Sum label="Balance" unit="€" decimals={2}>
2412
+ {ROWS.map((row) => (
2413
+ <Given key={row.id} label={row.name} value={row.amount} unit="€" decimals={2} />
2414
+ ))}
2415
+ </Sum>
2416
+ </Calculation>
2417
+ );
2418
+ }
2419
+ ```
2420
+
2421
+ ##### Zero and missing keep their sign
2422
+
2423
+ A row worth zero has no direction, and a missing row has no number: both keep the operator they are written with. The missing row makes the group and everything after it absent, with the reason – never zero.
2424
+
2425
+ ```tsx
2426
+ import { Calculation, Chain, Given, Interim, Minus, Plus, Sum } from "@umriss-ui/calculation";
2427
+
2428
+ const CORRECTIONS: readonly { id: string; name: string; amount: number | null }[] = [
2429
+ { id: "night", name: "Night work bonus, February", amount: 84 },
2430
+ { id: "travel", name: "Travel, February", amount: 0 },
2431
+ { id: "overtime", name: "Overtime, February", amount: null },
2432
+ ];
2433
+
2434
+ export default function ZeroAndMissingKeepTheirSign() {
2435
+ return (
2436
+ <Calculation aria-label="Payslip, March">
2437
+ <Chain>
2438
+ <Given label="Gross salary" value={4200} unit="€" decimals={2} />
2439
+ <Minus label="Income tax" value={612.5} unit="€" decimals={2} />
2440
+ <Plus>
2441
+ <Sum label="Corrections" unit="€" decimals={2}>
2442
+ {CORRECTIONS.map((correction) => (
2443
+ <Given key={correction.id} label={correction.name} value={correction.amount} unit="€" decimals={2} />
2444
+ ))}
2445
+ </Sum>
2446
+ </Plus>
2447
+ <Interim label="Net salary" unit="€" decimals={2} />
2448
+ </Chain>
2449
+ </Calculation>
2450
+ );
2451
+ }
2452
+ ```
2453
+
2454
+ ##### A sum from data in a tree
2455
+
2456
+ Rows from data work in a tree as in a chain: here the stock movements of a day, whatever their count and sign, stand as one operand of a `Difference`. Taken away, a negative total turns into a plus – "+ Movements 7" – and the derivation closes with its own sign.
2457
+
2458
+ ```tsx
2459
+ import { Calculation, Difference, Given, Sum } from "@umriss-ui/calculation";
2460
+
2461
+ const MOVEMENTS = [
2462
+ { id: "m1", name: "Picked, order 5512", amount: -12 },
2463
+ { id: "m2", name: "Received, delivery 881", amount: 40 },
2464
+ { id: "m3", name: "Picked, order 5517", amount: -35 },
2465
+ ];
2466
+
2467
+ export default function ASumFromDataInATree() {
2468
+ return (
2469
+ <Calculation aria-label="Shelf B-14, 17 March">
2470
+ <Difference label="Gap to plan" unit="pcs">
2471
+ <Given label="Planned stock" value={150} unit="pcs" />
2472
+ <Given label="Stock this morning" value={142} unit="pcs" />
2473
+ <Sum label="Movements" unit="pcs">
2474
+ {MOVEMENTS.map((movement) => (
2475
+ <Given key={movement.id} label={movement.name} value={movement.amount} unit="pcs" />
2476
+ ))}
2477
+ </Sum>
2478
+ </Difference>
2479
+ </Calculation>
2480
+ );
2481
+ }
2482
+ ```
2483
+
2484
+ ##### Rows of both signs with metrics
2485
+
2486
+ With metrics a line has one operator and a number per metric. Where they all point the same way, the line shows its contribution as everywhere else; a metric that is zero or missing does not count. Where they point in different directions – a part-timer joins: one more head, half a position less – the line keeps its written operator and every number its sign.
2487
+
2488
+ ```tsx
2489
+ import { Calculation, Chain, Given, Interim, Plus, Sum } from "@umriss-ui/calculation";
2490
+ import type { Metric } from "@umriss-ui/calculation";
2491
+
2492
+ const STAFF: readonly Metric[] = [
2493
+ { id: "heads", label: "Headcount", unit: "HC", decimals: 0 },
2494
+ { id: "fte", label: "Full-time equivalents", unit: "FTE", decimals: 1 },
2495
+ ];
2496
+
2497
+ /* The quarter's movements from the HR system. */
2498
+ const MOVEMENTS = [
2499
+ { id: "sales", name: "Transferred to sales", heads: -4, fte: -3.5 },
2500
+ { id: "hours", name: "Hours reduced", heads: 0, fte: -1.5 },
2501
+ { id: "part-time", name: "Full-timer replaced by two part-timers", heads: 1, fte: -0.5 },
2502
+ { id: "joiners", name: "Joiners", heads: 6, fte: 5.8 },
2503
+ ];
2504
+
2505
+ export default function RowsOfBothSignsWithMetrics() {
2506
+ return (
2507
+ <Calculation aria-label="Staff movement, logistics, third quarter" metrics={STAFF}>
2508
+ <Chain>
2509
+ <Given label="Staff on 30 June" value={{ heads: 64, fte: 48.9 }} />
2510
+ <Plus>
2511
+ <Sum label="Movements">
2512
+ {MOVEMENTS.map((movement) => (
2513
+ <Given key={movement.id} label={movement.name} value={{ heads: movement.heads, fte: movement.fte }} />
2514
+ ))}
2515
+ </Sum>
2516
+ </Plus>
2517
+ <Interim label="Staff on 30 September" />
2518
+ </Chain>
2519
+ </Calculation>
2520
+ );
2521
+ }
2522
+ ```
2523
+
2524
+ #### When to use something else
2525
+
2526
+ - A fixed set of lines that is always in view → Chain
2527
+
2528
+ #### Keyboard
2529
+
2530
+ The keys of [Calculation](#/calculation/keyboard-calculation) apply here.
2531
+
2532
+ #### Props on this page
2533
+
2534
+ From `CalculationProps` — the full table stands on [Calculation](#/calculation/type-CalculationProps).
2535
+
2536
+ | Prop | Type | Default | Description |
2537
+ |---|---|---|---|
2538
+ | [`children`](#/calculation/CalculationProps-children) *required* | `ReactNode` | — | The result: exactly one quantity - a tree (`<Sum>`, `<Difference>`, `<Product>`, `<Quotient>` with their operands, `<Given>` as leaves) or a `<Chain>`, the two mixing freely; `<Ref>` for a quantity defined elsewhere. |
2539
+ | [`metrics`](#/calculation/CalculationProps-metrics) | `readonly `[`Metric`](#/metrics/type-Metric)`[]` | — | Several numbers per quantity, side by side - headcount and full-time equivalents of the same teams ([ADR-0038](https://github.com/romanhaendler/umriss-ui/blob/main/docs/adr/0038-a-calculation-can-carry-several-metrics.md)). Every `value` is then an object with a number for each metric id; unit and places are the metric's. A calculation with metrics only adds and subtracts, and assesses no target or limits. |
2540
+
2541
+ From `OperatorProps` — the full table stands on [Tree](#/tree/type-OperatorProps).
2542
+
2543
+ | Prop | Type | Default | Description |
2544
+ |---|---|---|---|
2545
+ | [`children`](#/tree/OperatorProps-children) | `ReactNode` | — | The operands, in order: quantities, givens and references. |
2546
+ | [`label`](#/tree/OperatorProps-label) *required* | `string` | — | What the quantity is called. It stands on its line, wherever it is an operand, and in the accessible sentence. From `QuantityProps`. |
2547
+ | [`id`](#/tree/OperatorProps-id) | `string` | — | Makes the quantity referable: `<Ref to>` stands for it elsewhere. Needed only for a quantity used more than once. From `QuantityProps`. |
2548
+ | [`unit`](#/tree/OperatorProps-unit) | `string` | — | A label written after the number - "min", "pcs", "€". Never converted and never checked; the calculation does no unit algebra. From `QuantityProps`. |
2549
+ | [`format`](#/tree/OperatorProps-format) | `"percent"` | — | `percent` presents a plain ratio as per cent: 0.916 is shown as 91.6 %. The quantity stays a ratio in every operation. From `QuantityProps`. |
2550
+ | [`decimals`](#/tree/OperatorProps-decimals) | `number` | one digit for a percentage, at most two for a derived number, a given as it was given | Fixed number of fraction digits as shown. Rounding happens only in presentation; every operation uses the full value. From `QuantityProps`. |
2551
+
2552
+ From `RefProps` — the full table stands on [Tree](#/tree/type-RefProps).
2553
+
2554
+ | Prop | Type | Default | Description |
2555
+ |---|---|---|---|
2556
+ | [`to`](#/tree/RefProps-to) *required* | `string` | — | The `id` of the quantity this reference stands for. |
2557
+
2558
+ From `ChainProps` — the full table stands on [Chain](#/chain/type-ChainProps).
2559
+
2560
+ | Prop | Type | Default | Description |
2561
+ |---|---|---|---|
2562
+ | [`children`](#/chain/ChainProps-children) | `ReactNode` | — | The operands, top to bottom: a first quantity with no operator, then `Plus`, `Minus`, `Times` and `DividedBy` with their operands and `Interim`s naming the value where they stand. The last line is an `Interim`; a `Times` or `DividedBy` stands alone between two named values. |
2563
+
2564
+ From `ChainOperandProps` — the full table stands on [Chain](#/chain/type-ChainOperandProps).
2565
+
2566
+ | Prop | Type | Default | Description |
2567
+ |---|---|---|---|
2568
+ | [`label`](#/chain/ChainOperandProps-label) | `string` | — | The operand's name, where the line is a given written in place. Left out where the line holds a quantity as its child. |
2569
+ | [`value`](#/chain/ChainOperandProps-value) | `number \| null \| `[`MetricValues`](#/chain/type-MetricValues) | — | The operand's number, where the line is a given written in place. Absent as for a `Given`: the line and every interim after it are absent, with the reason. With `metrics`, an object by metric id, as on a `Given`. |
2570
+ | [`children`](#/chain/ChainOperandProps-children) | `ReactNode` | — | Instead of `label` and `value`: exactly one quantity - a tree, a `<Ref>` or a `<Chain>`. |
2571
+ | [`id`](#/chain/ChainOperandProps-id) | `string` | — | Makes the quantity referable: `<Ref to>` stands for it elsewhere. Needed only for a quantity used more than once. From `QuantityProps`. |
2572
+ | [`unit`](#/chain/ChainOperandProps-unit) | `string` | — | A label written after the number - "min", "pcs", "€". Never converted and never checked; the calculation does no unit algebra. From `QuantityProps`. |
2573
+ | [`format`](#/chain/ChainOperandProps-format) | `"percent"` | — | `percent` presents a plain ratio as per cent: 0.916 is shown as 91.6 %. The quantity stays a ratio in every operation. From `QuantityProps`. |
2574
+ | [`decimals`](#/chain/ChainOperandProps-decimals) | `number` | one digit for a percentage, at most two for a derived number, a given as it was given | Fixed number of fraction digits as shown. Rounding happens only in presentation; every operation uses the full value. From `QuantityProps`. |
2575
+
2576
+ From `QuantityProps` — the full table stands on [Chain](#/chain/type-QuantityProps).
2577
+
2578
+ | Prop | Type | Default | Description |
2579
+ |---|---|---|---|
2580
+ | [`label`](#/chain/QuantityProps-label) *required* | `string` | — | What the quantity is called. It stands on its line, wherever it is an operand, and in the accessible sentence. |
2581
+ | [`id`](#/chain/QuantityProps-id) | `string` | — | Makes the quantity referable: `<Ref to>` stands for it elsewhere. Needed only for a quantity used more than once. |
2582
+ | [`unit`](#/chain/QuantityProps-unit) | `string` | — | A label written after the number - "min", "pcs", "€". Never converted and never checked; the calculation does no unit algebra. |
2583
+ | [`format`](#/chain/QuantityProps-format) | `"percent"` | — | `percent` presents a plain ratio as per cent: 0.916 is shown as 91.6 %. The quantity stays a ratio in every operation. |
2584
+ | [`decimals`](#/chain/QuantityProps-decimals) | `number` | one digit for a percentage, at most two for a derived number, a given as it was given | Fixed number of fraction digits as shown. Rounding happens only in presentation; every operation uses the full value. |
2585
+
2586
+ From `GivenProps` — the full table stands on [Given](#/given/type-GivenProps).
2587
+
2588
+ | Prop | Type | Default | Description |
2589
+ |---|---|---|---|
2590
+ | [`value`](#/given/GivenProps-value) *required* | `number \| null \| undefined \| `[`MetricValues`](#/given/type-MetricValues) | — | The number the calculation starts from. Absent (`null`, `undefined`, not finite) makes every quantity that depends on it absent, with the reason - never zero. Where the calculation has `metrics`, an object with a number for each metric id instead; absence then stays in its metric. |
2591
+ | [`label`](#/given/GivenProps-label) *required* | `string` | — | What the quantity is called. It stands on its line, wherever it is an operand, and in the accessible sentence. From `QuantityProps`. |
2592
+ | [`id`](#/given/GivenProps-id) | `string` | — | Makes the quantity referable: `<Ref to>` stands for it elsewhere. Needed only for a quantity used more than once. From `QuantityProps`. |
2593
+ | [`unit`](#/given/GivenProps-unit) | `string` | — | A label written after the number - "min", "pcs", "€". Never converted and never checked; the calculation does no unit algebra. From `QuantityProps`. |
2594
+ | [`format`](#/given/GivenProps-format) | `"percent"` | — | `percent` presents a plain ratio as per cent: 0.916 is shown as 91.6 %. The quantity stays a ratio in every operation. From `QuantityProps`. |
2595
+ | [`decimals`](#/given/GivenProps-decimals) | `number` | one digit for a percentage, at most two for a derived number, a given as it was given | Fixed number of fraction digits as shown. Rounding happens only in presentation; every operation uses the full value. From `QuantityProps`. |
2596
+
2597
+ From `Metric` — the full table stands on [Metrics](#/metrics/type-Metric).
2598
+
2599
+ | Prop | Type | Default | Description |
2600
+ |---|---|---|---|
2601
+ | [`id`](#/metrics/Metric-id) *required* | `string` | — | The key of this metric's number in every `value` object. |
2602
+ | [`label`](#/metrics/Metric-label) *required* | `string` | — | The metric's name, in the head above its column and in each row's sentence. |
2603
+ | [`unit`](#/metrics/Metric-unit) | `string` | — | A label written after the number where a result closes, and beneath the metric's name in the head. Never converted and never checked. |
2604
+ | [`decimals`](#/metrics/Metric-decimals) | `number` | a given as it was given, at most two for a derived number | Fixed number of fraction digits as shown, for every quantity of this metric. |
2605
+
2606
+ #### Known limits
2607
+
2608
+ - Only a sum takes any count: an empty product, a difference of one and a quotient of anything but two still fail on the first render.
2609
+
2610
+ What umriss deliberately does not build, and why: [ADR-0032](https://romanhaendler.github.io/umriss-ui/what-umriss-ui-is-not/).
2611
+
2050
2612
  ### Given
2051
2613
 
2052
2614
  The numbers a calculation starts from (inputs, leaves): where they came from, when they were true, and whether they are still fresh.
@@ -2152,19 +2714,21 @@ The keys of [Calculation](#/calculation/keyboard-calculation) apply here.
2152
2714
 
2153
2715
  | Prop | Type | Default | Description |
2154
2716
  |---|---|---|---|
2155
- | `value` *required* | `number \| null \| undefined \| `[`MetricValues`](#type-MetricValues) | — | The number the calculation starts from. Absent (`null`, `undefined`, not finite) makes every quantity that depends on it absent, with the reason - never zero. Where the calculation has `metrics`, an object with a number for each metric id instead; absence then stays in its metric.<br>Shown in: [Say where a number came from](#/given/where-it-came-from), [State when a number was true](#/given/as-of), [Read in German](#/given/in-german) and 34 more |
2717
+ | `value` *required* | `number \| null \| undefined \| `[`MetricValues`](#type-MetricValues) | — | The number the calculation starts from. Absent (`null`, `undefined`, not finite) makes every quantity that depends on it absent, with the reason - never zero. Where the calculation has `metrics`, an object with a number for each metric id instead; absence then stays in its metric.<br>Shown in: [Say where a number came from](#/given/where-it-came-from), [State when a number was true](#/given/as-of), [Read in German](#/given/in-german) and 48 more |
2156
2718
  | `source` | `string` | — | Where the number came from: a system, a report, a person.<br>Shown in: [Say where a number came from](#/given/where-it-came-from), [State when a number was true](#/given/as-of), [Staff movement as a chain (Metrics)](#/metrics/staff-movement) and 7 more |
2157
2719
  | `asOf` | `Date \| number` | — | When the number was true - not when it was fetched.<br>Shown in: [Say where a number came from](#/given/where-it-came-from), [State when a number was true](#/given/as-of), [The cost per stop of a day's tours (Worked examples)](#/worked-examples/cost-per-tour) |
2158
2720
  | `ages` | [`FreshnessAges`](#type-FreshnessAges) | — | The ages at which `asOf` turns stale and lost. With both, the given carries a freshness through core; with `asOf` alone, only the time.<br>Shown in: [Say where a number came from](#/given/where-it-came-from), [The cost per stop of a day's tours (Worked examples)](#/worked-examples/cost-per-tour) |
2159
- | `label` *required* | `string` | — | What the quantity is called. It stands on its line, wherever it is an operand, and in the accessible sentence. From `QuantityProps`.<br>Shown in: [Say where a number came from](#/given/where-it-came-from), [State when a number was true](#/given/as-of), [Read in German](#/given/in-german) and 34 more |
2160
- | `id` | `string` | — | Makes the quantity referable: `<Ref to>` stands for it elsewhere. Needed only for a quantity used more than once. From `QuantityProps`.<br>Shown in: [Read in German](#/given/in-german), [The availability of a service (Installation)](#/installation/availability), [Write a tree (Calculation)](#/calculation/oee) and 9 more |
2161
- | `unit` | `string` | — | A label written after the number - "min", "pcs", "€". Never converted and never checked; the calculation does no unit algebra. From `QuantityProps`.<br>Shown in: [Say where a number came from](#/given/where-it-came-from), [State when a number was true](#/given/as-of), [Read in German](#/given/in-german) and 28 more |
2162
- | `format` | `"percent"` | — | `percent` presents a plain ratio as per cent: 0.916 is shown as 91.6 %. The quantity stays a ratio in every operation. From `QuantityProps`.<br>Shown in: [Say where a number came from](#/given/where-it-came-from), [Read in German](#/given/in-german), [The availability of a service (Installation)](#/installation/availability) and 16 more |
2163
- | `decimals` | `number` | one digit for a percentage, at most two for a derived number, a given as it was given | Fixed number of fraction digits as shown. Rounding happens only in presentation; every operation uses the full value. From `QuantityProps`.<br>Shown in: [Say where a number came from](#/given/where-it-came-from), [State when a number was true](#/given/as-of), [Read in German](#/given/in-german) and 18 more |
2721
+ | `label` *required* | `string` | — | What the quantity is called. It stands on its line, wherever it is an operand, and in the accessible sentence. From `QuantityProps`.<br>Shown in: [Say where a number came from](#/given/where-it-came-from), [State when a number was true](#/given/as-of), [Read in German](#/given/in-german) and 48 more |
2722
+ | `id` | `string` | — | Makes the quantity referable: `<Ref to>` stands for it elsewhere. Needed only for a quantity used more than once. From `QuantityProps`.<br>Shown in: [Read in German](#/given/in-german), [The availability of a service (Installation)](#/installation/availability), [Write a tree (Calculation)](#/calculation/oee) and 10 more |
2723
+ | `unit` | `string` | — | A label written after the number - "min", "pcs", "€". Never converted and never checked; the calculation does no unit algebra. From `QuantityProps`.<br>Shown in: [Say where a number came from](#/given/where-it-came-from), [State when a number was true](#/given/as-of), [Read in German](#/given/in-german) and 41 more |
2724
+ | `format` | `"percent"` | — | `percent` presents a plain ratio as per cent: 0.916 is shown as 91.6 %. The quantity stays a ratio in every operation. From `QuantityProps`.<br>Shown in: [Say where a number came from](#/given/where-it-came-from), [Read in German](#/given/in-german), [The availability of a service (Installation)](#/installation/availability) and 17 more |
2725
+ | `decimals` | `number` | one digit for a percentage, at most two for a derived number, a given as it was given | Fixed number of fraction digits as shown. Rounding happens only in presentation; every operation uses the full value. From `QuantityProps`.<br>Shown in: [Say where a number came from](#/given/where-it-came-from), [State when a number was true](#/given/as-of), [Read in German](#/given/in-german) and 29 more |
2164
2726
  | `target` | `number` | — | The value this quantity is meant to reach - missed, never violated. From `QuantityProps`.<br>Shown in: [The availability of a service (Installation)](#/installation/availability), [Write a tree (Calculation)](#/calculation/oee), [Show a share against a target (Tree)](#/tree/share-with-target) and 5 more |
2165
2727
  | `limits` | `readonly `[`Limit`](#type-Limit)`[]` | — | Bounds the quantity is assessed against, through core's `assess()`. From `QuantityProps`.<br>Shown in: [Say where a number came from](#/given/where-it-came-from), [Hold a figure to its limits (Tree)](#/tree/limits), [Hold an interim to its limits (Chain)](#/chain/error-budget) and 4 more |
2166
2728
  | `explanation` | `string` | — | A sentence of plain text beside the line: why the quantity is here, or what it means. From `QuantityProps`.<br>Shown in: [Say where a number came from](#/given/where-it-came-from), [A number one metric does not have (Metrics)](#/metrics/not-recorded), [Staff movement as a chain (Metrics)](#/metrics/staff-movement) and 1 more |
2167
2729
  | `aside` | `ReactNode` | — | Content of the caller's own beside the line - a sparkline, a link. It never takes part in the calculation. From `QuantityProps`.<br>Shown in: [Say where a number came from](#/given/where-it-came-from) |
2730
+ | `emphasis` | `"strong" \| "muted"` | — | How much the line stands out among the others ([ADR-0049](https://github.com/romanhaendler/umriss-ui/blob/main/docs/adr/0049-a-sum-takes-rows-from-data.md)): `strong` to be read first, `muted` to recede - a muted line still counts in full. Not on the Result, which is already the heaviest line. From `QuantityProps`.<br>Shown in: [A stronger line (Calculation)](#/calculation/a-stronger-line), [A quieter line (Calculation)](#/calculation/a-quieter-line), [Emphasis inside a group (Calculation)](#/calculation/emphasis-inside-a-group) |
2731
+ | `rule` | `"above"` | — | `above` rules the line off from the ones before it, where a section starts that is not an interim. Not on the Result. From `QuantityProps`.<br>Shown in: [A rule above (Calculation)](#/calculation/a-rule-above), [Emphasis inside a group (Calculation)](#/calculation/emphasis-inside-a-group) |
2168
2732
 
2169
2733
  ##### Types on this page
2170
2734
 
@@ -2689,10 +3253,10 @@ The keys of [Calculation](#/calculation/keyboard-calculation) apply here.
2689
3253
 
2690
3254
  | Prop | Type | Default | Description |
2691
3255
  |---|---|---|---|
2692
- | `id` *required* | `string` | — | The key of this metric's number in every `value` object.<br>Shown in: [Headcount and full-time equivalents](#/metrics/two-teams), [A number one metric does not have](#/metrics/not-recorded), [Team, cost centre, business line](#/metrics/business-line) and 3 more |
2693
- | `label` *required* | `string` | — | The metric's name, in the head above its column and in each row's sentence.<br>Shown in: [Headcount and full-time equivalents](#/metrics/two-teams), [A number one metric does not have](#/metrics/not-recorded), [Team, cost centre, business line](#/metrics/business-line) and 3 more |
2694
- | `unit` | `string` | — | A label written after the number where a result closes, and beneath the metric's name in the head. Never converted and never checked.<br>Shown in: [Headcount and full-time equivalents](#/metrics/two-teams), [A number one metric does not have](#/metrics/not-recorded), [Team, cost centre, business line](#/metrics/business-line) and 3 more |
2695
- | `decimals` | `number` | a given as it was given, at most two for a derived number | Fixed number of fraction digits as shown, for every quantity of this metric.<br>Shown in: [Headcount and full-time equivalents](#/metrics/two-teams), [A number one metric does not have](#/metrics/not-recorded), [Team, cost centre, business line](#/metrics/business-line) and 3 more |
3256
+ | `id` *required* | `string` | — | The key of this metric's number in every `value` object.<br>Shown in: [Headcount and full-time equivalents](#/metrics/two-teams), [A number one metric does not have](#/metrics/not-recorded), [Team, cost centre, business line](#/metrics/business-line) and 4 more |
3257
+ | `label` *required* | `string` | — | The metric's name, in the head above its column and in each row's sentence.<br>Shown in: [Headcount and full-time equivalents](#/metrics/two-teams), [A number one metric does not have](#/metrics/not-recorded), [Team, cost centre, business line](#/metrics/business-line) and 4 more |
3258
+ | `unit` | `string` | — | A label written after the number where a result closes, and beneath the metric's name in the head. Never converted and never checked.<br>Shown in: [Headcount and full-time equivalents](#/metrics/two-teams), [A number one metric does not have](#/metrics/not-recorded), [Team, cost centre, business line](#/metrics/business-line) and 4 more |
3259
+ | `decimals` | `number` | a given as it was given, at most two for a derived number | Fixed number of fraction digits as shown, for every quantity of this metric.<br>Shown in: [Headcount and full-time equivalents](#/metrics/two-teams), [A number one metric does not have](#/metrics/not-recorded), [Team, cost centre, business line](#/metrics/business-line) and 4 more |
2696
3260
 
2697
3261
  #### Known limits
2698
3262
 
@@ -3448,13 +4012,13 @@ Demo page: https://romanhaendler.github.io/umriss-ui/calculation/api/
3448
4012
 
3449
4013
  [Calculation](#/calculation) – Lets a reader follow and redo a figure (also called a KPI tree or calculation tree): each line a quantity with its operator, derived lines folded until opened beneath themselves. Reach for it where a number on the screen gets questioned: a cost, an availability, an invoice total.
3450
4014
 
3451
- Used on [Scenarios](#/), [Installation](#/installation), [Calculation](#/calculation), [Tree](#/tree), [Chain](#/chain), [Given](#/given), [Metrics](#/metrics), [What can go wrong](#/what-can-go-wrong) and [Worked examples](#/worked-examples).
4015
+ Used on [Scenarios](#/), [Installation](#/installation), [Calculation](#/calculation), [Tree](#/tree), [Chain](#/chain), [Rows from data](#/rows-from-data), [Given](#/given), [Metrics](#/metrics), [What can go wrong](#/what-can-go-wrong) and [Worked examples](#/worked-examples).
3452
4016
 
3453
4017
  ##### `Chain`
3454
4018
 
3455
4019
  [Chain](#/chain) – A sheet read top to bottom (a running calculation): each line worked into the value before it, and interims naming the value where they stand. Reach for it for invoices, budgets and cost sheets.
3456
4020
 
3457
- Used on [Calculation](#/calculation), [Chain](#/chain), [Given](#/given), [Metrics](#/metrics), [What can go wrong](#/what-can-go-wrong) and [Worked examples](#/worked-examples).
4021
+ Used on [Calculation](#/calculation), [Chain](#/chain), [Rows from data](#/rows-from-data), [Given](#/given), [Metrics](#/metrics), [What can go wrong](#/what-can-go-wrong) and [Worked examples](#/worked-examples).
3458
4022
 
3459
4023
  ##### `Difference`
3460
4024
 
@@ -3464,7 +4028,7 @@ The first operand minus every other: a − b − c.
3464
4028
  const Difference: (props: OperatorProps) => null;
3465
4029
  ```
3466
4030
 
3467
- Used on [Scenarios](#/), [Installation](#/installation), [Calculation](#/calculation), [Tree](#/tree) and [Worked examples](#/worked-examples).
4031
+ Used on [Scenarios](#/), [Installation](#/installation), [Calculation](#/calculation), [Tree](#/tree), [Rows from data](#/rows-from-data) and [Worked examples](#/worked-examples).
3468
4032
 
3469
4033
  ##### `DividedBy`
3470
4034
 
@@ -3480,7 +4044,7 @@ Used on [Chain](#/chain), [Metrics](#/metrics) and [Worked examples](#/worked-ex
3480
4044
 
3481
4045
  [Given](#/given) – The numbers a calculation starts from (inputs, leaves): where they came from, when they were true, and whether they are still fresh.
3482
4046
 
3483
- Used on [Scenarios](#/), [Installation](#/installation), [Calculation](#/calculation), [Tree](#/tree), [Chain](#/chain), [Given](#/given), [Metrics](#/metrics), [What can go wrong](#/what-can-go-wrong) and [Worked examples](#/worked-examples).
4047
+ Used on [Scenarios](#/), [Installation](#/installation), [Calculation](#/calculation), [Tree](#/tree), [Chain](#/chain), [Rows from data](#/rows-from-data), [Given](#/given), [Metrics](#/metrics), [What can go wrong](#/what-can-go-wrong) and [Worked examples](#/worked-examples).
3484
4048
 
3485
4049
  ##### `Interim`
3486
4050
 
@@ -3490,7 +4054,7 @@ Names the value of a chain where it stands.
3490
4054
  const Interim: (props: QuantityProps) => null;
3491
4055
  ```
3492
4056
 
3493
- Used on [Calculation](#/calculation), [Chain](#/chain), [Given](#/given), [Metrics](#/metrics), [What can go wrong](#/what-can-go-wrong) and [Worked examples](#/worked-examples).
4057
+ Used on [Calculation](#/calculation), [Chain](#/chain), [Rows from data](#/rows-from-data), [Given](#/given), [Metrics](#/metrics), [What can go wrong](#/what-can-go-wrong) and [Worked examples](#/worked-examples).
3494
4058
 
3495
4059
  ##### `Minus`
3496
4060
 
@@ -3500,7 +4064,7 @@ Takes its operand from the value before it.
3500
4064
  const Minus: (props: ChainOperandProps) => null;
3501
4065
  ```
3502
4066
 
3503
- Used on [Calculation](#/calculation), [Chain](#/chain), [Given](#/given) and [Metrics](#/metrics).
4067
+ Used on [Calculation](#/calculation), [Chain](#/chain), [Rows from data](#/rows-from-data), [Given](#/given) and [Metrics](#/metrics).
3504
4068
 
3505
4069
  ##### `Plus`
3506
4070
 
@@ -3510,7 +4074,7 @@ Adds its operand to the value before it.
3510
4074
  const Plus: (props: ChainOperandProps) => null;
3511
4075
  ```
3512
4076
 
3513
- Used on [Calculation](#/calculation), [Chain](#/chain), [Metrics](#/metrics), [What can go wrong](#/what-can-go-wrong) and [Worked examples](#/worked-examples).
4077
+ Used on [Calculation](#/calculation), [Chain](#/chain), [Rows from data](#/rows-from-data), [Metrics](#/metrics), [What can go wrong](#/what-can-go-wrong) and [Worked examples](#/worked-examples).
3514
4078
 
3515
4079
  ##### `Product`
3516
4080
 
@@ -3520,7 +4084,7 @@ The product of two or more operands.
3520
4084
  const Product: (props: OperatorProps) => null;
3521
4085
  ```
3522
4086
 
3523
- Used on [Scenarios](#/), [Calculation](#/calculation), [Tree](#/tree), [Chain](#/chain), [Given](#/given), [Metrics](#/metrics), [What can go wrong](#/what-can-go-wrong) and [Worked examples](#/worked-examples).
4087
+ Used on [Scenarios](#/), [Calculation](#/calculation), [Tree](#/tree), [Chain](#/chain), [Rows from data](#/rows-from-data), [Given](#/given), [Metrics](#/metrics), [What can go wrong](#/what-can-go-wrong) and [Worked examples](#/worked-examples).
3524
4088
 
3525
4089
  ##### `Quotient`
3526
4090
 
@@ -3536,17 +4100,18 @@ Used on [Scenarios](#/), [Installation](#/installation), [Calculation](#/calcula
3536
4100
 
3537
4101
  [Tree](#/tree) – A quantity defined elsewhere in the calculation, standing as an operand.
3538
4102
 
3539
- Used on [Scenarios](#/), [Installation](#/installation), [Calculation](#/calculation), [Tree](#/tree), [Chain](#/chain), [Given](#/given) and [Worked examples](#/worked-examples).
4103
+ Used on [Scenarios](#/), [Installation](#/installation), [Calculation](#/calculation), [Tree](#/tree), [Chain](#/chain), [Rows from data](#/rows-from-data), [Given](#/given) and [Worked examples](#/worked-examples).
3540
4104
 
3541
4105
  ##### `Sum`
3542
4106
 
3543
- The sum of two or more operands.
4107
+ The sum of its operands, however many: rows from data, one or none
4108
+ included. The sum of none is zero, and its line says it has no entries.
3544
4109
 
3545
4110
  ```ts
3546
4111
  const Sum: (props: OperatorProps) => null;
3547
4112
  ```
3548
4113
 
3549
- Used on [Scenarios](#/), [Calculation](#/calculation), [Tree](#/tree), [Chain](#/chain), [Metrics](#/metrics), [What can go wrong](#/what-can-go-wrong) and [Worked examples](#/worked-examples).
4114
+ Used on [Scenarios](#/), [Calculation](#/calculation), [Tree](#/tree), [Chain](#/chain), [Rows from data](#/rows-from-data), [Metrics](#/metrics), [What can go wrong](#/what-can-go-wrong) and [Worked examples](#/worked-examples).
3550
4115
 
3551
4116
  ##### `Times`
3552
4117
 
@@ -3556,7 +4121,7 @@ Multiplies the named value before it by its operand.
3556
4121
  const Times: (props: ChainOperandProps) => null;
3557
4122
  ```
3558
4123
 
3559
- Used on [Chain](#/chain) and [Metrics](#/metrics).
4124
+ Used on [Calculation](#/calculation), [Chain](#/chain) and [Metrics](#/metrics).
3560
4125
 
3561
4126
  #### Types
3562
4127
 
@@ -3580,7 +4145,7 @@ Its table stands on [Given](#/given/type-GivenProps).
3580
4145
 
3581
4146
  Its table stands on [Metrics](#/metrics/type-Metric).
3582
4147
 
3583
- Used on [Metrics](#/metrics).
4148
+ Used on [Rows from data](#/rows-from-data) and [Metrics](#/metrics).
3584
4149
 
3585
4150
  ##### `MetricValues`
3586
4151