@underverse-ui/underverse 0.2.30 → 0.2.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.
package/dist/index.cjs CHANGED
@@ -2688,11 +2688,6 @@ var ToastProvider = ({ children, position = "top-right", maxToasts = 5 }) => {
2688
2688
  const updated = [newToast, ...prev];
2689
2689
  return updated.slice(0, maxToasts);
2690
2690
  });
2691
- if (toast.duration !== 0) {
2692
- setTimeout(() => {
2693
- removeToast(id);
2694
- }, toast.duration || 5e3);
2695
- }
2696
2691
  },
2697
2692
  [maxToasts, removeToast]
2698
2693
  );
@@ -2713,53 +2708,59 @@ var ToastComponent = ({ toast, onRemove }) => {
2713
2708
  const [isVisible, setIsVisible] = (0, import_react8.useState)(false);
2714
2709
  const [progress, setProgress] = (0, import_react8.useState)(100);
2715
2710
  const [paused, setPaused] = (0, import_react8.useState)(false);
2716
- const [startTs] = (0, import_react8.useState)(() => Date.now());
2717
2711
  const total = toast.duration && toast.duration > 0 ? toast.duration : 5e3;
2718
- const [remaining, setRemaining] = (0, import_react8.useState)(total);
2712
+ const endTsRef = (0, import_react8.useRef)(Date.now() + total);
2713
+ const remainingRef = (0, import_react8.useRef)(total);
2714
+ const pausedRef = (0, import_react8.useRef)(false);
2715
+ const handleRemove = (0, import_react8.useCallback)(() => {
2716
+ setIsVisible(false);
2717
+ setTimeout(() => onRemove(toast.id), 150);
2718
+ }, [onRemove, toast.id]);
2719
2719
  (0, import_react8.useEffect)(() => {
2720
2720
  setIsVisible(true);
2721
2721
  if (toast.duration === 0) return;
2722
- let raf;
2723
- const tick = () => {
2724
- if (!paused) {
2725
- const elapsed = Date.now() - startTs;
2726
- const remain = Math.max(total - elapsed, 0);
2727
- setRemaining(remain);
2722
+ remainingRef.current = total;
2723
+ endTsRef.current = Date.now() + total;
2724
+ const intervalId = window.setInterval(() => {
2725
+ if (!pausedRef.current) {
2726
+ const remain = Math.max(endTsRef.current - Date.now(), 0);
2727
+ remainingRef.current = remain;
2728
2728
  setProgress(remain / total * 100);
2729
2729
  if (remain === 0) {
2730
2730
  handleRemove();
2731
- return;
2732
2731
  }
2733
2732
  }
2734
- raf = requestAnimationFrame(tick);
2735
- };
2736
- raf = requestAnimationFrame(tick);
2737
- return () => cancelAnimationFrame(raf);
2738
- }, []);
2739
- const handleRemove = () => {
2740
- setIsVisible(false);
2741
- setTimeout(() => onRemove(toast.id), 150);
2742
- };
2733
+ }, 50);
2734
+ return () => window.clearInterval(intervalId);
2735
+ }, [handleRemove, toast.duration, total]);
2743
2736
  const typeConfig = {
2744
2737
  success: {
2745
2738
  icon: import_lucide_react7.CheckCircle,
2746
- className: "bg-success/10 border-success/20 text-foreground",
2747
- iconClassName: "text-success"
2739
+ containerClassName: "bg-success/5 border-success/30",
2740
+ iconClassName: "text-success",
2741
+ iconBgClassName: "bg-success/15",
2742
+ accentBarClassName: "bg-success"
2748
2743
  },
2749
2744
  error: {
2750
2745
  icon: import_lucide_react7.AlertCircle,
2751
- className: "bg-destructive/10 border-destructive/20 text-foreground",
2752
- iconClassName: "text-destructive"
2746
+ containerClassName: "bg-destructive/5 border-destructive/30",
2747
+ iconClassName: "text-destructive",
2748
+ iconBgClassName: "bg-destructive/15",
2749
+ accentBarClassName: "bg-destructive"
2753
2750
  },
2754
2751
  warning: {
2755
2752
  icon: import_lucide_react7.AlertTriangle,
2756
- className: "bg-warning/10 border-warning/20 text-foreground",
2757
- iconClassName: "text-warning"
2753
+ containerClassName: "bg-warning/5 border-warning/30",
2754
+ iconClassName: "text-warning",
2755
+ iconBgClassName: "bg-warning/15",
2756
+ accentBarClassName: "bg-warning"
2758
2757
  },
2759
2758
  info: {
2760
2759
  icon: import_lucide_react7.Info,
2761
- className: "bg-info/10 border-info/20 text-foreground",
2762
- iconClassName: "text-info"
2760
+ containerClassName: "bg-info/5 border-info/30",
2761
+ iconClassName: "text-info",
2762
+ iconBgClassName: "bg-info/15",
2763
+ accentBarClassName: "bg-info"
2763
2764
  }
2764
2765
  };
2765
2766
  const config = typeConfig[toast.type];
@@ -2768,18 +2769,30 @@ var ToastComponent = ({ toast, onRemove }) => {
2768
2769
  "div",
2769
2770
  {
2770
2771
  className: cn(
2771
- "relative w-80 rounded-lg border backdrop-blur-sm transition-all duration-300 ease-soft pointer-events-auto",
2772
- "bg-card/95 shadow-lg animate-in slide-in-from-right-full",
2773
- config.className,
2772
+ "relative w-80 rounded-r-lg border border-l-0 backdrop-blur-md transition-all duration-300 pointer-events-auto overflow-hidden",
2773
+ "bg-card shadow-xl",
2774
+ "animate-in slide-in-from-right-full",
2775
+ config.containerClassName,
2774
2776
  isVisible ? "opacity-100 translate-x-0" : "opacity-0 translate-x-full"
2775
2777
  ),
2776
2778
  role: "status",
2777
2779
  "aria-live": toast.type === "error" ? "assertive" : "polite",
2778
- onMouseEnter: () => setPaused(true),
2779
- onMouseLeave: () => setPaused(false),
2780
+ onMouseEnter: () => {
2781
+ if (toast.duration === 0) return;
2782
+ pausedRef.current = true;
2783
+ remainingRef.current = Math.max(endTsRef.current - Date.now(), 0);
2784
+ setPaused(true);
2785
+ },
2786
+ onMouseLeave: () => {
2787
+ if (toast.duration === 0) return;
2788
+ pausedRef.current = false;
2789
+ endTsRef.current = Date.now() + remainingRef.current;
2790
+ setPaused(false);
2791
+ },
2780
2792
  children: [
2781
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-start gap-3 p-4", children: [
2782
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { className: cn("h-5 w-5 mt-0.5 shrink-0", config.iconClassName) }),
2793
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cn("absolute left-0 top-0 bottom-0 w-1", config.accentBarClassName) }),
2794
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-start gap-3 p-4 pl-5", children: [
2795
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cn("flex items-center justify-center w-8 h-8 rounded-full shrink-0", config.iconBgClassName), children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { className: cn("h-4 w-4", config.iconClassName) }) }),
2783
2796
  /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex-1 space-y-1", children: [
2784
2797
  toast.title && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h4", { className: "font-medium text-sm leading-none", children: toast.title }),
2785
2798
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-sm text-muted-foreground leading-relaxed", children: toast.message }),