@ataraui/ataraui-react 0.3.0 → 0.4.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/dist/index.js CHANGED
@@ -2,13 +2,14 @@
2
2
 
3
3
  var clsx = require('clsx');
4
4
  var tailwindMerge = require('tailwind-merge');
5
- var React3 = require('react');
5
+ var React13 = require('react');
6
6
  var classVarianceAuthority = require('class-variance-authority');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
+ var reactDom = require('react-dom');
8
9
 
9
10
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
11
 
11
- var React3__default = /*#__PURE__*/_interopDefault(React3);
12
+ var React13__default = /*#__PURE__*/_interopDefault(React13);
12
13
 
13
14
  // src/utils/cn.ts
14
15
  function cn(...inputs) {
@@ -94,7 +95,7 @@ var buttonVariants = classVarianceAuthority.cva(
94
95
  }
95
96
  }
96
97
  );
97
- var Button = React3__default.default.forwardRef(
98
+ var Button = React13__default.default.forwardRef(
98
99
  ({ className, variant, size, isLoading, children, disabled, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
99
100
  "button",
100
101
  {
@@ -133,7 +134,7 @@ var inputVariants = classVarianceAuthority.cva(
133
134
  }
134
135
  }
135
136
  );
136
- var Input = React3__default.default.forwardRef(
137
+ var Input = React13__default.default.forwardRef(
137
138
  ({ className, label, error, hint, id, inputSize, ...props }, ref) => {
138
139
  const inputId = id != null ? id : label == null ? void 0 : label.toLowerCase().replace(/\s+/g, "-");
139
140
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5 w-full", children: [
@@ -200,7 +201,7 @@ var cardVariants = classVarianceAuthority.cva(
200
201
  }
201
202
  }
202
203
  );
203
- var Card = React3__default.default.forwardRef(
204
+ var Card = React13__default.default.forwardRef(
204
205
  ({ className, variant, padding, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
205
206
  "div",
206
207
  {
@@ -211,23 +212,23 @@ var Card = React3__default.default.forwardRef(
211
212
  )
212
213
  );
213
214
  Card.displayName = "Card";
214
- var CardHeader = React3__default.default.forwardRef(
215
+ var CardHeader = React13__default.default.forwardRef(
215
216
  ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("flex flex-col gap-1.5 mb-4", className), ...props })
216
217
  );
217
218
  CardHeader.displayName = "CardHeader";
218
- var CardTitle = React3__default.default.forwardRef(
219
+ var CardTitle = React13__default.default.forwardRef(
219
220
  ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("h3", { ref, className: cn("text-lg font-semibold text-(--color-neutral-900)", className), ...props })
220
221
  );
221
222
  CardTitle.displayName = "CardTitle";
222
- var CardDescription = React3__default.default.forwardRef(
223
+ var CardDescription = React13__default.default.forwardRef(
223
224
  ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("p", { ref, className: cn("text-sm text-(--color-neutral-500)", className), ...props })
224
225
  );
225
226
  CardDescription.displayName = "CardDescription";
226
- var CardContent = React3__default.default.forwardRef(
227
+ var CardContent = React13__default.default.forwardRef(
227
228
  ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("text-sm text-(--color-neutral-700)", className), ...props })
228
229
  );
229
230
  CardContent.displayName = "CardContent";
230
- var CardFooter = React3__default.default.forwardRef(
231
+ var CardFooter = React13__default.default.forwardRef(
231
232
  ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("flex items-center gap-2 mt-4", className), ...props })
232
233
  );
233
234
  CardFooter.displayName = "CardFooter";
@@ -248,9 +249,9 @@ var avatarVariants = classVarianceAuthority.cva(
248
249
  }
249
250
  }
250
251
  );
251
- var Avatar = React3__default.default.forwardRef(
252
+ var Avatar = React13__default.default.forwardRef(
252
253
  ({ className, size, src, alt, fallback, ...props }, ref) => {
253
- const [imgError, setImgError] = React3__default.default.useState(false);
254
+ const [imgError, setImgError] = React13__default.default.useState(false);
254
255
  const initials = fallback == null ? void 0 : fallback.split(" ").map((word) => word[0]).slice(0, 2).join("").toUpperCase();
255
256
  return /* @__PURE__ */ jsxRuntime.jsx(
256
257
  "span",
@@ -294,7 +295,7 @@ var separatorVariants = classVarianceAuthority.cva(
294
295
  }
295
296
  }
296
297
  );
297
- var Separator = React3__default.default.forwardRef(
298
+ var Separator = React13__default.default.forwardRef(
298
299
  ({ className, orientation, label, ...props }, ref) => {
299
300
  if (label && orientation !== "vertical") {
300
301
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("flex items-center gap-3", className), ...props, children: [
@@ -333,7 +334,7 @@ var spinnerVariants = classVarianceAuthority.cva(
333
334
  }
334
335
  }
335
336
  );
336
- var Spinner = React3__default.default.forwardRef(
337
+ var Spinner = React13__default.default.forwardRef(
337
338
  ({ className, size, label, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs("span", { ref, role: "status", className: cn("inline-flex flex-col items-center gap-2", className), ...props, children: [
338
339
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(spinnerVariants({ size })) }),
339
340
  label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-(--color-neutral-500)", children: label }),
@@ -361,7 +362,7 @@ var selectVariants = classVarianceAuthority.cva(
361
362
  }
362
363
  }
363
364
  );
364
- var Select = React3__default.default.forwardRef(
365
+ var Select = React13__default.default.forwardRef(
365
366
  ({ className, label, error, hint, placeholder, options, selectSize, id, children, ...props }, ref) => {
366
367
  const selectId = id != null ? id : label == null ? void 0 : label.toLowerCase().replace(/\s+/g, "-");
367
368
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1.5 w-full", children: [
@@ -401,7 +402,7 @@ var Select = React3__default.default.forwardRef(
401
402
  }
402
403
  );
403
404
  Select.displayName = "Select";
404
- var Checkbox = React3__default.default.forwardRef(
405
+ var Checkbox = React13__default.default.forwardRef(
405
406
  ({ className, label, description, error, id, disabled, ...props }, ref) => {
406
407
  const checkboxId = id != null ? id : label == null ? void 0 : label.toLowerCase().replace(/\s+/g, "-");
407
408
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
@@ -520,10 +521,10 @@ var RadioGroup = ({
520
521
  ] });
521
522
  };
522
523
  RadioGroup.displayName = "RadioGroup";
523
- var Switch = React3__default.default.forwardRef(
524
+ var Switch = React13__default.default.forwardRef(
524
525
  ({ className, label, description, error, id, disabled, checked, defaultChecked, onChange, ...props }, ref) => {
525
526
  const switchId = id != null ? id : `switch-${Math.random().toString(36).slice(2, 9)}`;
526
- const [internalChecked, setInternalChecked] = React3__default.default.useState(
527
+ const [internalChecked, setInternalChecked] = React13__default.default.useState(
527
528
  defaultChecked != null ? defaultChecked : false
528
529
  );
529
530
  const isControlled = checked !== void 0;
@@ -592,6 +593,529 @@ var Switch = React3__default.default.forwardRef(
592
593
  }
593
594
  );
594
595
  Switch.displayName = "Switch";
596
+ var modalVariants = classVarianceAuthority.cva(
597
+ "relative bg-white rounded-(--radius-xl) shadow-lg w-full mx-4 transition-all",
598
+ {
599
+ variants: {
600
+ size: {
601
+ sm: "max-w-sm",
602
+ md: "max-w-md",
603
+ lg: "max-w-lg",
604
+ xl: "max-w-xl",
605
+ full: "max-w-full mx-4"
606
+ }
607
+ },
608
+ defaultVariants: {
609
+ size: "md"
610
+ }
611
+ }
612
+ );
613
+ var Modal = ({
614
+ open,
615
+ onClose,
616
+ children,
617
+ size,
618
+ className,
619
+ closeOnOverlayClick = true
620
+ }) => {
621
+ React13__default.default.useEffect(() => {
622
+ if (open) {
623
+ const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
624
+ document.body.style.overflow = "hidden";
625
+ document.body.style.paddingRight = `${scrollbarWidth}px`;
626
+ } else {
627
+ document.body.style.overflow = "";
628
+ document.body.style.paddingRight = "";
629
+ }
630
+ return () => {
631
+ document.body.style.overflow = "";
632
+ document.body.style.paddingRight = "";
633
+ };
634
+ }, [open]);
635
+ React13__default.default.useEffect(() => {
636
+ const handleKey = (e) => {
637
+ if (e.key === "Escape") onClose();
638
+ };
639
+ if (open) document.addEventListener("keydown", handleKey);
640
+ return () => document.removeEventListener("keydown", handleKey);
641
+ }, [open, onClose]);
642
+ if (!open) return null;
643
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [
644
+ /* @__PURE__ */ jsxRuntime.jsx(
645
+ "div",
646
+ {
647
+ className: "absolute inset-0 bg-black/50",
648
+ onClick: closeOnOverlayClick ? onClose : void 0
649
+ }
650
+ ),
651
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(modalVariants({ size }), className), children })
652
+ ] });
653
+ };
654
+ Modal.displayName = "Modal";
655
+ var ModalHeader = ({
656
+ className,
657
+ children,
658
+ onClose,
659
+ ...props
660
+ }) => /* @__PURE__ */ jsxRuntime.jsxs(
661
+ "div",
662
+ {
663
+ className: cn("flex items-start justify-between p-6 pb-4", className),
664
+ ...props,
665
+ children: [
666
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-1", children }),
667
+ onClose && /* @__PURE__ */ jsxRuntime.jsx(
668
+ "button",
669
+ {
670
+ type: "button",
671
+ onClick: onClose,
672
+ className: "ml-4 shrink-0 rounded-(--radius-md) p-1 text-(--color-neutral-400) hover:bg-(--color-neutral-100) hover:text-(--color-neutral-700) transition-colors",
673
+ children: /* @__PURE__ */ jsxRuntime.jsx(
674
+ "svg",
675
+ {
676
+ xmlns: "http://www.w3.org/2000/svg",
677
+ className: "h-4 w-4",
678
+ viewBox: "0 0 24 24",
679
+ fill: "none",
680
+ stroke: "currentColor",
681
+ strokeWidth: "2",
682
+ strokeLinecap: "round",
683
+ strokeLinejoin: "round",
684
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6 6 18M6 6l12 12" })
685
+ }
686
+ )
687
+ }
688
+ )
689
+ ]
690
+ }
691
+ );
692
+ ModalHeader.displayName = "ModalHeader";
693
+ var ModalTitle = ({
694
+ className,
695
+ ...props
696
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
697
+ "h2",
698
+ {
699
+ className: cn(
700
+ "text-lg font-semibold text-(--color-neutral-900)",
701
+ className
702
+ ),
703
+ ...props
704
+ }
705
+ );
706
+ ModalTitle.displayName = "ModalTitle";
707
+ var ModalDescription = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
708
+ "p",
709
+ {
710
+ className: cn("text-sm text-(--color-neutral-500)", className),
711
+ ...props
712
+ }
713
+ );
714
+ ModalDescription.displayName = "ModalDescription";
715
+ var ModalBody = ({
716
+ className,
717
+ ...props
718
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
719
+ "div",
720
+ {
721
+ className: cn("px-6 py-2 text-sm text-(--color-neutral-700)", className),
722
+ ...props
723
+ }
724
+ );
725
+ ModalBody.displayName = "ModalBody";
726
+ var ModalFooter = ({
727
+ className,
728
+ ...props
729
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
730
+ "div",
731
+ {
732
+ className: cn("flex items-center justify-end gap-2 p-6 pt-4", className),
733
+ ...props
734
+ }
735
+ );
736
+ ModalFooter.displayName = "ModalFooter";
737
+ var drawerVariants = classVarianceAuthority.cva(
738
+ "fixed z-50 bg-white shadow-xl transition-transform duration-300 ease-in-out",
739
+ {
740
+ variants: {
741
+ side: {
742
+ left: "inset-y-0 left-0 h-full",
743
+ right: "inset-y-0 right-0 h-full",
744
+ top: "inset-x-0 top-0 w-full",
745
+ bottom: "inset-x-0 bottom-0 w-full"
746
+ }
747
+ },
748
+ defaultVariants: {
749
+ side: "right"
750
+ }
751
+ }
752
+ );
753
+ var sizeStyle = {
754
+ sm: { width: "20rem" },
755
+ md: { width: "24rem" },
756
+ lg: { width: "32rem" },
757
+ full: { width: "100%" }
758
+ };
759
+ var translateMap = {
760
+ left: { closed: "translateX(-100%)", open: "translateX(0)" },
761
+ right: { closed: "translateX(100%)", open: "translateX(0)" },
762
+ top: { closed: "translateY(-100%)", open: "translateY(0)" },
763
+ bottom: { closed: "translateY(100%)", open: "translateY(0)" }
764
+ };
765
+ var Drawer = ({
766
+ open,
767
+ onClose,
768
+ children,
769
+ side = "right",
770
+ size = "md",
771
+ className,
772
+ closeOnOverlayClick = true
773
+ }) => {
774
+ React13__default.default.useEffect(() => {
775
+ if (open) {
776
+ const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
777
+ document.body.style.overflow = "hidden";
778
+ document.body.style.paddingRight = `${scrollbarWidth}px`;
779
+ } else {
780
+ document.body.style.overflow = "";
781
+ document.body.style.paddingRight = "";
782
+ }
783
+ return () => {
784
+ document.body.style.overflow = "";
785
+ document.body.style.paddingRight = "";
786
+ };
787
+ }, [open]);
788
+ React13__default.default.useEffect(() => {
789
+ const handleKey = (e) => {
790
+ if (e.key === "Escape") onClose();
791
+ };
792
+ if (open) document.addEventListener("keydown", handleKey);
793
+ return () => document.removeEventListener("keydown", handleKey);
794
+ }, [open, onClose]);
795
+ const resolvedSide = side != null ? side : "right";
796
+ const transform = open ? translateMap[resolvedSide].open : translateMap[resolvedSide].closed;
797
+ const isHorizontal = resolvedSide === "left" || resolvedSide === "right";
798
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("fixed inset-0 z-50", !open && "pointer-events-none"), children: [
799
+ /* @__PURE__ */ jsxRuntime.jsx(
800
+ "div",
801
+ {
802
+ className: cn(
803
+ "absolute inset-0 bg-black/50 transition-opacity duration-300",
804
+ open ? "opacity-100" : "opacity-0"
805
+ ),
806
+ onClick: closeOnOverlayClick ? onClose : void 0
807
+ }
808
+ ),
809
+ /* @__PURE__ */ jsxRuntime.jsx(
810
+ "div",
811
+ {
812
+ className: cn(drawerVariants({ side }), className),
813
+ style: {
814
+ transform,
815
+ ...isHorizontal ? sizeStyle[size] : { height: "auto", maxHeight: "80vh" }
816
+ },
817
+ children
818
+ }
819
+ )
820
+ ] });
821
+ };
822
+ Drawer.displayName = "Drawer";
823
+ var DrawerHeader = ({
824
+ className,
825
+ children,
826
+ onClose,
827
+ ...props
828
+ }) => /* @__PURE__ */ jsxRuntime.jsxs(
829
+ "div",
830
+ {
831
+ className: cn("flex items-start justify-between p-6 pb-4 border-b border-(--color-neutral-200)", className),
832
+ ...props,
833
+ children: [
834
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-1", children }),
835
+ onClose && /* @__PURE__ */ jsxRuntime.jsx(
836
+ "button",
837
+ {
838
+ type: "button",
839
+ onClick: onClose,
840
+ className: "ml-4 shrink-0 rounded-(--radius-md) p-1 text-(--color-neutral-400) hover:bg-(--color-neutral-100) hover:text-(--color-neutral-700) transition-colors",
841
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6 6 18M6 6l12 12" }) })
842
+ }
843
+ )
844
+ ]
845
+ }
846
+ );
847
+ DrawerHeader.displayName = "DrawerHeader";
848
+ var DrawerTitle = ({
849
+ className,
850
+ ...props
851
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
852
+ "h2",
853
+ {
854
+ className: cn("text-lg font-semibold text-(--color-neutral-900)", className),
855
+ ...props
856
+ }
857
+ );
858
+ DrawerTitle.displayName = "DrawerTitle";
859
+ var DrawerDescription = ({
860
+ className,
861
+ ...props
862
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
863
+ "p",
864
+ {
865
+ className: cn("text-sm text-(--color-neutral-500)", className),
866
+ ...props
867
+ }
868
+ );
869
+ DrawerDescription.displayName = "DrawerDescription";
870
+ var DrawerBody = ({
871
+ className,
872
+ ...props
873
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
874
+ "div",
875
+ {
876
+ className: cn("flex-1 overflow-y-auto p-6 text-sm text-(--color-neutral-700)", className),
877
+ ...props
878
+ }
879
+ );
880
+ DrawerBody.displayName = "DrawerBody";
881
+ var DrawerFooter = ({
882
+ className,
883
+ ...props
884
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
885
+ "div",
886
+ {
887
+ className: cn("flex items-center justify-end gap-2 p-6 pt-4 border-t border-(--color-neutral-200)", className),
888
+ ...props
889
+ }
890
+ );
891
+ DrawerFooter.displayName = "DrawerFooter";
892
+ var Tooltip = ({
893
+ content,
894
+ children,
895
+ side = "top",
896
+ delay = 300,
897
+ className
898
+ }) => {
899
+ var _a, _b;
900
+ const [visible, setVisible] = React13__default.default.useState(false);
901
+ const [coords, setCoords] = React13__default.default.useState(null);
902
+ const triggerRef = React13__default.default.useRef(null);
903
+ const tooltipRef = React13__default.default.useRef(null);
904
+ const timerRef = React13__default.default.useRef(null);
905
+ const computeCoords = React13__default.default.useCallback(() => {
906
+ if (!triggerRef.current || !tooltipRef.current) return;
907
+ const t = triggerRef.current.getBoundingClientRect();
908
+ const tt = tooltipRef.current.getBoundingClientRect();
909
+ const offset = 8;
910
+ switch (side) {
911
+ case "top":
912
+ setCoords({
913
+ top: t.top - tt.height - offset,
914
+ left: t.left + t.width / 2 - tt.width / 2
915
+ });
916
+ break;
917
+ case "bottom":
918
+ setCoords({
919
+ top: t.bottom + offset,
920
+ left: t.left + t.width / 2 - tt.width / 2
921
+ });
922
+ break;
923
+ case "left":
924
+ setCoords({
925
+ top: t.top + t.height / 2 - tt.height / 2,
926
+ left: t.left - tt.width - offset
927
+ });
928
+ break;
929
+ case "right":
930
+ setCoords({
931
+ top: t.top + t.height / 2 - tt.height / 2,
932
+ left: t.right + offset
933
+ });
934
+ break;
935
+ }
936
+ }, [side]);
937
+ React13__default.default.useLayoutEffect(() => {
938
+ if (!visible) return;
939
+ computeCoords();
940
+ }, [computeCoords, content, visible]);
941
+ React13__default.default.useEffect(() => {
942
+ if (!visible) return;
943
+ window.addEventListener("resize", computeCoords);
944
+ window.addEventListener("scroll", computeCoords, true);
945
+ return () => {
946
+ window.removeEventListener("resize", computeCoords);
947
+ window.removeEventListener("scroll", computeCoords, true);
948
+ };
949
+ }, [computeCoords, visible]);
950
+ const show = () => {
951
+ if (timerRef.current) clearTimeout(timerRef.current);
952
+ timerRef.current = setTimeout(() => {
953
+ setCoords(null);
954
+ setVisible(true);
955
+ }, delay);
956
+ };
957
+ const hide = () => {
958
+ if (timerRef.current) clearTimeout(timerRef.current);
959
+ setVisible(false);
960
+ setCoords(null);
961
+ };
962
+ React13__default.default.useEffect(() => {
963
+ return () => {
964
+ if (timerRef.current) clearTimeout(timerRef.current);
965
+ };
966
+ }, []);
967
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
968
+ /* @__PURE__ */ jsxRuntime.jsx(
969
+ "div",
970
+ {
971
+ ref: triggerRef,
972
+ className: "inline-flex",
973
+ onMouseEnter: show,
974
+ onMouseLeave: hide,
975
+ onFocus: show,
976
+ onBlur: hide,
977
+ children
978
+ }
979
+ ),
980
+ visible && /* @__PURE__ */ jsxRuntime.jsx(
981
+ "div",
982
+ {
983
+ ref: tooltipRef,
984
+ role: "tooltip",
985
+ className: cn(
986
+ "fixed z-50 px-2.5 py-1.5 text-xs font-medium text-white rounded-(--radius-md) shadow-md pointer-events-none whitespace-nowrap transition-opacity",
987
+ coords ? "opacity-100" : "opacity-0",
988
+ className
989
+ ),
990
+ style: {
991
+ top: (_a = coords == null ? void 0 : coords.top) != null ? _a : 0,
992
+ left: (_b = coords == null ? void 0 : coords.left) != null ? _b : 0,
993
+ backgroundColor: "var(--color-neutral-900)"
994
+ },
995
+ children: content
996
+ }
997
+ )
998
+ ] });
999
+ };
1000
+ Tooltip.displayName = "Tooltip";
1001
+ var Popover = ({
1002
+ content,
1003
+ children,
1004
+ side = "bottom",
1005
+ align = "center",
1006
+ open,
1007
+ defaultOpen = false,
1008
+ onOpenChange,
1009
+ className,
1010
+ closeOnOutsideClick = true
1011
+ }) => {
1012
+ var _a, _b;
1013
+ const [uncontrolledOpen, setUncontrolledOpen] = React13__default.default.useState(defaultOpen);
1014
+ const [coords, setCoords] = React13__default.default.useState(null);
1015
+ const [mounted, setMounted] = React13__default.default.useState(false);
1016
+ const triggerRef = React13__default.default.useRef(null);
1017
+ const popoverRef = React13__default.default.useRef(null);
1018
+ const isControlled = open !== void 0;
1019
+ const isOpen = isControlled ? open : uncontrolledOpen;
1020
+ const setOpen = React13__default.default.useCallback((nextOpen) => {
1021
+ if (!isControlled) setUncontrolledOpen(nextOpen);
1022
+ onOpenChange == null ? void 0 : onOpenChange(nextOpen);
1023
+ }, [isControlled, onOpenChange]);
1024
+ const close = React13__default.default.useCallback(() => setOpen(false), [setOpen]);
1025
+ const openPopover = React13__default.default.useCallback(() => setOpen(true), [setOpen]);
1026
+ const controls = React13__default.default.useMemo(() => ({
1027
+ close,
1028
+ open: openPopover,
1029
+ setOpen
1030
+ }), [close, openPopover, setOpen]);
1031
+ const computeCoords = React13__default.default.useCallback(() => {
1032
+ if (!triggerRef.current || !popoverRef.current) return;
1033
+ const trigger = triggerRef.current.getBoundingClientRect();
1034
+ const popover2 = popoverRef.current.getBoundingClientRect();
1035
+ const offset = 8;
1036
+ let top = 0;
1037
+ let left = 0;
1038
+ if (side === "top") top = trigger.top - popover2.height - offset;
1039
+ if (side === "bottom") top = trigger.bottom + offset;
1040
+ if (side === "left") left = trigger.left - popover2.width - offset;
1041
+ if (side === "right") left = trigger.right + offset;
1042
+ if (side === "top" || side === "bottom") {
1043
+ if (align === "start") left = trigger.left;
1044
+ if (align === "center") left = trigger.left + trigger.width / 2 - popover2.width / 2;
1045
+ if (align === "end") left = trigger.right - popover2.width;
1046
+ }
1047
+ if (side === "left" || side === "right") {
1048
+ if (align === "start") top = trigger.top;
1049
+ if (align === "center") top = trigger.top + trigger.height / 2 - popover2.height / 2;
1050
+ if (align === "end") top = trigger.bottom - popover2.height;
1051
+ }
1052
+ setCoords({
1053
+ top: Math.max(8, Math.min(top, window.innerHeight - popover2.height - 8)),
1054
+ left: Math.max(8, Math.min(left, window.innerWidth - popover2.width - 8))
1055
+ });
1056
+ }, [align, side]);
1057
+ React13__default.default.useEffect(() => {
1058
+ setMounted(true);
1059
+ }, []);
1060
+ React13__default.default.useLayoutEffect(() => {
1061
+ if (!isOpen) return;
1062
+ computeCoords();
1063
+ }, [computeCoords, content, isOpen]);
1064
+ React13__default.default.useEffect(() => {
1065
+ if (!isOpen) return;
1066
+ const handleKeyDown = (event) => {
1067
+ if (event.key === "Escape") close();
1068
+ };
1069
+ const handlePointerDown = (event) => {
1070
+ var _a2, _b2;
1071
+ const target = event.target;
1072
+ const clickedTrigger = (_a2 = triggerRef.current) == null ? void 0 : _a2.contains(target);
1073
+ const clickedPopover = (_b2 = popoverRef.current) == null ? void 0 : _b2.contains(target);
1074
+ if (!clickedTrigger && !clickedPopover) close();
1075
+ };
1076
+ document.addEventListener("keydown", handleKeyDown);
1077
+ if (closeOnOutsideClick) document.addEventListener("pointerdown", handlePointerDown);
1078
+ window.addEventListener("resize", computeCoords);
1079
+ window.addEventListener("scroll", computeCoords, true);
1080
+ return () => {
1081
+ document.removeEventListener("keydown", handleKeyDown);
1082
+ document.removeEventListener("pointerdown", handlePointerDown);
1083
+ window.removeEventListener("resize", computeCoords);
1084
+ window.removeEventListener("scroll", computeCoords, true);
1085
+ };
1086
+ }, [close, closeOnOutsideClick, computeCoords, isOpen]);
1087
+ const popover = isOpen ? /* @__PURE__ */ jsxRuntime.jsx(
1088
+ "div",
1089
+ {
1090
+ ref: popoverRef,
1091
+ role: "dialog",
1092
+ className: cn(
1093
+ "fixed z-50 min-w-48 rounded-(--radius-lg) border border-(--color-neutral-200) bg-white p-4 text-sm text-(--color-neutral-700) shadow-lg outline-none transition-opacity",
1094
+ coords ? "opacity-100" : "opacity-0",
1095
+ className
1096
+ ),
1097
+ style: {
1098
+ top: (_a = coords == null ? void 0 : coords.top) != null ? _a : 0,
1099
+ left: (_b = coords == null ? void 0 : coords.left) != null ? _b : 0
1100
+ },
1101
+ children: typeof content === "function" ? content(controls) : content
1102
+ }
1103
+ ) : null;
1104
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1105
+ /* @__PURE__ */ jsxRuntime.jsx(
1106
+ "div",
1107
+ {
1108
+ ref: triggerRef,
1109
+ className: "inline-flex",
1110
+ "aria-expanded": isOpen,
1111
+ onClick: () => setOpen(!isOpen),
1112
+ children
1113
+ }
1114
+ ),
1115
+ mounted && popover ? reactDom.createPortal(popover, document.body) : null
1116
+ ] });
1117
+ };
1118
+ Popover.displayName = "Popover";
595
1119
 
596
1120
  exports.Avatar = Avatar;
597
1121
  exports.Badge = Badge;
@@ -603,20 +1127,36 @@ exports.CardFooter = CardFooter;
603
1127
  exports.CardHeader = CardHeader;
604
1128
  exports.CardTitle = CardTitle;
605
1129
  exports.Checkbox = Checkbox;
1130
+ exports.Drawer = Drawer;
1131
+ exports.DrawerBody = DrawerBody;
1132
+ exports.DrawerDescription = DrawerDescription;
1133
+ exports.DrawerFooter = DrawerFooter;
1134
+ exports.DrawerHeader = DrawerHeader;
1135
+ exports.DrawerTitle = DrawerTitle;
606
1136
  exports.Input = Input;
1137
+ exports.Modal = Modal;
1138
+ exports.ModalBody = ModalBody;
1139
+ exports.ModalDescription = ModalDescription;
1140
+ exports.ModalFooter = ModalFooter;
1141
+ exports.ModalHeader = ModalHeader;
1142
+ exports.ModalTitle = ModalTitle;
1143
+ exports.Popover = Popover;
607
1144
  exports.RadioGroup = RadioGroup;
608
1145
  exports.Select = Select;
609
1146
  exports.Separator = Separator;
610
1147
  exports.Spinner = Spinner;
611
1148
  exports.Switch = Switch;
1149
+ exports.Tooltip = Tooltip;
612
1150
  exports.avatarVariants = avatarVariants;
613
1151
  exports.badgeVariants = badgeVariants;
614
1152
  exports.buttonVariants = buttonVariants;
615
1153
  exports.cardVariants = cardVariants;
616
1154
  exports.cn = cn;
617
1155
  exports.colors = colors;
1156
+ exports.drawerVariants = drawerVariants;
618
1157
  exports.fontSize = fontSize;
619
1158
  exports.inputVariants = inputVariants;
1159
+ exports.modalVariants = modalVariants;
620
1160
  exports.radius = radius;
621
1161
  exports.selectVariants = selectVariants;
622
1162
  exports.separatorVariants = separatorVariants;