UNPKG

@sikka/hawa

Version:

Modern UI Kit made with Tailwind

1,347 lines (1,334 loc) • 51.7 kB
"use client"; import { Sheet, SheetContent, SheetTrigger } from "../chunk-YHVUX2MP.mjs"; import { Button, Card, CardContent, CardTitle, Chip, DropdownMenu, Logos, MenuIcon, Skeleton, Tooltip, cn } from "../chunk-GGWTBYZF.mjs"; import { useBreakpoint, useClickOutside } from "../chunk-2LUXOXAL.mjs"; // layout/stats/Stats.tsx import React from "react"; var Stats = ({ label, icon, isLoading, number, helperText, helperTextColor = "default", chart, clickable, variant = "default", ...props }) => { let helperTextColorStyles = { default: "", positive: "hawa-text-green-600 dark:hawa-text-green-500", negative: "hawa-text-red-600 dark:hawa-text-red-500", muted: "hawa-text-muted-foreground" }; return /* @__PURE__ */ React.createElement(Card, { ...props, clickable }, /* @__PURE__ */ React.createElement("div", { className: "hawa-flex hawa-flex-row hawa-items-center hawa-justify-between hawa-p-4 hawa-px-6" }, /* @__PURE__ */ React.createElement(CardTitle, { className: "hawa-text-sm hawa-font-medium" }, label), icon && /* @__PURE__ */ React.createElement("span", null, icon)), /* @__PURE__ */ React.createElement(CardContent, { className: "hawa-transition-all" }, isLoading ? /* @__PURE__ */ React.createElement(Skeleton, { className: "hawa-h-8 hawa-w-3/4" }) : /* @__PURE__ */ React.createElement("div", { className: "hawa-text-2xl hawa-font-bold" }, number), helperText && /* @__PURE__ */ React.createElement( "div", { className: cn( "hawa-my-0 hawa-text-start hawa-text-xs hawa-transition-all", helperTextColorStyles[helperTextColor], helperText ? "hawa-h-4 hawa-opacity-100" : "hawa-h-0 hawa-opacity-0" ) }, isLoading ? /* @__PURE__ */ React.createElement(Skeleton, { className: "hawa-mt-2 hawa-h-4 hawa-w-1/2" }) : helperText ), chart && (isLoading ? /* @__PURE__ */ React.createElement(Skeleton, { className: "hawa-mt-2 hawa-h-4 hawa-w-1/2" }) : chart))); }; // layout/sidebar/Sidebar.tsx import * as React2 from "react"; import * as AccordionPrimitive from "@radix-ui/react-accordion"; var Accordion = AccordionPrimitive.Root; var triggerStyles = "hawa-flex hawa-flex-1 hawa-items-center hawa-duration-75 hawa-select-none hawa-cursor-pointer hawa-rounded hawa-justify-between hawa-p-2 hawa-px-3 hawa-font-medium hawa-transition-all [&[data-state=open]>svg]:hawa--rotate-90"; var AccordionItem = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React2.createElement(AccordionPrimitive.Item, { ref, className: cn(className), ...props })); AccordionItem.displayName = "AccordionItem"; var AccordionTrigger = React2.forwardRef(({ className, showArrow, children, ...props }, ref) => /* @__PURE__ */ React2.createElement(AccordionPrimitive.Header, { className: "flex" }, /* @__PURE__ */ React2.createElement( AccordionPrimitive.Trigger, { ref, className: cn(triggerStyles, className), ...props }, children, showArrow && /* @__PURE__ */ React2.createElement( "svg", { "aria-label": "Chevron Right Icon", stroke: "currentColor", fill: "currentColor", viewBox: "0 0 16 16", height: "1em", width: "1em", className: "hawa-icon hawa-shrink-0 hawa-rotate-90 hawa-transition-transform hawa-duration-200" }, /* @__PURE__ */ React2.createElement("path", { d: "M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z" }) ) ))); AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName; var AccordionContent = React2.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ React2.createElement( AccordionPrimitive.Content, { ref, className: cn( "hawa-overflow-hidden hawa-text-sm hawa-transition-all data-[state=closed]:hawa-animate-accordion-up data-[state=open]:hawa-animate-accordion-down", className ), ...props }, /* @__PURE__ */ React2.createElement("div", null, children) )); AccordionContent.displayName = AccordionPrimitive.Content.displayName; var SidebarGroup = ({ title, items, selectedItem, openedItem, setOpenedItem, onItemClick, onSubItemClick, direction, isOpen, ...props }) => { const LinkComponent = props.LinkComponent || "a"; return /* @__PURE__ */ React2.createElement("div", { className: "hawa-m-2" }, title && /* @__PURE__ */ React2.createElement("h3", { className: "hawa-mb-1 hawa-font-bold" }, title), /* @__PURE__ */ React2.createElement("ul", { className: "hawa-flex hawa-flex-col hawa-gap-2" }, /* @__PURE__ */ React2.createElement( Accordion, { value: openedItem, type: "single", onValueChange: (e) => { setOpenedItem(e); }, collapsible: true, className: "hawa-flex hawa-flex-col hawa-gap-1" }, items.map((item, idx) => /* @__PURE__ */ React2.createElement( SidebarItem, { isOpen, selectedItem, key: idx, direction, item, onItemClick, onSubItemClick, LinkComponent } )) ))); }; var SidebarItem = ({ item, onItemClick, onSubItemClick, direction, isOpen = true, LinkComponent, ...props }) => { const getSelectedStyle = (value) => { return props.selectedItem === value ? "hawa-bg-primary/90 hawa-text-primary-foreground hawa-cursor-default" : "hover:hawa-bg-primary/10"; }; if (item.subitems) { return /* @__PURE__ */ React2.createElement( AccordionItem, { value: item.value, className: "hawa-overflow-x-clip", dir: direction }, /* @__PURE__ */ React2.createElement( AccordionTrigger, { className: cn( "hawa-w-full hawa-overflow-x-clip", props.selectedItem === item.value ? "hawa-cursor-default hawa-bg-primary hawa-text-primary-foreground" : "hawa-h-10 hover:hawa-bg-primary/10", item.subitems && item.subitems.some( (subitem) => props.selectedItem === subitem.value ) ? "hawa-bg-primary/80 hawa-text-primary-foreground hover:hawa-bg-primary/80" : "" ), showArrow: isOpen }, /* @__PURE__ */ React2.createElement( "div", { className: cn( "hawa-flex hawa-h-fit hawa-w-fit hawa-flex-row hawa-items-center hawa-gap-2" ) }, item.icon && item.icon, /* @__PURE__ */ React2.createElement( "span", { className: cn( "hawa-transition-all hawa-flex hawa-flex-row hawa-items-center hawa-gap-2 hawa-whitespace-nowrap", isOpen ? "hawa-opacity-100" : "hawa-opacity-0" ) }, item.label, item.badge && /* @__PURE__ */ React2.createElement( Chip, { label: item.badge.label, color: item.badge.color, size: "small" } ) ) ) ), item.subitems && /* @__PURE__ */ React2.createElement(AccordionContent, { className: "hawa-mt-1 hawa-h-full hawa-rounded" }, /* @__PURE__ */ React2.createElement( "div", { className: cn( "hawa-flex hawa-h-full hawa-flex-col hawa-gap-2 hawa-bg-foreground/5 hawa-p-1" ) }, item.subitems.map((subitem, idx) => /* @__PURE__ */ React2.createElement( LinkComponent, { href: subitem.slug, key: idx, onMouseDown: (e) => { if (subitem.onMouseDown) { subitem.onMouseDown(e); } }, onClick: (e) => { e.stopPropagation(); if (subitem.onClick) { subitem.onClick(e); } if (onSubItemClick) { onSubItemClick([item.value, subitem.value]); } }, className: cn( "hawa-flex hawa-h-full hawa-cursor-pointer hawa-flex-row hawa-items-center hawa-gap-2 hawa-overflow-x-clip hawa-whitespace-nowrap hawa-rounded hawa-p-2 hawa-transition-all", // bg-foreground/10 getSelectedStyle(subitem.value) ) }, subitem.icon && subitem.icon, subitem.label, subitem.badge && /* @__PURE__ */ React2.createElement( Chip, { label: subitem.badge.label, color: subitem.badge.color, size: "small" } ) )) )) ); } else { return /* @__PURE__ */ React2.createElement( LinkComponent, { href: item.slug, dir: direction, onMouseDown: (e) => { if (item.onMouseDown) { item.onMouseDown(e); } }, onClick: (e) => { if (item.onClick) { item.onClick(e); } if (onItemClick) { onItemClick([item.value]); } }, className: cn( triggerStyles, getSelectedStyle(item.value), "hawa-overflow-x-clip" ) }, /* @__PURE__ */ React2.createElement("div", { className: "hawa-flex hawa-flex-row hawa-items-center hawa-gap-2" }, item.icon && item.icon, /* @__PURE__ */ React2.createElement( "span", { className: cn( "hawa-flex hawa-flex-row hawa-items-center hawa-gap-2 hawa-whitespace-nowrap hawa-transition-all", isOpen ? "hawa-opacity-100" : "hawa-opacity-0" ) }, item.label, " ", item.badge && /* @__PURE__ */ React2.createElement( Chip, { label: item.badge.label, color: item.badge.color, size: "small" } ) )) ); } }; // layout/copyrights/Copyrights.tsx import React3 from "react"; var Copyrights = (props) => { return /* @__PURE__ */ React3.createElement("div", { className: "hawa-my-2 hawa-flex hawa-flex-col hawa-items-center hawa-justify-center hawa-gap-1 hawa-text-xs hawa-text-gray-400" }, props.withLogo ? /* @__PURE__ */ React3.createElement("a", { href: props.onLogoClicked }, /* @__PURE__ */ React3.createElement("div", { className: "hawa-cursor-pointer" }, /* @__PURE__ */ React3.createElement("image", { href: props.logoURL, width: 100, height: 50 }))) : null, /* @__PURE__ */ React3.createElement("div", null, props.version), props.credits ? props.credits : null); }; // layout/navbar/Navbar.tsx import React4, { useState } from "react"; // elements/collapsible/Collapsible.tsx import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"; var Collapsible = CollapsiblePrimitive.Root; var CollapsibleTrigger2 = CollapsiblePrimitive.CollapsibleTrigger; var CollapsibleContent2 = CollapsiblePrimitive.CollapsibleContent; // layout/navbar/Navbar.tsx var Navbar = ({ backgroundColor, logo, handleLogoClick, ...props }) => { var _a, _b; const [isOpen, setIsOpen] = useState(false); return /* @__PURE__ */ React4.createElement("nav", { className: "hawa-sticky hawa-top-2 hawa-transition-all" }, /* @__PURE__ */ React4.createElement( Collapsible, { className: "hawa-relative hawa-m-2 hawa-rounded hawa-p-2", style: { backgroundColor: backgroundColor || "#1f2937" } }, /* @__PURE__ */ React4.createElement("div", { className: "hawa-flex hawa-items-center hawa-justify-between hawa-px-3" }, /* @__PURE__ */ React4.createElement("div", { className: "hawa-flex hawa-items-center" }, /* @__PURE__ */ React4.createElement( "div", { className: "hawa-p-1.5 hawa-text-xl hawa-font-bold hawa-text-white", onClick: () => { if (handleLogoClick) { handleLogoClick(); } } }, logo )), /* @__PURE__ */ React4.createElement("div", { className: "hawa-hidden md:hawa-flex" }, (_a = props.menuItems) == null ? void 0 : _a.map((item, i) => /* @__PURE__ */ React4.createElement( "div", { key: i, onClick: item.action, className: "hawa-cursor-pointer hawa-rounded hawa-p-1.5 hawa-px-2 hawa-text-center hawa-text-sm hawa-text-white hawa-transition-all hover:hawa-bg-gray-300 hover:hawa-text-black" }, item.label ))), /* @__PURE__ */ React4.createElement("div", { className: "hawa-m-0 hawa-flex hawa-h-fit hawa-p-0 md:hawa-hidden" }, /* @__PURE__ */ React4.createElement( CollapsibleTrigger2, { onClick: () => setIsOpen(!isOpen), className: "hawa-h-full hawa-text-white selection:hawa-p-0", "aria-label": "Toggle menu" }, /* @__PURE__ */ React4.createElement( "svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: cn( "hawa-fixed hawa-h-6 hawa-w-6", isOpen ? "hawa-invisible" : "hawa-visible" ) }, /* @__PURE__ */ React4.createElement("line", { x1: "4", x2: "20", y1: "12", y2: "12" }), /* @__PURE__ */ React4.createElement("line", { x1: "4", x2: "20", y1: "6", y2: "6" }), /* @__PURE__ */ React4.createElement("line", { x1: "4", x2: "20", y1: "18", y2: "18" }) ), /* @__PURE__ */ React4.createElement( "svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: cn( "hawa-h-6 hawa-w-6", !isOpen ? "hawa-invisible" : "hawa-visible" ) }, /* @__PURE__ */ React4.createElement("path", { d: "M18 6 6 18" }), /* @__PURE__ */ React4.createElement("path", { d: "m6 6 12 12" }) ) ))), /* @__PURE__ */ React4.createElement( CollapsibleContent2, { className: cn( "data-[state=closed]:hawa-opacity-0", "data-[state=open]:hawa-animate-in", "data-[state=open]:hawa-fade-in-90", "hawa-absolute hawa-left-0 hawa-top-[60px] hawa-flex hawa-flex-col hawa-rounded hawa-border hawa-bg-gray-200 hawa-p-1 hawa-transition-all" // "hawa-transition-all hawa-bg-gray-400 hawa-fixed hawa-left-0 hawa-top-[72px] hawa-w-full hawa-flex hawa-flex-col" ), style: { width: "calc(100%)", zIndex: -100 } }, (_b = props.menuItems) == null ? void 0 : _b.map((item, i) => /* @__PURE__ */ React4.createElement( "div", { key: i, onClick: item.action, className: "hawa-cursor-pointer hawa-rounded hawa-p-2 hawa-px-10 hawa-text-center hawa-text-black hawa-transition-all hover:hawa-bg-gray-300" }, item.label )) ) )); }; // layout/appLayout/AppLayout.tsx import React5, { useEffect, useState as useState2 } from "react"; import * as Dialog from "@radix-ui/react-dialog"; var LOCAL_STORAGE_KEY = "@sikka/hawa/keep-drawer-open"; var AppLayout = ({ profileMenuWidth = "default", DrawerFooterActions, classNames, bordered = true, design = "default", direction = "ltr", drawerSize = "md", currentPage, clickedItem, DrawerLinkComponent, MenuLinkComponent, onDrawerExpanded, onAvatarClick, ...props }) => { var _a, _b; useEffect(() => { let isDrawerOpen = localStorage.getItem(LOCAL_STORAGE_KEY); if (isDrawerOpen === null) { localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(false)); } }, []); let closeDrawerWidth = 56; let openDrawerWidth = 200; let drawerSizeStyle = { opened: { sm: "100", md: openDrawerWidth, lg: "250" }, closed: { sm: closeDrawerWidth, md: closeDrawerWidth, lg: closeDrawerWidth } }; const isRTL = direction === "rtl"; const [openedSidebarItem, setOpenedSidebarItem] = useState2(""); const [size, setSize] = useState2( typeof window !== "undefined" && window.innerWidth || 1200 ); const [openSideMenu, setOpenSideMenu] = useState2(() => { const savedState = localStorage.getItem(LOCAL_STORAGE_KEY); return savedState ? JSON.parse(savedState) : false; }); const [container, setContainer] = React5.useState(null); const [keepDrawerOpen, setKeepDrawerOpen] = useState2(() => { const savedState = localStorage.getItem(LOCAL_STORAGE_KEY); return savedState ? JSON.parse(savedState) : false; }); const handleClickOutside = () => { if (typeof window !== "undefined") { if (window.innerWidth < 600) { setKeepDrawerOpen(false); setOpenSideMenu(false); onDrawerExpanded && onDrawerExpanded(false); } } }; const ref = useClickOutside(handleClickOutside); useEffect(() => { if (typeof window !== "undefined") { const resize = () => { setSize(window.innerWidth); if (window.innerWidth > 600) { setKeepDrawerOpen(false); } else { localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(false)); } onDrawerExpanded && onDrawerExpanded(keepDrawerOpen); }; resize(); window.addEventListener("resize", resize); return () => { window.removeEventListener("resize", resize); }; } }, []); useEffect(() => { setKeepDrawerOpen(() => { const savedState = localStorage.getItem(LOCAL_STORAGE_KEY); return savedState ? JSON.parse(savedState) : true; }); }, [setKeepDrawerOpen]); useEffect(() => { if (size > 600) { setOpenSideMenu(keepDrawerOpen); onDrawerExpanded && onDrawerExpanded(keepDrawerOpen); } else { setKeepDrawerOpen(false); setOpenSideMenu(false); onDrawerExpanded && onDrawerExpanded(false); } }, [size, keepDrawerOpen]); const drawerSizeCondition = size > 600 ? drawerSizeStyle[keepDrawerOpen ? "opened" : "closed"][drawerSize] : 0; return /* @__PURE__ */ React5.createElement("div", { className: "hawa-fixed hawa-start-0" }, props.topBar && /* @__PURE__ */ React5.createElement( "div", { dir: direction, className: cn( "hawa-fixed hawa-end-0 hawa-start-0 hawa-top-0 hawa-z-10 hawa-flex hawa-h-14 hawa-w-full hawa-items-center hawa-justify-between hawa-bg-primary-foreground hawa-p-2", bordered && "hawa-border-b-[1px]" ) }, size > 600 ? /* @__PURE__ */ React5.createElement( "div", { className: cn( "dark:hawa-text-white", size > 600 ? "hawa-ms-14" : "hawa-ms-2" ), style: { marginInlineStart: `${drawerSizeStyle[keepDrawerOpen ? "opened" : "closed"][drawerSize] + 10}px` } }, props.pageTitle ) : ( // Mobile Drawer Menu Button /* @__PURE__ */ React5.createElement( "div", { dir: direction, className: "hawa-flex hawa-items-center hawa-justify-center hawa-gap-0.5" }, /* @__PURE__ */ React5.createElement( "div", { onClick: () => setOpenSideMenu(true), className: "hawa-z-40 hawa-mx-1 hawa-cursor-pointer hawa-rounded hawa-p-2 hawa-transition-all" }, /* @__PURE__ */ React5.createElement(MenuIcon, null) ), props.pageTitle ? /* @__PURE__ */ React5.createElement("div", { className: "hawa-text-sm" }, props.pageTitle) : /* @__PURE__ */ React5.createElement("div", null) ) ), /* @__PURE__ */ React5.createElement("div", { className: cn("hawa-flex hawa-gap-2 dark:hawa-text-white") }, size > 600 ? /* @__PURE__ */ React5.createElement("div", { className: "hawa-text-end hawa-text-xs" }, /* @__PURE__ */ React5.createElement("div", { className: "hawa-font-bold" }, props.username), " ", /* @__PURE__ */ React5.createElement("div", null, props.email)) : null, /* @__PURE__ */ React5.createElement( DropdownMenu, { LinkComponent: MenuLinkComponent, triggerClassname: "hawa-mx-2", align: "end", side: "bottom", sideOffset: 10, width: profileMenuWidth, direction, items: props.profileMenuItems || [], onItemSelect: (e) => console.log("selecting item ", e), trigger: /* @__PURE__ */ React5.createElement( "div", { onClick: onAvatarClick, className: "hawa-relative hawa-h-8 hawa-w-8 hawa-cursor-pointer hawa-overflow-clip hawa-rounded hawa-ring-1 hawa-ring-primary/30 dark:hawa-bg-gray-600" }, props.avatarImage ? /* @__PURE__ */ React5.createElement("img", { src: props.avatarImage, alt: "User Avatar" }) : /* @__PURE__ */ React5.createElement( "svg", { "aria-label": "Avatar Icon", className: "hawa-absolute hawa--start-1 hawa-h-10 hawa-w-10 hawa-text-gray-400", fill: "currentColor", viewBox: "0 0 20 20" }, /* @__PURE__ */ React5.createElement( "path", { fillRule: "evenodd", d: "M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z", clipRule: "evenodd" } ) ) ) } )) ), /* @__PURE__ */ React5.createElement("div", { ref: setContainer }, /* @__PURE__ */ React5.createElement( "div", { className: cn( "hawa-fixed hawa-z-40 hawa-flex hawa-flex-col hawa-justify-between hawa-overflow-x-clip hawa-transition-all hawa-top-0 hawa-h-[calc(100dvh)] hawa-bg-primary-foreground", isRTL ? "hawa-right-0" : "hawa-left-0", bordered ? size > 600 ? direction === "rtl" ? "hawa-border-s-[1px]" : "hawa-border-e-[1px]" : "" : "" ), style: { width: size > 600 ? openSideMenu ? `${drawerSizeStyle["opened"][drawerSize]}px` : `${drawerSizeStyle["closed"][drawerSize]}px` : openSideMenu ? `${drawerSizeStyle["opened"][drawerSize]}px` : "0px" }, onMouseEnter: () => { setOpenSideMenu(true); onDrawerExpanded && onDrawerExpanded(true); }, onMouseLeave: () => { if (size > 600) { if (keepDrawerOpen) { setOpenSideMenu(true); onDrawerExpanded && onDrawerExpanded(true); } else { setOpenedSidebarItem(""); setOpenSideMenu(false); onDrawerExpanded && onDrawerExpanded(false); } } else { setOpenSideMenu(false); onDrawerExpanded && onDrawerExpanded(false); } }, ref }, /* @__PURE__ */ React5.createElement( "div", { onClick: props.onLogoClick, dir: direction, className: cn( "hawa-fixed hawa-z-50 hawa-mb-2 hawa-flex hawa-h-14 hawa-w-full hawa-flex-row hawa-items-center hawa-justify-center hawa-transition-all", props.onLogoClick && "hawa-cursor-pointer", classNames == null ? void 0 : classNames.logoContainer ), style: { width: size > 600 ? `${openSideMenu ? openDrawerWidth : 56}px` : `${openSideMenu ? openDrawerWidth : 0}px` } }, openSideMenu && props.header && props.header, !props.header && /* @__PURE__ */ React5.createElement( "img", { src: props.logoLink, className: cn( "hawa-h-9 hawa-opacity-0 hawa-transition-all", !openSideMenu ? "hawa-invisible hawa-opacity-0" : "hawa-visible hawa-opacity-100", classNames == null ? void 0 : classNames.fullLogoImg ) } ), size > 600 ? /* @__PURE__ */ React5.createElement( "img", { src: props.logoSymbol, className: cn( "hawa-fixed hawa-h-9 hawa-transition-all hawa-start-2.5 hawa-top-2.5", openSideMenu ? "hawa-invisible hawa-opacity-0" : "hawa-visible hawa-opacity-100", classNames == null ? void 0 : classNames.symbolLogoImg ) } ) : null ), /* @__PURE__ */ React5.createElement( "div", { className: cn( "hawa-fixed hawa-bottom-14 hawa-top-14 hawa-p-0 hawa-py-2 hawa-transition-all", openSideMenu ? "hawa-overflow-auto" : "hawa-overflow-hidden" ), style: { width: size > 600 ? `${openSideMenu ? openDrawerWidth : drawerSizeCondition}px` : `${openSideMenu ? openDrawerWidth : 0}px` } }, /* @__PURE__ */ React5.createElement( SidebarGroup, { direction, selectedItem: currentPage, openedItem: openedSidebarItem, setOpenedItem: (e) => setOpenedSidebarItem(e), isOpen: keepDrawerOpen || openSideMenu, items: props.drawerItems, LinkComponent: DrawerLinkComponent, onItemClick: (values) => clickedItem && clickedItem(values), onSubItemClick: (values) => clickedItem && clickedItem(values) } ) ), /* @__PURE__ */ React5.createElement( "div", { className: cn( "hawa-fixed hawa-bottom-0 hawa-flex hawa-h-14 hawa-items-center hawa-justify-center hawa-gap-2 hawa-overflow-clip hawa-transition-all", direction === "rtl" ? "hawa-flex-row-reverse" : "hawa-flex-row" ), style: { width: size > 600 ? `${openSideMenu ? openDrawerWidth : 56}px` : `${openSideMenu ? openDrawerWidth : 0}px` } }, DrawerFooterActions && openSideMenu ? /* @__PURE__ */ React5.createElement(React5.Fragment, null, DrawerFooterActions) : null, size > 600 && openSideMenu ? /* @__PURE__ */ React5.createElement( Tooltip, { side: "left", delayDuration: 500, triggerProps: { asChild: true }, content: keepDrawerOpen ? ((_a = props.texts) == null ? void 0 : _a.collapseSidebar) || "Collapse Sidebar" : ((_b = props.texts) == null ? void 0 : _b.expandSidebar) || "Expand Sidebar" }, /* @__PURE__ */ React5.createElement( Button, { variant: "outline", size: "smallIcon", onClick: () => { const newKeepOpenState = !keepDrawerOpen; localStorage.setItem( LOCAL_STORAGE_KEY, JSON.stringify(newKeepOpenState) ); setKeepDrawerOpen(newKeepOpenState); } }, /* @__PURE__ */ React5.createElement( "svg", { className: cn( "hawa-h-6 hawa-w-6 hawa-shrink-0 hawa-text-primary hawa-transition-all disabled:hawa-bg-gray-200", keepDrawerOpen ? isRTL ? "hawa--rotate-90" : "hawa-rotate-90" : isRTL ? "hawa-rotate-90" : "hawa--rotate-90" ), fill: "currentColor", viewBox: "0 0 20 20" }, /* @__PURE__ */ React5.createElement( "path", { fillRule: "evenodd", d: "M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z", clipRule: "evenodd" } ) ) ) ) : null ) )), /* @__PURE__ */ React5.createElement( Dialog.Root, { open: size < 600 && openSideMenu, onOpenChange: setOpenSideMenu }, /* @__PURE__ */ React5.createElement(Dialog.Portal, { container }, /* @__PURE__ */ React5.createElement(Dialog.Overlay, { className: "hawa-fixed hawa-inset-0 hawa-bg-foreground/20 hawa-backdrop-blur-[2px] data-[state=open]:hawa-animate-in data-[state=closed]:hawa-animate-out hawa-z-10 data-[state=closed]:hawa-fade-out-0 data-[state=open]:hawa-fade-in-0" })) ), /* @__PURE__ */ React5.createElement( "div", { className: "hawa-fixed hawa-overflow-y-auto hawa-transition-all hawa-z-0", style: isRTL ? { left: "0px", top: props.topBar ? "56px" : "0px", width: `calc(100% - ${drawerSizeCondition}px)`, height: `calc(100% - ${props.topBar ? "56" : "0"}px)` } : { left: `${drawerSizeCondition}px`, top: props.topBar ? "56px" : "0px", width: `calc(100% - ${drawerSizeCondition}px)`, height: `calc(100% - ${props.topBar ? "56" : "0"}px)` } }, props.children )); }; // layout/appTopbar/AppTopbar.tsx import React6 from "react"; var AppTopbar = ({ ...props }) => { const isRTL = props.direction === "ltr"; const size = 1200; return /* @__PURE__ */ React6.createElement( "div", { className: cn( "hawa-fixed hawa-left-0 hawa-right-0 hawa-top-0 hawa-z-30 hawa-flex hawa-h-14 hawa-w-full hawa-items-center hawa-justify-between hawa-border-b hawa-bg-primary-foreground hawa-p-2", isRTL ? "hawa-flex-row-reverse" : "hawa-flex-row" ) }, size > 600 ? /* @__PURE__ */ React6.createElement( "div", null, "page title" ) : ( // Mobile Drawer Menu Button /* @__PURE__ */ React6.createElement( "div", { dir: props.direction, className: "hawa-flex hawa-items-center hawa-justify-center hawa-gap-0.5" }, /* @__PURE__ */ React6.createElement( "div", { className: "hawa-z-40 hawa-mx-1 hawa-cursor-pointer hawa-rounded hawa-p-2 hawa-transition-all hover:hawa-bg-gray-100" }, /* @__PURE__ */ React6.createElement( "svg", { stroke: "currentColor", fill: "currentColor", strokeWidth: 0, viewBox: "0 0 20 20", "aria-hidden": "true", height: "1.6em", width: "1.6em" }, /* @__PURE__ */ React6.createElement( "path", { fillRule: "evenodd", clipRule: "evenodd", d: "M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" } ) ) ), "Mobile title" ) ), /* @__PURE__ */ React6.createElement( "div", { className: cn( "hawa-flex hawa-gap-2 dark:hawa-text-white", isRTL ? "hawa-flex-row-reverse" : "hawa-flex-row" ) }, size > 600 ? /* @__PURE__ */ React6.createElement( "div", { className: isRTL ? "hawa-text-left hawa-text-xs" : "hawa-text-right hawa-text-xs" }, /* @__PURE__ */ React6.createElement("div", { className: "hawa-font-bold" }, props.username), " ", /* @__PURE__ */ React6.createElement("div", null, props.email) ) : null, /* @__PURE__ */ React6.createElement( DropdownMenu, { triggerClassname: "hawa-mx-2", align: "end", alignOffset: 8, side: "bottom", sideOffset: 5, direction: isRTL ? "rtl" : "ltr", items: props.profileMenuItems || [], onItemSelect: (e) => console.log("selecting item ", e), trigger: /* @__PURE__ */ React6.createElement("div", { className: "hawa-relative hawa-h-8 hawa-w-8 hawa-cursor-pointer hawa-overflow-clip hawa-rounded hawa-ring-1 hawa-ring-primary/30 dark:hawa-bg-gray-600" }, props.avatarImage ? /* @__PURE__ */ React6.createElement("img", { src: props.avatarImage, alt: "User Avatar" }) : /* @__PURE__ */ React6.createElement( "svg", { "aria-label": "Avatar Icon", className: "hawa-absolute hawa--left-1 hawa-h-10 hawa-w-10 hawa-text-gray-400", fill: "currentColor", viewBox: "0 0 20 20" }, /* @__PURE__ */ React6.createElement( "path", { fillRule: "evenodd", d: "M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z", clipRule: "evenodd" } ) )) } ) ) ); }; // layout/appMenubar/AppMenubar.tsx import * as React7 from "react"; import * as MenubarPrimitive from "@radix-ui/react-menubar"; var MenubarMenu = MenubarPrimitive.Menu; var MenubarGroup = MenubarPrimitive.Group; var MenubarPortal = MenubarPrimitive.Portal; var MenubarSub = MenubarPrimitive.Sub; var MenubarRadioGroup = MenubarPrimitive.RadioGroup; var Menubar = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React7.createElement( MenubarPrimitive.Root, { ref, className: cn( "hawa-flex hawa-h-10 hawa-items-center hawa-space-x-1 hawa-rounded-md hawa-border hawa-bg-background hawa-p-1", className ), ...props } )); Menubar.displayName = MenubarPrimitive.Root.displayName; var MenubarTrigger = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React7.createElement( MenubarPrimitive.Trigger, { ref, className: cn( "hawa-flex hawa-cursor-default hawa-select-none hawa-items-center hawa-rounded-sm hawa-px-3 hawa-py-1.5 hawa-text-sm hawa-font-medium hawa-outline-none focus:hawa-bg-accent focus:hawa-text-accent-foreground data-[state=open]:hawa-bg-accent data-[state=open]:hawa-text-accent-foreground", className ), ...props } )); MenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName; var MenubarSubTrigger = React7.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ React7.createElement( MenubarPrimitive.SubTrigger, { ref, className: cn( "hawa-flex hawa-cursor-default hawa-select-none hawa-items-center hawa-rounded-sm hawa-px-2 hawa-py-1.5 hawa-text-sm hawa-outline-none focus:hawa-bg-accent focus:hawa-text-accent-foreground data-[state=open]:hawa-bg-accent data-[state=open]:hawa-text-accent-foreground", inset && "pl-8", className ), ...props }, children, /* @__PURE__ */ React7.createElement( "svg", { "aria-label": "Chevron Right Icon", xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "hawa-icon hawa-ml-auto" }, /* @__PURE__ */ React7.createElement("path", { d: "m9 18 6-6-6-6" }) ) )); MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName; var MenubarSubContent = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React7.createElement( MenubarPrimitive.SubContent, { ref, className: cn( "hawa-z-50 hawa-min-w-[8rem] hawa-overflow-hidden hawa-rounded-md hawa-border hawa-bg-popover hawa-p-1 hawa-text-popover-foreground data-[state=open]:hawa-animate-in data-[state=closed]:hawa-animate-out data-[state=closed]:hawa-fade-out-0 data-[state=open]:hawa-fade-in-0 data-[state=closed]:hawa-zoom-out-95 data-[state=open]:hawa-zoom-in-95 data-[side=bottom]:hawa-slide-in-from-top-2 data-[side=left]:hawa-slide-in-from-right-2 data-[side=right]:hawa-slide-in-from-left-2 data-[side=top]:hawa-slide-in-from-bottom-2", className ), ...props } )); MenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName; var MenubarContent = React7.forwardRef( ({ className, align = "start", alignOffset = -4, sideOffset = 8, ...props }, ref) => /* @__PURE__ */ React7.createElement(MenubarPrimitive.Portal, null, /* @__PURE__ */ React7.createElement( MenubarPrimitive.Content, { ref, align, alignOffset, sideOffset, className: cn( "hawa-z-50 hawa-min-w-[12rem] hawa-overflow-hidden hawa-rounded-md hawa-border hawa-bg-popover hawa-p-1 hawa-text-popover-foreground hawa-shadow-md data-[state=open]:hawa-animate-in data-[state=closed]:hawa-fade-out-0 data-[state=open]:hawa-fade-in-0 data-[state=closed]:hawa-zoom-out-95 data-[state=open]:hawa-zoom-in-95 data-[side=bottom]:hawa-slide-in-from-top-2 data-[side=left]:hawa-slide-in-from-right-2 data-[side=right]:hawa-slide-in-from-left-2 data-[side=top]:hawa-slide-in-from-bottom-2", className ), ...props } )) ); MenubarContent.displayName = MenubarPrimitive.Content.displayName; var MenubarItem = React7.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ React7.createElement( MenubarPrimitive.Item, { ref, className: cn( "hawa-relative hawa-flex hawa-cursor-default hawa-select-none hawa-items-center hawa-rounded-sm hawa-px-2 hawa-py-1.5 hawa-text-sm hawa-outline-none focus:hawa-bg-accent focus:hawa-text-accent-foreground data-[disabled]:hawa-pointer-events-none data-[disabled]:hawa-opacity-50", inset && "pl-8", className ), ...props } )); MenubarItem.displayName = MenubarPrimitive.Item.displayName; var MenubarCheckboxItem = React7.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ React7.createElement( MenubarPrimitive.CheckboxItem, { ref, className: cn( "hawa-relative hawa-flex hawa-cursor-default hawa-select-none hawa-items-center hawa-rounded-sm hawa-py-1.5 hawa-pl-8 hawa-pr-2 hawa-text-sm hawa-outline-none focus:hawa-bg-accent focus:hawa-text-accent-foreground data-[disabled]:hawa-pointer-events-none data-[disabled]:hawa-opacity-50", className ), checked, ...props }, /* @__PURE__ */ React7.createElement("span", { className: "hawa-absolute hawa-left-2 hawa-flex hawa-h-3.5 hawa-w-3.5 hawa-items-center hawa-justify-center" }, /* @__PURE__ */ React7.createElement(MenubarPrimitive.ItemIndicator, null, /* @__PURE__ */ React7.createElement( "svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "hawa-icon" }, /* @__PURE__ */ React7.createElement("path", { d: "M20 6 9 17l-5-5" }) ))), children )); MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName; var MenubarRadioItem = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ React7.createElement( MenubarPrimitive.RadioItem, { ref, className: cn( "hawa-relative hawa-flex hawa-cursor-default hawa-select-none hawa-items-center hawa-rounded-sm hawa-py-1.5 hawa-pl-8 hawa-pr-2 hawa-text-sm hawa-outline-none focus:hawa-bg-accent focus:hawa-text-accent-foreground data-[disabled]:hawa-pointer-events-none data-[disabled]:hawa-opacity-50", className ), ...props }, /* @__PURE__ */ React7.createElement("span", { className: "hawa-absolute hawa-left-2 hawa-flex hawa-h-3.5 hawa-w-3.5 hawa-items-center hawa-justify-center" }, /* @__PURE__ */ React7.createElement(MenubarPrimitive.ItemIndicator, null, /* @__PURE__ */ React7.createElement( "svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "hawa-h-2 hawa-w-2 hawa-fill-current" }, /* @__PURE__ */ React7.createElement("circle", { cx: "12", cy: "12", r: "10" }) ))), children )); MenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName; var MenubarLabel = React7.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ React7.createElement( MenubarPrimitive.Label, { ref, className: cn( "hawa-px-2 hawa-py-1.5 hawa-text-sm hawa-font-semibold", inset && "hawa-pl-8", className ), ...props } )); MenubarLabel.displayName = MenubarPrimitive.Label.displayName; var MenubarSeparator = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React7.createElement( MenubarPrimitive.Separator, { ref, className: cn("hawa--mx-1 hawa-my-1 hawa-h-px hawa-bg-muted", className), ...props } )); MenubarSeparator.displayName = MenubarPrimitive.Separator.displayName; var MenubarShortcut = ({ className, ...props }) => { return /* @__PURE__ */ React7.createElement( "span", { className: cn( "hawa-ml-auto hawa-text-xs hawa-tracking-widest hawa-text-muted-foreground", className ), ...props } ); }; MenubarShortcut.displayname = "MenubarShortcut"; // layout/appTabs/AppTabs.tsx import React8, { useState as useState3 } from "react"; var AppTabs = ({ tabs, className }) => { const [selectedIndex, setSelectedIndex] = useState3(0); return /* @__PURE__ */ React8.createElement( "div", { className: cn( "hawa-w-full hawa-border-b hawa-bg-card hawa-p-6 hawa-pb-0", className ) }, /* @__PURE__ */ React8.createElement("div", { className: "hawa-flex hawa-flex-row hawa-justify-center" }, tabs.map((tab, index) => { const selected = index === selectedIndex; return /* @__PURE__ */ React8.createElement( "a", { href: tab.path, key: index, onMouseDown: (e) => { if (tab.onMouseDown) { tab.onMouseDown(e); } }, onClick: (e) => { if (tab.onClick) { tab.onClick(e); } setSelectedIndex(index); }, className: cn( "hawa-z-10 hawa-flex hawa-items-center hawa-translate-y-[1.1px] hawa-select-none hawa-flex-row hawa-gap-2 hawa-rounded-t hawa-p-4 hawa-py-2 hawa-text-sm hawa-transition-all", "hawa-border", // Always have a border but make it transparent selected ? "hawa-border hawa-border-b-transparent hawa-bg-background" : "hawa-cursor-pointer hawa-border-transparent hover:hawa-bg-card-foreground/5" ) }, tab.icon && tab.icon, tab.label ); })) ); }; // layout/docsLayout/DocsLayout.tsx import React10, { useEffect as useEffect2, useRef as useRef2, useState as useState4 } from "react"; // layout/docsSidebar/DocsSidebar.tsx import React9 from "react"; var DocsSidebar = ({ currentPage: propCurrentPage, pages, direction }) => { const [activePage, setActivePage] = React9.useState(pages[0]); const handlePageClick = (page, event) => { event.preventDefault(); setTimeout(() => { setActivePage(page); }, 50); const element = document.getElementById(page); element == null ? void 0 : element.scrollIntoView({ behavior: "smooth", block: "start" }); }; const getCurrentSection = () => { for (let i = pages.length - 1; i >= 0; i--) { const page = pages[i]; const element = document.getElementById(page); const rect = element == null ? void 0 : element.getBoundingClientRect(); if (rect) { if (rect.top < window.innerHeight && rect.bottom >= 0) { return page; } } } return pages[0]; }; React9.useEffect(() => { const handleScroll = () => { setActivePage(getCurrentSection()); }; window.addEventListener("scroll", handleScroll); return () => { window.removeEventListener("scroll", handleScroll); }; }, []); let selectedStyles = { rtl: "hawa-border-r-4 hawa-border-primary hawa-border-collapse hawa-bg-gray-200", ltr: "hawa-border-l-4 hawa-border-primary hawa-border-collapse hawa-bg-gray-200" }; return /* @__PURE__ */ React9.createElement( "div", { className: "hawa-flex hawa-flex-col hawa-overflow-x-clip", dir: direction }, pages.map((page, index) => /* @__PURE__ */ React9.createElement( "div", { key: index, className: cn( "hawa-cursor-pointer hawa-whitespace-nowrap hawa-px-3 hawa-py-1 hawa-text-xs hawa-transition-all hover:hawa-bg-gray-100", (propCurrentPage || activePage) === page ? selectedStyles[direction || "rtl"] : "" ), onClick: (event) => handlePageClick(page, event) }, page )) ); }; // layout/docsLayout/DocsLayout.tsx var DocsLayout = ({ direction = "ltr", drawerSize = "md", DrawerFooterActions, clickedItem, keepOpen, pages, setKeepOpen, ...props }) => { let closeDrawerWidth = 0; let openDrawerWidth = 200; let drawerSizeStyle = { opened: { sm: "100", md: openDrawerWidth, lg: "250" }, closed: { sm: closeDrawerWidth, md: closeDrawerWidth, lg: closeDrawerWidth } }; const ref = useRef2(null); const isRTL = direction === "rtl"; let size = useBreakpoint(); if (typeof window == "undefined") { size = 1200; } const [currentPage, setCurrentPage] = useState4("Introduction"); const [openSideMenu, setOpenSideMenu] = useState4(true); useEffect2(() => { const handleClickOutside = (event) => { if (ref.current && !ref.current.contains(event.target) && !openSideMenu) { setOpenSideMenu(false); } }; document.addEventListener("click", handleClickOutside, true); return () => { document.removeEventListener("click", handleClickOutside, true); }; }, [openSideMenu]); useEffect2(() => { const handleResize = () => { setOpenSideMenu(window.innerWidth > 600 ? true : false); }; handleResize(); window.addEventListener("resize", handleResize); return () => { window.removeEventListener("resize", handleResize); }; }, [keepOpen]); const observerRef = React10.useRef(null); const handleIntersection = (entries) => { const entry = entries.find((entry2) => entry2.isIntersecting); if (entry) { setCurrentPage(entry.target.id); } }; useEffect2(() => { observerRef.current = new IntersectionObserver(handleIntersection, { threshold: 0.5 // Adjust threshold as needed to determine when a section is in view }); React10.Children.forEach(props.children, (child) => { if (child && child.props.id) { const element = document.getElementById(child.props.id); if (element && observerRef.current) { observerRef.current.observe(element); } } }); return () => { if (observerRef.current) { observerRef.current.disconnect(); } }; }, [props.children]); let drawerSizeCondition = drawerSizeStyle[openSideMenu ? "opened" : "closed"][drawerSize]; return /* @__PURE__ */ React10.createElement("div", { className: "hawa-fixed" }, /* @__PURE__ */ React10.createElement( "div", { className: cn( "hawa-fixed hawa-left-0 hawa-right-0 hawa-top-0 hawa-z-30 hawa-flex hawa-h-14 hawa-w-full hawa-items-center hawa-justify-between hawa-bg-primary-foreground hawa-p-2", isRTL ? "hawa-flex-row-reverse" : "hawa-flex-row" ) }, size > 600 ? /* @__PURE__ */ React10.createElement("div", { onClick: props.onLogoClick, dir: direction }, /* @__PURE__ */ React10.createElement( "img", { className: cn( "hawa-h-8 hawa-opacity-0 hawa-transition-all", !openSideMenu ? "hawa-invisible hawa-opacity-0" : "hawa-visible hawa-opacity-100" ), src: props.logoLink } )) : ( // Mobile Drawer Menu Button /* @__PURE__ */ React10.createElement( "div", { dir: direction, className: "hawa-flex hawa-items-center hawa-justify-center hawa-gap-0.5" }, /* @__PURE__ */ React10.createElement(Sheet, null, /* @__PURE__ */ React10.createElement(SheetTrigger, null, " ", /* @__PURE__ */ React10.createElement( "div", { className: "hawa-z-40 hawa-mx-1 hawa-cursor-pointer hawa-rounded hawa-p-2 hawa-transition-all hover:hawa-bg-gray-100" }, /* @__PURE__ */ React10.createElement( "svg", { "aria-label": "Menu Icon", stroke: "currentColor", fill: "currentColor", strokeWidth: 0, viewBox: "0 0 20 20", "aria-hidden": "true", height: "1.6em", width: "1.6em" }, /* @__PURE__ */ React10.createElement( "path", { fillRule: "evenodd", clipRule: "evenodd", d: "M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" } ) ) )), /* @__PURE__ */ React10.createElement( SheetContent, { side: isRTL ? "right" : "left", className: "hawa-pt-10" }, /* @__PURE__ */ React10.createElement(DocsSidebar, { direction, pages: pages || [] }) )) ) ), /* @__PURE__ */ React10.createElement( "div", { className: cn( "hawa-flex hawa-gap-2 dark:hawa-text-white", isRTL ? "hawa-flex-row-reverse" : "hawa-flex-row" ) }, /* @__PURE__ */ React10.createElement(Button, { variant: "ghost", size: "smallIcon" }, /* @__PURE__ */ React10.createElement(Logos.github, { className: "hawa-icon" })) ) ), /* @__PURE__ */ React10.createElement( "div", { className: cn( "hawa-fixed hawa-z-40 hawa-flex hawa-flex-col hawa-justify-between hawa-overflow-x-clip hawa-bg-primary-foreground hawa-transition-all", isRTL ? "hawa-right-0 hawa-top-0 hawa-h-full" : "hawa-left-0 hawa-top