@orangecheck/app-design 0.5.13 → 0.6.1

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
@@ -2470,7 +2470,7 @@ function SiteHeader({
2470
2470
  "header",
2471
2471
  {
2472
2472
  className: cn(
2473
- "sticky top-0 z-40 w-full border-b border-transparent bg-background/85 backdrop-blur-md supports-[backdrop-filter]:bg-background/70",
2473
+ "sticky top-0 z-40 w-full border-b border-transparent bg-background/95 backdrop-blur-md supports-[backdrop-filter]:bg-background/90",
2474
2474
  className
2475
2475
  ),
2476
2476
  children: /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2618,6 +2618,57 @@ function SectionSwitch({
2618
2618
  }
2619
2619
  );
2620
2620
  }
2621
+ function TabBar({ items }) {
2622
+ return /* @__PURE__ */ jsxRuntime.jsx(
2623
+ "nav",
2624
+ {
2625
+ "aria-label": "Pages",
2626
+ "data-oca-tabbar": "",
2627
+ className: "fixed inset-x-0 bottom-0 z-40 border-t border-border bg-background/90 pb-[env(safe-area-inset-bottom)] backdrop-blur-md md:hidden",
2628
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2629
+ "div",
2630
+ {
2631
+ className: "mx-auto grid h-14 max-w-[32rem] px-1.5",
2632
+ style: { gridTemplateColumns: `repeat(${items.length}, minmax(0, 1fr))` },
2633
+ children: items.map((it) => /* @__PURE__ */ jsxRuntime.jsxs(
2634
+ Link2__default.default,
2635
+ {
2636
+ href: it.href,
2637
+ "aria-current": it.active ? "page" : void 0,
2638
+ className: cn(
2639
+ "flex min-w-0 flex-col items-center justify-center gap-1 rounded-2xl text-[0.6875rem] leading-none outline-none transition-colors [-webkit-tap-highlight-color:transparent] focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring",
2640
+ it.active ? "text-foreground" : "text-muted-foreground hover:text-foreground"
2641
+ ),
2642
+ children: [
2643
+ /* @__PURE__ */ jsxRuntime.jsxs(
2644
+ "span",
2645
+ {
2646
+ className: cn(
2647
+ "relative flex h-7 w-12 items-center justify-center rounded-full transition-[background-color,box-shadow] duration-200",
2648
+ "[&_svg]:size-[1.125rem] [&_svg]:shrink-0",
2649
+ it.active ? "bg-card shadow-sm ring-1 ring-border [&_svg]:stroke-2" : "[&_svg]:stroke-[1.75]"
2650
+ ),
2651
+ children: [
2652
+ it.icon,
2653
+ it.badge ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "absolute right-2.5 top-0.5 size-2 rounded-full bg-oca-orange ring-2 ring-background" }) : null
2654
+ ]
2655
+ }
2656
+ ),
2657
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-w-full truncate px-0.5", children: it.label }),
2658
+ it.badge ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: it.badge }) : null
2659
+ ]
2660
+ },
2661
+ it.href
2662
+ ))
2663
+ }
2664
+ )
2665
+ }
2666
+ );
2667
+ }
2668
+ function tabsFor(groups) {
2669
+ const items = groups.flatMap((g) => g.items);
2670
+ return items.length >= 2 && items.length <= 5 && items.every((it) => it.icon) ? items : null;
2671
+ }
2621
2672
  var activeItem = (groups) => groups.flatMap((g) => g.items).find((it) => it.active);
2622
2673
  var warned = /* @__PURE__ */ new Set();
2623
2674
  function warnDuplicateLabels(groups) {
@@ -2648,6 +2699,7 @@ function AppShell({
2648
2699
  const current = sections && sections.length > 0 ? sections.find((sec) => sec.id === activeSection) ?? sections.find((sec) => activeItem(sec.groups)) ?? sections[0] : void 0;
2649
2700
  const groups = current ? [...current.groups, ...persistent] : [...nav ?? [], ...persistent];
2650
2701
  warnDuplicateLabels(groups);
2702
+ const tabs = current ? null : tabsFor(groups);
2651
2703
  const page = activeItem(groups);
2652
2704
  const place = react.useMemo(
2653
2705
  () => ({
@@ -2657,50 +2709,75 @@ function AppShell({
2657
2709
  [current, page?.label, pageOverride]
2658
2710
  );
2659
2711
  const switcher = sections && current && sections.length > 1 ? /* @__PURE__ */ jsxRuntime.jsx(SectionSwitch, { sections, current, onNavigate: () => setOpen(false) }) : null;
2660
- return /* @__PURE__ */ jsxRuntime.jsx(ShellContext.Provider, { value: place, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("min-h-dvh bg-background", className), children: [
2661
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sticky top-0 z-40 border-b border-border bg-background/90 backdrop-blur-md lg:hidden", children: [
2662
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-14 items-center gap-2 px-3", children: [
2663
- /* @__PURE__ */ jsxRuntime.jsxs(Sheet, { open, onOpenChange: setOpen, children: [
2664
- /* @__PURE__ */ jsxRuntime.jsx(
2665
- SheetTrigger,
2712
+ return /* @__PURE__ */ jsxRuntime.jsx(ShellContext.Provider, { value: place, children: /* @__PURE__ */ jsxRuntime.jsxs(
2713
+ "div",
2714
+ {
2715
+ className: cn(
2716
+ "min-h-dvh bg-background",
2717
+ tabs && "max-md:pb-[calc(3.5rem_+_env(safe-area-inset-bottom))]",
2718
+ className
2719
+ ),
2720
+ children: [
2721
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sticky top-0 z-40 border-b border-border bg-background/90 backdrop-blur-md lg:hidden", children: [
2722
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-14 items-center gap-2 px-3", children: [
2723
+ /* @__PURE__ */ jsxRuntime.jsxs(Sheet, { open, onOpenChange: setOpen, children: [
2724
+ /* @__PURE__ */ jsxRuntime.jsx(
2725
+ SheetTrigger,
2726
+ {
2727
+ className: cn(
2728
+ "inline-flex size-10 items-center justify-center rounded-full hover:bg-accent",
2729
+ // The tab bar holds every page; the sheet is left for a footer.
2730
+ tabs && !footer && "max-md:hidden"
2731
+ ),
2732
+ "aria-label": "Open navigation",
2733
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Menu, { className: "size-5" })
2734
+ }
2735
+ ),
2736
+ /* @__PURE__ */ jsxRuntime.jsxs(SheetContent, { side: "left", className: "flex flex-col gap-6 overflow-y-auto p-4 pt-16", children: [
2737
+ /* @__PURE__ */ jsxRuntime.jsx(SheetTitle, { className: "sr-only", children: "Navigation" }),
2738
+ switcher,
2739
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: tabs ? "max-md:hidden" : void 0, children: /* @__PURE__ */ jsxRuntime.jsx(SideNav, { groups, onNavigate: () => setOpen(false) }) }),
2740
+ footer ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto flex flex-col gap-3", children: footer }) : null
2741
+ ] })
2742
+ ] }),
2743
+ /* @__PURE__ */ jsxRuntime.jsx(Link2__default.default, { href: home, "aria-label": "Home", className: "rounded-lg p-1", children: /* @__PURE__ */ jsxRuntime.jsx(Lockup, { size: 22 }) }),
2744
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto flex items-center", children: account })
2745
+ ] }),
2746
+ place.page ? /* @__PURE__ */ jsxRuntime.jsxs(
2747
+ "div",
2666
2748
  {
2667
- className: "inline-flex size-10 items-center justify-center rounded-full hover:bg-accent",
2668
- "aria-label": "Open navigation",
2669
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Menu, { className: "size-5" })
2749
+ className: cn(
2750
+ "flex h-9 items-center gap-1.5 border-t border-border px-4 text-[0.875rem]",
2751
+ // The active tab already names the page.
2752
+ tabs && !pageOverride && "max-md:hidden"
2753
+ ),
2754
+ children: [
2755
+ place.section ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2756
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-muted-foreground", children: place.section }),
2757
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": true, className: "size-3.5 shrink-0 text-muted-foreground" })
2758
+ ] }) : null,
2759
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-medium", children: place.page })
2760
+ ]
2670
2761
  }
2671
- ),
2672
- /* @__PURE__ */ jsxRuntime.jsxs(SheetContent, { side: "left", className: "flex flex-col gap-6 overflow-y-auto p-4 pt-16", children: [
2673
- /* @__PURE__ */ jsxRuntime.jsx(SheetTitle, { className: "sr-only", children: "Navigation" }),
2762
+ ) : null
2763
+ ] }),
2764
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto flex w-full max-w-[90rem]", children: [
2765
+ /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "sticky top-0 hidden h-dvh w-[17rem] shrink-0 flex-col gap-6 overflow-y-auto px-4 py-6 lg:flex", children: [
2766
+ /* @__PURE__ */ jsxRuntime.jsx(Link2__default.default, { href: home, className: "px-2", "aria-label": "Home", children: /* @__PURE__ */ jsxRuntime.jsx(Lockup, { size: 26 }) }),
2674
2767
  switcher,
2675
- /* @__PURE__ */ jsxRuntime.jsx(SideNav, { groups, onNavigate: () => setOpen(false) }),
2676
- footer ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto flex flex-col gap-3", children: footer }) : null
2768
+ /* @__PURE__ */ jsxRuntime.jsx(SideNav, { groups }),
2769
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto flex flex-col gap-3", children: footer })
2770
+ ] }),
2771
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
2772
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden h-[4.5rem] items-center justify-end gap-3 px-8 lg:flex", children: account }),
2773
+ banner ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 pb-2 pt-4 md:px-8 lg:pt-0", children: banner }) : null,
2774
+ /* @__PURE__ */ jsxRuntime.jsx("main", { id: "main-content", className: "flex-1 px-4 pb-16 pt-6 md:px-8 lg:pt-2", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto w-full max-w-[72rem]", children }) })
2677
2775
  ] })
2678
2776
  ] }),
2679
- /* @__PURE__ */ jsxRuntime.jsx(Link2__default.default, { href: home, "aria-label": "Home", className: "rounded-lg p-1", children: /* @__PURE__ */ jsxRuntime.jsx(Lockup, { size: 22 }) }),
2680
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto flex items-center", children: account })
2681
- ] }),
2682
- place.page ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-9 items-center gap-1.5 border-t border-border px-4 text-[0.875rem]", children: [
2683
- place.section ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2684
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-muted-foreground", children: place.section }),
2685
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": true, className: "size-3.5 shrink-0 text-muted-foreground" })
2686
- ] }) : null,
2687
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-medium", children: place.page })
2688
- ] }) : null
2689
- ] }),
2690
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto flex w-full max-w-[90rem]", children: [
2691
- /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "sticky top-0 hidden h-dvh w-[17rem] shrink-0 flex-col gap-6 overflow-y-auto px-4 py-6 lg:flex", children: [
2692
- /* @__PURE__ */ jsxRuntime.jsx(Link2__default.default, { href: home, className: "px-2", "aria-label": "Home", children: /* @__PURE__ */ jsxRuntime.jsx(Lockup, { size: 26 }) }),
2693
- switcher,
2694
- /* @__PURE__ */ jsxRuntime.jsx(SideNav, { groups }),
2695
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto flex flex-col gap-3", children: footer })
2696
- ] }),
2697
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
2698
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden h-[4.5rem] items-center justify-end gap-3 px-8 lg:flex", children: account }),
2699
- banner ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 pb-2 pt-4 md:px-8 lg:pt-0", children: banner }) : null,
2700
- /* @__PURE__ */ jsxRuntime.jsx("main", { id: "main-content", className: "flex-1 px-4 pb-16 pt-6 md:px-8 lg:pt-2", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto w-full max-w-[72rem]", children }) })
2701
- ] })
2702
- ] })
2703
- ] }) });
2777
+ tabs ? /* @__PURE__ */ jsxRuntime.jsx(TabBar, { items: tabs }) : null
2778
+ ]
2779
+ }
2780
+ ) });
2704
2781
  }
2705
2782
  function AccountMenu({
2706
2783
  name,