hazo_ui 3.5.0 → 4.1.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/dist/index.js CHANGED
@@ -72,6 +72,7 @@ import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
72
72
  import * as TogglePrimitive from '@radix-ui/react-toggle';
73
73
  import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
74
74
  import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
75
+ import * as SliderPrimitive from '@radix-ui/react-slider';
75
76
  import { Toaster, toast } from 'sonner';
76
77
  export { toast as rawToast } from 'sonner';
77
78
  import { useHazoState } from 'hazo_state/client';
@@ -7390,6 +7391,51 @@ function ButtonGroupText({ className, asChild = false, ...props }) {
7390
7391
  function ButtonGroupSeparator({ className, orientation = "vertical", ...props }) {
7391
7392
  return /* @__PURE__ */ jsx(Separator3, { orientation, className: cn("bg-input relative !m-0 self-stretch data-[orientation=vertical]:h-auto", className), ...props });
7392
7393
  }
7394
+ var Slider = React26.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(
7395
+ SliderPrimitive.Root,
7396
+ {
7397
+ ref,
7398
+ className: cn("relative flex w-full touch-none select-none items-center", className),
7399
+ ...props,
7400
+ children: [
7401
+ /* @__PURE__ */ jsx(SliderPrimitive.Track, { className: "relative h-2 w-full grow overflow-hidden rounded-full bg-secondary", children: /* @__PURE__ */ jsx(SliderPrimitive.Range, { className: "absolute h-full bg-primary" }) }),
7402
+ /* @__PURE__ */ jsx(SliderPrimitive.Thumb, { className: "block h-5 w-5 rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50" })
7403
+ ]
7404
+ }
7405
+ ));
7406
+ Slider.displayName = SliderPrimitive.Root.displayName;
7407
+ var InputAffix = React26.forwardRef(
7408
+ ({ className, containerClassName, prefix, suffix, type = "text", ...props }, ref) => {
7409
+ return /* @__PURE__ */ jsxs(
7410
+ "div",
7411
+ {
7412
+ className: cn(
7413
+ "flex h-10 w-full items-center rounded-md border border-input bg-background text-sm ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2",
7414
+ containerClassName
7415
+ ),
7416
+ children: [
7417
+ prefix != null && /* @__PURE__ */ jsx("span", { className: "flex select-none items-center pl-3 text-muted-foreground", children: prefix }),
7418
+ /* @__PURE__ */ jsx(
7419
+ "input",
7420
+ {
7421
+ type,
7422
+ ref,
7423
+ className: cn(
7424
+ "h-full w-full bg-transparent px-3 py-2 outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
7425
+ prefix != null && "pl-2",
7426
+ suffix != null && "pr-2",
7427
+ className
7428
+ ),
7429
+ ...props
7430
+ }
7431
+ ),
7432
+ suffix != null && /* @__PURE__ */ jsx("span", { className: "flex select-none items-center pr-3 text-muted-foreground", children: suffix })
7433
+ ]
7434
+ }
7435
+ );
7436
+ }
7437
+ );
7438
+ InputAffix.displayName = "InputAffix";
7393
7439
  var SkeletonBase = React26.forwardRef(
7394
7440
  ({ className, ...rest }, ref) => /* @__PURE__ */ jsx(
7395
7441
  "div",
@@ -9668,573 +9714,12 @@ function pick_x_label_indices(length) {
9668
9714
  if (length === 2) return [0, 0, 1];
9669
9715
  return [0, Math.floor(length / 2), length - 1];
9670
9716
  }
9671
- var PAD_LEFT = 38;
9672
- var PAD_RIGHT = 14;
9673
- var PAD_TOP = 12;
9717
+ var PAD_LEFT = 32;
9718
+ var PAD_RIGHT = 8;
9719
+ var PAD_TOP = 10;
9674
9720
  var PAD_BOTTOM = 22;
9675
- var AXIS_LABEL_COLOR = "#8b949e";
9676
- var GRIDLINE_COLOR = "#2a3441";
9677
- function compute_geometry(data, width, height) {
9678
- const vals = data.filter((v) => v !== null && !Number.isNaN(v));
9679
- if (vals.length === 0) return null;
9680
- const mn = Math.min(...vals);
9681
- const mx = Math.max(...vals);
9682
- const rng = mx - mn || mx * 0.1 + 1;
9683
- const y_min = Math.max(0, mn - rng * 0.1);
9684
- const y_max = mx + rng * 0.1;
9685
- const y_rng = y_max - y_min || 1;
9686
- const plot_w = width - PAD_LEFT - PAD_RIGHT;
9687
- const plot_h = height - PAD_TOP - PAD_BOTTOM;
9688
- return {
9689
- vbox_w: width,
9690
- vbox_h: height,
9691
- y_min,
9692
- y_max,
9693
- cx: (i) => data.length <= 1 ? PAD_LEFT + plot_w / 2 : PAD_LEFT + i * plot_w / (data.length - 1),
9694
- cy: (v) => PAD_TOP + (1 - (v - y_min) / y_rng) * plot_h
9695
- };
9696
- }
9697
- function build_paths(data, g) {
9698
- let line_d = "";
9699
- let first_idx = -1;
9700
- data.forEach((v, i) => {
9701
- if (v === null || Number.isNaN(v)) return;
9702
- if (first_idx === -1) first_idx = i;
9703
- line_d += `${line_d ? " L" : "M"}${g.cx(i).toFixed(1)},${g.cy(v).toFixed(1)}`;
9704
- });
9705
- const last_idx = data.length - 1;
9706
- const last_v = data[last_idx];
9707
- const area_d = line_d && last_v !== null && last_v !== void 0 && !Number.isNaN(last_v) ? `${line_d} L${g.cx(last_idx).toFixed(1)},${g.vbox_h - PAD_BOTTOM} L${g.cx(first_idx).toFixed(1)},${g.vbox_h - PAD_BOTTOM} Z` : "";
9708
- return { line_d, area_d };
9709
- }
9710
- function LineChart({
9711
- data,
9712
- dates,
9713
- color: color2,
9714
- width = 360,
9715
- height = 130,
9716
- unit = "",
9717
- showTooltip = true,
9718
- className
9719
- }) {
9720
- const geo = compute_geometry(data, width, height);
9721
- const svg_ref = React26.useRef(null);
9722
- const [hover_idx, set_hover_idx] = React26.useState(null);
9723
- const handle_mouse_move = React26.useCallback(
9724
- (e) => {
9725
- if (!geo) return;
9726
- const rect = e.currentTarget.getBoundingClientRect();
9727
- if (rect.width === 0) return;
9728
- const vbox_x = (e.clientX - rect.left) / rect.width * geo.vbox_w;
9729
- const plot_w = geo.vbox_w - PAD_LEFT - PAD_RIGHT;
9730
- if (vbox_x < PAD_LEFT || vbox_x > geo.vbox_w - PAD_RIGHT) {
9731
- set_hover_idx(null);
9732
- return;
9733
- }
9734
- const ratio = (vbox_x - PAD_LEFT) / plot_w;
9735
- const idx = Math.round(ratio * (data.length - 1));
9736
- const clamped = Math.max(0, Math.min(data.length - 1, idx));
9737
- let resolved = clamped;
9738
- if (data[resolved] === null || Number.isNaN(data[resolved])) {
9739
- for (let step = 1; step < data.length; step += 1) {
9740
- const left_i = clamped - step;
9741
- const right_i = clamped + step;
9742
- if (left_i >= 0 && data[left_i] !== null && !Number.isNaN(data[left_i])) {
9743
- resolved = left_i;
9744
- break;
9745
- }
9746
- if (right_i < data.length && data[right_i] !== null && !Number.isNaN(data[right_i])) {
9747
- resolved = right_i;
9748
- break;
9749
- }
9750
- }
9751
- }
9752
- set_hover_idx(resolved);
9753
- },
9754
- [geo, data]
9755
- );
9756
- const handle_mouse_leave = React26.useCallback(() => set_hover_idx(null), []);
9757
- if (!geo) {
9758
- return /* @__PURE__ */ jsx(
9759
- "svg",
9760
- {
9761
- viewBox: `0 0 ${width} ${height}`,
9762
- className: cn("cls_hazo_chart cls_hazo_chart_empty", className),
9763
- style: { width: "100%", height: "auto", display: "block", maxHeight: `${height + 10}px` }
9764
- }
9765
- );
9766
- }
9767
- const { line_d, area_d } = build_paths(data, geo);
9768
- const x_label_idx = pick_x_label_indices(data.length);
9769
- const last_idx = data.length - 1;
9770
- const last_v = data[last_idx];
9771
- const has_last = last_v !== null && last_v !== void 0 && !Number.isNaN(last_v);
9772
- const hover_v = hover_idx !== null ? data[hover_idx] : null;
9773
- const hover_has_v = hover_v !== null && hover_v !== void 0 && !Number.isNaN(hover_v);
9774
- return /* @__PURE__ */ jsxs(
9775
- "svg",
9776
- {
9777
- ref: svg_ref,
9778
- viewBox: `0 0 ${width} ${height}`,
9779
- onMouseMove: showTooltip ? handle_mouse_move : void 0,
9780
- onMouseLeave: showTooltip ? handle_mouse_leave : void 0,
9781
- className: cn("cls_hazo_chart", className),
9782
- style: {
9783
- width: "100%",
9784
- height: "auto",
9785
- display: "block",
9786
- maxHeight: `${height + 10}px`,
9787
- cursor: showTooltip ? "crosshair" : "default"
9788
- },
9789
- children: [
9790
- [0, 1, 2].map((i) => {
9791
- const y = PAD_TOP + i / 2 * (geo.vbox_h - PAD_TOP - PAD_BOTTOM);
9792
- return /* @__PURE__ */ jsx(
9793
- "line",
9794
- {
9795
- x1: PAD_LEFT,
9796
- x2: geo.vbox_w - PAD_RIGHT,
9797
- y1: y,
9798
- y2: y,
9799
- stroke: GRIDLINE_COLOR,
9800
- strokeWidth: 0.5,
9801
- strokeDasharray: "2,3"
9802
- },
9803
- i
9804
- );
9805
- }),
9806
- area_d && /* @__PURE__ */ jsx("path", { d: area_d, fill: color2, fillOpacity: 0.12, stroke: "none" }),
9807
- line_d && /* @__PURE__ */ jsx("path", { d: line_d, stroke: color2, strokeWidth: 1.8, fill: "none" }),
9808
- /* @__PURE__ */ jsx("text", { x: PAD_LEFT - 4, y: PAD_TOP + 3, textAnchor: "end", fill: AXIS_LABEL_COLOR, fontSize: 9, children: format_num(geo.y_max) }),
9809
- /* @__PURE__ */ jsx(
9810
- "text",
9811
- {
9812
- x: PAD_LEFT - 4,
9813
- y: PAD_TOP + (geo.vbox_h - PAD_TOP - PAD_BOTTOM) / 2 + 3,
9814
- textAnchor: "end",
9815
- fill: AXIS_LABEL_COLOR,
9816
- fontSize: 9,
9817
- children: format_num((geo.y_max + geo.y_min) / 2)
9818
- }
9819
- ),
9820
- /* @__PURE__ */ jsx(
9821
- "text",
9822
- {
9823
- x: PAD_LEFT - 4,
9824
- y: geo.vbox_h - PAD_BOTTOM + 3,
9825
- textAnchor: "end",
9826
- fill: AXIS_LABEL_COLOR,
9827
- fontSize: 9,
9828
- children: format_num(geo.y_min)
9829
- }
9830
- ),
9831
- x_label_idx.map((idx, k) => {
9832
- const anchor = k === 0 ? "start" : k === 1 ? "middle" : "end";
9833
- const x_pos = geo.cx(idx);
9834
- return /* @__PURE__ */ jsx(
9835
- "text",
9836
- {
9837
- x: x_pos,
9838
- y: geo.vbox_h - 6,
9839
- textAnchor: anchor,
9840
- fill: AXIS_LABEL_COLOR,
9841
- fontSize: 9,
9842
- children: dates[idx] ?? ""
9843
- },
9844
- `x_${k}`
9845
- );
9846
- }),
9847
- has_last && hover_idx === null && (() => {
9848
- const x = geo.cx(last_idx);
9849
- const y = geo.cy(last_v);
9850
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
9851
- /* @__PURE__ */ jsx(
9852
- "line",
9853
- {
9854
- x1: x,
9855
- x2: PAD_LEFT,
9856
- y1: y,
9857
- y2: y,
9858
- stroke: color2,
9859
- strokeWidth: 0.5,
9860
- strokeDasharray: "2,2",
9861
- opacity: 0.4
9862
- }
9863
- ),
9864
- /* @__PURE__ */ jsx("circle", { cx: x, cy: y, r: 3.5, fill: color2, stroke: color2, strokeWidth: 2, fillOpacity: 0.3 }),
9865
- /* @__PURE__ */ jsx("circle", { cx: x, cy: y, r: 2, fill: color2 }),
9866
- /* @__PURE__ */ jsxs("text", { x: x - 6, y: y - 6, textAnchor: "end", fill: color2, fontSize: 10, fontWeight: 700, children: [
9867
- format_num(last_v),
9868
- unit
9869
- ] })
9870
- ] });
9871
- })(),
9872
- showTooltip && hover_idx !== null && hover_has_v && (() => {
9873
- const x = geo.cx(hover_idx);
9874
- const y = geo.cy(hover_v);
9875
- const label = `${format_num(hover_v)}${unit}`;
9876
- const date = dates[hover_idx] ?? "";
9877
- const bubble_text_w = Math.max(label.length, date.length) * 5.5 + 12;
9878
- const bubble_w = Math.max(bubble_text_w, 40);
9879
- const bubble_h = 26;
9880
- const flip = x + bubble_w + 6 > geo.vbox_w - PAD_RIGHT;
9881
- const bubble_x = flip ? x - bubble_w - 6 : x + 6;
9882
- const bubble_y = Math.max(PAD_TOP, Math.min(y - bubble_h / 2, geo.vbox_h - PAD_BOTTOM - bubble_h));
9883
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
9884
- /* @__PURE__ */ jsx(
9885
- "line",
9886
- {
9887
- x1: x,
9888
- x2: x,
9889
- y1: PAD_TOP,
9890
- y2: geo.vbox_h - PAD_BOTTOM,
9891
- stroke: color2,
9892
- strokeWidth: 0.5,
9893
- strokeDasharray: "2,2",
9894
- opacity: 0.6
9895
- }
9896
- ),
9897
- /* @__PURE__ */ jsx("circle", { cx: x, cy: y, r: 3, fill: color2 }),
9898
- /* @__PURE__ */ jsx(
9899
- "rect",
9900
- {
9901
- x: bubble_x,
9902
- y: bubble_y,
9903
- width: bubble_w,
9904
- height: bubble_h,
9905
- rx: 3,
9906
- fill: "#0d1117",
9907
- stroke: color2,
9908
- strokeWidth: 0.5,
9909
- fillOpacity: 0.92
9910
- }
9911
- ),
9912
- /* @__PURE__ */ jsx(
9913
- "text",
9914
- {
9915
- x: bubble_x + bubble_w / 2,
9916
- y: bubble_y + 11,
9917
- textAnchor: "middle",
9918
- fill: color2,
9919
- fontSize: 10,
9920
- fontWeight: 700,
9921
- children: label
9922
- }
9923
- ),
9924
- /* @__PURE__ */ jsx(
9925
- "text",
9926
- {
9927
- x: bubble_x + bubble_w / 2,
9928
- y: bubble_y + 22,
9929
- textAnchor: "middle",
9930
- fill: AXIS_LABEL_COLOR,
9931
- fontSize: 8,
9932
- children: date
9933
- }
9934
- )
9935
- ] });
9936
- })()
9937
- ]
9938
- }
9939
- );
9940
- }
9941
- var PAD_LEFT2 = 38;
9942
- var PAD_RIGHT2 = 14;
9943
- var PAD_TOP2 = 12;
9944
- var PAD_BOTTOM2 = 22;
9945
- var AXIS_LABEL_COLOR2 = "#8b949e";
9946
- var GRIDLINE_COLOR2 = "#2a3441";
9947
- function compute_geometry2(series, width, height) {
9948
- const all_vals = [];
9949
- let n = 0;
9950
- for (const s of series) {
9951
- n = Math.max(n, s.data.length);
9952
- for (const v of s.data) if (v !== null && !Number.isNaN(v)) all_vals.push(v);
9953
- }
9954
- if (all_vals.length === 0 || n === 0) return null;
9955
- const mn = Math.min(...all_vals);
9956
- const mx = Math.max(...all_vals);
9957
- const rng = mx - mn || mx * 0.1 + 1;
9958
- const y_min = Math.max(0, mn - rng * 0.05);
9959
- const y_max = mx + rng * 0.05;
9960
- const y_rng = y_max - y_min || 1;
9961
- const plot_w = width - PAD_LEFT2 - PAD_RIGHT2;
9962
- const plot_h = height - PAD_TOP2 - PAD_BOTTOM2;
9963
- return {
9964
- vbox_w: width,
9965
- vbox_h: height,
9966
- y_min,
9967
- y_max,
9968
- point_count: n,
9969
- cx: (i) => n <= 1 ? PAD_LEFT2 + plot_w / 2 : PAD_LEFT2 + i * plot_w / (n - 1),
9970
- cy: (v) => PAD_TOP2 + (1 - (v - y_min) / y_rng) * plot_h
9971
- };
9972
- }
9973
- function MultiLineChart({
9974
- series,
9975
- dates,
9976
- width = 360,
9977
- height = 140,
9978
- showTooltip = true,
9979
- showLegend = true,
9980
- className
9981
- }) {
9982
- const geo = compute_geometry2(series, width, height);
9983
- const [hover_idx, set_hover_idx] = React26.useState(null);
9984
- const handle_mouse_move = React26.useCallback(
9985
- (e) => {
9986
- if (!geo) return;
9987
- const rect = e.currentTarget.getBoundingClientRect();
9988
- if (rect.width === 0) return;
9989
- const vbox_x = (e.clientX - rect.left) / rect.width * geo.vbox_w;
9990
- const plot_w = geo.vbox_w - PAD_LEFT2 - PAD_RIGHT2;
9991
- if (vbox_x < PAD_LEFT2 || vbox_x > geo.vbox_w - PAD_RIGHT2) {
9992
- set_hover_idx(null);
9993
- return;
9994
- }
9995
- const ratio = (vbox_x - PAD_LEFT2) / plot_w;
9996
- const idx = Math.round(ratio * (geo.point_count - 1));
9997
- set_hover_idx(Math.max(0, Math.min(geo.point_count - 1, idx)));
9998
- },
9999
- [geo]
10000
- );
10001
- const handle_mouse_leave = React26.useCallback(() => set_hover_idx(null), []);
10002
- if (!geo) {
10003
- return /* @__PURE__ */ jsx(
10004
- "svg",
10005
- {
10006
- viewBox: `0 0 ${width} ${height}`,
10007
- className: cn("cls_hazo_chart cls_hazo_chart_empty", className),
10008
- style: { width: "100%", height: "auto", display: "block", maxHeight: `${height + 10}px` }
10009
- }
10010
- );
10011
- }
10012
- const x_label_idx = pick_x_label_indices(geo.point_count);
10013
- return /* @__PURE__ */ jsxs("div", { className: cn("cls_hazo_chart_wrapper", className), children: [
10014
- /* @__PURE__ */ jsxs(
10015
- "svg",
10016
- {
10017
- viewBox: `0 0 ${width} ${height}`,
10018
- onMouseMove: showTooltip ? handle_mouse_move : void 0,
10019
- onMouseLeave: showTooltip ? handle_mouse_leave : void 0,
10020
- className: "cls_hazo_chart cls_hazo_chart_multi",
10021
- style: {
10022
- width: "100%",
10023
- height: "auto",
10024
- display: "block",
10025
- maxHeight: `${height + 10}px`,
10026
- cursor: showTooltip ? "crosshair" : "default"
10027
- },
10028
- children: [
10029
- [0, 1, 2].map((i) => {
10030
- const y = PAD_TOP2 + i / 2 * (geo.vbox_h - PAD_TOP2 - PAD_BOTTOM2);
10031
- return /* @__PURE__ */ jsx(
10032
- "line",
10033
- {
10034
- x1: PAD_LEFT2,
10035
- x2: geo.vbox_w - PAD_RIGHT2,
10036
- y1: y,
10037
- y2: y,
10038
- stroke: GRIDLINE_COLOR2,
10039
- strokeWidth: 0.5,
10040
- strokeDasharray: "2,3"
10041
- },
10042
- i
10043
- );
10044
- }),
10045
- /* @__PURE__ */ jsx("text", { x: PAD_LEFT2 - 4, y: PAD_TOP2 + 3, textAnchor: "end", fill: AXIS_LABEL_COLOR2, fontSize: 9, children: format_num(geo.y_max) }),
10046
- /* @__PURE__ */ jsx(
10047
- "text",
10048
- {
10049
- x: PAD_LEFT2 - 4,
10050
- y: PAD_TOP2 + (geo.vbox_h - PAD_TOP2 - PAD_BOTTOM2) / 2 + 3,
10051
- textAnchor: "end",
10052
- fill: AXIS_LABEL_COLOR2,
10053
- fontSize: 9,
10054
- children: format_num((geo.y_max + geo.y_min) / 2)
10055
- }
10056
- ),
10057
- /* @__PURE__ */ jsx("text", { x: PAD_LEFT2 - 4, y: geo.vbox_h - PAD_BOTTOM2 + 3, textAnchor: "end", fill: AXIS_LABEL_COLOR2, fontSize: 9, children: format_num(geo.y_min) }),
10058
- x_label_idx.map((idx, k) => {
10059
- const anchor = k === 0 ? "start" : k === 1 ? "middle" : "end";
10060
- return /* @__PURE__ */ jsx(
10061
- "text",
10062
- {
10063
- x: geo.cx(idx),
10064
- y: geo.vbox_h - 6,
10065
- textAnchor: anchor,
10066
- fill: AXIS_LABEL_COLOR2,
10067
- fontSize: 9,
10068
- children: dates[idx] ?? ""
10069
- },
10070
- `x_${k}`
10071
- );
10072
- }),
10073
- series.map((s, s_idx) => {
10074
- let d = "";
10075
- s.data.forEach((v, i) => {
10076
- if (v === null || Number.isNaN(v)) return;
10077
- d += `${d ? " L" : "M"}${geo.cx(i).toFixed(1)},${geo.cy(v).toFixed(1)}`;
10078
- });
10079
- const last_idx = s.data.length - 1;
10080
- const last_v = s.data[last_idx];
10081
- const has_last = last_v !== null && last_v !== void 0 && !Number.isNaN(last_v);
10082
- return /* @__PURE__ */ jsxs("g", { children: [
10083
- d && /* @__PURE__ */ jsx("path", { d, stroke: s.color, strokeWidth: 1.7, fill: "none" }),
10084
- has_last && hover_idx === null && /* @__PURE__ */ jsxs(Fragment$1, { children: [
10085
- /* @__PURE__ */ jsx(
10086
- "circle",
10087
- {
10088
- cx: geo.cx(last_idx),
10089
- cy: geo.cy(last_v),
10090
- r: 3,
10091
- fill: s.color,
10092
- fillOpacity: 0.3,
10093
- stroke: s.color,
10094
- strokeWidth: 1.5
10095
- }
10096
- ),
10097
- /* @__PURE__ */ jsx(
10098
- "text",
10099
- {
10100
- x: geo.cx(last_idx) - 5,
10101
- y: geo.cy(last_v) - 5,
10102
- textAnchor: "end",
10103
- fill: s.color,
10104
- fontSize: 9,
10105
- fontWeight: 700,
10106
- children: format_num(last_v)
10107
- }
10108
- )
10109
- ] })
10110
- ] }, `series_${s_idx}`);
10111
- }),
10112
- showTooltip && hover_idx !== null && (() => {
10113
- const x = geo.cx(hover_idx);
10114
- const items = series.map((s) => ({
10115
- label: s.label,
10116
- color: s.color,
10117
- value: s.data[hover_idx] ?? null
10118
- })).filter((it) => it.value !== null && !Number.isNaN(it.value));
10119
- if (items.length === 0) return null;
10120
- const bubble_w = 70;
10121
- const row_h = 12;
10122
- const bubble_h = items.length * row_h + 18;
10123
- const flip = x + bubble_w + 6 > geo.vbox_w - PAD_RIGHT2;
10124
- const bubble_x = flip ? x - bubble_w - 6 : x + 6;
10125
- const bubble_y = Math.max(PAD_TOP2, Math.min(PAD_TOP2 + 5, geo.vbox_h - PAD_BOTTOM2 - bubble_h));
10126
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
10127
- /* @__PURE__ */ jsx(
10128
- "line",
10129
- {
10130
- x1: x,
10131
- x2: x,
10132
- y1: PAD_TOP2,
10133
- y2: geo.vbox_h - PAD_BOTTOM2,
10134
- stroke: AXIS_LABEL_COLOR2,
10135
- strokeWidth: 0.5,
10136
- strokeDasharray: "2,2",
10137
- opacity: 0.6
10138
- }
10139
- ),
10140
- items.map((it) => /* @__PURE__ */ jsx(
10141
- "circle",
10142
- {
10143
- cx: x,
10144
- cy: geo.cy(it.value),
10145
- r: 3,
10146
- fill: it.color
10147
- },
10148
- `hd_${it.label}`
10149
- )),
10150
- /* @__PURE__ */ jsx(
10151
- "rect",
10152
- {
10153
- x: bubble_x,
10154
- y: bubble_y,
10155
- width: bubble_w,
10156
- height: bubble_h,
10157
- rx: 3,
10158
- fill: "#0d1117",
10159
- stroke: AXIS_LABEL_COLOR2,
10160
- strokeWidth: 0.5,
10161
- fillOpacity: 0.92
10162
- }
10163
- ),
10164
- /* @__PURE__ */ jsx("text", { x: bubble_x + 6, y: bubble_y + 10, fill: AXIS_LABEL_COLOR2, fontSize: 8, children: dates[hover_idx] ?? "" }),
10165
- items.map((it, i) => /* @__PURE__ */ jsxs("g", { children: [
10166
- /* @__PURE__ */ jsx(
10167
- "rect",
10168
- {
10169
- x: bubble_x + 6,
10170
- y: bubble_y + 14 + i * row_h,
10171
- width: 6,
10172
- height: 6,
10173
- fill: it.color
10174
- }
10175
- ),
10176
- /* @__PURE__ */ jsx(
10177
- "text",
10178
- {
10179
- x: bubble_x + 16,
10180
- y: bubble_y + 20 + i * row_h,
10181
- fill: it.color,
10182
- fontSize: 9,
10183
- fontWeight: 600,
10184
- children: format_num(it.value)
10185
- }
10186
- )
10187
- ] }, `row_${i}`))
10188
- ] });
10189
- })()
10190
- ]
10191
- }
10192
- ),
10193
- showLegend && /* @__PURE__ */ jsx(
10194
- "div",
10195
- {
10196
- className: "cls_hazo_chart_legend",
10197
- style: {
10198
- display: "flex",
10199
- gap: "12px",
10200
- justifyContent: "center",
10201
- marginTop: "4px",
10202
- fontSize: "10px",
10203
- color: AXIS_LABEL_COLOR2,
10204
- flexWrap: "wrap"
10205
- },
10206
- children: series.map((s) => /* @__PURE__ */ jsxs(
10207
- "span",
10208
- {
10209
- style: { display: "inline-flex", alignItems: "center", gap: "4px" },
10210
- children: [
10211
- /* @__PURE__ */ jsx(
10212
- "i",
10213
- {
10214
- style: {
10215
- display: "inline-block",
10216
- width: "8px",
10217
- height: "8px",
10218
- background: s.color,
10219
- borderRadius: "1px"
10220
- }
10221
- }
10222
- ),
10223
- s.label
10224
- ]
10225
- },
10226
- s.label
10227
- ))
10228
- }
10229
- )
10230
- ] });
10231
- }
10232
- var PAD_LEFT3 = 32;
10233
- var PAD_RIGHT3 = 8;
10234
- var PAD_TOP3 = 10;
10235
- var PAD_BOTTOM3 = 22;
10236
9721
  var BAR_GAP_RATIO = 0.25;
10237
- var AXIS_LABEL_COLOR3 = "#8b949e";
9722
+ var AXIS_LABEL_COLOR = "#8b949e";
10238
9723
  function StackedBars({
10239
9724
  bars,
10240
9725
  width = 360,
@@ -10244,11 +9729,11 @@ function StackedBars({
10244
9729
  }) {
10245
9730
  const totals = bars.map((b) => b.segments.reduce((sum, s) => sum + s.value, 0));
10246
9731
  const y_max = Math.max(0, ...totals) || 1;
10247
- const plot_w = width - PAD_LEFT3 - PAD_RIGHT3;
10248
- const plot_h = height - PAD_TOP3 - PAD_BOTTOM3;
9732
+ const plot_w = width - PAD_LEFT - PAD_RIGHT;
9733
+ const plot_h = height - PAD_TOP - PAD_BOTTOM;
10249
9734
  const slot_w = bars.length > 0 ? plot_w / bars.length : 0;
10250
9735
  const bar_w = slot_w * (1 - BAR_GAP_RATIO);
10251
- const x_for = (i) => PAD_LEFT3 + i * slot_w + (slot_w - bar_w) / 2;
9736
+ const x_for = (i) => PAD_LEFT + i * slot_w + (slot_w - bar_w) / 2;
10252
9737
  const x_label_idx = pick_x_label_indices(bars.length);
10253
9738
  return /* @__PURE__ */ jsxs(
10254
9739
  "svg",
@@ -10258,14 +9743,14 @@ function StackedBars({
10258
9743
  style: { width: "100%", height: "auto", display: "block", maxHeight: `${height + 10}px` },
10259
9744
  children: [
10260
9745
  showYAxis && /* @__PURE__ */ jsxs(Fragment$1, { children: [
10261
- /* @__PURE__ */ jsx("text", { x: PAD_LEFT3 - 4, y: PAD_TOP3 + 3, textAnchor: "end", fill: AXIS_LABEL_COLOR3, fontSize: 9, children: format_num(y_max) }),
9746
+ /* @__PURE__ */ jsx("text", { x: PAD_LEFT - 4, y: PAD_TOP + 3, textAnchor: "end", fill: AXIS_LABEL_COLOR, fontSize: 9, children: format_num(y_max) }),
10262
9747
  /* @__PURE__ */ jsx(
10263
9748
  "text",
10264
9749
  {
10265
- x: PAD_LEFT3 - 4,
10266
- y: PAD_TOP3 + plot_h / 2 + 3,
9750
+ x: PAD_LEFT - 4,
9751
+ y: PAD_TOP + plot_h / 2 + 3,
10267
9752
  textAnchor: "end",
10268
- fill: AXIS_LABEL_COLOR3,
9753
+ fill: AXIS_LABEL_COLOR,
10269
9754
  fontSize: 9,
10270
9755
  children: format_num(y_max / 2)
10271
9756
  }
@@ -10273,17 +9758,17 @@ function StackedBars({
10273
9758
  /* @__PURE__ */ jsx(
10274
9759
  "text",
10275
9760
  {
10276
- x: PAD_LEFT3 - 4,
10277
- y: height - PAD_BOTTOM3 + 3,
9761
+ x: PAD_LEFT - 4,
9762
+ y: height - PAD_BOTTOM + 3,
10278
9763
  textAnchor: "end",
10279
- fill: AXIS_LABEL_COLOR3,
9764
+ fill: AXIS_LABEL_COLOR,
10280
9765
  fontSize: 9,
10281
9766
  children: "0"
10282
9767
  }
10283
9768
  )
10284
9769
  ] }),
10285
9770
  bars.map((bar, i) => {
10286
- let cursor_y = height - PAD_BOTTOM3;
9771
+ let cursor_y = height - PAD_BOTTOM;
10287
9772
  return /* @__PURE__ */ jsx("g", { children: bar.segments.map((seg, s_idx) => {
10288
9773
  if (seg.value <= 0) return null;
10289
9774
  const seg_h = seg.value / y_max * plot_h;
@@ -10311,7 +9796,7 @@ function StackedBars({
10311
9796
  x: x_pos,
10312
9797
  y: height - 6,
10313
9798
  textAnchor: anchor,
10314
- fill: AXIS_LABEL_COLOR3,
9799
+ fill: AXIS_LABEL_COLOR,
10315
9800
  fontSize: 9,
10316
9801
  children: bars[idx]?.label ?? ""
10317
9802
  },
@@ -10360,15 +9845,15 @@ function DateRangeSelector({
10360
9845
  }
10361
9846
  );
10362
9847
  }
10363
- var PAD_LEFT4 = 80;
10364
- var PAD_RIGHT4 = 72;
10365
- var PAD_TOP4 = 12;
10366
- var PAD_BOTTOM4 = 12;
9848
+ var PAD_LEFT2 = 80;
9849
+ var PAD_RIGHT2 = 72;
9850
+ var PAD_TOP2 = 12;
9851
+ var PAD_BOTTOM2 = 12;
10367
9852
  var ROW_H = 44;
10368
9853
  var LABEL_H = 14;
10369
9854
  var BAR_H = 22;
10370
- var AXIS_LABEL_COLOR4 = "#8b949e";
10371
- var GRIDLINE_COLOR3 = "#2a3441";
9855
+ var AXIS_LABEL_COLOR2 = "#8b949e";
9856
+ var GRIDLINE_COLOR = "#2a3441";
10372
9857
  function step_total(step) {
10373
9858
  if (step.value !== void 0) return step.value;
10374
9859
  if (step.segments) return step.segments.reduce((s, g) => s + g.value, 0);
@@ -10388,15 +9873,15 @@ function FunnelChart({
10388
9873
  const fmt = valueFormat ?? format_num;
10389
9874
  const totals = steps.map(step_total);
10390
9875
  const value_max = Math.max(1, ...totals);
10391
- const plot_w = width - PAD_LEFT4 - PAD_RIGHT4;
10392
- const vbox_h = height ?? PAD_TOP4 + steps.length * ROW_H + PAD_BOTTOM4;
9876
+ const plot_w = width - PAD_LEFT2 - PAD_RIGHT2;
9877
+ const vbox_h = height ?? PAD_TOP2 + steps.length * ROW_H + PAD_BOTTOM2;
10393
9878
  const handle_mouse_move = React26.useCallback(
10394
9879
  (e) => {
10395
9880
  if (steps.length === 0) return;
10396
9881
  const rect = e.currentTarget.getBoundingClientRect();
10397
9882
  if (rect.height === 0) return;
10398
9883
  const vbox_y = (e.clientY - rect.top) / rect.height * vbox_h;
10399
- const row_idx = Math.floor((vbox_y - PAD_TOP4) / ROW_H);
9884
+ const row_idx = Math.floor((vbox_y - PAD_TOP2) / ROW_H);
10400
9885
  if (row_idx < 0 || row_idx >= steps.length) {
10401
9886
  set_hover_idx(null);
10402
9887
  return;
@@ -10423,11 +9908,11 @@ function FunnelChart({
10423
9908
  steps.length > 0 && /* @__PURE__ */ jsx(
10424
9909
  "line",
10425
9910
  {
10426
- x1: PAD_LEFT4 + plot_w / 2,
10427
- x2: PAD_LEFT4 + plot_w / 2,
10428
- y1: PAD_TOP4,
10429
- y2: PAD_TOP4 + steps.length * ROW_H,
10430
- stroke: GRIDLINE_COLOR3,
9911
+ x1: PAD_LEFT2 + plot_w / 2,
9912
+ x2: PAD_LEFT2 + plot_w / 2,
9913
+ y1: PAD_TOP2,
9914
+ y2: PAD_TOP2 + steps.length * ROW_H,
9915
+ stroke: GRIDLINE_COLOR,
10431
9916
  strokeWidth: 0.5,
10432
9917
  strokeDasharray: "2,3"
10433
9918
  }
@@ -10435,8 +9920,8 @@ function FunnelChart({
10435
9920
  steps.map((step, i) => {
10436
9921
  const total = totals[i];
10437
9922
  const bar_w = total / value_max * plot_w;
10438
- const bar_x = PAD_LEFT4 + (plot_w - bar_w) / 2;
10439
- const bar_y = PAD_TOP4 + i * ROW_H + LABEL_H;
9923
+ const bar_x = PAD_LEFT2 + (plot_w - bar_w) / 2;
9924
+ const bar_y = PAD_TOP2 + i * ROW_H + LABEL_H;
10440
9925
  const pct_first = i === 0 ? 100 : Math.round(total / (totals[0] || 1) * 100);
10441
9926
  const value_label = i === 0 ? `${fmt(total)} (100%)` : `${fmt(total)} (${pct_first}%)`;
10442
9927
  const dropoff = i > 0 ? totals[i - 1] - total : 0;
@@ -10445,10 +9930,10 @@ function FunnelChart({
10445
9930
  /* @__PURE__ */ jsx(
10446
9931
  "text",
10447
9932
  {
10448
- x: PAD_LEFT4 - 6,
9933
+ x: PAD_LEFT2 - 6,
10449
9934
  y: bar_y + BAR_H / 2 + 4,
10450
9935
  textAnchor: "end",
10451
- fill: AXIS_LABEL_COLOR4,
9936
+ fill: AXIS_LABEL_COLOR2,
10452
9937
  fontSize: 9,
10453
9938
  children: step.label
10454
9939
  }
@@ -10490,7 +9975,7 @@ function FunnelChart({
10490
9975
  x: label_x,
10491
9976
  y: bar_y + BAR_H / 2 + 10,
10492
9977
  textAnchor: "start",
10493
- fill: AXIS_LABEL_COLOR4,
9978
+ fill: AXIS_LABEL_COLOR2,
10494
9979
  fontSize: 8,
10495
9980
  children: `\u2212${fmt(dropoff)}`
10496
9981
  }
@@ -10505,8 +9990,8 @@ function FunnelChart({
10505
9990
  const pct_prev = i === 0 ? 100 : Math.round(total / (totals[i - 1] || 1) * 100);
10506
9991
  const dropoff = i > 0 ? totals[i - 1] - total : 0;
10507
9992
  const bar_w = total / value_max * plot_w;
10508
- const bar_x = PAD_LEFT4 + (plot_w - bar_w) / 2;
10509
- const bar_y = PAD_TOP4 + i * ROW_H + LABEL_H;
9993
+ const bar_x = PAD_LEFT2 + (plot_w - bar_w) / 2;
9994
+ const bar_y = PAD_TOP2 + i * ROW_H + LABEL_H;
10510
9995
  const bubble_anchor_y = bar_y + BAR_H / 2;
10511
9996
  const lines = [
10512
9997
  { text: step.label, accent: true },
@@ -10560,7 +10045,7 @@ function FunnelChart({
10560
10045
  {
10561
10046
  x: bubble_x + 7,
10562
10047
  y: bubble_y + pad_v + k * line_h + line_h * 0.75,
10563
- fill: line.accent ? color2 : AXIS_LABEL_COLOR4,
10048
+ fill: line.accent ? color2 : AXIS_LABEL_COLOR2,
10564
10049
  fontSize: line.accent ? 10 : 8,
10565
10050
  fontWeight: line.accent ? 700 : 400,
10566
10051
  children: line.text
@@ -11030,6 +10515,6 @@ function HazoUiEtaProgress({
11030
10515
  );
11031
10516
  }
11032
10517
 
11033
- export { ANIMATION_PRESETS, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CELEBRATION_GRADIENT, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CelebrationProvider, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, CommandNodeExtension, CommandPill, CommandPopover, DateRangeSelector, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, ErrorBanner, ErrorPage, FunnelChart, HazoContextProvider, HazoUiConfirmDialog, HazoUiDialog, DialogClose as HazoUiDialogClose, DialogContent as HazoUiDialogContent, DialogDescription as HazoUiDialogDescription, DialogFooter as HazoUiDialogFooter, DialogHeader as HazoUiDialogHeader, DialogOverlay as HazoUiDialogOverlay, DialogPortal as HazoUiDialogPortal, Dialog as HazoUiDialogRoot, DialogTitle as HazoUiDialogTitle, DialogTrigger as HazoUiDialogTrigger, HazoUiEtaProgress, HazoUiFlexInput, HazoUiFlexRadio, HazoUiKanban, HazoUiKanbanFilter, HazoUiMultiFilterDialog, HazoUiMultiSortDialog, HazoUiPillRadio, HazoUiProgressBar, HazoUiRte, HazoUiTable, HazoUiTextarea, HazoUiTextbox, HazoUiToaster, HoverCard, HoverCardContent, HoverCardTrigger, Input, InverseSparkline, Label3 as Label, LineChart, LoadingTimeout, MarkdownEditor, MultiLineChart, Popover, PopoverContent, PopoverTrigger, ProgressiveImage, RadioGroup, RadioGroupItem, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Command as ShadcnCommand, CommandEmpty as ShadcnCommandEmpty, CommandGroup as ShadcnCommandGroup, CommandInput as ShadcnCommandInput, CommandItem as ShadcnCommandItem, CommandList as ShadcnCommandList, Skeleton, SkeletonBar, SkeletonCircle, SkeletonGroup, SkeletonRect, Sparkline, Spinner, StackedBars, Switch, Table2 as Table, TableBody, TableCaption, TableCell2 as TableCell, TableFooter, TableHead, TableHeader2 as TableHeader, TableRow2 as TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, applyKanbanFilter, buttonGroupVariants, celebrate, cn, computeEta, create_command_suggestion_extension, easeToward, errorToast, format_num, generateUUID, get_hazo_ui_config, get_logger, median, parse_commands_from_text, pick_x_label_indices, reset_hazo_ui_config, resolve_animation_classes, set_hazo_ui_config, set_logger, successToast, text_to_tiptap_content, toggleVariants, useClickOutside, useCopyToClipboard, useDebounce, useErrorDisplay, useEtaProgress, useFullscreen, useIsMobile, useLoadingState, useLocalStorage, useMediaQuery, useSessionStorage, useViewport, useWakeLock, use_fullscreen, use_wake_lock };
10518
+ export { ANIMATION_PRESETS, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CELEBRATION_GRADIENT, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CelebrationProvider, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, CommandNodeExtension, CommandPill, CommandPopover, DateRangeSelector, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, ErrorBanner, ErrorPage, FunnelChart, HazoContextProvider, HazoUiConfirmDialog, HazoUiDialog, DialogClose as HazoUiDialogClose, DialogContent as HazoUiDialogContent, DialogDescription as HazoUiDialogDescription, DialogFooter as HazoUiDialogFooter, DialogHeader as HazoUiDialogHeader, DialogOverlay as HazoUiDialogOverlay, DialogPortal as HazoUiDialogPortal, Dialog as HazoUiDialogRoot, DialogTitle as HazoUiDialogTitle, DialogTrigger as HazoUiDialogTrigger, HazoUiEtaProgress, HazoUiFlexInput, HazoUiFlexRadio, HazoUiKanban, HazoUiKanbanFilter, HazoUiMultiFilterDialog, HazoUiMultiSortDialog, HazoUiPillRadio, HazoUiProgressBar, HazoUiRte, HazoUiTable, HazoUiTextarea, HazoUiTextbox, HazoUiToaster, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputAffix, InverseSparkline, Label3 as Label, LoadingTimeout, MarkdownEditor, Popover, PopoverContent, PopoverTrigger, ProgressiveImage, RadioGroup, RadioGroupItem, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Command as ShadcnCommand, CommandEmpty as ShadcnCommandEmpty, CommandGroup as ShadcnCommandGroup, CommandInput as ShadcnCommandInput, CommandItem as ShadcnCommandItem, CommandList as ShadcnCommandList, Skeleton, SkeletonBar, SkeletonCircle, SkeletonGroup, SkeletonRect, Slider, Sparkline, Spinner, StackedBars, Switch, Table2 as Table, TableBody, TableCaption, TableCell2 as TableCell, TableFooter, TableHead, TableHeader2 as TableHeader, TableRow2 as TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, applyKanbanFilter, buttonGroupVariants, celebrate, cn, computeEta, create_command_suggestion_extension, easeToward, errorToast, format_num, generateUUID, get_hazo_ui_config, get_logger, median, parse_commands_from_text, pick_x_label_indices, reset_hazo_ui_config, resolve_animation_classes, set_hazo_ui_config, set_logger, successToast, text_to_tiptap_content, toggleVariants, useClickOutside, useCopyToClipboard, useDebounce, useErrorDisplay, useEtaProgress, useFullscreen, useIsMobile, useLoadingState, useLocalStorage, useMediaQuery, useSessionStorage, useViewport, useWakeLock, use_fullscreen, use_wake_lock };
11034
10519
  //# sourceMappingURL=index.js.map
11035
10520
  //# sourceMappingURL=index.js.map