1// role-components/exports/components/anchored-region/[email protected] downloaded from https://ga.jspm.io/npm:[email protected]/exports/components/anchored-region/anchored-region.js 2 3import{autoUpdate as t,offset as e,size as r,flip as i,shift as o,arrow as a,computePosition as s}from"@floating-ui/dom";import{classMap as n}from"lit/directives/class-map.js";import{css as l,html as h}from"lit";import{B as p}from"role-components/_/BrvVHMV_";import{hostStyles as d}from"role-components/exports/styles/host-styles";import{RoleRepositionEvent as c}from"role-components/exports/events/role-reposition-event";import{ifDefined as u}from"lit/directives/if-defined.js";import"web-component-define";import"role-components/exports/events/base-event"; 4/** 5 * @param {Record<string, unknown>} obj 6 * @return {string} 7 */function stringMap(t){let e="";for(const[r,i]of Object.entries(t))Boolean(i)&&(e+=`${r} `);return e} 8/** 9 * @typedef {object} VirtualElement 10 * @property {() => DOMRect} getBoundingClientRect 11 * @property {Element} [contextElement] 12 */ 13/** 14 * @param {unknown} e 15 * @satisfies {VirtualElement} 16 */function isVirtualElement(t){return t!==null&&typeof t==="object"&&"getBoundingClientRect"in t&&(!("contextElement"in t)||t instanceof Element)} 17/** 18 * @template {import('form-associated-helpers/exports/mixins/types.js').Constructable} T 19 * @param {T} superclass 20 */function AnchoredRegionMixin(t){return class __AnchoredRegionMixin__ extends t{ 21/** 22 * @param {any[]} args 23 */ 24constructor(...t){super(...t); 25/** 26 * The element the popover will be anchored to. If the anchor lives outside of the popover, you can provide the anchor 27 * element `id`, a DOM element reference, or a `VirtualElement`. If the anchor lives inside the popover, use the 28 * `anchor` slot instead. 29 * @type {null | Element | string | VirtualElement} 30 */this.anchor=this.anchor??null; 31/** 32 * The preferred placement of the popover. Note that the actual placement will vary as configured to keep the 33 * panel inside of the viewport. 34 * @attr 35 * @type { 36 'top' 37 | 'top-start' 38 | 'top-end' 39 | 'bottom' 40 | 'bottom-start' 41 | 'bottom-end' 42 | 'right' 43 | 'right-start' 44 | 'right-end' 45 | 'left' 46 | 'left-start' 47 | 'left-end' 48 } 49 */this.placement=this.placement??"top"; 50/** 51 * The `currentPlacement` property / `current-placement` attribute are where Floating UI actually positions the popup. 52 * @attr current-placement 53 * @reflect 54 * @type { 55 'top' 56 | 'top-start' 57 | 'top-end' 58 | 'bottom' 59 | 'bottom-start' 60 | 'bottom-end' 61 | 'right' 62 | 'right-start' 63 | 'right-end' 64 | 'left' 65 | 'left-start' 66 | 'left-end' 67 | null 68 } 69 */this.currentPlacement=this.placement??null; 70/** 71 * Determines how the popover is positioned. Because you native "popover" API uses a fixed strategy, we use it as the default. 72 * @attr 73 * @reflect 74 * @type {import("@floating-ui/dom").Strategy} 75 */this.strategy=this.strategy??"fixed"; 76/** 77 * The distance in pixels from which to offset along the "main axis". Usually its equivalent to offsetY 78 * @attr 79 * @type {number} 80 */this.distance=this.distance??0; 81/** 82 * The distance in pixels from which to offset along the "cross axis". Usually its equivalent to offsetX. 83 * @attr 84 * @type {number} 85 */this.skidding=this.skidding??0; 86/** 87 * Attaches an arrow to the popover. The arrow's size and color can be customized using the `--arrow-size` and 88 * `--background-color` custom properties. For additional customizations, you can also target the arrow using 89 * `::part(arrow)` in your stylesheet. 90 * @attr 91 * @type {boolean} 92 */this.arrow=this.arrow??false; 93/** 94 * The placement of the arrow. The default is `anchor`, which will align the arrow as close to the center of the 95 * anchor as possible, considering available space and `arrow-padding`. A value of `start`, `end`, or `center` will 96 * align the arrow to the start, end, or center of the popover instead. 97 * @attr arrow-placement 98 * @type {'start' | 'end' | 'center' | 'anchor'} 99 */this.arrowPlacement=this.arrowPlacement??"anchor"; 100/** 101 * The amount of padding between the arrow and the edges of the popover. If the popover has a border-radius, for example, 102 * this will prevent it from overflowing the corners. 103 * @attr arrow-padding 104 * @type {number} 105 */this.arrowPadding=this.arrowPadding??10; 106/** 107 * When set, placement of the popover will flip to the opposite site to keep it in view. You can use 108 * `flipFallbackPlacements` to further configure how the fallback placement is determined. 109 * @attr 110 * @type {boolean} 111 */this.flip=this.flip??true; 112/** 113 * If the preferred placement doesn't fit, popover will be tested in these fallback placements until one fits. Must be a 114 * string of any number of placements separated by a space, e.g. "top bottom left". If no placement fits, the flip 115 * fallback strategy will be used instead. 116 * @attr flip-fallback-placements 117 * @type {string} 118 */this.flipFallbackPlacements=this.flipFallbackPlacements??""; 119/** 120 * When neither the preferred placement nor the fallback placements fit, this value will be used to determine whether 121 * the popover should be positioned using the best available fit based on available space or as it was initially 122 * preferred. 123 * @type {'best-fit' | 'initial'} 124 * @attr flip-fallback-strategy 125 */this.flipFallbackStrategy=this.flipFallbackStrategy??"best-fit"; 126/**
127 * The flip boundary describes clipping element(s) that overflow will be checked relative to when flipping. By 128 * default, the boundary includes overflow ancestors that will cause the element to be clipped. If needed, you can 129 * change the boundary by passing a reference to one or more elements to this property. 130 * @type {undefined | Element | Element[]} 131 * @prop 132 */this.flipBoundary=this.flipBoundary??void 0; 133/** 134 * The amount of padding, in pixels, to exceed before the flip behavior will occur. 135 * @attr flip-padding 136 * @type {number} 137 */this.flipPadding=this.flipPadding??0; 138/** 139 * Moves the popover along the axis to keep it in view when clipped. 140 * @attr 141 * @type {boolean} 142 */this.shift=this.shift??true; 143/** 144 * The shift boundary describes clipping element(s) that overflow will be checked relative to when shifting. By 145 * default, the boundary includes overflow ancestors that will cause the element to be clipped. If needed, you can 146 * change the boundary by passing a reference to one or more elements to this property. 147 * @type {undefined | Element | Element[]} 148 * @property 149 */this.shiftBoundary=this.shiftBoundary??void 0; 150/** 151 * The amount of padding, in pixels, to exceed before the shift behavior will occur. 152 * @attr shift-padding 153 * @type {number} 154 */this.shiftPadding=this.shiftPadding??0; 155/** 156 * When set, this will cause the popover to automatically resize itself to prevent it from overflowing. 157 * @type {null | 'horizontal' | 'vertical' | 'both'} 158 * @attr auto-size 159 */this.autoSize=this.autoSize??null; 160/** 161 * Syncs the popover's width or height to that of the anchor element. 162 * @attr 163 * @type {null | 'width' | 'height' | 'both'} 164 */this.sync=this.sync??null; 165/** 166 * The auto-size boundary describes clipping element(s) that overflow will be checked relative to when resizing. By 167 * default, the boundary includes overflow ancestors that will cause the element to be clipped. If needed, you can 168 * change the boundary by passing a reference to one or more elements to this property. 169 * @type {undefined | Element | Element[]} 170 * @prop 171 */this.autoSizeBoundary=this.autoSizeBoundary??void 0; 172/** 173 * The amount of padding, in pixels, to exceed before the auto-size behavior will occur. 174 * @attr auto-size-padding 175 * @type {number} 176 */this.autoSizePadding=this.autoSizePadding??0; 177/** 178 * When a gap exists between the anchor and the popover element, this option will add a "hover bridge" that fills the 179 * gap using an invisible element. This makes listening for events such as `mouseenter` and `mouseleave` more sane 180 * because the pointer never technically leaves the element. The hover bridge will only be drawn when the popover is 181 * active. 182 * @attr hover-bridge 183 * @type {boolean} 184 */this.hoverBridge=this.hoverBridge??true;this.active=this.active??false; 185/** 186 * The type of popover to use for anchoring. Default is "auto". If "none", will not use "popover" for top layer. 187 * @type {"auto" | "manual" | "none"} 188 */this.anchoredPopoverType=this.anchoredPopoverType??"auto"}}}const AnchoredRegionProperties=()=>({active:{type:Boolean,reflect:true},anchor:{attribute:false,state:true},placement:{reflect:true},currentPlacement:{attribute:"current-placement",reflect:true},strategy:{reflect:true},distance:{type:Number},skidding:{type:Number},arrow:{type:Boolean},arrowPlacement:{attribute:"arrow-placement"},arrowPadding:{attribute:"arrow-padding",type:Number},flip:{type:Boolean},flipFallbackPlacements:{attribute:"flip-fallback-placements",converter:{ 189/** 190 * @param {string} value 191 */ 192fromAttribute:t=>t.split(" ").map((t=>t.trim())).filter((t=>t!=="")), 193/** 194 * @param {[]} value 195 */ 196toAttribute:t=>t.join(" ")}},flipFallbackStrategy:{attribute:"flip-fallback-strategy"},flipBoundary:{attribute:false,type:Object},flipPadding:{attribute:"flip-padding",type:Number},shift:{type:Boolean},shiftBoundary:{attribute:false,type:Object},shiftPadding:{attribute:"shift-padding",type:Number},autoSize:{attribute:"auto-size"},sync:{},autoSizeBoundary:{type:Object},autoSizePadding:{attribute:"auto-size-padding",type:Number},hoverBridge:{attribute:"hover-bridge",type:Boolean},anchoredPopoverType:{attribute:"anchored-popover-type",reflect:true}});class RoleAnchoredRegion extends(AnchoredRegionMixin(p)){static baseName="role-anchored-region";static styles=[d,l` 197 :host { 198 --__background: var(--background, #222); 199 --__border-color: var(--border-color, #222); 200 --__border-width: var(--border-width, 1px); 201 --__arrow-size: var(--arrow-size, 8px); 202 203 /* 204 * These properties are computed to account for the arrow's dimensions after being rotated 45º. The constant 205 * 0.7071 is derived from sin(45), which is the diagonal size of the arrow's container after rotating. 206 */ 207 --arrow-size-diagonal: calc(var(--__arrow-size) * 0.7071); 208 --arrow-padding-offset: calc(var(--arrow-size-diagonal) - var(--__arrow-size)); 209 210 display: contents; 211 } 212 213 [part~="popover"] { 214 position: absolute; 215 isolation: isolate; 216 max-width: var(--auto-size-available-width, none); 217 max-height: var(--auto-size-available-height, none); 218 border: var(--__border-width) solid var(--__border-color); 219 background: var(--__background); 220 } 221 222 [popover] { 223 position: fixed; 224 border: none; 225 background: none; 226 inset: unset; 227 color: inherit; 228 margin: 0; 229 padding: 0; 230 } 231 232 [part~="popover--fixed"] { 233 position: fixed; 234 } 235 236 [part~="arrow"] { 237 position: absolute; 238 width: calc(var(--arrow-size-diagonal) * 2); 239 height: calc(var(--arrow-size-diagonal) * 2); 240 background: var(--__background); 241 /* background: tomato; */ 242 z-index: -1; 243 margin: 0; 244 transform-style: preserve-3d; 245 border: var(--__border-width) solid var(--__border-color); 246 border-top-color: transparent; 247 border-right-color: transparent; 248 } 249 250 /* Hover bridge */ 251 [part~="hover-bridge"]:not([part~="hover-bridge--visible"]) { 252 display: none; 253 } 254 255 [part~="hover-bridge"] { 256 /* background: tomato; */ 257 position: fixed; 258 z-index: calc(var(--z-index-dropdown, 900) - 1); 259 top: 0; 260 right: 0; 261 bottom: 0; 262 left: 0; 263 clip-path: polygon( 264 var(--hover-bridge-top-left-x, 0) var(--hover-bridge-top-left-y, 0),
265 var(--hover-bridge-top-right-x, 0) var(--hover-bridge-top-right-y, 0), 266 var(--hover-bridge-bottom-right-x, 0) var(--hover-bridge-bottom-right-y, 0), 267 var(--hover-bridge-bottom-left-x, 0) var(--hover-bridge-bottom-left-y, 0) 268 ); 269 } 270 271 :host([current-placement="top"]) [part~="arrow"] { 272 transform: rotate(315deg); 273 } 274 275 :host([current-placement="bottom"]) [part~="arrow"] { 276 transform: rotate(135deg); 277 } 278 279 :host([current-placement="left"]) [part~="arrow"] { 280 transform: rotate(225deg); 281 } 282 283 :host([current-placement="right"]) [part~="arrow"] { 284 transform: rotate(45deg); 285 } 286 `];static properties={...AnchoredRegionProperties()};constructor(){super();window.process==null&&(window.process={});window.process.env==null&&(window.process.env="development") 287/** 288 * The element the popover will be anchored to. If the anchor lives outside of the popover, you can provide the anchor 289 * element `id`, a DOM element reference, or a `VirtualElement`. If the anchor lives inside the popover, use the 290 * `anchor` slot instead. 291 * @type {null | Element | string | VirtualElement} 292 */;this.anchor=null;this.active=false; 293/** 294 * @internal 295 * @type {Element | VirtualElement | null} 296 */this.__anchorEl=null; 297/** 298 * @internal 299 * @type {ReturnType<typeof autoUpdate> | undefined} 300 */this.__cleanup}async connectedCallback(){super.connectedCallback();await this.updateComplete;this.__start()}disconnectedCallback(){super.disconnectedCallback();this.__stop()} 301/** 302 * @param {import('lit').PropertyValues<this>} changedProps 303 */willUpdate(t){super.willUpdate(t);t.has("active")&&(this.active?this.__start():this.__stop());t.has("anchor")&&this.__handleAnchorChange()} 304/** 305 * @param {import('lit').PropertyValues<this>} changedProps 306 */async updated(t){super.updated(t);if(this.active){await this.updateComplete;this.reposition()}}get popoverElement(){/** @type {null | HTMLElement} */ 307return this.shadowRoot?.querySelector('[part~="popover"]')||null}get arrowElement(){/** @type {null | HTMLElement} */ 308return this.shadowRoot?.querySelector('[part~="arrow"]')||null}async __handleAnchorChange(){await this.__stop();if(this.anchor&&typeof this.anchor==="string"){const t=/** @type {Document | ShadowRoot} */this.getRootNode();this.__anchorEl=t.getElementById(this.anchor)}else this.anchor instanceof Element||isVirtualElement(this.anchor)?this.__anchorEl=/** @type {Element | VirtualElement} */this.anchor:this.__anchorEl=/** @type {HTMLElement} */this.querySelector('[slot="anchor"]');this.__anchorEl instanceof HTMLSlotElement&&(this.__anchorEl=/** @type {HTMLElement} */this.__anchorEl.assignedElements({flatten:true})[0]);this.__anchorEl&&this.__start()}
308__start(){if(this.__anchorEl&&this.popoverElement){this.__togglePopover__();this.cleanup=t(this.__anchorEl,this.popoverElement,(()=>{this.reposition()}))}} 309/** 310 * @internal 311 * @returns {Promise<void>} 312 */async __stop(){return new Promise((t=>{if(this.cleanup){this.cleanup();this.cleanup=void 0;this.currentPlacement=null;this.style.removeProperty("--auto-size-available-width");this.style.removeProperty("--auto-size-available-height");requestAnimationFrame((()=>{t();this.__togglePopover__()}))}else{this.__togglePopover__();t()}}))}__togglePopover__(){ 313/** 314 * @type {HTMLElement | null} 315 */ 316const t=this.shadowRoot?.querySelector("[popover]")||null;if(t)if(this.active)try{t.showPopover()}catch(t){}else try{t.hidePopover()}catch(t){}}reposition(){const t=this.popoverElement;if(!this.active||!this.__anchorEl||!t)return;const n=[e({mainAxis:this.distance,crossAxis:this.skidding})];if(this.sync)n.push(r({apply:({rects:e})=>{const r=this.sync==="width"||this.sync==="both";const i=this.sync==="height"||this.sync==="both";t.style.width=r?`${e.reference.width}px`:"";t.style.height=i?`${e.reference.height}px`:""}}));else{t.style.width="";t.style.height=""}this.flip&&n.push(i({boundary:this.flipBoundary,fallbackPlacements:this.flipFallbackPlacements,fallbackStrategy:this.flipFallbackStrategy==="best-fit"?"bestFit":"initialPlacement",padding:this.flipPadding}));this.shift&&n.push(o({boundary:this.shiftBoundary,padding:this.shiftPadding}));if(this.autoSize)n.push(r({boundary:this.autoSizeBoundary,padding:this.autoSizePadding,apply:({availableWidth:t,availableHeight:e})=>{this.autoSize==="vertical"||this.autoSize==="both"?this.style.setProperty("--auto-size-available-height",`${e}px`):this.style.removeProperty("--auto-size-available-height");this.autoSize==="horizontal"||this.autoSize==="both"?this.style.setProperty("--auto-size-available-width",`${t}px`):this.style.removeProperty("--auto-size-available-width")}}));else{this.style.removeProperty("--auto-size-available-width");this.style.removeProperty("--auto-size-available-height")}this.arrow&&this.arrowElement&&n.push(a({element:this.arrowElement,padding:this.arrowPadding}));s(this.__anchorEl,t,{placement:this.placement,middleware:n,strategy:this.strategy}).then((({x:e,y:r,middlewareData:i,placement:o})=>{const a=getComputedStyle(this).direction==="rtl";this.currentPlacement=o;const s={top:"bottom",right:"left",bottom:"top",left:"right"}[o.split("-")[0]]||this.placement;Object.assign(t.style,{left:`${e}px`,top:`${r}px`});if(this.arrow&&i.arrow){const t=i.arrow.x;const e=i.arrow.y;let r="";let o="";let n="";let l="";if(this.arrowPlacement==="start"){const i=typeof t==="number"?`calc(${this.arrowPadding}px - var(--arrow-padding-offset))`:"";r=typeof e==="number"?`calc(${this.arrowPadding}px - var(--arrow-padding-offset))`:"";o=a?i:"";l=a?"":i}else if(this.arrowPlacement==="end"){const r=typeof t==="number"?`calc(${this.arrowPadding}px - var(--arrow-padding-offset))`:"";o=a?"":r;l=a?r:"";n=typeof e==="number"?`calc(${this.arrowPadding}px - var(--arrow-padding-offset))`:""}else if(this.arrowPlacement==="center"){l=typeof t==="number"?"calc(50% - var(--arrow-size-diagonal))":"";r=typeof e==="number"?"calc(50% - var(--arrow-size-diagonal))":""}else{l=typeof t==="number"?`${t}px`:"";r=typeof e==="number"?`${e}px`:""}this.arrowElement&&Object.assign(this.arrowElement.style,{top:r,right:o,bottom:n,left:l,[s]:"calc(var(--arrow-size-diagonal) * -1)"})}}));requestAnimationFrame((()=>this.updateHoverBridge()));this.dispatchEvent(new c)}updateHoverBridge=()=>{if(this.hoverBridge&&this.__anchorEl&&this.popoverElement){const t=this.__anchorEl.getBoundingClientRect();const e=this.popoverElement.getBoundingClientRect();const r=(this.currentPlacement?.includes("top")||this.currentPlacement?.includes("bottom"))??true;let i=0;let o=0;let a=0;let s=0;let n=0;let l=0;let h=0;let p=0;if(r)if(t.top<e.top){i=t.left;o=t.bottom;a=t.right;s=t.bottom;n=e.left;l=e.top;h=e.right;p=e.top}else{i=e.left;o=e.bottom;a=e.right;s=e.bottom;n=t.left;l=t.top;h=t.right;p=t.top}else if(this.currentPlacement?.includes("left")){i=e.right;o=e.top;a=t.right;s=t.top;n=e.right;l=e.bottom;h=t.right;p=t.bottom}else{i=t.left;
316o=t.top;a=e.left;s=e.top;n=t.left;l=t.bottom;h=e.left;p=e.bottom}this.style.setProperty("--hover-bridge-top-left-x",`${i}px`);this.style.setProperty("--hover-bridge-top-left-y",`${o}px`);this.style.setProperty("--hover-bridge-top-right-x",`${a}px`);this.style.setProperty("--hover-bridge-top-right-y",`${s}px`);this.style.setProperty("--hover-bridge-bottom-left-x",`${n}px`);this.style.setProperty("--hover-bridge-bottom-left-y",`${l}px`);this.style.setProperty("--hover-bridge-bottom-right-x",`${h}px`);this.style.setProperty("--hover-bridge-bottom-right-y",`${p}px`)}};render(){return h` 317 <slot name="anchor" @slotchange=${this.__handleAnchorChange}></slot> 318 319 <div 320 part="popover-base" 321 popover=${u(this.anchoredPopoverType==="none"?null:this.anchoredPopoverType)} 322 > 323 <span 324 part=${stringMap({"hover-bridge":true,"hover-bridge--visible":this.hoverBridge&&this.active})} 325 ></span> 326 327 <div 328 part=${stringMap({popover:true,"popover--active":this.active,"popover--fixed":this.strategy==="fixed","popover--has-arrow":this.arrow})} 329 class=${n({"visually-hidden":!this.active})} 330 > 331 <slot></slot> 332 ${this.arrow?h`<div part="arrow" role="presentation"></div>`:""} 333 </div> 334 </div> 335 `}}export{AnchoredRegionMixin,AnchoredRegionProperties,RoleAnchoredRegion as default}; 336
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.