UNPKG

@xo-union/tk-component-header-nav

Version:
235 lines • 7.69 kB
import _extends from "@babel/runtime-corejs3/helpers/esm/extends"; import _mapInstanceProperty from "@babel/runtime-corejs3/core-js/instance/map"; import _Object$entries from "@babel/runtime-corejs3/core-js/object/entries"; import React from "react"; import PropTypes from "prop-types"; import cx from "classnames"; import colors from "@xo-union/tk-ui-colors/lib/variables.css"; import { useMobileMedia } from "@xo-union/tk-ui-breakpoints"; import { Column, Row } from "@xo-union/tk-component-grid"; import { Skeleton, Bone } from "@xo-union/tk-ui-skeleton"; import { Picture, Source, Img } from "@xo-union/tk-component-picture"; import { Body2 } from "@xo-union/tk-ui-typography"; import { compose } from "@xo-union/react-css-modules"; import { useMegaMenuID, useMegaMenuLayout } from "./MegaMenuCore.js"; import { useHeaderNavContext } from "../Context.js"; import Link from "../Link/index.js"; import { MenuAside } from "./MenuSections.js"; const FeaturedSectionRow = _ref => { let { children, ...props } = _ref; const { classes } = useHeaderNavContext(); return /*#__PURE__*/React.createElement(Row, _extends({ classes: compose({ row: classes['featured-section-row'] }) }, props), children); }; process.env.NODE_ENV !== "production" ? FeaturedSectionRow.propTypes = { children: PropTypes.node } : void 0; const FeaturedSection = _ref2 => { var _context; let { headingContent, sponsored = true, children, className, isLoading = false, rowAs = 'ul' } = _ref2; const layout = useMegaMenuLayout(); const { alignSectionsBreakpoint, featuredSection: { unitSize, numberOfColumns, containerColumnProps } } = layout; const menuID = useMegaMenuID(); const { classes } = useHeaderNavContext(); const featuredSectionLabelId = `${menuID}-featured-section-heading`; const loadingLabel = /*#__PURE__*/React.createElement(Skeleton, { "aria-label": "Loading section..." }, /*#__PURE__*/React.createElement(Bone, { className: classes['bone-basic'] })); const loadedLabel = /*#__PURE__*/React.createElement("div", { className: cx(sponsored ? classes['sponsored-featured-section-label'] : classes['featured-section-label']), id: featuredSectionLabelId, role: "heading", "aria-level": "1" }, headingContent); const rightAlignedClass = `featured-section-right-aligned-${alignSectionsBreakpoint}`; if (containerColumnProps[alignSectionsBreakpoint] === undefined) { throw new Error(`[${menuID}] Featured section has to shrink at the alignedSectionsBreakpoint so that both sections fit together.`); } return /*#__PURE__*/React.createElement(Column, containerColumnProps, /*#__PURE__*/React.createElement("div", { className: classes['featured-section'] }, /*#__PURE__*/React.createElement(MenuAside, { "aria-labelledby": featuredSectionLabelId, "data-trackable-context-section": "featured", className: cx(sponsored && classes['sponsored-featured-section'], classes['featured-section-core'], ..._mapInstanceProperty(_context = _Object$entries(numberOfColumns || {})).call(_context, _ref3 => { let [breakpoint, columnCount] = _ref3; const key = `featured-section-${breakpoint}-${columnCount}-columns`; return key in classes && classes[key]; }), (unitSize === 'lg' || unitSize === 'xl') && classes['featured-section-size-lg'], unitSize === 'sm' && classes['featured-section-size-sm'], classes[rightAlignedClass], className) }, isLoading ? loadingLabel : loadedLabel, /*#__PURE__*/React.createElement(FeaturedSectionRow, { as: rowAs }, children)))); }; process.env.NODE_ENV !== "production" ? FeaturedSection.propTypes = { headingContent: PropTypes.node, sponsored: PropTypes.bool, children: PropTypes.node, className: PropTypes.string, isLoading: PropTypes.bool, rowAs: PropTypes.elementType } : void 0; FeaturedSection.defaultProps = { rowAs: 'ul', sponsored: false, isLoading: false }; const smallCardImageSizes = { xs: { width: 124, height: 114 }, md: { width: 144, height: 132 } }; const largeCardImageSizes = { xs: { width: 260, height: 124 }, md: { width: 310, height: 148 } }; const extraLargeCardImageSizes = { xs: { width: 260, height: 195 }, md: { width: 310, height: 232 } }; const LoadingPlaceholder = _ref4 => { let { width, height } = _ref4; return /*#__PURE__*/React.createElement(Skeleton, { "aria-label": "Loading section..." }, /*#__PURE__*/React.createElement(Bone, { style: { height: `${height}px`, width: `${width}px`, borderRadius: '8px', border: `1px solid var(--tkww-union-header-nav-mega-menu-featured-border-color, ${colors.varBorderDefault})`, display: 'inline-block' } })); }; process.env.NODE_ENV !== "production" ? LoadingPlaceholder.propTypes = { width: PropTypes.number, height: PropTypes.number } : void 0; const FeaturedUnitCard = props => { const { classes } = useHeaderNavContext(); const [isImageLoaded, setIsImageLoaded] = React.useState(false); const { linkUrl, imageId: imageMediaID, copy, linkProps, as: ElementType = 'li', subtleBorder, boldCopy = false, alt = copy } = props; const { featuredSection } = useMegaMenuLayout(); let sizes; if (featuredSection.unitSize === 'sm') { sizes = smallCardImageSizes; } if (featuredSection.unitSize === 'lg') { sizes = largeCardImageSizes; } if (featuredSection.unitSize === 'xl') { sizes = extraLargeCardImageSizes; } if (!sizes) { throw new Error('featuredSection.unitSize in layout not configured correctly'); } if (typeof alt !== 'string' || alt.length === 0) { throw new Error('Please pass a string `alt` with some content'); } const copyIsAriaHidden = copy === alt; const mobileMedia = useMobileMedia(); const isMobile = mobileMedia.yes; return /*#__PURE__*/React.createElement(ElementType, { className: classes['featured-section-unit'] }, /*#__PURE__*/React.createElement(Link, _extends({ className: classes['featured-card-link'], href: linkUrl }, linkProps), !isImageLoaded && isMobile && /*#__PURE__*/React.createElement(LoadingPlaceholder, { width: sizes.xs.width, height: sizes.xs.height }), !isImageLoaded && !isMobile && /*#__PURE__*/React.createElement(LoadingPlaceholder, { width: sizes.md.width, height: sizes.md.height }), /*#__PURE__*/React.createElement(Picture, { id: imageMediaID, lazy: true }, /*#__PURE__*/React.createElement(Source, { viewport: "md", width: sizes.md.width, height: sizes.md.height }), /*#__PURE__*/React.createElement(Source, { viewport: "xs", width: sizes.xs.width, height: sizes.xs.height }), /*#__PURE__*/React.createElement(Img, { className: cx(subtleBorder && classes['featured-card-image-subtle-border'], !isImageLoaded && classes['featured-card-image-loading']), width: sizes.md.width, height: sizes.md.height, alt: alt, onLoad: () => { setIsImageLoaded(true); } })), copy && /*#__PURE__*/React.createElement(Body2, { className: classes['featured-card-copy'], "aria-hidden": copyIsAriaHidden ? 'true' : null, bold: boldCopy }, copy))); }; process.env.NODE_ENV !== "production" ? FeaturedUnitCard.propTypes = { subtleBorder: PropTypes.bool, boldCopy: PropTypes.bool, as: PropTypes.elementType, linkUrl: PropTypes.string, imageId: PropTypes.string, copy: PropTypes.node, alt: PropTypes.string, linkProps: PropTypes.shape() } : void 0; export { FeaturedSection, FeaturedUnitCard };