@avenue-ticketing/ui 0.5.0 → 0.6.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.
@@ -87,9 +87,7 @@ var Checkbox = React5.forwardRef(
87
87
  ...rest
88
88
  }, ref) => {
89
89
  const isControlled = checkedProp !== void 0;
90
- const [uncontrolledChecked, setUncontrolledChecked] = useState(
91
- defaultChecked
92
- );
90
+ const [uncontrolledChecked, setUncontrolledChecked] = useState(defaultChecked);
93
91
  const checked = isControlled ? checkedProp : uncontrolledChecked;
94
92
  const ariaChecked = indeterminate ? "mixed" : checked ? true : false;
95
93
  return /* @__PURE__ */ jsx(
@@ -130,7 +128,7 @@ var Checkbox = React5.forwardRef(
130
128
  className: cn(
131
129
  "flex size-5 shrink-0 items-center justify-center rounded-[4px] border",
132
130
  !disabled && (indeterminate ? "border-primary bg-primary text-background" : checked ? "border-primary bg-primary text-background" : "border-primary/20 bg-background"),
133
- disabled && (indeterminate ? "border-primary/40 bg-primary/45 text-primary-foreground" : checked ? "border-primary/40 bg-primary/45 text-primary-foreground" : "border-primary/10 bg-muted/25")
131
+ disabled && (indeterminate ? "border-transparent bg-primary/45 text-primary-foreground" : checked ? "border-transparent bg-primary/45 text-primary-foreground" : "border-primary/10 bg-muted/25")
134
132
  ),
135
133
  children: indeterminate ? /* @__PURE__ */ jsx(
136
134
  "span",
@@ -219,6 +217,22 @@ function resolveDropdownMobileSheet(mobileOptions) {
219
217
  };
220
218
  }
221
219
  var DROPDOWN_SUB_CONTENT_ATTR = "data-dropdown-sub-content";
220
+ var DROPDOWN_PANEL_SHADOW = "shadow-[0_12px_32px_-8px_rgba(0,0,0,0.18),0_2px_6px_-2px_rgba(0,0,0,0.06)] dark:shadow-[0_12px_32px_-8px_rgba(0,0,0,0.55),0_2px_6px_-2px_rgba(0,0,0,0.35)]";
221
+ var DROPDOWN_PANEL_SCROLL = "[&_*]:[scrollbar-width:none] [&_*::-webkit-scrollbar]:hidden [&_*]:overscroll-contain";
222
+ function preventMenuWheelChain(menu, e) {
223
+ let el = e.target;
224
+ while (el && menu.contains(el)) {
225
+ const oy = getComputedStyle(el).overflowY;
226
+ if ((oy === "auto" || oy === "scroll") && el.scrollHeight > el.clientHeight) {
227
+ const atTop = el.scrollTop <= 0;
228
+ const atBottom = el.scrollTop + el.clientHeight >= el.scrollHeight;
229
+ if (e.deltaY < 0 && !atTop || e.deltaY > 0 && !atBottom) return;
230
+ break;
231
+ }
232
+ el = el.parentElement;
233
+ }
234
+ e.preventDefault();
235
+ }
222
236
  var DROPDOWN_SHEET_MENU_TEXT = "max-[1024px]:text-base";
223
237
  var DROPDOWN_SHEET_MENU_SHORTCUT = "max-[1024px]:text-sm";
224
238
  var DROPDOWN_CONTENT_ORIGIN = {
@@ -302,10 +316,12 @@ function computePos(trigger, menu, side, align, offset, pad) {
302
316
  return { top, left, side: effectiveSide };
303
317
  }
304
318
  function useIsMobile(breakpoint = 1025) {
305
- const [isMobile, setIsMobile] = useState(false);
319
+ const [isMobile, setIsMobile] = useState(() => {
320
+ if (typeof window === "undefined") return false;
321
+ return window.matchMedia(`(max-width: ${breakpoint - 1}px)`).matches;
322
+ });
306
323
  useEffect(() => {
307
324
  const mq = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);
308
- setIsMobile(mq.matches);
309
325
  const handler = (e) => setIsMobile(e.matches);
310
326
  mq.addEventListener("change", handler);
311
327
  return () => mq.removeEventListener("change", handler);
@@ -450,6 +466,7 @@ function DropdownMobileBottomSheetPortal({
450
466
  onRequestClose,
451
467
  menuRef,
452
468
  portalZClassName = "z-50",
469
+ isSubPortal = false,
453
470
  children,
454
471
  className,
455
472
  style,
@@ -461,6 +478,7 @@ function DropdownMobileBottomSheetPortal({
461
478
  /* @__PURE__ */ jsxs(
462
479
  "div",
463
480
  {
481
+ ...isSubPortal ? { [DROPDOWN_SUB_CONTENT_ATTR]: "" } : {},
464
482
  className: cn(
465
483
  "fixed inset-0 flex items-end justify-center p-0",
466
484
  portalZClassName
@@ -487,8 +505,9 @@ function DropdownMobileBottomSheetPortal({
487
505
  ...panelProps,
488
506
  ref: menuRef,
489
507
  className: cn(
490
- "bg-background border-primary/10 relative z-10 flex w-full max-h-[min(90dvh,calc(100dvh-env(safe-area-inset-bottom,0px)))] flex-col overflow-hidden shadow-2xl outline-none",
508
+ "bg-background border-primary/8 relative z-10 flex w-full max-h-[min(90dvh,calc(100dvh-env(safe-area-inset-bottom,0px)))] flex-col overflow-hidden shadow-2xl outline-none",
491
509
  "rounded-t-2xl rounded-b-none border-x-0 border-b-0 border-t",
510
+ DROPDOWN_PANEL_SCROLL,
492
511
  sheetExtraClassName,
493
512
  className
494
513
  ),
@@ -565,25 +584,25 @@ var DropdownContent = ({
565
584
  const [pos, setPos] = useState({ top: -9999, left: -9999, side });
566
585
  const [triggerW, setTriggerW] = useState(0);
567
586
  const menuRef = useRef(null);
568
- const resolvedMobile = useMemo(
569
- () => resolveDropdownMobileSheet(mobileOptions),
570
- [mobileOptions]
571
- );
572
- const slideOffsetPx = useMemo(
573
- () => slideEntranceOffsetPxProp ?? DROPDOWN_MOBILE_SHEET_SLIDE_ENTRANCE_OFFSET_DEFAULT_PX,
574
- [slideEntranceOffsetPxProp]
575
- );
576
- const closeDuration = isMobile && resolvedMobile.sheet ? DROPDOWN_MOBILE_SHEET_MOTION_MS : duration;
577
- const closeMenu = useCallback(() => setOpen(false), [setOpen]);
587
+ const resolvedMobile = resolveDropdownMobileSheet(mobileOptions);
588
+ const isMobileSheet = isMobile && resolvedMobile.sheet;
589
+ const slideOffsetPx = slideEntranceOffsetPxProp ?? DROPDOWN_MOBILE_SHEET_SLIDE_ENTRANCE_OFFSET_DEFAULT_PX;
578
590
  useEffect(() => {
579
591
  if (open) {
580
592
  setShouldRender(true);
581
- } else {
582
- setIsAnimating(false);
583
- const timer = setTimeout(() => setShouldRender(false), closeDuration);
584
- return () => clearTimeout(timer);
593
+ return;
585
594
  }
586
- }, [open, closeDuration]);
595
+ if (!isMobileSheet) {
596
+ setShouldRender(false);
597
+ return;
598
+ }
599
+ setIsAnimating(false);
600
+ const t = setTimeout(
601
+ () => setShouldRender(false),
602
+ DROPDOWN_MOBILE_SHEET_MOTION_MS
603
+ );
604
+ return () => clearTimeout(t);
605
+ }, [open, isMobileSheet]);
587
606
  useEffect(() => {
588
607
  if (!shouldRender || !open) return;
589
608
  let raf2 = 0;
@@ -613,12 +632,27 @@ var DropdownContent = ({
613
632
  };
614
633
  update();
615
634
  window.addEventListener("resize", update);
616
- window.addEventListener("scroll", update, true);
617
635
  return () => {
618
636
  window.removeEventListener("resize", update);
619
- window.removeEventListener("scroll", update, true);
620
637
  };
621
638
  }, [shouldRender, side, align, offset, viewportPadding]);
639
+ useEffect(() => {
640
+ if (!open || isMobileSheet) return;
641
+ const isInsideMenu = (t) => t instanceof Node && (!!menuRef.current?.contains(t) || !!triggerRef.current?.contains(t) || t instanceof Element && !!t.closest(`[${DROPDOWN_SUB_CONTENT_ATTR}]`));
642
+ const onScroll = (e) => {
643
+ if (!isInsideMenu(e.target)) setOpen(false);
644
+ };
645
+ window.addEventListener("scroll", onScroll, true);
646
+ return () => window.removeEventListener("scroll", onScroll, true);
647
+ }, [open, isMobileSheet, setOpen, triggerRef]);
648
+ useEffect(() => {
649
+ if (!shouldRender || isMobileSheet) return;
650
+ const menu = menuRef.current;
651
+ if (!menu) return;
652
+ const onWheel = (e) => preventMenuWheelChain(menu, e);
653
+ menu.addEventListener("wheel", onWheel, { passive: false });
654
+ return () => menu.removeEventListener("wheel", onWheel);
655
+ }, [shouldRender, isMobileSheet]);
622
656
  useEffect(() => {
623
657
  if (isAnimating && menuRef.current) {
624
658
  menuRef.current.focus();
@@ -684,15 +718,14 @@ var DropdownContent = ({
684
718
  return () => window.removeEventListener("keydown", handler);
685
719
  }, [open, closeOnEscape, loop, setOpen, triggerRef]);
686
720
  useEffect(() => {
687
- if (open && isMobile && resolvedMobile.sheet) {
688
- document.body.style.overflow = "hidden";
689
- }
721
+ if (!open || !isMobileSheet) return;
722
+ document.body.style.overflow = "hidden";
690
723
  return () => {
691
724
  document.body.style.overflow = "";
692
725
  };
693
- }, [open, isMobile, resolvedMobile.sheet]);
726
+ }, [open, isMobileSheet]);
694
727
  if (!shouldRender || typeof document === "undefined") return null;
695
- if (isMobile && resolvedMobile.sheet) {
728
+ if (isMobileSheet) {
696
729
  return /* @__PURE__ */ jsx(
697
730
  DropdownMobileBottomSheetPortal,
698
731
  {
@@ -704,7 +737,7 @@ var DropdownContent = ({
704
737
  sheetTitle: resolvedMobile.title,
705
738
  sheetExtraClassName: resolvedMobile.sheetExtraClassName,
706
739
  contentClassName: resolvedMobile.contentClassName,
707
- onRequestClose: closeMenu,
740
+ onRequestClose: () => setOpen(false),
708
741
  menuRef,
709
742
  portalZClassName: "z-50",
710
743
  className,
@@ -727,7 +760,9 @@ var DropdownContent = ({
727
760
  "aria-orientation": "vertical",
728
761
  tabIndex: -1,
729
762
  className: cn(
730
- "bg-background border-primary/10 absolute z-50 overflow-hidden rounded-xl border py-1.5 shadow-xl outline-none",
763
+ "bg-background border-primary/8 absolute z-50 overflow-hidden rounded-xl border py-1.5 outline-none",
764
+ DROPDOWN_PANEL_SHADOW,
765
+ DROPDOWN_PANEL_SCROLL,
731
766
  className
732
767
  ),
733
768
  style: {
@@ -803,7 +838,7 @@ var DropdownItem = ({
803
838
  ),
804
839
  children: [
805
840
  icon && /* @__PURE__ */ jsx("span", { className: "flex size-4 shrink-0 items-center justify-center", children: icon }),
806
- /* @__PURE__ */ jsx("span", { className: "flex-1", children }),
841
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1", children }),
807
842
  shortcut ? /* @__PURE__ */ jsx(
808
843
  "span",
809
844
  {