@spectrum-web-components/overlay
Version:
An `<sp-overlay>` element is used to decorate content that you would like to present to your visitors as "overlaid" on the rest of the application. This includes dialogs (modal and not), pickers, tooltips, context menus, et al.
3 lines (2 loc) • 3.39 kB
JavaScript
"use strict";const c="showPopover"in document.createElement("div");class d{constructor(){this.root=document.body;this.stack=[];this.originalBodyOverflow="";this.bodyScrollBlocked=!1;this.handleScroll=t=>{t.target!==document&&t.target!==document.documentElement&&t.target!==document.body||this.stack.forEach(e=>{e.open&&(e.type==="auto"&&e.triggerElement instanceof HTMLElement&&e.triggerElement.closest("sp-picker, sp-action-menu")&&t.stopPropagation(),document.dispatchEvent(new CustomEvent("sp-update-overlays",{bubbles:!0,composed:!0,cancelable:!0})))})};this.handlePointerdown=t=>{this.pointerdownPath=t.composedPath(),this.lastOverlay=this.stack[this.stack.length-1]};this.handlePointerup=()=>{const t=this.pointerdownPath;if(this.pointerdownPath=void 0,!this.stack.length||!(t!=null&&t.length))return;const e=this.lastOverlay;this.lastOverlay=void 0;const s=this.stack.length-1,o=this.stack.filter((n,i)=>!t.find(r=>r===n||r===(n==null?void 0:n.triggerElement)&&(n==null?void 0:n.type)==="hint"||i===s&&n!==e&&n.triggerInteraction==="longpress")&&!n.shouldPreventClose()&&n.type!=="manual"&&!(n.type==="modal"&&e!==n));o.reverse(),o.forEach(n=>{this.closeOverlay(n);let i=n.parentOverlayToForceClose;for(;i;)this.closeOverlay(i),i=i.parentOverlayToForceClose})};this.handleBeforetoggle=t=>{const{target:e,newState:s}=t;s!=="open"&&this.closeOverlay(e)};this.handleKeydown=t=>{if(t.code!=="Escape"||!this.stack.length)return;const e=this.stack[this.stack.length-1];if((e==null?void 0:e.type)==="page"){t.preventDefault();return}if((e==null?void 0:e.type)==="manual"){this.closeOverlay(e);return}c||e&&this.closeOverlay(e)};this.bindEvents()}get document(){return this.root.ownerDocument||document}bindEvents(){this.document.addEventListener("pointerdown",this.handlePointerdown),this.document.addEventListener("pointerup",this.handlePointerup),this.document.addEventListener("keydown",this.handleKeydown),this.document.addEventListener("scroll",this.handleScroll,{capture:!0})}closeOverlay(t){const e=this.stack.indexOf(t);e>-1&&this.stack.splice(e,1),t.open=!1,this.manageBodyScroll()}manageBodyScroll(){const t=this.stack.some(e=>e.type==="modal"||e.type==="page");t&&!this.bodyScrollBlocked?(this.originalBodyOverflow=document.body.style.overflow||"",document.body.style.overflow="hidden",this.bodyScrollBlocked=!0):!t&&this.bodyScrollBlocked&&(document.body.style.overflow=this.originalBodyOverflow,this.bodyScrollBlocked=!1)}overlaysByTriggerElement(t){return this.stack.filter(e=>e.triggerElement===t)}add(t){if(this.stack.includes(t)){const e=this.stack.indexOf(t);e>-1&&(this.stack.splice(e,1),this.stack.push(t));return}if(t.type==="auto"||t.type==="modal"||t.type==="page"){const e="sp-overlay-query-path",s=new Event(e,{composed:!0,bubbles:!0});t.addEventListener(e,o=>{const n=o.composedPath();this.stack.forEach(i=>{!n.find(r=>r===i)&&i.type!=="manual"&&i.type!=="modal"&&this.closeOverlay(i)})},{once:!0}),t.dispatchEvent(s)}else if(t.type==="hint"){if(this.stack.some(s=>s.type!=="manual"&&s.triggerElement&&s.triggerElement===t.triggerElement)){t.open=!1;return}this.stack.forEach(s=>{s.type==="hint"&&this.closeOverlay(s)})}requestAnimationFrame(()=>{this.stack.push(t),t.addEventListener("beforetoggle",this.handleBeforetoggle,{once:!0}),this.manageBodyScroll()})}remove(t){this.closeOverlay(t)}}export const overlayStack=new d;
//# sourceMappingURL=OverlayStack.js.map