@umriss-ui/calculation 0.43.0 → 0.44.0
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/CHANGELOG.md +11 -0
- package/dist/calculation.client.js +182 -170
- package/docs/llms-full.md +6 -6
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,17 @@ From 0.34.0 the packages share one number - five, and six from 0.40.0, when the
|
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
|
+
## 0.44.0 – A calculation without a name says so (Oct. 2026)
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- **A `Calculation` with neither `aria-label` nor `aria-labelledby` (or an empty label) warns once in development.**
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- **The peer range on core moves to `^0.44.0`.**
|
|
26
|
+
- Migration: install the 0.44 version of `@umriss-ui/core` beside it.
|
|
27
|
+
|
|
17
28
|
## 0.43.0 – Places that carry down, and a calculation's root (Oct. 2026)
|
|
18
29
|
|
|
19
30
|
### Added
|
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import "./calculation.css";
|
|
3
|
-
import { jsx as
|
|
4
|
-
import { useId as
|
|
5
|
-
import { assess as Me, verdictWeight as X, useDensityFor as
|
|
3
|
+
import { jsx as l, jsxs as O } from "react/jsx-runtime";
|
|
4
|
+
import { useId as ye, useState as ae, useRef as ke, useCallback as me, useLayoutEffect as Ae, useEffect as Ee } from "react";
|
|
5
|
+
import { assess as Me, verdictWeight as X, useDensityFor as Te, useFormats as be, useWording as Ne, VisuallyHidden as Be, AngleGlyph as De, Badge as se, useFreshness as Le, Tooltip as Re } from "@umriss-ui/core";
|
|
6
6
|
import { p as We } from "./calculation.model-CZuohgrp.js";
|
|
7
|
-
function
|
|
7
|
+
function we(e, t) {
|
|
8
8
|
if (e.decimals !== void 0) return e.decimals;
|
|
9
9
|
const m = e.format === "percent" ? 1 : e.given ? void 0 : 2;
|
|
10
10
|
if (m === void 0) return;
|
|
11
11
|
const i = e.format === "percent" ? t * 100 : t;
|
|
12
|
-
return i !== 0 &&
|
|
12
|
+
return i !== 0 && $e(i, m) === 0 ? void 0 : m;
|
|
13
13
|
}
|
|
14
14
|
function pe(e, t) {
|
|
15
15
|
const [m, i = "0"] = String(e).split("e");
|
|
16
16
|
return +`${m}e${Number(i) + t}`;
|
|
17
17
|
}
|
|
18
|
-
function
|
|
18
|
+
function $e(e, t) {
|
|
19
19
|
return t === void 0 ? e : Math.sign(e) * pe(Math.round(pe(Math.abs(e), t)), -t) || 0;
|
|
20
20
|
}
|
|
21
|
-
function J(e, t, m =
|
|
22
|
-
return
|
|
21
|
+
function J(e, t, m = we(e, t)) {
|
|
22
|
+
return $e(e.format === "percent" ? t * 100 : t, m);
|
|
23
23
|
}
|
|
24
24
|
const Fe = (e, t) => e.format === "percent" ? t / 100 : t;
|
|
25
25
|
function fe(e, t, m) {
|
|
26
26
|
const [i, ...d] = t;
|
|
27
27
|
switch (e) {
|
|
28
28
|
case "sum":
|
|
29
|
-
return t.reduce((n,
|
|
29
|
+
return t.reduce((n, r, g) => m[g] ? n - r : n + r, 0);
|
|
30
30
|
case "difference":
|
|
31
|
-
return d.reduce((n,
|
|
31
|
+
return d.reduce((n, r) => n - r, i);
|
|
32
32
|
case "product":
|
|
33
|
-
return d.reduce((n,
|
|
33
|
+
return d.reduce((n, r) => n * r, i);
|
|
34
34
|
case "quotient":
|
|
35
35
|
return i / d[0];
|
|
36
36
|
}
|
|
@@ -41,10 +41,10 @@ function qe(e) {
|
|
|
41
41
|
const d = t.get(i);
|
|
42
42
|
if (d) return d;
|
|
43
43
|
const n = e.quantities.get(i);
|
|
44
|
-
let
|
|
44
|
+
let r = null, g, p = !1, s;
|
|
45
45
|
if (n.given) {
|
|
46
46
|
const N = n.given.value;
|
|
47
|
-
typeof N == "number" && Number.isFinite(N) ?
|
|
47
|
+
typeof N == "number" && Number.isFinite(N) ? r = N : g = { kind: "missing", label: n.label };
|
|
48
48
|
} else {
|
|
49
49
|
const N = n.operands.map((w) => ({ operand: w, ...m(w.key) }));
|
|
50
50
|
for (const { operand: w, verdict: S, worst: C } of N) {
|
|
@@ -55,44 +55,55 @@ function qe(e) {
|
|
|
55
55
|
const I = N[1];
|
|
56
56
|
if (!g && n.operator === "quotient" && I.value === 0 && (g = { kind: "zero", label: e.quantities.get(I.operand.key).label }), !g) {
|
|
57
57
|
const w = n.operands.map(($) => $.negated === !0);
|
|
58
|
-
|
|
58
|
+
r = fe(n.operator, N.map(($) => $.value), w);
|
|
59
59
|
const S = fe(
|
|
60
60
|
n.operator,
|
|
61
61
|
N.map(($) => Fe(e.quantities.get($.operand.key), $.shown)),
|
|
62
62
|
w
|
|
63
|
-
), C =
|
|
64
|
-
p = J(n, S, C) !== J(n,
|
|
63
|
+
), C = we(n, r);
|
|
64
|
+
p = J(n, S, C) !== J(n, r, C);
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
const
|
|
68
|
-
value:
|
|
67
|
+
const M = { target: n.target, limits: n.limits }, T = n.target !== void 0 || (n.limits?.length ?? 0) > 0 ? Me(r, M) : void 0, h = (n.limits?.length ?? 0) > 0 ? T.verdict : r === null ? "unknown" : void 0, q = {
|
|
68
|
+
value: r,
|
|
69
69
|
absence: g,
|
|
70
|
-
shown:
|
|
70
|
+
shown: r === null ? null : J(n, r),
|
|
71
71
|
approximate: p,
|
|
72
72
|
assessment: T,
|
|
73
73
|
verdict: h,
|
|
74
74
|
worst: s
|
|
75
75
|
};
|
|
76
|
-
return t.set(i,
|
|
76
|
+
return t.set(i, q), q;
|
|
77
77
|
};
|
|
78
78
|
for (const i of e.quantities.keys()) m(i);
|
|
79
79
|
return t;
|
|
80
80
|
}
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
function je() {
|
|
82
|
+
try {
|
|
83
|
+
return process.env.NODE_ENV !== "production";
|
|
84
|
+
} catch {
|
|
85
|
+
return !1;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const Pe = je(), ve = /* @__PURE__ */ new Set();
|
|
89
|
+
function Ue(e, t) {
|
|
90
|
+
!Pe || ve.has(e) || (ve.add(e), console.warn(`@umriss-ui/calculation: ${t}`));
|
|
91
|
+
}
|
|
92
|
+
const ge = 4;
|
|
93
|
+
function Ie(e, t, m) {
|
|
83
94
|
const i = e.operands[t];
|
|
84
95
|
if (i.previous) return;
|
|
85
96
|
const d = e.operator, n = t === 0;
|
|
86
97
|
if (d !== "sum" && d !== "difference") return n ? void 0 : { operator: d, negated: !1 };
|
|
87
|
-
const
|
|
98
|
+
const r = d === "difference" ? !n : i.negated === !0, g = new Set(m.filter((s) => s !== null && s !== 0).map(Math.sign)), p = g.size === 1 ? { operator: "sum", negated: r !== g.has(-1), unsigned: !0 } : { operator: "sum", negated: r };
|
|
88
99
|
return n && !p.negated ? void 0 : p;
|
|
89
100
|
}
|
|
90
|
-
const
|
|
101
|
+
const Ve = {
|
|
91
102
|
sum: "calculationSumSymbol",
|
|
92
103
|
difference: "calculationDifferenceSymbol",
|
|
93
104
|
product: "calculationProductSymbol",
|
|
94
105
|
quotient: "calculationQuotientSymbol"
|
|
95
|
-
},
|
|
106
|
+
}, ze = {
|
|
96
107
|
sum: "calculationSumWord",
|
|
97
108
|
difference: "calculationDifferenceWord",
|
|
98
109
|
product: "calculationProductWord",
|
|
@@ -112,246 +123,247 @@ function K(e, t) {
|
|
|
112
123
|
}
|
|
113
124
|
function ee(e, t, m) {
|
|
114
125
|
const i = e.negated ? "difference" : e.operator;
|
|
115
|
-
return m[(t ?
|
|
126
|
+
return m[(t ? ze : Ve)[i]];
|
|
116
127
|
}
|
|
117
|
-
function
|
|
128
|
+
function He(e, t) {
|
|
118
129
|
return e.kind === "missing" ? t.calculationMissing(e.label) : t.calculationDivisionByZero(e.label);
|
|
119
130
|
}
|
|
120
|
-
function
|
|
131
|
+
function _e(e, t, m, i) {
|
|
121
132
|
const d = e.format === "percent" ? i : e.unit, n = m.number(t, e.decimals);
|
|
122
133
|
return d ? `${n} ${d}` : n;
|
|
123
134
|
}
|
|
124
|
-
function
|
|
135
|
+
function Qe(e, t, m, i, d, n, r, g = () => {
|
|
125
136
|
}) {
|
|
126
|
-
const p = e.quantities.get(m), s = t.get(m),
|
|
127
|
-
const
|
|
128
|
-
return
|
|
137
|
+
const p = e.quantities.get(m), s = t.get(m), M = (v, k) => v.shown !== null && k?.unsigned ? Math.abs(v.shown) : v.shown, T = (v, k, _, W) => {
|
|
138
|
+
const j = M(k, W);
|
|
139
|
+
return j === null ? _ ? n.verdictUnknown : n.statAbsentValue : _e(v, j, d, _ ? n.calculationPercent : "%");
|
|
129
140
|
}, h = (v) => {
|
|
130
141
|
if (i || !p.operator) return {};
|
|
131
142
|
if (p.operands.length === 0) return { names: n.calculationNoOperands };
|
|
132
|
-
if (!v && p.operands.length >
|
|
143
|
+
if (!v && p.operands.length > ge)
|
|
133
144
|
return { names: n.calculationOperandCount(p.operands.length) };
|
|
134
|
-
const
|
|
135
|
-
const Y = e.quantities.get(
|
|
136
|
-
return
|
|
145
|
+
const k = (_) => p.operands.map((W, j) => {
|
|
146
|
+
const Y = e.quantities.get(W.key), F = g(j);
|
|
147
|
+
return F ? `${ee(F, v, n)} ${_(Y, F)}` : _(Y);
|
|
137
148
|
}).join(" ");
|
|
138
149
|
return {
|
|
139
|
-
names:
|
|
140
|
-
numbers:
|
|
150
|
+
names: k((_) => _.label),
|
|
151
|
+
numbers: k((_, W) => T(_, t.get(_.key), v, W))
|
|
141
152
|
};
|
|
142
|
-
},
|
|
143
|
-
const
|
|
144
|
-
if (
|
|
145
|
-
const _ =
|
|
146
|
-
return
|
|
147
|
-
}, N = h(!1).names, I = N === void 0 || p.operands.length === 0 || p.operands.length >
|
|
148
|
-
(
|
|
153
|
+
}, q = (v) => {
|
|
154
|
+
const k = s.assessment?.deviation;
|
|
155
|
+
if (k === void 0 || p.target === void 0) return;
|
|
156
|
+
const _ = _e(p, J(p, p.target), d, v ? n.calculationPercent : "%");
|
|
157
|
+
return k > 0 ? n.calculationAboveTarget(_) : k < 0 ? n.calculationBelowTarget(_) : n.calculationOnTarget(_);
|
|
158
|
+
}, N = h(!1).names, I = N === void 0 || p.operands.length === 0 || p.operands.length > ge ? N : `= ${N}`, w = h(!0), S = s.absence ? He(s.absence, n) : void 0, C = ` ${n.calculationEquals} `, $ = s.approximate ? `${n.calculationApproximately} ${T(p, s, !0, r)}` : T(p, s, !0, r), te = [
|
|
159
|
+
(r ? `${ee(r, !0, n)} ` : "") + p.label + C + [w.names, w.numbers, $].filter(Boolean).join(`,${C}`),
|
|
149
160
|
s.verdict !== void 0 && s.verdict !== "unknown" ? K(s.verdict, n) : void 0,
|
|
150
|
-
|
|
161
|
+
q(!0),
|
|
151
162
|
S
|
|
152
|
-
].filter(Boolean).join(", "), G = s.shown === null ? void 0 : p.format === "percent" ? "%" : p.unit,
|
|
153
|
-
return { amount:
|
|
163
|
+
].filter(Boolean).join(", "), G = s.shown === null ? void 0 : p.format === "percent" ? "%" : p.unit, y = (v) => v === null ? n.statAbsentValue : d.number(v, p.decimals);
|
|
164
|
+
return { amount: y(M(s, r)), ownAmount: y(s.shown), unit: G, names: I, target: q(!1), reason: S, sentence: te, spokenNames: w.names, spokenNumber: $ };
|
|
154
165
|
}
|
|
155
|
-
function
|
|
156
|
-
const n = d ? `${ee(d, !0, i)} ` : "",
|
|
157
|
-
(s,
|
|
166
|
+
function Ge(e, t, m, i, d) {
|
|
167
|
+
const n = d ? `${ee(d, !0, i)} ` : "", r = t[0].spokenNames, g = n + e + (r === void 0 ? "" : ` ${i.calculationEquals} ${r}`), p = m.map(
|
|
168
|
+
(s, M) => [`${s.label} ${t[M].spokenNumber}`, t[M].reason].filter(Boolean).join(", ")
|
|
158
169
|
);
|
|
159
170
|
return `${g}: ${p.join("; ")}`;
|
|
160
171
|
}
|
|
161
|
-
const
|
|
162
|
-
frame:
|
|
163
|
-
calculation:
|
|
164
|
-
line:
|
|
165
|
-
assessment:
|
|
166
|
-
disclosure:
|
|
167
|
-
amount:
|
|
168
|
-
list:
|
|
169
|
-
item:
|
|
170
|
-
derivation:
|
|
171
|
-
labelCell:
|
|
172
|
-
names:
|
|
173
|
-
operator:
|
|
174
|
-
unit:
|
|
175
|
-
label:
|
|
176
|
-
approximate:
|
|
177
|
-
target:
|
|
178
|
-
worst:
|
|
179
|
-
head:
|
|
180
|
-
headCell:
|
|
181
|
-
headUnit:
|
|
182
|
-
notes:
|
|
183
|
-
freshness:
|
|
184
|
-
headLabel:
|
|
185
|
-
},
|
|
186
|
-
function
|
|
187
|
-
const m =
|
|
172
|
+
const Ye = "_frame_10pic_24 _text_18806_22", Ze = "_calculation_10pic_51", Je = "_line_10pic_86", Ke = "_assessment_10pic_98", Xe = "_disclosure_10pic_107", et = "_amount_10pic_90", tt = "_list_10pic_128", nt = "_item_10pic_129", at = "_derivation_10pic_130", st = "_labelCell_10pic_90", ot = "_names_10pic_90", it = "_operator_10pic_90", rt = "_unit_10pic_90", ct = "_label_10pic_90", lt = "_approximate_10pic_360", dt = "_target_10pic_102", ut = "_worst_10pic_102", mt = "_head_10pic_512", pt = "_headCell_10pic_519", ft = "_headUnit_10pic_532", ht = "_notes_10pic_539", vt = "_freshness_10pic_553", gt = "_headLabel_10pic_583", o = {
|
|
173
|
+
frame: Ye,
|
|
174
|
+
calculation: Ze,
|
|
175
|
+
line: Je,
|
|
176
|
+
assessment: Ke,
|
|
177
|
+
disclosure: Xe,
|
|
178
|
+
amount: et,
|
|
179
|
+
list: tt,
|
|
180
|
+
item: nt,
|
|
181
|
+
derivation: at,
|
|
182
|
+
labelCell: st,
|
|
183
|
+
names: ot,
|
|
184
|
+
operator: it,
|
|
185
|
+
unit: rt,
|
|
186
|
+
label: ct,
|
|
187
|
+
approximate: lt,
|
|
188
|
+
target: dt,
|
|
189
|
+
worst: ut,
|
|
190
|
+
head: mt,
|
|
191
|
+
headCell: pt,
|
|
192
|
+
headUnit: ft,
|
|
193
|
+
notes: ht,
|
|
194
|
+
freshness: vt,
|
|
195
|
+
headLabel: gt
|
|
196
|
+
}, _t = 10, Q = (e) => 4 + 2 * e, bt = (e) => 5 + 2 * e, Nt = { ok: "success", unknown: "neutral", warning: "warning", alarm: "danger" }, wt = (...e) => e.filter(Boolean).join(" ");
|
|
197
|
+
function $t({ asOf: e, ages: t }) {
|
|
198
|
+
const m = be(), i = Ne(), d = Le(e, t), n = d.freshness === "lost" ? i.freshnessDisconnected : d.freshness === "stale" ? i.freshnessStale : i.freshnessFresh;
|
|
188
199
|
return /* @__PURE__ */ O("span", { className: o.freshness, "data-freshness": d.freshness, children: [
|
|
189
200
|
n,
|
|
190
201
|
d.age !== null && ` · ${m.relative(d.age)}`
|
|
191
202
|
] });
|
|
192
203
|
}
|
|
193
|
-
function
|
|
204
|
+
function yt({
|
|
194
205
|
model: e,
|
|
195
206
|
ref: t,
|
|
196
207
|
className: m,
|
|
197
208
|
style: i,
|
|
198
209
|
density: d,
|
|
199
210
|
"aria-label": n,
|
|
200
|
-
"aria-labelledby":
|
|
211
|
+
"aria-labelledby": r,
|
|
201
212
|
"aria-describedby": g,
|
|
202
213
|
...p
|
|
203
214
|
}) {
|
|
204
|
-
|
|
215
|
+
!n && !r && Ue("no-name", "A Calculation has no accessible name: give it aria-label or aria-labelledby.");
|
|
216
|
+
const s = e.metrics, M = Te(d, "regular") === "compact", T = be(), h = Ne(), q = ye(), N = We(e).map((a) => ({ view: a, results: qe(a) })), [I, w] = ae(() => /* @__PURE__ */ new Set()), [S, C] = ae(null), $ = ke(null), oe = me(
|
|
205
217
|
(a) => {
|
|
206
218
|
$.current = a, typeof t == "function" ? t(a) : t && (t.current = a);
|
|
207
219
|
},
|
|
208
220
|
[t]
|
|
209
|
-
), [te, G] = ae(!1),
|
|
210
|
-
const a = $.current, u = a &&
|
|
221
|
+
), [te, G] = ae(!1), y = s?.length ?? 0, v = me(() => {
|
|
222
|
+
const a = $.current, u = a && y > 0 ? getComputedStyle(a.firstElementChild).gridTemplateColumns.split(" ").map(parseFloat) : [], f = Q(y) - 1;
|
|
211
223
|
if (!a || u.length <= f || u.some((x) => !Number.isFinite(x))) {
|
|
212
224
|
G(!1);
|
|
213
225
|
return;
|
|
214
226
|
}
|
|
215
|
-
const A = u.slice(2, f).reduce((x,
|
|
216
|
-
let
|
|
217
|
-
const
|
|
227
|
+
const A = u.slice(2, f).reduce((x, E) => x + E, 0);
|
|
228
|
+
let c = 0;
|
|
229
|
+
const B = document.createRange();
|
|
218
230
|
for (const x of a.querySelectorAll(`.${o.label}`)) {
|
|
219
|
-
|
|
220
|
-
const
|
|
221
|
-
if (
|
|
222
|
-
const
|
|
223
|
-
|
|
231
|
+
B.selectNodeContents(x);
|
|
232
|
+
const E = [...B.getClientRects()].reduce((L, R) => L + R.width, 0);
|
|
233
|
+
if (E === 0) continue;
|
|
234
|
+
const z = x.parentElement, V = x.getBoundingClientRect().left - z.getBoundingClientRect().left;
|
|
235
|
+
c = Math.max(c, V + E + parseFloat(getComputedStyle(z).paddingRight));
|
|
224
236
|
}
|
|
225
|
-
const
|
|
226
|
-
G(a.clientWidth - A < Math.min(
|
|
227
|
-
}, [
|
|
228
|
-
|
|
237
|
+
const D = parseFloat(getComputedStyle(document.documentElement).fontSize);
|
|
238
|
+
G(a.clientWidth - A < Math.min(c, _t * D));
|
|
239
|
+
}, [y]);
|
|
240
|
+
Ae(() => v()), Ee(() => {
|
|
229
241
|
const a = $.current;
|
|
230
|
-
if (!a ||
|
|
242
|
+
if (!a || y === 0) return;
|
|
231
243
|
const u = new ResizeObserver(() => v());
|
|
232
244
|
return u.observe(a), () => u.disconnect();
|
|
233
|
-
}, [v,
|
|
234
|
-
const
|
|
245
|
+
}, [v, y]);
|
|
246
|
+
const k = (a) => w((u) => {
|
|
235
247
|
const f = new Set(u);
|
|
236
248
|
return f.delete(a) || f.add(a), f;
|
|
237
|
-
}), _ = (a, u) =>
|
|
249
|
+
}), _ = (a, u) => Ie(
|
|
238
250
|
a,
|
|
239
251
|
u,
|
|
240
252
|
N.map(({ results: f }) => f.get(a.operands[u].key).shown)
|
|
241
253
|
);
|
|
242
|
-
let
|
|
243
|
-
const
|
|
254
|
+
let W = !1;
|
|
255
|
+
const j = (a, u) => a.map(({ own: f, text: A }, c) => [
|
|
244
256
|
/* @__PURE__ */ O(
|
|
245
257
|
"span",
|
|
246
258
|
{
|
|
247
259
|
className: o.amount,
|
|
248
260
|
"aria-hidden": "true",
|
|
249
261
|
"data-verdict": f.verdict,
|
|
250
|
-
"data-later":
|
|
251
|
-
style: s ? { "--_calculation-column": Q(
|
|
262
|
+
"data-later": c > 0 ? "" : void 0,
|
|
263
|
+
style: s ? { "--_calculation-column": Q(c) } : void 0,
|
|
252
264
|
children: [
|
|
253
|
-
f.approximate && /* @__PURE__ */
|
|
265
|
+
f.approximate && /* @__PURE__ */ l(Re, { content: h.calculationApproximateNote, children: /* @__PURE__ */ l("span", { className: o.approximate, children: "≈" }) }),
|
|
254
266
|
u ? A.ownAmount : A.amount
|
|
255
267
|
]
|
|
256
268
|
},
|
|
257
|
-
`amount-${
|
|
269
|
+
`amount-${c}`
|
|
258
270
|
),
|
|
259
|
-
/* @__PURE__ */
|
|
271
|
+
/* @__PURE__ */ l(
|
|
260
272
|
"span",
|
|
261
273
|
{
|
|
262
274
|
className: o.unit,
|
|
263
275
|
"aria-hidden": "true",
|
|
264
|
-
style: s ? { "--_calculation-column":
|
|
265
|
-
"data-last": s &&
|
|
276
|
+
style: s ? { "--_calculation-column": bt(c) } : void 0,
|
|
277
|
+
"data-last": s && c === a.length - 1 ? "" : void 0,
|
|
266
278
|
children: s && !u ? void 0 : A.unit
|
|
267
279
|
},
|
|
268
|
-
`unit-${
|
|
280
|
+
`unit-${c}`
|
|
269
281
|
)
|
|
270
|
-
]), Y = (a, u) => S === null ? void 0 : a === S ? "use" : u === S ? "operand" : void 0,
|
|
271
|
-
const
|
|
282
|
+
]), Y = (a, u) => S === null ? void 0 : a === S ? "use" : u === S ? "operand" : void 0, F = (a, u, f, A) => {
|
|
283
|
+
const c = e.quantities.get(a), B = N.map(({ view: b, results: U }) => ({
|
|
272
284
|
own: U.get(a),
|
|
273
|
-
text:
|
|
274
|
-
})), { own:
|
|
275
|
-
|
|
276
|
-
const ie = `${
|
|
277
|
-
(b, U) => b.previous ? null :
|
|
278
|
-
) : [], H =
|
|
279
|
-
!u &&
|
|
280
|
-
P?.source !== void 0 && /* @__PURE__ */
|
|
281
|
-
P?.asOf !== void 0 && (P.ages !== void 0 ? /* @__PURE__ */
|
|
282
|
-
!u &&
|
|
283
|
-
].filter(Boolean), de =
|
|
285
|
+
text: Qe(b, U, a, u, T, h, f.position, (Ce) => _(c, Ce))
|
|
286
|
+
})), { own: D, text: x } = B[0], E = c.operator !== void 0 && !u, z = a === e.result && !u, V = E && c.operands.length > 0 && (c.interim ? f.flat : z), L = E && !V && c.operands.length > 0, R = L && I.has(a);
|
|
287
|
+
W ||= L;
|
|
288
|
+
const ie = `${q}-${a}`, ne = { depth: V ? f.depth : f.depth + 1, flat: !1, parent: a }, Z = E ? c.operands.find((b) => b.previous) : void 0, re = Z && f.flat ? F(Z.key, !1, { ...f, parent: a, position: void 0 }, `${A}-c`) : [], Oe = Z && !f.flat ? F(Z.key, !1, { ...ne, flat: !0 }, `${A}-c`) : [], ce = E ? c.operands.map(
|
|
289
|
+
(b, U) => b.previous ? null : F(b.key, b.reference, { ...ne, position: _(c, U) }, `${A}-${U}`)
|
|
290
|
+
) : [], H = L && !R && D.worst !== void 0 && X(D.worst) > X(D.verdict ?? "ok") ? D.worst : void 0, P = u ? void 0 : c.given, Se = f.position ? ee(f.position, !1, h) : void 0, le = [
|
|
291
|
+
!u && c.explanation !== void 0 && /* @__PURE__ */ l("span", { children: c.explanation }, "explanation"),
|
|
292
|
+
P?.source !== void 0 && /* @__PURE__ */ l("span", { children: h.calculationSource(P.source) }, "source"),
|
|
293
|
+
P?.asOf !== void 0 && (P.ages !== void 0 ? /* @__PURE__ */ l($t, { asOf: P.asOf, ages: P.ages }, "asOf") : /* @__PURE__ */ l("span", { children: h.asOfAgo(T.dateTime(new Date(P.asOf), !1)) }, "asOf")),
|
|
294
|
+
!u && c.aside !== void 0 && /* @__PURE__ */ l("span", { children: c.aside }, "aside")
|
|
295
|
+
].filter(Boolean), de = z ? "result" : c.interim && !u && f.flat ? "interim" : void 0, ue = /* @__PURE__ */ O(
|
|
284
296
|
"div",
|
|
285
297
|
{
|
|
286
298
|
className: o.line,
|
|
287
299
|
style: { "--_calculation-depth": f.depth },
|
|
288
300
|
"data-inner": f.depth > 0 ? "" : void 0,
|
|
289
301
|
"data-kind": de,
|
|
290
|
-
"data-foldable":
|
|
302
|
+
"data-foldable": L ? "" : void 0,
|
|
291
303
|
"data-reference": u ? "" : void 0,
|
|
292
|
-
"data-emphasis": u ? void 0 :
|
|
293
|
-
"data-rule": !u &&
|
|
304
|
+
"data-emphasis": u ? void 0 : c.emphasis,
|
|
305
|
+
"data-rule": !u && c.rule ? "" : void 0,
|
|
294
306
|
"data-mark": Y(a, f.parent),
|
|
295
307
|
onPointerEnter: () => C(a),
|
|
296
308
|
onPointerLeave: () => C(null),
|
|
297
309
|
onFocus: () => C(a),
|
|
298
310
|
onBlur: () => C(null),
|
|
299
|
-
onClick:
|
|
300
|
-
window.getSelection()?.toString() ||
|
|
311
|
+
onClick: L ? () => {
|
|
312
|
+
window.getSelection()?.toString() || k(a);
|
|
301
313
|
} : void 0,
|
|
302
314
|
children: [
|
|
303
|
-
/* @__PURE__ */
|
|
304
|
-
s ?
|
|
305
|
-
|
|
315
|
+
/* @__PURE__ */ l(Be, { children: [
|
|
316
|
+
s ? Ge(c.label, B.map((b) => b.text), s, h, f.position) : x.sentence,
|
|
317
|
+
B.some((b) => b.own.approximate) && h.calculationApproximateNote,
|
|
306
318
|
H !== void 0 && h.calculationWorstInside(K(H, h))
|
|
307
319
|
].filter(Boolean).join(". ") }),
|
|
308
320
|
/* @__PURE__ */ O("span", { className: o.labelCell, children: [
|
|
309
|
-
|
|
321
|
+
L ? /* @__PURE__ */ l(
|
|
310
322
|
"button",
|
|
311
323
|
{
|
|
312
324
|
type: "button",
|
|
313
325
|
className: o.disclosure,
|
|
314
|
-
"aria-expanded":
|
|
326
|
+
"aria-expanded": R,
|
|
315
327
|
"aria-controls": ie,
|
|
316
|
-
"aria-label": (
|
|
317
|
-
children: /* @__PURE__ */
|
|
328
|
+
"aria-label": (R ? h.calculationHideDerivation : h.calculationShowDerivation)(c.label),
|
|
329
|
+
children: /* @__PURE__ */ l(De, { "data-open": R ? "" : void 0 })
|
|
318
330
|
}
|
|
319
|
-
) : /* @__PURE__ */
|
|
320
|
-
/* @__PURE__ */
|
|
331
|
+
) : /* @__PURE__ */ l("span", { className: o.disclosure, "aria-hidden": "true" }),
|
|
332
|
+
/* @__PURE__ */ l("span", { className: o.label, "aria-hidden": "true", children: c.label })
|
|
321
333
|
] }),
|
|
322
|
-
/* @__PURE__ */
|
|
323
|
-
/* @__PURE__ */
|
|
324
|
-
|
|
334
|
+
/* @__PURE__ */ l("span", { className: o.names, "aria-hidden": "true", children: E && !V && !R ? x.names : void 0 }),
|
|
335
|
+
/* @__PURE__ */ l("span", { className: o.operator, "aria-hidden": "true", children: Se }),
|
|
336
|
+
j(B, de !== void 0),
|
|
325
337
|
/* @__PURE__ */ O("span", { className: o.assessment, "aria-hidden": "true", children: [
|
|
326
338
|
s ? (
|
|
327
339
|
/* Short: which metric. The sentence carries the full reason. */
|
|
328
340
|
s.map(
|
|
329
|
-
(b, U) =>
|
|
341
|
+
(b, U) => B[U].own.absence && /* @__PURE__ */ l(se, { children: h.calculationMissing(b.unit ?? b.label) }, b.id)
|
|
330
342
|
)
|
|
331
|
-
) : x.reason !== void 0 ? /* @__PURE__ */
|
|
332
|
-
x.target !== void 0 && /* @__PURE__ */
|
|
333
|
-
H !== void 0 && /* @__PURE__ */
|
|
343
|
+
) : x.reason !== void 0 ? /* @__PURE__ */ l(se, { children: x.reason }) : D.verdict !== void 0 && /* @__PURE__ */ l(se, { tone: Nt[D.verdict], children: K(D.verdict, h) }),
|
|
344
|
+
x.target !== void 0 && /* @__PURE__ */ l("span", { className: o.target, children: x.target }),
|
|
345
|
+
H !== void 0 && /* @__PURE__ */ l("span", { className: o.worst, "data-verdict": H, children: h.calculationWorstInside(K(H, h)) })
|
|
334
346
|
] }),
|
|
335
347
|
le.length > 0 && /* A click here - on a link in the aside, on a sparkline - is the
|
|
336
348
|
caller's, not a fold. */
|
|
337
|
-
/* @__PURE__ */
|
|
349
|
+
/* @__PURE__ */ l("span", { className: o.notes, onClick: (b) => b.stopPropagation(), children: le })
|
|
338
350
|
]
|
|
339
351
|
}
|
|
340
352
|
);
|
|
341
|
-
return
|
|
353
|
+
return V ? [
|
|
342
354
|
...re,
|
|
343
355
|
/* @__PURE__ */ O("li", { className: o.item, children: [
|
|
344
|
-
/* @__PURE__ */
|
|
356
|
+
/* @__PURE__ */ l("ul", { className: o.list, children: ce }),
|
|
345
357
|
ue
|
|
346
358
|
] }, A)
|
|
347
359
|
] : [
|
|
348
360
|
...re,
|
|
349
|
-
/* @__PURE__ */ O("li", { className: o.item, "data-open":
|
|
361
|
+
/* @__PURE__ */ O("li", { className: o.item, "data-open": R ? "" : void 0, style: { "--_calculation-depth": f.depth }, children: [
|
|
350
362
|
ue,
|
|
351
|
-
|
|
352
|
-
|
|
363
|
+
L && /* @__PURE__ */ O("ul", { id: ie, className: o.derivation, hidden: !R, children: [
|
|
364
|
+
Oe,
|
|
353
365
|
ce,
|
|
354
|
-
/* @__PURE__ */
|
|
366
|
+
/* @__PURE__ */ l("li", { className: o.item, "aria-hidden": "true", children: /* @__PURE__ */ O(
|
|
355
367
|
"div",
|
|
356
368
|
{
|
|
357
369
|
className: o.line,
|
|
@@ -361,63 +373,63 @@ function xt({
|
|
|
361
373
|
"data-mark": S === a ? "use" : void 0,
|
|
362
374
|
children: [
|
|
363
375
|
/* @__PURE__ */ O("span", { className: o.labelCell, children: [
|
|
364
|
-
/* @__PURE__ */
|
|
376
|
+
/* @__PURE__ */ l("span", { className: o.disclosure }),
|
|
365
377
|
/* @__PURE__ */ O("span", { className: o.label, children: [
|
|
366
378
|
"= ",
|
|
367
|
-
|
|
379
|
+
c.label
|
|
368
380
|
] })
|
|
369
381
|
] }),
|
|
370
|
-
/* @__PURE__ */
|
|
371
|
-
/* @__PURE__ */
|
|
372
|
-
|
|
382
|
+
/* @__PURE__ */ l("span", { className: o.names }),
|
|
383
|
+
/* @__PURE__ */ l("span", { className: o.operator }),
|
|
384
|
+
j(B, !0)
|
|
373
385
|
]
|
|
374
386
|
}
|
|
375
387
|
) })
|
|
376
388
|
] })
|
|
377
389
|
] }, A)
|
|
378
390
|
];
|
|
379
|
-
},
|
|
391
|
+
}, xe = F(e.result, !1, { depth: 0, flat: !0, parent: null }, "r");
|
|
380
392
|
return (
|
|
381
393
|
/* The frame is the surface and the container the layout measures itself
|
|
382
394
|
against; the list inside it is the statement. */
|
|
383
|
-
/* @__PURE__ */
|
|
395
|
+
/* @__PURE__ */ l(
|
|
384
396
|
"div",
|
|
385
397
|
{
|
|
386
398
|
...p,
|
|
387
399
|
ref: oe,
|
|
388
|
-
className:
|
|
400
|
+
className: wt(o.frame, m),
|
|
389
401
|
style: s ? {
|
|
390
|
-
"--_calculation-figure-tracks": Array(
|
|
391
|
-
"--_calculation-figures-end": Q(
|
|
392
|
-
"--_calculation-assessment-column": Q(
|
|
402
|
+
"--_calculation-figure-tracks": Array(y * 2).fill("auto").join(" "),
|
|
403
|
+
"--_calculation-figures-end": Q(y),
|
|
404
|
+
"--_calculation-assessment-column": Q(y),
|
|
393
405
|
...i
|
|
394
406
|
} : i,
|
|
395
|
-
"data-still":
|
|
396
|
-
"data-metrics": s ?
|
|
407
|
+
"data-still": W ? void 0 : "",
|
|
408
|
+
"data-metrics": s ? y : void 0,
|
|
397
409
|
"data-two-lines": te ? "" : void 0,
|
|
398
|
-
"data-compact":
|
|
399
|
-
children: /* @__PURE__ */ O("ul", { className: o.calculation, "aria-label": n, "aria-labelledby":
|
|
410
|
+
"data-compact": M ? "" : void 0,
|
|
411
|
+
children: /* @__PURE__ */ O("ul", { className: o.calculation, "aria-label": n, "aria-labelledby": r, "aria-describedby": g, children: [
|
|
400
412
|
s && /* The head names each metric and its unit above its column. Every
|
|
401
413
|
row's sentence names them too, so the head is for the eye. */
|
|
402
|
-
/* @__PURE__ */
|
|
414
|
+
/* @__PURE__ */ l("li", { className: o.item, "aria-hidden": "true", children: /* @__PURE__ */ l("div", { className: o.head, children: s.map((a, u) => /* @__PURE__ */ O(
|
|
403
415
|
"span",
|
|
404
416
|
{
|
|
405
417
|
className: o.headCell,
|
|
406
418
|
"data-unit": a.unit === void 0 ? void 0 : "",
|
|
407
419
|
style: { "--_calculation-column": Q(u) },
|
|
408
420
|
children: [
|
|
409
|
-
/* @__PURE__ */
|
|
410
|
-
a.unit !== void 0 && /* @__PURE__ */
|
|
421
|
+
/* @__PURE__ */ l("span", { className: o.headLabel, children: a.label }),
|
|
422
|
+
a.unit !== void 0 && /* @__PURE__ */ l("span", { className: o.headUnit, children: a.unit })
|
|
411
423
|
]
|
|
412
424
|
},
|
|
413
425
|
a.id
|
|
414
426
|
)) }) }),
|
|
415
|
-
|
|
427
|
+
xe
|
|
416
428
|
] })
|
|
417
429
|
}
|
|
418
430
|
)
|
|
419
431
|
);
|
|
420
432
|
}
|
|
421
433
|
export {
|
|
422
|
-
|
|
434
|
+
yt as CalculationView
|
|
423
435
|
};
|
package/docs/llms-full.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @umriss-ui/calculation 0.
|
|
1
|
+
# @umriss-ui/calculation 0.44.0
|
|
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
|
|
|
@@ -1568,7 +1568,7 @@ Also takes every attribute of `<div>` – without `children`.
|
|
|
1568
1568
|
- No result, formula text or operator of your own: a written-out operation the library did not perform could say something the number does not ([ADR-0027](https://github.com/romanhaendler/umriss-ui/blob/main/docs/adr/0027-a-calculation-is-written-as-it-is-shown.md)).
|
|
1569
1569
|
- No input: a calculation shows how a figure came about; changing a given is your application's form.
|
|
1570
1570
|
|
|
1571
|
-
What umriss deliberately does not build, and why: [ADR-0032](https://github.com/romanhaendler/umriss-ui/blob/calculation-v0.
|
|
1571
|
+
What umriss deliberately does not build, and why: [ADR-0032](https://github.com/romanhaendler/umriss-ui/blob/calculation-v0.44.0/docs/adr/0032-what-umriss-is-not.md).
|
|
1572
1572
|
|
|
1573
1573
|
### Tree
|
|
1574
1574
|
|
|
@@ -1849,7 +1849,7 @@ type Severity = "warning" | "alarm";
|
|
|
1849
1849
|
- Four operators and nothing else – no powers, roots or functions; compute those before and hand them in as givens.
|
|
1850
1850
|
- A unit is a label and is never converted or checked; the calculation does no unit algebra.
|
|
1851
1851
|
|
|
1852
|
-
What umriss deliberately does not build, and why: [ADR-0032](https://github.com/romanhaendler/umriss-ui/blob/calculation-v0.
|
|
1852
|
+
What umriss deliberately does not build, and why: [ADR-0032](https://github.com/romanhaendler/umriss-ui/blob/calculation-v0.44.0/docs/adr/0032-what-umriss-is-not.md).
|
|
1853
1853
|
|
|
1854
1854
|
### Chain
|
|
1855
1855
|
|
|
@@ -2197,7 +2197,7 @@ type Severity = "warning" | "alarm";
|
|
|
2197
2197
|
|
|
2198
2198
|
- A chain in view does not fold; as an operand of a tree it folds to its last interim.
|
|
2199
2199
|
|
|
2200
|
-
What umriss deliberately does not build, and why: [ADR-0032](https://github.com/romanhaendler/umriss-ui/blob/calculation-v0.
|
|
2200
|
+
What umriss deliberately does not build, and why: [ADR-0032](https://github.com/romanhaendler/umriss-ui/blob/calculation-v0.44.0/docs/adr/0032-what-umriss-is-not.md).
|
|
2201
2201
|
|
|
2202
2202
|
### Rows from data
|
|
2203
2203
|
|
|
@@ -2637,7 +2637,7 @@ From `Metric` — the full table stands on [Metrics](#metrics).
|
|
|
2637
2637
|
|
|
2638
2638
|
- 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.
|
|
2639
2639
|
|
|
2640
|
-
What umriss deliberately does not build, and why: [ADR-0032](https://github.com/romanhaendler/umriss-ui/blob/calculation-v0.
|
|
2640
|
+
What umriss deliberately does not build, and why: [ADR-0032](https://github.com/romanhaendler/umriss-ui/blob/calculation-v0.44.0/docs/adr/0032-what-umriss-is-not.md).
|
|
2641
2641
|
|
|
2642
2642
|
### Given
|
|
2643
2643
|
|
|
@@ -3323,7 +3323,7 @@ The keys of [Calculation](#calculation) apply here.
|
|
|
3323
3323
|
- Unit, format and places belong to the metric; on a quantity they fail on the first render, and so does a missing or unknown metric key in a `value`.
|
|
3324
3324
|
- No target or limits with metrics: an assessment per cell is not there yet.
|
|
3325
3325
|
|
|
3326
|
-
What umriss deliberately does not build, and why: [ADR-0032](https://github.com/romanhaendler/umriss-ui/blob/calculation-v0.
|
|
3326
|
+
What umriss deliberately does not build, and why: [ADR-0032](https://github.com/romanhaendler/umriss-ui/blob/calculation-v0.44.0/docs/adr/0032-what-umriss-is-not.md).
|
|
3327
3327
|
|
|
3328
3328
|
## In practice
|
|
3329
3329
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umriss-ui/calculation",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0",
|
|
4
4
|
"description": "React calculation view for data-dense applications - a derivation written as it is shown, evaluated by the library, folded and read line by line.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Roman Händler",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
}
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@umriss-ui/core": "^0.
|
|
59
|
+
"@umriss-ui/core": "^0.44.0",
|
|
60
60
|
"react": ">=19",
|
|
61
61
|
"react-dom": ">=19"
|
|
62
62
|
},
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"typescript": "^5.6.3",
|
|
73
73
|
"vite": "^6.0.0",
|
|
74
74
|
"vite-plugin-dts": "^4.3.0",
|
|
75
|
-
"@umriss-ui/core": "0.
|
|
75
|
+
"@umriss-ui/core": "0.44.0",
|
|
76
76
|
"@umriss-ui/demo": "0.0.0"
|
|
77
77
|
},
|
|
78
78
|
"scripts": {
|