1 line
8.5 KiB
JavaScript
1 line
8.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.icon {\n fill: none;\n height: 0.8rem;\n width: 0.8rem;\n stroke: rgba(var(--text-color), 0.7);\n stroke-width: 6;\n overflow: visible;\n stroke-linecap: round;\n stroke-linejoin: round;\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 --foreground-color: 255, 255, 255;\n --background-color: #F6f6f6;\n --danger-color: red;\n --max-height: auto;\n --min-width: 100%;\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.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.5rem; \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(--foreground-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" tabindex="0">\n <div class="option-text"></div>\n <svg class="icon toggle" viewBox="0 0 64 64">\n <polyline points="63.65 15.99 32 47.66 0.35 15.99"/>\n </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)}static get observedAttributes(){return["value"]}get value(){return this.getAttribute("value")}set value(e){this.setAttribute("value",e)}reset(){}collapse(){this.chevron.classList.remove("rotate"),this.optionList.animate(this.slideUp,this.animationOptions).onfinish=(()=>{this.optionList.classList.add("hide"),this.open=!1})}connectedCallback(){this.availableOptions,this.optionList=this.shadowRoot.querySelector(".options"),this.chevron=this.shadowRoot.querySelector(".toggle");let e,t=this.shadowRoot.querySelector(".options slot"),n=this.shadowRoot.querySelector(".selection");this.open=!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"},n.addEventListener("click",e=>{this.open?this.collapse():(this.optionList.classList.remove("hide"),this.optionList.animate(this.slideDown,this.animationOptions),this.chevron.classList.add("rotate"),this.open=!0)}),n.addEventListener("keydown",e=>{"ArrowDown"!==e.code&&"ArrowRight"!==e.code||(e.preventDefault(),this.availableOptions[0].focus()),"Enter"!==e.code&&"Space"!==e.code||(this.open?this.collapse():(this.optionList.classList.remove("hide"),this.optionList.animate(this.slideDown,this.animationOptions),this.chevron.classList.add("rotate"),this.open=!0))}),this.optionList.addEventListener("keydown",e=>{"ArrowUp"!==e.code&&"ArrowRight"!==e.code||(e.preventDefault(),document.activeElement.previousElementSibling?document.activeElement.previousElementSibling.focus():this.availableOptions[this.availableOptions.length-1].focus()),"ArrowDown"!==e.code&&"ArrowLeft"!==e.code||(e.preventDefault(),document.activeElement.nextElementSibling?document.activeElement.nextElementSibling.focus():this.availableOptions[0].focus())}),this.addEventListener("optionSelected",t=>{e!==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}})),e&&e.classList.remove("check-selected"),e=t.target),t.detail.switching||this.collapse(),t.target.classList.add("check-selected")}),t.addEventListener("slotchange",n=>{if(this.availableOptions=t.assignedElements(),this.availableOptions[0]){let t=this.availableOptions[0];e=t,t.classList.add("check-selected"),this.setAttribute("value",t.getAttribute("value")),this.shadowRoot.querySelector(".option-text").textContent=t.textContent,this.availableOptions.forEach((e,t)=>{e.setAttribute("data-rank",t+1),e.setAttribute("tabindex","0")})}}),document.addEventListener("mousedown",e=>{!this.contains(e.target)&&this.open&&this.collapse()})}});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))}sendDetails(e){let t=new CustomEvent("optionSelected",{bubbles:!0,composed:!0,detail:{text:this.textContent,value:this.getAttribute("value"),switching:e}});this.dispatchEvent(t)}connectedCallback(){let e=["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"];this.addEventListener("click",e=>{this.sendDetails()}),this.addEventListener("keyup",t=>{"Enter"!==t.code&&"Space"!==t.code||(t.preventDefault(),this.sendDetails(!1)),e.includes(t.code)&&(t.preventDefault(),this.sendDetails(!0))}),this.hasAttribute("default")&&setTimeout(()=>{this.sendDetails()},0)}}); |