From c521935635f20c1173355ac5560978e1d275c849 Mon Sep 17 00:00:00 2001 From: Eunsun Mota Date: Wed, 11 Dec 2024 17:50:56 -0500 Subject: [PATCH 1/2] fix: add `fluid` attribute to dropdown and make its default display `inline-block` #107 #117 --- components/combobox/demo/api.min.js | 9023 ++++++++ components/combobox/demo/index.min.js | 8925 ++++++++ components/combobox/src/auro-combobox.js | 3 +- components/counter/demo/api.md | 1053 + components/counter/docs/api.md | 2 +- components/datepicker/demo/api.min.js | 18452 ++++++++++++++++ components/datepicker/demo/index.min.js | 18181 +++++++++++++++ components/datepicker/src/auro-datepicker.js | 1 + .../apiExamples/commonMatchWidth.html | 2 +- components/dropdown/apiExamples/inline.html | 38 + .../apiExamples/programmaticallyHide.html | 2 +- .../apiExamples/programmaticallyShow.html | 2 +- components/dropdown/demo/api.html | 2 + components/dropdown/demo/api.md | 1174 + components/dropdown/demo/api.min.js | 2873 +++ components/dropdown/demo/index.html | 1 + components/dropdown/demo/index.md | 404 + components/dropdown/demo/index.min.js | 2839 +++ components/dropdown/docs/api.md | 5 +- components/dropdown/docs/partials/index.md | 33 +- .../dropdown/scripts/wca/auro-dropdown.js | 5 +- components/dropdown/src/auro-dropdown.js | 9 +- components/dropdown/src/styles/bibStyles.scss | 4 +- components/dropdown/src/styles/style.scss | 6 + components/select/demo/api.min.js | 4851 ++++ components/select/demo/index.min.js | 4774 ++++ components/select/src/auro-select.js | 1 + 27 files changed, 72635 insertions(+), 30 deletions(-) create mode 100644 components/combobox/demo/api.min.js create mode 100644 components/combobox/demo/index.min.js create mode 100644 components/counter/demo/api.md create mode 100644 components/datepicker/demo/api.min.js create mode 100644 components/datepicker/demo/index.min.js create mode 100644 components/dropdown/apiExamples/inline.html create mode 100644 components/dropdown/demo/api.md create mode 100644 components/dropdown/demo/api.min.js create mode 100644 components/dropdown/demo/index.md create mode 100644 components/dropdown/demo/index.min.js create mode 100644 components/select/demo/api.min.js create mode 100644 components/select/demo/index.min.js diff --git a/components/combobox/demo/api.min.js b/components/combobox/demo/api.min.js new file mode 100644 index 00000000..36ef657f --- /dev/null +++ b/components/combobox/demo/api.min.js @@ -0,0 +1,9023 @@ +class DynamicData { + getData() { + const response = [ + {iso2: 'AR', iso3: 'ARG', country: 'Argentina', cities: ['Germania']}, + {iso2: 'CA', iso3: 'CAN', country: 'Canada', cities: ['Saint-Germain-de-Grantham']}, + {iso2: 'FR', iso3: 'FRA', country: 'France', cities: ['Chatel-Saint-Germain', 'Domgermain', 'Germaine', 'Germainville', 'Germenay']}, + {iso2: 'DE', iso3: 'DEU', country: 'Germany', cities: ['Algermissen', 'Angermunde', 'Germering', 'Hilgermissen', 'Tangermunde']}, + {iso2: 'IR', iso3: 'IRN', country: 'Iran', cities: ['Germi']} + ]; + + return response; + } + + filterData(data, value) { + const filteredData = []; + + for (let index = 0; index < data.length; index ++) { + let countryName = data[index]['country'].toLowerCase(); + + if (value) { + data[index]['cities'] = data[index]['cities'].filter(city => city.toLowerCase().includes(value.toLowerCase())); + + if (countryName.includes(value.toLowerCase()) || data[index]['cities'].length > 0) { + filteredData.push(data[index]); + } + } + } + return filteredData; + } +} + +// Javascript example file +// ----------------------- + +function dynamicMenuExample() { + // Resets the root menu + function resetMenu(root) { + while (root.firstChild) { + root.removeChild(root.firstChild); + } + } + + // Generates HTML for menu and submenus using country & city data from an external API + function generateHtml(data) { + const initialMenu = document.querySelector('#initMenu'); + + resetMenu(initialMenu); + + for (let index = 0; index < data.length; index++) { + let country = data[index]['country']; + let cities = data[index]['cities']; + + generateMenuOptionHtml(initialMenu, country, country); + + for (let indexB = 0; indexB < cities.length; indexB++) { + let subMenu = document.createElement('auro-menu'); + + generateMenuOptionHtml(subMenu, cities[indexB], cities[indexB]); + + initialMenu.appendChild(subMenu); + } + } } + + // Helper function that generates HTML for menuoptions + function generateMenuOptionHtml(menu, label, value) { + let option = document.createElement('auro-menuoption'); + + option.value = value; + option.innerHTML = label; + + menu.appendChild(option); + } + + // Main javascript that runs all JS to create example + const dynamicData = new DynamicData(); + const dynamicMenuExample = document.querySelector('#dynamicMenuExample'); + const dropdownEl = dynamicMenuExample.shadowRoot.querySelector(dynamicMenuExample.dropdownTag._$litStatic$); + const inputEl = dropdownEl.querySelector(dynamicMenuExample.inputTag._$litStatic$); + + inputEl.addEventListener('input', () => { + let data = dynamicData.getData(); + data = dynamicData.filterData(data, dynamicMenuExample.value); + + generateHtml(data); + }); +} + +function valueExample() { + const valueExample = document.querySelector('#valueExample'); + + document.querySelector('#valueValidExampleBtn').addEventListener('click', () => { + valueExample.value = 'Oranges'; + }); + + document.querySelector('#valueInvalidExampleBtn').addEventListener('click', () => { + valueExample.value = 'Dragon Fruit'; + }); + + document.querySelector('#valueUndefinedExampleBtn').addEventListener('click', () => { + valueExample.value = undefined; + }); +} + +function focusExample() { + const focusExample = document.querySelector('#focusExample'); + const focusExampleBtnElem = document.querySelector('#focusExampleBtn'); + + focusExampleBtnElem.addEventListener('click', () => { + focusExample.focus(); + }); +} + +function inDialogExample() { + document.querySelector("#combobox-dialog-opener").addEventListener("click", () => { + const dialog = document.querySelector("#combobox-dialog"); + dialog.open = true; + }); +} + +/** + * @license + * Copyright 2019 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */ +const t$7=globalThis,e$9=t$7.ShadowRoot&&(void 0===t$7.ShadyCSS||t$7.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,s$7=Symbol(),o$a=new WeakMap;let n$8 = class n{constructor(t,e,o){if(this._$cssResult$=!0,o!==s$7)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e;}get styleSheet(){let t=this.o;const s=this.t;if(e$9&&void 0===t){const e=void 0!==s&&1===s.length;e&&(t=o$a.get(s)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),e&&o$a.set(s,t));}return t}toString(){return this.cssText}};const r$9=t=>new n$8("string"==typeof t?t:t+"",void 0,s$7),i$c=(t,...e)=>{const o=1===t.length?t[0]:e.reduce(((e,s,o)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(s)+t[o+1]),t[0]);return new n$8(o,t,s$7)},S$4=(s,o)=>{if(e$9)s.adoptedStyleSheets=o.map((t=>t instanceof CSSStyleSheet?t:t.styleSheet));else for(const e of o){const o=document.createElement("style"),n=t$7.litNonce;void 0!==n&&o.setAttribute("nonce",n),o.textContent=e.cssText,s.appendChild(o);}},c$7=e$9?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const s of t.cssRules)e+=s.cssText;return r$9(e)})(t):t; + +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */const{is:i$b,defineProperty:e$8,getOwnPropertyDescriptor:r$8,getOwnPropertyNames:h$4,getOwnPropertySymbols:o$9,getPrototypeOf:n$7}=Object,a$6=globalThis,c$6=a$6.trustedTypes,l$6=c$6?c$6.emptyScript:"",p$5=a$6.reactiveElementPolyfillSupport,d$4=(t,s)=>t,u$8={toAttribute(t,s){switch(s){case Boolean:t=t?l$6:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t);}return t},fromAttribute(t,s){let i=t;switch(s){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t);}catch(t){i=null;}}return i}},f$4=(t,s)=>!i$b(t,s),y$4={attribute:!0,type:String,converter:u$8,reflect:!1,hasChanged:f$4};Symbol.metadata??=Symbol("metadata"),a$6.litPropertyMetadata??=new WeakMap;let b$2 = class b extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t);}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,s=y$4){if(s.state&&(s.attribute=!1),this._$Ei(),this.elementProperties.set(t,s),!s.noAccessor){const i=Symbol(),r=this.getPropertyDescriptor(t,i,s);void 0!==r&&e$8(this.prototype,t,r);}}static getPropertyDescriptor(t,s,i){const{get:e,set:h}=r$8(this.prototype,t)??{get(){return this[s]},set(t){this[s]=t;}};return {get(){return e?.call(this)},set(s){const r=e?.call(this);h.call(this,s),this.requestUpdate(t,r,i);},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??y$4}static _$Ei(){if(this.hasOwnProperty(d$4("elementProperties")))return;const t=n$7(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties);}static finalize(){if(this.hasOwnProperty(d$4("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(d$4("properties"))){const t=this.properties,s=[...h$4(t),...o$9(t)];for(const i of s)this.createProperty(i,t[i]);}const t=this[Symbol.metadata];if(null!==t){const s=litPropertyMetadata.get(t);if(void 0!==s)for(const[t,i]of s)this.elementProperties.set(t,i);}this._$Eh=new Map;for(const[t,s]of this.elementProperties){const i=this._$Eu(t,s);void 0!==i&&this._$Eh.set(i,t);}this.elementStyles=this.finalizeStyles(this.styles);}static finalizeStyles(s){const i=[];if(Array.isArray(s)){const e=new Set(s.flat(1/0).reverse());for(const s of e)i.unshift(c$7(s));}else void 0!==s&&i.push(c$7(s));return i}static _$Eu(t,s){const i=s.attribute;return !1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev();}_$Ev(){this._$ES=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach((t=>t(this)));}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.();}removeController(t){this._$EO?.delete(t);}_$E_(){const t=new Map,s=this.constructor.elementProperties;for(const i of s.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t);}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return S$4(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach((t=>t.hostConnected?.()));}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach((t=>t.hostDisconnected?.()));}attributeChangedCallback(t,s,i){this._$AK(t,i);}_$EC(t,s){const i=this.constructor.elementProperties.get(t),e=this.constructor._$Eu(t,i);if(void 0!==e&&!0===i.reflect){const r=(void 0!==i.converter?.toAttribute?i.converter:u$8).toAttribute(s,i.type);this._$Em=t,null==r?this.removeAttribute(e):this.setAttribute(e,r),this._$Em=null;}}_$AK(t,s){const i=this.constructor,e=i._$Eh.get(t);if(void 0!==e&&this._$Em!==e){const t=i.getPropertyOptions(e),r="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:u$8;this._$Em=e,this[e]=r.fromAttribute(s,t.type),this._$Em=null;}}requestUpdate(t,s,i){if(void 0!==t){if(i??=this.constructor.getPropertyOptions(t),!(i.hasChanged??f$4)(this[t],s))return;this.P(t,s,i);}!1===this.isUpdatePending&&(this._$ES=this._$ET());}P(t,s,i){this._$AL.has(t)||this._$AL.set(t,s),!0===i.reflect&&this._$Em!==t&&(this._$Ej??=new Set).add(t);}async _$ET(){this.isUpdatePending=!0;try{await this._$ES;}catch(t){Promise.reject(t);}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,s]of this._$Ep)this[t]=s;this._$Ep=void 0;}const t=this.constructor.elementProperties;if(t.size>0)for(const[s,i]of t)!0!==i.wrapped||this._$AL.has(s)||void 0===this[s]||this.P(s,this[s],i);}let t=!1;const s=this._$AL;try{t=this.shouldUpdate(s),t?(this.willUpdate(s),this._$EO?.forEach((t=>t.hostUpdate?.())),this.update(s)):this._$EU();}catch(s){throw t=!1,this._$EU(),s}t&&this._$AE(s);}willUpdate(t){}_$AE(t){this._$EO?.forEach((t=>t.hostUpdated?.())),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t);}_$EU(){this._$AL=new Map,this.isUpdatePending=!1;}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return !0}update(t){this._$Ej&&=this._$Ej.forEach((t=>this._$EC(t,this[t]))),this._$EU();}updated(t){}firstUpdated(t){}};b$2.elementStyles=[],b$2.shadowRootOptions={mode:"open"},b$2[d$4("elementProperties")]=new Map,b$2[d$4("finalized")]=new Map,p$5?.({ReactiveElement:b$2}),(a$6.reactiveElementVersions??=[]).push("2.0.4"); + +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */ +const t$6=globalThis,i$a=t$6.trustedTypes,s$6=i$a?i$a.createPolicy("lit-html",{createHTML:t=>t}):void 0,e$7="$lit$",h$3=`lit$${Math.random().toFixed(9).slice(2)}$`,o$8="?"+h$3,n$6=`<${o$8}>`,r$7=document,l$5=()=>r$7.createComment(""),c$5=t=>null===t||"object"!=typeof t&&"function"!=typeof t,a$5=Array.isArray,u$7=t=>a$5(t)||"function"==typeof t?.[Symbol.iterator],d$3="[ \t\n\f\r]",f$3=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,v$3=/-->/g,_$2=/>/g,m$3=RegExp(`>|${d$3}(?:([^\\s"'>=/]+)(${d$3}*=${d$3}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),p$4=/'/g,g$2=/"/g,$$2=/^(?:script|style|textarea|title)$/i,y$3=t=>(i,...s)=>({_$litType$:t,strings:i,values:s}),x$2=y$3(1),T$2=Symbol.for("lit-noChange"),E$2=Symbol.for("lit-nothing"),A$2=new WeakMap,C$2=r$7.createTreeWalker(r$7,129);function P$2(t,i){if(!a$5(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==s$6?s$6.createHTML(i):i}const V$2=(t,i)=>{const s=t.length-1,o=[];let r,l=2===i?"":3===i?"":"",c=f$3;for(let i=0;i"===u[0]?(c=r??f$3,d=-1):void 0===u[1]?d=-2:(d=c.lastIndex-u[2].length,a=u[1],c=void 0===u[3]?m$3:'"'===u[3]?g$2:p$4):c===g$2||c===p$4?c=m$3:c===v$3||c===_$2?c=f$3:(c=m$3,r=void 0);const x=c===m$3&&t[i+1].startsWith("/>")?" ":"";l+=c===f$3?s+n$6:d>=0?(o.push(a),s.slice(0,d)+e$7+s.slice(d)+h$3+x):s+h$3+(-2===d?i:x);}return [P$2(t,l+(t[s]||"")+(2===i?"":3===i?"":"")),o]};let N$2 = class N{constructor({strings:t,_$litType$:s},n){let r;this.parts=[];let c=0,a=0;const u=t.length-1,d=this.parts,[f,v]=V$2(t,s);if(this.el=N.createElement(f,n),C$2.currentNode=this.el.content,2===s||3===s){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes);}for(;null!==(r=C$2.nextNode())&&d.length0){r.textContent=i$a?i$a.emptyScript:"";for(let i=0;i2||""!==s[0]||""!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=E$2;}_$AI(t,i=this,s,e){const h=this.strings;let o=!1;if(void 0===h)t=S$3(this,t,i,0),o=!c$5(t)||t!==this._$AH&&t!==T$2,o&&(this._$AH=t);else {const e=t;let n,r;for(t=h[0],n=0;n{const e=s?.renderBefore??i;let h=e._$litPart$;if(void 0===h){const t=s?.renderBefore??null;e._$litPart$=h=new R$2(i.insertBefore(l$5(),t),t,void 0,s??{});}return h._$AI(t),h}; + +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */let r$6 = class r extends b$2{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0;}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const s=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=B$2(s,this.renderRoot,this.renderOptions);}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0);}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1);}render(){return T$2}};r$6._$litElement$=!0,r$6["finalized"]=!0,globalThis.litElementHydrateSupport?.({LitElement:r$6});const i$9=globalThis.litElementPolyfillSupport;i$9?.({LitElement:r$6});(globalThis.litElementVersions??=[]).push("4.1.1"); + +/** + * @license + * Copyright 2020 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */ +const a$4=Symbol.for(""),o$7=t=>{if(t?.r===a$4)return t?._$litStatic$},s$5=t=>({_$litStatic$:t,r:a$4}),i$8=(t,...r)=>({_$litStatic$:r.reduce(((r,e,a)=>r+(t=>{if(void 0!==t._$litStatic$)return t._$litStatic$;throw Error(`Value passed to 'literal' function must be a 'literal' result: ${t}. Use 'unsafeStatic' to pass non-literal values, but\n take care to ensure page security.`)})(e)+t[a+1]),t[0]),r:a$4}),l$4=new Map,n$5=t=>(r,...e)=>{const a=e.length;let s,i;const n=[],u=[];let c,$=0,f=!1;for(;$ + !el || el === document || el === window + ? null // standard .closest() returns null for non-found selectors also + : found + ? found // found a selector INside this element + : __Closest(el.getRootNode().host) // recursion!! break out to parent DOM + ) { + return __Closest(base); + } + /* eslint-enable jsdoc/require-param */ + + /** + * If the element passed is registered with a different tag name than what is passed in, the tag name is added as an attribute to the element. + * @param {Object} elem - The element to check. + * @param {String} tagName - The name of the Auro component to check for or add as an attribute. + * @returns {void} + */ + handleComponentTagRename(elem, tagName) { + const tag = tagName.toLowerCase(); + const elemTag = elem.tagName.toLowerCase(); + + if (elemTag !== tag) { + elem.setAttribute(tag, true); + } + } + + /** + * Validates if an element is a specific Auro component. + * @param {Object} elem - The element to validate. + * @param {String} tagName - The name of the Auro component to check against. + * @returns {Boolean} - Returns true if the element is the specified Auro component. + */ + elementMatch(elem, tagName) { + const tag = tagName.toLowerCase(); + const elemTag = elem.tagName.toLowerCase(); + + return elemTag === tag || elem.hasAttribute(tag); + } +}; + +// Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license +// See LICENSE in the project root for license information. + + +let AuroFormValidation$1 = class AuroFormValidation { + constructor() { + this.runtimeUtils = new AuroLibraryRuntimeUtils$2(); + } + + /** + * Determines the validity state of the element based on the common attribute restrictions (pattern). + * @private + * @param {object} elem - HTML element to validate. + * @returns {void} + */ + validateAttributes(elem) { + if (elem.pattern) { + const pattern = new RegExp(`^${elem.pattern}$`, 'u'); + + if (!pattern.test(elem.value)) { + elem.validity = 'badInput'; + elem.setCustomValidity = elem.setCustomValidityBadInput || ''; + } + } else if (elem.value && elem.value.length > 0 && elem.value.length < elem.minLength) { + elem.validity = 'tooShort'; + elem.setCustomValidity = elem.setCustomValidityTooShort || ''; + } else if (elem.value && elem.value.length > elem.maxLength) { + elem.validity = 'tooLong'; + elem.setCustomValidity = elem.setCustomValidityTooLong || ''; + } + } + + /** + * Determines the validity state of the element based on the type attribute. + * @private + * @param {object} elem - HTML element to validate. + * @returns {void} + */ + validateType(elem) { + if (elem.hasAttribute('type')) { + if (elem.type === 'email') { + const emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/; // eslint-disable-line require-unicode-regexp + + if (!elem.value.match(emailRegex)) { + elem.validity = 'badInput'; + elem.setCustomValidity = elem.setCustomValidityForType || ''; + } + } else if (elem.type === 'credit-card') { + if (elem.value.length > 0 && elem.value.length < elem.validationCCLength) { + elem.validity = 'tooShort'; + elem.setCustomValidity = elem.setCustomValidityForType || ''; + } + } else if (elem.type === 'number' || elem.type === 'numeric') { // 'numeric` is a deprecated alias for number' + if (elem.max !== undefined && Number(elem.max) < Number(elem.value)) { + elem.validity = 'rangeOverflow'; + elem.setCustomValidity = elem.getAttribute('setCustomValidityRangeOverflow') || ''; + } + + if (elem.min !== undefined && Number(elem.min) > Number(elem.value)) { + elem.validity = 'rangeUnderflow'; + elem.setCustomValidity = elem.getAttribute('setCustomValidityRangeUnderflow') || ''; + } + + } else if (elem.type === 'month-day-year' || + elem.type === 'month-year' || + elem.type === 'month-fullYear' || + elem.type === 'year-month-day' + ) { + if (elem.value && elem.value.length > 0 && elem.value.length < elem.dateStrLength) { + elem.validity = 'tooShort'; + elem.setCustomValidity = elem.setCustomValidityForType || ''; + } else { + const valueDate = new Date(elem.value); + + // validate max + if (elem.max !== undefined) { + const maxDate = new Date(elem.max); + + if (valueDate > maxDate) { + elem.validity = 'rangeOverflow'; + elem.setCustomValidity = elem.getAttribute('setCustomValidityRangeOverflow') || ''; + } + } + + // validate min + if (elem.min) { + const minDate = new Date(elem.min); + + if (valueDate < minDate) { + elem.validity = 'rangeUnderflow'; + elem.setCustomValidity = elem.getAttribute('setCustomValidityRangeUnderflow') || ''; + } + } + } + } + } + } + + /** + * Determines the validity state of the element. + * @param {object} elem - HTML element to validate. + * @param {boolean} force - Boolean that forces validation to run. + * @returns {void} + */ + validate(elem, force) { + this.getInputElements(elem); + this.getAuroInputs(elem); + + // Validate only if noValidate is not true and the input does not have focus + const validationShouldRun = force || (!elem.contains(document.activeElement) && elem.value !== undefined) || elem.validateOnInput; + + if (elem.hasAttribute('error')) { + elem.validity = 'customError'; + elem.setCustomValidity = elem.error; + } else if (validationShouldRun) { + elem.validity = 'valid'; + elem.setCustomValidity = ''; + + /** + * Only validate once we interact with the datepicker + * elem.value === undefined is the initial state pre-interaction. + * + * The validityState definitions are located at https://developer.mozilla.org/en-US/docs/Web/API/ValidityState. + */ + + let hasValue = elem.value && elem.value.length > 0; + + // If there is a second input in the elem and that value is undefined or an empty string set hasValue to false; + if (this.auroInputElements && this.auroInputElements.length === 2) { + if (!this.auroInputElements[1].value || this.auroInputElements[1].length === 0) { + hasValue = false; + } + } + + if (!hasValue && elem.required) { + elem.validity = 'valueMissing'; + elem.setCustomValidity = elem.setCustomValidityValueMissing || ''; + } else if (this.runtimeUtils.elementMatch(elem, 'auro-input')) { + this.validateType(elem); + this.validateAttributes(elem); + } + } + + if (this.auroInputElements && this.auroInputElements.length > 0) { + elem.validity = this.auroInputElements[0].validity; + elem.setCustomValidity = this.auroInputElements[0].setCustomValidity; + + if (elem.validity === 'valid') { + if (this.auroInputElements.length > 1) { + elem.validity = this.auroInputElements[1].validity; + elem.setCustomValidity = this.auroInputElements[1].setCustomValidity; + } + } + } + + if (validationShouldRun || elem.hasAttribute('error')) { + if (elem.validity && elem.validity !== 'valid') { + elem.isValid = false; + + // Use the validity message override if it is declared + if (elem.ValidityMessageOverride) { + elem.setCustomValidity = elem.ValidityMessageOverride; + } + } else { + elem.isValid = true; + } + + this.getErrorMessage(elem); + + elem.dispatchEvent(new CustomEvent('auroFormElement-validated', { + bubbles: true, + composed: true, + detail: { + validity: elem.validity, + message: elem.errorMessage + } + })); + } + } + + /** + * Gets all the HTML5 `inputs` in the element shadow DOM. + * @private + * @param {object} elem - HTML element to validate. + * @returns {void} + */ + getInputElements(elem) { + this.inputElements = elem.renderRoot.querySelectorAll('input'); + } + + /** + * Gets all the `auro-inputs` in the element shadow DOM. + * @private + * @param {object} elem - HTML element to validate. + * @returns {void} + */ + getAuroInputs(elem) { + this.auroInputElements = elem.shadowRoot.querySelectorAll('auro-input, [auro-input]'); + } + + /** + * Return appropriate error message. + * @private + * @param {object} elem - HTML element to validate. + * @returns {void} + */ + getErrorMessage(elem) { + if (elem.validity !== 'valid') { + if (elem.setCustomValidity) { + elem.errorMessage = elem.setCustomValidity; + } else if (this.runtimeUtils.elementMatch(elem, 'auro-input')) { + const input = elem.renderRoot.querySelector('input'); + + if (input.validationMessage.length > 0) { + elem.errorMessage = input.validationMessage; + } + } else if (this.inputElements && this.inputElements.length > 0) { + const firstInput = this.inputElements[0]; + + if (firstInput.validationMessage.length > 0) { + elem.errorMessage = firstInput.validationMessage; + } else if (this.inputElements.length === 2) { + const secondInput = this.inputElements[1]; + + if (secondInput.validationMessage.length > 0) { + elem.errorMessage = secondInput.validationMessage; + } + } + } + } else { + elem.errorMessage = undefined; + } + } +}; + +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */ +const t$2$1=globalThis,i$5$1=t$2$1.trustedTypes,s$2$1=i$5$1?i$5$1.createPolicy("lit-html",{createHTML:t=>t}):void 0,e$4$1="$lit$",h$1$1=`lit$${Math.random().toFixed(9).slice(2)}$`,o$4$1="?"+h$1$1,n$3$1=`<${o$4$1}>`,r$3$1=document,l$2$1=()=>r$3$1.createComment(""),c$2$1=t=>null===t||"object"!=typeof t&&"function"!=typeof t,a$2$1=Array.isArray,u$2$1=t=>a$2$1(t)||"function"==typeof t?.[Symbol.iterator],d$1$1="[ \t\n\f\r]",f$1$1=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,v$2=/-->/g,_$1=/>/g,m$2=RegExp(`>|${d$1$1}(?:([^\\s"'>=/]+)(${d$1$1}*=${d$1$1}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),p$1$1=/'/g,g$1=/"/g,$$1=/^(?:script|style|textarea|title)$/i,y$1$1=t=>(i,...s)=>({_$litType$:t,strings:i,values:s}),x$1=y$1$1(1),T$1=Symbol.for("lit-noChange"),E$1=Symbol.for("lit-nothing"),A$1=new WeakMap,C$1=r$3$1.createTreeWalker(r$3$1,129);function P$1(t,i){if(!a$2$1(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==s$2$1?s$2$1.createHTML(i):i}const V$1=(t,i)=>{const s=t.length-1,o=[];let r,l=2===i?"":3===i?"":"",c=f$1$1;for(let i=0;i"===u[0]?(c=r??f$1$1,d=-1):void 0===u[1]?d=-2:(d=c.lastIndex-u[2].length,a=u[1],c=void 0===u[3]?m$2:'"'===u[3]?g$1:p$1$1):c===g$1||c===p$1$1?c=m$2:c===v$2||c===_$1?c=f$1$1:(c=m$2,r=void 0);const x=c===m$2&&t[i+1].startsWith("/>")?" ":"";l+=c===f$1$1?s+n$3$1:d>=0?(o.push(a),s.slice(0,d)+e$4$1+s.slice(d)+h$1$1+x):s+h$1$1+(-2===d?i:x);}return [P$1(t,l+(t[s]||"")+(2===i?"":3===i?"":"")),o]};let N$1 = class N{constructor({strings:t,_$litType$:s},n){let r;this.parts=[];let c=0,a=0;const u=t.length-1,d=this.parts,[f,v]=V$1(t,s);if(this.el=N.createElement(f,n),C$1.currentNode=this.el.content,2===s||3===s){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes);}for(;null!==(r=C$1.nextNode())&&d.length0){r.textContent=i$5$1?i$5$1.emptyScript:"";for(let i=0;i2||""!==s[0]||""!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=E$1;}_$AI(t,i=this,s,e){const h=this.strings;let o=!1;if(void 0===h)t=S$1$1(this,t,i,0),o=!c$2$1(t)||t!==this._$AH&&t!==T$1,o&&(this._$AH=t);else {const e=t;let n,r;for(t=h[0],n=0;n{const e=s?.renderBefore??i;let h=e._$litPart$;if(void 0===h){const t=s?.renderBefore??null;e._$litPart$=h=new R$1(i.insertBefore(l$2$1(),t),t,void 0,s??{});}return h._$AI(t),h}; + +/** + * @license + * Copyright 2020 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */ +const a$1$1=Symbol.for(""),o$3$1=t=>{if(t?.r===a$1$1)return t?._$litStatic$},s$1$1=t=>({_$litStatic$:t,r:a$1$1}),i$4$1=(t,...r)=>({_$litStatic$:r.reduce(((r,e,a)=>r+(t=>{if(void 0!==t._$litStatic$)return t._$litStatic$;throw Error(`Value passed to 'literal' function must be a 'literal' result: ${t}. Use 'unsafeStatic' to pass non-literal values, but\n take care to ensure page security.`)})(e)+t[a+1]),t[0]),r:a$1$1}),l$1$1=new Map,n$2$1=t=>(r,...e)=>{const a=e.length;let s,i;const n=[],u=[];let c,$=0,f=!1;for(;$new n$1$1("string"==typeof t?t:t+"",void 0,s$4),i$3$1=(t,...e)=>{const o=1===t.length?t[0]:e.reduce(((e,s,o)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(s)+t[o+1]),t[0]);return new n$1$1(o,t,s$4)},S$2=(s,o)=>{if(e$3$1)s.adoptedStyleSheets=o.map((t=>t instanceof CSSStyleSheet?t:t.styleSheet));else for(const e of o){const o=document.createElement("style"),n=t$1$1.litNonce;void 0!==n&&o.setAttribute("nonce",n),o.textContent=e.cssText,s.appendChild(o);}},c$1$1=e$3$1?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const s of t.cssRules)e+=s.cssText;return r$2$1(e)})(t):t; + +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */const{is:i$2$1,defineProperty:e$2$1,getOwnPropertyDescriptor:r$1$1,getOwnPropertyNames:h$2,getOwnPropertySymbols:o$1$1,getPrototypeOf:n$4}=Object,a$3=globalThis,c$4=a$3.trustedTypes,l$3=c$4?c$4.emptyScript:"",p$3=a$3.reactiveElementPolyfillSupport,d$2=(t,s)=>t,u$5={toAttribute(t,s){switch(s){case Boolean:t=t?l$3:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t);}return t},fromAttribute(t,s){let i=t;switch(s){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t);}catch(t){i=null;}}return i}},f$2=(t,s)=>!i$2$1(t,s),y$2={attribute:!0,type:String,converter:u$5,reflect:!1,hasChanged:f$2};Symbol.metadata??=Symbol("metadata"),a$3.litPropertyMetadata??=new WeakMap;let b$1 = class b extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t);}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,s=y$2){if(s.state&&(s.attribute=!1),this._$Ei(),this.elementProperties.set(t,s),!s.noAccessor){const i=Symbol(),r=this.getPropertyDescriptor(t,i,s);void 0!==r&&e$2$1(this.prototype,t,r);}}static getPropertyDescriptor(t,s,i){const{get:e,set:h}=r$1$1(this.prototype,t)??{get(){return this[s]},set(t){this[s]=t;}};return {get(){return e?.call(this)},set(s){const r=e?.call(this);h.call(this,s),this.requestUpdate(t,r,i);},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??y$2}static _$Ei(){if(this.hasOwnProperty(d$2("elementProperties")))return;const t=n$4(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties);}static finalize(){if(this.hasOwnProperty(d$2("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(d$2("properties"))){const t=this.properties,s=[...h$2(t),...o$1$1(t)];for(const i of s)this.createProperty(i,t[i]);}const t=this[Symbol.metadata];if(null!==t){const s=litPropertyMetadata.get(t);if(void 0!==s)for(const[t,i]of s)this.elementProperties.set(t,i);}this._$Eh=new Map;for(const[t,s]of this.elementProperties){const i=this._$Eu(t,s);void 0!==i&&this._$Eh.set(i,t);}this.elementStyles=this.finalizeStyles(this.styles);}static finalizeStyles(s){const i=[];if(Array.isArray(s)){const e=new Set(s.flat(1/0).reverse());for(const s of e)i.unshift(c$1$1(s));}else void 0!==s&&i.push(c$1$1(s));return i}static _$Eu(t,s){const i=s.attribute;return !1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev();}_$Ev(){this._$ES=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach((t=>t(this)));}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.();}removeController(t){this._$EO?.delete(t);}_$E_(){const t=new Map,s=this.constructor.elementProperties;for(const i of s.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t);}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return S$2(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach((t=>t.hostConnected?.()));}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach((t=>t.hostDisconnected?.()));}attributeChangedCallback(t,s,i){this._$AK(t,i);}_$EC(t,s){const i=this.constructor.elementProperties.get(t),e=this.constructor._$Eu(t,i);if(void 0!==e&&!0===i.reflect){const r=(void 0!==i.converter?.toAttribute?i.converter:u$5).toAttribute(s,i.type);this._$Em=t,null==r?this.removeAttribute(e):this.setAttribute(e,r),this._$Em=null;}}_$AK(t,s){const i=this.constructor,e=i._$Eh.get(t);if(void 0!==e&&this._$Em!==e){const t=i.getPropertyOptions(e),r="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:u$5;this._$Em=e,this[e]=r.fromAttribute(s,t.type),this._$Em=null;}}requestUpdate(t,s,i){if(void 0!==t){if(i??=this.constructor.getPropertyOptions(t),!(i.hasChanged??f$2)(this[t],s))return;this.P(t,s,i);}!1===this.isUpdatePending&&(this._$ES=this._$ET());}P(t,s,i){this._$AL.has(t)||this._$AL.set(t,s),!0===i.reflect&&this._$Em!==t&&(this._$Ej??=new Set).add(t);}async _$ET(){this.isUpdatePending=!0;try{await this._$ES;}catch(t){Promise.reject(t);}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,s]of this._$Ep)this[t]=s;this._$Ep=void 0;}const t=this.constructor.elementProperties;if(t.size>0)for(const[s,i]of t)!0!==i.wrapped||this._$AL.has(s)||void 0===this[s]||this.P(s,this[s],i);}let t=!1;const s=this._$AL;try{t=this.shouldUpdate(s),t?(this.willUpdate(s),this._$EO?.forEach((t=>t.hostUpdate?.())),this.update(s)):this._$EU();}catch(s){throw t=!1,this._$EU(),s}t&&this._$AE(s);}willUpdate(t){}_$AE(t){this._$EO?.forEach((t=>t.hostUpdated?.())),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t);}_$EU(){this._$AL=new Map,this.isUpdatePending=!1;}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return !0}update(t){this._$Ej&&=this._$Ej.forEach((t=>this._$EC(t,this[t]))),this._$EU();}updated(t){}firstUpdated(t){}};b$1.elementStyles=[],b$1.shadowRootOptions={mode:"open"},b$1[d$2("elementProperties")]=new Map,b$1[d$2("finalized")]=new Map,p$3?.({ReactiveElement:b$1}),(a$3.reactiveElementVersions??=[]).push("2.0.4"); + +/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */let r$5 = class r extends b$1{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0;}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const s=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=B$1(s,this.renderRoot,this.renderOptions);}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0);}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1);}render(){return T$1}};r$5._$litElement$=!0,r$5["finalized"]=!0,globalThis.litElementHydrateSupport?.({LitElement:r$5});const i$1$1=globalThis.litElementPolyfillSupport;i$1$1?.({LitElement:r$5});(globalThis.litElementVersions??=[]).push("4.1.1"); + +// Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license +// See LICENSE in the project root for license information. + +// --------------------------------------------------------------------- + +/* eslint-disable line-comment-position, no-inline-comments, no-confusing-arrow, no-nested-ternary, implicit-arrow-linebreak */ + +let AuroLibraryRuntimeUtils$1 = class AuroLibraryRuntimeUtils { + + /* eslint-disable jsdoc/require-param */ + + /** + * This will register a new custom element with the browser. + * @param {String} name - The name of the custom element. + * @param {Object} componentClass - The class to register as a custom element. + * @returns {void} + */ + registerComponent(name, componentClass) { + if (!customElements.get(name)) { + customElements.define(name, class extends componentClass {}); + } + } + + /** + * Finds and returns the closest HTML Element based on a selector. + * @returns {void} + */ + closestElement( + selector, // selector like in .closest() + base = this, // extra functionality to skip a parent + __Closest = (el, found = el && el.closest(selector)) => + !el || el === document || el === window + ? null // standard .closest() returns null for non-found selectors also + : found + ? found // found a selector INside this element + : __Closest(el.getRootNode().host) // recursion!! break out to parent DOM + ) { + return __Closest(base); + } + /* eslint-enable jsdoc/require-param */ + + /** + * If the element passed is registered with a different tag name than what is passed in, the tag name is added as an attribute to the element. + * @param {Object} elem - The element to check. + * @param {String} tagName - The name of the Auro component to check for or add as an attribute. + * @returns {void} + */ + handleComponentTagRename(elem, tagName) { + const tag = tagName.toLowerCase(); + const elemTag = elem.tagName.toLowerCase(); + + if (elemTag !== tag) { + elem.setAttribute(tag, true); + } + } + + /** + * Validates if an element is a specific Auro component. + * @param {Object} elem - The element to validate. + * @param {String} tagName - The name of the Auro component to check against. + * @returns {Boolean} - Returns true if the element is the specified Auro component. + */ + elementMatch(elem, tagName) { + const tag = tagName.toLowerCase(); + const elemTag = elem.tagName.toLowerCase(); + + return elemTag === tag || elem.hasAttribute(tag); + } +}; + +/** + * Custom positioning reference element. + * @see https://floating-ui.com/docs/virtual-elements + */ + +const sides = ['top', 'right', 'bottom', 'left']; +const alignments = ['start', 'end']; +const placements = /*#__PURE__*/sides.reduce((acc, side) => acc.concat(side, side + "-" + alignments[0], side + "-" + alignments[1]), []); +const min = Math.min; +const max = Math.max; +const round = Math.round; +const floor = Math.floor; +const createCoords = v => ({ + x: v, + y: v +}); +const oppositeSideMap = { + left: 'right', + right: 'left', + bottom: 'top', + top: 'bottom' +}; +const oppositeAlignmentMap = { + start: 'end', + end: 'start' +}; +function evaluate(value, param) { + return typeof value === 'function' ? value(param) : value; +} +function getSide(placement) { + return placement.split('-')[0]; +} +function getAlignment(placement) { + return placement.split('-')[1]; +} +function getOppositeAxis(axis) { + return axis === 'x' ? 'y' : 'x'; +} +function getAxisLength(axis) { + return axis === 'y' ? 'height' : 'width'; +} +function getSideAxis(placement) { + return ['top', 'bottom'].includes(getSide(placement)) ? 'y' : 'x'; +} +function getAlignmentAxis(placement) { + return getOppositeAxis(getSideAxis(placement)); +} +function getAlignmentSides(placement, rects, rtl) { + if (rtl === void 0) { + rtl = false; + } + const alignment = getAlignment(placement); + const alignmentAxis = getAlignmentAxis(placement); + const length = getAxisLength(alignmentAxis); + let mainAlignmentSide = alignmentAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top'; + if (rects.reference[length] > rects.floating[length]) { + mainAlignmentSide = getOppositePlacement(mainAlignmentSide); + } + return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)]; +} +function getExpandedPlacements(placement) { + const oppositePlacement = getOppositePlacement(placement); + return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)]; +} +function getOppositeAlignmentPlacement(placement) { + return placement.replace(/start|end/g, alignment => oppositeAlignmentMap[alignment]); +} +function getSideList(side, isStart, rtl) { + const lr = ['left', 'right']; + const rl = ['right', 'left']; + const tb = ['top', 'bottom']; + const bt = ['bottom', 'top']; + switch (side) { + case 'top': + case 'bottom': + if (rtl) return isStart ? rl : lr; + return isStart ? lr : rl; + case 'left': + case 'right': + return isStart ? tb : bt; + default: + return []; + } +} +function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) { + const alignment = getAlignment(placement); + let list = getSideList(getSide(placement), direction === 'start', rtl); + if (alignment) { + list = list.map(side => side + "-" + alignment); + if (flipAlignment) { + list = list.concat(list.map(getOppositeAlignmentPlacement)); + } + } + return list; +} +function getOppositePlacement(placement) { + return placement.replace(/left|right|bottom|top/g, side => oppositeSideMap[side]); +} +function expandPaddingObject(padding) { + return { + top: 0, + right: 0, + bottom: 0, + left: 0, + ...padding + }; +} +function getPaddingObject(padding) { + return typeof padding !== 'number' ? expandPaddingObject(padding) : { + top: padding, + right: padding, + bottom: padding, + left: padding + }; +} +function rectToClientRect(rect) { + const { + x, + y, + width, + height + } = rect; + return { + width, + height, + top: y, + left: x, + right: x + width, + bottom: y + height, + x, + y + }; +} + +function computeCoordsFromPlacement(_ref, placement, rtl) { + let { + reference, + floating + } = _ref; + const sideAxis = getSideAxis(placement); + const alignmentAxis = getAlignmentAxis(placement); + const alignLength = getAxisLength(alignmentAxis); + const side = getSide(placement); + const isVertical = sideAxis === 'y'; + const commonX = reference.x + reference.width / 2 - floating.width / 2; + const commonY = reference.y + reference.height / 2 - floating.height / 2; + const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2; + let coords; + switch (side) { + case 'top': + coords = { + x: commonX, + y: reference.y - floating.height + }; + break; + case 'bottom': + coords = { + x: commonX, + y: reference.y + reference.height + }; + break; + case 'right': + coords = { + x: reference.x + reference.width, + y: commonY + }; + break; + case 'left': + coords = { + x: reference.x - floating.width, + y: commonY + }; + break; + default: + coords = { + x: reference.x, + y: reference.y + }; + } + switch (getAlignment(placement)) { + case 'start': + coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1); + break; + case 'end': + coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1); + break; + } + return coords; +} + +/** + * Computes the `x` and `y` coordinates that will place the floating element + * next to a given reference element. + * + * This export does not have any `platform` interface logic. You will need to + * write one for the platform you are using Floating UI with. + */ +const computePosition$1 = async (reference, floating, config) => { + const { + placement = 'bottom', + strategy = 'absolute', + middleware = [], + platform + } = config; + const validMiddleware = middleware.filter(Boolean); + const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(floating)); + let rects = await platform.getElementRects({ + reference, + floating, + strategy + }); + let { + x, + y + } = computeCoordsFromPlacement(rects, placement, rtl); + let statefulPlacement = placement; + let middlewareData = {}; + let resetCount = 0; + for (let i = 0; i < validMiddleware.length; i++) { + const { + name, + fn + } = validMiddleware[i]; + const { + x: nextX, + y: nextY, + data, + reset + } = await fn({ + x, + y, + initialPlacement: placement, + placement: statefulPlacement, + strategy, + middlewareData, + rects, + platform, + elements: { + reference, + floating + } + }); + x = nextX != null ? nextX : x; + y = nextY != null ? nextY : y; + middlewareData = { + ...middlewareData, + [name]: { + ...middlewareData[name], + ...data + } + }; + if (reset && resetCount <= 50) { + resetCount++; + if (typeof reset === 'object') { + if (reset.placement) { + statefulPlacement = reset.placement; + } + if (reset.rects) { + rects = reset.rects === true ? await platform.getElementRects({ + reference, + floating, + strategy + }) : reset.rects; + } + ({ + x, + y + } = computeCoordsFromPlacement(rects, statefulPlacement, rtl)); + } + i = -1; + } + } + return { + x, + y, + placement: statefulPlacement, + strategy, + middlewareData + }; +}; + +/** + * Resolves with an object of overflow side offsets that determine how much the + * element is overflowing a given clipping boundary on each side. + * - positive = overflowing the boundary by that number of pixels + * - negative = how many pixels left before it will overflow + * - 0 = lies flush with the boundary + * @see https://floating-ui.com/docs/detectOverflow + */ +async function detectOverflow(state, options) { + var _await$platform$isEle; + if (options === void 0) { + options = {}; + } + const { + x, + y, + platform, + rects, + elements, + strategy + } = state; + const { + boundary = 'clippingAncestors', + rootBoundary = 'viewport', + elementContext = 'floating', + altBoundary = false, + padding = 0 + } = evaluate(options, state); + const paddingObject = getPaddingObject(padding); + const altContext = elementContext === 'floating' ? 'reference' : 'floating'; + const element = elements[altBoundary ? altContext : elementContext]; + const clippingClientRect = rectToClientRect(await platform.getClippingRect({ + element: ((_await$platform$isEle = await (platform.isElement == null ? void 0 : platform.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || (await (platform.getDocumentElement == null ? void 0 : platform.getDocumentElement(elements.floating))), + boundary, + rootBoundary, + strategy + })); + const rect = elementContext === 'floating' ? { + x, + y, + width: rects.floating.width, + height: rects.floating.height + } : rects.reference; + const offsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating)); + const offsetScale = (await (platform.isElement == null ? void 0 : platform.isElement(offsetParent))) ? (await (platform.getScale == null ? void 0 : platform.getScale(offsetParent))) || { + x: 1, + y: 1 + } : { + x: 1, + y: 1 + }; + const elementClientRect = rectToClientRect(platform.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform.convertOffsetParentRelativeRectToViewportRelativeRect({ + elements, + rect, + offsetParent, + strategy + }) : rect); + return { + top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y, + bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y, + left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x, + right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x + }; +} + +function getPlacementList(alignment, autoAlignment, allowedPlacements) { + const allowedPlacementsSortedByAlignment = alignment ? [...allowedPlacements.filter(placement => getAlignment(placement) === alignment), ...allowedPlacements.filter(placement => getAlignment(placement) !== alignment)] : allowedPlacements.filter(placement => getSide(placement) === placement); + return allowedPlacementsSortedByAlignment.filter(placement => { + if (alignment) { + return getAlignment(placement) === alignment || (autoAlignment ? getOppositeAlignmentPlacement(placement) !== placement : false); + } + return true; + }); +} +/** + * Optimizes the visibility of the floating element by choosing the placement + * that has the most space available automatically, without needing to specify a + * preferred placement. Alternative to `flip`. + * @see https://floating-ui.com/docs/autoPlacement + */ +const autoPlacement$1 = function (options) { + if (options === void 0) { + options = {}; + } + return { + name: 'autoPlacement', + options, + async fn(state) { + var _middlewareData$autoP, _middlewareData$autoP2, _placementsThatFitOnE; + const { + rects, + middlewareData, + placement, + platform, + elements + } = state; + const { + crossAxis = false, + alignment, + allowedPlacements = placements, + autoAlignment = true, + ...detectOverflowOptions + } = evaluate(options, state); + const placements$1 = alignment !== undefined || allowedPlacements === placements ? getPlacementList(alignment || null, autoAlignment, allowedPlacements) : allowedPlacements; + const overflow = await detectOverflow(state, detectOverflowOptions); + const currentIndex = ((_middlewareData$autoP = middlewareData.autoPlacement) == null ? void 0 : _middlewareData$autoP.index) || 0; + const currentPlacement = placements$1[currentIndex]; + if (currentPlacement == null) { + return {}; + } + const alignmentSides = getAlignmentSides(currentPlacement, rects, await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating))); + + // Make `computeCoords` start from the right place. + if (placement !== currentPlacement) { + return { + reset: { + placement: placements$1[0] + } + }; + } + const currentOverflows = [overflow[getSide(currentPlacement)], overflow[alignmentSides[0]], overflow[alignmentSides[1]]]; + const allOverflows = [...(((_middlewareData$autoP2 = middlewareData.autoPlacement) == null ? void 0 : _middlewareData$autoP2.overflows) || []), { + placement: currentPlacement, + overflows: currentOverflows + }]; + const nextPlacement = placements$1[currentIndex + 1]; + + // There are more placements to check. + if (nextPlacement) { + return { + data: { + index: currentIndex + 1, + overflows: allOverflows + }, + reset: { + placement: nextPlacement + } + }; + } + const placementsSortedByMostSpace = allOverflows.map(d => { + const alignment = getAlignment(d.placement); + return [d.placement, alignment && crossAxis ? + // Check along the mainAxis and main crossAxis side. + d.overflows.slice(0, 2).reduce((acc, v) => acc + v, 0) : + // Check only the mainAxis. + d.overflows[0], d.overflows]; + }).sort((a, b) => a[1] - b[1]); + const placementsThatFitOnEachSide = placementsSortedByMostSpace.filter(d => d[2].slice(0, + // Aligned placements should not check their opposite crossAxis + // side. + getAlignment(d[0]) ? 2 : 3).every(v => v <= 0)); + const resetPlacement = ((_placementsThatFitOnE = placementsThatFitOnEachSide[0]) == null ? void 0 : _placementsThatFitOnE[0]) || placementsSortedByMostSpace[0][0]; + if (resetPlacement !== placement) { + return { + data: { + index: currentIndex + 1, + overflows: allOverflows + }, + reset: { + placement: resetPlacement + } + }; + } + return {}; + } + }; +}; + +/** + * Optimizes the visibility of the floating element by flipping the `placement` + * in order to keep it in view when the preferred placement(s) will overflow the + * clipping boundary. Alternative to `autoPlacement`. + * @see https://floating-ui.com/docs/flip + */ +const flip$1 = function (options) { + if (options === void 0) { + options = {}; + } + return { + name: 'flip', + options, + async fn(state) { + var _middlewareData$arrow, _middlewareData$flip; + const { + placement, + middlewareData, + rects, + initialPlacement, + platform, + elements + } = state; + const { + mainAxis: checkMainAxis = true, + crossAxis: checkCrossAxis = true, + fallbackPlacements: specifiedFallbackPlacements, + fallbackStrategy = 'bestFit', + fallbackAxisSideDirection = 'none', + flipAlignment = true, + ...detectOverflowOptions + } = evaluate(options, state); + + // If a reset by the arrow was caused due to an alignment offset being + // added, we should skip any logic now since `flip()` has already done its + // work. + // https://github.com/floating-ui/floating-ui/issues/2549#issuecomment-1719601643 + if ((_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) { + return {}; + } + const side = getSide(placement); + const initialSideAxis = getSideAxis(initialPlacement); + const isBasePlacement = getSide(initialPlacement) === initialPlacement; + const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating)); + const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement)); + const hasFallbackAxisSideDirection = fallbackAxisSideDirection !== 'none'; + if (!specifiedFallbackPlacements && hasFallbackAxisSideDirection) { + fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl)); + } + const placements = [initialPlacement, ...fallbackPlacements]; + const overflow = await detectOverflow(state, detectOverflowOptions); + const overflows = []; + let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || []; + if (checkMainAxis) { + overflows.push(overflow[side]); + } + if (checkCrossAxis) { + const sides = getAlignmentSides(placement, rects, rtl); + overflows.push(overflow[sides[0]], overflow[sides[1]]); + } + overflowsData = [...overflowsData, { + placement, + overflows + }]; + + // One or more sides is overflowing. + if (!overflows.every(side => side <= 0)) { + var _middlewareData$flip2, _overflowsData$filter; + const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1; + const nextPlacement = placements[nextIndex]; + if (nextPlacement) { + // Try next placement and re-run the lifecycle. + return { + data: { + index: nextIndex, + overflows: overflowsData + }, + reset: { + placement: nextPlacement + } + }; + } + + // First, find the candidates that fit on the mainAxis side of overflow, + // then find the placement that fits the best on the main crossAxis side. + let resetPlacement = (_overflowsData$filter = overflowsData.filter(d => d.overflows[0] <= 0).sort((a, b) => a.overflows[1] - b.overflows[1])[0]) == null ? void 0 : _overflowsData$filter.placement; + + // Otherwise fallback. + if (!resetPlacement) { + switch (fallbackStrategy) { + case 'bestFit': + { + var _overflowsData$filter2; + const placement = (_overflowsData$filter2 = overflowsData.filter(d => { + if (hasFallbackAxisSideDirection) { + const currentSideAxis = getSideAxis(d.placement); + return currentSideAxis === initialSideAxis || + // Create a bias to the `y` side axis due to horizontal + // reading directions favoring greater width. + currentSideAxis === 'y'; + } + return true; + }).map(d => [d.placement, d.overflows.filter(overflow => overflow > 0).reduce((acc, overflow) => acc + overflow, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$filter2[0]; + if (placement) { + resetPlacement = placement; + } + break; + } + case 'initialPlacement': + resetPlacement = initialPlacement; + break; + } + } + if (placement !== resetPlacement) { + return { + reset: { + placement: resetPlacement + } + }; + } + } + return {}; + } + }; +}; + +// For type backwards-compatibility, the `OffsetOptions` type was also +// Derivable. + +async function convertValueToCoords(state, options) { + const { + placement, + platform, + elements + } = state; + const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating)); + const side = getSide(placement); + const alignment = getAlignment(placement); + const isVertical = getSideAxis(placement) === 'y'; + const mainAxisMulti = ['left', 'top'].includes(side) ? -1 : 1; + const crossAxisMulti = rtl && isVertical ? -1 : 1; + const rawValue = evaluate(options, state); + + // eslint-disable-next-line prefer-const + let { + mainAxis, + crossAxis, + alignmentAxis + } = typeof rawValue === 'number' ? { + mainAxis: rawValue, + crossAxis: 0, + alignmentAxis: null + } : { + mainAxis: rawValue.mainAxis || 0, + crossAxis: rawValue.crossAxis || 0, + alignmentAxis: rawValue.alignmentAxis + }; + if (alignment && typeof alignmentAxis === 'number') { + crossAxis = alignment === 'end' ? alignmentAxis * -1 : alignmentAxis; + } + return isVertical ? { + x: crossAxis * crossAxisMulti, + y: mainAxis * mainAxisMulti + } : { + x: mainAxis * mainAxisMulti, + y: crossAxis * crossAxisMulti + }; +} + +/** + * Modifies the placement by translating the floating element along the + * specified axes. + * A number (shorthand for `mainAxis` or distance), or an axes configuration + * object may be passed. + * @see https://floating-ui.com/docs/offset + */ +const offset$1 = function (options) { + if (options === void 0) { + options = 0; + } + return { + name: 'offset', + options, + async fn(state) { + var _middlewareData$offse, _middlewareData$arrow; + const { + x, + y, + placement, + middlewareData + } = state; + const diffCoords = await convertValueToCoords(state, options); + + // If the placement is the same and the arrow caused an alignment offset + // then we don't need to change the positioning coordinates. + if (placement === ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse.placement) && (_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) { + return {}; + } + return { + x: x + diffCoords.x, + y: y + diffCoords.y, + data: { + ...diffCoords, + placement + } + }; + } + }; +}; + +function hasWindow() { + return typeof window !== 'undefined'; +} +function getNodeName(node) { + if (isNode(node)) { + return (node.nodeName || '').toLowerCase(); + } + // Mocked nodes in testing environments may not be instances of Node. By + // returning `#document` an infinite loop won't occur. + // https://github.com/floating-ui/floating-ui/issues/2317 + return '#document'; +} +function getWindow(node) { + var _node$ownerDocument; + return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window; +} +function getDocumentElement(node) { + var _ref; + return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement; +} +function isNode(value) { + if (!hasWindow()) { + return false; + } + return value instanceof Node || value instanceof getWindow(value).Node; +} +function isElement(value) { + if (!hasWindow()) { + return false; + } + return value instanceof Element || value instanceof getWindow(value).Element; +} +function isHTMLElement(value) { + if (!hasWindow()) { + return false; + } + return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement; +} +function isShadowRoot(value) { + if (!hasWindow() || typeof ShadowRoot === 'undefined') { + return false; + } + return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot; +} +function isOverflowElement(element) { + const { + overflow, + overflowX, + overflowY, + display + } = getComputedStyle$1(element); + return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !['inline', 'contents'].includes(display); +} +function isTableElement(element) { + return ['table', 'td', 'th'].includes(getNodeName(element)); +} +function isTopLayer(element) { + return [':popover-open', ':modal'].some(selector => { + try { + return element.matches(selector); + } catch (e) { + return false; + } + }); +} +function isContainingBlock(elementOrCss) { + const webkit = isWebKit(); + const css = isElement(elementOrCss) ? getComputedStyle$1(elementOrCss) : elementOrCss; + + // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block + return css.transform !== 'none' || css.perspective !== 'none' || (css.containerType ? css.containerType !== 'normal' : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== 'none' : false) || !webkit && (css.filter ? css.filter !== 'none' : false) || ['transform', 'perspective', 'filter'].some(value => (css.willChange || '').includes(value)) || ['paint', 'layout', 'strict', 'content'].some(value => (css.contain || '').includes(value)); +} +function getContainingBlock(element) { + let currentNode = getParentNode(element); + while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) { + if (isContainingBlock(currentNode)) { + return currentNode; + } else if (isTopLayer(currentNode)) { + return null; + } + currentNode = getParentNode(currentNode); + } + return null; +} +function isWebKit() { + if (typeof CSS === 'undefined' || !CSS.supports) return false; + return CSS.supports('-webkit-backdrop-filter', 'none'); +} +function isLastTraversableNode(node) { + return ['html', 'body', '#document'].includes(getNodeName(node)); +} +function getComputedStyle$1(element) { + return getWindow(element).getComputedStyle(element); +} +function getNodeScroll(element) { + if (isElement(element)) { + return { + scrollLeft: element.scrollLeft, + scrollTop: element.scrollTop + }; + } + return { + scrollLeft: element.scrollX, + scrollTop: element.scrollY + }; +} +function getParentNode(node) { + if (getNodeName(node) === 'html') { + return node; + } + const result = + // Step into the shadow DOM of the parent of a slotted node. + node.assignedSlot || + // DOM Element detected. + node.parentNode || + // ShadowRoot detected. + isShadowRoot(node) && node.host || + // Fallback. + getDocumentElement(node); + return isShadowRoot(result) ? result.host : result; +} +function getNearestOverflowAncestor(node) { + const parentNode = getParentNode(node); + if (isLastTraversableNode(parentNode)) { + return node.ownerDocument ? node.ownerDocument.body : node.body; + } + if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) { + return parentNode; + } + return getNearestOverflowAncestor(parentNode); +} +function getOverflowAncestors(node, list, traverseIframes) { + var _node$ownerDocument2; + if (list === void 0) { + list = []; + } + if (traverseIframes === void 0) { + traverseIframes = true; + } + const scrollableAncestor = getNearestOverflowAncestor(node); + const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body); + const win = getWindow(scrollableAncestor); + if (isBody) { + const frameElement = getFrameElement(win); + return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []); + } + return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes)); +} +function getFrameElement(win) { + return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null; +} + +function getCssDimensions(element) { + const css = getComputedStyle$1(element); + // In testing environments, the `width` and `height` properties are empty + // strings for SVG elements, returning NaN. Fallback to `0` in this case. + let width = parseFloat(css.width) || 0; + let height = parseFloat(css.height) || 0; + const hasOffset = isHTMLElement(element); + const offsetWidth = hasOffset ? element.offsetWidth : width; + const offsetHeight = hasOffset ? element.offsetHeight : height; + const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight; + if (shouldFallback) { + width = offsetWidth; + height = offsetHeight; + } + return { + width, + height, + $: shouldFallback + }; +} + +function unwrapElement(element) { + return !isElement(element) ? element.contextElement : element; +} + +function getScale(element) { + const domElement = unwrapElement(element); + if (!isHTMLElement(domElement)) { + return createCoords(1); + } + const rect = domElement.getBoundingClientRect(); + const { + width, + height, + $ + } = getCssDimensions(domElement); + let x = ($ ? round(rect.width) : rect.width) / width; + let y = ($ ? round(rect.height) : rect.height) / height; + + // 0, NaN, or Infinity should always fallback to 1. + + if (!x || !Number.isFinite(x)) { + x = 1; + } + if (!y || !Number.isFinite(y)) { + y = 1; + } + return { + x, + y + }; +} + +const noOffsets = /*#__PURE__*/createCoords(0); +function getVisualOffsets(element) { + const win = getWindow(element); + if (!isWebKit() || !win.visualViewport) { + return noOffsets; + } + return { + x: win.visualViewport.offsetLeft, + y: win.visualViewport.offsetTop + }; +} +function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) { + if (isFixed === void 0) { + isFixed = false; + } + if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) { + return false; + } + return isFixed; +} + +function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) { + if (includeScale === void 0) { + includeScale = false; + } + if (isFixedStrategy === void 0) { + isFixedStrategy = false; + } + const clientRect = element.getBoundingClientRect(); + const domElement = unwrapElement(element); + let scale = createCoords(1); + if (includeScale) { + if (offsetParent) { + if (isElement(offsetParent)) { + scale = getScale(offsetParent); + } + } else { + scale = getScale(element); + } + } + const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0); + let x = (clientRect.left + visualOffsets.x) / scale.x; + let y = (clientRect.top + visualOffsets.y) / scale.y; + let width = clientRect.width / scale.x; + let height = clientRect.height / scale.y; + if (domElement) { + const win = getWindow(domElement); + const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent; + let currentWin = win; + let currentIFrame = getFrameElement(currentWin); + while (currentIFrame && offsetParent && offsetWin !== currentWin) { + const iframeScale = getScale(currentIFrame); + const iframeRect = currentIFrame.getBoundingClientRect(); + const css = getComputedStyle$1(currentIFrame); + const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x; + const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y; + x *= iframeScale.x; + y *= iframeScale.y; + width *= iframeScale.x; + height *= iframeScale.y; + x += left; + y += top; + currentWin = getWindow(currentIFrame); + currentIFrame = getFrameElement(currentWin); + } + } + return rectToClientRect({ + width, + height, + x, + y + }); +} + +// If has a CSS width greater than the viewport, then this will be +// incorrect for RTL. +function getWindowScrollBarX(element, rect) { + const leftScroll = getNodeScroll(element).scrollLeft; + if (!rect) { + return getBoundingClientRect(getDocumentElement(element)).left + leftScroll; + } + return rect.left + leftScroll; +} + +function getHTMLOffset(documentElement, scroll, ignoreScrollbarX) { + if (ignoreScrollbarX === void 0) { + ignoreScrollbarX = false; + } + const htmlRect = documentElement.getBoundingClientRect(); + const x = htmlRect.left + scroll.scrollLeft - (ignoreScrollbarX ? 0 : + // RTL scrollbar. + getWindowScrollBarX(documentElement, htmlRect)); + const y = htmlRect.top + scroll.scrollTop; + return { + x, + y + }; +} + +function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) { + let { + elements, + rect, + offsetParent, + strategy + } = _ref; + const isFixed = strategy === 'fixed'; + const documentElement = getDocumentElement(offsetParent); + const topLayer = elements ? isTopLayer(elements.floating) : false; + if (offsetParent === documentElement || topLayer && isFixed) { + return rect; + } + let scroll = { + scrollLeft: 0, + scrollTop: 0 + }; + let scale = createCoords(1); + const offsets = createCoords(0); + const isOffsetParentAnElement = isHTMLElement(offsetParent); + if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { + if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) { + scroll = getNodeScroll(offsetParent); + } + if (isHTMLElement(offsetParent)) { + const offsetRect = getBoundingClientRect(offsetParent); + scale = getScale(offsetParent); + offsets.x = offsetRect.x + offsetParent.clientLeft; + offsets.y = offsetRect.y + offsetParent.clientTop; + } + } + const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll, true) : createCoords(0); + return { + width: rect.width * scale.x, + height: rect.height * scale.y, + x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x, + y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y + }; +} + +function getClientRects(element) { + return Array.from(element.getClientRects()); +} + +// Gets the entire size of the scrollable document area, even extending outside +// of the `` and `` rect bounds if horizontally scrollable. +function getDocumentRect(element) { + const html = getDocumentElement(element); + const scroll = getNodeScroll(element); + const body = element.ownerDocument.body; + const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth); + const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight); + let x = -scroll.scrollLeft + getWindowScrollBarX(element); + const y = -scroll.scrollTop; + if (getComputedStyle$1(body).direction === 'rtl') { + x += max(html.clientWidth, body.clientWidth) - width; + } + return { + width, + height, + x, + y + }; +} + +function getViewportRect(element, strategy) { + const win = getWindow(element); + const html = getDocumentElement(element); + const visualViewport = win.visualViewport; + let width = html.clientWidth; + let height = html.clientHeight; + let x = 0; + let y = 0; + if (visualViewport) { + width = visualViewport.width; + height = visualViewport.height; + const visualViewportBased = isWebKit(); + if (!visualViewportBased || visualViewportBased && strategy === 'fixed') { + x = visualViewport.offsetLeft; + y = visualViewport.offsetTop; + } + } + return { + width, + height, + x, + y + }; +} + +// Returns the inner client rect, subtracting scrollbars if present. +function getInnerBoundingClientRect(element, strategy) { + const clientRect = getBoundingClientRect(element, true, strategy === 'fixed'); + const top = clientRect.top + element.clientTop; + const left = clientRect.left + element.clientLeft; + const scale = isHTMLElement(element) ? getScale(element) : createCoords(1); + const width = element.clientWidth * scale.x; + const height = element.clientHeight * scale.y; + const x = left * scale.x; + const y = top * scale.y; + return { + width, + height, + x, + y + }; +} +function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) { + let rect; + if (clippingAncestor === 'viewport') { + rect = getViewportRect(element, strategy); + } else if (clippingAncestor === 'document') { + rect = getDocumentRect(getDocumentElement(element)); + } else if (isElement(clippingAncestor)) { + rect = getInnerBoundingClientRect(clippingAncestor, strategy); + } else { + const visualOffsets = getVisualOffsets(element); + rect = { + x: clippingAncestor.x - visualOffsets.x, + y: clippingAncestor.y - visualOffsets.y, + width: clippingAncestor.width, + height: clippingAncestor.height + }; + } + return rectToClientRect(rect); +} +function hasFixedPositionAncestor(element, stopNode) { + const parentNode = getParentNode(element); + if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) { + return false; + } + return getComputedStyle$1(parentNode).position === 'fixed' || hasFixedPositionAncestor(parentNode, stopNode); +} + +// A "clipping ancestor" is an `overflow` element with the characteristic of +// clipping (or hiding) child elements. This returns all clipping ancestors +// of the given element up the tree. +function getClippingElementAncestors(element, cache) { + const cachedResult = cache.get(element); + if (cachedResult) { + return cachedResult; + } + let result = getOverflowAncestors(element, [], false).filter(el => isElement(el) && getNodeName(el) !== 'body'); + let currentContainingBlockComputedStyle = null; + const elementIsFixed = getComputedStyle$1(element).position === 'fixed'; + let currentNode = elementIsFixed ? getParentNode(element) : element; + + // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block + while (isElement(currentNode) && !isLastTraversableNode(currentNode)) { + const computedStyle = getComputedStyle$1(currentNode); + const currentNodeIsContaining = isContainingBlock(currentNode); + if (!currentNodeIsContaining && computedStyle.position === 'fixed') { + currentContainingBlockComputedStyle = null; + } + const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && ['absolute', 'fixed'].includes(currentContainingBlockComputedStyle.position) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode); + if (shouldDropCurrentNode) { + // Drop non-containing blocks. + result = result.filter(ancestor => ancestor !== currentNode); + } else { + // Record last containing block for next iteration. + currentContainingBlockComputedStyle = computedStyle; + } + currentNode = getParentNode(currentNode); + } + cache.set(element, result); + return result; +} + +// Gets the maximum area that the element is visible in due to any number of +// clipping ancestors. +function getClippingRect(_ref) { + let { + element, + boundary, + rootBoundary, + strategy + } = _ref; + const elementClippingAncestors = boundary === 'clippingAncestors' ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary); + const clippingAncestors = [...elementClippingAncestors, rootBoundary]; + const firstClippingAncestor = clippingAncestors[0]; + const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => { + const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy); + accRect.top = max(rect.top, accRect.top); + accRect.right = min(rect.right, accRect.right); + accRect.bottom = min(rect.bottom, accRect.bottom); + accRect.left = max(rect.left, accRect.left); + return accRect; + }, getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy)); + return { + width: clippingRect.right - clippingRect.left, + height: clippingRect.bottom - clippingRect.top, + x: clippingRect.left, + y: clippingRect.top + }; +} + +function getDimensions(element) { + const { + width, + height + } = getCssDimensions(element); + return { + width, + height + }; +} + +function getRectRelativeToOffsetParent(element, offsetParent, strategy) { + const isOffsetParentAnElement = isHTMLElement(offsetParent); + const documentElement = getDocumentElement(offsetParent); + const isFixed = strategy === 'fixed'; + const rect = getBoundingClientRect(element, true, isFixed, offsetParent); + let scroll = { + scrollLeft: 0, + scrollTop: 0 + }; + const offsets = createCoords(0); + if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { + if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) { + scroll = getNodeScroll(offsetParent); + } + if (isOffsetParentAnElement) { + const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent); + offsets.x = offsetRect.x + offsetParent.clientLeft; + offsets.y = offsetRect.y + offsetParent.clientTop; + } else if (documentElement) { + // If the scrollbar appears on the left (e.g. RTL systems). Use + // Firefox with layout.scrollbar.side = 3 in about:config to test this. + offsets.x = getWindowScrollBarX(documentElement); + } + } + const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0); + const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x; + const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y; + return { + x, + y, + width: rect.width, + height: rect.height + }; +} + +function isStaticPositioned(element) { + return getComputedStyle$1(element).position === 'static'; +} + +function getTrueOffsetParent(element, polyfill) { + if (!isHTMLElement(element) || getComputedStyle$1(element).position === 'fixed') { + return null; + } + if (polyfill) { + return polyfill(element); + } + let rawOffsetParent = element.offsetParent; + + // Firefox returns the element as the offsetParent if it's non-static, + // while Chrome and Safari return the element. The element must + // be used to perform the correct calculations even if the element is + // non-static. + if (getDocumentElement(element) === rawOffsetParent) { + rawOffsetParent = rawOffsetParent.ownerDocument.body; + } + return rawOffsetParent; +} + +// Gets the closest ancestor positioned element. Handles some edge cases, +// such as table ancestors and cross browser bugs. +function getOffsetParent(element, polyfill) { + const win = getWindow(element); + if (isTopLayer(element)) { + return win; + } + if (!isHTMLElement(element)) { + let svgOffsetParent = getParentNode(element); + while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) { + if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) { + return svgOffsetParent; + } + svgOffsetParent = getParentNode(svgOffsetParent); + } + return win; + } + let offsetParent = getTrueOffsetParent(element, polyfill); + while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) { + offsetParent = getTrueOffsetParent(offsetParent, polyfill); + } + if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) { + return win; + } + return offsetParent || getContainingBlock(element) || win; +} + +const getElementRects = async function (data) { + const getOffsetParentFn = this.getOffsetParent || getOffsetParent; + const getDimensionsFn = this.getDimensions; + const floatingDimensions = await getDimensionsFn(data.floating); + return { + reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy), + floating: { + x: 0, + y: 0, + width: floatingDimensions.width, + height: floatingDimensions.height + } + }; +}; + +function isRTL(element) { + return getComputedStyle$1(element).direction === 'rtl'; +} + +const platform = { + convertOffsetParentRelativeRectToViewportRelativeRect, + getDocumentElement, + getClippingRect, + getOffsetParent, + getElementRects, + getClientRects, + getDimensions, + getScale, + isElement, + isRTL +}; + +// https://samthor.au/2021/observing-dom/ +function observeMove(element, onMove) { + let io = null; + let timeoutId; + const root = getDocumentElement(element); + function cleanup() { + var _io; + clearTimeout(timeoutId); + (_io = io) == null || _io.disconnect(); + io = null; + } + function refresh(skip, threshold) { + if (skip === void 0) { + skip = false; + } + if (threshold === void 0) { + threshold = 1; + } + cleanup(); + const { + left, + top, + width, + height + } = element.getBoundingClientRect(); + if (!skip) { + onMove(); + } + if (!width || !height) { + return; + } + const insetTop = floor(top); + const insetRight = floor(root.clientWidth - (left + width)); + const insetBottom = floor(root.clientHeight - (top + height)); + const insetLeft = floor(left); + const rootMargin = -insetTop + "px " + -insetRight + "px " + -insetBottom + "px " + -insetLeft + "px"; + const options = { + rootMargin, + threshold: max(0, min(1, threshold)) || 1 + }; + let isFirstUpdate = true; + function handleObserve(entries) { + const ratio = entries[0].intersectionRatio; + if (ratio !== threshold) { + if (!isFirstUpdate) { + return refresh(); + } + if (!ratio) { + // If the reference is clipped, the ratio is 0. Throttle the refresh + // to prevent an infinite loop of updates. + timeoutId = setTimeout(() => { + refresh(false, 1e-7); + }, 1000); + } else { + refresh(false, ratio); + } + } + isFirstUpdate = false; + } + + // Older browsers don't support a `document` as the root and will throw an + // error. + try { + io = new IntersectionObserver(handleObserve, { + ...options, + // Handle