carbon-react
Version:
A library of reusable React components for easily building user interfaces.
2 lines (1 loc) • 4.28 kB
JavaScript
;Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime"),t=require("react"),n=require("./focus-trap-utils.js"),r=require("../modal/modal.context.js"),o=require("../../hooks/__internal__/usePrevious/index.js"),u=require("../../components/carbon-provider/__internal__/top-modal.context.js");function c(e){return e&&e.__esModule?e:{default:e}}var s=c(t);function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}const a="tab-guard-top",i="tab-guard-bottom";exports.TAB_GUARD_BOTTOM=i,exports.TAB_GUARD_TOP=a,exports.default=({children:c,autoFocus:d=!0,focusableSelectors:f,focusFirstElement:b,bespokeTrap:m,wrapperRef:v,isOpen:p,additionalWrapperRefs:E})=>{const O=t.useRef(null),[j,g]=t.useState(),{isAnimationComplete:x=!0,triggerRefocusFlag:y}=t.useContext(r.default),{topModal:h}=t.useContext(u.default),F=!h||v.current&&h.contains(v.current),S=t.useMemo((()=>(null==E?void 0:E.length)?[v,...E]:[v]),[E,v]),_=t.useMemo((()=>n.onTabGuardFocus(S,f,"top")),[f,S]),P=t.useMemo((()=>n.onTabGuardFocus(S,f,"bottom")),[f,S]);t.useEffect((()=>(null==E||E.forEach((e=>{const{current:t}=e;if(t){var n,r;if(!(null===(n=t.previousElementSibling)||void 0===n?void 0:n.matches(`[data-element=${a}]`))){const n=document.createElement("div");n.tabIndex=0,n.dataset.element=a,t.insertAdjacentElement("beforebegin",n),n.addEventListener("focus",_(e))}if(!(null===(r=t.nextElementSibling)||void 0===r?void 0:r.matches(`[data-element=${i}]`))){const n=document.createElement("div");n.tabIndex=0,n.dataset.element=i,t.insertAdjacentElement("afterend",n),n.addEventListener("focus",P(e))}}})),()=>{null==E||E.forEach((e=>{var t,n;const r=null===(t=e.current)||void 0===t?void 0:t.previousElementSibling;(null==r?void 0:r.matches(`[data-element=${a}]`))&&r.remove();const o=null===(n=e.current)||void 0===n?void 0:n.nextElementSibling;(null==o?void 0:o.matches(`[data-element=${i}]`))&&o.remove()}))})),[E,_,P]);const w=d&&p&&x,A=o.default(w),k=t.useCallback((e=>{const t=[];return S.forEach((n=>{n.current&&t.push(...Array.from(n.current.querySelectorAll(e)).filter((e=>-1!==Number(e.tabIndex))))})),t}),[S]);t.useEffect((()=>{if(w&&!A){const e=b&&"current"in b?b.current:b,t=k(n.defaultFocusableSelectors).find((e=>"true"===e.getAttribute("data-has-autofocus"))),r=e||t||v.current;r&&n.setElementFocus(r)}}),[w,A,k,b,v]),t.useEffect((()=>{const e=e=>{if(!F||!p)return;const t=k(n.defaultFocusableSelectors);n.trapFunction(e,t,document.activeElement===v.current,f,m)};return document.addEventListener("keydown",e,!0),function(){document.removeEventListener("keydown",e,!0)}}),[m,v,f,k,F,p]);const T=t.useCallback((()=>{const e=k(f||n.defaultFocusableSelectors),t=null==e?void 0:e.find((e=>e===document.activeElement));t&&g(t)}),[k,f]),q=t.useCallback((()=>{var e;if(j&&!j.hasAttribute("disabled"))n.setElementFocus(j);else if(null===(e=v.current)||void 0===e?void 0:e.hasAttribute("tabindex"))n.setElementFocus(v.current);else{const e=k(f||n.defaultFocusableSelectors);e.length&&n.setElementFocus(e[0])}}),[j,v,f,k]);t.useEffect((()=>{y&&q()}),[y,q]);const[C,I]=t.useState(0);t.useEffect((()=>{p||I(0)}),[p]);const M=()=>{p&&I(void 0)},D=e=>{return t=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},r=Object.keys(n);"function"==typeof Object.getOwnPropertySymbols&&(r=r.concat(Object.getOwnPropertySymbols(n).filter((function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable})))),r.forEach((function(t){l(e,t,n[t])}))}return e}({},e&&{tabIndex:C,onBlur:M}),n=null!=(n={onFocus:T})?n:{},Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):function(e){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t.push.apply(t,n)}return t}(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))})),t;var t,n},R=s.default.Children.map(c,(e=>{var t;const n=e;return s.default.cloneElement(n,D(void 0===(null==n||null===(t=n.props)||void 0===t?void 0:t.tabIndex)))}));return e.jsxs("div",{ref:O,children:[p&&e.jsx("div",{"data-element":a,tabIndex:0,onFocus:_(v)}),R,p&&e.jsx("div",{"data-element":i,tabIndex:0,onFocus:P(v)})]})};