diff --git a/components/dist/input.js b/components/dist/input.js
index f38e59c..4064b92 100644
--- a/components/dist/input.js
+++ b/components/dist/input.js
@@ -518,19 +518,13 @@ customElements.define('sm-input',
this.customValidation = config?.customValidation;
}
}
- updatePosition = (e = { type: '' }) => {
+ updatePosition = () => {
requestAnimationFrame(() => {
- if (!this.dimensions || e.type === 'resize') {
- this.scrollingParentDimensions = this.scrollingParent.getBoundingClientRect()
- }
this.dimensions = this.getBoundingClientRect()
if (this.dimensions.width === 0 || this.dimensions.height === 0) return;
- let topOffset = this.dimensions.top - this.scrollingParentDimensions.top + this.scrollingParent.scrollTop + this.dimensions.height;
- if (topOffset + this.feedbackPopover.offsetHeight > this.scrollingParentDimensions.height) {
- topOffset = this.dimensions.top - this.feedbackPopover.offsetHeight;
- }
- let leftOffset = this.dimensions.left - this.scrollingParentDimensions.left + this.scrollingParent.scrollLeft;
- const maxWidth = this.scrollingParentDimensions.width - this.dimensions.left
+ let topOffset = this.dimensions.top + this.dimensions.height;
+ let leftOffset = this.dimensions.left;
+ const maxWidth = this.dimensions.width
this.feedbackPopover.style = `top: ${topOffset}px; left: ${leftOffset}px; max-width: ${maxWidth}px;`
})
}
@@ -547,21 +541,19 @@ customElements.define('sm-input',
this.scrollingParent.style.position = 'relative'
if (!this.containment) {
this.observerHidFeedback = false;
- new IntersectionObserver((entries) => {
+ this.intersectionObserver = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
if (!this.observerHidFeedback) return;
this.feedbackPopover.classList.remove('hidden');
this.observerHidFeedback = false;
} else {
- if (this.feedbackPopover.classList.contains('hidden')) return;
- this.observerHidFeedback = true;
this.feedbackPopover.classList.add('hidden');
+ this.observerHidFeedback = true;
}
}).observe(this);
}
this.updatePosition()
window.addEventListener('resize', this.updatePosition, { passive: true })
- document.addEventListener('scroll', this.updatePosition, { passive: true, capture: true })
return true;
}
getNearestScrollingParent = (element) => {
@@ -599,7 +591,6 @@ customElements.define('sm-input',
this.feedbackPopover.remove();
this.feedbackPopover = null;
window.removeEventListener('resize', this.updatePosition, { passive: true })
- document.removeEventListener('scroll', this.updatePosition, { passive: true, capture: true })
}
}
connectedCallback() {
@@ -745,8 +736,9 @@ customElements.define('sm-input',
this.input.removeEventListener('focusin', this.handleFocus);
this.removeEventListener('focusout', this.handleBlur);
window.removeEventListener('resize', this.updatePosition, { passive: true })
- document.removeEventListener('scroll', this.updatePosition, { passive: true, capture: true })
if (this.feedbackPopover)
this.feedbackPopover.remove();
+ if (this.intersectionObserver)
+ this.intersectionObserver.disconnect();
}
- })
\ No newline at end of file
+ })
\ No newline at end of file
diff --git a/components/dist/input.min.js b/components/dist/input.min.js
index 18dec13..d146317 100644
--- a/components/dist/input.min.js
+++ b/components/dist/input.min.js
@@ -1 +1 @@
-const smInput=document.createElement("template");smInput.innerHTML='\n \n
\n ',customElements.define("sm-input",class SmInput extends HTMLElement{static hasAppendedStyles=!1;#validationState={validatedFor:void 0,isValid:!1,errorMessage:"Please fill out this field."};constructor(){super(),this.attachShadow({mode:"open"}).append(smInput.content.cloneNode(!0)),this.inputParent=this.shadowRoot.querySelector(".input"),this.input=this.shadowRoot.querySelector("input"),this.clearBtn=this.shadowRoot.querySelector(".clear"),this.placeholderElement=this.shadowRoot.querySelector(".placeholder"),this.outerContainer=this.shadowRoot.querySelector(".outer-container"),this.optionList=this.shadowRoot.querySelector(".datalist"),this._helperText="",this.isRequired=!1,this.datalist=[],this.validationFunction=void 0,this.reflectedAttributes=["value","required","disabled","type","inputmode","readonly","min","max","pattern","minlength","maxlength","step","list","autocomplete"]}static get observedAttributes(){return["value","placeholder","required","disabled","type","inputmode","readonly","min","max","pattern","minlength","maxlength","step","helper-text","error-text","list"]}get value(){return this.input.value}set value(val){val!==this.input.value&&(this.input.value=val,this._value=val,this.checkInput())}get placeholder(){return this.getAttribute("placeholder")}set placeholder(val){this.setAttribute("placeholder",val)}get type(){return this.getAttribute("type")}set type(val){this.setAttribute("type",val)}get validity(){return this.input.validity}get disabled(){return this.hasAttribute("disabled")}set disabled(value){value?(this.inputParent.classList.add("disabled"),this.setAttribute("disabled","")):(this.inputParent.classList.remove("disabled"),this.removeAttribute("disabled"))}get readOnly(){return this.hasAttribute("readonly")}set readOnly(value){value?this.setAttribute("readonly",""):this.removeAttribute("readonly")}set customValidation(val){val&&(this.validationFunction=val)}set errorText(val){this.#validationState.errorText=val}showError=(errorText=this.#validationState.errorText)=>{const appendedNew=this.appendFeedbackElement();this.feedbackPopover.innerHTML=`\n \n ${errorText}\n `,this.feedbackPopover.dataset.state="error",appendedNew&&this.feedbackPopover.animate([{transform:"scale(0.95)",opacity:0},{transform:"scale(1)",opacity:1}],{duration:200,easing:"ease",fill:"forwards"})};set helperText(val){this._helperText=val}get isValid(){if(this.#validationState.validatedFor===this.input.value)return this.#validationState.isValid;const _isValid=this.input.checkValidity();let _validity={isValid:!0,errorText:""};return this.validationFunction&&(_validity=this.validationFunction(this.input.value)),_isValid&&_validity.isValid?(this.setAttribute("valid",""),this.removeAttribute("invalid"),this.hideFeedback()):(this.removeAttribute("valid"),this.setAttribute("invalid",""),""!==this.value.trim()&&(_validity.errorText||this.#validationState.errorText)&&this.showError(_validity.errorText||this.#validationState.errorText)),this.#validationState.validatedFor=this.input.value,this.#validationState.isValid=_isValid&&_validity.isValid,this.#validationState.errorText=_validity.errorText||this.#validationState.errorText,this.#validationState.isValid}reset=()=>{this.value=""};clear=()=>{this.value="",this.input.focus(),this.fireEvent()};focusIn=()=>{this.input.focus()};focusOut=()=>{this.input.blur()};fireEvent=()=>{let event=new Event("input",{bubbles:!0,cancelable:!0,composed:!0});this.dispatchEvent(event)};searchDatalist=searchKey=>{const filteredData=this.datalist.filter((item=>item.toLowerCase().includes(searchKey.toLowerCase())));if(filteredData.sort(((a,b)=>a.toLowerCase().indexOf(searchKey.toLowerCase())-b.toLowerCase().indexOf(searchKey.toLowerCase()))),filteredData.length){if(this.optionList.children.length>filteredData.length){const optionsToRemove=this.optionList.children.length-filteredData.length;for(let i=0;i{if(this.optionList.children[index])this.optionList.children[index].textContent=item;else{const option=document.createElement("li");option.textContent=item,option.classList.add("datalist-item"),option.setAttribute("tabindex","0"),this.optionList.appendChild(option)}})),this.optionList.classList.remove("hidden")}else this.optionList.classList.add("hidden")};checkInput=e=>{this.hasAttribute("readonly")||(""!==this.input.value?this.clearBtn.classList.remove("hidden"):this.clearBtn.classList.add("hidden")),this.hasAttribute("placeholder")&&""!==this.getAttribute("placeholder").trim()&&(""!==this.input.value?(this.shouldAnimatePlaceholder&&this.inputParent.classList.add("animate-placeholder"),this.placeholderElement.classList.toggle("hidden",!this.shouldAnimatePlaceholder),this.datalist.length&&(this.searchTimeout&&clearTimeout(this.searchTimeout),this.searchTimeout=setTimeout((()=>{this.searchDatalist(this.input.value.trim())}),100))):(this.shouldAnimatePlaceholder&&this.inputParent.classList.remove("animate-placeholder"),this.placeholderElement.classList.remove("hidden"),this.hideFeedback(),this.datalist.length&&(this.optionList.innerHTML="",this.optionList.classList.add("hidden"))))};allowOnlyNum=e=>{e.ctrlKey||1===e.key.length&&(("."!==e.key||!e.target.value.includes(".")&&0!==e.target.value.length)&&["0","1","2","3","4","5","6","7","8","9","."].includes(e.key)||e.preventDefault())};handleOptionClick=e=>{this.input.value=e.target.textContent,this.optionList.classList.add("hidden"),this.input.focus()};handleInputNavigation=e=>{"ArrowDown"===e.key?(e.preventDefault(),this.optionList.children.length&&this.optionList.children[0].focus()):"ArrowUp"===e.key&&(e.preventDefault(),this.optionList.children.length&&this.optionList.children[this.optionList.children.length-1].focus())};handleDatalistNavigation=e=>{"ArrowUp"===e.key?(e.preventDefault(),this.shadowRoot.activeElement.previousElementSibling?this.shadowRoot.activeElement.previousElementSibling.focus():this.input.focus()):"ArrowDown"===e.key?(e.preventDefault(),this.shadowRoot.activeElement.nextElementSibling?this.shadowRoot.activeElement.nextElementSibling.focus():this.input.focus()):"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.input.value=e.target.textContent,this.optionList.classList.add("hidden"),this.input.focus())};handleFocus=e=>{this.datalist.length&&this.searchDatalist(this.input.value.trim())};handleBlur=e=>{this.datalist.length&&this.optionList.classList.add("hidden")};applyGlobalCustomValidation=()=>{if(void 0!==window.smCompConfig&&window.smCompConfig["sm-input"]){const config=window.smCompConfig["sm-input"].find((config=>this.matches(config.selector)));this.customValidation=config?.customValidation}};updatePosition=(e={type:""})=>{requestAnimationFrame((()=>{if(this.dimensions&&"resize"!==e.type||(this.scrollingParentDimensions=this.scrollingParent.getBoundingClientRect()),this.dimensions=this.getBoundingClientRect(),0===this.dimensions.width||0===this.dimensions.height)return;let topOffset=this.dimensions.top-this.scrollingParentDimensions.top+this.scrollingParent.scrollTop+this.dimensions.height;topOffset+this.feedbackPopover.offsetHeight>this.scrollingParentDimensions.height&&(topOffset=this.dimensions.top-this.feedbackPopover.offsetHeight);let leftOffset=this.dimensions.left-this.scrollingParentDimensions.left+this.scrollingParent.scrollLeft;const maxWidth=this.scrollingParentDimensions.width-this.dimensions.left;this.feedbackPopover.style=`top: ${topOffset}px; left: ${leftOffset}px; max-width: ${maxWidth}px;`}))};appendFeedbackElement=()=>{if(this.feedbackPopover)return!1;this.feedbackPopover=document.createElement("div"),this.feedbackPopover.className="feedback-popover",this.feedbackPopover.setAttribute("aria-live","polite"),this.containment=this.closest("[data-sm-containment]"),this.scrollingParent=this.getNearestScrollingParent(this);return(this.containment||this.scrollingParent).appendChild(this.feedbackPopover),""===this.scrollingParent.style.position&&(this.scrollingParent.style.position="relative"),this.containment||(this.observerHidFeedback=!1,new IntersectionObserver((entries=>{if(entries[0].isIntersecting){if(!this.observerHidFeedback)return;this.feedbackPopover.classList.remove("hidden"),this.observerHidFeedback=!1}else{if(this.feedbackPopover.classList.contains("hidden"))return;this.observerHidFeedback=!0,this.feedbackPopover.classList.add("hidden")}})).observe(this)),this.updatePosition(),window.addEventListener("resize",this.updatePosition,{passive:!0}),document.addEventListener("scroll",this.updatePosition,{passive:!0,capture:!0}),!0};getNearestScrollingParent=element=>{const scrollingParent=element.closest("[data-scrollable]");if(scrollingParent)return scrollingParent;let parent=element.parentNode;for(;parent;){if(parent.scrollHeight>parent.clientHeight||parent.scrollWidth>parent.clientWidth)return parent;parent=parent.parentNode}return document.body};hideFeedback=()=>{this.feedbackPopover&&(this.feedbackPopover.animate([{transform:"none",opacity:1},{transform:"scale(0.95)",opacity:0}],{duration:100,easing:"ease-in-out",fill:"forwards"}).onfinish=()=>{this.feedbackPopover.remove(),this.feedbackPopover=null,window.removeEventListener("resize",this.updatePosition,{passive:!0}),document.removeEventListener("scroll",this.updatePosition,{passive:!0,capture:!0})})};connectedCallback(){SmInput.hasAppendedStyles||(document.head.insertAdjacentHTML("beforeend",""),SmInput.hasAppendedStyles=!0),this.shouldAnimatePlaceholder=this.hasAttribute("animate"),this.shouldAnimatePlaceholder&&""!==this.placeholderElement&&this.value&&(this.inputParent.classList.add("animate-placeholder"),this.placeholderElement.classList.remove("hidden")),this.setAttribute("role","textbox"),"loading"===document.readyState?window.addEventListener("load",this.applyGlobalCustomValidation,{once:!0}):this.applyGlobalCustomValidation(),this.input.addEventListener("input",this.checkInput),this.clearBtn.addEventListener("click",this.clear),this.datalist.length&&(this.optionList.addEventListener("click",this.handleOptionClick),this.input.addEventListener("keydown",this.handleInputNavigation),this.optionList.addEventListener("keydown",this.handleDatalistNavigation)),this.input.addEventListener("focusin",this.handleFocus),this.addEventListener("focusout",this.handleBlur)}attributeChangedCallback(name,oldValue,newValue){if(oldValue!==newValue)switch(this.reflectedAttributes.includes(name)&&(this.hasAttribute(name)?this.input.setAttribute(name,this.getAttribute(name)?this.getAttribute(name):""):this.input.removeAttribute(name)),name){case"placeholder":this.placeholderElement.textContent=newValue,this.setAttribute("aria-label",newValue);break;case"value":this.checkInput();break;case"type":this.hasAttribute("type")&&"number"===this.getAttribute("type")?(this.input.setAttribute("inputmode","decimal"),this.input.addEventListener("keydown",this.allowOnlyNum)):this.input.removeEventListener("keydown",this.allowOnlyNum);break;case"helper-text":this._helperText=newValue;break;case"error-text":this.#validationState.errorText=newValue;break;case"required":this.isRequired=this.hasAttribute("required"),this.isRequired?this.setAttribute("aria-required","true"):this.setAttribute("aria-required","false");break;case"readonly":this.hasAttribute("readonly")?this.inputParent.classList.add("readonly"):this.inputParent.classList.remove("readonly");break;case"disabled":this.hasAttribute("disabled")?this.inputParent.classList.add("disabled"):this.inputParent.classList.remove("disabled");break;case"list":this.hasAttribute("list")&&""!==this.getAttribute("list").trim()&&(this.datalist=this.getAttribute("list").split(","))}}disconnectedCallback(){this.input.removeEventListener("input",this.checkInput),this.clearBtn.removeEventListener("click",this.clear),this.input.removeEventListener("keydown",this.allowOnlyNum),this.optionList.removeEventListener("click",this.handleOptionClick),this.input.removeEventListener("keydown",this.handleInputNavigation),this.optionList.removeEventListener("keydown",this.handleDatalistNavigation),this.input.removeEventListener("focusin",this.handleFocus),this.removeEventListener("focusout",this.handleBlur),window.removeEventListener("resize",this.updatePosition,{passive:!0}),document.removeEventListener("scroll",this.updatePosition,{passive:!0,capture:!0}),this.feedbackPopover&&this.feedbackPopover.remove()}});
\ No newline at end of file
+const smInput=document.createElement("template");smInput.innerHTML='\n \n \n ',customElements.define("sm-input",class SmInput extends HTMLElement{static hasAppendedStyles=!1;#validationState={validatedFor:void 0,isValid:!1,errorMessage:"Please fill out this field."};constructor(){super(),this.attachShadow({mode:"open"}).append(smInput.content.cloneNode(!0)),this.inputParent=this.shadowRoot.querySelector(".input"),this.input=this.shadowRoot.querySelector("input"),this.clearBtn=this.shadowRoot.querySelector(".clear"),this.placeholderElement=this.shadowRoot.querySelector(".placeholder"),this.outerContainer=this.shadowRoot.querySelector(".outer-container"),this.optionList=this.shadowRoot.querySelector(".datalist"),this._helperText="",this.isRequired=!1,this.datalist=[],this.validationFunction=void 0,this.reflectedAttributes=["value","required","disabled","type","inputmode","readonly","min","max","pattern","minlength","maxlength","step","list","autocomplete"]}static get observedAttributes(){return["value","placeholder","required","disabled","type","inputmode","readonly","min","max","pattern","minlength","maxlength","step","helper-text","error-text","list"]}get value(){return this.input.value}set value(val){val!==this.input.value&&(this.input.value=val,this._value=val,this.checkInput())}get placeholder(){return this.getAttribute("placeholder")}set placeholder(val){this.setAttribute("placeholder",val)}get type(){return this.getAttribute("type")}set type(val){this.setAttribute("type",val)}get validity(){return this.input.validity}get disabled(){return this.hasAttribute("disabled")}set disabled(value){value?(this.inputParent.classList.add("disabled"),this.setAttribute("disabled","")):(this.inputParent.classList.remove("disabled"),this.removeAttribute("disabled"))}get readOnly(){return this.hasAttribute("readonly")}set readOnly(value){value?this.setAttribute("readonly",""):this.removeAttribute("readonly")}set customValidation(val){val&&(this.validationFunction=val)}set errorText(val){this.#validationState.errorText=val}showError=(errorText=this.#validationState.errorText)=>{const appendedNew=this.appendFeedbackElement();this.feedbackPopover.innerHTML=`\n \n ${errorText}\n `,this.feedbackPopover.dataset.state="error",appendedNew&&this.feedbackPopover.animate([{transform:"scale(0.95)",opacity:0},{transform:"scale(1)",opacity:1}],{duration:200,easing:"ease",fill:"forwards"})};set helperText(val){this._helperText=val}get isValid(){if(this.#validationState.validatedFor===this.input.value)return this.#validationState.isValid;const _isValid=this.input.checkValidity();let _validity={isValid:!0,errorText:""};return this.validationFunction&&(_validity=this.validationFunction(this.input.value)),_isValid&&_validity.isValid?(this.setAttribute("valid",""),this.removeAttribute("invalid"),this.hideFeedback()):(this.removeAttribute("valid"),this.setAttribute("invalid",""),""!==this.value.trim()&&(_validity.errorText||this.#validationState.errorText)&&this.showError(_validity.errorText||this.#validationState.errorText)),this.#validationState.validatedFor=this.input.value,this.#validationState.isValid=_isValid&&_validity.isValid,this.#validationState.errorText=_validity.errorText||this.#validationState.errorText,this.#validationState.isValid}reset=()=>{this.value=""};clear=()=>{this.value="",this.input.focus(),this.fireEvent()};focusIn=()=>{this.input.focus()};focusOut=()=>{this.input.blur()};fireEvent=()=>{let event=new Event("input",{bubbles:!0,cancelable:!0,composed:!0});this.dispatchEvent(event)};searchDatalist=searchKey=>{const filteredData=this.datalist.filter((item=>item.toLowerCase().includes(searchKey.toLowerCase())));if(filteredData.sort(((a,b)=>a.toLowerCase().indexOf(searchKey.toLowerCase())-b.toLowerCase().indexOf(searchKey.toLowerCase()))),filteredData.length){if(this.optionList.children.length>filteredData.length){const optionsToRemove=this.optionList.children.length-filteredData.length;for(let i=0;i{if(this.optionList.children[index])this.optionList.children[index].textContent=item;else{const option=document.createElement("li");option.textContent=item,option.classList.add("datalist-item"),option.setAttribute("tabindex","0"),this.optionList.appendChild(option)}})),this.optionList.classList.remove("hidden")}else this.optionList.classList.add("hidden")};checkInput=e=>{this.hasAttribute("readonly")||(""!==this.input.value?this.clearBtn.classList.remove("hidden"):this.clearBtn.classList.add("hidden")),this.hasAttribute("placeholder")&&""!==this.getAttribute("placeholder").trim()&&(""!==this.input.value?(this.shouldAnimatePlaceholder&&this.inputParent.classList.add("animate-placeholder"),this.placeholderElement.classList.toggle("hidden",!this.shouldAnimatePlaceholder),this.datalist.length&&(this.searchTimeout&&clearTimeout(this.searchTimeout),this.searchTimeout=setTimeout((()=>{this.searchDatalist(this.input.value.trim())}),100))):(this.shouldAnimatePlaceholder&&this.inputParent.classList.remove("animate-placeholder"),this.placeholderElement.classList.remove("hidden"),this.hideFeedback(),this.datalist.length&&(this.optionList.innerHTML="",this.optionList.classList.add("hidden"))))};allowOnlyNum=e=>{e.ctrlKey||1===e.key.length&&(("."!==e.key||!e.target.value.includes(".")&&0!==e.target.value.length)&&["0","1","2","3","4","5","6","7","8","9","."].includes(e.key)||e.preventDefault())};handleOptionClick=e=>{this.input.value=e.target.textContent,this.optionList.classList.add("hidden"),this.input.focus()};handleInputNavigation=e=>{"ArrowDown"===e.key?(e.preventDefault(),this.optionList.children.length&&this.optionList.children[0].focus()):"ArrowUp"===e.key&&(e.preventDefault(),this.optionList.children.length&&this.optionList.children[this.optionList.children.length-1].focus())};handleDatalistNavigation=e=>{"ArrowUp"===e.key?(e.preventDefault(),this.shadowRoot.activeElement.previousElementSibling?this.shadowRoot.activeElement.previousElementSibling.focus():this.input.focus()):"ArrowDown"===e.key?(e.preventDefault(),this.shadowRoot.activeElement.nextElementSibling?this.shadowRoot.activeElement.nextElementSibling.focus():this.input.focus()):"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),this.input.value=e.target.textContent,this.optionList.classList.add("hidden"),this.input.focus())};handleFocus=e=>{this.datalist.length&&this.searchDatalist(this.input.value.trim())};handleBlur=e=>{this.datalist.length&&this.optionList.classList.add("hidden")};applyGlobalCustomValidation=()=>{if(void 0!==window.smCompConfig&&window.smCompConfig["sm-input"]){const config=window.smCompConfig["sm-input"].find((config=>this.matches(config.selector)));this.customValidation=config?.customValidation}};updatePosition=()=>{requestAnimationFrame((()=>{if(this.dimensions=this.getBoundingClientRect(),0===this.dimensions.width||0===this.dimensions.height)return;let topOffset=this.dimensions.top+this.dimensions.height,leftOffset=this.dimensions.left;const maxWidth=this.dimensions.width;this.feedbackPopover.style=`top: ${topOffset}px; left: ${leftOffset}px; max-width: ${maxWidth}px;`}))};appendFeedbackElement=()=>{if(this.feedbackPopover)return!1;this.feedbackPopover=document.createElement("div"),this.feedbackPopover.className="feedback-popover",this.feedbackPopover.setAttribute("aria-live","polite"),this.containment=this.closest("[data-sm-containment]"),this.scrollingParent=this.getNearestScrollingParent(this);return(this.containment||this.scrollingParent).appendChild(this.feedbackPopover),""===this.scrollingParent.style.position&&(this.scrollingParent.style.position="relative"),this.containment||(this.observerHidFeedback=!1,this.intersectionObserver=new IntersectionObserver((entries=>{if(entries[0].isIntersecting){if(!this.observerHidFeedback)return;this.feedbackPopover.classList.remove("hidden"),this.observerHidFeedback=!1}else this.feedbackPopover.classList.add("hidden"),this.observerHidFeedback=!0})).observe(this)),this.updatePosition(),window.addEventListener("resize",this.updatePosition,{passive:!0}),!0};getNearestScrollingParent=element=>{const scrollingParent=element.closest("[data-scrollable]");if(scrollingParent)return scrollingParent;let parent=element.parentNode;for(;parent;){if(parent.scrollHeight>parent.clientHeight||parent.scrollWidth>parent.clientWidth)return parent;parent=parent.parentNode}return document.body};hideFeedback=()=>{this.feedbackPopover&&(this.feedbackPopover.animate([{transform:"none",opacity:1},{transform:"scale(0.95)",opacity:0}],{duration:100,easing:"ease-in-out",fill:"forwards"}).onfinish=()=>{this.feedbackPopover.remove(),this.feedbackPopover=null,window.removeEventListener("resize",this.updatePosition,{passive:!0})})};connectedCallback(){SmInput.hasAppendedStyles||(document.head.insertAdjacentHTML("beforeend",""),SmInput.hasAppendedStyles=!0),this.shouldAnimatePlaceholder=this.hasAttribute("animate"),this.shouldAnimatePlaceholder&&""!==this.placeholderElement&&this.value&&(this.inputParent.classList.add("animate-placeholder"),this.placeholderElement.classList.remove("hidden")),this.setAttribute("role","textbox"),"loading"===document.readyState?window.addEventListener("load",this.applyGlobalCustomValidation,{once:!0}):this.applyGlobalCustomValidation(),this.input.addEventListener("input",this.checkInput),this.clearBtn.addEventListener("click",this.clear),this.datalist.length&&(this.optionList.addEventListener("click",this.handleOptionClick),this.input.addEventListener("keydown",this.handleInputNavigation),this.optionList.addEventListener("keydown",this.handleDatalistNavigation)),this.input.addEventListener("focusin",this.handleFocus),this.addEventListener("focusout",this.handleBlur)}attributeChangedCallback(name,oldValue,newValue){if(oldValue!==newValue)switch(this.reflectedAttributes.includes(name)&&(this.hasAttribute(name)?this.input.setAttribute(name,this.getAttribute(name)?this.getAttribute(name):""):this.input.removeAttribute(name)),name){case"placeholder":this.placeholderElement.textContent=newValue,this.setAttribute("aria-label",newValue);break;case"value":this.checkInput();break;case"type":this.hasAttribute("type")&&"number"===this.getAttribute("type")?(this.input.setAttribute("inputmode","decimal"),this.input.addEventListener("keydown",this.allowOnlyNum)):this.input.removeEventListener("keydown",this.allowOnlyNum);break;case"helper-text":this._helperText=newValue;break;case"error-text":this.#validationState.errorText=newValue;break;case"required":this.isRequired=this.hasAttribute("required"),this.isRequired?this.setAttribute("aria-required","true"):this.setAttribute("aria-required","false");break;case"readonly":this.hasAttribute("readonly")?this.inputParent.classList.add("readonly"):this.inputParent.classList.remove("readonly");break;case"disabled":this.hasAttribute("disabled")?this.inputParent.classList.add("disabled"):this.inputParent.classList.remove("disabled");break;case"list":this.hasAttribute("list")&&""!==this.getAttribute("list").trim()&&(this.datalist=this.getAttribute("list").split(","))}}disconnectedCallback(){this.input.removeEventListener("input",this.checkInput),this.clearBtn.removeEventListener("click",this.clear),this.input.removeEventListener("keydown",this.allowOnlyNum),this.optionList.removeEventListener("click",this.handleOptionClick),this.input.removeEventListener("keydown",this.handleInputNavigation),this.optionList.removeEventListener("keydown",this.handleDatalistNavigation),this.input.removeEventListener("focusin",this.handleFocus),this.removeEventListener("focusout",this.handleBlur),window.removeEventListener("resize",this.updatePosition,{passive:!0}),this.feedbackPopover&&this.feedbackPopover.remove(),this.intersectionObserver&&this.intersectionObserver.disconnect()}});
\ No newline at end of file
diff --git a/components/dist/popup.js b/components/dist/popup.js
index cb815a0..add79a4 100644
--- a/components/dist/popup.js
+++ b/components/dist/popup.js
@@ -18,7 +18,7 @@ class Stack {
const popupStack = new Stack();
const smPopup = document.createElement('template');
-smPopup.innerHTML = `
+smPopup.innerHTML = /*html*/`
`, customElements.define("sm-popup", class extends HTMLElement { constructor() { super(), this.attachShadow({ mode: "open" }).append(smPopup.content.cloneNode(!0)), this.allowClosing = !1, this.isOpen = !1, this.offset = 0, this.touchStartY = 0, this.touchEndY = 0, this.touchStartTime = 0, this.touchEndTime = 0, this.touchEndAnimation = void 0, this.focusable, this.autoFocus, this.mutationObserver, this.popupContainer = this.shadowRoot.querySelector(".popup-container"), this.backdrop = this.shadowRoot.querySelector(".backdrop"), this.dialogBox = this.shadowRoot.querySelector(".popup"), this.popupBodySlot = this.shadowRoot.querySelector(".popup-body slot"), this.popupHeader = this.shadowRoot.querySelector(".popup-top"), this.resumeScrolling = this.resumeScrolling.bind(this), this.setStateOpen = this.setStateOpen.bind(this), this.show = this.show.bind(this), this.hide = this.hide.bind(this), this.handleTouchStart = this.handleTouchStart.bind(this), this.handleTouchMove = this.handleTouchMove.bind(this), this.handleTouchEnd = this.handleTouchEnd.bind(this), this.detectFocus = this.detectFocus.bind(this), this.handleSoftDismiss = this.handleSoftDismiss.bind(this), this.debounce = this.debounce.bind(this) } static get observedAttributes() { return ["open"] } get open() { return this.isOpen } animateTo(t, e, i) { let s = t.animate(e, { ...i, fill: "both" }); return s.finished.then(() => { s.commitStyles(), s.cancel() }), s } resumeScrolling() { let t = document.body.style.top; window.scrollTo(0, -1 * parseInt(t || "0")), document.body.style.overflow = "", document.body.style.top = "initial" } setStateOpen() { if (!this.isOpen || this.offset) { let t = window.innerWidth > 640 ? "scale(1.1)" : `translateY(${this.offset ? `${this.offset}px` : "100%"})`; this.animateTo(this.dialogBox, [{ opacity: this.offset ? 1 : 0, transform: t }, { opacity: 1, transform: "none" },], { duration: 300, easing: "ease" }) } } show(t = {}) { let { pinned: e = !1, payload: i } = t; if (this.isOpen) return; let s = { duration: 300, easing: "ease" }; return this.payload = i, popupStack.push({ popup: this, permission: e }), popupStack.items.length > 1 && this.animateTo(popupStack.items[popupStack.items.length - 2].popup.shadowRoot.querySelector(".popup"), [{ transform: "none" }, { transform: window.innerWidth > 640 ? "scale(0.95)" : "translateY(-1.5rem)" },], s), this.popupContainer.classList.remove("hide"), this.offset || (this.backdrop.animate([{ opacity: 0 }, { opacity: 1 },], s).onfinish = () => { this.resolveOpen(this.payload) }, this.dispatchEvent(new CustomEvent("popupopened", { bubbles: !0, composed: !0, detail: { payload: this.payload } })), document.body.style.overflow = "hidden", document.body.style.top = `-${window.scrollY}px`), this.setStateOpen(), this.pinned = e, this.isOpen = !0, setTimeout(() => { let t = this.autoFocus || this.focusable?.[0] || this.dialogBox; t && (t.tagName.includes("-") ? t.focusIn() : t.focus()) }, 0), this.hasAttribute("open") || (this.setAttribute("open", ""), this.addEventListener("keydown", this.detectFocus), this.resizeObserver.observe(this), this.mutationObserver.observe(this, { attributes: !0, childList: !0, subtree: !0 }), this.popupHeader.addEventListener("touchstart", this.handleTouchStart, { passive: !0 }), this.backdrop.addEventListener("mousedown", this.handleSoftDismiss)), { opened: new Promise(t => { this.resolveOpen = t }), closed: new Promise(t => { this.resolveClose = t }) } } hide(t = {}) { let { payload: e } = t, i = { duration: 150, easing: "ease" }; this.backdrop.animate([{ opacity: 1 }, { opacity: 0 }], i), this.animateTo(this.dialogBox, [{ opacity: 1, transform: window.innerWidth > 640 ? "none" : `translateY(${this.offset ? `${this.offset}px` : "0"})` }, { opacity: 0, transform: window.innerWidth > 640 ? "scale(1.1)" : "translateY(100%)" },], i).finished.finally(() => { this.popupContainer.classList.add("hide"), this.dialogBox.style = "", this.removeAttribute("open"), this.forms.length && this.forms.forEach(t => t.reset()), this.dispatchEvent(new CustomEvent("popupclosed", { bubbles: !0, composed: !0, detail: { payload: e || this.payload } })), this.resolveClose(e || this.payload), this.isOpen = !1 }), popupStack.pop(), popupStack.items.length ? this.animateTo(popupStack.items[popupStack.items.length - 1].popup.shadowRoot.querySelector(".popup"), [{ transform: window.innerWidth > 640 ? "scale(0.95)" : "translateY(-1.5rem)" }, { transform: "none" },], i) : this.resumeScrolling(), this.resizeObserver.disconnect(), this.mutationObserver.disconnect(), this.removeEventListener("keydown", this.detectFocus), this.popupHeader.removeEventListener("touchstart", this.handleTouchStart, { passive: !0 }), this.backdrop.removeEventListener("mousedown", this.handleSoftDismiss) } handleTouchStart(t) { this.offset = 0, this.popupHeader.addEventListener("touchmove", this.handleTouchMove, { passive: !0 }), this.popupHeader.addEventListener("touchend", this.handleTouchEnd, { passive: !0 }), this.touchStartY = t.changedTouches[0].clientY, this.touchStartTime = t.timeStamp } handleTouchMove(t) { this.touchStartY < t.changedTouches[0].clientY && (this.offset = t.changedTouches[0].clientY - this.touchStartY, this.touchEndAnimation = window.requestAnimationFrame(() => { this.dialogBox.style.transform = `translateY(${this.offset}px)` })) } handleTouchEnd(t) { if (this.touchEndTime = t.timeStamp, cancelAnimationFrame(this.touchEndAnimation), this.touchEndY = t.changedTouches[0].clientY, this.threshold = .3 * this.dialogBox.getBoundingClientRect().height, this.touchEndTime - this.touchStartTime > 200) { if (this.touchEndY - this.touchStartY > this.threshold) { if (this.pinned) { this.setStateOpen(); return } this.hide() } else this.setStateOpen() } else if (this.touchEndY > this.touchStartY) { if (this.pinned) { this.setStateOpen(); return } this.hide() } this.popupHeader.removeEventListener("touchmove", this.handleTouchMove, { passive: !0 }), this.popupHeader.removeEventListener("touchend", this.handleTouchEnd, { passive: !0 }) } detectFocus(t) { if ("Tab" === t.key && this.focusable.length) { if (!this.firstFocusable) { for (let e = 0; e < this.focusable.length; e++)if (!this.focusable[e].disabled) { this.firstFocusable = this.focusable[e]; break } } if (!this.lastFocusable) { for (let i = this.focusable.length - 1; i >= 0; i--)if (!this.focusable[i].disabled) { this.lastFocusable = this.focusable[i]; break } } t.shiftKey && document.activeElement === this.firstFocusable ? (t.preventDefault(), this.lastFocusable.tagName.includes("SM-") ? this.lastFocusable.focusIn() : this.lastFocusable.focus()) : t.shiftKey || document.activeElement !== this.lastFocusable || (t.preventDefault(), this.firstFocusable.tagName.includes("SM-") ? this.firstFocusable.focusIn() : this.firstFocusable.focus()) } } updateFocusableList() { this.focusable = this.querySelectorAll('sm-button:not([disabled]), button:not([disabled]), [href], sm-input, input:not([readonly]), sm-select, select, sm-checkbox, sm-textarea, textarea, [tabindex]:not([tabindex="-1"])'), this.autoFocus = this.querySelector("[autofocus]"), this.firstFocusable = null, this.lastFocusable = null } handleSoftDismiss() { this.pinned ? this.dialogBox.animate([{ transform: "translateX(-1rem)" }, { transform: "translateX(1rem)" }, { transform: "translateX(-0.5rem)" }, { transform: "translateX(0.5rem)" }, { transform: "translateX(0)" },], { duration: 300, easing: "ease" }) : this.hide() } debounce(t, e) { let i = null; return (...s) => { window.clearTimeout(i), i = window.setTimeout(() => { t.apply(null, s) }, e) } } connectedCallback() { this.popupBodySlot.addEventListener("slotchange", this.debounce(() => { this.forms = this.querySelectorAll("sm-form"), this.updateFocusableList() }, 0)), this.resizeObserver = new ResizeObserver(t => { t.forEach(t => { if (t.contentBoxSize) { let e = Array.isArray(t.contentBoxSize) ? t.contentBoxSize[0] : t.contentBoxSize; this.threshold = .3 * e.blockSize.height } else this.threshold = .3 * t.contentRect.height }) }), this.mutationObserver = new MutationObserver(t => { this.updateFocusableList() }) } disconnectedCallback() { this.resizeObserver.disconnect(), this.mutationObserver.disconnect(), this.removeEventListener("keydown", this.detectFocus), this.popupHeader.removeEventListener("touchstart", this.handleTouchStart, { passive: !0 }), this.backdrop.removeEventListener("mousedown", this.handleSoftDismiss) } attributeChangedCallback(t) { "open" === t && this.hasAttribute("open") && this.show() } });
\ No newline at end of file
+class Stack{constructor(){this.items=[]}push(element){this.items.push(element)}pop(){return 0==this.items.length?"Underflow":this.items.pop()}peek(){return this.items[this.items.length-1]}}const popupStack=new Stack,smPopup=document.createElement("template");smPopup.innerHTML='\n\n\n',customElements.define("sm-popup",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smPopup.content.cloneNode(!0)),this.allowClosing=!1,this.isOpen=!1,this.offset=0,this.touchStartY=0,this.touchEndY=0,this.touchStartTime=0,this.touchEndTime=0,this.touchEndAnimation=void 0,this.focusable,this.autoFocus,this.mutationObserver,this.popupContainer=this.shadowRoot.querySelector(".popup-container"),this.backdrop=this.shadowRoot.querySelector(".backdrop"),this.dialogBox=this.shadowRoot.querySelector(".popup"),this.popupBodySlot=this.shadowRoot.querySelector(".popup-body slot"),this.popupHeader=this.shadowRoot.querySelector(".popup-top")}static get observedAttributes(){return["open"]}get open(){return this.isOpen}animateTo=(element,keyframes,options)=>{const anime=element.animate(keyframes,{...options,fill:"both"});return anime.finished.then((()=>{anime.commitStyles(),anime.cancel()})),anime};resumeScrolling=()=>{const scrollY=document.body.style.top;window.scrollTo(0,-1*parseInt(scrollY||"0")),document.body.style.overflow="",document.body.style.top="initial"};setStateOpen=()=>{if(!this.isOpen||this.offset){const animOptions={duration:300,easing:"ease"},initialAnimation=window.innerWidth>640?"scale(1.1)":`translateY(${this.offset?`${this.offset}px`:"100%"})`;this.animateTo(this.dialogBox,[{opacity:this.offset?1:0,transform:initialAnimation},{opacity:1,transform:"none"}],animOptions)}};show=(options={})=>{const{pinned:pinned=!1,payload:payload}=options;if(this.isOpen)return;const animOptions={duration:300,easing:"ease"};return this.payload=payload,popupStack.push({popup:this,permission:pinned}),popupStack.items.length>1&&this.animateTo(popupStack.items[popupStack.items.length-2].popup.shadowRoot.querySelector(".popup"),[{transform:"none"},{transform:window.innerWidth>640?"scale(0.95)":"translateY(-1.5rem)"}],animOptions),this.popupContainer.classList.remove("hide"),this.offset||(this.backdrop.animate([{opacity:0},{opacity:1}],animOptions).onfinish=()=>{this.resolveOpen(this.payload)},this.dispatchEvent(new CustomEvent("popupopened",{bubbles:!0,composed:!0,detail:{payload:this.payload}})),document.body.style.overflow="hidden",document.body.style.top=`-${window.scrollY}px`),this.setStateOpen(),this.pinned=pinned,this.isOpen=!0,setTimeout((()=>{const elementToFocus=this.autoFocus||this.focusable?.[0]||this.dialogBox;elementToFocus&&(elementToFocus.tagName.includes("-")?elementToFocus.focusIn():elementToFocus.focus())}),0),this.hasAttribute("open")||(this.setAttribute("open",""),this.addEventListener("keydown",this.detectFocus),this.resizeObserver.observe(this),this.mutationObserver.observe(this,{attributes:!0,childList:!0,subtree:!0}),this.popupHeader.addEventListener("touchstart",this.handleTouchStart,{passive:!0}),this.backdrop.addEventListener("mousedown",this.handleSoftDismiss)),{opened:new Promise((resolve=>{this.resolveOpen=resolve})),closed:new Promise((resolve=>{this.resolveClose=resolve}))}};hide=(options={})=>{const{payload:payload}=options,animOptions={duration:150,easing:"ease"};this.backdrop.animate([{opacity:1},{opacity:0}],animOptions),this.animateTo(this.dialogBox,[{opacity:1,transform:window.innerWidth>640?"none":`translateY(${this.offset?`${this.offset}px`:"0"})`},{opacity:0,transform:window.innerWidth>640?"scale(1.1)":"translateY(100%)"}],animOptions).finished.finally((()=>{this.popupContainer.classList.add("hide"),this.dialogBox.style="",this.removeAttribute("open"),this.forms.length&&this.forms.forEach((form=>form.reset())),this.dispatchEvent(new CustomEvent("popupclosed",{bubbles:!0,composed:!0,detail:{payload:payload||this.payload}})),this.resolveClose(payload||this.payload),this.isOpen=!1})),popupStack.pop(),popupStack.items.length?this.animateTo(popupStack.items[popupStack.items.length-1].popup.shadowRoot.querySelector(".popup"),[{transform:window.innerWidth>640?"scale(0.95)":"translateY(-1.5rem)"},{transform:"none"}],animOptions):this.resumeScrolling(),this.resizeObserver.disconnect(),this.mutationObserver.disconnect(),this.removeEventListener("keydown",this.detectFocus),this.popupHeader.removeEventListener("touchstart",this.handleTouchStart,{passive:!0}),this.backdrop.removeEventListener("mousedown",this.handleSoftDismiss)};handleTouchStart=e=>{this.offset=0,this.popupHeader.addEventListener("touchmove",this.handleTouchMove,{passive:!0}),this.popupHeader.addEventListener("touchend",this.handleTouchEnd,{passive:!0}),this.touchStartY=e.changedTouches[0].clientY,this.touchStartTime=e.timeStamp};handleTouchMove=e=>{this.touchStartY{this.dialogBox.style.transform=`translateY(${this.offset}px)`})))};handleTouchEnd=e=>{if(this.touchEndTime=e.timeStamp,cancelAnimationFrame(this.touchEndAnimation),this.touchEndY=e.changedTouches[0].clientY,this.threshold=.3*this.dialogBox.getBoundingClientRect().height,this.touchEndTime-this.touchStartTime>200)if(this.touchEndY-this.touchStartY>this.threshold){if(this.pinned)return void this.setStateOpen();this.hide()}else this.setStateOpen();else if(this.touchEndY>this.touchStartY){if(this.pinned)return void this.setStateOpen();this.hide()}this.popupHeader.removeEventListener("touchmove",this.handleTouchMove,{passive:!0}),this.popupHeader.removeEventListener("touchend",this.handleTouchEnd,{passive:!0})};detectFocus=e=>{if("Tab"===e.key){if(!this.focusable.length)return;if(!this.firstFocusable)for(let i=0;i=0;i--)if(!this.focusable[i].disabled){this.lastFocusable=this.focusable[i];break}e.shiftKey&&document.activeElement===this.firstFocusable?(e.preventDefault(),this.lastFocusable.tagName.includes("SM-")?this.lastFocusable.focusIn():this.lastFocusable.focus()):e.shiftKey||document.activeElement!==this.lastFocusable||(e.preventDefault(),this.firstFocusable.tagName.includes("SM-")?this.firstFocusable.focusIn():this.firstFocusable.focus())}};updateFocusableList=()=>{this.focusable=this.querySelectorAll('sm-button:not([disabled]), button:not([disabled]), [href], sm-input, input:not([readonly]), sm-select, select, sm-checkbox, sm-textarea, textarea, [tabindex]:not([tabindex="-1"])'),this.autoFocus=this.querySelector("[autofocus]"),this.firstFocusable=null,this.lastFocusable=null};handleSoftDismiss=()=>{this.pinned?this.dialogBox.animate([{transform:"translateX(-1rem)"},{transform:"translateX(1rem)"},{transform:"translateX(-0.5rem)"},{transform:"translateX(0.5rem)"},{transform:"translateX(0)"}],{duration:300,easing:"ease"}):this.hide()};debounce=(callback,wait)=>{let timeoutId=null;return(...args)=>{window.clearTimeout(timeoutId),timeoutId=window.setTimeout((()=>{callback.apply(null,args)}),wait)}};connectedCallback(){this.popupBodySlot.addEventListener("slotchange",this.debounce((()=>{this.forms=this.querySelectorAll("sm-form"),this.updateFocusableList()}),0)),this.resizeObserver=new ResizeObserver((entries=>{entries.forEach((entry=>{if(entry.contentBoxSize){const contentBoxSize=Array.isArray(entry.contentBoxSize)?entry.contentBoxSize[0]:entry.contentBoxSize;this.threshold=.3*contentBoxSize.blockSize.height}else this.threshold=.3*entry.contentRect.height}))})),this.mutationObserver=new MutationObserver((entries=>{this.updateFocusableList()}))}disconnectedCallback(){this.resizeObserver.disconnect(),this.mutationObserver.disconnect(),this.removeEventListener("keydown",this.detectFocus),this.popupHeader.removeEventListener("touchstart",this.handleTouchStart,{passive:!0}),this.backdrop.removeEventListener("mousedown",this.handleSoftDismiss)}attributeChangedCallback(name){"open"===name&&this.hasAttribute("open")&&this.show()}});
\ No newline at end of file