@nexub/react 4.0.0 → 4.2.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/accessibility.json +36 -25
- package/dist/components/Aurora/Aurora.d.ts +3 -0
- package/dist/components/Aurora/Aurora.js +12 -0
- package/dist/components/Aurora/index.d.ts +2 -0
- package/dist/components/Aurora/index.js +4 -0
- package/dist/components/Button/Button.js +2 -0
- package/dist/components/Card/Card.js +1 -0
- package/dist/components/Chart/Chart.d.ts +7 -5
- package/dist/components/Chart/Chart.js +82 -41
- package/dist/components/Chart/index.d.ts +1 -1
- package/dist/components/Chart/index.js +2 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +4 -1
- package/dist/styles.css +1 -1
- package/package.json +6 -6
package/accessibility.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "4.
|
|
2
|
+
"version": "4.2.0",
|
|
3
3
|
"standard": "WCAG 2.2 Level AA",
|
|
4
4
|
"method": {
|
|
5
5
|
"automated": "axe-core rules tagged wcag2a, wcag2aa, wcag21a, wcag21aa and wcag22aa, run on every Storybook story in light and dark on every pull request; a new violation fails the build.",
|
|
@@ -69,6 +69,17 @@
|
|
|
69
69
|
"keyboard": [],
|
|
70
70
|
"screenReader": []
|
|
71
71
|
},
|
|
72
|
+
{
|
|
73
|
+
"slug": "aurora",
|
|
74
|
+
"name": "Aurora",
|
|
75
|
+
"package": "@nexub/react",
|
|
76
|
+
"automated": "not covered",
|
|
77
|
+
"exceptions": [],
|
|
78
|
+
"keyboard": [],
|
|
79
|
+
"screenReader": [
|
|
80
|
+
"Decorative: the whole layer is `aria-hidden`."
|
|
81
|
+
]
|
|
82
|
+
},
|
|
72
83
|
{
|
|
73
84
|
"slug": "autocomplete",
|
|
74
85
|
"name": "Autocomplete",
|
|
@@ -114,7 +125,7 @@
|
|
|
114
125
|
"slug": "bar-chart",
|
|
115
126
|
"name": "Bar Chart",
|
|
116
127
|
"package": "@nexub/react",
|
|
117
|
-
"automated": "
|
|
128
|
+
"automated": "pass",
|
|
118
129
|
"exceptions": [],
|
|
119
130
|
"keyboard": [],
|
|
120
131
|
"screenReader": [
|
|
@@ -298,7 +309,7 @@
|
|
|
298
309
|
"slug": "donut-chart",
|
|
299
310
|
"name": "Donut Chart",
|
|
300
311
|
"package": "@nexub/react",
|
|
301
|
-
"automated": "
|
|
312
|
+
"automated": "pass",
|
|
302
313
|
"exceptions": [],
|
|
303
314
|
"keyboard": [],
|
|
304
315
|
"screenReader": [
|
|
@@ -461,7 +472,7 @@
|
|
|
461
472
|
"slug": "line-chart",
|
|
462
473
|
"name": "Line Chart",
|
|
463
474
|
"package": "@nexub/react",
|
|
464
|
-
"automated": "
|
|
475
|
+
"automated": "pass",
|
|
465
476
|
"exceptions": [],
|
|
466
477
|
"keyboard": [],
|
|
467
478
|
"screenReader": [
|
|
@@ -513,7 +524,7 @@
|
|
|
513
524
|
"slug": "money-input",
|
|
514
525
|
"name": "Money Input",
|
|
515
526
|
"package": "@nexub/react",
|
|
516
|
-
"automated": "
|
|
527
|
+
"automated": "pass",
|
|
517
528
|
"exceptions": [],
|
|
518
529
|
"keyboard": [],
|
|
519
530
|
"screenReader": []
|
|
@@ -540,7 +551,7 @@
|
|
|
540
551
|
"slug": "motion-float",
|
|
541
552
|
"name": "Float",
|
|
542
553
|
"package": "@nexub/react",
|
|
543
|
-
"automated": "
|
|
554
|
+
"automated": "pass",
|
|
544
555
|
"exceptions": [],
|
|
545
556
|
"keyboard": [],
|
|
546
557
|
"screenReader": []
|
|
@@ -549,7 +560,7 @@
|
|
|
549
560
|
"slug": "motion-marquee",
|
|
550
561
|
"name": "Marquee",
|
|
551
562
|
"package": "@nexub/react",
|
|
552
|
-
"automated": "
|
|
563
|
+
"automated": "pass",
|
|
553
564
|
"exceptions": [],
|
|
554
565
|
"keyboard": [],
|
|
555
566
|
"screenReader": []
|
|
@@ -558,7 +569,7 @@
|
|
|
558
569
|
"slug": "motion-reveal",
|
|
559
570
|
"name": "Reveal",
|
|
560
571
|
"package": "@nexub/react",
|
|
561
|
-
"automated": "
|
|
572
|
+
"automated": "pass",
|
|
562
573
|
"exceptions": [],
|
|
563
574
|
"keyboard": [],
|
|
564
575
|
"screenReader": []
|
|
@@ -585,7 +596,7 @@
|
|
|
585
596
|
"slug": "navigation-rail",
|
|
586
597
|
"name": "Navigation Rail",
|
|
587
598
|
"package": "@nexub/react",
|
|
588
|
-
"automated": "
|
|
599
|
+
"automated": "pass",
|
|
589
600
|
"exceptions": [],
|
|
590
601
|
"keyboard": [],
|
|
591
602
|
"screenReader": []
|
|
@@ -748,7 +759,7 @@
|
|
|
748
759
|
"slug": "sheet",
|
|
749
760
|
"name": "Sheet",
|
|
750
761
|
"package": "@nexub/react",
|
|
751
|
-
"automated": "
|
|
762
|
+
"automated": "pass",
|
|
752
763
|
"exceptions": [],
|
|
753
764
|
"keyboard": [],
|
|
754
765
|
"screenReader": []
|
|
@@ -775,7 +786,7 @@
|
|
|
775
786
|
"slug": "sparkline",
|
|
776
787
|
"name": "Sparkline",
|
|
777
788
|
"package": "@nexub/react",
|
|
778
|
-
"automated": "
|
|
789
|
+
"automated": "pass",
|
|
779
790
|
"exceptions": [],
|
|
780
791
|
"keyboard": [],
|
|
781
792
|
"screenReader": [
|
|
@@ -796,7 +807,7 @@
|
|
|
796
807
|
"slug": "split-button",
|
|
797
808
|
"name": "Split Button",
|
|
798
809
|
"package": "@nexub/react",
|
|
799
|
-
"automated": "
|
|
810
|
+
"automated": "pass",
|
|
800
811
|
"exceptions": [],
|
|
801
812
|
"keyboard": [],
|
|
802
813
|
"screenReader": []
|
|
@@ -970,7 +981,7 @@
|
|
|
970
981
|
"slug": "cta-band",
|
|
971
982
|
"name": "CTABand",
|
|
972
983
|
"package": "@nexub/marketing",
|
|
973
|
-
"automated": "
|
|
984
|
+
"automated": "pass",
|
|
974
985
|
"exceptions": [],
|
|
975
986
|
"keyboard": [],
|
|
976
987
|
"screenReader": []
|
|
@@ -992,7 +1003,7 @@
|
|
|
992
1003
|
"slug": "faq",
|
|
993
1004
|
"name": "FAQ",
|
|
994
1005
|
"package": "@nexub/marketing",
|
|
995
|
-
"automated": "
|
|
1006
|
+
"automated": "pass",
|
|
996
1007
|
"exceptions": [],
|
|
997
1008
|
"keyboard": [],
|
|
998
1009
|
"screenReader": []
|
|
@@ -1001,7 +1012,7 @@
|
|
|
1001
1012
|
"slug": "feature-split",
|
|
1002
1013
|
"name": "FeatureSplit",
|
|
1003
1014
|
"package": "@nexub/marketing",
|
|
1004
|
-
"automated": "
|
|
1015
|
+
"automated": "pass",
|
|
1005
1016
|
"exceptions": [],
|
|
1006
1017
|
"keyboard": [],
|
|
1007
1018
|
"screenReader": []
|
|
@@ -1019,7 +1030,7 @@
|
|
|
1019
1030
|
"slug": "hero",
|
|
1020
1031
|
"name": "Hero",
|
|
1021
1032
|
"package": "@nexub/marketing",
|
|
1022
|
-
"automated": "
|
|
1033
|
+
"automated": "pass",
|
|
1023
1034
|
"exceptions": [],
|
|
1024
1035
|
"keyboard": [],
|
|
1025
1036
|
"screenReader": []
|
|
@@ -1028,7 +1039,7 @@
|
|
|
1028
1039
|
"slug": "how-it-works",
|
|
1029
1040
|
"name": "HowItWorks",
|
|
1030
1041
|
"package": "@nexub/marketing",
|
|
1031
|
-
"automated": "
|
|
1042
|
+
"automated": "pass",
|
|
1032
1043
|
"exceptions": [],
|
|
1033
1044
|
"keyboard": [],
|
|
1034
1045
|
"screenReader": []
|
|
@@ -1055,7 +1066,7 @@
|
|
|
1055
1066
|
"slug": "logo-strip",
|
|
1056
1067
|
"name": "LogoStrip",
|
|
1057
1068
|
"package": "@nexub/marketing",
|
|
1058
|
-
"automated": "
|
|
1069
|
+
"automated": "pass",
|
|
1059
1070
|
"exceptions": [],
|
|
1060
1071
|
"keyboard": [],
|
|
1061
1072
|
"screenReader": []
|
|
@@ -1064,7 +1075,7 @@
|
|
|
1064
1075
|
"slug": "marketing-footer",
|
|
1065
1076
|
"name": "MarketingFooter",
|
|
1066
1077
|
"package": "@nexub/marketing",
|
|
1067
|
-
"automated": "
|
|
1078
|
+
"automated": "pass",
|
|
1068
1079
|
"exceptions": [],
|
|
1069
1080
|
"keyboard": [],
|
|
1070
1081
|
"screenReader": []
|
|
@@ -1073,7 +1084,7 @@
|
|
|
1073
1084
|
"slug": "marketing-nav",
|
|
1074
1085
|
"name": "MarketingNav",
|
|
1075
1086
|
"package": "@nexub/marketing",
|
|
1076
|
-
"automated": "
|
|
1087
|
+
"automated": "pass",
|
|
1077
1088
|
"exceptions": [],
|
|
1078
1089
|
"keyboard": [],
|
|
1079
1090
|
"screenReader": []
|
|
@@ -1100,7 +1111,7 @@
|
|
|
1100
1111
|
"slug": "pricing-table",
|
|
1101
1112
|
"name": "PricingTable",
|
|
1102
1113
|
"package": "@nexub/marketing",
|
|
1103
|
-
"automated": "
|
|
1114
|
+
"automated": "pass",
|
|
1104
1115
|
"exceptions": [],
|
|
1105
1116
|
"keyboard": [],
|
|
1106
1117
|
"screenReader": []
|
|
@@ -1109,7 +1120,7 @@
|
|
|
1109
1120
|
"slug": "product-grid",
|
|
1110
1121
|
"name": "ProductGrid",
|
|
1111
1122
|
"package": "@nexub/marketing",
|
|
1112
|
-
"automated": "
|
|
1123
|
+
"automated": "pass",
|
|
1113
1124
|
"exceptions": [],
|
|
1114
1125
|
"keyboard": [],
|
|
1115
1126
|
"screenReader": []
|
|
@@ -1118,7 +1129,7 @@
|
|
|
1118
1129
|
"slug": "section-header",
|
|
1119
1130
|
"name": "SectionHeader",
|
|
1120
1131
|
"package": "@nexub/marketing",
|
|
1121
|
-
"automated": "
|
|
1132
|
+
"automated": "pass",
|
|
1122
1133
|
"exceptions": [],
|
|
1123
1134
|
"keyboard": [],
|
|
1124
1135
|
"screenReader": []
|
|
@@ -1136,7 +1147,7 @@
|
|
|
1136
1147
|
"slug": "stat-band",
|
|
1137
1148
|
"name": "StatBand",
|
|
1138
1149
|
"package": "@nexub/marketing",
|
|
1139
|
-
"automated": "
|
|
1150
|
+
"automated": "pass",
|
|
1140
1151
|
"exceptions": [],
|
|
1141
1152
|
"keyboard": [],
|
|
1142
1153
|
"screenReader": []
|
|
@@ -1163,7 +1174,7 @@
|
|
|
1163
1174
|
"slug": "testimonial-grid",
|
|
1164
1175
|
"name": "TestimonialGrid",
|
|
1165
1176
|
"package": "@nexub/marketing",
|
|
1166
|
-
"automated": "
|
|
1177
|
+
"automated": "pass",
|
|
1167
1178
|
"exceptions": [],
|
|
1168
1179
|
"keyboard": [],
|
|
1169
1180
|
"screenReader": []
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../../utils/cn.js";
|
|
4
|
+
const Aurora = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs("div", { ref, "aria-hidden": "true", className: cn("nx-aurora", className), ...props, children: [
|
|
5
|
+
/* @__PURE__ */ jsx("span", {}),
|
|
6
|
+
/* @__PURE__ */ jsx("span", {}),
|
|
7
|
+
/* @__PURE__ */ jsx("span", {})
|
|
8
|
+
] }));
|
|
9
|
+
Aurora.displayName = "Aurora";
|
|
10
|
+
export {
|
|
11
|
+
Aurora
|
|
12
|
+
};
|
|
@@ -95,6 +95,8 @@ const Button = React.forwardRef(
|
|
|
95
95
|
className
|
|
96
96
|
),
|
|
97
97
|
"data-tone": tone,
|
|
98
|
+
// Styling hook for opt-in layers (vivid, marketing); no styles depend on it by default.
|
|
99
|
+
"data-variant": variant ?? "primary",
|
|
98
100
|
...variant === "glass" && { "data-material": "glass", "data-glass-thickness": "thin" },
|
|
99
101
|
...props
|
|
100
102
|
};
|
|
@@ -61,6 +61,7 @@ const Card = React.forwardRef(
|
|
|
61
61
|
className: cn(cardVariants({ variant, surface }), toneStyle, sheen && "nx-sheen", className),
|
|
62
62
|
onPointerMove: handlePointerMove,
|
|
63
63
|
"data-tone": tone,
|
|
64
|
+
"data-variant": variant ?? "flat",
|
|
64
65
|
"data-product": accent,
|
|
65
66
|
"data-material": surface === "glass" ? "glass" : void 0,
|
|
66
67
|
...props,
|
|
@@ -4,13 +4,15 @@ export type ChartColor = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
|
|
|
4
4
|
export interface ChartSeries {
|
|
5
5
|
/** Key of the value in each data row. */
|
|
6
6
|
key: string;
|
|
7
|
-
/** Name shown in the legend and the data table. Defaults to `key`. */
|
|
7
|
+
/** Name shown in the legend, the tooltip and the data table. Defaults to `key`. */
|
|
8
8
|
label?: string;
|
|
9
9
|
/** Palette colour, 1–8. Defaults to the series' position. */
|
|
10
10
|
color?: ChartColor;
|
|
11
11
|
}
|
|
12
12
|
/** Rounds up to 1, 2, 2.5 or 5 × 10ⁿ so the four gridlines get round labels. */
|
|
13
13
|
export declare function niceMax(max: number): number;
|
|
14
|
+
/** The axis range for a set of values: [0, nice max], or [−nice, +nice] when some are negative. */
|
|
15
|
+
export declare function niceDomain(values: number[]): [number, number];
|
|
14
16
|
declare const PLOT_HEIGHT: {
|
|
15
17
|
readonly sm: "h-32";
|
|
16
18
|
readonly md: "h-48";
|
|
@@ -33,7 +35,7 @@ interface CartesianProps<T> extends Omit<React.HTMLAttributes<HTMLElement>, 'tit
|
|
|
33
35
|
series: ChartSeries[];
|
|
34
36
|
/** Accessible name of the chart, e.g. "Revenue by month". */
|
|
35
37
|
title: string;
|
|
36
|
-
/** Formats axis labels, the
|
|
38
|
+
/** Formats axis labels, the tooltip and the data table. */
|
|
37
39
|
valueFormat?: (value: number) => string;
|
|
38
40
|
/** Height of the plot area. */
|
|
39
41
|
size?: keyof typeof PLOT_HEIGHT;
|
|
@@ -44,13 +46,13 @@ export interface BarChartProps<T> extends CartesianProps<T> {
|
|
|
44
46
|
/** Stack the series in one bar per category instead of side by side. */
|
|
45
47
|
stacked?: boolean;
|
|
46
48
|
}
|
|
47
|
-
/** Bars per category, grouped or stacked.
|
|
49
|
+
/** Bars per category, grouped or stacked. Negative values grow down from the zero line. */
|
|
48
50
|
export declare function BarChart<T extends object>({ stacked, ...props }: BarChartProps<T>): React.JSX.Element;
|
|
49
51
|
export interface LineChartProps<T> extends CartesianProps<T> {
|
|
50
|
-
/** Fill the area under each line. */
|
|
52
|
+
/** Fill the area under each line (down to the zero line). */
|
|
51
53
|
area?: boolean;
|
|
52
54
|
}
|
|
53
|
-
/** One line per series across the categories.
|
|
55
|
+
/** One line per series across the categories. Negative values go below the zero line. */
|
|
54
56
|
export declare function LineChart<T extends object>({ area, ...props }: LineChartProps<T>): React.JSX.Element;
|
|
55
57
|
export interface DonutChartProps extends Omit<React.HTMLAttributes<HTMLElement>, 'title'> {
|
|
56
58
|
data: {
|
|
@@ -11,6 +11,13 @@ function niceMax(max) {
|
|
|
11
11
|
const step = [1, 2, 2.5, 5, 10].find((s) => s * pow >= max);
|
|
12
12
|
return step * pow;
|
|
13
13
|
}
|
|
14
|
+
function niceDomain(values) {
|
|
15
|
+
const lo = Math.min(0, ...values);
|
|
16
|
+
const hi = Math.max(0, ...values);
|
|
17
|
+
if (lo === 0) return [0, niceMax(hi)];
|
|
18
|
+
if (hi === 0) return [-niceMax(-lo), 0];
|
|
19
|
+
return [-niceMax(-lo), niceMax(hi)];
|
|
20
|
+
}
|
|
14
21
|
const defaultFormat = (n) => n.toLocaleString();
|
|
15
22
|
const PLOT_HEIGHT = { sm: "h-32", md: "h-48", lg: "h-64" };
|
|
16
23
|
const VB_W = 300;
|
|
@@ -21,6 +28,7 @@ function ChartLegend({ items, className, ...props }) {
|
|
|
21
28
|
item.label
|
|
22
29
|
] }, item.label)) });
|
|
23
30
|
}
|
|
31
|
+
const valueOf = (row, key) => Number(row[key]) || 0;
|
|
24
32
|
function Frame({
|
|
25
33
|
data,
|
|
26
34
|
index,
|
|
@@ -29,33 +37,46 @@ function Frame({
|
|
|
29
37
|
valueFormat = defaultFormat,
|
|
30
38
|
size = "md",
|
|
31
39
|
legend,
|
|
32
|
-
|
|
40
|
+
domain,
|
|
33
41
|
className,
|
|
34
42
|
children,
|
|
35
43
|
...props
|
|
36
44
|
}) {
|
|
37
45
|
const labels = series.map((s) => s.label ?? s.key);
|
|
46
|
+
const [lo, hi] = domain;
|
|
38
47
|
const ticks = [1, 0.75, 0.5, 0.25, 0];
|
|
48
|
+
const zero = VB_H - (0 - lo) / (hi - lo) * VB_H;
|
|
39
49
|
return /* @__PURE__ */ jsxs("figure", { "aria-label": title, className: cn("m-0 flex flex-col gap-3", className), ...props, children: [
|
|
40
50
|
(legend ?? series.length > 1) && /* @__PURE__ */ jsx(ChartLegend, { "aria-hidden": "true", items: series.map((s, i) => ({ label: labels[i], color: s.color })) }),
|
|
41
51
|
/* @__PURE__ */ jsxs("div", { "aria-hidden": "true", className: "flex gap-2", children: [
|
|
42
|
-
/* @__PURE__ */ jsx("div", { className: cn("flex flex-col justify-between text-end text-label-sm tabular-nums text-[var(--color-on-surface-muted)]", PLOT_HEIGHT[size]), children: ticks.map((t) => /* @__PURE__ */ jsx("span", { className: "flex h-0 items-center justify-end", children: valueFormat(
|
|
52
|
+
/* @__PURE__ */ jsx("div", { className: cn("flex flex-col justify-between text-end text-label-sm tabular-nums text-[var(--color-on-surface-muted)]", PLOT_HEIGHT[size]), children: ticks.map((t) => /* @__PURE__ */ jsx("span", { className: "flex h-0 items-center justify-end", children: valueFormat(lo + (hi - lo) * t) }, t)) }),
|
|
43
53
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
|
|
44
|
-
/* @__PURE__ */ jsxs("
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
/* @__PURE__ */ jsxs("div", { className: cn("relative", PLOT_HEIGHT[size]), children: [
|
|
55
|
+
/* @__PURE__ */ jsxs("svg", { viewBox: `0 0 ${VB_W} ${VB_H}`, preserveAspectRatio: "none", className: "size-full overflow-visible rtl:-scale-x-100", children: [
|
|
56
|
+
ticks.map((t) => /* @__PURE__ */ jsx(
|
|
57
|
+
"line",
|
|
58
|
+
{
|
|
59
|
+
x1: "0",
|
|
60
|
+
x2: VB_W,
|
|
61
|
+
y1: VB_H * (1 - t),
|
|
62
|
+
y2: VB_H * (1 - t),
|
|
63
|
+
strokeWidth: "1",
|
|
64
|
+
vectorEffect: "non-scaling-stroke",
|
|
65
|
+
className: "stroke-[var(--color-outline-variant)]"
|
|
66
|
+
},
|
|
67
|
+
t
|
|
68
|
+
)),
|
|
69
|
+
/* @__PURE__ */ jsx("line", { x1: "0", x2: VB_W, y1: zero, y2: zero, strokeWidth: "1", vectorEffect: "non-scaling-stroke", className: "stroke-[var(--color-outline)]" }),
|
|
70
|
+
children
|
|
71
|
+
] }),
|
|
72
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 grid auto-cols-fr grid-flow-col", children: data.map((row, i) => /* @__PURE__ */ jsx("div", { className: "group/col relative rounded-shape-tooltip transition-colors hover:bg-[color-mix(in_oklab,var(--color-on-surface)_6%,transparent)]", children: /* @__PURE__ */ jsxs("div", { className: "pointer-events-none absolute top-1 start-1/2 z-10 min-w-max -translate-x-1/2 rounded-shape-tooltip bg-[var(--color-inverse-surface)] px-3 py-2 text-label-md text-[var(--color-inverse-on-surface)] opacity-0 shadow-elevation-2 transition-opacity group-hover/col:opacity-100 rtl:translate-x-1/2", children: [
|
|
73
|
+
/* @__PURE__ */ jsx("div", { className: "mb-1 font-semibold", children: String(row[index]) }),
|
|
74
|
+
series.map((s, j) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 tabular-nums", children: [
|
|
75
|
+
/* @__PURE__ */ jsx("span", { className: cn("size-2 shrink-0 rounded-full", BG[colorIndex(s.color, j)]) }),
|
|
76
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1", children: labels[j] }),
|
|
77
|
+
/* @__PURE__ */ jsx("span", { className: "ps-3", children: valueFormat(valueOf(row, s.key)) })
|
|
78
|
+
] }, s.key))
|
|
79
|
+
] }) }, i)) })
|
|
59
80
|
] }),
|
|
60
81
|
/* @__PURE__ */ jsx("div", { className: "grid auto-cols-fr grid-flow-col text-center text-label-sm text-[var(--color-on-surface-muted)]", children: data.map((row, i) => /* @__PURE__ */ jsx("span", { className: "truncate px-0.5", children: String(row[index]) }, i)) })
|
|
61
82
|
] })
|
|
@@ -68,46 +89,65 @@ function Frame({
|
|
|
68
89
|
] }) }),
|
|
69
90
|
/* @__PURE__ */ jsx("tbody", { children: data.map((row, i) => /* @__PURE__ */ jsxs("tr", { children: [
|
|
70
91
|
/* @__PURE__ */ jsx("th", { scope: "row", children: String(row[index]) }),
|
|
71
|
-
series.map((s) => /* @__PURE__ */ jsx("td", { children: valueFormat(
|
|
92
|
+
series.map((s) => /* @__PURE__ */ jsx("td", { children: valueFormat(valueOf(row, s.key)) }, s.key))
|
|
72
93
|
] }, i)) })
|
|
73
94
|
] })
|
|
74
95
|
] });
|
|
75
96
|
}
|
|
76
|
-
const valueOf = (row, key) => Math.max(0, Number(row[key]) || 0);
|
|
77
97
|
function BarChart({ stacked = false, ...props }) {
|
|
78
|
-
const { data, series
|
|
79
|
-
const
|
|
98
|
+
const { data, series } = props;
|
|
99
|
+
const totals = data.flatMap((row) => {
|
|
100
|
+
if (!stacked) return series.map((s) => valueOf(row, s.key));
|
|
101
|
+
const vals = series.map((s) => valueOf(row, s.key));
|
|
102
|
+
return [vals.filter((v) => v > 0).reduce((a, b) => a + b, 0), vals.filter((v) => v < 0).reduce((a, b) => a + b, 0)];
|
|
103
|
+
});
|
|
104
|
+
const domain = niceDomain(totals);
|
|
105
|
+
const [lo, hi] = domain;
|
|
106
|
+
const y = (v) => VB_H - (v - lo) / (hi - lo) * VB_H;
|
|
80
107
|
const slot = VB_W / Math.max(1, data.length);
|
|
81
108
|
const groupW = slot * 0.7;
|
|
82
109
|
const barW = stacked ? groupW : groupW / series.length;
|
|
83
|
-
return /* @__PURE__ */ jsx(Frame, { ...props,
|
|
84
|
-
let
|
|
110
|
+
return /* @__PURE__ */ jsx(Frame, { ...props, domain, children: data.map((row, i) => {
|
|
111
|
+
let up = 0;
|
|
112
|
+
let down = 0;
|
|
85
113
|
return /* @__PURE__ */ jsx("g", { children: series.map((s, j) => {
|
|
86
114
|
const v = valueOf(row, s.key);
|
|
87
|
-
const
|
|
115
|
+
const from = stacked ? v >= 0 ? up : down : 0;
|
|
116
|
+
const to = from + v;
|
|
117
|
+
if (stacked) {
|
|
118
|
+
if (v >= 0) up = to;
|
|
119
|
+
else down = to;
|
|
120
|
+
}
|
|
121
|
+
const top = Math.min(y(from), y(to));
|
|
88
122
|
const x = i * slot + (slot - groupW) / 2 + (stacked ? 0 : j * barW);
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
123
|
+
return /* @__PURE__ */ jsx(
|
|
124
|
+
"rect",
|
|
125
|
+
{
|
|
126
|
+
x,
|
|
127
|
+
y: top,
|
|
128
|
+
width: Math.max(0, barW - (stacked ? 0 : 1)),
|
|
129
|
+
height: Math.abs(y(to) - y(from)),
|
|
130
|
+
"data-negative": v < 0 ? "" : void 0,
|
|
131
|
+
className: cn("nx-chart-bar", FILL[colorIndex(s.color, j)])
|
|
132
|
+
},
|
|
133
|
+
s.key
|
|
134
|
+
);
|
|
92
135
|
}) }, i);
|
|
93
136
|
}) });
|
|
94
137
|
}
|
|
95
138
|
function LineChart({ area = false, ...props }) {
|
|
96
|
-
const { data, series
|
|
97
|
-
const
|
|
139
|
+
const { data, series } = props;
|
|
140
|
+
const domain = niceDomain(data.flatMap((row) => series.map((s) => valueOf(row, s.key))));
|
|
141
|
+
const [lo, hi] = domain;
|
|
98
142
|
const slot = VB_W / Math.max(1, data.length);
|
|
99
143
|
const x = (i) => i * slot + slot / 2;
|
|
100
|
-
const y = (v) => VB_H - v /
|
|
101
|
-
return /* @__PURE__ */ jsx(Frame, { ...props,
|
|
144
|
+
const y = (v) => VB_H - (v - lo) / (hi - lo) * VB_H;
|
|
145
|
+
return /* @__PURE__ */ jsx(Frame, { ...props, domain, children: series.map((s, j) => {
|
|
102
146
|
const c = colorIndex(s.color, j);
|
|
103
147
|
const pts = data.map((row, i) => `${x(i)},${y(valueOf(row, s.key))}`);
|
|
104
|
-
return /* @__PURE__ */ jsxs("g", { children: [
|
|
105
|
-
area && data.length > 0 && /* @__PURE__ */ jsx("polygon", { points: `${x(0)},${
|
|
106
|
-
/* @__PURE__ */ jsx("polyline", { points: pts.join(" "), fill: "none", strokeWidth: "2", strokeLinejoin: "round", strokeLinecap: "round", vectorEffect: "non-scaling-stroke", className: STROKE[c] })
|
|
107
|
-
data.map((row, i) => (
|
|
108
|
-
// A wide, invisible hit area per point carries the hover text.
|
|
109
|
-
/* @__PURE__ */ jsx("rect", { x: x(i) - slot / 2, y: "0", width: slot, height: VB_H, className: "fill-transparent", children: /* @__PURE__ */ jsx("title", { children: `${String(row[index])} \xB7 ${s.label ?? s.key}: ${valueFormat(valueOf(row, s.key))}` }) }, i)
|
|
110
|
-
))
|
|
148
|
+
return /* @__PURE__ */ jsxs("g", { className: "nx-chart-line", children: [
|
|
149
|
+
area && data.length > 0 && /* @__PURE__ */ jsx("polygon", { points: `${x(0)},${y(0)} ${pts.join(" ")} ${x(data.length - 1)},${y(0)}`, className: cn(FILL[c], "opacity-15") }),
|
|
150
|
+
/* @__PURE__ */ jsx("polyline", { points: pts.join(" "), fill: "none", strokeWidth: "2", strokeLinejoin: "round", strokeLinecap: "round", vectorEffect: "non-scaling-stroke", className: STROKE[c] })
|
|
111
151
|
] }, s.key);
|
|
112
152
|
}) });
|
|
113
153
|
}
|
|
@@ -149,7 +189,7 @@ function Sparkline({ values, label, color = 1, area = false, className, ...props
|
|
|
149
189
|
const step = values.length > 1 ? VB_W / (values.length - 1) : 0;
|
|
150
190
|
const pts = values.map((v, i) => `${i * step},${VB_H - 4 - (v - min) / span * (VB_H - 8)}`).join(" ");
|
|
151
191
|
const c = colorIndex(color, 0);
|
|
152
|
-
return /* @__PURE__ */
|
|
192
|
+
return /* @__PURE__ */ jsx(
|
|
153
193
|
"svg",
|
|
154
194
|
{
|
|
155
195
|
viewBox: `0 0 ${VB_W} ${VB_H}`,
|
|
@@ -157,10 +197,10 @@ function Sparkline({ values, label, color = 1, area = false, className, ...props
|
|
|
157
197
|
...label ? { role: "img", "aria-label": label } : { "aria-hidden": true },
|
|
158
198
|
className: cn("h-8 w-24 overflow-visible rtl:-scale-x-100", className),
|
|
159
199
|
...props,
|
|
160
|
-
children: [
|
|
200
|
+
children: /* @__PURE__ */ jsxs("g", { className: "nx-chart-line", children: [
|
|
161
201
|
area && values.length > 1 && /* @__PURE__ */ jsx("polygon", { points: `0,${VB_H} ${pts} ${VB_W},${VB_H}`, className: cn(FILL[c], "opacity-15") }),
|
|
162
202
|
/* @__PURE__ */ jsx("polyline", { points: pts, fill: "none", strokeWidth: "1.5", strokeLinejoin: "round", strokeLinecap: "round", vectorEffect: "non-scaling-stroke", className: STROKE[c] })
|
|
163
|
-
]
|
|
203
|
+
] })
|
|
164
204
|
}
|
|
165
205
|
);
|
|
166
206
|
}
|
|
@@ -170,5 +210,6 @@ export {
|
|
|
170
210
|
DonutChart,
|
|
171
211
|
LineChart,
|
|
172
212
|
Sparkline,
|
|
213
|
+
niceDomain,
|
|
173
214
|
niceMax
|
|
174
215
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { BarChart, LineChart, DonutChart, Sparkline, ChartLegend, niceMax } from './Chart.js';
|
|
1
|
+
export { BarChart, LineChart, DonutChart, Sparkline, ChartLegend, niceMax, niceDomain } from './Chart.js';
|
|
2
2
|
export type { BarChartProps, LineChartProps, DonutChartProps, SparklineProps, ChartLegendProps, ChartSeries, ChartColor } from './Chart.js';
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { BarChart, LineChart, DonutChart, Sparkline, ChartLegend, niceMax } from "./Chart.js";
|
|
1
|
+
import { BarChart, LineChart, DonutChart, Sparkline, ChartLegend, niceMax, niceDomain } from "./Chart.js";
|
|
2
2
|
export {
|
|
3
3
|
BarChart,
|
|
4
4
|
ChartLegend,
|
|
5
5
|
DonutChart,
|
|
6
6
|
LineChart,
|
|
7
7
|
Sparkline,
|
|
8
|
+
niceDomain,
|
|
8
9
|
niceMax
|
|
9
10
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -36,7 +36,9 @@ export type { NumberInputProps } from './components/NumberInput/index.js';
|
|
|
36
36
|
export { MoneyInput } from './components/MoneyInput/index.js';
|
|
37
37
|
export type { MoneyInputProps } from './components/MoneyInput/index.js';
|
|
38
38
|
export { Amount } from './components/Amount/index.js';
|
|
39
|
-
export {
|
|
39
|
+
export { Aurora } from './components/Aurora/index.js';
|
|
40
|
+
export type { AuroraProps } from './components/Aurora/index.js';
|
|
41
|
+
export { BarChart, LineChart, DonutChart, Sparkline, ChartLegend, niceMax, niceDomain } from './components/Chart/index.js';
|
|
40
42
|
export type { BarChartProps, LineChartProps, DonutChartProps, SparklineProps, ChartLegendProps, ChartSeries, ChartColor } from './components/Chart/index.js';
|
|
41
43
|
export type { AmountProps } from './components/Amount/index.js';
|
|
42
44
|
export { NumberTicker } from './components/NumberTicker/index.js';
|
package/dist/index.js
CHANGED
|
@@ -21,7 +21,8 @@ import { Textarea, textareaVariants } from "./components/Textarea/index.js";
|
|
|
21
21
|
import { NumberInput } from "./components/NumberInput/index.js";
|
|
22
22
|
import { MoneyInput } from "./components/MoneyInput/index.js";
|
|
23
23
|
import { Amount } from "./components/Amount/index.js";
|
|
24
|
-
import {
|
|
24
|
+
import { Aurora } from "./components/Aurora/index.js";
|
|
25
|
+
import { BarChart, LineChart, DonutChart, Sparkline, ChartLegend, niceMax, niceDomain } from "./components/Chart/index.js";
|
|
25
26
|
import { NumberTicker } from "./components/NumberTicker/index.js";
|
|
26
27
|
import { SearchInput } from "./components/SearchInput/index.js";
|
|
27
28
|
import { PasswordInput } from "./components/PasswordInput/index.js";
|
|
@@ -118,6 +119,7 @@ export {
|
|
|
118
119
|
Amount,
|
|
119
120
|
AppShell,
|
|
120
121
|
AspectRatio,
|
|
122
|
+
Aurora,
|
|
121
123
|
Autocomplete,
|
|
122
124
|
Avatar,
|
|
123
125
|
AvatarGroup,
|
|
@@ -255,6 +257,7 @@ export {
|
|
|
255
257
|
labelVariants,
|
|
256
258
|
linkVariants,
|
|
257
259
|
logoVariants,
|
|
260
|
+
niceDomain,
|
|
258
261
|
niceMax,
|
|
259
262
|
progressFillVariants,
|
|
260
263
|
progressTrackVariants,
|