lightswind
Version:
A collection of beautifully crafted React Components, Blocks & Templates for Modern Developers. Create stunning web applications effortlessly by using our 160+ professional and animated react components.
202 lines • 11.8 kB
JavaScript
;
"use client";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.SidebarProvider = SidebarProvider;
exports.useSidebar = useSidebar;
exports.Sidebar = Sidebar;
exports.SidebarRoot = Sidebar;
exports.SidebarTrigger = SidebarTrigger;
exports.SidebarHeader = SidebarHeader;
exports.SidebarContent = SidebarContent;
exports.SidebarGroup = SidebarGroup;
exports.SidebarGroupLabel = SidebarGroupLabel;
exports.SidebarGroupContent = SidebarGroupContent;
exports.SidebarMenu = SidebarMenu;
exports.SidebarMenuItem = SidebarMenuItem;
exports.SidebarMenuButton = SidebarMenuButton;
exports.SidebarFooter = SidebarFooter;
const jsx_runtime_1 = require("react/jsx-runtime");
const React = __importStar(require("react"));
const lucide_react_1 = require("lucide-react");
const framer_motion_1 = require("framer-motion");
const tailwind_merge_1 = require("tailwind-merge");
const clsx_1 = require("clsx");
// Re-implementing the 'cn' utility function directly for self-containment
function cn(...inputs) {
return (0, tailwind_merge_1.twMerge)((0, clsx_1.clsx)(inputs));
}
const SidebarContext = React.createContext(undefined);
function SidebarProvider({ defaultExpanded = true, expanded: controlledExpanded, onExpandedChange, children, }) {
const [expanded, setExpandedState] = React.useState(defaultExpanded);
const [activeMenuItem, setActiveMenuItem] = React.useState(null);
const isControlled = controlledExpanded !== undefined;
const actualExpanded = isControlled ? controlledExpanded : expanded;
const setExpanded = React.useCallback((value) => {
if (!isControlled) {
setExpandedState(value);
}
onExpandedChange?.(value);
}, [isControlled, onExpandedChange]);
// Sync active menu item from URL on mount
React.useEffect(() => {
if (typeof window === 'undefined')
return;
const url = new URL(window.location.href);
const searchParams = url.searchParams;
const path = url.pathname;
let potentialMenuItemValue = null;
if (searchParams.has("component")) {
potentialMenuItemValue = searchParams.get("component");
}
else {
const pathSegments = path.split("/").filter((segment) => segment);
if (pathSegments.length > 0) {
potentialMenuItemValue = pathSegments[pathSegments.length - 1];
}
}
setActiveMenuItem(potentialMenuItemValue);
}, []);
return ((0, jsx_runtime_1.jsx)(SidebarContext.Provider, { value: {
expanded: actualExpanded,
setExpanded,
activeMenuItem,
setActiveMenuItem,
}, children: (0, jsx_runtime_1.jsx)(framer_motion_1.LayoutGroup, { id: "sidebar-indicator", children: children }) }));
}
function useSidebar() {
const context = React.useContext(SidebarContext);
if (!context) {
throw new Error("useSidebar must be used within a SidebarProvider");
}
return context;
}
function Sidebar({ className, children, ...props }) {
const { expanded } = useSidebar();
return ((0, jsx_runtime_1.jsx)("div", { className: cn("h-full min-h-screen z-40 w-64 relative", "bg-background border-r border-border/40 shadow-sm", "fixed lg:sticky top-0", expanded ? "left-0" : "md:left-0 -left-full", className), role: "complementary", "data-collapsed": !expanded, ...props, children: children }));
}
function SidebarTrigger({ className, ...props }) {
const { expanded, setExpanded } = useSidebar();
return ((0, jsx_runtime_1.jsx)("button", { type: "button", className: cn("inline-flex items-center justify-center rounded-lg p-2 text-muted-foreground", "hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", "fixed md:static z-50 left-4 top-20 bg-background/80 backdrop-blur-sm border border-border shadow-sm", className), onClick: () => setExpanded(!expanded), "aria-label": expanded ? "Close sidebar" : "Open sidebar", ...props, children: expanded ? ((0, jsx_runtime_1.jsx)(lucide_react_1.ChevronLeft, { className: "h-4 w-4" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { className: "h-4 w-4" })) }));
}
function SidebarHeader({ className, children, ...props }) {
const { expanded } = useSidebar();
return ((0, jsx_runtime_1.jsx)("div", { className: cn("flex h-16 items-center border-b border-border/40 px-6", expanded ? "justify-between" : "justify-center", className), ...props, children: (0, jsx_runtime_1.jsx)(framer_motion_1.AnimatePresence, { mode: "wait", children: expanded && ((0, jsx_runtime_1.jsx)(framer_motion_1.motion.div, { initial: { opacity: 0, x: -10 }, animate: { opacity: 1, x: 0 }, exit: { opacity: 0, x: -10 }, transition: { duration: 0.2 }, className: "flex-1", children: children })) }) }));
}
const SCROLL_STORAGE_KEY = "sidebarScrollTop";
function SidebarContent({ className, children, ...props }) {
const scrollRef = React.useRef(null);
// Load/Save scroll position remains similar but cleaner
React.useEffect(() => {
const scrollElement = scrollRef.current;
if (scrollElement) {
const savedScrollTop = localStorage.getItem(SCROLL_STORAGE_KEY);
if (savedScrollTop)
scrollElement.scrollTop = parseInt(savedScrollTop, 10);
const handleScroll = () => {
localStorage.setItem(SCROLL_STORAGE_KEY, scrollElement.scrollTop.toString());
};
scrollElement.addEventListener("scroll", handleScroll, { passive: true });
return () => scrollElement.removeEventListener("scroll", handleScroll);
}
}, []);
return ((0, jsx_runtime_1.jsx)("div", { className: cn("flex-1 overflow-hidden h-full flex flex-col", className), ...props, children: (0, jsx_runtime_1.jsx)("div", { ref: scrollRef, className: "flex-1 overflow-y-auto overflow-x-hidden [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden py-4 px-3", children: children }) }));
}
// --- Grouping Components ---
function SidebarGroup({ className, children, ...props }) {
return ((0, jsx_runtime_1.jsx)("div", { className: cn("mb-6 last:mb-0", className), ...props, children: children }));
}
function SidebarGroupLabel({ className, children, ...props }) {
const { expanded } = useSidebar();
if (!expanded)
return null;
return ((0, jsx_runtime_1.jsx)("div", { className: cn("mb-2 px-3 text-[11px] font-bold uppercase tracking-widest text-muted-foreground/70", className), ...props, children: children }));
}
function SidebarGroupContent({ className, children, ...props }) {
return ((0, jsx_runtime_1.jsx)("div", { className: cn("space-y-0.5", className), ...props, children: children }));
}
// --- Menu Item Components (using LayoutID for Indicator) ---
function SidebarMenu({ className, children, ...props }) {
return ((0, jsx_runtime_1.jsx)("div", { className: cn("relative flex flex-col", className), ...props, children: children }));
}
function SidebarMenuItem({ className, children, value, ...props }) {
return ((0, jsx_runtime_1.jsx)("div", { className: cn("group relative w-full", className), "data-value": value, ...props, children: children }));
}
function SidebarMenuButton({ className, children, asChild = false, value, isActive: propIsActive, ...props }) {
const { expanded, activeMenuItem, setActiveMenuItem } = useSidebar();
const isActive = propIsActive ?? (activeMenuItem === value);
const handleClick = (e) => {
if (value)
setActiveMenuItem(value);
if (props.onClick)
props.onClick(e);
};
const content = ((0, jsx_runtime_1.jsxs)("div", { className: cn("relative flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm outline-none ", "hover:bg-secondary/50 active:scale-[0.98]", isActive
? "text-primary font-bold bg-primary/5 shadow-sm ring-1 ring-primary/10"
: "text-muted-foreground hover:text-foreground", !expanded && "justify-center px-0 py-3", className), onClick: handleClick, ...props, children: [isActive && ((0, jsx_runtime_1.jsx)(framer_motion_1.motion.div, { layoutId: "active-indicator", className: "absolute inset-0 rounded-lg bg-primary/5 dark:bg-primary/10 border-l-2 border-primary z-0", initial: false, transition: {
type: "spring",
stiffness: 400,
damping: 35
} })), (0, jsx_runtime_1.jsx)("span", { className: "relative z-10 flex items-center gap-3 w-full", children: children })] }));
if (asChild) {
const child = React.Children.only(children);
const childProps = child.props;
return React.cloneElement(child, {
...props,
className: cn("relative flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm outline-none group", "hover:bg-secondary/50 active:scale-[0.98]", isActive
? "text-primary font-bold bg-primary/5 shadow-sm ring-1 ring-primary/10"
: "text-muted-foreground hover:text-foreground", !expanded && "justify-center px-0 py-3", className, childProps.className),
onClick: (e) => {
if (value)
setActiveMenuItem(value);
if (childProps.onClick)
childProps.onClick(e);
if (props.onClick)
props.onClick(e);
},
children: ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [isActive && ((0, jsx_runtime_1.jsx)(framer_motion_1.motion.div, { layoutId: "active-indicator", className: "absolute inset-0 rounded-lg bg-primary/5 dark:bg-primary/10 border-l-2 border-primary z-0", initial: false, transition: {
type: "spring",
stiffness: 400,
damping: 35
} })), (0, jsx_runtime_1.jsx)("span", { className: "relative z-10 flex items-center gap-3 w-full", children: childProps.children })] }))
});
}
return content;
}
function SidebarFooter({ className, children, ...props }) {
const { expanded } = useSidebar();
return ((0, jsx_runtime_1.jsx)("div", { className: cn("mt-auto border-t border-border/40 p-4", expanded ? "flex-row items-center justify-between" : "flex-col justify-center", className), ...props, children: children }));
}
//# sourceMappingURL=sidebar.js.map