@bizapps/ui 1.2.2 → 1.3.3

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/main.cjs CHANGED
@@ -1598,7 +1598,8 @@ var ease = {
1598
1598
  smooth: [0.4, 0, 0.2, 1],
1599
1599
  enter: [0, 0, 0.2, 1],
1600
1600
  exit: [0.4, 0, 1, 1],
1601
- linear: [0, 0, 1, 1]
1601
+ linear: [0, 0, 1, 1],
1602
+ drawer: [0.22, 1, 0.36, 1]
1602
1603
  };
1603
1604
  var spring = {
1604
1605
  gentle: { type: "spring", stiffness: 260, damping: 28 },
@@ -1642,6 +1643,15 @@ var transition = {
1642
1643
  card: {
1643
1644
  duration: duration.fast,
1644
1645
  ease: ease.smooth
1646
+ },
1647
+ // Drawer / slide panel — smooth enter, fast exit
1648
+ drawer: {
1649
+ duration: 0.3,
1650
+ ease: ease.drawer
1651
+ },
1652
+ drawerExit: {
1653
+ duration: 0.2,
1654
+ ease: ease.exit
1645
1655
  }
1646
1656
  };
1647
1657
  var fadeIn = {
@@ -8364,14 +8374,170 @@ function DataTableSearch({
8364
8374
  )
8365
8375
  ] });
8366
8376
  }
8367
- var DrawerContext = react.createContext(false);
8368
- function Drawer({ children, open, onOpenChange, ...props }) {
8377
+ function BottomNav({ items, className }) {
8378
+ return /* @__PURE__ */ jsxRuntime.jsx(
8379
+ "nav",
8380
+ {
8381
+ "data-slot": "bottom-nav",
8382
+ className: cn(
8383
+ "fixed bottom-0 left-0 right-0 z-50 mx-4 mb-4 rounded-2xl bg-background shadow-[0_-4px_20px_rgba(0,0,0,0.08)]",
8384
+ className
8385
+ ),
8386
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-20 items-center justify-around px-4", children: items.map(({ label, href, icon, isActive, onClick }) => /* @__PURE__ */ jsxRuntime.jsxs(
8387
+ "a",
8388
+ {
8389
+ href,
8390
+ onClick,
8391
+ "data-slot": "bottom-nav-item",
8392
+ className: cn(
8393
+ "group flex flex-col items-center gap-0 transition-colors",
8394
+ isActive ? "text-primary" : "text-muted-foreground"
8395
+ ),
8396
+ children: [
8397
+ /* @__PURE__ */ jsxRuntime.jsxs(
8398
+ "span",
8399
+ {
8400
+ className: cn(
8401
+ "flex h-12 items-center justify-center rounded-2xl transition-all",
8402
+ isActive ? "flex-col gap-0.5 bg-primary/10 px-4" : "w-12 group-hover:bg-muted group-active:bg-primary/10"
8403
+ ),
8404
+ children: [
8405
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-6 w-6 shrink-0", children: icon }),
8406
+ isActive && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-semibold leading-none", children: label })
8407
+ ]
8408
+ }
8409
+ ),
8410
+ /* @__PURE__ */ jsxRuntime.jsx(
8411
+ "span",
8412
+ {
8413
+ className: cn(
8414
+ "text-[10px] font-medium",
8415
+ isActive ? "invisible" : "visible"
8416
+ ),
8417
+ children: label
8418
+ }
8419
+ ),
8420
+ /* @__PURE__ */ jsxRuntime.jsx(
8421
+ "span",
8422
+ {
8423
+ className: cn(
8424
+ "h-1 w-5 rounded-full transition-all",
8425
+ isActive ? "bg-primary" : "bg-transparent"
8426
+ )
8427
+ }
8428
+ )
8429
+ ]
8430
+ },
8431
+ href
8432
+ )) })
8433
+ }
8434
+ );
8435
+ }
8436
+ var BottomNavTabsContext = react.createContext(null);
8437
+ function useBottomNavTabsContext() {
8438
+ const ctx = react.useContext(BottomNavTabsContext);
8439
+ if (!ctx) throw new Error("BottomNavTabsList must be inside BottomNavTabs");
8440
+ return ctx;
8441
+ }
8442
+ function BottomNavTabs({
8443
+ defaultValue,
8444
+ value: controlledValue,
8445
+ onValueChange,
8446
+ ...props
8447
+ }) {
8448
+ const [internalValue, setInternalValue] = react.useState(controlledValue ?? defaultValue ?? "");
8449
+ const activeValue = controlledValue ?? internalValue;
8450
+ const listId = react.useId();
8451
+ const handleValueChange = (v) => {
8452
+ if (controlledValue === void 0) setInternalValue(v);
8453
+ onValueChange?.(v);
8454
+ };
8455
+ return /* @__PURE__ */ jsxRuntime.jsx(BottomNavTabsContext.Provider, { value: { activeValue, listId }, children: /* @__PURE__ */ jsxRuntime.jsx(
8456
+ radixUi.Tabs.Root,
8457
+ {
8458
+ "data-slot": "bottom-nav-tabs",
8459
+ value: activeValue,
8460
+ onValueChange: handleValueChange,
8461
+ ...props
8462
+ }
8463
+ ) });
8464
+ }
8465
+ function BottomNavTabsContent({
8466
+ className,
8467
+ ...props
8468
+ }) {
8469
+ return /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { className: cn("pb-28", className), ...props });
8470
+ }
8471
+ function BottomNavTabsList({ items, className }) {
8472
+ const { activeValue, listId } = useBottomNavTabsContext();
8473
+ return /* @__PURE__ */ jsxRuntime.jsx(
8474
+ "nav",
8475
+ {
8476
+ "data-slot": "bottom-nav-tabs-list",
8477
+ className: cn(
8478
+ "fixed bottom-0 left-0 right-0 z-50 mx-4 mb-4 rounded-2xl bg-background shadow-[0_-4px_20px_rgba(0,0,0,0.08)]",
8479
+ className
8480
+ ),
8481
+ children: /* @__PURE__ */ jsxRuntime.jsx(radixUi.Tabs.List, { className: "flex h-20 items-center justify-around px-4", children: items.map(({ value, label, icon, activeIcon }) => {
8482
+ const isActive = value === activeValue;
8483
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8484
+ radixUi.Tabs.Trigger,
8485
+ {
8486
+ value,
8487
+ "data-slot": "bottom-nav-tabs-trigger",
8488
+ className: cn(
8489
+ "group flex flex-col items-center gap-0.5 transition-colors",
8490
+ "data-[state=active]:text-primary data-[state=inactive]:text-muted-foreground",
8491
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:rounded-2xl"
8492
+ ),
8493
+ children: [
8494
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "relative flex h-12 w-12 items-center justify-center", children: [
8495
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.AnimatePresence, { initial: false, children: isActive && /* @__PURE__ */ jsxRuntime.jsx(
8496
+ react$1.motion.span,
8497
+ {
8498
+ layoutId: `${listId}-pill`,
8499
+ className: "absolute inset-0 rounded-2xl bg-primary/10",
8500
+ transition: spring.snappy
8501
+ }
8502
+ ) }),
8503
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative z-10 h-6 w-6", children: isActive ? activeIcon ?? icon : icon })
8504
+ ] }),
8505
+ /* @__PURE__ */ jsxRuntime.jsx(
8506
+ "span",
8507
+ {
8508
+ className: cn(
8509
+ "text-[10px] font-medium",
8510
+ isActive && "font-semibold"
8511
+ ),
8512
+ children: label
8513
+ }
8514
+ ),
8515
+ /* @__PURE__ */ jsxRuntime.jsx(
8516
+ "span",
8517
+ {
8518
+ className: cn(
8519
+ "h-1 w-5 rounded-full transition-colors",
8520
+ isActive ? "bg-primary" : "bg-transparent"
8521
+ )
8522
+ }
8523
+ )
8524
+ ]
8525
+ },
8526
+ value
8527
+ );
8528
+ }) })
8529
+ }
8530
+ );
8531
+ }
8532
+ var DrawerContext = react.createContext({ isOpen: false, modal: true });
8533
+ function Drawer({ children, open, onOpenChange, modal = true, ...props }) {
8369
8534
  const [internalOpen, setInternalOpen] = react.useState(props.defaultOpen ?? false);
8370
8535
  const isOpen = open !== void 0 ? open : internalOpen;
8371
- return /* @__PURE__ */ jsxRuntime.jsx(DrawerContext.Provider, { value: isOpen, children: /* @__PURE__ */ jsxRuntime.jsx(
8536
+ return /* @__PURE__ */ jsxRuntime.jsx(DrawerContext.Provider, { value: { isOpen, modal }, children: /* @__PURE__ */ jsxRuntime.jsx(
8372
8537
  radixUi.Dialog.Root,
8373
8538
  {
8374
8539
  "data-slot": "drawer",
8540
+ modal,
8375
8541
  ...props,
8376
8542
  open: isOpen,
8377
8543
  onOpenChange: (v) => {
@@ -8389,7 +8555,7 @@ function DrawerClose({ ...props }) {
8389
8555
  return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Dialog.Close, { "data-slot": "drawer-close", ...props });
8390
8556
  }
8391
8557
  function DrawerPortal({ children, ...props }) {
8392
- const isOpen = react.useContext(DrawerContext);
8558
+ const { isOpen } = react.useContext(DrawerContext);
8393
8559
  return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Dialog.Portal, { forceMount: true, ...props, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.AnimatePresence, { mode: "sync", children: isOpen && children }) });
8394
8560
  }
8395
8561
  function DrawerOverlay({ className, ...props }) {
@@ -8427,8 +8593,9 @@ function DrawerContent({
8427
8593
  const xInitial = side === "right" ? "100%" : side === "left" ? "-100%" : 0;
8428
8594
  const yInitial = side === "bottom" ? "100%" : side === "top" ? "-100%" : 0;
8429
8595
  const dragRef = react.useRef(null);
8596
+ const { modal } = react.useContext(DrawerContext);
8430
8597
  return /* @__PURE__ */ jsxRuntime.jsxs(DrawerPortal, { children: [
8431
- /* @__PURE__ */ jsxRuntime.jsx(DrawerOverlay, {}),
8598
+ modal && /* @__PURE__ */ jsxRuntime.jsx(DrawerOverlay, {}),
8432
8599
  /* @__PURE__ */ jsxRuntime.jsx(
8433
8600
  radixUi.Dialog.Content,
8434
8601
  {
@@ -8452,9 +8619,8 @@ function DrawerContent({
8452
8619
  {
8453
8620
  className: cn("flex flex-col", isHorizontal && "h-full"),
8454
8621
  initial: { x: xInitial, y: yInitial, opacity: 0 },
8455
- animate: { x: 0, y: 0, opacity: 1 },
8456
- exit: { x: xInitial, y: yInitial, opacity: 0 },
8457
- transition: transition.sidebar,
8622
+ animate: { x: 0, y: 0, opacity: 1, transition: transition.drawer },
8623
+ exit: { x: xInitial, y: yInitial, opacity: 0, transition: transition.drawerExit },
8458
8624
  children: [
8459
8625
  children,
8460
8626
  showCloseButton && /* @__PURE__ */ jsxRuntime.jsx(radixUi.Dialog.Close, { "data-slot": "drawer-close", asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
@@ -8635,6 +8801,10 @@ exports.AvatarGroup = AvatarGroup;
8635
8801
  exports.AvatarGroupCount = AvatarGroupCount;
8636
8802
  exports.AvatarImage = AvatarImage;
8637
8803
  exports.Badge = Badge2;
8804
+ exports.BottomNav = BottomNav;
8805
+ exports.BottomNavTabs = BottomNavTabs;
8806
+ exports.BottomNavTabsContent = BottomNavTabsContent;
8807
+ exports.BottomNavTabsList = BottomNavTabsList;
8638
8808
  exports.Breadcrumb = Breadcrumb;
8639
8809
  exports.BreadcrumbEllipsis = BreadcrumbEllipsis;
8640
8810
  exports.BreadcrumbItem = BreadcrumbItem;