@shopgate/engage
Version:
Shopgate's ENGAGE library.
37 lines • 3.29 kB
JavaScript
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;}import{useEffect,useState,useRef}from'react';import{useDispatch}from'react-redux';import{increaseModalCount,decreaseModalCount}from"../action-creators";/**
* The useReduceMotion hook
* to determine whether the user selected reduced motion in the phone settings
* @returns {boolean} whether the user prefers reduced motions in the settings
*/export var useReduceMotion=function useReduceMotion(){var _useState=useState(window.matchMedia('(prefers-reduced-motion: reduce)').matches),_useState2=_slicedToArray(_useState,2),matches=_useState2[0],setMatch=_useState2[1];useEffect(function(){var mq=window.matchMedia('(prefers-reduced-motion: reduce)');// eslint-disable-next-line require-jsdoc
var handleChange=function handleChange(){setMatch(mq.matches);};handleChange();mq.addEventListener('change',handleChange);return function(){mq.removeEventListener('change',handleChange);};},[]);return matches;};/**
* Tracks when a modal-like component is considered "visible", and dispatches Redux
* actions accordingly. This is useful for global tracking of visible overlays,
* modals, drawers, or any component with a similar behavior.
*
* Dispatches `increaseModalCount()` when the component becomes visible
* Dispatches `decreaseModalCount()` when the component becomes hidden
* Dispatches `decreaseModalCount()` on unmount if the component was still visible
*
* Call this hook inside any modal like component that:
* - Mounts/unmounts based on visibility (like a modal or tooltip)
* - OR uses a visibility prop (e.g. `isVisible`)
*
* @param {boolean} isVisible Optional visibility flag.
* If omitted, visibility is assumed `true` while mounted.
*
* @example
* // Component that uses isVisible prop
* function MyModal({ isVisible }) {
* useTrackModalState(isVisible);
* return <div className="my_modal">...</div>;
* }
*
* @example
* // Component that appears/disappears via mounting
* function MyModal() {
* useTrackModalState(); // defaults to `true`
* return <div className="tooltip">Hello!</div>;
* }
*/export function useTrackModalState(){var isVisible=arguments.length>0&&arguments[0]!==undefined?arguments[0]:true;var dispatch=useDispatch();var wasVisible=useRef(false);// React to changes in visibility
useEffect(function(){if(isVisible&&!wasVisible.current){dispatch(increaseModalCount());wasVisible.current=true;}else if(!isVisible&&wasVisible.current){dispatch(decreaseModalCount());wasVisible.current=false;}},[isVisible,dispatch]);// On unmount, dispatch hide if it was still visible
useEffect(function(){return function(){if(wasVisible.current){dispatch(decreaseModalCount());wasVisible.current=false;}};},[dispatch]);}