diff --git a/components/css/main.css b/components/css/main.css index 02fdf4a..9536427 100644 --- a/components/css/main.css +++ b/components/css/main.css @@ -16,20 +16,17 @@ html, body { body { --accent-color: #4d2588; - --light-shade: rgba(var(--text-color), 0.06); --text-color: 17, 17, 17; --text-color-light: 100, 100, 100; --foreground-color: 255, 255, 255; --background-color: #F6f6f6; --error-color: red; - --green: #00843b; color: rgba(var(--text-color), 1); background: var(--background-color); } body[data-theme=dark] { --accent-color: #976dd6; - --green: #13ff5a; --text-color: 240, 240, 240; --text-color-light: 170, 170, 170; --foreground-color: 20, 20, 20; @@ -73,6 +70,7 @@ p { font-size: 0.8; max-width: 75ch; line-height: 1.7; + margin-bottom: 1.5rem; color: rgba(var(--text-color), 0.8); } p:not(:last-of-type) { @@ -449,7 +447,7 @@ main { font-size: 0.9rem; letter-spacing: 0.08em; text-transform: uppercase; - padding: 1rem 1.5rem; + padding: 1.5rem; } .right { @@ -497,6 +495,7 @@ sm-tab-header { .page { display: flex; flex-direction: column; + padding-bottom: 3rem; } ol { diff --git a/components/css/main.min.css b/components/css/main.min.css index f4ecf85..b8640a7 100644 --- a/components/css/main.min.css +++ b/components/css/main.min.css @@ -1 +1 @@ -.weight-400,code{font-weight:400}.hide,.ripple{pointer-events:none}.list,ul{list-style:none}*{padding:0;margin:0;box-sizing:border-box;font-family:Roboto,sans-serif}code,code>*{font-family:"Roboto Mono",monospace}:root{font-size:clamp(1rem,1.2vmax,3rem)}body,html{height:100%;scroll-behavior:smooth}body{--accent-color:#4d2588;--light-shade:rgba(var(--text-color), 0.06);--text-color:17,17,17;--text-color-light:100,100,100;--foreground-color:255,255,255;--background-color:#F6f6f6;--error-color:red;--green:#00843b;color:rgba(var(--text-color),1);background:var(--background-color)}body[data-theme=dark]{--accent-color:#976dd6;--green:#13ff5a;--text-color:240,240,240;--text-color-light:170,170,170;--foreground-color:20,20,20;--background-color:#0a0a0a;--error-color:rgb(255, 106, 106)}.full-bleed{grid-column:1/4}.h1{font-size:2.5rem}.h2{font-size:2rem}.h3{font-size:1.4rem}.h4{font-size:1rem}.h5{font-size:.8rem}.uppercase{text-transform:uppercase}.capitalize,.list__item,h2,ol li::first-letter{text-transform:capitalize}p{font-size:.8;max-width:75ch;line-height:1.7;color:rgba(var(--text-color),.8)}p:not(:last-of-type){margin-bottom:1rem}img{object-fit:cover}a{color:inherit;text-decoration:none}a:focus-visible{box-shadow:0 0 0 .1rem rgba(var(--text-color),1) inset}button{display:inline-flex;border:none;background-color:inherit}a:any-link:focus-visible{outline:solid rgba(var(--text-color),1)}sm-button{--border-radius:0.3rem}.hide{opacity:0}.hide-completely{display:none!important}.no-transformations{transform:none!important}.overflow-ellipsis{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.breakable{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.flex{display:flex}.grid{display:grid}.grid-3{grid-template-columns:1fr auto auto}.flow-column{grid-auto-flow:column}.gap-0-5{gap:.5rem}.gap-1{gap:1rem}.gap-1-5{gap:1.5rem}.gap-2{gap:2rem}.gap-3{gap:3rem}.text-align-right{text-align:right}.align-start{align-items:flex-start}.align-center{align-items:center}.text-center{text-align:center}.justify-start{justify-content:start}.justify-center{justify-content:center}.justify-right{margin-left:auto}.align-self-center{align-self:center}.justify-self-center{justify-self:center}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.direction-column{flex-direction:column}.space-between{justify-content:space-between}.w-100{width:100%}.color-0-8{color:rgba(var(--text-color),.8)}.weight-500{font-weight:500}.ripple{position:absolute;border-radius:50%;transform:scale(0);background:rgba(var(--text-color),.16)}.interact,.theme-switcher{position:relative;cursor:pointer;-webkit-tap-highlight-color:transparent}code,pre{background:rgba(var(--text-color),.04)}.interact{overflow:hidden}.observe-empty-state:empty{display:none}.observe-empty-state:not(:empty)~.empty-state{display:none}.icon{width:1.5rem;height:1.5rem;fill:rgba(var(--text-color),.9)}.button__icon{height:1.2rem;width:1.2rem}.button__icon--left{margin-right:.5rem}.button__icon--right{margin-left:.5rem}.theme-switcher{justify-self:flex-end;width:1.5rem;height:1.5rem}.card,.list{flex-direction:column}.theme-switcher .icon{position:absolute;transition:transform .6s}.theme-switcher__checkbox{display:none}.theme-switcher__checkbox:checked~.moon-icon{transform:scale(0) rotate(90deg)}.theme-switcher__checkbox:not(:checked)~.sun-icon{transform:scale(0) rotate(-90deg)}code .str,pre .str{color:#65B042}code .kwd,pre .kwd{color:#E28964}code .com,pre .com{color:#AEAEAE;font-style:italic}code .typ,pre .typ{color:#4395ff}code .lit,pre .lit{color:#1a76c2}code .pln,code .pun,pre .pln,pre .pun{color:rgba(var(--text-color),.8)}code .tag,pre .tag{color:#22863a}code .atn,pre .atn{color:#005cc5}code .atv,pre .atv{color:var(--accent-color)}code .dec,pre .dec{color:#3387CC}pre{max-width:100%;margin:1rem 0;padding:0 1.5rem;overflow-x:auto;font-size:.9rem;white-space:pre-line;border-radius:.5rem}code{border-radius:.2rem;padding:.2rem .4rem}pre code{line-height:1.4;border-radius:none;background:0 0;width:100%}h1,h2,h3,h4.h5{font-family:Poppins,sans-serif}h2{margin:3rem 0 1rem}h2:first-of-type{margin-top:1rem}main{display:grid;height:100%}.card,.list,.list__item,.page{display:flex}#main_header{padding:.5rem 1.5rem;border-bottom:1px solid rgba(var(--text-color),.1)}#side_nav_button{padding:.5rem;margin-left:-.5rem}#backdrop{position:fixed;z-index:4;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,.5)}#side_nav,.right{max-height:100%;overflow-y:auto;padding-bottom:3rem}#side_nav h4{font-size:.9rem;letter-spacing:.08em;text-transform:uppercase;padding:1rem 1.5rem}.right{padding:1.5rem}.right h1{margin-bottom:1.5rem}.list{margin-bottom:.8rem}ol li,sm-carousel{margin-bottom:1rem}.list__item{padding:.8rem 1.5rem}.list__item--active{color:var(--accent-color);background:rgba(var(--text-color),.06)}.card{margin-right:1rem;border-radius:.4rem;padding:1.5rem;min-width:min(24rem,80%);background-color:rgba(var(--text-color),.06)}sm-tab-header{margin-bottom:1.5rem}.page{flex-direction:column}ol{padding:.6rem 1rem}ol li:last-of-type{margin-bottom:0}#total_components_count{font-size:4rem}#components_selection_list{display:grid;gap:1.5rem;grid-template-columns:repeat(auto-fill,minmax(10rem,1fr));padding:1.5rem 0 3rem}.comp-checkbox__title{margin-left:.5rem}@media screen and (max-width:640px){main{grid-template-rows:auto 1fr;grid-template-columns:1fr}#side_nav{display:flex;flex-direction:column;position:fixed;z-index:5;height:100%;width:calc(100% - 4rem);transition:transform .3s;background-color:rgba(var(--foreground-color),1);box-shadow:.5rem 0 2rem rgba(0,0,0,.1)}#side_nav:not(.reveal){transform:translateX(-100%)}.reveal{transform:none}}@media screen and (min-width:640px){#main_header{padding:1rem 1.5rem;grid-area:main-header}#side_nav_button{display:none}main{grid-template-columns:14rem minmax(0,1fr);grid-template-areas:"main-header main-header" ". ."}.right{display:grid;grid-template-columns:1fr 90% 1fr}.right>*{grid-column:2/3}#overview_page{display:grid;gap:1.5rem;grid-template-columns:1fr auto}#overview_page>div:first-of-type{grid-column:2/3;text-align:right}#overview_page>div:nth-of-type(2){grid-row:1/2}}@media (any-hover:hover){::-webkit-scrollbar{width:.5rem;height:.5rem}::-webkit-scrollbar-thumb{background:rgba(var(--text-color),.3);border-radius:1rem}::-webkit-scrollbar-thumb:hover{background:rgba(var(--text-color),.5)}.list__item:hover{background:rgba(var(--text-color),.1);cursor:pointer}} \ No newline at end of file +.weight-400,code{font-weight:400}.hide,.ripple{pointer-events:none}.list,ul{list-style:none}*{padding:0;margin:0;box-sizing:border-box;font-family:Roboto,sans-serif}code,code>*{font-family:"Roboto Mono",monospace}:root{font-size:clamp(1rem,1.2vmax,3rem)}body,html{height:100%;scroll-behavior:smooth}body{--accent-color:#4d2588;--text-color:17,17,17;--text-color-light:100,100,100;--foreground-color:255,255,255;--background-color:#F6f6f6;--error-color:red;color:rgba(var(--text-color),1);background:var(--background-color)}body[data-theme=dark]{--accent-color:#976dd6;--text-color:240,240,240;--text-color-light:170,170,170;--foreground-color:20,20,20;--background-color:#0a0a0a;--error-color:rgb(255, 106, 106)}.full-bleed{grid-column:1/4}.h1{font-size:2.5rem}.h2{font-size:2rem}.h3{font-size:1.4rem}.h4{font-size:1rem}.h5{font-size:.8rem}.uppercase{text-transform:uppercase}.capitalize,.list__item,h2,ol li::first-letter{text-transform:capitalize}p{font-size:.8;max-width:75ch;line-height:1.7;margin-bottom:1.5rem;color:rgba(var(--text-color),.8)}p:not(:last-of-type){margin-bottom:1rem}img{object-fit:cover}a{color:inherit;text-decoration:none}a:focus-visible{box-shadow:0 0 0 .1rem rgba(var(--text-color),1) inset}button{display:inline-flex;border:none;background-color:inherit}a:any-link:focus-visible{outline:solid rgba(var(--text-color),1)}sm-button{--border-radius:0.3rem}.hide{opacity:0}.hide-completely{display:none!important}.no-transformations{transform:none!important}.overflow-ellipsis{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.breakable{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.flex{display:flex}.grid{display:grid}.grid-3{grid-template-columns:1fr auto auto}.flow-column{grid-auto-flow:column}.gap-0-5{gap:.5rem}.gap-1{gap:1rem}.gap-1-5{gap:1.5rem}.gap-2{gap:2rem}.gap-3{gap:3rem}.text-align-right{text-align:right}.align-start{align-items:flex-start}.align-center{align-items:center}.text-center{text-align:center}.justify-start{justify-content:start}.justify-center{justify-content:center}.justify-right{margin-left:auto}.button__icon--right,.comp-checkbox__title{margin-left:.5rem}.align-self-center{align-self:center}.justify-self-center{justify-self:center}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.direction-column{flex-direction:column}.space-between{justify-content:space-between}.w-100{width:100%}.color-0-8{color:rgba(var(--text-color),.8)}.weight-500{font-weight:500}.ripple{position:absolute;border-radius:50%;transform:scale(0);background:rgba(var(--text-color),.16)}.interact,.theme-switcher{position:relative;cursor:pointer;-webkit-tap-highlight-color:transparent}code,pre{background:rgba(var(--text-color),.04)}.interact{overflow:hidden}.observe-empty-state:empty{display:none}.observe-empty-state:not(:empty)~.empty-state{display:none}.icon{width:1.5rem;height:1.5rem;fill:rgba(var(--text-color),.9)}.button__icon{height:1.2rem;width:1.2rem}.button__icon--left{margin-right:.5rem}.theme-switcher{justify-self:flex-end;width:1.5rem;height:1.5rem}.card,.list{flex-direction:column}.theme-switcher .icon{position:absolute;transition:transform .6s}.theme-switcher__checkbox{display:none}.theme-switcher__checkbox:checked~.moon-icon{transform:scale(0) rotate(90deg)}.theme-switcher__checkbox:not(:checked)~.sun-icon{transform:scale(0) rotate(-90deg)}code .str,pre .str{color:#65B042}code .kwd,pre .kwd{color:#E28964}code .com,pre .com{color:#AEAEAE;font-style:italic}code .typ,pre .typ{color:#4395ff}code .lit,pre .lit{color:#1a76c2}code .pln,code .pun,pre .pln,pre .pun{color:rgba(var(--text-color),.8)}code .tag,pre .tag{color:#22863a}code .atn,pre .atn{color:#005cc5}code .atv,pre .atv{color:var(--accent-color)}code .dec,pre .dec{color:#3387CC}pre{max-width:100%;margin:1rem 0;padding:0 1.5rem;overflow-x:auto;font-size:.9rem;white-space:pre-line;border-radius:.5rem}code{border-radius:.2rem;padding:.2rem .4rem}pre code{line-height:1.4;border-radius:none;background:0 0;width:100%}h1,h2,h3,h4.h5{font-family:Poppins,sans-serif}h2{margin:3rem 0 1rem}h2:first-of-type{margin-top:1rem}main{display:grid;height:100%}.card,.list,.list__item,.page{display:flex}#main_header{padding:.5rem 1.5rem;border-bottom:1px solid rgba(var(--text-color),.1)}#side_nav_button{padding:.5rem;margin-left:-.5rem}#backdrop{position:fixed;z-index:4;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,.5)}#side_nav,.right{max-height:100%;overflow-y:auto;padding-bottom:3rem}#side_nav h4,.right{padding:1.5rem}#side_nav h4{font-size:.9rem;letter-spacing:.08em;text-transform:uppercase}.right h1{margin-bottom:1.5rem}.list{margin-bottom:.8rem}ol li,sm-carousel{margin-bottom:1rem}.list__item{padding:.8rem 1.5rem}.list__item--active{color:var(--accent-color);background:rgba(var(--text-color),.06)}.card{margin-right:1rem;border-radius:.4rem;padding:1.5rem;min-width:min(24rem,80%);background-color:rgba(var(--text-color),.06)}sm-tab-header{margin-bottom:1.5rem}.page{flex-direction:column;padding-bottom:3rem}ol{padding:.6rem 1rem}ol li:last-of-type{margin-bottom:0}#total_components_count{font-size:4rem}#components_selection_list{display:grid;gap:1.5rem;grid-template-columns:repeat(auto-fill,minmax(10rem,1fr));padding:1.5rem 0 3rem}@media screen and (max-width:640px){main{grid-template-rows:auto 1fr;grid-template-columns:1fr}#side_nav{display:flex;flex-direction:column;position:fixed;z-index:5;height:100%;width:calc(100% - 4rem);transition:transform .3s;background-color:rgba(var(--foreground-color),1);box-shadow:.5rem 0 2rem rgba(0,0,0,.1)}#side_nav:not(.reveal){transform:translateX(-100%)}.reveal{transform:none}}@media screen and (min-width:640px){#main_header{padding:1rem 1.5rem;grid-area:main-header}#side_nav_button{display:none}main{grid-template-columns:14rem minmax(0,1fr);grid-template-areas:"main-header main-header" ". ."}.right{display:grid;grid-template-columns:1fr 90% 1fr}.right>*{grid-column:2/3}#overview_page{display:grid;gap:1.5rem;grid-template-columns:1fr auto}#overview_page>div:first-of-type{grid-column:2/3;text-align:right}#overview_page>div:nth-of-type(2){grid-row:1/2}}@media (any-hover:hover){::-webkit-scrollbar{width:.5rem;height:.5rem}::-webkit-scrollbar-thumb{background:rgba(var(--text-color),.3);border-radius:1rem}::-webkit-scrollbar-thumb:hover{background:rgba(var(--text-color),.5)}.list__item:hover{background:rgba(var(--text-color),.1);cursor:pointer}} \ No newline at end of file diff --git a/components/css/main.scss b/components/css/main.scss index a5f23c8..3d5dc29 100644 --- a/components/css/main.scss +++ b/components/css/main.scss @@ -13,19 +13,16 @@ html, body{ } body { --accent-color: #4d2588; - --light-shade: rgba(var(--text-color), 0.06); --text-color: 17, 17, 17; --text-color-light: 100, 100, 100; --foreground-color: 255, 255, 255; --background-color: #F6f6f6; --error-color: red; - --green: #00843b; color: rgba(var(--text-color), 1); background: var(--background-color); } body[data-theme='dark']{ --accent-color: #976dd6; - --green: #13ff5a; --text-color: 240, 240, 240; --text-color-light: 170, 170, 170; --foreground-color: 20, 20, 20; @@ -62,6 +59,7 @@ p { font-size: 0.8; max-width: 75ch; line-height: 1.7; + margin-bottom: 1.5rem; color: rgba(var(--text-color), 0.8); &:not(:last-of-type){ margin-bottom: 1rem; @@ -347,7 +345,7 @@ main{ font-size: 0.9rem; letter-spacing: 0.08em; text-transform: uppercase; - padding: 1rem 1.5rem; + padding: 1.5rem; } } .right{ @@ -389,8 +387,7 @@ sm-tab-header{ .page{ display: flex; flex-direction: column; -} -.page__title{ + padding-bottom: 3rem; } ol{ padding: 0.6rem 1rem; diff --git a/components/dist/button.js b/components/dist/button.js index 4f36929..bdb925a 100644 --- a/components/dist/button.js +++ b/components/dist/button.js @@ -60,15 +60,11 @@ smButton.innerHTML = ` -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; - -webkit-transition: -webkit-box-shadow 0.3s; - transition: -webkit-box-shadow 0.3s; - -o-transition: box-shadow 0.3s; - transition: box-shadow 0.3s; - transition: box-shadow 0.3s, -webkit-box-shadow 0.3s; + transition: box-shadow 0.3s, background-color 0.3s; font-family: inherit; font-size: 0.9rem; font-weight: 500; - background: var(--background); + background-color: var(--background); -webkit-tap-highlight-color: transparent; outline: none; overflow: hidden; diff --git a/components/dist/button.min.js b/components/dist/button.min.js index ed068c0..a824f4a 100644 --- a/components/dist/button.min.js +++ b/components/dist/button.min.js @@ -1 +1 @@ -const smButton=document.createElement("template");smButton.innerHTML="\n\n",customElements.define("sm-button",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smButton.content.cloneNode(!0))}get disabled(){return this.isDisabled}set disabled(n){n&&!this.isDisabled?(this.isDisabled=!0,this.setAttribute("disabled",""),this.button.removeAttribute("tabindex")):!n&&this.isDisabled&&(this.isDisabled=!1,this.removeAttribute("disabled"))}dispatch(){this.isDisabled?this.dispatchEvent(new CustomEvent("disabled",{bubbles:!0,composed:!0})):this.dispatchEvent(new CustomEvent("clicked",{bubbles:!0,composed:!0}))}connectedCallback(){this.isDisabled=!1,this.button=this.shadowRoot.querySelector(".button"),this.hasAttribute("disabled")&&!this.isDisabled&&(this.isDisabled=!0),this.addEventListener("click",n=>{this.dispatch()})}}); \ No newline at end of file +const smButton=document.createElement("template");smButton.innerHTML="\n\n",customElements.define("sm-button",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smButton.content.cloneNode(!0))}get disabled(){return this.isDisabled}set disabled(n){n&&!this.isDisabled?(this.isDisabled=!0,this.setAttribute("disabled",""),this.button.removeAttribute("tabindex")):!n&&this.isDisabled&&(this.isDisabled=!1,this.removeAttribute("disabled"))}dispatch(){this.isDisabled?this.dispatchEvent(new CustomEvent("disabled",{bubbles:!0,composed:!0})):this.dispatchEvent(new CustomEvent("clicked",{bubbles:!0,composed:!0}))}connectedCallback(){this.isDisabled=!1,this.button=this.shadowRoot.querySelector(".button"),this.hasAttribute("disabled")&&!this.isDisabled&&(this.isDisabled=!0),this.addEventListener("click",n=>{this.dispatch()})}}); \ No newline at end of file diff --git a/components/dist/checkbox.js b/components/dist/checkbox.js index a8d58c8..255ea63 100644 --- a/components/dist/checkbox.js +++ b/components/dist/checkbox.js @@ -11,8 +11,8 @@ smCheckbox.innerHTML = ` display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; - --height: 1.4rem; - --width: 1.4rem; + --height: 1.2rem; + --width: 1.2rem; --border-radius: 0.2rem; --border-color: rgba(var(--text-color), 0.7); } @@ -30,7 +30,6 @@ smCheckbox.innerHTML = ` -ms-flex-align: center; align-items: center; cursor: pointer; - height: 1.5rem; outline: none; -webkit-tap-highlight-color: transparent; } @@ -40,7 +39,7 @@ smCheckbox.innerHTML = ` } .checkbox:active .icon, .checkbox:focus-within .icon{ - box-shadow: 0 0 0 0.2rem var(--accent-color) inset; + box-shadow: 0 0 0 0.1rem var(--accent-color) inset; } input { @@ -65,14 +64,14 @@ smCheckbox.innerHTML = ` background: var(--accent-color); } :host(:not([checked])) .icon { - box-shadow: 0 0 0 0.2rem var(--border-color) inset; + box-shadow: 0 0 0 0.1rem var(--border-color) inset; } .icon { fill: none; height: var(--height); width: var(--width); - padding: 0.2rem; + padding: 0.1rem; stroke: rgba(var(--text-color), 0.7); stroke-width: 6; overflow: visible; diff --git a/components/dist/checkbox.min.js b/components/dist/checkbox.min.js index abb8d49..e03a648 100644 --- a/components/dist/checkbox.min.js +++ b/components/dist/checkbox.min.js @@ -1 +1 @@ -const smCheckbox=document.createElement("template");smCheckbox.innerHTML='\n\n',customElements.define("sm-checkbox",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smCheckbox.content.cloneNode(!0)),this.checkbox=this.shadowRoot.querySelector(".checkbox"),this.reset=this.reset.bind(this),this.dispatch=this.dispatch.bind(this),this.handleKeyup=this.handleKeyup.bind(this),this.handleClick=this.handleClick.bind(this)}static get observedAttributes(){return["value","disabled","checked"]}get disabled(){return this.hasAttribute("disabled")}set disabled(e){e?this.setAttribute("disabled",""):this.removeAttribute("disabled")}get checked(){return this.hasAttribute("checked")}set checked(e){e?this.setAttribute("checked",""):this.removeAttribute("checked")}set value(e){this.setAttribute("value",e)}get value(){return this.getAttribute("value")}reset(){this.removeAttribute("checked")}dispatch(){this.dispatchEvent(new CustomEvent("change",{bubbles:!0,composed:!0}))}handleKeyup(e){"Space"===e.code&&this.click()}handleClick(e){this.toggleAttribute("checked")}connectedCallback(){this.hasAttribute("disabled")||this.setAttribute("tabindex","0"),this.setAttribute("role","checkbox"),this.hasAttribute("checked")||this.setAttribute("aria-checked","false"),this.addEventListener("keyup",this.handleKeyup),this.addEventListener("click",this.handleClick)}attributeChangedCallback(e,t,n){t!==n&&("checked"===e?(this.setAttribute("aria-checked",this.hasAttribute("checked")),this.dispatch()):"disabled"===e&&(this.hasAttribute("disabled")?this.removeAttribute("tabindex"):this.setAttribute("tabindex","0")))}disconnectedCallback(){this.removeEventListener("keyup",this.handleKeyup),this.removeEventListener("change",this.handleClick)}}); \ No newline at end of file +const smCheckbox=document.createElement("template");smCheckbox.innerHTML='\n\n',customElements.define("sm-checkbox",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smCheckbox.content.cloneNode(!0)),this.checkbox=this.shadowRoot.querySelector(".checkbox"),this.reset=this.reset.bind(this),this.dispatch=this.dispatch.bind(this),this.handleKeyup=this.handleKeyup.bind(this),this.handleClick=this.handleClick.bind(this)}static get observedAttributes(){return["value","disabled","checked"]}get disabled(){return this.hasAttribute("disabled")}set disabled(e){e?this.setAttribute("disabled",""):this.removeAttribute("disabled")}get checked(){return this.hasAttribute("checked")}set checked(e){e?this.setAttribute("checked",""):this.removeAttribute("checked")}set value(e){this.setAttribute("value",e)}get value(){return this.getAttribute("value")}reset(){this.removeAttribute("checked")}dispatch(){this.dispatchEvent(new CustomEvent("change",{bubbles:!0,composed:!0}))}handleKeyup(e){"Space"===e.code&&this.click()}handleClick(e){this.toggleAttribute("checked")}connectedCallback(){this.hasAttribute("disabled")||this.setAttribute("tabindex","0"),this.setAttribute("role","checkbox"),this.hasAttribute("checked")||this.setAttribute("aria-checked","false"),this.addEventListener("keyup",this.handleKeyup),this.addEventListener("click",this.handleClick)}attributeChangedCallback(e,t,n){t!==n&&("checked"===e?(this.setAttribute("aria-checked",this.hasAttribute("checked")),this.dispatch()):"disabled"===e&&(this.hasAttribute("disabled")?this.removeAttribute("tabindex"):this.setAttribute("tabindex","0")))}disconnectedCallback(){this.removeEventListener("keyup",this.handleKeyup),this.removeEventListener("change",this.handleClick)}}); \ No newline at end of file diff --git a/components/dist/file-input.js b/components/dist/file-input.js index 653c18e..c362390 100644 --- a/components/dist/file-input.js +++ b/components/dist/file-input.js @@ -8,7 +8,7 @@ fileInput.innerHTML = ` } :host{ --border-radius: 0.3rem; - --button-color: inherit; + --button-color: var(--background-color); --button-font-weight: 500; --button-background-color: var(--accent-color); } @@ -16,7 +16,7 @@ fileInput.innerHTML = ` display: flex; } - .file-picker { + .file-picker-button { display: flex; cursor: pointer; user-select: none; @@ -56,7 +56,7 @@ fileInput.innerHTML = ` ` @@ -70,7 +70,7 @@ customElements.define('file-input', class extends HTMLElement { this.input = this.shadowRoot.querySelector('input') this.fileInput = this.shadowRoot.querySelector('.file-input') this.filesPreviewWraper = this.shadowRoot.querySelector('.files-preview-wrapper') - this.observeList = ['accept', 'multiple', 'capture'] + this.reflectedAttributes = ['accept', 'multiple', 'capture'] this.reset = this.reset.bind(this) this.formatBytes = this.formatBytes.bind(this) @@ -142,7 +142,7 @@ customElements.define('file-input', class extends HTMLElement { this.fileInput.addEventListener('keydown', this.handleKeyDown) } attributeChangedCallback(name) { - if (this.observeList.includes(name)){ + if (this.reflectedAttributes.includes(name)){ if (this.hasAttribute(name)) { this.input.setAttribute(name, this.getAttribute(name) ? this.getAttribute(name) : '') } diff --git a/components/dist/file-input.min.js b/components/dist/file-input.min.js index 2c94bdf..faa7e60 100644 --- a/components/dist/file-input.min.js +++ b/components/dist/file-input.min.js @@ -1 +1 @@ -const fileInput=document.createElement("template");fileInput.innerHTML='\n \t\n\t\n \t\n',customElements.define("file-input",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(fileInput.content.cloneNode(!0)),this.input=this.shadowRoot.querySelector("input"),this.fileInput=this.shadowRoot.querySelector(".file-input"),this.filesPreviewWraper=this.shadowRoot.querySelector(".files-preview-wrapper"),this.observeList=["accept","multiple","capture"],this.reset=this.reset.bind(this),this.formatBytes=this.formatBytes.bind(this),this.createFilePreview=this.createFilePreview.bind(this),this.handleChange=this.handleChange.bind(this),this.handleKeyDown=this.handleKeyDown.bind(this)}static get observedAttributes(){return["accept","multiple","capture"]}get files(){return this.input.files}set accept(t){this.setAttribute("accept",t)}set multiple(t){t?this.setAttribute("mutiple",""):this.removeAttribute("mutiple")}set capture(t){this.setAttribute("capture",t)}set value(t){this.input.value=t}get isValid(){return""!==this.input.value}reset(){this.input.value="",this.filesPreviewWraper.innerHTML=""}formatBytes(t,e=2){if(0===t)return"0 Bytes";const n=0>e?0:e,i=Math.floor(Math.log(t)/Math.log(1024));return parseFloat((t/Math.pow(1024,i)).toFixed(n))+" "+["Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"][i]}createFilePreview(t){const e=document.createElement("li"),{name:n,size:i}=t;return e.className="file-preview",e.innerHTML=`\n\t\t\t
${n}
\n
${this.formatBytes(i)}
\n\t\t`,e}handleChange(t){this.filesPreviewWraper.innerHTML="";const e=document.createDocumentFragment();Array.from(t.target.files).forEach(t=>{e.append(this.createFilePreview(t))}),this.filesPreviewWraper.append(e)}handleKeyDown(t){"Enter"!==t.key&&"Space"!==t.code||(t.preventDefault(),this.input.click())}connectedCallback(){this.setAttribute("role","button"),this.setAttribute("aria-label","File upload"),this.input.addEventListener("change",this.handleChange),this.fileInput.addEventListener("keydown",this.handleKeyDown)}attributeChangedCallback(t){this.observeList.includes(t)&&(this.hasAttribute(t)?this.input.setAttribute(t,this.getAttribute(t)?this.getAttribute(t):""):this.input.removeAttribute(t))}disconnectedCallback(){this.input.removeEventListener("change",this.handleChange),this.fileInput.removeEventListener("keydown",this.handleKeyDown)}}); \ No newline at end of file +const fileInput=document.createElement("template");fileInput.innerHTML='\n \t\n\t\n \t\n',customElements.define("file-input",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(fileInput.content.cloneNode(!0)),this.input=this.shadowRoot.querySelector("input"),this.fileInput=this.shadowRoot.querySelector(".file-input"),this.filesPreviewWraper=this.shadowRoot.querySelector(".files-preview-wrapper"),this.reflectedAttributes=["accept","multiple","capture"],this.reset=this.reset.bind(this),this.formatBytes=this.formatBytes.bind(this),this.createFilePreview=this.createFilePreview.bind(this),this.handleChange=this.handleChange.bind(this),this.handleKeyDown=this.handleKeyDown.bind(this)}static get observedAttributes(){return["accept","multiple","capture"]}get files(){return this.input.files}set accept(t){this.setAttribute("accept",t)}set multiple(t){t?this.setAttribute("mutiple",""):this.removeAttribute("mutiple")}set capture(t){this.setAttribute("capture",t)}set value(t){this.input.value=t}get isValid(){return""!==this.input.value}reset(){this.input.value="",this.filesPreviewWraper.innerHTML=""}formatBytes(t,e=2){if(0===t)return"0 Bytes";const n=0>e?0:e,i=Math.floor(Math.log(t)/Math.log(1024));return parseFloat((t/Math.pow(1024,i)).toFixed(n))+" "+["Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"][i]}createFilePreview(t){const e=document.createElement("li"),{name:n,size:i}=t;return e.className="file-preview",e.innerHTML=`\n\t\t\t
${n}
\n
${this.formatBytes(i)}
\n\t\t`,e}handleChange(t){this.filesPreviewWraper.innerHTML="";const e=document.createDocumentFragment();Array.from(t.target.files).forEach(t=>{e.append(this.createFilePreview(t))}),this.filesPreviewWraper.append(e)}handleKeyDown(t){"Enter"!==t.key&&"Space"!==t.code||(t.preventDefault(),this.input.click())}connectedCallback(){this.setAttribute("role","button"),this.setAttribute("aria-label","File upload"),this.input.addEventListener("change",this.handleChange),this.fileInput.addEventListener("keydown",this.handleKeyDown)}attributeChangedCallback(t){this.reflectedAttributes.includes(t)&&(this.hasAttribute(t)?this.input.setAttribute(t,this.getAttribute(t)?this.getAttribute(t):""):this.input.removeAttribute(t))}disconnectedCallback(){this.input.removeEventListener("change",this.handleChange),this.fileInput.removeEventListener("keydown",this.handleKeyDown)}}); \ No newline at end of file diff --git a/components/dist/form.js b/components/dist/form.js index c0c251e..c09452c 100644 --- a/components/dist/form.js +++ b/components/dist/form.js @@ -40,7 +40,7 @@ customElements.define('sm-form', class extends HTMLElement { this.handleKeydown = this.handleKeydown.bind(this) this.reset = this.reset.bind(this) } - debounce(callback, wait){ + debounce(callback, wait) { let timeoutId = null; return (...args) => { window.clearTimeout(timeoutId); @@ -64,12 +64,22 @@ customElements.define('sm-form', class extends HTMLElement { if (this.allRequiredValid) { this.submitButton.click() } - else { - // implement show validity logic - } +/* else { + this.requiredElements.find(elem => !elem.isValid) + .animate([ + { transform: 'translateX(-1rem)' }, + { transform: 'translateX(1rem)' }, + { transform: 'translateX(-0.5rem)' }, + { transform: 'translateX(0.5rem)' }, + { transform: 'translateX(0)' }, + ], { + duration: 300, + easing: 'ease' + }) + } */ } } - reset(){ + reset() { this.formElements.forEach(elem => elem.reset()) } connectedCallback() { @@ -79,7 +89,7 @@ customElements.define('sm-form', class extends HTMLElement { this.requiredElements = this.formElements.filter(elem => elem.hasAttribute('required')) this.submitButton = e.target.assignedElements().find(elem => elem.getAttribute('variant') === 'primary' || elem.getAttribute('type') === 'submit'); this.resetButton = e.target.assignedElements().find(elem => elem.getAttribute('type') === 'reset'); - if (this.resetButton) { + if (this.resetButton) { this.resetButton.addEventListener('click', this.reset) } }) diff --git a/components/dist/input.js b/components/dist/input.js index 2b6468c..88581d1 100644 --- a/components/dist/input.js +++ b/components/dist/input.js @@ -43,6 +43,7 @@ border: none; --border-radius: 0.3rem; --padding: 0.7rem 1rem; --background: rgba(var(--text-color), 0.06); + --success-color: #00C853; } .hide{ opacity: 0 !important; @@ -179,15 +180,29 @@ input{ .animate-label:focus-within:not(.readonly) .label{ color: var(--accent-color) } -.feedback-text{ - font-size: 0.9rem; +.feedback-text:not(:empty){ + display: flex; width: 100%; - color: var(--error-color); - padding: 0.6rem 1rem; text-align: left; + font-size: 0.9rem; + align-items: center; + padding: 0.8rem 1rem; + color: rgba(var(--text-color), 0.8); } -.feedback-text:empty{ - padding: 0; +.success{ + color: var(--success-color); +} +.error{ + color: var(--error-color); +} +.status-icon{ + margin-right: 0.2rem; +} +.status-icon--error{ + fill: var(--error-color); +} +.status-icon--success{ + fill: var(--success-color); } @media (any-hover: hover){ .icon:hover{ @@ -199,12 +214,12 @@ input{ -
+

`; customElements.define('sm-input', @@ -221,13 +236,13 @@ customElements.define('sm-input', this.clearBtn = this.shadowRoot.querySelector('.clear') this.label = this.shadowRoot.querySelector('.label') this.feedbackText = this.shadowRoot.querySelector('.feedback-text') + this._helperText + this._errorText + this.isRequired = false this.validationFunction - this.observeList = ['type', 'required', 'disabled', 'readonly', 'min', 'max', 'pattern', 'minlength', 'maxlength', 'step'] + this.reflectedAttributes = ['required', 'disabled', 'type', 'inputmode', 'readonly', 'min', 'max', 'pattern', 'minlength', 'maxlength', 'step'] this.reset = this.reset.bind(this) - this.setValidity = this.setValidity.bind(this) - this.showValidity = this.showValidity.bind(this) - this.hideValidity = this.hideValidity.bind(this) this.focusIn = this.focusIn.bind(this) this.focusOut = this.focusOut.bind(this) this.fireEvent = this.fireEvent.bind(this) @@ -236,7 +251,7 @@ customElements.define('sm-input', } static get observedAttributes() { - return ['placeholder', 'type', 'required', 'disabled', 'readonly', 'min', 'max', 'pattern', 'minlength', 'maxlength', 'step'] + return ['placeholder', 'required', 'disabled', 'type', 'inputmode', 'readonly', 'min', 'max', 'pattern', 'minlength', 'maxlength', 'step', 'helper-text', 'error-text'] } get value() { @@ -266,12 +281,12 @@ customElements.define('sm-input', } get isValid() { + const _isValid = this.input.checkValidity() + let _customValid = true if (this.customValidation) { - return this.validationFunction(this.input.value) - } - else { - return this.input.checkValidity() + _customValid = this.validationFunction(this.input.value) } + return (_isValid && _customValid) } get validity() { @@ -294,22 +309,16 @@ customElements.define('sm-input', set customValidation(val) { this.validationFunction = val } + set errorText(val) { + this._errorText = val + } + set helperText(val) { + this._helperText = val + } reset(){ this.value = '' } - setValidity(message){ - this.feedbackText.textContent = message - } - - showValidity(){ - this.feedbackText.classList.remove('hide-completely') - } - - hideValidity(){ - this.feedbackText.classList.add('hide-completely') - } - focusIn(){ this.input.focus() } @@ -342,9 +351,26 @@ customElements.define('sm-input', this.clearBtn.classList.remove('hide') } else { this.clearBtn.classList.add('hide') + if (this.isRequired) { + this.feedbackText.textContent = '* required' + } + } + if (!this.isValid) { + if (this._errorText) { + this.feedbackText.classList.add('error') + this.feedbackText.classList.remove('success') + this.feedbackText.innerHTML = ` + + ${this._errorText} + ` + } + } else { + this.feedbackText.classList.remove('error') + this.feedbackText.classList.add('success') + this.feedbackText.textContent = '' } } - if (!this.hasAttribute('placeholder') || this.getAttribute('placeholder') === '') return; + if (!this.hasAttribute('placeholder') || this.getAttribute('placeholder').trim() === '') return; if (this.input.value !== '') { if (this.animate) this.inputParent.classList.add('animate-label') @@ -361,24 +387,13 @@ customElements.define('sm-input', connectedCallback() { this.animate = this.hasAttribute('animate') - if (this.hasAttribute('value')) { - this.input.value = this.getAttribute('value') - this.checkInput() - } - if (this.hasAttribute('error-text')) { - this.feedbackText.textContent = this.getAttribute('error-text') - } - if (!this.hasAttribute('type')) { - this.setAttribute('type', 'text') - } - this.input.addEventListener('input', this.checkInput) this.clearBtn.addEventListener('click', this.reset) } attributeChangedCallback(name, oldValue, newValue) { if (oldValue !== newValue) { - if (this.observeList.includes(name)) { + if (this.reflectedAttributes.includes(name)) { if (this.hasAttribute(name)) { this.input.setAttribute(name, this.getAttribute(name) ? this.getAttribute(name) : '') } @@ -390,11 +405,24 @@ customElements.define('sm-input', this.label.textContent = newValue; this.setAttribute('aria-label', newValue); } + else if (this.hasAttribute('value')) { + this.checkInput() + } else if (name === 'type') { if (this.hasAttribute('type') && this.getAttribute('type') === 'number') { this.input.setAttribute('inputmode', 'numeric') } } + else if (name === 'helper-text') { + this._helperText = this.getAttribute('helper-text') + } + else if (name === 'error-text') { + this._errorText = this.getAttribute('error-text') + } + else if (name === 'required') { + this.isRequired = this.hasAttribute('required') + this.feedbackText.textContent = '* required' + } else if (name === 'readonly') { if (this.hasAttribute('readonly')) { this.inputParent.classList.add('readonly') diff --git a/components/dist/input.min.js b/components/dist/input.min.js index 84126d8..1807b7c 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 \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.validationFunction,this.observeList=["type","required","disabled","readonly","min","max","pattern","minlength","maxlength","step"],this.reset=this.reset.bind(this),this.setValidity=this.setValidity.bind(this),this.showValidity=this.showValidity.bind(this),this.hideValidity=this.hideValidity.bind(this),this.focusIn=this.focusIn.bind(this),this.focusOut=this.focusOut.bind(this),this.fireEvent=this.fireEvent.bind(this),this.debounce=this.debounce.bind(this),this.checkInput=this.checkInput.bind(this)}static get observedAttributes(){return["placeholder","type","required","disabled","readonly","min","max","pattern","minlength","maxlength","step"]}get value(){return this.input.value}set value(t){this.input.value=t,this.checkInput(),this.fireEvent()}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 isValid(){return this.customValidation?this.validationFunction(this.input.value):this.input.checkValidity()}get validity(){return this.input.validity}set disabled(t){t?this.inputParent.classList.add("disabled"):this.inputParent.classList.remove("disabled")}set readOnly(t){t?this.setAttribute("readonly",""):this.removeAttribute("readonly")}set customValidation(t){this.validationFunction=t}reset(){this.value=""}setValidity(t){this.feedbackText.textContent=t}showValidity(){this.feedbackText.classList.remove("hide-completely")}hideValidity(){this.feedbackText.classList.add("hide-completely")}focusIn(){this.input.focus()}focusOut(){this.input.blur()}fireEvent(){let t=new Event("input",{bubbles:!0,cancelable:!0,composed:!0});this.dispatchEvent(t)}debounce(t,e){let n=null;return(...i)=>{window.clearTimeout(n),n=window.setTimeout(()=>{t.apply(null,i)},e)}}checkInput(t){this.hasAttribute("readonly")||(""!==this.input.value?this.clearBtn.classList.remove("hide"):this.clearBtn.classList.add("hide")),this.hasAttribute("placeholder")&&""!==this.getAttribute("placeholder")&&(""!==this.input.value?this.animate?this.inputParent.classList.add("animate-label"):this.label.classList.add("hide"):this.animate?this.inputParent.classList.remove("animate-label"):this.label.classList.remove("hide"))}connectedCallback(){this.animate=this.hasAttribute("animate"),this.hasAttribute("value")&&(this.input.value=this.getAttribute("value"),this.checkInput()),this.hasAttribute("error-text")&&(this.feedbackText.textContent=this.getAttribute("error-text")),this.hasAttribute("type")||this.setAttribute("type","text"),this.input.addEventListener("input",this.checkInput),this.clearBtn.addEventListener("click",this.reset)}attributeChangedCallback(t,e,n){e!==n&&(this.observeList.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)):"type"===t?this.hasAttribute("type")&&"number"===this.getAttribute("type")&&this.input.setAttribute("inputmode","numeric"):"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.reset)}}); \ No newline at end of file +const smInput=document.createElement("template");smInput.innerHTML='\n\n
\n \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._helperText,this._errorText,this.isRequired=!1,this.validationFunction,this.reflectedAttributes=["required","disabled","type","inputmode","readonly","min","max","pattern","minlength","maxlength","step"],this.reset=this.reset.bind(this),this.focusIn=this.focusIn.bind(this),this.focusOut=this.focusOut.bind(this),this.fireEvent=this.fireEvent.bind(this),this.debounce=this.debounce.bind(this),this.checkInput=this.checkInput.bind(this)}static get observedAttributes(){return["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){this.input.value=t,this.checkInput(),this.fireEvent()}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 isValid(){const t=this.input.checkValidity();let e=!0;return this.customValidation&&(e=this.validationFunction(this.input.value)),t&&e}get validity(){return this.input.validity}set disabled(t){t?this.inputParent.classList.add("disabled"):this.inputParent.classList.remove("disabled")}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}reset(){this.value=""}focusIn(){this.input.focus()}focusOut(){this.input.blur()}fireEvent(){let t=new Event("input",{bubbles:!0,cancelable:!0,composed:!0});this.dispatchEvent(t)}debounce(t,e){let n=null;return(...i)=>{window.clearTimeout(n),n=window.setTimeout(()=>{t.apply(null,i)},e)}}checkInput(t){this.hasAttribute("readonly")||(""!==this.input.value?this.clearBtn.classList.remove("hide"):(this.clearBtn.classList.add("hide"),this.isRequired&&(this.feedbackText.textContent="* required")),this.isValid?(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 `)),this.hasAttribute("placeholder")&&""!==this.getAttribute("placeholder").trim()&&(""!==this.input.value?this.animate?this.inputParent.classList.add("animate-label"):this.label.classList.add("hide"):this.animate?this.inputParent.classList.remove("animate-label"):this.label.classList.remove("hide"))}connectedCallback(){this.animate=this.hasAttribute("animate"),this.input.addEventListener("input",this.checkInput),this.clearBtn.addEventListener("click",this.reset)}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","numeric"):"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.feedbackText.textContent="* required"):"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.reset)}}); \ No newline at end of file diff --git a/components/dist/menu.js b/components/dist/menu.js index 28c81e2..ababb1c 100644 --- a/components/dist/menu.js +++ b/components/dist/menu.js @@ -178,6 +178,11 @@ customElements.define('sm-menu', class extends HTMLElement { menu = this.shadowRoot.querySelector('.menu') this.icon = this.shadowRoot.querySelector('.icon') this.open = false; + + slot.addEventListener('slotchange', e => { + this.availableOptions = slot.assignedElements() + this.containerDimensions = this.optionList.getBoundingClientRect() + }); menu.addEventListener('click', e => { if (!this.open) { this.expand() @@ -204,21 +209,22 @@ customElements.define('sm-menu', class extends HTMLElement { e.preventDefault() if (document.activeElement.previousElementSibling) { document.activeElement.previousElementSibling.focus() + } else { + this.availableOptions[this.availableOptions.length - 1].focus() } } if (e.code === 'ArrowDown' || e.code === 'ArrowLeft') { e.preventDefault() - if (document.activeElement.nextElementSibling) + if (document.activeElement.nextElementSibling) { document.activeElement.nextElementSibling.focus() + } else{ + this.availableOptions[0].focus() + } } }) this.optionList.addEventListener('click', e => { this.collapse() }) - slot.addEventListener('slotchange', e => { - this.availableOptions = slot.assignedElements() - this.containerDimensions = this.optionList.getBoundingClientRect() - }); window.addEventListener('mousedown', e => { if (!this.contains(e.target) && e.button !== 2) { this.collapse() diff --git a/components/dist/menu.min.js b/components/dist/menu.min.js index 57d8cd9..4b591af 100644 --- a/components/dist/menu.min.js +++ b/components/dist/menu.min.js @@ -1 +1 @@ -const smMenu=document.createElement("template");smMenu.innerHTML='\n\n
\n \n
\n \n
\n
',customElements.define("sm-menu",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smMenu.content.cloneNode(!0)),this.expand=this.expand.bind(this)}static get observedAttributes(){return["value"]}get value(){return this.getAttribute("value")}set value(n){this.setAttribute("value",n)}expand(){this.open||(this.optionList.classList.remove("hide"),this.optionList.classList.add("no-transformations"),this.open=!0,this.icon.classList.add("focused"),this.availableOptions.forEach(n=>{n.setAttribute("tabindex","0")}))}collapse(){this.open&&(this.open=!1,this.icon.classList.remove("focused"),this.optionList.classList.add("hide"),this.optionList.classList.remove("no-transformations"),this.availableOptions.forEach(n=>{n.removeAttribute("tabindex")}))}connectedCallback(){this.availableOptions,this.containerDimensions,this.optionList=this.shadowRoot.querySelector(".options");let n=this.shadowRoot.querySelector(".options slot"),e=this.shadowRoot.querySelector(".menu");this.icon=this.shadowRoot.querySelector(".icon"),this.open=!1,e.addEventListener("click",n=>{this.open?this.collapse():this.expand()}),e.addEventListener("keydown",n=>{"ArrowDown"!==n.code&&"ArrowRight"!==n.code||(n.preventDefault(),this.availableOptions[0].focus()),"Enter"!==n.code&&"Space"!==n.code||(n.preventDefault(),this.open?this.collapse():this.expand())}),this.optionList.addEventListener("keydown",n=>{"ArrowUp"!==n.code&&"ArrowRight"!==n.code||(n.preventDefault(),document.activeElement.previousElementSibling&&document.activeElement.previousElementSibling.focus()),"ArrowDown"!==n.code&&"ArrowLeft"!==n.code||(n.preventDefault(),document.activeElement.nextElementSibling&&document.activeElement.nextElementSibling.focus())}),this.optionList.addEventListener("click",n=>{this.collapse()}),n.addEventListener("slotchange",e=>{this.availableOptions=n.assignedElements(),this.containerDimensions=this.optionList.getBoundingClientRect()}),window.addEventListener("mousedown",n=>{this.contains(n.target)||2===n.button||this.collapse()})}});const smMenuOption=document.createElement("template");smMenuOption.innerHTML='\n\n
\n \n
',customElements.define("sm-menu-option",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smMenuOption.content.cloneNode(!0))}connectedCallback(){this.addEventListener("keyup",n=>{"Enter"!==n.code&&"Space"!==n.code||(n.preventDefault(),this.click())})}}); \ No newline at end of file +const smMenu=document.createElement("template");smMenu.innerHTML='\n\n
\n \n
\n \n
\n
',customElements.define("sm-menu",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smMenu.content.cloneNode(!0)),this.expand=this.expand.bind(this)}static get observedAttributes(){return["value"]}get value(){return this.getAttribute("value")}set value(n){this.setAttribute("value",n)}expand(){this.open||(this.optionList.classList.remove("hide"),this.optionList.classList.add("no-transformations"),this.open=!0,this.icon.classList.add("focused"),this.availableOptions.forEach(n=>{n.setAttribute("tabindex","0")}))}collapse(){this.open&&(this.open=!1,this.icon.classList.remove("focused"),this.optionList.classList.add("hide"),this.optionList.classList.remove("no-transformations"),this.availableOptions.forEach(n=>{n.removeAttribute("tabindex")}))}connectedCallback(){this.availableOptions,this.containerDimensions,this.optionList=this.shadowRoot.querySelector(".options");let n=this.shadowRoot.querySelector(".options slot"),t=this.shadowRoot.querySelector(".menu");this.icon=this.shadowRoot.querySelector(".icon"),this.open=!1,n.addEventListener("slotchange",t=>{this.availableOptions=n.assignedElements(),this.containerDimensions=this.optionList.getBoundingClientRect()}),t.addEventListener("click",n=>{this.open?this.collapse():this.expand()}),t.addEventListener("keydown",n=>{"ArrowDown"!==n.code&&"ArrowRight"!==n.code||(n.preventDefault(),this.availableOptions[0].focus()),"Enter"!==n.code&&"Space"!==n.code||(n.preventDefault(),this.open?this.collapse():this.expand())}),this.optionList.addEventListener("keydown",n=>{"ArrowUp"!==n.code&&"ArrowRight"!==n.code||(n.preventDefault(),document.activeElement.previousElementSibling?document.activeElement.previousElementSibling.focus():this.availableOptions[this.availableOptions.length-1].focus()),"ArrowDown"!==n.code&&"ArrowLeft"!==n.code||(n.preventDefault(),document.activeElement.nextElementSibling?document.activeElement.nextElementSibling.focus():this.availableOptions[0].focus())}),this.optionList.addEventListener("click",n=>{this.collapse()}),window.addEventListener("mousedown",n=>{this.contains(n.target)||2===n.button||this.collapse()})}});const smMenuOption=document.createElement("template");smMenuOption.innerHTML='\n\n
\n \n
',customElements.define("sm-menu-option",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smMenuOption.content.cloneNode(!0))}connectedCallback(){this.addEventListener("keyup",n=>{"Enter"!==n.code&&"Space"!==n.code||(n.preventDefault(),this.click())})}}); \ No newline at end of file diff --git a/components/dist/notifications.js b/components/dist/notifications.js index ae7b811..79f20ee 100644 --- a/components/dist/notifications.js +++ b/components/dist/notifications.js @@ -11,6 +11,8 @@ smNotifications.innerHTML = ` display: -webkit-box; display: -ms-flexbox; display: flex; + --icon-height: 2rem; + --icon-width: 2rem; } .hide{ opacity: 0 !important; @@ -25,7 +27,7 @@ smNotifications.innerHTML = ` bottom: 0; z-index: 100; max-height: 100%; - padding: 1.5rem; + padding: 1rem; overflow: hidden auto; -ms-scroll-chaining: none; overscroll-behavior: contain; @@ -39,10 +41,6 @@ smNotifications.innerHTML = ` display: flex; position: relative; border-radius: 0.3rem; - -webkit-box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.1), - 0.5rem 1rem 2rem rgba(0, 0, 0, 0.1); - box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.1), - 0.5rem 1rem 2rem rgba(0, 0, 0, 0.1); background: rgba(var(--foreground-color), 1); overflow: hidden; overflow-wrap: break-word; @@ -56,6 +54,11 @@ smNotifications.innerHTML = ` max-width: 100%; padding: 1rem; } + .icon-container:not(:empty){ + margin-right: 0.5rem; + height: var(--icon-height); + width: var(--icon-width); + } h4:first-letter, p:first-letter{ text-transform: uppercase; @@ -148,24 +151,35 @@ customElements.define('sm-notifications', class extends HTMLElement { } this.push = this.push.bind(this) + this.createNotification = this.createNotification.bind(this) this.removeNotification = this.removeNotification.bind(this) this.clearAll = this.clearAll.bind(this) - + } - push(messageBody, options = {}) { - const {pinned} = options - let notification = document.createElement('div'), - composition = `` + createNotification(message, options) { + const { pinned = false, icon = '' } = options + const notification = document.createElement('div') notification.classList.add('notification') - if (pinned) - notification.classList.add('pinned') + let composition = `` composition += ` -

${messageBody}

- ` +
${icon}
+

${message}

+ ` + if (pinned) { + notification.classList.add('pinned') + composition += ` + + ` + } notification.innerHTML = composition + return notification + } + + push(message, options = {}) { + const notification = this.createNotification(message, options) this.notificationPanel.append(notification) notification.animate([ { @@ -179,7 +193,7 @@ customElements.define('sm-notifications', class extends HTMLElement { ], this.animationOptions) } - removeNotification(notification){ + removeNotification(notification) { notification.animate([ { transform: `none`, @@ -194,7 +208,7 @@ customElements.define('sm-notifications', class extends HTMLElement { } } - clearAll(){ + clearAll() { Array.from(this.notificationPanel.children).forEach(child => { this.removeNotification(child) }) @@ -202,7 +216,7 @@ customElements.define('sm-notifications', class extends HTMLElement { connectedCallback() { this.notificationPanel.addEventListener('click', e => { - if (e.target.closest('.close'))( + if (e.target.closest('.close')) ( this.removeNotification(e.target.closest('.notification')) ) }) @@ -210,11 +224,12 @@ customElements.define('sm-notifications', class extends HTMLElement { const observer = new MutationObserver(mutationList => { mutationList.forEach(mutation => { if (mutation.type === 'childList') { - if (mutation.addedNodes.length && !mutation.addedNodes[0].classList.contains('pinned')) + if (mutation.addedNodes.length && !mutation.addedNodes[0].classList.contains('pinned')) { setTimeout(() => { this.removeNotification(mutation.addedNodes[0]) }, 5000); } + } }) }) observer.observe(this.notificationPanel, { diff --git a/components/dist/notifications.min.js b/components/dist/notifications.min.js index 48bf48e..4e4552d 100644 --- a/components/dist/notifications.min.js +++ b/components/dist/notifications.min.js @@ -1 +1 @@ -const smNotifications=document.createElement("template");smNotifications.innerHTML='\n\n
\n',customElements.define("sm-notifications",class extends HTMLElement{constructor(){super(),this.shadow=this.attachShadow({mode:"open"}).append(smNotifications.content.cloneNode(!0)),this.notificationPanel=this.shadowRoot.querySelector(".notification-panel"),this.animationOptions={duration:300,fill:"forwards",easing:"ease"},this.push=this.push.bind(this),this.removeNotification=this.removeNotification.bind(this),this.clearAll=this.clearAll.bind(this)}push(n,o={}){const{pinned:e}=o;let t=document.createElement("div"),i="";t.classList.add("notification"),e&&t.classList.add("pinned"),i+=`\n

${n}

\n `,t.innerHTML=i,this.notificationPanel.append(t),t.animate([{transform:"translateY(1rem)",opacity:"0"},{transform:"none",opacity:"1"}],this.animationOptions)}removeNotification(n){n.animate([{transform:"none",opacity:"1"},{transform:"translateY(1rem)",opacity:"0"}],this.animationOptions).onfinish=(()=>{n.remove()})}clearAll(){Array.from(this.notificationPanel.children).forEach(n=>{this.removeNotification(n)})}connectedCallback(){this.notificationPanel.addEventListener("click",n=>{n.target.closest(".close")&&this.removeNotification(n.target.closest(".notification"))});const n=new MutationObserver(n=>{n.forEach(n=>{"childList"===n.type&&n.addedNodes.length&&!n.addedNodes[0].classList.contains("pinned")&&setTimeout(()=>{this.removeNotification(n.addedNodes[0])},5e3)})});n.observe(this.notificationPanel,{childList:!0})}}); \ No newline at end of file +const smNotifications=document.createElement("template");smNotifications.innerHTML='\n\n
\n',customElements.define("sm-notifications",class extends HTMLElement{constructor(){super(),this.shadow=this.attachShadow({mode:"open"}).append(smNotifications.content.cloneNode(!0)),this.notificationPanel=this.shadowRoot.querySelector(".notification-panel"),this.animationOptions={duration:300,fill:"forwards",easing:"ease"},this.push=this.push.bind(this),this.createNotification=this.createNotification.bind(this),this.removeNotification=this.removeNotification.bind(this),this.clearAll=this.clearAll.bind(this)}createNotification(n,t){const{pinned:i=!1,icon:o=""}=t,e=document.createElement("div");e.classList.add("notification");let a="";return a+=`\n
${o}
\n

${n}

\n `,i&&(e.classList.add("pinned"),a+='\n \n '),e.innerHTML=a,e}push(n,t={}){const i=this.createNotification(n,t);this.notificationPanel.append(i),i.animate([{transform:"translateY(1rem)",opacity:"0"},{transform:"none",opacity:"1"}],this.animationOptions)}removeNotification(n){n.animate([{transform:"none",opacity:"1"},{transform:"translateY(1rem)",opacity:"0"}],this.animationOptions).onfinish=(()=>{n.remove()})}clearAll(){Array.from(this.notificationPanel.children).forEach(n=>{this.removeNotification(n)})}connectedCallback(){this.notificationPanel.addEventListener("click",n=>{n.target.closest(".close")&&this.removeNotification(n.target.closest(".notification"))});const n=new MutationObserver(n=>{n.forEach(n=>{"childList"===n.type&&n.addedNodes.length&&!n.addedNodes[0].classList.contains("pinned")&&setTimeout(()=>{this.removeNotification(n.addedNodes[0])},5e3)})});n.observe(this.notificationPanel,{childList:!0})}}); \ No newline at end of file diff --git a/components/dist/select.js b/components/dist/select.js index 3d062d0..8137fff 100644 --- a/components/dist/select.js +++ b/components/dist/select.js @@ -220,12 +220,17 @@ customElements.define('sm-select', class extends HTMLElement { e.preventDefault() if (document.activeElement.previousElementSibling) { document.activeElement.previousElementSibling.focus() + } else { + this.availableOptions[this.availableOptions.length - 1].focus() } } if (e.code === 'ArrowDown' || e.code === 'ArrowLeft') { e.preventDefault() - if (document.activeElement.nextElementSibling) + if (document.activeElement.nextElementSibling) { document.activeElement.nextElementSibling.focus() + } else{ + this.availableOptions[0].focus() + } } }) this.addEventListener('optionSelected', e => { diff --git a/components/dist/select.min.js b/components/dist/select.min.js index 985181b..f93b92e 100644 --- a/components/dist/select.min.js +++ b/components/dist/select.min.js @@ -1 +1 @@ -const smSelect=document.createElement("template");smSelect.innerHTML='\n\n
\n
\n
\n \n \n \n
\n
\n \n
\n
',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()),"ArrowDown"!==e.code&&"ArrowLeft"!==e.code||(e.preventDefault(),document.activeElement.nextElementSibling&&document.activeElement.nextElementSibling.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\n
\n \n \n \n \n
',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)}}); \ No newline at end of file +const smSelect=document.createElement("template");smSelect.innerHTML='\n\n
\n
\n
\n \n \n \n
\n
\n \n
\n
',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\n
\n \n \n \n \n
',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)}}); \ No newline at end of file diff --git a/components/dist/strip-select.js b/components/dist/strip-select.js index 71abbe3..41d7b9b 100644 --- a/components/dist/strip-select.js +++ b/components/dist/strip-select.js @@ -23,10 +23,18 @@ stripSelect.innerHTML = ` padding: 1rem 0; } .strip-select{ + position: relative; + } + :host([multiline]) .strip-select{ + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + overflow: auto hidden; + } + :host(:not([multiline])) .strip-select{ display: grid; grid-auto-flow: column; gap: var(--gap); - position: relative; max-width: 100%; align-items: center; overflow: auto hidden; @@ -69,13 +77,6 @@ stripSelect.innerHTML = ` fill: rgba(var(--text-color), .8); } @media (hover: none){ - ::-webkit-scrollbar-track { - background-color: transparent !important; - } - ::-webkit-scrollbar { - height: 0; - background-color: transparent; - } .nav-button{ display: none; } @@ -87,6 +88,13 @@ stripSelect.innerHTML = ` } } @media (hover: hover){ + ::-webkit-scrollbar-track { + background-color: transparent !important; + } + ::-webkit-scrollbar { + height: 0; + background-color: transparent; + } .strip-select{ overflow: hidden; } @@ -163,17 +171,19 @@ customElements.define('strip-select', class extends HTMLElement{ this._value = elem.value } }) - if (assignedElements.length > 0) { - firstOptionObserver.observe(slot.assignedElements()[0]) - lastOptionObserver.observe(slot.assignedElements()[slot.assignedElements().length - 1]) - } - else { - navButtonLeft.classList.add('hide') - navButtonRight.classList.add('hide') - coverLeft.classList.add('hide') - coverRight.classList.add('hide') - firstOptionObserver.disconnect() - lastOptionObserver.disconnect() + if (!this.hasAttribute('multiline')) { + if (assignedElements.length > 0) { + firstOptionObserver.observe(slot.assignedElements()[0]) + lastOptionObserver.observe(slot.assignedElements()[slot.assignedElements().length - 1]) + } + else { + navButtonLeft.classList.add('hide') + navButtonRight.classList.add('hide') + coverLeft.classList.add('hide') + coverRight.classList.add('hide') + firstOptionObserver.disconnect() + lastOptionObserver.disconnect() + } } }) const resObs = new ResizeObserver(entries => { diff --git a/components/dist/strip-select.min.js b/components/dist/strip-select.min.js index 7e51c3e..8c8987a 100644 --- a/components/dist/strip-select.min.js +++ b/components/dist/strip-select.min.js @@ -1 +1 @@ -const stripSelect=document.createElement("template");stripSelect.innerHTML='\n\n
\n
\n \n
\n \n
\n \n
\n
\n\n',customElements.define("strip-select",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(stripSelect.content.cloneNode(!0)),this.stripSelect=this.shadowRoot.querySelector(".strip-select"),this.slottedOptions,this._value,this.scrollDistance,this.scrollLeft=this.scrollLeft.bind(this),this.scrollRight=this.scrollRight.bind(this),this.fireEvent=this.fireEvent.bind(this)}get value(){return this._value}scrollLeft(){this.stripSelect.scrollBy({left:-this.scrollDistance,behavior:"smooth"})}scrollRight(){this.stripSelect.scrollBy({left:this.scrollDistance,behavior:"smooth"})}fireEvent(){this.dispatchEvent(new CustomEvent("change",{bubbles:!0,composed:!0,detail:{value:this._value}}))}connectedCallback(){const t=this.shadowRoot.querySelector("slot"),e=this.shadowRoot.querySelector(".cover--left"),n=this.shadowRoot.querySelector(".cover--right"),i=this.shadowRoot.querySelector(".nav-button--left"),o=this.shadowRoot.querySelector(".nav-button--right");t.addEventListener("slotchange",s=>{const l=t.assignedElements();l.forEach(t=>{t.hasAttribute("selected")&&(t.setAttribute("active",""),this._value=t.value)}),l.length>0?(r.observe(t.assignedElements()[0]),a.observe(t.assignedElements()[t.assignedElements().length-1])):(i.classList.add("hide"),o.classList.add("hide"),e.classList.add("hide"),n.classList.add("hide"),r.disconnect(),a.disconnect())});const s=new ResizeObserver(t=>{t.forEach(t=>{if(t.contentBoxSize){const e=Array.isArray(t.contentBoxSize)?t.contentBoxSize[0]:t.contentBoxSize;this.scrollDistance=.6*e.inlineSize}else this.scrollDistance=.6*t.contentRect.width})});s.observe(this),this.stripSelect.addEventListener("option-clicked",e=>{this._value!==e.target.value&&(this._value=e.target.value,t.assignedElements().forEach(t=>t.removeAttribute("active")),e.target.setAttribute("active",""),e.target.scrollIntoView({behavior:"smooth",block:"nearest",inline:"center"}),this.fireEvent())});const r=new IntersectionObserver(t=>{t.forEach(t=>{t.isIntersecting?(i.classList.add("hide"),e.classList.add("hide")):(i.classList.remove("hide"),e.classList.remove("hide"))})},{threshold:.9,root:this}),a=new IntersectionObserver(t=>{t.forEach(t=>{t.isIntersecting?(o.classList.add("hide"),n.classList.add("hide")):(o.classList.remove("hide"),n.classList.remove("hide"))})},{threshold:.9,root:this});i.addEventListener("click",this.scrollLeft),o.addEventListener("click",this.scrollRight)}disconnectedCallback(){navButtonLeft.removeEventListener("click",this.scrollLeft),navButtonRight.removeEventListener("click",this.scrollRight)}});const stripOption=document.createElement("template");stripOption.innerHTML='\n\n\n',customElements.define("strip-option",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(stripOption.content.cloneNode(!0)),this._value,this.radioButton=this.shadowRoot.querySelector("input"),this.fireEvent=this.fireEvent.bind(this),this.handleKeyDown=this.handleKeyDown.bind(this)}get value(){return this._value}fireEvent(){this.dispatchEvent(new CustomEvent("option-clicked",{bubbles:!0,composed:!0,detail:{value:this._value}}))}handleKeyDown(t){"Enter"!==t.key&&"Space"!==t.key||this.fireEvent()}connectedCallback(){this._value=this.getAttribute("value"),this.addEventListener("click",this.fireEvent),this.addEventListener("keydown",this.handleKeyDown)}disconnectedCallback(){this.removeEventListener("click",this.fireEvent),this.removeEventListener("keydown",this.handleKeyDown)}}); \ No newline at end of file +const stripSelect=document.createElement("template");stripSelect.innerHTML='\n\n
\n
\n \n
\n \n
\n \n
\n
\n\n',customElements.define("strip-select",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(stripSelect.content.cloneNode(!0)),this.stripSelect=this.shadowRoot.querySelector(".strip-select"),this.slottedOptions,this._value,this.scrollDistance,this.scrollLeft=this.scrollLeft.bind(this),this.scrollRight=this.scrollRight.bind(this),this.fireEvent=this.fireEvent.bind(this)}get value(){return this._value}scrollLeft(){this.stripSelect.scrollBy({left:-this.scrollDistance,behavior:"smooth"})}scrollRight(){this.stripSelect.scrollBy({left:this.scrollDistance,behavior:"smooth"})}fireEvent(){this.dispatchEvent(new CustomEvent("change",{bubbles:!0,composed:!0,detail:{value:this._value}}))}connectedCallback(){const t=this.shadowRoot.querySelector("slot"),e=this.shadowRoot.querySelector(".cover--left"),n=this.shadowRoot.querySelector(".cover--right"),i=this.shadowRoot.querySelector(".nav-button--left"),o=this.shadowRoot.querySelector(".nav-button--right");t.addEventListener("slotchange",s=>{const l=t.assignedElements();l.forEach(t=>{t.hasAttribute("selected")&&(t.setAttribute("active",""),this._value=t.value)}),this.hasAttribute("multiline")||(l.length>0?(r.observe(t.assignedElements()[0]),a.observe(t.assignedElements()[t.assignedElements().length-1])):(i.classList.add("hide"),o.classList.add("hide"),e.classList.add("hide"),n.classList.add("hide"),r.disconnect(),a.disconnect()))});const s=new ResizeObserver(t=>{t.forEach(t=>{if(t.contentBoxSize){const e=Array.isArray(t.contentBoxSize)?t.contentBoxSize[0]:t.contentBoxSize;this.scrollDistance=.6*e.inlineSize}else this.scrollDistance=.6*t.contentRect.width})});s.observe(this),this.stripSelect.addEventListener("option-clicked",e=>{this._value!==e.target.value&&(this._value=e.target.value,t.assignedElements().forEach(t=>t.removeAttribute("active")),e.target.setAttribute("active",""),e.target.scrollIntoView({behavior:"smooth",block:"nearest",inline:"center"}),this.fireEvent())});const r=new IntersectionObserver(t=>{t.forEach(t=>{t.isIntersecting?(i.classList.add("hide"),e.classList.add("hide")):(i.classList.remove("hide"),e.classList.remove("hide"))})},{threshold:.9,root:this}),a=new IntersectionObserver(t=>{t.forEach(t=>{t.isIntersecting?(o.classList.add("hide"),n.classList.add("hide")):(o.classList.remove("hide"),n.classList.remove("hide"))})},{threshold:.9,root:this});i.addEventListener("click",this.scrollLeft),o.addEventListener("click",this.scrollRight)}disconnectedCallback(){navButtonLeft.removeEventListener("click",this.scrollLeft),navButtonRight.removeEventListener("click",this.scrollRight)}});const stripOption=document.createElement("template");stripOption.innerHTML='\n\n\n',customElements.define("strip-option",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(stripOption.content.cloneNode(!0)),this._value,this.radioButton=this.shadowRoot.querySelector("input"),this.fireEvent=this.fireEvent.bind(this),this.handleKeyDown=this.handleKeyDown.bind(this)}get value(){return this._value}fireEvent(){this.dispatchEvent(new CustomEvent("option-clicked",{bubbles:!0,composed:!0,detail:{value:this._value}}))}handleKeyDown(t){"Enter"!==t.key&&"Space"!==t.key||this.fireEvent()}connectedCallback(){this._value=this.getAttribute("value"),this.addEventListener("click",this.fireEvent),this.addEventListener("keydown",this.handleKeyDown)}disconnectedCallback(){this.removeEventListener("click",this.fireEvent),this.removeEventListener("keydown",this.handleKeyDown)}}); \ No newline at end of file diff --git a/components/dist/tags-input.js b/components/dist/tags-input.js index d8f6b88..f2dd08b 100644 --- a/components/dist/tags-input.js +++ b/components/dist/tags-input.js @@ -87,7 +87,7 @@ customElements.define('tags-input', class extends HTMLElement { this.input = this.shadowRoot.querySelector('input') this.tagsWrapper = this.shadowRoot.querySelector('.tags-wrapper') this.placeholder = this.shadowRoot.querySelector('.placeholder') - this.observeList = ['placeholder', 'limit'] + this.reflectedAttributes = ['placeholder', 'limit'] this.limit = undefined this.tags = new Set() diff --git a/components/dist/tags-input.min.js b/components/dist/tags-input.min.js index 8b5b3b5..7ec6a5e 100644 --- a/components/dist/tags-input.min.js +++ b/components/dist/tags-input.min.js @@ -1 +1 @@ -const tagsInput=document.createElement("template");tagsInput.innerHTML='\n \n
\n \n

\n
\n',customElements.define("tags-input",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(tagsInput.content.cloneNode(!0)),this.input=this.shadowRoot.querySelector("input"),this.tagsWrapper=this.shadowRoot.querySelector(".tags-wrapper"),this.placeholder=this.shadowRoot.querySelector(".placeholder"),this.observeList=["placeholder","limit"],this.limit=void 0,this.tags=new Set,this.reset=this.reset.bind(this),this.handleInput=this.handleInput.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.handleClick=this.handleClick.bind(this),this.removeTag=this.removeTag.bind(this)}static get observedAttributes(){return["placeholder","limit"]}get value(){return[...this.tags].join()}reset(){for(this.input.value="",this.tags.clear();this.input.previousElementSibling;)this.input.previousElementSibling.remove()}handleInput(e){const t=e.target.value.trim().length;e.target.setAttribute("size",t||"3"),t?this.placeholder.classList.add("hide"):t||this.tags.size||this.placeholder.classList.remove("hide")}handleKeydown(e){if(","!==e.key&&"/"!==e.key||e.preventDefault(),""!==e.target.value.trim()){if("Enter"===e.key||","===e.key||"/"===e.key||"Space"===e.code){const t=e.target.value.trim();if(this.tags.has(t))this.tagsWrapper.querySelector(`[data-value="${t}"]`).animate([{backgroundColor:"initial"},{backgroundColor:"var(--accent-color)"},{backgroundColor:"initial"}],{duration:300,easing:"ease"});else{const e=document.createElement("span");e.dataset.value=t,e.className="tag",e.innerHTML=`\n ${t}\n \n `,this.input.before(e),this.tags.add(t)}if(e.target.value="",e.target.setAttribute("size","3"),this.limit&&this.limitthis.tags.size&&(this.input.readOnly=!1)}handleClick(e){e.target.closest(".tag")?this.removeTag(e.target.closest(".tag")):this.input.focus()}removeTag(e){this.tags.delete(e.dataset.value),e.remove(),this.tags.size||this.placeholder.classList.remove("hide")}connectedCallback(){this.input.addEventListener("input",this.handleInput),this.input.addEventListener("keydown",this.handleKeydown),this.tagsWrapper.addEventListener("click",this.handleClick)}attributeChangedCallback(e,t,n){"placeholder"===e&&(this.placeholder.textContent=n),"limit"===e&&(this.limit=parseInt(n))}disconnectedCallback(){this.input.removeEventListener("input",this.handleInput),this.input.removeEventListener("keydown",this.handleKeydown),this.tagsWrapper.removeEventListener("click",this.handleClick)}}); \ No newline at end of file +const tagsInput=document.createElement("template");tagsInput.innerHTML='\n \n
\n \n

\n
\n',customElements.define("tags-input",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(tagsInput.content.cloneNode(!0)),this.input=this.shadowRoot.querySelector("input"),this.tagsWrapper=this.shadowRoot.querySelector(".tags-wrapper"),this.placeholder=this.shadowRoot.querySelector(".placeholder"),this.reflectedAttributes=["placeholder","limit"],this.limit=void 0,this.tags=new Set,this.reset=this.reset.bind(this),this.handleInput=this.handleInput.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.handleClick=this.handleClick.bind(this),this.removeTag=this.removeTag.bind(this)}static get observedAttributes(){return["placeholder","limit"]}get value(){return[...this.tags].join()}reset(){for(this.input.value="",this.tags.clear();this.input.previousElementSibling;)this.input.previousElementSibling.remove()}handleInput(e){const t=e.target.value.trim().length;e.target.setAttribute("size",t||"3"),t?this.placeholder.classList.add("hide"):t||this.tags.size||this.placeholder.classList.remove("hide")}handleKeydown(e){if(","!==e.key&&"/"!==e.key||e.preventDefault(),""!==e.target.value.trim()){if("Enter"===e.key||","===e.key||"/"===e.key||"Space"===e.code){const t=e.target.value.trim();if(this.tags.has(t))this.tagsWrapper.querySelector(`[data-value="${t}"]`).animate([{backgroundColor:"initial"},{backgroundColor:"var(--accent-color)"},{backgroundColor:"initial"}],{duration:300,easing:"ease"});else{const e=document.createElement("span");e.dataset.value=t,e.className="tag",e.innerHTML=`\n ${t}\n \n `,this.input.before(e),this.tags.add(t)}if(e.target.value="",e.target.setAttribute("size","3"),this.limit&&this.limitthis.tags.size&&(this.input.readOnly=!1)}handleClick(e){e.target.closest(".tag")?this.removeTag(e.target.closest(".tag")):this.input.focus()}removeTag(e){this.tags.delete(e.dataset.value),e.remove(),this.tags.size||this.placeholder.classList.remove("hide")}connectedCallback(){this.input.addEventListener("input",this.handleInput),this.input.addEventListener("keydown",this.handleKeydown),this.tagsWrapper.addEventListener("click",this.handleClick)}attributeChangedCallback(e,t,n){"placeholder"===e&&(this.placeholder.textContent=n),"limit"===e&&(this.limit=parseInt(n))}disconnectedCallback(){this.input.removeEventListener("input",this.handleInput),this.input.removeEventListener("keydown",this.handleKeydown),this.tagsWrapper.removeEventListener("click",this.handleClick)}}); \ No newline at end of file diff --git a/components/dist/textarea.js b/components/dist/textarea.js index 123d7b9..39b3726 100644 --- a/components/dist/textarea.js +++ b/components/dist/textarea.js @@ -118,7 +118,7 @@ customElements.define('sm-textarea', this.textarea = this.shadowRoot.querySelector('textarea') this.textareaBox = this.shadowRoot.querySelector('.textarea') this.placeholder = this.shadowRoot.querySelector('.placeholder') - this.observeList = ['required', 'readonly', 'rows', 'minlength', 'maxlength'] + this.reflectedAttributes = ['required', 'readonly', 'rows', 'minlength', 'maxlength'] this.reset = this.reset.bind(this) this.focusIn = this.focusIn.bind(this) @@ -168,7 +168,7 @@ customElements.define('sm-textarea', }) } attributeChangedCallback(name, oldValue, newValue) { - if (this.observeList.includes(name)) { + if (this.reflectedAttributes.includes(name)) { if (this.hasAttribute(name)) { this.textarea.setAttribute(name, this.getAttribute(name) ? this.getAttribute(name) : '') } diff --git a/components/dist/textarea.min.js b/components/dist/textarea.min.js index fdc92b7..d81e924 100644 --- a/components/dist/textarea.min.js +++ b/components/dist/textarea.min.js @@ -1 +1 @@ -const smTextarea=document.createElement("template");smTextarea.innerHTML='\n\n\n',customElements.define("sm-textarea",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smTextarea.content.cloneNode(!0)),this.textarea=this.shadowRoot.querySelector("textarea"),this.textareaBox=this.shadowRoot.querySelector(".textarea"),this.placeholder=this.shadowRoot.querySelector(".placeholder"),this.observeList=["required","readonly","rows","minlength","maxlength"],this.reset=this.reset.bind(this),this.focusIn=this.focusIn.bind(this),this.fireEvent=this.fireEvent.bind(this),this.checkInput=this.checkInput.bind(this)}static get observedAttributes(){return["value","placeholder","required","readonly","rows","minlength","maxlength"]}get value(){return this.textarea.value}set value(e){this.setAttribute("value",e),this.fireEvent()}get isValid(){return this.textarea.checkValidity()}reset(){this.setAttribute("value","")}focusIn(){this.textarea.focus()}fireEvent(){let e=new Event("input",{bubbles:!0,cancelable:!0,composed:!0});this.dispatchEvent(e)}checkInput(){this.hasAttribute("placeholder")&&""!==this.getAttribute("placeholder")&&(""!==this.textarea.value?this.placeholder.classList.add("hide"):this.placeholder.classList.remove("hide"))}connectedCallback(){this.textarea.addEventListener("input",e=>{this.textareaBox.dataset.value=this.textarea.value,this.checkInput()})}attributeChangedCallback(e,t,n){this.observeList.includes(e)?this.hasAttribute(e)?this.textarea.setAttribute(e,this.getAttribute(e)?this.getAttribute(e):""):this.input.removeAttribute(e):"placeholder"===e?this.placeholder.textContent=this.getAttribute("placeholder"):"value"===e&&(this.textarea.value=n,this.textareaBox.dataset.value=n,this.checkInput())}}); \ No newline at end of file +const smTextarea=document.createElement("template");smTextarea.innerHTML='\n\n\n',customElements.define("sm-textarea",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smTextarea.content.cloneNode(!0)),this.textarea=this.shadowRoot.querySelector("textarea"),this.textareaBox=this.shadowRoot.querySelector(".textarea"),this.placeholder=this.shadowRoot.querySelector(".placeholder"),this.reflectedAttributes=["required","readonly","rows","minlength","maxlength"],this.reset=this.reset.bind(this),this.focusIn=this.focusIn.bind(this),this.fireEvent=this.fireEvent.bind(this),this.checkInput=this.checkInput.bind(this)}static get observedAttributes(){return["value","placeholder","required","readonly","rows","minlength","maxlength"]}get value(){return this.textarea.value}set value(e){this.setAttribute("value",e),this.fireEvent()}get isValid(){return this.textarea.checkValidity()}reset(){this.setAttribute("value","")}focusIn(){this.textarea.focus()}fireEvent(){let e=new Event("input",{bubbles:!0,cancelable:!0,composed:!0});this.dispatchEvent(e)}checkInput(){this.hasAttribute("placeholder")&&""!==this.getAttribute("placeholder")&&(""!==this.textarea.value?this.placeholder.classList.add("hide"):this.placeholder.classList.remove("hide"))}connectedCallback(){this.textarea.addEventListener("input",e=>{this.textareaBox.dataset.value=this.textarea.value,this.checkInput()})}attributeChangedCallback(e,t,n){this.reflectedAttributes.includes(e)?this.hasAttribute(e)?this.textarea.setAttribute(e,this.getAttribute(e)?this.getAttribute(e):""):this.input.removeAttribute(e):"placeholder"===e?this.placeholder.textContent=this.getAttribute("placeholder"):"value"===e&&(this.textarea.value=n,this.textareaBox.dataset.value=n,this.checkInput())}}); \ No newline at end of file diff --git a/components/index.html b/components/index.html index 27a568b..3d3c96d 100644 --- a/components/index.html +++ b/components/index.html @@ -104,7 +104,7 @@

To start using SM Components, Select components you want to download.

-
+
Get minified @@ -201,7 +201,8 @@ To start using SM Components

- + + Submit

@@ -211,7 +212,7 @@

To start using SM Components

-

@@ -237,9 +238,9 @@

Example

+ onclick="notify('Lorem ipsum dolor, consectetur adipisicing elit.', 'success')"> push success notification - + push error notification @@ -273,10 +274,17 @@ Popups are used to show addition UI elements that you may want to hide at first and reveal them when needed.

- - - - +
+ +
  On
+
+ +
  Off
+
+ +
  ðŸ¤·
+
+
@@ -307,7 +315,7 @@

To start using SM Components

- + Movie TV series Video @@ -418,9 +426,12 @@ } } - function create(tagName, obj) { - const { className, textContent, innerHTML } = obj + function createElement(tagName, obj) { + const { className, textContent, innerHTML, attributes = {}} = obj const elem = document.createElement(tagName) + for(let attribute in attributes){ + elem.setAttribute(attribute, attributes[attribute]) + } if (className) elem.className = className elem.textContent = textContent @@ -595,7 +606,16 @@ function notify(message, mode, options = {}) { const {pinned = false, sound} = options if (mode === "error") console.error(message); - getRef("notification_drawer").push(message, {pinned}); + let icon + switch(mode){ + case 'success': + icon = `` + break; + case 'error': + icon = `` + break; + } + getRef("notification_drawer").push(message, {pinned, icon}); if (navigator.onLine && sound) { getRef("notification_sound").currentTime = 0; getRef("notification_sound").play(); @@ -633,23 +653,8 @@ } } - const inputValidation = debounce((e) => { - if (e.target.closest('sm-input')) { - const input = e.target.closest('sm-input') - if (input.value === '') - input.setValidity('') - if (input.hasAttribute('data-flo-id')) { - if (validateAddr(input.value.trim()) || input.value.trim() === '') - input.setValidity('') - else - input.setValidity('Invalid FLO address.') - } - } - }, 100) - window.addEventListener("load", () => { // document.querySelectorAll('sm-input[data-flo-id]').forEach(input => input.customValidation = validateAddr) - document.addEventListener('input', inputValidation) document.addEventListener('keyup', (e) => { if (e.code === 'Escape') { hidePopup() @@ -930,12 +935,15 @@ } function downloadJs(componentsArray, options = {minified: true}){ const {minified} = options - const element = document.createElement('a'); - element.setAttribute('href', 'data:application/javascript;charset=utf-8,' + encodeURIComponent(componentsArray.join("\n"))); const extension = minified ? '.min.js': '.js' - element.setAttribute('download', `components${extension}`); + const element = createElement('a', { + attributes: { + 'href': 'data:application/javascript;charset=utf-8,' + encodeURIComponent(componentsArray.join("\n")), + 'download': `components${extension}`, + 'style': 'display:none' + } + }); - element.style.display = 'none'; document.body.appendChild(element); element.click();