@xo-union/tk-component-header-nav
Version:
235 lines • 7.69 kB
JavaScript
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 };