diff --git a/components/dist/form.js b/components/dist/form.js
index 8c59563..83effbb 100644
--- a/components/dist/form.js
+++ b/components/dist/form.js
@@ -34,6 +34,7 @@ customElements.define('sm-form', class extends HTMLElement {
this.submitButton
this.resetButton
this.invalidFields = false;
+ this.mutationObserver
this.debounce = this.debounce.bind(this)
this._checkValidity = this._checkValidity.bind(this)
@@ -87,18 +88,18 @@ customElements.define('sm-form', class extends HTMLElement {
this.shadowRoot.querySelector('slot').addEventListener('slotchange', this.elementsChanged)
this.addEventListener('input', this.debounce(this._checkValidity, 100));
this.addEventListener('keydown', this.debounce(this.handleKeydown, 100));
- const mutationObserver = new MutationObserver(mutations => {
+ this.mutationObserver = new MutationObserver(mutations => {
mutations.forEach(mutation => {
if (mutation.type === 'childList') {
this.elementsChanged()
}
})
})
- mutationObserver.observe(this, { childList: true, subtree: true })
+ this.mutationObserver.observe(this, { childList: true, subtree: true })
}
disconnectedCallback() {
this.removeEventListener('input', this.debounce(this._checkValidity, 100));
this.removeEventListener('keydown', this.debounce(this.handleKeydown, 100));
- mutationObserver.disconnect()
+ this.mutationObserver.disconnect()
}
})
\ No newline at end of file
diff --git a/components/dist/form.min.js b/components/dist/form.min.js
index a91384b..9747001 100644
--- a/components/dist/form.min.js
+++ b/components/dist/form.min.js
@@ -1 +1 @@
-const smForm=document.createElement("template");smForm.innerHTML='\n \n
\n ',customElements.define("sm-form",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smForm.content.cloneNode(!0)),this.form=this.shadowRoot.querySelector("form"),this.formElements,this.requiredElements,this.submitButton,this.resetButton,this.invalidFields=!1,this.debounce=this.debounce.bind(this),this._checkValidity=this._checkValidity.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.reset=this.reset.bind(this),this.elementsChanged=this.elementsChanged.bind(this)}debounce(e,t){let i=null;return(...s)=>{window.clearTimeout(i),i=window.setTimeout(()=>{e.apply(null,s)},t)}}_checkValidity(){this.submitButton&&(this.invalidFields=this.requiredElements.filter(e=>!e.isValid),this.submitButton.disabled=this.invalidFields.length)}handleKeydown(e){"Enter"===e.key&&e.target.tagName.includes("SM-INPUT")&&(this.invalidFields.length?this.requiredElements.forEach(e=>{e.isValid||e.vibrate()}):(this.submitButton&&this.submitButton.click(),this.dispatchEvent(new CustomEvent("submit",{bubbles:!0,composed:!0}))))}reset(){this.formElements.forEach(e=>e.reset())}elementsChanged(){this.formElements=[...this.querySelectorAll("sm-input, sm-textarea, sm-checkbox, tags-input, file-input, sm-switch, sm-radio")],this.requiredElements=this.formElements.filter(e=>e.hasAttribute("required")),this.submitButton=this.querySelector('[variant="primary"], [type="submit"]'),this.resetButton=this.querySelector('[type="reset"]'),this.resetButton&&this.resetButton.addEventListener("click",this.reset),this._checkValidity()}connectedCallback(){this.shadowRoot.querySelector("slot").addEventListener("slotchange",this.elementsChanged),this.addEventListener("input",this.debounce(this._checkValidity,100)),this.addEventListener("keydown",this.debounce(this.handleKeydown,100));const e=new MutationObserver(e=>{e.forEach(e=>{"childList"===e.type&&this.elementsChanged()})});e.observe(this,{childList:!0,subtree:!0})}disconnectedCallback(){this.removeEventListener("input",this.debounce(this._checkValidity,100)),this.removeEventListener("keydown",this.debounce(this.handleKeydown,100)),mutationObserver.disconnect()}});
\ No newline at end of file
+const smForm=document.createElement("template");smForm.innerHTML='\n \n \n ',customElements.define("sm-form",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smForm.content.cloneNode(!0)),this.form=this.shadowRoot.querySelector("form"),this.formElements,this.requiredElements,this.submitButton,this.resetButton,this.invalidFields=!1,this.mutationObserver,this.debounce=this.debounce.bind(this),this._checkValidity=this._checkValidity.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.reset=this.reset.bind(this),this.elementsChanged=this.elementsChanged.bind(this)}debounce(t,e){let i=null;return(...s)=>{window.clearTimeout(i),i=window.setTimeout(()=>{t.apply(null,s)},e)}}_checkValidity(){this.submitButton&&(this.invalidFields=this.requiredElements.filter(t=>!t.isValid),this.submitButton.disabled=this.invalidFields.length)}handleKeydown(t){"Enter"===t.key&&t.target.tagName.includes("SM-INPUT")&&(this.invalidFields.length?this.requiredElements.forEach(t=>{t.isValid||t.vibrate()}):(this.submitButton&&this.submitButton.click(),this.dispatchEvent(new CustomEvent("submit",{bubbles:!0,composed:!0}))))}reset(){this.formElements.forEach(t=>t.reset())}elementsChanged(){this.formElements=[...this.querySelectorAll("sm-input, sm-textarea, sm-checkbox, tags-input, file-input, sm-switch, sm-radio")],this.requiredElements=this.formElements.filter(t=>t.hasAttribute("required")),this.submitButton=this.querySelector('[variant="primary"], [type="submit"]'),this.resetButton=this.querySelector('[type="reset"]'),this.resetButton&&this.resetButton.addEventListener("click",this.reset),this._checkValidity()}connectedCallback(){this.shadowRoot.querySelector("slot").addEventListener("slotchange",this.elementsChanged),this.addEventListener("input",this.debounce(this._checkValidity,100)),this.addEventListener("keydown",this.debounce(this.handleKeydown,100)),this.mutationObserver=new MutationObserver(t=>{t.forEach(t=>{"childList"===t.type&&this.elementsChanged()})}),this.mutationObserver.observe(this,{childList:!0,subtree:!0})}disconnectedCallback(){this.removeEventListener("input",this.debounce(this._checkValidity,100)),this.removeEventListener("keydown",this.debounce(this.handleKeydown,100)),this.mutationObserver.disconnect()}});
\ No newline at end of file
diff --git a/components/dist/select.js b/components/dist/select.js
index 4f196ce..c6ebead 100644
--- a/components/dist/select.js
+++ b/components/dist/select.js
@@ -144,7 +144,6 @@ customElements.define('sm-select', class extends HTMLElement {
this.availableOptions
this.previousOption
- this._value = undefined;
this.isOpen = false;
this.label = ''
this.slideDown = [{
@@ -182,7 +181,7 @@ customElements.define('sm-select', class extends HTMLElement {
return this.getAttribute('value')
}
set value(val) {
- const selectedOption = this.availableOptions.find(option => option.getAttribute('value') === val)
+ const selectedOption = this.shadowRoot.querySelector('slot').assignedElements().find(option => option.getAttribute('value') === val)
if (selectedOption) {
this.setAttribute('value', val)
this.selectOption(selectedOption)
@@ -201,12 +200,8 @@ customElements.define('sm-select', class extends HTMLElement {
}
}
selectOption(selectedOption) {
- if (this.previousOption) {
- this.previousOption.classList.remove('check-selected')
- this.previousOption.removeAttribute('selected')
- }
if (this.previousOption !== selectedOption) {
- selectedOption.classList.add('check-selected')
+ this.querySelectorAll('[selected]').forEach(option => option.removeAttribute('selected'))
selectedOption.setAttribute('selected', '')
this.selectedOptionText.textContent = `${this.label}${selectedOption.textContent}`;
this.previousOption = selectedOption
@@ -316,11 +311,6 @@ customElements.define('sm-select', class extends HTMLElement {
let slot = this.shadowRoot.querySelector('slot')
slot.addEventListener('slotchange', e => {
this.availableOptions = slot.assignedElements()
- this.availableOptions.forEach(elem => {
- if (elem.hasAttribute('selected')) {
- this._value = elem.value;
- }
- });
this.reset(false)
});
this.addEventListener('click', this.handleClick)
@@ -328,6 +318,7 @@ customElements.define('sm-select', class extends HTMLElement {
document.addEventListener('mousedown', this.handleClickOutside)
}
disconnectedCallback() {
+ this.removeEventListener('click', this.handleClick)
this.removeEventListener('click', this.toggle)
this.removeEventListener('keydown', this.handleKeydown)
document.removeEventListener('mousedown', this.handleClickOutside)
@@ -387,14 +378,14 @@ smOption.innerHTML = `
:host(:focus) .option .icon{
opacity: 0.4
}
-:host(.check-selected) .icon{
+:host([selected]) .icon{
opacity: 1
}
@media (hover: hover){
.option:hover{
background: rgba(var(--text-color,(17,17,17)), 0.1);
}
- :host(:not(.check-selected):hover) .icon{
+ :host(:not([selected]):hover) .icon{
opacity: 0.4
}
}
diff --git a/components/dist/select.min.js b/components/dist/select.min.js
index 948f2d0..8c8c7bf 100644
--- a/components/dist/select.min.js
+++ b/components/dist/select.min.js
@@ -1 +1 @@
-const smSelect=document.createElement("template");smSelect.innerHTML='\n\n',customElements.define("sm-select",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smSelect.content.cloneNode(!0)),this.focusIn=this.focusIn.bind(this),this.reset=this.reset.bind(this),this.open=this.open.bind(this),this.collapse=this.collapse.bind(this),this.toggle=this.toggle.bind(this),this.handleOptionsNavigation=this.handleOptionsNavigation.bind(this),this.handleOptionSelection=this.handleOptionSelection.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.handleClickOutside=this.handleClickOutside.bind(this),this.selectOption=this.selectOption.bind(this),this.availableOptions,this.previousOption,this._value=void 0,this.isOpen=!1,this.label="",this.slideDown=[{transform:"translateY(-0.5rem)",opacity:0},{transform:"translateY(0)",opacity:1}],this.slideUp=[{transform:"translateY(0)",opacity:1},{transform:"translateY(-0.5rem)",opacity:0}],this.animationOptions={duration:300,fill:"forwards",easing:"ease"},this.optionList=this.shadowRoot.querySelector(".options"),this.selection=this.shadowRoot.querySelector(".selection"),this.selectedOptionText=this.shadowRoot.querySelector(".selected-option-text")}static get observedAttributes(){return["disabled","label"]}get value(){return this.getAttribute("value")}set value(t){const e=this.availableOptions.find(e=>e.getAttribute("value")===t);e?(this.setAttribute("value",t),this.selectOption(e)):console.warn(`There is no option with ${t} as value`)}reset(t=!0){if(this.availableOptions[0]&&this.previousOption!==this.availableOptions[0]){const e=this.availableOptions.find(t=>t.hasAttribute("selected"))||this.availableOptions[0];this.value=e.getAttribute("value"),t&&this.fireEvent()}}selectOption(t){this.previousOption&&(this.previousOption.classList.remove("check-selected"),this.previousOption.removeAttribute("selected")),this.previousOption!==t&&(t.classList.add("check-selected"),t.setAttribute("selected",""),this.selectedOptionText.textContent=`${this.label}${t.textContent}`,this.previousOption=t)}focusIn(){this.selection.focus()}open(){this.optionList.classList.remove("hide"),this.optionList.animate(this.slideDown,this.animationOptions),this.setAttribute("open",""),this.isOpen=!0}collapse(){this.removeAttribute("open"),this.optionList.animate(this.slideUp,this.animationOptions).onfinish=(()=>{this.optionList.classList.add("hide"),this.isOpen=!1})}toggle(){this.isOpen||this.hasAttribute("disabled")?this.collapse():this.open()}fireEvent(){this.dispatchEvent(new CustomEvent("change",{bubbles:!0,composed:!0,detail:{value:this.value}}))}handleOptionsNavigation(t){"ArrowUp"===t.key?(t.preventDefault(),document.activeElement.previousElementSibling?document.activeElement.previousElementSibling.focus():this.availableOptions[this.availableOptions.length-1].focus()):"ArrowDown"===t.key&&(t.preventDefault(),document.activeElement.nextElementSibling?document.activeElement.nextElementSibling.focus():this.availableOptions[0].focus())}handleOptionSelection(t){this.previousOption!==document.activeElement&&(this.value=document.activeElement.getAttribute("value"),this.fireEvent())}handleClick(t){t.target===this?this.toggle():(this.handleOptionSelection(),this.collapse())}handleKeydown(t){t.target===this?this.isOpen&&"ArrowDown"===t.key?(t.preventDefault(),this.availableOptions[0].focus(),this.handleOptionSelection(t)):"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),this.toggle()):(this.handleOptionsNavigation(t),this.handleOptionSelection(t),"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),this.collapse()))}handleClickOutside(t){this.isOpen&&!this.contains(t.target)&&this.collapse()}connectedCallback(){this.setAttribute("role","listbox"),this.hasAttribute("disabled")||this.selection.setAttribute("tabindex","0");let t=this.shadowRoot.querySelector("slot");t.addEventListener("slotchange",e=>{this.availableOptions=t.assignedElements(),this.availableOptions.forEach(t=>{t.hasAttribute("selected")&&(this._value=t.value)}),this.reset(!1)}),this.addEventListener("click",this.handleClick),this.addEventListener("keydown",this.handleKeydown),document.addEventListener("mousedown",this.handleClickOutside)}disconnectedCallback(){this.removeEventListener("click",this.toggle),this.removeEventListener("keydown",this.handleKeydown),document.removeEventListener("mousedown",this.handleClickOutside)}attributeChangedCallback(t){"disabled"===t?this.hasAttribute("disabled")?this.selection.removeAttribute("tabindex"):this.selection.setAttribute("tabindex","0"):"label"===t&&(this.label=this.hasAttribute("label")?`${this.getAttribute("label")} `:"")}});const smOption=document.createElement("template");smOption.innerHTML='\n\n',customElements.define("sm-option",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smOption.content.cloneNode(!0))}connectedCallback(){this.setAttribute("role","option"),this.setAttribute("tabindex","0")}});
\ No newline at end of file
+const smSelect=document.createElement("template");smSelect.innerHTML='\n\n',customElements.define("sm-select",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smSelect.content.cloneNode(!0)),this.focusIn=this.focusIn.bind(this),this.reset=this.reset.bind(this),this.open=this.open.bind(this),this.collapse=this.collapse.bind(this),this.toggle=this.toggle.bind(this),this.handleOptionsNavigation=this.handleOptionsNavigation.bind(this),this.handleOptionSelection=this.handleOptionSelection.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.handleClickOutside=this.handleClickOutside.bind(this),this.selectOption=this.selectOption.bind(this),this.availableOptions,this.previousOption,this.isOpen=!1,this.label="",this.slideDown=[{transform:"translateY(-0.5rem)",opacity:0},{transform:"translateY(0)",opacity:1}],this.slideUp=[{transform:"translateY(0)",opacity:1},{transform:"translateY(-0.5rem)",opacity:0}],this.animationOptions={duration:300,fill:"forwards",easing:"ease"},this.optionList=this.shadowRoot.querySelector(".options"),this.selection=this.shadowRoot.querySelector(".selection"),this.selectedOptionText=this.shadowRoot.querySelector(".selected-option-text")}static get observedAttributes(){return["disabled","label"]}get value(){return this.getAttribute("value")}set value(t){const e=this.shadowRoot.querySelector("slot").assignedElements().find(e=>e.getAttribute("value")===t);e?(this.setAttribute("value",t),this.selectOption(e)):console.warn(`There is no option with ${t} as value`)}reset(t=!0){if(this.availableOptions[0]&&this.previousOption!==this.availableOptions[0]){const e=this.availableOptions.find(t=>t.hasAttribute("selected"))||this.availableOptions[0];this.value=e.getAttribute("value"),t&&this.fireEvent()}}selectOption(t){this.previousOption!==t&&(this.querySelectorAll("[selected]").forEach(t=>t.removeAttribute("selected")),t.setAttribute("selected",""),this.selectedOptionText.textContent=`${this.label}${t.textContent}`,this.previousOption=t)}focusIn(){this.selection.focus()}open(){this.optionList.classList.remove("hide"),this.optionList.animate(this.slideDown,this.animationOptions),this.setAttribute("open",""),this.isOpen=!0}collapse(){this.removeAttribute("open"),this.optionList.animate(this.slideUp,this.animationOptions).onfinish=(()=>{this.optionList.classList.add("hide"),this.isOpen=!1})}toggle(){this.isOpen||this.hasAttribute("disabled")?this.collapse():this.open()}fireEvent(){this.dispatchEvent(new CustomEvent("change",{bubbles:!0,composed:!0,detail:{value:this.value}}))}handleOptionsNavigation(t){"ArrowUp"===t.key?(t.preventDefault(),document.activeElement.previousElementSibling?document.activeElement.previousElementSibling.focus():this.availableOptions[this.availableOptions.length-1].focus()):"ArrowDown"===t.key&&(t.preventDefault(),document.activeElement.nextElementSibling?document.activeElement.nextElementSibling.focus():this.availableOptions[0].focus())}handleOptionSelection(t){this.previousOption!==document.activeElement&&(this.value=document.activeElement.getAttribute("value"),this.fireEvent())}handleClick(t){t.target===this?this.toggle():(this.handleOptionSelection(),this.collapse())}handleKeydown(t){t.target===this?this.isOpen&&"ArrowDown"===t.key?(t.preventDefault(),this.availableOptions[0].focus(),this.handleOptionSelection(t)):"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),this.toggle()):(this.handleOptionsNavigation(t),this.handleOptionSelection(t),"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),this.collapse()))}handleClickOutside(t){this.isOpen&&!this.contains(t.target)&&this.collapse()}connectedCallback(){this.setAttribute("role","listbox"),this.hasAttribute("disabled")||this.selection.setAttribute("tabindex","0");let t=this.shadowRoot.querySelector("slot");t.addEventListener("slotchange",e=>{this.availableOptions=t.assignedElements(),this.reset(!1)}),this.addEventListener("click",this.handleClick),this.addEventListener("keydown",this.handleKeydown),document.addEventListener("mousedown",this.handleClickOutside)}disconnectedCallback(){this.removeEventListener("click",this.handleClick),this.removeEventListener("click",this.toggle),this.removeEventListener("keydown",this.handleKeydown),document.removeEventListener("mousedown",this.handleClickOutside)}attributeChangedCallback(t){"disabled"===t?this.hasAttribute("disabled")?this.selection.removeAttribute("tabindex"):this.selection.setAttribute("tabindex","0"):"label"===t&&(this.label=this.hasAttribute("label")?`${this.getAttribute("label")} `:"")}});const smOption=document.createElement("template");smOption.innerHTML='\n\n',customElements.define("sm-option",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smOption.content.cloneNode(!0))}connectedCallback(){this.setAttribute("role","option"),this.setAttribute("tabindex","0")}});
\ No newline at end of file