UNPKG

@heycar-uikit/core

Version:
124 lines (120 loc) 10.1 kB
import React, { useState } from 'react'; import Grid from '../../grid/modern'; import { Close, Search, HeartDefault, Dealer, Call, Hamburger } from '../../icons/modern'; import Logo from '../../logo/modern'; import Typography from '../../typography/modern'; import LanguageList from './components/LanguageList.js'; import NavigationBurgerMenu from './components/NavigationBurgerMenu.js'; import NavigationDropdown from './components/NavigationDropdown.js'; import { MAX_FAVES_DISPLAY_NO, DEFAULT_LOCALE } from './constants/Header.constants.js'; import { useLangList } from './hooks/useLangList.js'; import { useNavigationItem } from './hooks/useNavigationItem.js'; import { hasHeaderItems, getCurrentLang } from './utils/headerItemHelpers.js'; import '../../collapse/modern'; import './components/SubNav.js'; import './utils/navigationHelpers.js'; var styles = {"header":"header__header_idaml","isBurgerOpen":"header__isBurgerOpen_idaml","headerInner":"header__headerInner_idaml","colLeft":"header__colLeft_idaml","colRight":"header__colRight_idaml","logo":"header__logo_idaml","searchWrapper":"header__searchWrapper_idaml","closeSearch":"header__closeSearch_idaml","active":"header__active_idaml","faves":"header__faves_idaml","counter":"header__counter_idaml","item":"header__item_idaml","horizontalNavOnly":"header__horizontalNavOnly_idaml","desktopOnly":"header__desktopOnly_idaml","focused":"header__focused_idaml","notHorizontalNav":"header__notHorizontalNav_idaml","asideItem":"header__asideItem_idaml","langWrapper":"header__langWrapper_idaml","navWrapper":"header__navWrapper_idaml"}; require('./styles/default.css'); const DefaultLinkComponent = (props) => React.createElement("a", { ...props }); const Header = React.forwardRef(({ accountItemConfig, auxiliaryDetails, callItemConfig, currentRoute, dataTestId, favoritesItemConfig, langItemConfig, LinkComponent, locale = DEFAULT_LOCALE, logoHref, navigation, onToggleBurgerMenu, searchItemConfig, trackingFn, }, ref) => { // State items const [isNavTrayOpen, setIsNavTrayOpen] = useState(false); const [activeNavItem, setActiveNavItem] = useState(undefined); const [isSearchOpen, setIsSearchOpen] = useState(false); const toggleBurgerMenu = (isOpen) => { setIsNavTrayOpen(isOpen); if (typeof onToggleBurgerMenu === 'function') onToggleBurgerMenu(isOpen); }; const resetMenuState = () => { setActiveNavItem(undefined); toggleBurgerMenu(false); }; const { itemOnClick } = useNavigationItem(activeNavItem, setActiveNavItem, resetMenuState); // Link component const Link = (LinkComponent || DefaultLinkComponent); // Header items const { hasSearch, hasFaves, hasLang, hasAccount, hasCall } = hasHeaderItems(searchItemConfig, favoritesItemConfig, langItemConfig, accountItemConfig, callItemConfig); const favesCount = favoritesItemConfig?.favoritesNumber || 0; // Lang const currentLang = hasLang ? getCurrentLang(langItemConfig.currentLang, langItemConfig.options) : undefined; const LangIco = currentLang?.icon; const { isLangListOpen, keyboardOpen, setIsFocused, setIsHovering } = useLangList(); // Event handlers const handleSearchToggle = (newState) => { setIsSearchOpen(newState); if (searchItemConfig?.onClick) searchItemConfig.onClick(newState); }; return (React.createElement("header", { className: `${styles.header} ${isNavTrayOpen ? styles.isBurgerOpen : ''}`, "data-test-id": dataTestId, ref: ref }, React.createElement(Grid.Container, { className: styles.headerInner }, React.createElement(Grid.Row, { gutter: { mobile: 8, tablet: 12, desktop: 24 } }, React.createElement(Grid.Col, { className: styles.colLeft }, React.createElement(Link, { "aria-label": locale.logoLabel, className: styles.logo, href: logoHref, onClick: () => itemOnClick({ fn: trackingFn, obj: { label: 'Logo', href: logoHref }, }) }, React.createElement(Logo, null)), hasSearch && (React.createElement("div", { className: `${styles.searchWrapper} ${isSearchOpen ? styles.active : ''}` }, React.createElement("button", { "aria-label": locale.closeSearchLabel, className: styles.closeSearch, onClick: () => itemOnClick({ fn: trackingFn, obj: { label: 'Mobile Search Toggle', action: 'close', }, }, () => handleSearchToggle(false)) }, React.createElement(Close, null)), searchItemConfig.Component))), React.createElement(Grid.Col, { className: styles.colRight }, hasSearch && (React.createElement("button", { "aria-label": searchItemConfig.label, className: `${styles.notHorizontalNav} ${styles.item}`, onClick: () => itemOnClick({ fn: trackingFn, obj: { label: 'Mobile Search Toggle', action: 'open' }, }, () => handleSearchToggle(true)) }, React.createElement(Search, null))), hasFaves && (React.createElement(Link, { "aria-label": favoritesItemConfig.label, className: `${styles.item} ${styles.faves}`, href: favoritesItemConfig.href, onClick: () => itemOnClick({ fn: trackingFn, obj: { label: favoritesItemConfig.label, href: favoritesItemConfig.href, }, }, favoritesItemConfig.onClick) }, React.createElement(HeartDefault, null), React.createElement("span", { "aria-label": locale.favoritesCountLabel, className: `${styles.counter} ${favesCount > 0 ? styles.active : ''}` }, favesCount > MAX_FAVES_DISPLAY_NO ? MAX_FAVES_DISPLAY_NO : favesCount), React.createElement(Typography, { variant: "subheading3" }, favoritesItemConfig.label))), hasLang && currentLang && (React.createElement("div", { className: styles.langWrapper }, React.createElement("button", { "aria-haspopup": "menu", "aria-label": `${locale.langListHeading} - ${locale.spaceBarNotification}`, className: `${styles.horizontalNavOnly} ${styles.item} ${isLangListOpen ? styles.focused : ''}`, onBlur: () => setIsFocused(false), onFocus: () => setIsFocused(true), onKeyDown: e => keyboardOpen(e), onMouseOut: () => setIsHovering(false), onMouseOver: () => setIsHovering(true) }, LangIco, React.createElement(Typography, { variant: "subheading3" }, currentLang.shortName)), isLangListOpen && (React.createElement(LanguageList, { dataTestId: "header-language-list", heading: locale.langListHeading, itemOnClick: itemOnClick, onFocusEvents: setIsFocused, onHoverEvents: setIsHovering, options: langItemConfig.options, trackingFn: trackingFn })))), hasAccount && (React.createElement("button", { "aria-label": accountItemConfig.label, className: `${styles.horizontalNavOnly} ${styles.item}`, onClick: () => itemOnClick({ fn: trackingFn, obj: { label: accountItemConfig.label }, }, accountItemConfig.onClick) }, React.createElement(Dealer, null), React.createElement(Typography, { variant: "subheading3" }, accountItemConfig.label))), hasCall && (React.createElement(Link, { "aria-label": callItemConfig.label, className: `${styles.horizontalNavOnly} ${styles.item} ${styles.asideItem}`, href: callItemConfig.href, onClick: () => itemOnClick({ fn: trackingFn, obj: { label: callItemConfig.label, href: callItemConfig.href, }, }, callItemConfig.onClick) }, React.createElement(Call, null), React.createElement(Typography, { variant: "subheading3" }, callItemConfig.label))), React.createElement("button", { "aria-label": DEFAULT_LOCALE.burgerMenuButtonLabel, className: `${styles.notHorizontalNav} ${styles.item}`, onClick: () => itemOnClick({ fn: trackingFn, obj: { label: 'Burger Menu Toggle', action: isNavTrayOpen ? 'close' : 'open', }, }, () => toggleBurgerMenu(!isNavTrayOpen), false) }, isNavTrayOpen ? React.createElement(Close, null) : React.createElement(Hamburger, null))))), React.createElement("div", { className: `${styles.navWrapper} ${isNavTrayOpen ? 'navOpen' : ''}` }, React.createElement(NavigationBurgerMenu, { Link: Link, accountItemConfig: accountItemConfig, activeNavItem: activeNavItem, auxiliaryDetails: auxiliaryDetails, currentLang: currentLang?.langCode, dataTestId: `${dataTestId}-navigation`, itemOnClick: itemOnClick, langItemConfig: langItemConfig, locale: locale, navigation: navigation, setActiveNavItem: setActiveNavItem, trackingFn: trackingFn }), React.createElement(NavigationDropdown, { Link: Link, activeNavItem: activeNavItem, currentRoute: currentRoute, dataTestId: `${dataTestId}-navigation`, itemOnClick: itemOnClick, locale: locale, navigation: navigation, setActiveNavItem: setActiveNavItem, trackingFn: trackingFn })))); }); Header.displayName = 'Header'; export { Header as default };