@dimasbaguspm/versaur 0.0.31 → 0.0.32

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.
@@ -1,7 +1,7 @@
1
1
  import { c as cva, j as jsxRuntimeExports, a as cn } from "./index-DOdDlCoL.js";
2
2
  import * as React from "react";
3
- import React__default, { forwardRef, useState, useEffect, useCallback, useRef, createContext, useContext } from "react";
4
- import { X, XIcon, ImageOff } from "lucide-react";
3
+ import React__default, { forwardRef, useState, useEffect, useCallback, useRef, useId, cloneElement, createContext, useContext } from "react";
4
+ import { EllipsisVerticalIcon, X, XIcon, ImageOff } from "lucide-react";
5
5
  import { S as Skeleton } from "./skeleton-BNZyaRjo.js";
6
6
  const alertVariants = cva(
7
7
  "relative flex items-center gap-2 rounded-md p-2 text-sm transition-all duration-200",
@@ -148,10 +148,10 @@ const alertVariants = cva(
148
148
  className: s,
149
149
  children: i,
150
150
  ...o
151
- }, n) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
151
+ }, a) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
152
152
  "div",
153
153
  {
154
- ref: n,
154
+ ref: a,
155
155
  role: "alert",
156
156
  className: cn(alertVariants({ variant: e, color: t }), s),
157
157
  ...o,
@@ -228,16 +228,16 @@ const alertVariants = cva(
228
228
  fontSize: s = "base",
229
229
  fontWeight: i = "medium",
230
230
  quiet: o = !1,
231
- ...n
232
- }, a) => /* @__PURE__ */ jsxRuntimeExports.jsx(
231
+ ...a
232
+ }, n) => /* @__PURE__ */ jsxRuntimeExports.jsx(
233
233
  "a",
234
234
  {
235
- ref: a,
235
+ ref: n,
236
236
  className: cn(
237
237
  anchorVariants({ color: r, fontSize: s, fontWeight: i, quiet: o }),
238
238
  t
239
239
  ),
240
- ...n,
240
+ ...a,
241
241
  children: e
242
242
  }
243
243
  )
@@ -318,13 +318,13 @@ const alertVariants = cva(
318
318
  isCapitalize: s = !1,
319
319
  align: i = "left",
320
320
  italic: o = !1,
321
- clamp: n = "none",
322
- ellipsis: a = !1,
321
+ clamp: a = "none",
322
+ ellipsis: n = !1,
323
323
  fontSize: l,
324
324
  fontWeight: c,
325
- className: u,
325
+ className: g,
326
326
  children: d,
327
- ...g
327
+ ...u
328
328
  }, f) => {
329
329
  const x = [
330
330
  "h1",
@@ -348,16 +348,16 @@ const alertVariants = cva(
348
348
  isCapitalize: s,
349
349
  align: i,
350
350
  italic: o,
351
- clamp: n,
352
- ellipsis: a,
351
+ clamp: a,
352
+ ellipsis: n,
353
353
  // @ts-expect-error - `as` is not a valid variant
354
354
  as: x
355
355
  }),
356
356
  m,
357
357
  h,
358
- u
358
+ g
359
359
  ),
360
- ...g,
360
+ ...u,
361
361
  children: d
362
362
  }
363
363
  );
@@ -440,17 +440,17 @@ function getGridCols(e = 4) {
440
440
  return "grid-cols-4";
441
441
  }
442
442
  }
443
- const AttributeListItem = forwardRef(function({ children: t, className: r, span: s = 1, title: i, ...o }, n) {
444
- const a = getColSpan(s);
445
- return /* @__PURE__ */ jsxRuntimeExports.jsx("li", { ref: n, className: cn(a, r), ...o, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Attribute, { title: i, children: t }) });
443
+ const AttributeListItem = forwardRef(function({ children: t, className: r, span: s = 1, title: i, ...o }, a) {
444
+ const n = getColSpan(s);
445
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("li", { ref: a, className: cn(n, r), ...o, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Attribute, { title: i, children: t }) });
446
446
  }), AttributeListRoot = forwardRef(
447
447
  function({ children: t, className: r, columns: s = 4, ...i }, o) {
448
- const n = getGridCols(s);
448
+ const a = getGridCols(s);
449
449
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
450
450
  "ul",
451
451
  {
452
452
  ref: o,
453
- className: cn("grid gap-4", n, r),
453
+ className: cn("grid gap-4", a, r),
454
454
  ...i,
455
455
  children: t
456
456
  }
@@ -504,10 +504,10 @@ const AttributeListItem = forwardRef(function({ children: t, className: r, span:
504
504
  className: s,
505
505
  children: i,
506
506
  ...o
507
- }, n) => /* @__PURE__ */ jsxRuntimeExports.jsx(
507
+ }, a) => /* @__PURE__ */ jsxRuntimeExports.jsx(
508
508
  "div",
509
509
  {
510
- ref: n,
510
+ ref: a,
511
511
  className: cn(avatarVariants({ variant: e, size: t, shape: r }), s),
512
512
  ...o,
513
513
  children: i
@@ -515,17 +515,17 @@ const AttributeListItem = forwardRef(function({ children: t, className: r, span:
515
515
  )
516
516
  ), AvatarImage = forwardRef(
517
517
  ({ src: e, alt: t, className: r, onError: s, ...i }, o) => {
518
- const [n, a] = useState(!1);
518
+ const [a, n] = useState(!1);
519
519
  useEffect(() => {
520
- a(!1);
520
+ n(!1);
521
521
  }, [e]);
522
522
  const l = useCallback(
523
523
  (c) => {
524
- a(!0), s?.(c);
524
+ n(!0), s?.(c);
525
525
  },
526
526
  [s]
527
527
  );
528
- return n ? null : /* @__PURE__ */ jsxRuntimeExports.jsx(
528
+ return a ? null : /* @__PURE__ */ jsxRuntimeExports.jsx(
529
529
  "img",
530
530
  {
531
531
  ref: o,
@@ -703,11 +703,11 @@ const AttributeListItem = forwardRef(function({ children: t, className: r, span:
703
703
  size: s = "md",
704
704
  iconLeft: i,
705
705
  iconRight: o,
706
- className: n,
707
- children: a,
706
+ className: a,
707
+ children: n,
708
708
  ...l
709
709
  }, c) => {
710
- const g = !(a != null && a !== "") && !!(i || o);
710
+ const u = !(n != null && n !== "") && !!(i || o);
711
711
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
712
712
  "span",
713
713
  {
@@ -718,19 +718,19 @@ const AttributeListItem = forwardRef(function({ children: t, className: r, span:
718
718
  color: r,
719
719
  shape: t,
720
720
  size: s,
721
- iconOnly: g
721
+ iconOnly: u
722
722
  }),
723
- n
723
+ a
724
724
  ),
725
725
  ...l,
726
- children: g ? (
726
+ children: u ? (
727
727
  // Icon-only mode: display only the icon
728
728
  i || o
729
729
  ) : (
730
730
  // Normal mode: display icon(s) and text
731
731
  /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
732
732
  i,
733
- a,
733
+ n,
734
734
  o
735
735
  ] })
736
736
  )
@@ -833,8 +833,8 @@ const AttributeListItem = forwardRef(function({ children: t, className: r, span:
833
833
  size: s = "md",
834
834
  disabled: i = !1,
835
835
  type: o = "button",
836
- children: n,
837
- ...a
836
+ children: a,
837
+ ...n
838
838
  }, l) {
839
839
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
840
840
  "button",
@@ -845,142 +845,96 @@ const AttributeListItem = forwardRef(function({ children: t, className: r, span:
845
845
  disabled: i,
846
846
  "aria-disabled": i,
847
847
  inert: i ? !0 : void 0,
848
- ...a,
849
- children: n
848
+ ...n,
849
+ children: a
850
850
  }
851
851
  );
852
852
  }
853
- ), buttonFloatVariants = cva(
854
- [
855
- "inline-flex items-center justify-center gap-2",
856
- "rounded-lg",
857
- "font-medium",
858
- "transition-all",
859
- "duration-200",
860
- "focus-visible:outline-none",
861
- "focus-visible:ring-2",
862
- "focus-visible:ring-offset-2",
863
- "disabled:opacity-50",
864
- "disabled:pointer-events-none",
865
- "select-none",
866
- "shadow-lg",
867
- "transition-transform",
868
- "transition-shadow",
869
- "will-change-transform,opacity,box-shadow",
870
- "hover:scale-105",
871
- "active:scale-95",
872
- "focus-visible:shadow-xl",
873
- "hover:shadow-xl",
874
- "active:shadow-md"
875
- ].join(" "),
853
+ ), menuVariants = cva(
854
+ "absolute z-70 min-w-40 bg-background rounded-lg border border-border transition-all duration-200 ease-out will-change-transform",
876
855
  {
877
856
  variants: {
878
- variant: {
879
- primary: "bg-primary text-white hover:bg-primary/90 focus-visible:ring-primary-light focus-visible:ring-offset-white shadow-sm hover:shadow-md",
880
- secondary: "bg-secondary text-white hover:bg-secondary/90 focus-visible:ring-secondary-light focus-visible:ring-offset-white shadow-sm hover:shadow-md",
881
- tertiary: "bg-tertiary text-white hover:bg-tertiary/90 focus-visible:ring-tertiary-light focus-visible:ring-offset-white shadow-sm hover:shadow-md",
882
- ghost: "bg-white text-foreground hover:bg-ghost-soft focus-visible:ring-ghost-light focus-visible:ring-offset-white",
883
- neutral: "bg-neutral text-foreground border border-border hover:bg-neutral/80 focus-visible:ring-foreground-light focus-visible:ring-offset-white shadow-sm",
884
- "primary-outline": "border border-primary text-primary bg-white hover:bg-primary hover:text-white focus-visible:ring-primary-light focus-visible:ring-offset-white transition-all",
885
- "secondary-outline": "border border-secondary text-secondary bg-white hover:bg-secondary hover:text-white focus-visible:ring-secondary-light focus-visible:ring-offset-white transition-all",
886
- "tertiary-outline": "border border-tertiary text-tertiary bg-white hover:bg-tertiary hover:text-white focus-visible:ring-tertiary-light focus-visible:ring-offset-white transition-all",
887
- "ghost-outline": "border border-ghost text-ghost bg-white hover:bg-ghost hover:text-white focus-visible:ring-ghost-light focus-visible:ring-offset-white transition-all",
888
- "neutral-outline": "border border-border text-foreground bg-white hover:bg-neutral hover:text-foreground focus-visible:ring-foreground-light focus-visible:ring-offset-white transition-all",
889
- "primary-ghost": "text-primary bg-white hover:bg-primary/20 focus-visible:ring-primary focus-visible:ring-offset-white",
890
- "secondary-ghost": "text-secondary bg-white hover:bg-secondary/20 focus-visible:ring-secondary focus-visible:ring-offset-white",
891
- "tertiary-ghost": "text-tertiary bg-white hover:bg-tertiary/20 focus-visible:ring-tertiary focus-visible:ring-offset-white",
892
- "neutral-ghost": "text-foreground bg-white hover:bg-neutral/50 focus-visible:ring-foreground focus-visible:ring-offset-white",
893
- success: "bg-success text-white hover:bg-success/90 focus-visible:ring-success-light focus-visible:ring-offset-white shadow-sm hover:shadow-md",
894
- "success-outline": "border border-success text-success bg-white hover:bg-success hover:text-white focus-visible:ring-success-light focus-visible:ring-offset-white transition-all",
895
- "success-ghost": "text-success bg-white hover:bg-success/20 focus-visible:ring-success-light focus-visible:ring-offset-white",
896
- info: "bg-info text-white hover:bg-info/90 focus-visible:ring-info-light focus-visible:ring-offset-white shadow-sm hover:shadow-md",
897
- "info-outline": "border border-info text-info bg-white hover:bg-info hover:text-white focus-visible:ring-info-light focus-visible:ring-offset-white transition-all",
898
- "info-ghost": "text-info bg-white hover:bg-info/20 focus-visible:ring-info-light focus-visible:ring-offset-white",
899
- warning: "bg-warning text-white hover:bg-warning/90 focus-visible:ring-warning-light focus-visible:ring-offset-white shadow-sm hover:shadow-md",
900
- "warning-outline": "border border-warning text-warning bg-white hover:bg-warning hover:text-white focus-visible:ring-warning-light focus-visible:ring-offset-white transition-all",
901
- "warning-ghost": "text-warning bg-white hover:bg-warning/20 focus-visible:ring-warning-light focus-visible:ring-offset-white",
902
- danger: "bg-danger text-white hover:bg-danger/90 focus-visible:ring-danger-light focus-visible:ring-offset-white shadow-sm hover:shadow-md",
903
- "danger-outline": "border border-danger text-danger bg-white hover:bg-danger hover:text-white focus-visible:ring-danger-light focus-visible:ring-offset-white transition-all",
904
- "danger-ghost": "text-danger bg-white hover:bg-danger/20 focus-visible:ring-danger-light focus-visible:ring-offset-white",
905
- outline: "border border-border text-foreground bg-white hover:bg-accent-soft focus-visible:ring-accent-soft focus-visible:ring-offset-white transition-all",
906
- destructive: "bg-danger text-white hover:bg-danger/90 focus-visible:ring-danger-soft focus-visible:ring-offset-white shadow-sm hover:shadow-md"
907
- },
908
857
  size: {
909
- sm: "h-12 w-12 min-w-12 min-h-12 text-base",
910
- md: "h-14 w-14 min-w-14 min-h-14 text-lg",
911
- lg: "h-16 w-16 min-w-16 min-h-16 text-xl"
858
+ sm: "py-1.5 px-1",
859
+ md: "py-2 px-1"
860
+ },
861
+ open: {
862
+ true: "opacity-100 translate-y-1",
863
+ false: "opacity-0 pointer-events-none translate-y-3"
912
864
  }
913
865
  },
914
866
  defaultVariants: {
915
- variant: "primary",
916
- size: "md"
867
+ size: "md",
868
+ open: !1
917
869
  }
918
870
  }
919
871
  );
920
- function useFloatingPosition(e, t = "1rem") {
921
- const r = useRef(null), [s, i] = useState({}), [o, n] = useState("fixed bottom-4 right-4"), a = useCallback(() => {
922
- const c = r.current;
923
- if (!c) return;
924
- const d = c.getBoundingClientRect().height > window.innerHeight;
925
- let g = {}, f = "";
926
- d ? (g = {
927
- position: "fixed",
928
- bottom: t,
929
- zIndex: 50,
930
- transform: `translateY(${c.scrollTop}px)`
931
- }, f = `fixed bottom-4 ${e}-4`) : (g = {
932
- position: "fixed",
933
- bottom: t,
934
- zIndex: 50
935
- }, f = `fixed bottom-4 ${e}-4`), i(g), n(f);
936
- }, [e, t]);
872
+ function useMenuOutsideClick(e, t, r, s) {
873
+ useEffect(() => {
874
+ if (!e) return;
875
+ function i(o) {
876
+ !t.current?.contains(o.target) && !r.current?.contains(o.target) && s();
877
+ }
878
+ return document.addEventListener("mousedown", i), () => document.removeEventListener("mousedown", i);
879
+ }, [e, s, t, r]);
880
+ }
881
+ function useEscapeClose(e, t, r) {
882
+ const s = useRef(null);
937
883
  return useEffect(() => {
938
- a();
939
- const c = r.current;
940
- return c && c.addEventListener("scroll", a), window.addEventListener("resize", a), () => {
941
- c && c.removeEventListener("scroll", a), window.removeEventListener("resize", a);
884
+ s.current && s.current.focus();
885
+ }, []), useEffect(() => {
886
+ const i = (o) => {
887
+ o.key === "Escape" && e && s.current && s.current.contains(document.activeElement) && !r && t();
942
888
  };
943
- }, [a]), useEffect(() => {
944
- r.current && a();
945
- }, [e, t, a]), [useCallback(
946
- (c) => {
947
- r.current = c, c && a();
948
- },
949
- [a]
950
- ), s, o];
889
+ return e && (document.addEventListener("keydown", i), document.body.style.overflow = "hidden"), () => {
890
+ document.removeEventListener("keydown", i), document.body.style.overflow = "unset";
891
+ };
892
+ }, [e, t, r, s]), s;
951
893
  }
952
- const ButtonFloat = forwardRef(
953
- function({
954
- className: t,
955
- variant: r = "primary",
956
- size: s = "md",
957
- side: i = "right",
958
- offset: o = "1rem",
959
- ...n
960
- }, a) {
961
- const [l, c, u] = useFloatingPosition(
962
- i,
963
- o
964
- ), [d, g] = useState(!1);
965
- return useEffect(() => {
966
- g(!0);
967
- }, []), /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: l, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
968
- "button",
894
+ const MenuContent = forwardRef(
895
+ ({ children: e }, t) => /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { ref: t, className: "flex flex-col gap-1", children: e })
896
+ ), MenuItem = forwardRef(
897
+ ({ children: e, disabled: t, ...r }, s) => /* @__PURE__ */ jsxRuntimeExports.jsx("li", { ref: s, ...r, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
898
+ Button,
899
+ {
900
+ variant: "ghost",
901
+ className: cn("block text-left w-full"),
902
+ disabled: t,
903
+ children: e
904
+ }
905
+ ) })
906
+ ), MenuRoot = ({
907
+ isOpen: e,
908
+ onOutsideClick: t,
909
+ size: r = "md",
910
+ content: s,
911
+ children: i
912
+ }) => {
913
+ const o = useRef(null), a = useRef(null), n = useId();
914
+ return useMenuOutsideClick(e, a, o, t), useEscapeClose(e, t), /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative w-fit", children: [
915
+ cloneElement(i, {
916
+ // @ts-expect-error: ref is valid for button or forwardRef components
917
+ ref: o,
918
+ "aria-haspopup": "menu",
919
+ "aria-expanded": e,
920
+ "aria-controls": n
921
+ }),
922
+ e && /* @__PURE__ */ jsxRuntimeExports.jsx(
923
+ "div",
969
924
  {
925
+ id: n,
970
926
  ref: a,
971
- type: n.type || "button",
972
- className: cn(
973
- buttonFloatVariants({ variant: r, size: s }),
974
- u,
975
- d && "animate-fab-in",
976
- t
977
- ),
978
- style: c,
979
- ...n
927
+ className: cn(menuVariants({ size: r, open: e })),
928
+ role: "menu",
929
+ "aria-hidden": !e,
930
+ children: s
980
931
  }
981
- ) });
982
- }
983
- );
932
+ )
933
+ ] });
934
+ }, Menu = Object.assign(MenuRoot, {
935
+ Content: MenuContent,
936
+ Item: MenuItem
937
+ });
984
938
  function getIconColorFromVariant(e = "primary") {
985
939
  const t = e.split("-");
986
940
  if (t.length === 1)
@@ -1098,11 +1052,11 @@ const buttonIconVariants = cva(
1098
1052
  size: "md",
1099
1053
  color: "primary"
1100
1054
  }
1101
- }), Icon = React__default.forwardRef(function({ as: t, color: r = "primary", size: s = "md", className: i, ...o }, n) {
1055
+ }), Icon = React__default.forwardRef(function({ as: t, color: r = "primary", size: s = "md", className: i, ...o }, a) {
1102
1056
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
1103
1057
  t,
1104
1058
  {
1105
- ref: n,
1059
+ ref: a,
1106
1060
  className: iconVariants({ color: r, size: s, className: i }),
1107
1061
  ...o
1108
1062
  }
@@ -1114,8 +1068,8 @@ const buttonIconVariants = cva(
1114
1068
  size: s = "md",
1115
1069
  shape: i = "rounded",
1116
1070
  disabled: o = !1,
1117
- as: n,
1118
- "aria-label": a,
1071
+ as: a,
1072
+ "aria-label": n,
1119
1073
  ...l
1120
1074
  }, c) {
1121
1075
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -1133,13 +1087,13 @@ const buttonIconVariants = cva(
1133
1087
  ),
1134
1088
  disabled: o,
1135
1089
  "aria-disabled": o,
1136
- "aria-label": a,
1090
+ "aria-label": n,
1137
1091
  inert: o ? !0 : void 0,
1138
1092
  ...l,
1139
1093
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(
1140
1094
  Icon,
1141
1095
  {
1142
- as: n,
1096
+ as: a,
1143
1097
  size: "sm",
1144
1098
  color: getIconColorFromVariant(r)
1145
1099
  }
@@ -1147,6 +1101,166 @@ const buttonIconVariants = cva(
1147
1101
  }
1148
1102
  );
1149
1103
  }
1104
+ ), ButtonMenuIconRoot = forwardRef(
1105
+ (e, t) => {
1106
+ const {
1107
+ as: r = EllipsisVerticalIcon,
1108
+ content: s,
1109
+ onOpenChange: i,
1110
+ onClick: o,
1111
+ ...a
1112
+ } = e ?? {}, [n, l] = useState(!1);
1113
+ useEffect(() => {
1114
+ i?.(n);
1115
+ }, [n, i]);
1116
+ const c = () => {
1117
+ l(!1);
1118
+ }, g = (d) => {
1119
+ l((u) => !u), o?.(d);
1120
+ };
1121
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
1122
+ Menu,
1123
+ {
1124
+ isOpen: n,
1125
+ onOutsideClick: c,
1126
+ size: "md",
1127
+ content: /* @__PURE__ */ jsxRuntimeExports.jsx(Menu.Content, { children: s }),
1128
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(ButtonIcon, { ref: t, as: r, onClick: g, ...a })
1129
+ }
1130
+ );
1131
+ }
1132
+ ), ButtonMenuIcon = Object.assign(ButtonMenuIconRoot, {
1133
+ Item: Menu.Item
1134
+ }), buttonFloatVariants = cva(
1135
+ [
1136
+ "inline-flex items-center justify-center gap-2",
1137
+ "rounded-lg",
1138
+ "font-medium",
1139
+ "transition-all",
1140
+ "duration-200",
1141
+ "focus-visible:outline-none",
1142
+ "focus-visible:ring-2",
1143
+ "focus-visible:ring-offset-2",
1144
+ "disabled:opacity-50",
1145
+ "disabled:pointer-events-none",
1146
+ "select-none",
1147
+ "shadow-lg",
1148
+ "transition-transform",
1149
+ "transition-shadow",
1150
+ "will-change-transform,opacity,box-shadow",
1151
+ "hover:scale-105",
1152
+ "active:scale-95",
1153
+ "focus-visible:shadow-xl",
1154
+ "hover:shadow-xl",
1155
+ "active:shadow-md"
1156
+ ].join(" "),
1157
+ {
1158
+ variants: {
1159
+ variant: {
1160
+ primary: "bg-primary text-white hover:bg-primary/90 focus-visible:ring-primary-light focus-visible:ring-offset-white shadow-sm hover:shadow-md",
1161
+ secondary: "bg-secondary text-white hover:bg-secondary/90 focus-visible:ring-secondary-light focus-visible:ring-offset-white shadow-sm hover:shadow-md",
1162
+ tertiary: "bg-tertiary text-white hover:bg-tertiary/90 focus-visible:ring-tertiary-light focus-visible:ring-offset-white shadow-sm hover:shadow-md",
1163
+ ghost: "bg-white text-foreground hover:bg-ghost-soft focus-visible:ring-ghost-light focus-visible:ring-offset-white",
1164
+ neutral: "bg-neutral text-foreground border border-border hover:bg-neutral/80 focus-visible:ring-foreground-light focus-visible:ring-offset-white shadow-sm",
1165
+ "primary-outline": "border border-primary text-primary bg-white hover:bg-primary hover:text-white focus-visible:ring-primary-light focus-visible:ring-offset-white transition-all",
1166
+ "secondary-outline": "border border-secondary text-secondary bg-white hover:bg-secondary hover:text-white focus-visible:ring-secondary-light focus-visible:ring-offset-white transition-all",
1167
+ "tertiary-outline": "border border-tertiary text-tertiary bg-white hover:bg-tertiary hover:text-white focus-visible:ring-tertiary-light focus-visible:ring-offset-white transition-all",
1168
+ "ghost-outline": "border border-ghost text-ghost bg-white hover:bg-ghost hover:text-white focus-visible:ring-ghost-light focus-visible:ring-offset-white transition-all",
1169
+ "neutral-outline": "border border-border text-foreground bg-white hover:bg-neutral hover:text-foreground focus-visible:ring-foreground-light focus-visible:ring-offset-white transition-all",
1170
+ "primary-ghost": "text-primary bg-white hover:bg-primary/20 focus-visible:ring-primary focus-visible:ring-offset-white",
1171
+ "secondary-ghost": "text-secondary bg-white hover:bg-secondary/20 focus-visible:ring-secondary focus-visible:ring-offset-white",
1172
+ "tertiary-ghost": "text-tertiary bg-white hover:bg-tertiary/20 focus-visible:ring-tertiary focus-visible:ring-offset-white",
1173
+ "neutral-ghost": "text-foreground bg-white hover:bg-neutral/50 focus-visible:ring-foreground focus-visible:ring-offset-white",
1174
+ success: "bg-success text-white hover:bg-success/90 focus-visible:ring-success-light focus-visible:ring-offset-white shadow-sm hover:shadow-md",
1175
+ "success-outline": "border border-success text-success bg-white hover:bg-success hover:text-white focus-visible:ring-success-light focus-visible:ring-offset-white transition-all",
1176
+ "success-ghost": "text-success bg-white hover:bg-success/20 focus-visible:ring-success-light focus-visible:ring-offset-white",
1177
+ info: "bg-info text-white hover:bg-info/90 focus-visible:ring-info-light focus-visible:ring-offset-white shadow-sm hover:shadow-md",
1178
+ "info-outline": "border border-info text-info bg-white hover:bg-info hover:text-white focus-visible:ring-info-light focus-visible:ring-offset-white transition-all",
1179
+ "info-ghost": "text-info bg-white hover:bg-info/20 focus-visible:ring-info-light focus-visible:ring-offset-white",
1180
+ warning: "bg-warning text-white hover:bg-warning/90 focus-visible:ring-warning-light focus-visible:ring-offset-white shadow-sm hover:shadow-md",
1181
+ "warning-outline": "border border-warning text-warning bg-white hover:bg-warning hover:text-white focus-visible:ring-warning-light focus-visible:ring-offset-white transition-all",
1182
+ "warning-ghost": "text-warning bg-white hover:bg-warning/20 focus-visible:ring-warning-light focus-visible:ring-offset-white",
1183
+ danger: "bg-danger text-white hover:bg-danger/90 focus-visible:ring-danger-light focus-visible:ring-offset-white shadow-sm hover:shadow-md",
1184
+ "danger-outline": "border border-danger text-danger bg-white hover:bg-danger hover:text-white focus-visible:ring-danger-light focus-visible:ring-offset-white transition-all",
1185
+ "danger-ghost": "text-danger bg-white hover:bg-danger/20 focus-visible:ring-danger-light focus-visible:ring-offset-white",
1186
+ outline: "border border-border text-foreground bg-white hover:bg-accent-soft focus-visible:ring-accent-soft focus-visible:ring-offset-white transition-all",
1187
+ destructive: "bg-danger text-white hover:bg-danger/90 focus-visible:ring-danger-soft focus-visible:ring-offset-white shadow-sm hover:shadow-md"
1188
+ },
1189
+ size: {
1190
+ sm: "h-12 w-12 min-w-12 min-h-12 text-base",
1191
+ md: "h-14 w-14 min-w-14 min-h-14 text-lg",
1192
+ lg: "h-16 w-16 min-w-16 min-h-16 text-xl"
1193
+ }
1194
+ },
1195
+ defaultVariants: {
1196
+ variant: "primary",
1197
+ size: "md"
1198
+ }
1199
+ }
1200
+ );
1201
+ function useFloatingPosition(e, t = "1rem") {
1202
+ const r = useRef(null), [s, i] = useState({}), [o, a] = useState("fixed bottom-4 right-4"), n = useCallback(() => {
1203
+ const c = r.current;
1204
+ if (!c) return;
1205
+ const d = c.getBoundingClientRect().height > window.innerHeight;
1206
+ let u = {}, f = "";
1207
+ d ? (u = {
1208
+ position: "fixed",
1209
+ bottom: t,
1210
+ zIndex: 50,
1211
+ transform: `translateY(${c.scrollTop}px)`
1212
+ }, f = `fixed bottom-4 ${e}-4`) : (u = {
1213
+ position: "fixed",
1214
+ bottom: t,
1215
+ zIndex: 50
1216
+ }, f = `fixed bottom-4 ${e}-4`), i(u), a(f);
1217
+ }, [e, t]);
1218
+ return useEffect(() => {
1219
+ n();
1220
+ const c = r.current;
1221
+ return c && c.addEventListener("scroll", n), window.addEventListener("resize", n), () => {
1222
+ c && c.removeEventListener("scroll", n), window.removeEventListener("resize", n);
1223
+ };
1224
+ }, [n]), useEffect(() => {
1225
+ r.current && n();
1226
+ }, [e, t, n]), [useCallback(
1227
+ (c) => {
1228
+ r.current = c, c && n();
1229
+ },
1230
+ [n]
1231
+ ), s, o];
1232
+ }
1233
+ const ButtonFloat = forwardRef(
1234
+ function({
1235
+ className: t,
1236
+ variant: r = "primary",
1237
+ size: s = "md",
1238
+ side: i = "right",
1239
+ offset: o = "1rem",
1240
+ ...a
1241
+ }, n) {
1242
+ const [l, c, g] = useFloatingPosition(
1243
+ i,
1244
+ o
1245
+ ), [d, u] = useState(!1);
1246
+ return useEffect(() => {
1247
+ u(!0);
1248
+ }, []), /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: l, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
1249
+ "button",
1250
+ {
1251
+ ref: n,
1252
+ type: a.type || "button",
1253
+ className: cn(
1254
+ buttonFloatVariants({ variant: r, size: s }),
1255
+ g,
1256
+ d && "animate-fab-in",
1257
+ t
1258
+ ),
1259
+ style: c,
1260
+ ...a
1261
+ }
1262
+ ) });
1263
+ }
1150
1264
  ), calculatorRootVariants = cva(
1151
1265
  "flex flex-col w-full max-w-xs rounded-lg bg-background",
1152
1266
  {
@@ -1265,7 +1379,7 @@ const BUTTONS = [
1265
1379
  className: s,
1266
1380
  "aria-label": i
1267
1381
  }, o) => {
1268
- const { input: n, inputRef: a, handleButton: l, handleInput: c } = useCalculator({
1382
+ const { input: a, inputRef: n, handleButton: l, handleInput: c } = useCalculator({
1269
1383
  initialValue: e,
1270
1384
  disabled: r,
1271
1385
  onChange: t
@@ -1281,16 +1395,16 @@ const BUTTONS = [
1281
1395
  /* @__PURE__ */ jsxRuntimeExports.jsx(
1282
1396
  "input",
1283
1397
  {
1284
- ref: a,
1398
+ ref: n,
1285
1399
  className: "w-full mb-3 px-3 py-2 rounded border border-[var(--color-neutral)] bg-[var(--color-neutral-soft)] text-right text-xl font-mono focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)]",
1286
- value: n,
1400
+ value: a,
1287
1401
  onChange: c,
1288
1402
  disabled: r,
1289
1403
  inputMode: "decimal",
1290
1404
  "aria-label": "Calculator input"
1291
1405
  }
1292
1406
  ),
1293
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-1 mb-3", children: BUTTONS.map((u, d) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex w-full", children: u.map((g) => g === "⌫" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
1407
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-1 mb-3", children: BUTTONS.map((g, d) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex w-full", children: g.map((u) => u === "⌫" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
1294
1408
  ButtonIcon,
1295
1409
  {
1296
1410
  as: X,
@@ -1304,13 +1418,13 @@ const BUTTONS = [
1304
1418
  ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
1305
1419
  CalculatorButton,
1306
1420
  {
1307
- variant: g === "=" ? "action" : g === "C" ? "danger" : ["/", "*", "-", "+", "/"].includes(g) ? "operator" : "default",
1308
- onClick: () => l(g),
1421
+ variant: u === "=" ? "action" : u === "C" ? "danger" : ["/", "*", "-", "+", "/"].includes(u) ? "operator" : "default",
1422
+ onClick: () => l(u),
1309
1423
  disabled: r,
1310
- "aria-label": g,
1311
- children: g
1424
+ "aria-label": u,
1425
+ children: u
1312
1426
  },
1313
- g
1427
+ u
1314
1428
  )) }, d)) })
1315
1429
  ]
1316
1430
  }
@@ -1363,15 +1477,15 @@ const cardVariants = cva(
1363
1477
  title: s,
1364
1478
  subtitle: i,
1365
1479
  badge: o,
1366
- supplementaryInfo: n,
1367
- bordered: a = !1,
1480
+ supplementaryInfo: a,
1481
+ bordered: n = !1,
1368
1482
  className: l,
1369
1483
  ...c
1370
- }, u) => /* @__PURE__ */ jsxRuntimeExports.jsx(
1484
+ }, g) => /* @__PURE__ */ jsxRuntimeExports.jsx(
1371
1485
  "button",
1372
1486
  {
1373
- ref: u,
1374
- className: cn(cardVariants({ size: e, shape: t, bordered: a }), l),
1487
+ ref: g,
1488
+ className: cn(cardVariants({ size: e, shape: t, bordered: n }), l),
1375
1489
  ...c,
1376
1490
  children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-4", children: [
1377
1491
  r && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-shrink-0", children: r }),
@@ -1380,9 +1494,9 @@ const cardVariants = cva(
1380
1494
  s && /* @__PURE__ */ jsxRuntimeExports.jsx(Text, { as: "h3", fontSize: "lg", fontWeight: "semibold", children: s }),
1381
1495
  i && /* @__PURE__ */ jsxRuntimeExports.jsx(Text, { as: "p", fontSize: "sm", color: "gray", children: i })
1382
1496
  ] }),
1383
- (o || n) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center", children: [
1497
+ (o || a) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between items-center", children: [
1384
1498
  o,
1385
- typeof n == "string" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Text, { as: "p", fontSize: "sm", color: "gray", children: n }) : n
1499
+ typeof a == "string" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Text, { as: "p", fontSize: "sm", color: "gray", children: a }) : a
1386
1500
  ] })
1387
1501
  ] })
1388
1502
  ] })
@@ -1436,19 +1550,19 @@ const cardVariants = cva(
1436
1550
  size: s = "md",
1437
1551
  disabled: i = !1,
1438
1552
  children: o,
1439
- ...n
1440
- }, a) {
1553
+ ...a
1554
+ }, n) {
1441
1555
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1442
1556
  "button",
1443
1557
  {
1444
- ref: a,
1558
+ ref: n,
1445
1559
  type: "button",
1446
1560
  className: cn(filterChipVariants({ variant: r, size: s }), t),
1447
1561
  disabled: i,
1448
1562
  "aria-disabled": i,
1449
1563
  "aria-label": `${o}, removable`,
1450
1564
  inert: i ? !0 : void 0,
1451
- ...n,
1565
+ ...a,
1452
1566
  children: [
1453
1567
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-shrink-0", children: o }),
1454
1568
  /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { as: XIcon, color: "inherit", size: s === "lg" ? "md" : "sm" })
@@ -1478,15 +1592,15 @@ const cardVariants = cva(
1478
1592
  ), noResultsHeaderVariants = cva(
1479
1593
  "flex flex-row items-center gap-3 mb-2"
1480
1594
  ), NoResults = React__default.forwardRef(
1481
- function e({ icon: t, title: r, subtitle: s, action: i, className: o, hasGrayBackground: n, ...a }, l) {
1595
+ function e({ icon: t, title: r, subtitle: s, action: i, className: o, hasGrayBackground: a, ...n }, l) {
1482
1596
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1483
1597
  "section",
1484
1598
  {
1485
1599
  ref: l,
1486
- className: cn(noResultsVariants({ hasGrayBackground: n }), o),
1600
+ className: cn(noResultsVariants({ hasGrayBackground: a }), o),
1487
1601
  role: "status",
1488
1602
  "aria-label": "No results found",
1489
- ...a,
1603
+ ...n,
1490
1604
  children: [
1491
1605
  /* @__PURE__ */ jsxRuntimeExports.jsxs("header", { className: noResultsHeaderVariants(), children: [
1492
1606
  /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { as: t, size: "lg", color: "ghost", "aria-hidden": "true" }),
@@ -1631,14 +1745,14 @@ const getTableColumnClass = (e) => {
1631
1745
  );
1632
1746
  }
1633
1747
  ), TableColumn = forwardRef(
1634
- ({ as: e = "td", span: t, align: r = "left", children: s, className: i, ...o }, n) => {
1635
- const a = e === "th" ? "columnheader" : "cell";
1748
+ ({ as: e = "td", span: t, align: r = "left", children: s, className: i, ...o }, a) => {
1749
+ const n = e === "th" ? "columnheader" : "cell";
1636
1750
  let l = "text-left";
1637
1751
  return r === "center" ? l = "text-center" : r === "right" && (l = "text-right"), /* @__PURE__ */ jsxRuntimeExports.jsx(
1638
1752
  "div",
1639
1753
  {
1640
- ref: n,
1641
- role: a,
1754
+ ref: a,
1755
+ role: n,
1642
1756
  className: cn(
1643
1757
  "px-4 py-2",
1644
1758
  "[&:not(:last-child)]:border-r [&:not(:last-child)]:border-border",
@@ -1749,9 +1863,9 @@ const getTableColumnClass = (e) => {
1749
1863
  )
1750
1864
  );
1751
1865
  function useImage({ src: e }) {
1752
- const [t, r] = useState(!1), [s, i] = useState(!1), o = useRef(!1), n = () => {
1866
+ const [t, r] = useState(!1), [s, i] = useState(!1), o = useRef(!1), a = () => {
1753
1867
  r(!0);
1754
- }, a = () => {
1868
+ }, n = () => {
1755
1869
  i(!0);
1756
1870
  };
1757
1871
  return useEffect(() => {
@@ -1767,8 +1881,8 @@ function useImage({ src: e }) {
1767
1881
  }, [e]), {
1768
1882
  loaded: t,
1769
1883
  errored: s,
1770
- handleLoad: n,
1771
- handleError: a
1884
+ handleLoad: a,
1885
+ handleError: n
1772
1886
  };
1773
1887
  }
1774
1888
  const imageVariants = cva("block object-cover", {
@@ -1846,12 +1960,12 @@ function BaseImageFallback({
1846
1960
  className: s,
1847
1961
  style: i,
1848
1962
  shape: o,
1849
- size: n
1963
+ size: a
1850
1964
  }) {
1851
1965
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1852
1966
  "div",
1853
1967
  {
1854
- className: imageAtomVariants({ shape: o, size: n, className: s }),
1968
+ className: imageAtomVariants({ shape: o, size: a, className: s }),
1855
1969
  style: { width: t, height: r, ...i },
1856
1970
  "aria-label": e,
1857
1971
  role: "img",
@@ -1877,13 +1991,13 @@ const BaseImage = forwardRef(
1877
1991
  onError: s,
1878
1992
  width: i,
1879
1993
  height: o,
1880
- loading: n = "lazy",
1881
- position: a = "cover",
1994
+ loading: a = "lazy",
1995
+ position: n = "cover",
1882
1996
  size: l = "auto",
1883
1997
  shape: c,
1884
- className: u,
1998
+ className: g,
1885
1999
  ...d
1886
- }, g) => {
2000
+ }, u) => {
1887
2001
  const { loaded: f, errored: b, handleLoad: x, handleError: m } = useImage({
1888
2002
  src: e
1889
2003
  }), h = typeof i == "number" ? i : Number(i), v = typeof o == "number" ? o : Number(o);
@@ -1905,19 +2019,19 @@ const BaseImage = forwardRef(
1905
2019
  ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
1906
2020
  "img",
1907
2021
  {
1908
- ref: g,
2022
+ ref: u,
1909
2023
  src: e,
1910
2024
  alt: t,
1911
2025
  width: h,
1912
2026
  height: v,
1913
- loading: n,
2027
+ loading: a,
1914
2028
  className: cn(
1915
2029
  imageVariants({
1916
- position: a,
2030
+ position: n,
1917
2031
  size: l,
1918
2032
  shape: c
1919
2033
  }),
1920
- u
2034
+ g
1921
2035
  ),
1922
2036
  onLoad: (w) => {
1923
2037
  x(), r?.(w);
@@ -1936,6 +2050,7 @@ export {
1936
2050
  Calculator as C,
1937
2051
  FilterChip as F,
1938
2052
  Icon as I,
2053
+ Menu as M,
1939
2054
  NoResults as N,
1940
2055
  Table as T,
1941
2056
  Anchor as a,
@@ -1944,13 +2059,15 @@ export {
1944
2059
  Avatar as d,
1945
2060
  Brand as e,
1946
2061
  Button as f,
1947
- ButtonFloat as g,
1948
- ButtonIcon as h,
1949
- Card as i,
1950
- Text as j,
1951
- Tile as k,
1952
- ImageCircle as l,
1953
- ImageSquare as m,
1954
- ImageRectangle as n,
1955
- BaseImage as o
2062
+ ButtonMenuIcon as g,
2063
+ ButtonFloat as h,
2064
+ ButtonIcon as i,
2065
+ Card as j,
2066
+ Text as k,
2067
+ Tile as l,
2068
+ ImageCircle as m,
2069
+ ImageSquare as n,
2070
+ ImageRectangle as o,
2071
+ BaseImage as p,
2072
+ useEscapeClose as u
1956
2073
  };