UNPKG

@arolariu/components

Version:

🎨 70+ beautiful, accessible React components built on Base UI. TypeScript-first, CSS Modules styling, tree-shakeable, SSR-ready. Perfect for modern web apps, design systems & rapid prototyping. Zero config, maximum flexibility! ⚡

473 lines (472 loc) • 19.2 kB
"use client"; import { jsx, jsxs } from "react/jsx-runtime"; import { PanelLeft } from "lucide-react"; import { createPortal } from "react-dom"; import { Button } from "./button.js"; import { Input } from "./input.js"; import { Separator } from "./separator.js"; import { Skeleton } from "./skeleton.js"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./tooltip.js"; import { useIsMobile } from "../../hooks/useIsMobile.js"; import { cn } from "../../lib/utilities.js"; import sidebar_module from "./sidebar.module.js"; import * as __rspack_external_react from "react"; const SIDEBAR_COOKIE_NAME = "sidebar_state"; const SIDEBAR_COOKIE_MAX_AGE = 604800; const SIDEBAR_WIDTH = "16rem"; const SIDEBAR_WIDTH_MOBILE = "18rem"; const SIDEBAR_WIDTH_ICON = "3rem"; const SIDEBAR_KEYBOARD_SHORTCUT = "b"; const SidebarContext = /*#__PURE__*/ __rspack_external_react.createContext(null); function useSidebar() { const context = __rspack_external_react.useContext(SidebarContext); if (!context) throw new Error("useSidebar must be used within a SidebarProvider."); return context; } const SidebarProvider = /*#__PURE__*/ __rspack_external_react.forwardRef(({ defaultOpen = true, open: openProp, onOpenChange: setOpenProp, className, style, children, ...props }, ref)=>{ const isMobile = useIsMobile(); const [openMobile, setOpenMobile] = __rspack_external_react.useState(false); const [internalOpen, setInternalOpen] = __rspack_external_react.useState(defaultOpen); const open = openProp ?? internalOpen; const setOpen = __rspack_external_react.useCallback((value)=>{ const nextValue = "function" == typeof value ? value(open) : value; if (setOpenProp) setOpenProp(nextValue); else setInternalOpen(nextValue); document.cookie = `${SIDEBAR_COOKIE_NAME}=${nextValue}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`; }, [ open, setOpenProp ]); const toggleSidebar = __rspack_external_react.useCallback(()=>{ if (isMobile) return void setOpenMobile((currentOpen)=>!currentOpen); setOpen((currentOpen)=>!currentOpen); }, [ isMobile, setOpen ]); __rspack_external_react.useEffect(()=>{ const handleKeyDown = (event)=>{ if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) { event.preventDefault(); toggleSidebar(); } }; globalThis.window.addEventListener("keydown", handleKeyDown); return ()=>{ globalThis.window.removeEventListener("keydown", handleKeyDown); }; }, [ toggleSidebar ]); const state = open ? "expanded" : "collapsed"; const contextValue = __rspack_external_react.useMemo(()=>({ isMobile, open, openMobile, setOpen, setOpenMobile, state, toggleSidebar }), [ isMobile, open, openMobile, setOpen, state, toggleSidebar ]); return /*#__PURE__*/ jsx(SidebarContext.Provider, { value: contextValue, children: /*#__PURE__*/ jsx(TooltipProvider, { children: /*#__PURE__*/ jsx("div", { ref: ref, style: { "--ac-sidebar-width": SIDEBAR_WIDTH, "--ac-sidebar-width-icon": SIDEBAR_WIDTH_ICON, ...style }, className: cn(sidebar_module.wrapper, className), ...props, children: children }) }) }); }); SidebarProvider.displayName = "SidebarProvider"; const Sidebar = /*#__PURE__*/ __rspack_external_react.forwardRef(({ side = "left", variant = "sidebar", collapsible = "offcanvas", className, children, ...props }, ref)=>{ const { isMobile, openMobile, setOpenMobile, state } = useSidebar(); if ("none" === collapsible) return /*#__PURE__*/ jsx("div", { ref: ref, className: cn(sidebar_module.staticSidebar, className), ...props, children: children }); if (isMobile) return /*#__PURE__*/ jsx(MobileSidebarPortal, { className: className, open: openMobile, side: side, onOpenChange: setOpenMobile, ...props, children: children }); return /*#__PURE__*/ jsxs("div", { ref: ref, className: sidebar_module.desktopRoot, "data-state": state, "data-collapsible": "collapsed" === state ? collapsible : "", "data-variant": variant, "data-side": side, children: [ /*#__PURE__*/ jsx("div", { className: sidebar_module.gap }), /*#__PURE__*/ jsx("div", { className: cn(sidebar_module.panelWrap, className), ...props, children: /*#__PURE__*/ jsx("div", { "data-sidebar": "sidebar", className: sidebar_module.panel, children: children }) }) ] }); }); Sidebar.displayName = "Sidebar"; function MobileSidebarPortal({ open, side, onOpenChange, className, children, ...props }) { __rspack_external_react.useEffect(()=>{ if (!open) return; const previousOverflow = document.body.style.overflow; const handleKeyDown = (event)=>{ if ("Escape" === event.key) onOpenChange(false); }; document.body.style.overflow = "hidden"; globalThis.window.addEventListener("keydown", handleKeyDown); return ()=>{ document.body.style.overflow = previousOverflow; globalThis.window.removeEventListener("keydown", handleKeyDown); }; }, [ onOpenChange, open ]); if (!open || "u" < typeof document) return null; return /*#__PURE__*/ createPortal(/*#__PURE__*/ jsxs("div", { className: sidebar_module.mobilePortal, children: [ /*#__PURE__*/ jsx("button", { type: "button", "aria-label": "Close sidebar", className: sidebar_module.mobileOverlay, onClick: ()=>onOpenChange(false) }), /*#__PURE__*/ jsxs("div", { role: "dialog", "aria-modal": "true", "aria-label": "Sidebar", "data-sidebar": "sidebar", className: cn(sidebar_module.mobilePanel, "right" === side ? sidebar_module.mobilePanelRight : sidebar_module.mobilePanelLeft, className), style: { "--ac-sidebar-width": SIDEBAR_WIDTH_MOBILE }, ...props, children: [ /*#__PURE__*/ jsxs("div", { className: sidebar_module.srOnly, children: [ /*#__PURE__*/ jsx("h2", { children: "Sidebar" }), /*#__PURE__*/ jsx("p", { children: "Displays the mobile sidebar." }) ] }), /*#__PURE__*/ jsx("div", { className: sidebar_module.mobileContent, children: children }) ] }) ] }), document.body); } const SidebarTrigger = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, onClick, ...props }, ref)=>{ const { toggleSidebar } = useSidebar(); return /*#__PURE__*/ jsxs(Button, { ref: ref, "data-sidebar": "trigger", variant: "ghost", size: "icon", className: cn(sidebar_module.trigger, className), onClick: (event)=>{ onClick?.(event); toggleSidebar(); }, ...props, children: [ /*#__PURE__*/ jsx(PanelLeft, { className: sidebar_module.triggerIcon }), /*#__PURE__*/ jsx("span", { className: sidebar_module.srOnly, children: "Toggle Sidebar" }) ] }); }); SidebarTrigger.displayName = "SidebarTrigger"; const SidebarRail = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, ...props }, ref)=>{ const { toggleSidebar } = useSidebar(); return /*#__PURE__*/ jsx("button", { ref: ref, "data-sidebar": "rail", "aria-label": "Toggle Sidebar", tabIndex: -1, title: "Toggle Sidebar", type: "button", className: cn(sidebar_module.rail, className), onClick: toggleSidebar, ...props }); }); SidebarRail.displayName = "SidebarRail"; const SidebarInset = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("main", { ref: ref, className: cn(sidebar_module.inset, className), ...props })); SidebarInset.displayName = "SidebarInset"; const SidebarInput = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx(Input, { ref: ref, "data-sidebar": "input", className: cn(sidebar_module.input, className), ...props })); SidebarInput.displayName = "SidebarInput"; const SidebarHeader = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("div", { ref: ref, "data-sidebar": "header", className: cn(sidebar_module.header, className), ...props })); SidebarHeader.displayName = "SidebarHeader"; const SidebarFooter = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("div", { ref: ref, "data-sidebar": "footer", className: cn(sidebar_module.footer, className), ...props })); SidebarFooter.displayName = "SidebarFooter"; const SidebarSeparator = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx(Separator, { ref: ref, "data-sidebar": "separator", className: cn(sidebar_module.separator, className), ...props })); SidebarSeparator.displayName = "SidebarSeparator"; const SidebarContent = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("div", { ref: ref, "data-sidebar": "content", className: cn(sidebar_module.content, className), ...props })); SidebarContent.displayName = "SidebarContent"; const SidebarGroup = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("div", { ref: ref, "data-sidebar": "group", className: cn(sidebar_module.group, className), ...props })); SidebarGroup.displayName = "SidebarGroup"; function cloneSidebarChild(children, mergedProps) { if (!/*#__PURE__*/ __rspack_external_react.isValidElement(children)) return null; const child = children; return /*#__PURE__*/ __rspack_external_react.cloneElement(child, { ...mergedProps, className: cn(mergedProps.className, child.props.className) }); } const SidebarGroupLabel = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, asChild = false, children, ...props }, ref)=>{ const mergedProps = { ...props, children, className: cn(sidebar_module.groupLabel, className), "data-sidebar": "group-label", ref }; if (asChild) { const clonedChild = cloneSidebarChild(children, mergedProps); if (clonedChild) return clonedChild; } return /*#__PURE__*/ jsx("div", { ...mergedProps }); }); SidebarGroupLabel.displayName = "SidebarGroupLabel"; const SidebarGroupAction = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, asChild = false, children, ...props }, ref)=>{ const mergedProps = { ...props, children, className: cn(sidebar_module.groupAction, className), "data-sidebar": "group-action", ref, type: props.type ?? "button" }; if (asChild) { const clonedChild = cloneSidebarChild(children, mergedProps); if (clonedChild) return clonedChild; } return /*#__PURE__*/ jsx("button", { type: "submit" === props.type ? "submit" : "reset" === props.type ? "reset" : "button", ...mergedProps }); }); SidebarGroupAction.displayName = "SidebarGroupAction"; const SidebarGroupContent = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("div", { ref: ref, "data-sidebar": "group-content", className: cn(sidebar_module.groupContent, className), ...props })); SidebarGroupContent.displayName = "SidebarGroupContent"; const SidebarMenu = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("ul", { ref: ref, "data-sidebar": "menu", className: cn(sidebar_module.menu, className), ...props })); SidebarMenu.displayName = "SidebarMenu"; const SidebarMenuItem = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("li", { ref: ref, "data-sidebar": "menu-item", className: cn(sidebar_module.menuItem, className), ...props })); SidebarMenuItem.displayName = "SidebarMenuItem"; const sidebarMenuButtonVariantStyles = { default: sidebar_module.menuButtonDefault, outline: sidebar_module.menuButtonOutline }; const sidebarMenuButtonSizeStyles = { default: sidebar_module.menuButtonSizeDefault, sm: sidebar_module.menuButtonSizeSm, lg: sidebar_module.menuButtonSizeLg }; const SidebarMenuButton = /*#__PURE__*/ __rspack_external_react.forwardRef(({ asChild = false, isActive = false, variant = "default", size = "default", tooltip, className, children, ...props }, ref)=>{ const { isMobile, state } = useSidebar(); const mergedProps = { ...props, children, className: cn(sidebar_module.menuButton, sidebarMenuButtonVariantStyles[variant], sidebarMenuButtonSizeStyles[size], className), "data-active": isActive, "data-sidebar": "menu-button", "data-size": size, ref, type: props.type ?? "button" }; const clonedChild = asChild ? cloneSidebarChild(children, mergedProps) : null; const button = clonedChild ?? /*#__PURE__*/ jsx("button", { type: "submit" === props.type ? "submit" : "reset" === props.type ? "reset" : "button", ...mergedProps }); if (!tooltip) return button; const resolvedTooltip = "string" == typeof tooltip ? { children: tooltip } : tooltip; return /*#__PURE__*/ jsxs(Tooltip, { children: [ /*#__PURE__*/ jsx(TooltipTrigger, { render: button }), /*#__PURE__*/ jsx(TooltipContent, { hidden: "collapsed" !== state || isMobile, ...resolvedTooltip }) ] }); }); SidebarMenuButton.displayName = "SidebarMenuButton"; const SidebarMenuAction = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, asChild = false, showOnHover = false, children, ...props }, ref)=>{ const mergedProps = { ...props, children, className: cn(sidebar_module.menuAction, showOnHover && sidebar_module.menuActionShowOnHover, className), "data-sidebar": "menu-action", ref, type: props.type ?? "button" }; if (asChild) { const clonedChild = cloneSidebarChild(children, mergedProps); if (clonedChild) return clonedChild; } return /*#__PURE__*/ jsx("button", { type: "submit" === props.type ? "submit" : "reset" === props.type ? "reset" : "button", ...mergedProps }); }); SidebarMenuAction.displayName = "SidebarMenuAction"; const SidebarMenuBadge = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("div", { ref: ref, "data-sidebar": "menu-badge", className: cn(sidebar_module.menuBadge, className), ...props })); SidebarMenuBadge.displayName = "SidebarMenuBadge"; const SidebarMenuSkeleton = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, showIcon = false, ...props }, ref)=>{ const width = __rspack_external_react.useMemo(()=>`${Math.floor(40 * Math.random()) + 50}%`, []); return /*#__PURE__*/ jsxs("div", { ref: ref, "data-sidebar": "menu-skeleton", className: cn(sidebar_module.menuSkeleton, className), ...props, children: [ Boolean(showIcon) && /*#__PURE__*/ jsx(Skeleton, { className: sidebar_module.menuSkeletonIcon, "data-sidebar": "menu-skeleton-icon" }), /*#__PURE__*/ jsx(Skeleton, { className: sidebar_module.menuSkeletonText, "data-sidebar": "menu-skeleton-text", style: { "--ac-skeleton-width": width } }) ] }); }); SidebarMenuSkeleton.displayName = "SidebarMenuSkeleton"; const SidebarMenuSub = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("ul", { ref: ref, "data-sidebar": "menu-sub", className: cn(sidebar_module.menuSub, className), ...props })); SidebarMenuSub.displayName = "SidebarMenuSub"; const SidebarMenuSubItem = /*#__PURE__*/ __rspack_external_react.forwardRef((props, ref)=>/*#__PURE__*/ jsx("li", { ref: ref, ...props })); SidebarMenuSubItem.displayName = "SidebarMenuSubItem"; const SidebarMenuSubButton = /*#__PURE__*/ __rspack_external_react.forwardRef(({ asChild = false, size = "md", isActive, className, children, ...props }, ref)=>{ const mergedProps = { ...props, children, className: cn(sidebar_module.menuSubButton, "sm" === size ? sidebar_module.menuSubButtonSm : sidebar_module.menuSubButtonMd, className), "data-active": isActive, "data-sidebar": "menu-sub-button", "data-size": size, ref }; if (asChild) { const clonedChild = cloneSidebarChild(children, mergedProps); if (clonedChild) return clonedChild; } return /*#__PURE__*/ jsx("a", { ...mergedProps, children: children }); }); SidebarMenuSubButton.displayName = "SidebarMenuSubButton"; export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, useSidebar }; //# sourceMappingURL=sidebar.js.map