@shopgate/engage
Version:
Shopgate's ENGAGE library.
17 lines • 4.13 kB
JavaScript
var _excluded=["title","titleParams","children"];function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}function _slicedToArray(arr,i){return _arrayWithHoles(arr)||_iterableToArrayLimit(arr,i)||_nonIterableRest();}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance");}function _iterableToArrayLimit(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break;}}catch(err){_d=true;_e=err;}finally{try{if(!_n&&_i["return"]!=null)_i["return"]();}finally{if(_d)throw _e;}}return _arr;}function _arrayWithHoles(arr){if(Array.isArray(arr))return arr;}function _objectWithoutProperties(source,excluded){if(source==null)return{};var target=_objectWithoutPropertiesLoose(source,excluded);var key,i;if(Object.getOwnPropertySymbols){var sourceSymbolKeys=Object.getOwnPropertySymbols(source);for(i=0;i<sourceSymbolKeys.length;i++){key=sourceSymbolKeys[i];if(excluded.indexOf(key)>=0)continue;if(!Object.prototype.propertyIsEnumerable.call(source,key))continue;target[key]=source[key];}}return target;}function _objectWithoutPropertiesLoose(source,excluded){if(source==null)return{};var target={};var sourceKeys=Object.keys(source);var key,i;for(i=0;i<sourceKeys.length;i++){key=sourceKeys[i];if(excluded.indexOf(key)>=0)continue;target[key]=source[key];}return target;}import React,{useRef,useState,useMemo,useLayoutEffect}from'react';import PropTypes from'prop-types';import kebabCase from'lodash/kebabCase';import{I18n}from'@shopgate/engage/components';import VisuallyHidden from"../VisuallyHidden";/**
* Checks the section ref has suitable child nodes.
* @param {Object} ref A React ref.
* @param {string} headlineId The ID of the section headline.
* @returns {bool}
*/var hasChildNodes=function hasChildNodes(ref,headlineId){if(!ref.current){return false;}// Determine all child nodes except the headline.
var childNodes=[].filter.call(ref.current.childNodes,function(el){return el.getAttribute('id')!==headlineId;});return childNodes.length>0;};/**
* The Section component is supposed to be used to structure the content to improve a11y. It
* renders a headline on top which is only visible for screen readers and describes the section.
* Internally a MutationObserver maintains the visibility based on the presence of rendered content.
* @param {Object} props The component props.
* @param {string} props.title The section title - can be a placeholder.
* @param {Object} [props.titleParams={}] Additional parameters for the title placeholder.
* @param {Object} [props.className=null] A class name for the section.
* @param {NodeList} [props.children=null] Component children.
* @returns {JSX.Element}
*/function Section(props){var title=props.title,titleParams=props.titleParams,children=props.children,rest=_objectWithoutProperties(props,_excluded);var contentRef=useRef(null);var _useState=useState(false),_useState2=_slicedToArray(_useState,2),hasContent=_useState2[0],setHasContent=_useState2[1];var id=useMemo(function(){return kebabCase(title);},[title]);var observer=useMemo(function(){return new MutationObserver(function(){setHasContent(hasChildNodes(contentRef,id));});},[contentRef,id]);useLayoutEffect(function(){setHasContent(hasChildNodes(contentRef,id));observer.observe(contentRef.current,{childList:true});return function(){observer.disconnect();};},[contentRef,id,observer]);if(!hasContent){return React.createElement("section",_extends({},rest,{ref:contentRef}),children);}return React.createElement("section",_extends({},rest,{ref:contentRef,"aria-labelledby":id}),React.createElement(VisuallyHidden,null,React.createElement("h2",{id:id},React.createElement(I18n.Text,{string:title,params:titleParams}))),children);}Section.defaultProps={children:null,className:'',titleParams:{}};export default Section;