UNPKG

@carbon/react

Version:

React components for the Carbon Design System

661 lines (648 loc) 26.5 kB
/** * Copyright IBM Corp. 2016, 2023 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js'); var React = require('react'); var PropTypes = require('prop-types'); var cx = require('classnames'); var iconsReact = require('@carbon/icons-react'); var Link = require('../Link/Link.js'); var keys = require('../../internal/keyboard/keys.js'); var match = require('../../internal/keyboard/match.js'); var deprecate = require('../../prop-types/deprecate.js'); var events = require('../../tools/events.js'); var usePrefix = require('../../internal/usePrefix.js'); var useIsomorphicEffect = require('../../internal/useIsomorphicEffect.js'); var useNoInteractiveChildren = require('../../internal/useNoInteractiveChildren.js'); var useMergedRefs = require('../../internal/useMergedRefs.js'); var index = require('../FeatureFlags/index.js'); var useId = require('../../internal/useId.js'); require('../Text/index.js'); var index$1 = require('../AILabel/index.js'); var utils = require('../../internal/utils.js'); var Text = require('../Text/Text.js'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var React__default = /*#__PURE__*/_interopDefaultLegacy(React); var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes); var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx); var _CheckboxCheckedFille, _Checkbox, _ChevronDown, _ChevronDown2; const Tile = /*#__PURE__*/React__default["default"].forwardRef(function Tile({ children, className, decorator, light = false, slug, hasRoundedCorners = false, ...rest }, ref) { const prefix = usePrefix.usePrefix(); const tileClasses = cx__default["default"](`${prefix}--tile`, { [`${prefix}--tile--light`]: light, [`${prefix}--tile--slug`]: slug, [`${prefix}--tile--slug-rounded`]: slug && hasRoundedCorners, [`${prefix}--tile--decorator`]: decorator, [`${prefix}--tile--decorator-rounded`]: decorator && hasRoundedCorners }, className); return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({ className: tileClasses, ref: ref }, rest), children, slug, decorator && /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--tile--inner-decorator` }, decorator)); }); Tile.displayName = 'Tile'; Tile.propTypes = { /** * The child nodes. */ children: PropTypes__default["default"].node, /** * The CSS class names. */ className: PropTypes__default["default"].string, /** * **Experimental**: Provide a `decorator` component to be rendered inside the `Tile` component */ decorator: PropTypes__default["default"].node, /** * **Experimental**: Specify if the `Tile` component should be rendered with rounded corners. Only valid * when an AILabel is present */ hasRoundedCorners: PropTypes__default["default"].bool, /** * `true` to use the light version. For use on $ui-01 backgrounds only. * Don't use this to make tile background color same as container background color. * * @deprecated */ light: deprecate["default"](PropTypes__default["default"].bool, 'The `light` prop for `Tile` is no longer needed and has been deprecated. It will be removed in the next major release. Use the Layer component instead.'), /** * **Experimental**: Provide a `Slug` component to be rendered inside the `Tile` component */ slug: deprecate["default"](PropTypes__default["default"].node, 'The `slug` prop for `Tile` has ' + 'been deprecated in favor of the new `decorator` prop. It will be removed in the next major release.') }; const ClickableTile = /*#__PURE__*/React__default["default"].forwardRef(function ClickableTile({ children, className, clicked = false, decorator, disabled, href, light, onClick = () => {}, onKeyDown = () => {}, renderIcon: Icon, hasRoundedCorners, slug, ...rest }, ref) { const prefix = usePrefix.usePrefix(); const classes = cx__default["default"](`${prefix}--tile`, `${prefix}--tile--clickable`, { [`${prefix}--tile--is-clicked`]: clicked, [`${prefix}--tile--light`]: light, [`${prefix}--tile--slug`]: slug, [`${prefix}--tile--slug-rounded`]: slug && hasRoundedCorners, [`${prefix}--tile--decorator`]: decorator, [`${prefix}--tile--decorator-rounded`]: decorator && hasRoundedCorners }, className); const [isSelected, setIsSelected] = React.useState(clicked); function handleOnClick(evt) { evt?.persist?.(); setIsSelected(!isSelected); onClick(evt); } function handleOnKeyDown(evt) { evt?.persist?.(); if (match.matches(evt, [keys.Enter, keys.Space])) { setIsSelected(!isSelected); } onKeyDown(evt); } const v12DefaultIcons = index.useFeatureFlag('enable-v12-tile-default-icons'); if (v12DefaultIcons) { if (!Icon) { Icon = iconsReact.ArrowRight; } if (disabled) { Icon = iconsReact.Error; } } const iconClasses = cx__default["default"]({ [`${prefix}--tile--icon`]: !v12DefaultIcons || v12DefaultIcons && !disabled, [`${prefix}--tile--disabled-icon`]: v12DefaultIcons && disabled }); return /*#__PURE__*/React__default["default"].createElement(Link["default"], _rollupPluginBabelHelpers["extends"]({ className: classes, href: href, tabIndex: !href && !disabled ? 0 : undefined, onClick: !disabled ? handleOnClick : undefined, onKeyDown: handleOnKeyDown, ref: ref, disabled: disabled }, rest), slug || decorator ? /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--tile-content` }, children) : children, (slug === true || decorator === true) && /*#__PURE__*/React__default["default"].createElement(iconsReact.AiLabel, { size: "24", className: `${prefix}--tile--ai-label-icon` }), /*#__PURE__*/React__default["default"].isValidElement(decorator) && /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--tile--inner-decorator` }, decorator), Icon && /*#__PURE__*/React__default["default"].createElement(Icon, { className: iconClasses, "aria-hidden": "true" })); }); ClickableTile.displayName = 'ClickableTile'; ClickableTile.propTypes = { /** * The child nodes. */ children: PropTypes__default["default"].node, /** * The CSS class names. */ className: PropTypes__default["default"].string, /** * Boolean for whether a tile has been clicked. */ clicked: PropTypes__default["default"].bool, /** * **Experimental**: Provide a `decorator` component or set the boolean to True for an AILabel icon to be rendered inside the `ClickableTile` component */ decorator: PropTypes__default["default"].oneOfType([PropTypes__default["default"].bool, PropTypes__default["default"].node]), /** * Specify whether the ClickableTile should be disabled */ disabled: PropTypes__default["default"].bool, /** * **Experimental**: Specify if the `ClickableTile` component should be rendered with rounded corners. * Only valid when `slug` prop is present */ hasRoundedCorners: PropTypes__default["default"].bool, /** * The href for the link. */ href: PropTypes__default["default"].string, /** * `true` to use the light version. For use on $ui-01 backgrounds only. * Don't use this to make tile background color same as container background color. */ light: deprecate["default"](PropTypes__default["default"].bool, 'The `light` prop for `ClickableTile` is no longer needed and has been deprecated. It will be removed in the next major release. Use the Layer component instead.'), /** * Specify the function to run when the ClickableTile is clicked */ onClick: PropTypes__default["default"].func, /** * Specify the function to run when the ClickableTile is interacted with via a keyboard */ onKeyDown: PropTypes__default["default"].func, /** * The rel property for the link. */ rel: PropTypes__default["default"].string, /** * A component used to render an icon. */ renderIcon: PropTypes__default["default"].oneOfType([PropTypes__default["default"].func, PropTypes__default["default"].object]) }; const SelectableTile = /*#__PURE__*/React__default["default"].forwardRef(function SelectableTile({ children, className, decorator, disabled, id, light, onClick = () => {}, onChange = () => {}, onKeyDown = () => {}, selected = false, tabIndex = 0, title = 'title', slug, hasRoundedCorners, ...rest }, ref) { const prefix = usePrefix.usePrefix(); const clickHandler = onClick; const keyDownHandler = onKeyDown; const [isSelected, setIsSelected] = React.useState(selected); // Use useEffect to sync with prop changes instead of render-time logic React.useEffect(() => { setIsSelected(selected); }, [selected]); const classes = cx__default["default"](`${prefix}--tile`, `${prefix}--tile--selectable`, { [`${prefix}--tile--is-selected`]: isSelected, [`${prefix}--tile--light`]: light, [`${prefix}--tile--disabled`]: disabled, [`${prefix}--tile--slug`]: slug, [`${prefix}--tile--slug-rounded`]: slug && hasRoundedCorners, [`${prefix}--tile--decorator`]: decorator, [`${prefix}--tile--decorator-rounded`]: decorator && hasRoundedCorners }, className); // Single function to handle selection changes const handleSelectionChange = React.useCallback((evt, newSelected) => { setIsSelected(newSelected); onChange(evt, newSelected, id); }, [onChange, id]); function handleClick(evt) { evt.preventDefault(); evt?.persist?.(); if (normalizedDecorator && decoratorRef.current && evt.target instanceof Node && decoratorRef.current.contains(evt.target)) { return; } const newSelected = !isSelected; handleSelectionChange(evt, newSelected); clickHandler(evt); } function handleKeyDown(evt) { evt?.persist?.(); if (match.matches(evt, [keys.Enter, keys.Space])) { evt.preventDefault(); const newSelected = !isSelected; handleSelectionChange(evt, newSelected); } keyDownHandler(evt); } // AILabel is always size `xs` const decoratorRef = React.useRef(null); const candidate = slug ?? decorator; const candidateIsAILabel = utils.isComponentElement(candidate, index$1.AILabel); const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/React.cloneElement(candidate, { size: 'xs', ref: decoratorRef }) : null; return ( /*#__PURE__*/ // eslint-disable-next-line jsx-a11y/interactive-supports-focus React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({ className: classes, onClick: !disabled ? handleClick : undefined, role: "checkbox", "aria-checked": isSelected, onKeyDown: !disabled ? handleKeyDown : undefined // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex , tabIndex: !disabled ? tabIndex : undefined, ref: ref, id: id, title: title }, rest), /*#__PURE__*/React__default["default"].createElement("span", { className: `${prefix}--tile__checkmark ${prefix}--tile__checkmark--persistent` }, isSelected ? _CheckboxCheckedFille || (_CheckboxCheckedFille = /*#__PURE__*/React__default["default"].createElement(iconsReact.CheckboxCheckedFilled, null)) : _Checkbox || (_Checkbox = /*#__PURE__*/React__default["default"].createElement(iconsReact.Checkbox, null))), /*#__PURE__*/React__default["default"].createElement(Text.Text, { as: "label", htmlFor: id, className: `${prefix}--tile-content` }, children), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--tile--inner-decorator` }, normalizedDecorator) : '') ); }); SelectableTile.propTypes = { children: PropTypes__default["default"].node, className: PropTypes__default["default"].string, /** * **Experimental**: Provide a `decorator` component to be rendered inside the `SelectableTile` component */ decorator: PropTypes__default["default"].node, /** * Specify whether the SelectableTile should be disabled */ disabled: PropTypes__default["default"].bool, /** * **Experimental**: Specify if the `SelectableTile` component should be rendered with rounded corners. * Only valid when `slug` prop is present */ hasRoundedCorners: PropTypes__default["default"].bool, /** * The ID of the `<input>`. */ id: PropTypes__default["default"].string, /** * `true` to use the light version. For use on $ui-01 backgrounds only. * Don't use this to make tile background color same as container background color. */ light: deprecate["default"](PropTypes__default["default"].bool, 'The `light` prop for `SelectableTile` is no longer needed and has been deprecated. It will be removed in the next major release. Use the Layer component instead.'), /** * The `name` of the `<input>`. * @deprecated */ name: deprecate["default"](PropTypes__default["default"].string, 'The `name` property is no longer used. It will be removed in the next major release.'), /** * The empty handler of the `<input>`. */ onChange: PropTypes__default["default"].func, /** * Specify the function to run when the SelectableTile is clicked */ onClick: PropTypes__default["default"].func, /** * Specify the function to run when the SelectableTile is interacted with via a keyboard */ onKeyDown: PropTypes__default["default"].func, /** * `true` to select this tile. */ selected: PropTypes__default["default"].bool, /** * **Experimental**: Provide a `Slug` component to be rendered inside the `SelectableTile` component */ slug: deprecate["default"](PropTypes__default["default"].node, 'The `slug` prop for `SelectableTile` has ' + 'been deprecated in favor of the new `decorator` prop. It will be removed in the next major release.'), /** * Specify the tab index of the wrapper element */ tabIndex: PropTypes__default["default"].number, /** * The `title` of the `<input>`. */ title: PropTypes__default["default"].string, /** * The value of the `<input>`. * @deprecated */ value: deprecate["default"](PropTypes__default["default"].oneOfType([PropTypes__default["default"].string, PropTypes__default["default"].number]), 'The `value` property is no longer used. It will be removed in the next major release.`') }; const ExpandableTile = /*#__PURE__*/React__default["default"].forwardRef(function ExpandableTile({ tabIndex = 0, className, children, decorator, expanded = false, tileMaxHeight = 0, // eslint-disable-line tilePadding = 0, // eslint-disable-line onClick, onKeyUp, tileCollapsedIconText = 'Interact to expand Tile', tileExpandedIconText = 'Interact to collapse Tile', tileCollapsedLabel, tileExpandedLabel, light, slug, hasRoundedCorners, ...rest }, forwardRef) { const [isTileMaxHeight, setIsTileMaxHeight] = React.useState(tileMaxHeight); const [isTilePadding, setIsTilePadding] = React.useState(tilePadding); const [prevExpanded, setPrevExpanded] = React.useState(expanded); const [prevTileMaxHeight, setPrevTileMaxHeight] = React.useState(tileMaxHeight); const [prevTilePadding, setPrevTilePadding] = React.useState(tilePadding); const [isExpanded, setIsExpanded] = React.useState(expanded); const [interactive, setInteractive] = React.useState(true); const aboveTheFold = React.useRef(null); const belowTheFold = React.useRef(null); const chevronInteractiveRef = React.useRef(null); const tileContent = React.useRef(null); const tile = React.useRef(null); const ref = useMergedRefs.useMergedRefs([forwardRef, tile]); const prefix = usePrefix.usePrefix(); if (expanded !== prevExpanded) { setIsExpanded(expanded); setPrevExpanded(expanded); setMaxHeight(); } if (tileMaxHeight !== prevTileMaxHeight) { setIsTileMaxHeight(tileMaxHeight); setPrevTileMaxHeight(tileMaxHeight); } if (tilePadding !== prevTilePadding) { setIsTilePadding(tilePadding); setPrevTilePadding(tilePadding); } function setMaxHeight() { if (isExpanded && tileContent.current) { setIsTileMaxHeight(tileContent.current.getBoundingClientRect()?.height); } if (aboveTheFold.current) { setIsTileMaxHeight(aboveTheFold.current.getBoundingClientRect().height); } } function handleClick(evt) { evt?.persist?.(); setIsExpanded(!isExpanded); setMaxHeight(); } function handleKeyUp(evt) { if (evt.target !== tile.current && evt.target !== chevronInteractiveRef.current) { if (match.matches(evt, [keys.Enter, keys.Space])) { evt.preventDefault(); } } } function getChildren() { return React__default["default"].Children.toArray(children); } const classNames = cx__default["default"](`${prefix}--tile`, `${prefix}--tile--expandable`, { [`${prefix}--tile--is-expanded`]: isExpanded, [`${prefix}--tile--light`]: light }, className); const interactiveClassNames = cx__default["default"](`${prefix}--tile`, `${prefix}--tile--expandable`, `${prefix}--tile--expandable--interactive`, { [`${prefix}--tile--is-expanded`]: isExpanded, [`${prefix}--tile--light`]: light, [`${prefix}--tile--slug`]: slug, [`${prefix}--tile--slug-rounded`]: slug && hasRoundedCorners, [`${prefix}--tile--decorator`]: decorator, [`${prefix}--tile--decorator-rounded`]: decorator && hasRoundedCorners }, className); const chevronInteractiveClassNames = cx__default["default"](`${prefix}--tile__chevron`, `${prefix}--tile__chevron--interactive`); const childrenAsArray = getChildren(); useIsomorphicEffect["default"](() => { if (!tile.current || !aboveTheFold.current) { return; } const getStyle = window.getComputedStyle(tile.current, null); const { current: node } = aboveTheFold; const { height } = node.getBoundingClientRect(); const paddingTop = parseInt(getStyle.getPropertyValue('padding-top'), 10); const paddingBottom = parseInt(getStyle.getPropertyValue('padding-bottom'), 10); setIsTileMaxHeight(height); setIsTilePadding(paddingTop + paddingBottom); }, [isTileMaxHeight]); useIsomorphicEffect["default"](() => { if (!aboveTheFold.current || !belowTheFold.current) { return; } // Interactive elements or elements that are given a role should be treated // the same because elements with a role can not be rendered inside a `button` if (!useNoInteractiveChildren.getInteractiveContent(belowTheFold.current) && !useNoInteractiveChildren.getRoleContent(belowTheFold.current) && !useNoInteractiveChildren.getInteractiveContent(aboveTheFold.current) && !useNoInteractiveChildren.getRoleContent(aboveTheFold.current) && !(slug || decorator)) { setInteractive(false); } }, [slug, decorator]); useIsomorphicEffect["default"](() => { if (!tile.current) { return; } if (isExpanded) { tile.current.style.maxHeight = ''; } else { tile.current.style.maxHeight = isTileMaxHeight + isTilePadding + 'px'; } }, [isExpanded, isTileMaxHeight, isTilePadding]); React.useEffect(() => { if (!aboveTheFold.current) { return; } const resizeObserver = new ResizeObserver(entries => { const [aboveTheFold] = entries; setIsTileMaxHeight(aboveTheFold.contentRect.height); }); resizeObserver.observe(aboveTheFold.current); return () => resizeObserver.disconnect(); }, []); const belowTheFoldId = useId.useId('expandable-tile-interactive'); // AILabel is always size `xs` const candidate = slug ?? decorator; const candidateIsAILabel = utils.isComponentElement(candidate, index$1.AILabel); const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/React.cloneElement(candidate, { size: 'xs' }) : null; return interactive ? /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({ ref: ref, className: interactiveClassNames }, rest), /*#__PURE__*/React__default["default"].createElement("div", { ref: tileContent }, slug ? normalizedDecorator : decorator ? /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--tile--inner-decorator` }, normalizedDecorator) : '', /*#__PURE__*/React__default["default"].createElement("div", { ref: aboveTheFold, className: `${prefix}--tile-content` }, childrenAsArray[0]), /*#__PURE__*/React__default["default"].createElement("button", { type: "button", "aria-expanded": isExpanded, "aria-controls": belowTheFoldId, onKeyUp: events.composeEventHandlers([onKeyUp, handleKeyUp]), onClick: events.composeEventHandlers([onClick, handleClick]), "aria-label": isExpanded ? tileExpandedIconText : tileCollapsedIconText, ref: chevronInteractiveRef, className: chevronInteractiveClassNames }, _ChevronDown || (_ChevronDown = /*#__PURE__*/React__default["default"].createElement(iconsReact.ChevronDown, null))), /*#__PURE__*/React__default["default"].createElement("div", { ref: belowTheFold, className: `${prefix}--tile-content`, id: belowTheFoldId }, childrenAsArray[1]))) : /*#__PURE__*/React__default["default"].createElement("button", _rollupPluginBabelHelpers["extends"]({ type: "button", ref: ref, className: classNames, "aria-expanded": isExpanded, title: isExpanded ? tileExpandedIconText : tileCollapsedIconText }, rest, { onKeyUp: events.composeEventHandlers([onKeyUp, handleKeyUp]), onClick: events.composeEventHandlers([onClick, handleClick]), tabIndex: tabIndex }), /*#__PURE__*/React__default["default"].createElement("div", { ref: tileContent }, /*#__PURE__*/React__default["default"].createElement("div", { ref: aboveTheFold, className: `${prefix}--tile-content` }, childrenAsArray[0]), /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--tile__chevron` }, /*#__PURE__*/React__default["default"].createElement("span", null, isExpanded ? tileExpandedLabel : tileCollapsedLabel), _ChevronDown2 || (_ChevronDown2 = /*#__PURE__*/React__default["default"].createElement(iconsReact.ChevronDown, null))), /*#__PURE__*/React__default["default"].createElement("div", { ref: belowTheFold, className: `${prefix}--tile-content` }, childrenAsArray[1]))); }); ExpandableTile.propTypes = { children: PropTypes__default["default"].node, className: PropTypes__default["default"].string, /** * **Experimental**: Provide a `decorator` component to be rendered inside the `ExpandableTile` component */ decorator: PropTypes__default["default"].node, /** * `true` if the tile is expanded. */ expanded: PropTypes__default["default"].bool, /** * Specify if the `ExpandableTile` component should be rendered with rounded corners. * Only valid when `slug` prop is present */ hasRoundedCorners: PropTypes__default["default"].bool, /** * An ID that can be provided to aria-labelledby */ id: PropTypes__default["default"].string, /** * `true` to use the light version. For use on $ui-01 backgrounds only. * Don't use this to make tile background color same as container background color. */ light: deprecate["default"](PropTypes__default["default"].bool, 'The `light` prop for `ExpandableTile` is no longer needed and has been deprecated. It will be removed in the next major release. Use the Layer component instead.'), /** * Specify the function to run when the ExpandableTile is clicked */ onClick: PropTypes__default["default"].func, /** * optional handler to trigger a function when a key is pressed */ onKeyUp: PropTypes__default["default"].func, /** * **Experimental**: Provide a `Slug` component to be rendered inside the `ExpandableTile` component */ slug: deprecate["default"](PropTypes__default["default"].node, 'The `slug` prop for `ExpandableTile` has ' + 'been deprecated in favor of the new `decorator` prop. It will be removed in the next major release.'), /** * The `tabindex` attribute. */ tabIndex: PropTypes__default["default"].number, /** * The description of the "collapsed" icon that can be read by screen readers. */ tileCollapsedIconText: PropTypes__default["default"].string, /** * When "collapsed", a label to appear next to the chevron (e.g., "View more"). */ tileCollapsedLabel: PropTypes__default["default"].string, /** * The description of the "expanded" icon that can be read by screen readers. */ tileExpandedIconText: PropTypes__default["default"].string, /** * When "expanded", a label to appear next to the chevron (e.g., "View less"). */ tileExpandedLabel: PropTypes__default["default"].string }; ExpandableTile.displayName = 'ExpandableTile'; const TileAboveTheFoldContent = /*#__PURE__*/React__default["default"].forwardRef(function TilAboveTheFoldContent({ children }, ref) { const prefix = usePrefix.usePrefix(); return /*#__PURE__*/React__default["default"].createElement("div", { ref: ref, className: `${prefix}--tile-content__above-the-fold` }, children); }); TileAboveTheFoldContent.propTypes = { /** * The child nodes. */ children: PropTypes__default["default"].node }; TileAboveTheFoldContent.displayName = 'TileAboveTheFoldContent'; const TileBelowTheFoldContent = /*#__PURE__*/React__default["default"].forwardRef(function TileBelowTheFoldContent({ children }, ref) { const prefix = usePrefix.usePrefix(); return /*#__PURE__*/React__default["default"].createElement("div", { ref: ref, className: `${prefix}--tile-content__below-the-fold` }, children); }); TileBelowTheFoldContent.propTypes = { /** * The child nodes. */ children: PropTypes__default["default"].node }; TileBelowTheFoldContent.displayName = 'TileBelowTheFoldContent'; exports.ClickableTile = ClickableTile; exports.ExpandableTile = ExpandableTile; exports.SelectableTile = SelectableTile; exports.Tile = Tile; exports.TileAboveTheFoldContent = TileAboveTheFoldContent; exports.TileBelowTheFoldContent = TileBelowTheFoldContent;