UNPKG

@penaprieto/design-system

Version:

Multi-brand React design system with design tokens from Figma

77 lines (76 loc) 5.32 kB
"use strict"; 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;