@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.79 kB
JavaScript
"use strict";import{conditionAttributeWithId as o}from"@spectrum-web-components/base/src/condition-attribute-with-id.js";import{isWebKit as l}from"@spectrum-web-components/shared";import{randomID as h}from"@spectrum-web-components/shared/src/random-id.js";import{noop as s}from"./AbstractOverlay.js";import{InteractionController as d,InteractionTypes as a,lastInteractionType as v}from"./InteractionController.js";export class HoverController extends d{constructor(){super(...arguments);this.type=a.hover;this.elementIds=[];this.targetFocused=!1;this.hovering=!1;this.overlayFocused=!1}handleKeyup(e){e.code==="Tab"?this.open=!0:e.code==="Escape"&&this.open&&(e.preventDefault(),e.stopPropagation(),this.open=!1,this.target&&this.target.focus())}handleTargetFocusin(){this.target.matches(":focus-visible")&&(l()&&this.target[v]===a.click||(this.open=!0,this.targetFocused=!0))}handleTargetFocusout(){this.targetFocused=!1,!this.hovering&&this.doFocusleave()}clearCloseTimeout(){this.hoverTimeout&&(clearTimeout(this.hoverTimeout),this.hoverTimeout=void 0)}handleTargetPointerenter(){var e;this.clearCloseTimeout(),!((e=this.overlay)!=null&&e.disabled)&&(this.open=!0,this.hovering=!0)}handleTargetPointerleave(){this.doPointerleave()}handleHostPointerenter(){this.clearCloseTimeout()}handleHostPointerleave(){this.doPointerleave()}handleOverlayFocusin(){this.overlayFocused=!0,this.clearCloseTimeout()}handleOverlayFocusout(){this.overlayFocused=!1,!this.hovering&&(this.targetFocused&&this.target.matches(":focus-visible")||this.doFocusleave())}prepareDescription(){if(!this.overlay.elements.length)return;const e=this.target.getRootNode(),t=this.overlay.elements[0].getRootNode(),r=this.overlay.getRootNode();e===r?this.prepareOverlayRelativeDescription():e===t&&this.prepareContentRelativeDescription()}prepareOverlayRelativeDescription(){const e=o(this.target,"aria-describedby",[this.overlay.id]);this.releaseDescription=()=>{e(),this.releaseDescription=s}}prepareContentRelativeDescription(){const e=[],t=this.overlay.elements.map(i=>(e.push(i.id),i.id||(i.id=`${this.overlay.tagName.toLowerCase()}-helper-${h()}`),i.id));this.elementIds=e;const r=o(this.target,"aria-describedby",t);this.releaseDescription=()=>{r(),this.overlay.elements.map((i,n)=>{i.id=this.elementIds[n]}),this.releaseDescription=s}}scheduleClose(){this.hoverTimeout=setTimeout(()=>{this.open=!1},300)}doPointerleave(){this.hovering=!1;const e=this.target;this.targetFocused&&e.matches(":focus-visible")||this.overlayFocused||this.scheduleClose()}doFocusleave(){this.clearCloseTimeout(),!this.targetFocused&&!this.overlayFocused&&!this.hovering&&this.scheduleClose()}init(){var t;(t=this.abortController)==null||t.abort(),this.abortController=new AbortController;const{signal:e}=this.abortController;this.target.addEventListener("keyup",r=>this.handleKeyup(r),{signal:e}),this.target.addEventListener("focusin",()=>this.handleTargetFocusin(),{signal:e}),this.target.addEventListener("focusout",()=>this.handleTargetFocusout(),{signal:e}),this.target.addEventListener("pointerenter",()=>this.handleTargetPointerenter(),{signal:e}),this.target.addEventListener("pointerleave",()=>this.handleTargetPointerleave(),{signal:e}),this.overlay&&this.initOverlay()}initOverlay(){if(!this.abortController)return;const{signal:e}=this.abortController;this.overlay.addEventListener("pointerenter",()=>this.handleHostPointerenter(),{signal:e}),this.overlay.addEventListener("pointerleave",()=>this.handleHostPointerleave(),{signal:e}),this.overlay.addEventListener("focusin",()=>this.handleOverlayFocusin(),{signal:e}),this.overlay.addEventListener("focusout",()=>this.handleOverlayFocusout(),{signal:e}),this.overlay.addEventListener("keyup",t=>this.handleKeyup(t),{signal:e})}}
//# sourceMappingURL=HoverController.js.map