react-vite-themes
Version:
A test/experimental React theme system created for learning purposes. Features atomic design components, SCSS variables, and dark/light theme support. Not intended for production use.
33 lines (32 loc) • 2.28 kB
JavaScript
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
import React, { useEffect } from 'react';
import { cn } from '../../../utils';
export const Sidebar = ({ children, className, direction = 'left', isOpen = false, onClose, showHeader = true, headerContent, ...props }) => {
const closeSidebar = () => {
onClose?.();
};
// Lock body scroll when sidebar is open
useEffect(() => {
if (isOpen) {
// Store original body styles
const originalOverflow = document.body.style.overflow;
const originalPaddingRight = document.body.style.paddingRight;
const scrollBarWidth = window.innerWidth - document.documentElement.clientWidth;
// Lock body scroll
document.body.style.overflow = 'hidden';
document.body.style.paddingRight = `${scrollBarWidth}px`;
// Restore original styles when sidebar closes
return () => {
document.body.style.overflow = originalOverflow;
document.body.style.paddingRight = originalPaddingRight;
};
}
else {
// Ensure scroll is restored when sidebar is not open
document.body.style.overflow = '';
document.body.style.paddingRight = '';
}
}, [isOpen]);
const defaultHeaderContent = (_jsxs(_Fragment, { children: [_jsxs("h3", { children: ["Sidebar (", direction, ")"] }), _jsx("button", { className: "sidebar__close", onClick: closeSidebar, "aria-label": "Close sidebar", children: _jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), _jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })] }));
return (_jsxs(_Fragment, { children: [isOpen && (_jsx("div", { className: "sidebar-overlay", onClick: closeSidebar })), _jsx("aside", { className: cn('sidebar', `sidebar--${direction}`, isOpen && 'sidebar--open', className), ...props, children: _jsxs("div", { className: "sidebar__container", children: [showHeader && (_jsx("div", { className: "sidebar__header", children: headerContent || defaultHeaderContent })), children] }) })] }));
};