diff --git a/components/dist/input.js b/components/dist/input.js
index 26296bb..835f6fe 100644
--- a/components/dist/input.js
+++ b/components/dist/input.js
@@ -32,7 +32,7 @@ smInput.innerHTML = `
box-shadow: none;
}
::-moz-focus-inner{
- border: none;
+ border: none;
}
:host{
display: flex;
@@ -46,6 +46,7 @@ smInput.innerHTML = `
.hide{
display: none !important;
}
+
button{
display: flex;
border: none;
@@ -88,6 +89,9 @@ smInput.innerHTML = `
margin-right: -2rem;
pointer-events: none !important;
}
+ .clear{
+ visibility: hidden;
+ }
.readonly{
pointer-events: none;
}
@@ -194,7 +198,7 @@ smInput.innerHTML = `
@@ -222,7 +226,7 @@ customElements.define('sm-input',
this._errorText = '';
this.isRequired = false;
this.validationFunction = undefined;
- this.reflectedAttributes = ['value', 'required', 'disabled', 'type', 'inputmode', 'readonly', 'min', 'max', 'pattern', 'minlength', 'maxlength', 'step'];
+ this.reflectedAttributes = ['value', 'required', 'disabled', 'type', 'inputmode', 'readonly', 'min', 'max', 'pattern', 'minlength', 'maxlength', 'step', 'list', 'autocomplete'];
this.reset = this.reset.bind(this);
this.clear = this.clear.bind(this);
@@ -235,7 +239,7 @@ customElements.define('sm-input',
}
static get observedAttributes() {
- return ['value', 'placeholder', 'required', 'disabled', 'type', 'inputmode', 'readonly', 'min', 'max', 'pattern', 'minlength', 'maxlength', 'step', 'helper-text', 'error-text', 'hiderequired'];
+ return ['value', 'placeholder', 'required', 'disabled', 'type', 'inputmode', 'readonly', 'min', 'max', 'pattern', 'minlength', 'maxlength', 'step', 'helper-text', 'error-text'];
}
get value() {
@@ -326,6 +330,7 @@ customElements.define('sm-input',
clear() {
this.value = '';
this.input.focus();
+ this.fireEvent();
}
focusIn() {
@@ -347,11 +352,7 @@ customElements.define('sm-input',
checkInput(e) {
if (!this.hasAttribute('readonly')) {
- if (this.input.value.trim() !== '') {
- this.clearBtn.classList.remove('hide');
- } else {
- this.clearBtn.classList.add('hide');
- }
+ this.clearBtn.style.visibility = this.input.value !== '' ? 'visible' : 'hidden';
}
if (!this.hasAttribute('placeholder') || this.getAttribute('placeholder').trim() === '') return;
if (this.input.value !== '') {
diff --git a/components/dist/input.min.js b/components/dist/input.min.js
index 5da5b32..c97ec58 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 extends HTMLElement{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.label=this.shadowRoot.querySelector(".label"),this.feedbackText=this.shadowRoot.querySelector(".feedback-text"),this.outerContainer=this.shadowRoot.querySelector(".outer-container"),this._helperText="",this._errorText="",this.isRequired=!1,this.validationFunction=void 0,this.reflectedAttributes=["value","required","disabled","type","inputmode","readonly","min","max","pattern","minlength","maxlength","step"],this.reset=this.reset.bind(this),this.clear=this.clear.bind(this),this.focusIn=this.focusIn.bind(this),this.focusOut=this.focusOut.bind(this),this.fireEvent=this.fireEvent.bind(this),this.checkInput=this.checkInput.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.vibrate=this.vibrate.bind(this)}static get observedAttributes(){return["value","placeholder","required","disabled","type","inputmode","readonly","min","max","pattern","minlength","maxlength","step","helper-text","error-text","hiderequired"]}get value(){return this.input.value}set value(t){t!==this.input.value&&(this.input.value=t,this.checkInput())}get placeholder(){return this.getAttribute("placeholder")}set placeholder(t){this.setAttribute("placeholder",t)}get type(){return this.getAttribute("type")}set type(t){this.setAttribute("type",t)}get validity(){return this.input.validity}get disabled(){return this.hasAttribute("disabled")}set disabled(t){t?this.inputParent.classList.add("disabled"):this.inputParent.classList.remove("disabled")}get readOnly(){return this.hasAttribute("readonly")}set readOnly(t){t?this.setAttribute("readonly",""):this.removeAttribute("readonly")}set customValidation(t){this.validationFunction=t}set errorText(t){this._errorText=t}set helperText(t){this._helperText=t}get isValid(){if(""!==this.input.value){const t=this.input.checkValidity();let e=!0;return this.validationFunction&&(e=Boolean(this.validationFunction(this.input.value))),t&&e?(this.feedbackText.classList.remove("error"),this.feedbackText.classList.add("success"),this.feedbackText.textContent=""):this._errorText&&(this.feedbackText.classList.add("error"),this.feedbackText.classList.remove("success"),this.feedbackText.innerHTML=`\n \n ${this._errorText}\n `),t&&e}}reset(){this.value=""}clear(){this.value="",this.input.focus()}focusIn(){this.input.focus()}focusOut(){this.input.blur()}fireEvent(){let t=new Event("input",{bubbles:!0,cancelable:!0,composed:!0});this.dispatchEvent(t)}checkInput(t){this.hasAttribute("readonly")||(""!==this.input.value.trim()?this.clearBtn.classList.remove("hide"):this.clearBtn.classList.add("hide")),this.hasAttribute("placeholder")&&""!==this.getAttribute("placeholder").trim()&&(""!==this.input.value?this.animate?this.inputParent.classList.add("animate-placeholder"):this.label.classList.add("hide"):(this.animate?this.inputParent.classList.remove("animate-placeholder"):this.label.classList.remove("hide"),this.feedbackText.textContent=""))}handleKeydown(t){1===t.key.length&&(["0","1","2","3","4","5","6","7","8","9","."].includes(t.key)?"."===t.key&&t.target.value.includes(".")&&t.preventDefault():t.preventDefault())}vibrate(){this.outerContainer.animate([{transform:"translateX(-1rem)"},{transform:"translateX(1rem)"},{transform:"translateX(-0.5rem)"},{transform:"translateX(0.5rem)"},{transform:"translateX(0)"}],{duration:300,easing:"ease"})}connectedCallback(){this.animate=this.hasAttribute("animate"),this.setAttribute("role","textbox"),this.input.addEventListener("input",this.checkInput),this.clearBtn.addEventListener("click",this.clear)}attributeChangedCallback(t,e,n){e!==n&&(this.reflectedAttributes.includes(t)&&(this.hasAttribute(t)?this.input.setAttribute(t,this.getAttribute(t)?this.getAttribute(t):""):this.input.removeAttribute(t)),"placeholder"===t?(this.label.textContent=n,this.setAttribute("aria-label",n)):this.hasAttribute("value")?this.checkInput():"type"===t?this.hasAttribute("type")&&"number"===this.getAttribute("type")?(this.input.setAttribute("inputmode","decimal"),this.input.addEventListener("keydown",this.handleKeydown)):this.input.removeEventListener("keydown",this.handleKeydown):"helper-text"===t?this._helperText=this.getAttribute("helper-text"):"error-text"===t?this._errorText=this.getAttribute("error-text"):"required"===t?(this.isRequired=this.hasAttribute("required"),this.isRequired?this.setAttribute("aria-required","true"):this.setAttribute("aria-required","false")):"readonly"===t?this.hasAttribute("readonly")?this.inputParent.classList.add("readonly"):this.inputParent.classList.remove("readonly"):"disabled"===t&&(this.hasAttribute("disabled")?this.inputParent.classList.add("disabled"):this.inputParent.classList.remove("disabled")))}disconnectedCallback(){this.input.removeEventListener("input",this.checkInput),this.clearBtn.removeEventListener("click",this.clear),this.input.removeEventListener("keydown",this.handleKeydown)}});
\ No newline at end of file
+const smInput=document.createElement("template");smInput.innerHTML='\n \n \n ',customElements.define("sm-input",class extends HTMLElement{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.label=this.shadowRoot.querySelector(".label"),this.feedbackText=this.shadowRoot.querySelector(".feedback-text"),this.outerContainer=this.shadowRoot.querySelector(".outer-container"),this._helperText="",this._errorText="",this.isRequired=!1,this.validationFunction=void 0,this.reflectedAttributes=["value","required","disabled","type","inputmode","readonly","min","max","pattern","minlength","maxlength","step","list","autocomplete"],this.reset=this.reset.bind(this),this.clear=this.clear.bind(this),this.focusIn=this.focusIn.bind(this),this.focusOut=this.focusOut.bind(this),this.fireEvent=this.fireEvent.bind(this),this.checkInput=this.checkInput.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.vibrate=this.vibrate.bind(this)}static get observedAttributes(){return["value","placeholder","required","disabled","type","inputmode","readonly","min","max","pattern","minlength","maxlength","step","helper-text","error-text"]}get value(){return this.input.value}set value(t){t!==this.input.value&&(this.input.value=t,this.checkInput())}get placeholder(){return this.getAttribute("placeholder")}set placeholder(t){this.setAttribute("placeholder",t)}get type(){return this.getAttribute("type")}set type(t){this.setAttribute("type",t)}get validity(){return this.input.validity}get disabled(){return this.hasAttribute("disabled")}set disabled(t){t?this.inputParent.classList.add("disabled"):this.inputParent.classList.remove("disabled")}get readOnly(){return this.hasAttribute("readonly")}set readOnly(t){t?this.setAttribute("readonly",""):this.removeAttribute("readonly")}set customValidation(t){this.validationFunction=t}set errorText(t){this._errorText=t}set helperText(t){this._helperText=t}get isValid(){if(""!==this.input.value){const t=this.input.checkValidity();let e=!0;return this.validationFunction&&(e=Boolean(this.validationFunction(this.input.value))),t&&e?(this.feedbackText.classList.remove("error"),this.feedbackText.classList.add("success"),this.feedbackText.textContent=""):this._errorText&&(this.feedbackText.classList.add("error"),this.feedbackText.classList.remove("success"),this.feedbackText.innerHTML=`\n \n ${this._errorText}\n `),t&&e}}reset(){this.value=""}clear(){this.value="",this.input.focus(),this.fireEvent()}focusIn(){this.input.focus()}focusOut(){this.input.blur()}fireEvent(){let t=new Event("input",{bubbles:!0,cancelable:!0,composed:!0});this.dispatchEvent(t)}checkInput(t){this.hasAttribute("readonly")||(this.clearBtn.style.visibility=""!==this.input.value?"visible":"hidden"),this.hasAttribute("placeholder")&&""!==this.getAttribute("placeholder").trim()&&(""!==this.input.value?this.animate?this.inputParent.classList.add("animate-placeholder"):this.label.classList.add("hide"):(this.animate?this.inputParent.classList.remove("animate-placeholder"):this.label.classList.remove("hide"),this.feedbackText.textContent=""))}handleKeydown(t){1===t.key.length&&(["0","1","2","3","4","5","6","7","8","9","."].includes(t.key)?"."===t.key&&t.target.value.includes(".")&&t.preventDefault():t.preventDefault())}vibrate(){this.outerContainer.animate([{transform:"translateX(-1rem)"},{transform:"translateX(1rem)"},{transform:"translateX(-0.5rem)"},{transform:"translateX(0.5rem)"},{transform:"translateX(0)"}],{duration:300,easing:"ease"})}connectedCallback(){this.animate=this.hasAttribute("animate"),this.setAttribute("role","textbox"),this.input.addEventListener("input",this.checkInput),this.clearBtn.addEventListener("click",this.clear)}attributeChangedCallback(t,e,n){e!==n&&(this.reflectedAttributes.includes(t)&&(this.hasAttribute(t)?this.input.setAttribute(t,this.getAttribute(t)?this.getAttribute(t):""):this.input.removeAttribute(t)),"placeholder"===t?(this.label.textContent=n,this.setAttribute("aria-label",n)):this.hasAttribute("value")?this.checkInput():"type"===t?this.hasAttribute("type")&&"number"===this.getAttribute("type")?(this.input.setAttribute("inputmode","decimal"),this.input.addEventListener("keydown",this.handleKeydown)):this.input.removeEventListener("keydown",this.handleKeydown):"helper-text"===t?this._helperText=this.getAttribute("helper-text"):"error-text"===t?this._errorText=this.getAttribute("error-text"):"required"===t?(this.isRequired=this.hasAttribute("required"),this.isRequired?this.setAttribute("aria-required","true"):this.setAttribute("aria-required","false")):"readonly"===t?this.hasAttribute("readonly")?this.inputParent.classList.add("readonly"):this.inputParent.classList.remove("readonly"):"disabled"===t&&(this.hasAttribute("disabled")?this.inputParent.classList.add("disabled"):this.inputParent.classList.remove("disabled")))}disconnectedCallback(){this.input.removeEventListener("input",this.checkInput),this.clearBtn.removeEventListener("click",this.clear),this.input.removeEventListener("keydown",this.handleKeydown)}});
\ No newline at end of file
diff --git a/components/dist/select.js b/components/dist/select.js
index c6ebead..94685df 100644
--- a/components/dist/select.js
+++ b/components/dist/select.js
@@ -89,8 +89,7 @@ smSelect.innerHTML = `
border: solid 1px rgba(var(--text-color,(17,17,17)), 0.2);
border-radius: var(--border-radius, 0.5rem);
z-index: 1;
- -webkit-box-shadow: 0.4rem 0.8rem 1.2rem #00000030;
- box-shadow: 0.4rem 0.8rem 1.2rem #00000030;
+ box-shadow: 0 1rem 1.5rem rgba(0 0 0 /0.2);
}
:host([open]) .toggle-icon{
-webkit-transform: rotate(180deg);
@@ -141,8 +140,9 @@ customElements.define('sm-select', class extends HTMLElement {
this.handleKeydown = this.handleKeydown.bind(this)
this.handleClickOutside = this.handleClickOutside.bind(this)
this.selectOption = this.selectOption.bind(this)
+ this.debounce = this.debounce.bind(this)
- this.availableOptions
+ this.availableOptions = []
this.previousOption
this.isOpen = false;
this.label = ''
@@ -189,6 +189,15 @@ customElements.define('sm-select', class extends HTMLElement {
console.warn(`There is no option with ${val} as value`)
}
}
+ debounce(callback, wait) {
+ let timeoutId = null;
+ return (...args) => {
+ window.clearTimeout(timeoutId);
+ timeoutId = window.setTimeout(() => {
+ callback.apply(null, args);
+ }, wait);
+ };
+ }
reset(fire = true) {
if (this.availableOptions[0] && this.previousOption !== this.availableOptions[0]) {
@@ -202,8 +211,8 @@ customElements.define('sm-select', class extends HTMLElement {
selectOption(selectedOption) {
if (this.previousOption !== selectedOption) {
this.querySelectorAll('[selected]').forEach(option => option.removeAttribute('selected'))
- selectedOption.setAttribute('selected', '')
this.selectedOptionText.textContent = `${this.label}${selectedOption.textContent}`;
+ selectedOption.setAttribute('selected', '')
this.previousOption = selectedOption
}
}
@@ -213,15 +222,18 @@ customElements.define('sm-select', class extends HTMLElement {
}
open() {
+ this.availableOptions.forEach(option => option.setAttribute('tabindex', 0))
this.optionList.classList.remove('hide')
this.optionList.animate(this.slideDown, this.animationOptions)
- this.setAttribute('open', '')
+ this.setAttribute('open', '');
+ (this.availableOptions.find(option => option.hasAttribute('selected')) || this.availableOptions[0]).focus()
this.isOpen = true
}
collapse() {
this.removeAttribute('open')
this.optionList.animate(this.slideUp, this.animationOptions)
.onfinish = () => {
+ this.availableOptions.forEach(option => option.removeAttribute('tabindex'))
this.optionList.classList.add('hide')
this.isOpen = false
}
@@ -252,8 +264,7 @@ customElements.define('sm-select', class extends HTMLElement {
} else {
this.availableOptions[this.availableOptions.length - 1].focus()
}
- }
- else if (e.key === 'ArrowDown') {
+ } else if (e.key === 'ArrowDown') {
e.preventDefault()
if (document.activeElement.nextElementSibling) {
document.activeElement.nextElementSibling.focus()
@@ -280,21 +291,20 @@ customElements.define('sm-select', class extends HTMLElement {
handleKeydown(e) {
if (e.target === this) {
if (this.isOpen && e.key === 'ArrowDown') {
- e.preventDefault()
- this.availableOptions[0].focus()
+ e.preventDefault();
+ (this.availableOptions.find(option => option.hasAttribute('selected')) || this.availableOptions[0]).focus()
this.handleOptionSelection(e)
- }
- else if (e.key === 'Enter' || e.key === ' ') {
+ } else if (e.key === ' ') {
e.preventDefault()
this.toggle()
}
- }
- else {
+ } else {
this.handleOptionsNavigation(e)
this.handleOptionSelection(e)
- if (e.key === 'Enter' || e.key === ' ') {
+ if (['Enter', ' ', 'Escape', 'Tab'].includes(e.key)) {
e.preventDefault()
this.collapse()
+ this.focusIn()
}
}
}
@@ -309,10 +319,22 @@ customElements.define('sm-select', class extends HTMLElement {
this.selection.setAttribute('tabindex', '0')
}
let slot = this.shadowRoot.querySelector('slot')
- slot.addEventListener('slotchange', e => {
+ slot.addEventListener('slotchange', this.debounce(e => {
this.availableOptions = slot.assignedElements()
this.reset(false)
- });
+ }, 100));
+ new IntersectionObserver((entries, observer) => {
+ entries.forEach(entry => {
+ if (entry.isIntersecting) {
+ const offsetLeft = this.selection.getBoundingClientRect().left
+ if (offsetLeft < window.innerWidth / 2) {
+ this.setAttribute('align-select', 'left')
+ } else {
+ this.setAttribute('align-select', 'right')
+ }
+ }
+ })
+ }).observe(this)
this.addEventListener('click', this.handleClick)
this.addEventListener('keydown', this.handleKeydown)
document.addEventListener('mousedown', this.handleClickOutside)
@@ -350,12 +372,15 @@ smOption.innerHTML = `
display: -webkit-box;
display: -ms-flexbox;
display: flex;
+ overflow: hidden;
+ border-radius: var(--border-radius, 0.3rem);
}
.option{
+ position: relative;
display: grid;
-webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
+ -ms-flex-align: center;
+ align-items: center;
width: 100%;
gap: 0.5rem;
grid-template-columns: max-content minmax(0, 1fr);
@@ -363,35 +388,39 @@ smOption.innerHTML = `
cursor: pointer;
outline: none;
user-select: none;
- border-radius: var(--border-radius, 0.3rem);
+}
+.option::before{
+ position: absolute;
+ content: '';
+ display: block;
+ width: 0.2rem;
+ height: 1em;
+ border-radius: 0 1em 1em 0;
+ background: rgba(var(--text-color,(17,17,17)), 0.5);
+ transition: all 0.2s ease-in-out;
+ opacity: 0;
}
:host(:focus){
outline: none;
background: rgba(var(--text-color,(17,17,17)), 0.1);
}
-.icon {
- opacity: 0;
- height: 1.2rem;
- width: 1.2rem;
- fill: rgba(var(--text-color,(17,17,17)), 0.8);
-}
-:host(:focus) .option .icon{
- opacity: 0.4
-}
-:host([selected]) .icon{
+:host(:focus) .option::before{
opacity: 1
}
+:host([selected]) .option::before{
+ opacity: 1;
+ background: var(--accent-color, teal);
+}
@media (hover: hover){
.option:hover{
background: rgba(var(--text-color,(17,17,17)), 0.1);
}
- :host(:not([selected]):hover) .icon{
- opacity: 0.4
+ :host(:not([selected]):hover) .option::before{
+ opacity: 1
}
}
`;
customElements.define('sm-option', class extends HTMLElement {
@@ -404,6 +433,5 @@ customElements.define('sm-option', class extends HTMLElement {
connectedCallback() {
this.setAttribute('role', 'option')
- this.setAttribute('tabindex', '0')
}
})
\ No newline at end of file
diff --git a/components/dist/select.min.js b/components/dist/select.min.js
index 8c8c7bf..42ce859 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.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
+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.debounce=this.debounce.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`)}debounce(t,e){let n=null;return(...i)=>{window.clearTimeout(n),n=window.setTimeout(()=>{t.apply(null,i)},e)}}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")),this.selectedOptionText.textContent=`${this.label}${t.textContent}`,t.setAttribute("selected",""),this.previousOption=t)}focusIn(){this.selection.focus()}open(){this.availableOptions.forEach(t=>t.setAttribute("tabindex",0)),this.optionList.classList.remove("hide"),this.optionList.animate(this.slideDown,this.animationOptions),this.setAttribute("open",""),(this.availableOptions.find(t=>t.hasAttribute("selected"))||this.availableOptions[0]).focus(),this.isOpen=!0}collapse(){this.removeAttribute("open"),this.optionList.animate(this.slideUp,this.animationOptions).onfinish=(()=>{this.availableOptions.forEach(t=>t.removeAttribute("tabindex")),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.find(t=>t.hasAttribute("selected"))||this.availableOptions[0]).focus(),this.handleOptionSelection(t)):" "===t.key&&(t.preventDefault(),this.toggle()):(this.handleOptionsNavigation(t),this.handleOptionSelection(t),["Enter"," ","Escape","Tab"].includes(t.key)&&(t.preventDefault(),this.collapse(),this.focusIn()))}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",this.debounce(e=>{this.availableOptions=t.assignedElements(),this.reset(!1)},100)),new IntersectionObserver((t,e)=>{t.forEach(t=>{if(t.isIntersecting){const t=this.selection.getBoundingClientRect().left;t \n*{\n padding: 0;\n margin: 0;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n} \n:host{\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n overflow: hidden;\n border-radius: var(--border-radius, 0.3rem);\n}\n.option{\n position: relative;\n display: grid;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n width: 100%;\n gap: 0.5rem;\n grid-template-columns: max-content minmax(0, 1fr);\n padding: var(--padding, 0.6rem 1rem);\n cursor: pointer;\n outline: none;\n user-select: none;\n}\n.option::before{\n position: absolute;\n content: '';\n display: block;\n width: 0.2rem;\n height: 1em;\n border-radius: 0 1em 1em 0;\n background: rgba(var(--text-color,(17,17,17)), 0.5);\n transition: all 0.2s ease-in-out;\n opacity: 0;\n}\n:host(:focus){\n outline: none;\n background: rgba(var(--text-color,(17,17,17)), 0.1);\n}\n:host(:focus) .option::before{\n opacity: 1\n}\n:host([selected]) .option::before{\n opacity: 1;\n background: var(--accent-color, teal);\n}\n@media (hover: hover){\n .option:hover{\n background: rgba(var(--text-color,(17,17,17)), 0.1);\n }\n :host(:not([selected]):hover) .option::before{\n opacity: 1\n }\n}\n\n\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")}});
\ No newline at end of file
diff --git a/components/dist/switch.js b/components/dist/switch.js
index c23d9d0..7822cc6 100644
--- a/components/dist/switch.js
+++ b/components/dist/switch.js
@@ -4,24 +4,22 @@ const smSwitch = document.createElement('template')
smSwitch.innerHTML = `
\n\n \n \n \n ',customElements.define("sm-switch",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smSwitch.content.cloneNode(!0)),this.switch=this.shadowRoot.querySelector(".switch"),this.input=this.shadowRoot.querySelector("input"),this.isChecked=!1,this.isDisabled=!1,this.dispatch=this.dispatch.bind(this)}static get observedAttributes(){return["disabled","checked"]}get disabled(){return this.isDisabled}set disabled(n){n?this.setAttribute("disabled",""):this.removeAttribute("disabled")}get checked(){return this.isChecked}set checked(n){n?this.setAttribute("checked",""):this.removeAttribute("checked")}get value(){return this.isChecked}reset(){}dispatch(){this.dispatchEvent(new CustomEvent("change",{bubbles:!0,composed:!0,detail:{value:this.isChecked}}))}connectedCallback(){this.addEventListener("keydown",n=>{" "!==n.key||this.isDisabled||(n.preventDefault(),this.input.click())}),this.input.addEventListener("click",n=>{this.input.checked?this.checked=!0:this.checked=!1,this.dispatch()})}attributeChangedCallback(n,e,t){e!==t&&("disabled"===n?this.hasAttribute("disabled")?this.disabled=!0:this.disabled=!1:"checked"===n&&(this.hasAttribute("checked")?(this.isChecked=!0,this.input.checked=!0):(this.isChecked=!1,this.input.checked=!1)))}});
\ No newline at end of file
+const smSwitch=document.createElement("template");smSwitch.innerHTML='\t\n\n\n \n \n \n ',customElements.define("sm-switch",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smSwitch.content.cloneNode(!0)),this.switch=this.shadowRoot.querySelector(".switch"),this.input=this.shadowRoot.querySelector("input"),this.isChecked=!1,this.isDisabled=!1,this.dispatch=this.dispatch.bind(this)}static get observedAttributes(){return["disabled","checked"]}get disabled(){return this.isDisabled}set disabled(e){e?this.setAttribute("disabled",""):this.removeAttribute("disabled")}get checked(){return this.isChecked}set checked(e){e?this.setAttribute("checked",""):this.removeAttribute("checked")}get value(){return this.isChecked}reset(){}dispatch(){this.dispatchEvent(new CustomEvent("change",{bubbles:!0,composed:!0,detail:{value:this.isChecked}}))}connectedCallback(){this.addEventListener("keydown",e=>{" "!==e.key||this.isDisabled||(e.preventDefault(),this.input.click())}),this.input.addEventListener("click",e=>{this.input.checked?this.checked=!0:this.checked=!1,this.dispatch()})}attributeChangedCallback(e,t,n){t!==n&&("disabled"===e?this.hasAttribute("disabled")?this.disabled=!0:this.disabled=!1:"checked"===e&&(this.hasAttribute("checked")?(this.isChecked=!0,this.input.checked=!0):(this.isChecked=!1,this.input.checked=!1)))}});
\ No newline at end of file
diff --git a/components/test.html b/components/test.html
new file mode 100644
index 0000000..d6f56c4
--- /dev/null
+++ b/components/test.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+ Document
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file