@penaprieto/design-system
Version:
Multi-brand React design system with design tokens from Figma
77 lines (76 loc) • 5.32 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Header = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
require("./Header.css");
const Avatar_1 = require("../Avatar");
const Button_1 = require("../Button");
const Icon_1 = require("../Icon");
const Header = ({ logo, navItems = [], user, primaryAction, rightActions, onNavItemClick, onUserClick, className = '', ...rest }) => {
const [mobileOpen, setMobileOpen] = (0, react_1.useState)(false);
const navRef = (0, react_1.useRef)(null);
const rootClassName = ['ds-header', className].filter(Boolean).join(' ');
const handleToggleMobile = () => {
setMobileOpen((prev) => !prev);
};
const handleCloseMobile = () => {
setMobileOpen(false);
};
(0, react_1.useEffect)(() => {
if (!mobileOpen)
return;
const handler = (event) => {
if (!navRef.current)
return;
if (!navRef.current.contains(event.target)) {
handleCloseMobile();
}
};
document.addEventListener('mousedown', handler);
return () => document.removeEventListener('mousedown', handler);
}, [mobileOpen]);
const handleNavClick = (item, event) => {
if (!item.href) {
event.preventDefault();
}
onNavItemClick === null || onNavItemClick === void 0 ? void 0 : onNavItemClick(item.id);
if (window.innerWidth <= 768) {
handleCloseMobile();
}
};
const renderUserAvatar = (variant) => {
if (!user)
return null;
const { name, email, avatarSrc, initials } = user;
if (variant === 'desktop') {
return ((0, jsx_runtime_1.jsxs)("button", { type: "button", className: "ds-header__avatar ds-header__avatar--desktop", onClick: onUserClick, children: [(0, jsx_runtime_1.jsx)(Avatar_1.Avatar, { size: "xsmall", src: avatarSrc, initials: initials, name: name }), (0, jsx_runtime_1.jsx)("span", { className: "ds-header__chevron", "aria-hidden": "true", children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "chevron-down", size: 16 }) })] }));
}
return ((0, jsx_runtime_1.jsxs)("button", { type: "button", className: "ds-header__avatar ds-header__avatar--mobile", onClick: onUserClick, children: [(0, jsx_runtime_1.jsx)(Avatar_1.Avatar, { size: "medium", src: avatarSrc, initials: initials, name: name }), (0, jsx_runtime_1.jsxs)("div", { className: "ds-header__user-info", children: [name && (0, jsx_runtime_1.jsx)("div", { className: "ds-header__user-name", children: name }), email && (0, jsx_runtime_1.jsx)("div", { className: "ds-header__user-email", children: email })] })] }));
};
return ((0, jsx_runtime_1.jsxs)("header", { className: rootClassName, ...rest, children: [(0, jsx_runtime_1.jsxs)("div", { className: "ds-header__container", children: [(0, jsx_runtime_1.jsx)("div", { className: "ds-header__left", children: logo && (0, jsx_runtime_1.jsx)("div", { className: "ds-header__logo", children: logo }) }), (0, jsx_runtime_1.jsxs)("nav", { ref: navRef, className: [
'ds-header__nav',
mobileOpen && 'ds-header__nav--open',
]
.filter(Boolean)
.join(' '), "aria-label": "Navegaci\u00F3n principal", children: [renderUserAvatar('mobile'), navItems.map((item) => {
const isActive = item.active;
const itemClassName = [
'ds-header__nav-item',
isActive && 'ds-header__nav-item--active',
]
.filter(Boolean)
.join(' ');
const content = ((0, jsx_runtime_1.jsx)("span", { className: "ds-header__nav-link", children: item.label }));
if (item.href) {
return ((0, jsx_runtime_1.jsx)("a", { href: item.href, className: itemClassName, onClick: (e) => handleNavClick(item, e), children: content }, item.id));
}
return ((0, jsx_runtime_1.jsx)("button", { type: "button", className: itemClassName, onClick: (e) => handleNavClick(item, e), children: content }, item.id));
})] }), (0, jsx_runtime_1.jsxs)("div", { className: "ds-header__right", children: [primaryAction, renderUserAvatar('desktop'), rightActions, (0, jsx_runtime_1.jsx)(Button_1.Button, { shape: "icon", variant: "ghost", size: "large", "aria-label": mobileOpen ? 'Cerrar menú de navegación' : 'Abrir menú de navegación', "aria-expanded": mobileOpen, className: "ds-header__menu-btn", onClick: handleToggleMobile, iconLeft: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "menu", size: 28 }) })] })] }), (0, jsx_runtime_1.jsx)("div", { className: [
'ds-header__overlay',
mobileOpen && 'ds-header__overlay--active',
]
.filter(Boolean)
.join(' '), onClick: handleCloseMobile })] }));
};
exports.Header = Header;