standard-ui/components/dist/select.min.js
2021-07-16 18:50:54 +05:30

1 line
9.5 KiB
JavaScript

const smSelect=document.createElement("template");smSelect.innerHTML='\n<style> \n*{\n padding: 0;\n margin: 0;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n} \n:host{\n display: -webkit-inline-box;\n display: -ms-inline-flexbox;\n display: inline-flex;\n --accent-color: #4d2588;\n --text-color: 17, 17, 17;\n --background-color: 255, 255, 255;\n --max-height: auto;\n --min-width: 100%;\n}\n:host([disabled]) .select{\n opacity: 0.6;\n cursor: not-allowed;\n}\n.hide{\n display: none !important;\n}\n.select{\n position: relative;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n cursor: pointer;\n width: 100%;\n -webkit-tap-highlight-color: transparent;\n}\n.icon {\n height: 1.5rem;\n width: 1.5rem;\n fill: rgba(var(--text-color), 0.7);\n} \n.option-text{\n font-size: 0.9rem;\n overflow: hidden;\n -o-text-overflow: ellipsis;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.selection{\n border-radius: 0.3rem;\n display: -ms-grid;\n display: grid;\n -ms-grid-columns: 1fr auto;\n grid-template-columns: 1fr auto;\n grid-template-areas: \'heading heading\' \'. .\';\n padding: 0.4rem 1rem;\n background: rgba(var(--text-color), 0.06);\n border: solid 1px rgba(var(--text-color), 0.2);\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n outline: none;\n}\n.selection:focus{\n -webkit-box-shadow: 0 0 0 0.1rem var(--accent-color);\n box-shadow: 0 0 0 0.1rem var(--accent-color) \n}\n.icon{\n margin-left: 1rem;\n}\n:host([align-select="left"]) .options{\n left: 0;\n}\n:host([align-select="right"]) .options{\n right: 0;\n}\n.options{\n top: 100%;\n margin-top: 0.2rem; \n overflow: hidden auto;\n position: absolute;\n grid-area: options;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: vertical;\n -webkit-box-direction: normal;\n -ms-flex-direction: column;\n flex-direction: column;\n min-width: var(--min-width);\n max-height: var(--max-height);\n background: rgba(var(--background-color), 1);\n border: solid 1px rgba(var(--text-color), 0.2);\n border-radius: 0.3rem;\n z-index: 2;\n -webkit-box-shadow: 0.4rem 0.8rem 1.2rem #00000030;\n box-shadow: 0.4rem 0.8rem 1.2rem #00000030;\n}\n.rotate{\n -webkit-transform: rotate(180deg);\n -ms-transform: rotate(180deg);\n transform: rotate(180deg)\n}\n@media (any-hover: hover){\n ::-webkit-scrollbar{\n width: 0.5rem;\n height: 0.5rem;\n }\n \n ::-webkit-scrollbar-thumb{\n background: rgba(var(--text-color), 0.3);\n border-radius: 1rem;\n &:hover{\n background: rgba(var(--text-color), 0.5);\n }\n }\n}\n</style>\n<div class="select" >\n <div class="selection">\n <div class="option-text"></div>\n <svg class="icon toggle" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 13.172l4.95-4.95 1.414 1.414L12 16 5.636 9.636 7.05 8.222z"/></svg>\n </div>\n <div part="options" class="options hide">\n <slot></slot> \n </div>\n</div>',customElements.define("sm-select",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smSelect.content.cloneNode(!0)),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.handleSelectKeyDown=this.handleSelectKeyDown.bind(this),this.handleOptionsKeyDown=this.handleOptionsKeyDown.bind(this),this.handleOptionsKeyDown=this.handleOptionsKeyDown.bind(this),this.availableOptions,this.optionList=this.shadowRoot.querySelector(".options"),this.chevron=this.shadowRoot.querySelector(".toggle"),this.selection=this.shadowRoot.querySelector(".selection"),this.previousOption,this.isOpen=!1,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"}}static get observedAttributes(){return["value","disabled"]}get value(){return this.getAttribute("value")}set value(t){this.setAttribute("value",t)}reset(){}open(){this.optionList.classList.remove("hide"),this.optionList.animate(this.slideDown,this.animationOptions),this.chevron.classList.add("rotate"),this.isOpen=!0}collapse(){this.chevron.classList.remove("rotate"),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()}handleSelectKeyDown(t){"ArrowDown"===t.code||"ArrowRight"===t.code?(t.preventDefault(),this.availableOptions[0].focus()):"Enter"!==t.code&&"Space"!==t.code||(this.isOpen?this.collapse():(this.optionList.classList.remove("hide"),this.optionList.animate(this.slideDown,this.animationOptions),this.chevron.classList.add("rotate"),this.isOpen=!0))}handleOptionsKeyDown(t){"ArrowUp"===t.code||"ArrowRight"===t.code?(t.preventDefault(),document.activeElement.previousElementSibling?document.activeElement.previousElementSibling.focus():this.availableOptions[this.availableOptions.length-1].focus()):"ArrowDown"!==t.code&&"ArrowLeft"!==t.code||(t.preventDefault(),document.activeElement.nextElementSibling?document.activeElement.nextElementSibling.focus():this.availableOptions[0].focus())}connectedCallback(){this.setAttribute("role","listbox"),this.hasAttribute("disabled")||this.selection.setAttribute("tabindex","0");let t=this.shadowRoot.querySelector("slot");t.addEventListener("slotchange",e=>{if(this.availableOptions=t.assignedElements(),this.availableOptions[0]){let t=this.availableOptions[0];this.previousOption=t,t.classList.add("check-selected"),this.setAttribute("value",t.getAttribute("value")),this.shadowRoot.querySelector(".option-text").textContent=t.textContent,this.availableOptions.forEach((t,e)=>{t.setAttribute("tabindex","0")})}}),this.selection.addEventListener("click",this.toggle),this.selection.addEventListener("keydown",this.handleSelectKeyDown),this.optionList.addEventListener("keydown",this.handleOptionsKeyDown),this.addEventListener("optionSelected",t=>{this.previousOption!==t.target&&(this.setAttribute("value",t.detail.value),this.shadowRoot.querySelector(".option-text").textContent=t.detail.text,this.dispatchEvent(new CustomEvent("change",{bubbles:!0,composed:!0,detail:{value:t.detail.value}})),this.previousOption&&this.previousOption.classList.remove("check-selected"),this.previousOption=t.target),t.detail.switching||this.collapse(),t.target.classList.add("check-selected")}),document.addEventListener("mousedown",t=>{this.isOpen&&!this.contains(t.target)&&this.collapse()})}attributeChangedCallback(t,e,n){"disabled"===t&&(this.hasAttribute("disabled")?this.selection.removeAttribute("tabindex"):this.selection.setAttribute("tabindex","0"))}disconnectedCallback(){this.selection.removeEventListener("click",this.toggle),this.selection.removeEventListener("keydown",this.handleSelectKeyDown),this.optionList.removeEventListener("keydown",this.handleOptionsKeyDown)}});const smOption=document.createElement("template");smOption.innerHTML='\n<style> \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}\n.option{\n min-width: 100%;\n padding: 0.8rem 1.2rem;\n cursor: pointer;\n overflow-wrap: break-word;\n outline: none;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n}\n:host(:focus){\n outline: none;\n background: rgba(var(--text-color), 0.1);\n}\n:host(:focus) .option .icon{\n opacity: 0.4\n}\n:host(.check-selected) .icon{\n opacity: 1 !important\n}\n.icon {\n margin-right: 0.8rem;\n fill: none;\n height: 0.8rem;\n width: 0.8rem;\n stroke: rgba(var(--text-color), 0.7);\n stroke-width: 10;\n overflow: visible;\n stroke-linecap: round;\n border-radius: 1rem;\n stroke-linejoin: round;\n opacity: 0;\n}\n@media (hover: hover){\n .option:hover{\n background: rgba(var(--text-color), 0.1);\n }\n .option:hover .icon{\n opacity: 0.4\n }\n}\n</style>\n<div class="option">\n <svg class="icon" viewBox="0 0 64 64">\n <polyline points="0.35 31.82 21.45 52.98 63.65 10.66"/>\n </svg>\n <slot></slot> \n</div>',customElements.define("sm-option",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smOption.content.cloneNode(!0)),this.sendDetails=this.sendDetails.bind(this)}sendDetails(t){let e=new CustomEvent("optionSelected",{bubbles:!0,composed:!0,detail:{text:this.textContent,value:this.getAttribute("value"),switching:t}});this.dispatchEvent(e)}connectedCallback(){this.setAttribute("role","option");let t=["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"];this.addEventListener("click",this.sendDetails),this.addEventListener("keyup",e=>{"Enter"!==e.code&&"Space"!==e.code||(e.preventDefault(),this.sendDetails(!1)),t.includes(e.code)&&(e.preventDefault(),this.sendDetails(!0))}),this.hasAttribute("default")&&setTimeout(()=>{this.sendDetails()},0)}});