@flood-md/react 0.2.11 → 0.2.13
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/README.md +39 -7
- package/dist/app-shell.js +2 -2
- package/dist/box-plot.d.ts +2 -0
- package/dist/box-plot.js +148 -0
- package/dist/bullet-chart.d.ts +2 -0
- package/dist/bullet-chart.js +27 -0
- package/dist/charts.d.ts +6 -0
- package/dist/charts.js +561 -0
- package/dist/collection-toolbar.js +4 -4
- package/dist/data-display.js +27 -3
- package/dist/data-table-columns.d.ts +25 -0
- package/dist/data-table-columns.js +271 -0
- package/dist/data-table-expansion.d.ts +21 -0
- package/dist/data-table-expansion.js +79 -0
- package/dist/data-table.js +100 -7
- package/dist/dumbbell-chart.d.ts +2 -0
- package/dist/dumbbell-chart.js +80 -0
- package/dist/editable.js +57 -18
- package/dist/feedback-actions.js +18 -3
- package/dist/foundations.css +2006 -227
- package/dist/histogram.d.ts +2 -0
- package/dist/histogram.js +78 -0
- package/dist/index.d.ts +328 -3
- package/dist/index.js +57 -4
- package/dist/menu.d.ts +1 -0
- package/dist/menu.js +6 -6
- package/dist/overlay-runtime.d.ts +5 -4
- package/dist/overlay-runtime.js +35 -12
- package/dist/overlays.d.ts +1 -0
- package/dist/overlays.js +5 -3
- package/dist/range-chart.d.ts +2 -0
- package/dist/range-chart.js +97 -0
- package/dist/scatter-chart.d.ts +2 -0
- package/dist/scatter-chart.js +170 -0
- package/dist/sparkline.d.ts +2 -0
- package/dist/sparkline.js +65 -0
- package/dist/waterfall-chart.d.ts +2 -0
- package/dist/waterfall-chart.js +89 -0
- package/package.json +2 -2
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useId, useState } from "react";
|
|
3
|
+
import { Surface, Text, VisuallyHidden } from "./index.js";
|
|
4
|
+
const number = new Intl.NumberFormat("en", { maximumSignificantDigits: 21 });
|
|
5
|
+
export const WaterfallPlot = /* @__PURE__ */ forwardRef(function WaterfallPlot({ label, steps, domain, formatValue = number.format, changeLabel = "Change", totalLabel = "Total", emptyLabel = "No steps", navigationLabel = "Use arrow keys to explore steps, or Home and End to jump.", className, ...props }, ref) {
|
|
6
|
+
const instructions = useId();
|
|
7
|
+
const [cursor, setCursor] = useState(0);
|
|
8
|
+
const [hovered, setHovered] = useState();
|
|
9
|
+
const [tapped, setTapped] = useState();
|
|
10
|
+
const [focused, setFocused] = useState(false);
|
|
11
|
+
const ids = new Set();
|
|
12
|
+
let running = 0;
|
|
13
|
+
let low = 0;
|
|
14
|
+
let high = 0;
|
|
15
|
+
const bars = steps.map(step => {
|
|
16
|
+
if (!step.id.trim() || ids.has(step.id) || !step.label.trim() || !Number.isFinite(step.value)) {
|
|
17
|
+
throw new Error("Flood WaterfallChart needs unique step IDs, labels and finite values");
|
|
18
|
+
}
|
|
19
|
+
ids.add(step.id);
|
|
20
|
+
const total = step.kind === "total";
|
|
21
|
+
const start = total ? 0 : running;
|
|
22
|
+
const end = start + step.value;
|
|
23
|
+
if (!Number.isFinite(end))
|
|
24
|
+
throw new RangeError("Flood WaterfallChart running totals must be finite");
|
|
25
|
+
low = Math.min(low, start, end);
|
|
26
|
+
high = Math.max(high, start, end);
|
|
27
|
+
running = end;
|
|
28
|
+
return { ...step, start, end, total };
|
|
29
|
+
});
|
|
30
|
+
if (domain && (!Number.isFinite(domain[0]) || !Number.isFinite(domain[1]) ||
|
|
31
|
+
domain[0] >= domain[1] || domain[0] > low || domain[1] < high)) {
|
|
32
|
+
throw new RangeError("Flood WaterfallChart domain must contain zero and all running totals");
|
|
33
|
+
}
|
|
34
|
+
const [min, max] = domain ?? [low, low === high ? 1 : high];
|
|
35
|
+
const span = max - min;
|
|
36
|
+
const percent = (value) => 100 * (Number.isFinite(span)
|
|
37
|
+
? (value - min) / span
|
|
38
|
+
: (value / 2 - min / 2) / (max / 2 - min / 2));
|
|
39
|
+
const last = bars.length - 1;
|
|
40
|
+
const active = Math.min(last, hovered ?? tapped ?? cursor);
|
|
41
|
+
const current = bars[active];
|
|
42
|
+
const inspecting = hovered !== undefined || tapped !== undefined || focused;
|
|
43
|
+
const change = current && !current.total ? `${current.value > 0 ? "+" : ""}${formatValue(current.value)}` : undefined;
|
|
44
|
+
const total = current ? formatValue(current.end) : undefined;
|
|
45
|
+
const accessible = current && [current.label, ...(change === undefined ? [] : [`${changeLabel}: ${change}`]), `${totalLabel}: ${total}`].join(", ");
|
|
46
|
+
const navigate = (event) => {
|
|
47
|
+
let next;
|
|
48
|
+
switch (event.key) {
|
|
49
|
+
case "ArrowRight":
|
|
50
|
+
case "ArrowUp":
|
|
51
|
+
next = active + 1;
|
|
52
|
+
break;
|
|
53
|
+
case "ArrowLeft":
|
|
54
|
+
case "ArrowDown":
|
|
55
|
+
next = active - 1;
|
|
56
|
+
break;
|
|
57
|
+
case "Home":
|
|
58
|
+
next = 0;
|
|
59
|
+
break;
|
|
60
|
+
case "End":
|
|
61
|
+
next = last;
|
|
62
|
+
break;
|
|
63
|
+
case "Escape":
|
|
64
|
+
setHovered(undefined);
|
|
65
|
+
setTapped(undefined);
|
|
66
|
+
setFocused(false);
|
|
67
|
+
return;
|
|
68
|
+
default: return;
|
|
69
|
+
}
|
|
70
|
+
event.preventDefault();
|
|
71
|
+
setHovered(undefined);
|
|
72
|
+
setTapped(undefined);
|
|
73
|
+
setFocused(true);
|
|
74
|
+
setCursor(Math.max(0, Math.min(next, last)));
|
|
75
|
+
};
|
|
76
|
+
return _jsx("div", { ...props, ref: ref, className: ["flood-waterfall-chart", className].filter(Boolean).join(" "), role: "group", "aria-label": label, children: current ? _jsxs(_Fragment, { children: [last > 0 && _jsx(VisuallyHidden, { id: instructions, children: navigationLabel }), _jsxs("div", { className: "flood-waterfall-chart__plot", dir: "ltr", role: last > 0 ? "slider" : "img", tabIndex: last > 0 ? 0 : undefined, "aria-label": last > 0 ? label : accessible, "aria-describedby": last > 0 ? instructions : undefined, "aria-valuemin": last > 0 ? 1 : undefined, "aria-valuemax": last > 0 ? bars.length : undefined, "aria-valuenow": last > 0 ? active + 1 : undefined, "aria-valuetext": last > 0 ? accessible : undefined, style: { "--flood-waterfall-columns": bars.length, "--flood-waterfall-zero": 1 - percent(0) / 100 }, onFocus: event => setFocused(event.currentTarget.matches(":focus-visible")), onBlur: () => setFocused(false), onKeyDown: navigate, onPointerLeave: () => setHovered(undefined), children: [_jsx("div", { className: "flood-waterfall-chart__columns", "aria-hidden": "true", children: bars.map((bar, index) => {
|
|
77
|
+
const start = percent(bar.start);
|
|
78
|
+
const end = percent(bar.end);
|
|
79
|
+
const next = bars[index + 1];
|
|
80
|
+
const connectBefore = index > 0 && (!bar.total || bars[index - 1].end === bar.end);
|
|
81
|
+
const connectAfter = next && (!next.total || bar.end === next.end);
|
|
82
|
+
return _jsxs("div", { className: "flood-waterfall-chart__column", "data-active": inspecting && index === active || undefined, onPointerEnter: event => { if (event.pointerType !== "touch")
|
|
83
|
+
setHovered(index); }, onPointerUp: event => { if (event.pointerType === "touch")
|
|
84
|
+
setTapped(previous => previous === index ? undefined : index); }, children: [_jsxs("div", { className: "flood-waterfall-chart__track", children: [connectBefore && _jsx("span", { className: "flood-waterfall-chart__connector", "data-side": "before", style: { insetBlockEnd: `${bar.total ? end : start}%` } }), connectAfter && _jsx("span", { className: "flood-waterfall-chart__connector", "data-side": "after", style: { insetBlockEnd: `${end}%` } }), _jsx("span", { className: "flood-waterfall-chart__bar", "data-kind": bar.total ? "total" : bar.value < 0 ? "decrease" : "increase", "data-flat": start === end || undefined, style: { insetBlockEnd: `${Math.min(start, end)}%`, blockSize: `${Math.abs(start - end)}%` } })] }), _jsx(Text, { className: "flood-waterfall-chart__category", size: "helper", tone: "subtle", dir: "auto", title: bar.label, children: bar.label })] }, bar.id);
|
|
85
|
+
}) }), inspecting && _jsxs(Surface, { className: "flood-chart__tooltip flood-waterfall-chart__tooltip", elevation: "raised", padding: "2", "aria-hidden": "true", style: {
|
|
86
|
+
"--flood-waterfall-position": `${(active + .5) / bars.length * 100}%`,
|
|
87
|
+
"--flood-waterfall-tip-side": active >= bars.length / 2 ? -1 : 0,
|
|
88
|
+
}, children: [_jsx(Text, { size: "helper", children: current.label }), change !== undefined && _jsxs("div", { className: "flood-waterfall-chart__reading", children: [_jsx(Text, { size: "helper", tone: "subtle", children: changeLabel }), _jsx(Text, { size: "helper", children: change })] }), _jsxs("div", { className: "flood-waterfall-chart__reading", children: [_jsx(Text, { size: "helper", tone: "subtle", children: totalLabel }), _jsx(Text, { size: "helper", children: total })] })] })] })] }) : _jsx(Text, { className: "flood-waterfall-chart__empty", size: "compact", tone: "subtle", children: emptyLabel }) });
|
|
89
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flood-md/react",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Original Flood components for React and Next.js.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"react-dom": "^18.3.0 || ^19.0.0"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@flood-md/tokens": "0.2.
|
|
33
|
+
"@flood-md/tokens": "0.2.13"
|
|
34
34
|
},
|
|
35
35
|
"publishConfig": {
|
|
36
36
|
"access": "public"
|