UNPKG

@codegouvfr/react-dsfr

Version:

French State Design System React integration library

139 lines 11.6 kB
var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; /* eslint-disable no-inner-declarations */ import React, { memo, forwardRef, cloneElement } from "react"; import { fr } from "../fr"; import { createComponentI18nApi } from "../i18n"; import { symToStr } from "tsafe/symToStr"; import { cx } from "../tools/cx"; import { getLink } from "../link"; import { assert } from "tsafe/assert"; import { MainNavigation } from "../MainNavigation"; import { Display } from "../Display/Display"; import { setBrandTopAndHomeLinkProps } from "../zz_internal/brandTopAndHomeLinkProps"; import { typeGuard } from "tsafe/typeGuard"; import { SearchButton } from "../SearchBar/SearchButton"; import { useTranslation as useSearchBarTranslation } from "../SearchBar/SearchBar"; export const headerMenuModalIdPrefix = "header-menu-modal"; /** @see <https://components.react-dsfr.codegouv.studio/?path=/docs/components-header> */ export const Header = memo(forwardRef((props, ref) => { const { className, id: id_props, brandTop, serviceTitle, serviceTagline, homeLinkProps, navigation = undefined, quickAccessItems = [], operatorLogo, renderSearchInput, clearSearchInputOnSearch = false, allowEmptySearch = false, onSearchButtonClick, classes = {}, style } = props, rest = __rest(props, ["className", "id", "brandTop", "serviceTitle", "serviceTagline", "homeLinkProps", "navigation", "quickAccessItems", "operatorLogo", "renderSearchInput", "clearSearchInputOnSearch", "allowEmptySearch", "onSearchButtonClick", "classes", "style"]); assert(); const id = id_props !== null && id_props !== void 0 ? id_props : "fr-header"; const menuModalId = `${headerMenuModalIdPrefix}-${id}`; const menuButtonId = `${id}-menu-button`; const searchModalId = `${id}-search-modal`; const searchInputId = `${id}-search-input`; const isSearchBarEnabled = renderSearchInput !== undefined || onSearchButtonClick !== undefined; setBrandTopAndHomeLinkProps({ brandTop, homeLinkProps }); const { t } = useTranslation(); const { t: tSearchBar } = useSearchBarTranslation(); const { Link } = getLink(); const getQuickAccessNode = (usecase) => (React.createElement("ul", { className: fr.cx("fr-btns-group") }, quickAccessItems.map((quickAccessItem, i) => (React.createElement("li", { key: i }, (() => { const node = !typeGuard(quickAccessItem, quickAccessItem instanceof Object && "text" in quickAccessItem) ? (quickAccessItem) : (React.createElement(HeaderQuickAccessItem, { quickAccessItem: quickAccessItem })); if (node === null) { return null; } return cloneElement(node, { "id": `${id}-quick-access-item-${i}${(() => { switch (usecase) { case "mobile": return "-mobile"; case "desktop": return ""; } assert(); })()}` }); })()))))); const hasOperatorLink = (operatorLogo === null || operatorLogo === void 0 ? void 0 : operatorLogo.linkProps) !== undefined; return (React.createElement(React.Fragment, null, React.createElement(Display, null), React.createElement("header", Object.assign({ role: "banner", id: id, className: cx(fr.cx("fr-header"), classes.root, className), ref: ref, style: style }, rest), React.createElement("div", { className: cx(fr.cx("fr-header__body"), classes.body) }, React.createElement("div", { className: cx(fr.cx("fr-container"), classes.container) }, React.createElement("div", { className: cx(fr.cx("fr-header__body-row"), classes.bodyRow) }, React.createElement("div", { className: cx(fr.cx("fr-header__brand", !hasOperatorLink && "fr-enlarge-link"), classes.brand) }, React.createElement("div", { className: cx(fr.cx("fr-header__brand-top"), classes.brandTop) }, React.createElement("div", { className: cx(fr.cx("fr-header__logo"), classes.logo) }, (() => { const children = (React.createElement("p", { className: fr.cx("fr-logo") }, brandTop)); return serviceTitle !== undefined ? (children) : (React.createElement(Link, Object.assign({}, homeLinkProps), children)); })()), operatorLogo !== undefined && (React.createElement("div", { className: cx(fr.cx("fr-header__operator", hasOperatorLink && "fr-enlarge-link"), classes.operator) }, (() => { const children = (React.createElement("img", { className: cx(fr.cx("fr-responsive-img"), classes.operator), style: (() => { switch (operatorLogo.orientation) { case "vertical": return { "width": "3.5rem" }; case "horizontal": return { "maxWidth": "9.0625rem" }; } })(), src: operatorLogo.imgUrl, alt: operatorLogo.alt })); return hasOperatorLink ? (React.createElement(Link, Object.assign({}, operatorLogo.linkProps), children)) : (children); })())), (quickAccessItems.length > 0 || navigation !== undefined || isSearchBarEnabled) && (React.createElement("div", { className: cx(fr.cx("fr-header__navbar"), classes.navbar) }, isSearchBarEnabled && (React.createElement("button", { id: `${id}-search-button`, className: fr.cx("fr-btn--search", "fr-btn"), "data-fr-opened": false, "aria-controls": searchModalId, title: tSearchBar("label") }, tSearchBar("label"))), React.createElement("button", { className: fr.cx("fr-btn--menu", "fr-btn"), "data-fr-opened": "false", "aria-controls": menuModalId, "aria-haspopup": "menu", id: menuButtonId, title: t("menu") }, t("menu"))))), serviceTitle !== undefined && (React.createElement("div", { className: cx(fr.cx("fr-header__service", hasOperatorLink && "fr-enlarge-link"), classes.service) }, React.createElement(Link, Object.assign({}, homeLinkProps), React.createElement("p", { className: cx(fr.cx("fr-header__service-title"), classes.serviceTitle) }, serviceTitle)), serviceTagline !== undefined && (React.createElement("p", { className: cx(fr.cx("fr-header__service-tagline"), classes.serviceTagline) }, serviceTagline))))), (quickAccessItems.length > 0 || isSearchBarEnabled) && (React.createElement("div", { className: fr.cx("fr-header__tools") }, quickAccessItems.length > 0 && (React.createElement("div", { className: cx(fr.cx("fr-header__tools-links"), classes.toolsLinks) }, getQuickAccessNode("desktop"))), isSearchBarEnabled && (React.createElement("div", { className: fr.cx("fr-header__search", "fr-modal"), id: searchModalId, "aria-labelledby": `${id}-search-bar-button` }, React.createElement("div", { className: fr.cx("fr-container", "fr-container-lg--fluid") }, React.createElement("button", { id: `${id}-search-close-button`, className: fr.cx("fr-btn--close", "fr-btn"), "aria-controls": searchModalId, title: t("close") }, t("close")), React.createElement("div", { className: fr.cx("fr-search-bar"), role: "search" }, React.createElement("label", { className: fr.cx("fr-label"), htmlFor: searchInputId }, tSearchBar("label")), (renderSearchInput !== null && renderSearchInput !== void 0 ? renderSearchInput : (({ className, id, placeholder, type }) => (React.createElement("input", { className: className, id: id, placeholder: placeholder, type: type }))))({ "className": fr.cx("fr-input"), "id": searchInputId, "placeholder": tSearchBar("label"), "type": "search" }), React.createElement(SearchButton, { id: `${id}-search-bar-button`, searchInputId: searchInputId, onClick: onSearchButtonClick, clearInputOnSearch: clearSearchInputOnSearch, allowEmptySearch: allowEmptySearch })))))))))), (navigation !== undefined || quickAccessItems.length !== 0) && (React.createElement("div", { className: cx(fr.cx("fr-header__menu", "fr-modal"), classes.menu), id: menuModalId, "aria-labelledby": menuButtonId }, React.createElement("div", { className: fr.cx("fr-container") }, React.createElement("button", { id: `${id}-mobile-overlay-button-close`, className: fr.cx("fr-btn--close", "fr-btn"), "aria-controls": menuModalId, title: t("close") }, t("close")), React.createElement("div", { className: cx(fr.cx("fr-header__menu-links"), classes.menuLinks) }, getQuickAccessNode("mobile")), navigation !== undefined && (navigation instanceof Array ? (React.createElement(MainNavigation, { id: `${id}-main-navigation`, items: navigation })) : (navigation)))))))); })); Header.displayName = symToStr({ Header }); export default Header; export const { useTranslation, addHeaderTranslations } = createComponentI18nApi({ "componentName": symToStr({ Header }), "frMessages": { /* spell-checker: disable */ "menu": "Menu", "close": "Fermer" /* spell-checker: enable */ } }); addHeaderTranslations({ "lang": "en", "messages": { "close": "Close" } }); /** NOTE: If you wrap this component you should forward the id */ export function HeaderQuickAccessItem(props) { const { className, quickAccessItem, id } = props; const { Link } = getLink(); return quickAccessItem.linkProps !== undefined ? (React.createElement(Link, Object.assign({}, quickAccessItem.linkProps, { className: cx(fr.cx("fr-btn", quickAccessItem.iconId), quickAccessItem.linkProps.className, className), id: id }), quickAccessItem.text)) : (React.createElement("button", Object.assign({}, quickAccessItem.buttonProps, { className: cx(fr.cx("fr-btn", quickAccessItem.iconId), quickAccessItem.buttonProps.className, className), id: id }), quickAccessItem.text)); } //# sourceMappingURL=Header.js.map