components update

This commit is contained in:
sairaj mote 2021-07-11 18:06:45 +05:30
parent 5c3d8359dd
commit e858394b03
25 changed files with 239 additions and 166 deletions

View File

@ -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 {

File diff suppressed because one or more lines are too long

View File

@ -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;

View File

@ -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;

View File

@ -1 +1 @@
const smButton=document.createElement("template");smButton.innerHTML="\n<style> \n*{\n padding: 0;\n margin: 0;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n} \n:host{\n display: -webkit-inline-box;\n display: -ms-inline-flexbox;\n display: inline-flex;\n --padding: 0.6rem 1.2rem;\n --border-radius: 0.3rem;\n --background: rgba(var(--text-color), 0.1);\n}\n:host([disabled]) .button{\n cursor: not-allowed;\n opacity: 0.6;\n background: rgba(var(--text-color), 0.3) !important;\n color: rgba(var(--foreground-color), 0.6);\n}\n:host([disabled][variant=\"primary\"]) .button{\n color: rgba(var(--text-color), 1);\n}\n:host([variant='primary']) .button{\n background: var(--accent-color);\n color: rgba(var(--foreground-color), 1);\n}\n:host([variant='outlined']) .button{\n -webkit-box-shadow: 0 0 0 1px rgba(var(--text-color), 0.2) inset;\n box-shadow: 0 0 0 1px rgba(var(--text-color), 0.2) inset;\n background: transparent; \n color: var(--accent-color);\n}\n:host([variant='no-outline']) .button{\n background: rgba(var(--foreground-color), 1); \n color: var(--accent-color);\n}\n:host(.small) .button{\n padding: 0.4rem 0.8rem;\n}\n:host(.round) .button{\n border-radius: 10rem;\n}\n.button {\n position: relative;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n width: 100%;\n padding: var(--padding);\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n border-radius: var(--border-radius); \n -webkit-box-pack: center; \n -ms-flex-pack: center; \n justify-content: center;\n -webkit-transition: -webkit-box-shadow 0.3s;\n transition: -webkit-box-shadow 0.3s;\n -o-transition: box-shadow 0.3s;\n transition: box-shadow 0.3s;\n transition: box-shadow 0.3s, -webkit-box-shadow 0.3s;\n font-family: inherit;\n font-size: 0.9rem;\n font-weight: 500;\n background: var(--background); \n -webkit-tap-highlight-color: transparent;\n outline: none;\n overflow: hidden;\n border: none;\n color: inherit;\n align-items: center;\n}\n:host(:not([disabled])) .button:focus-visible{\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:host([variant='outlined']) .button:focus-visible{\n -webkit-box-shadow: 0 0 0 1px rgba(var(--text-color), 0.2) inset, 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0 0 0.1rem var(--accent-color);\n box-shadow: 0 0 0 1px rgba(var(--text-color), 0.2) inset, 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0 0 0.1rem var(--accent-color);\n}\n@media (hover: hover){\n :host(:not([disabled])) .button:hover{\n -webkit-box-shadow: 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.2rem 0.8rem rgba(0, 0, 0, 0.12);\n box-shadow: 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.2rem 0.8rem rgba(0, 0, 0, 0.12);\n }\n :host([variant='outlined']) .button:hover{\n -webkit-box-shadow: 0 0 0 1px rgba(var(--text-color), 0.2) inset, 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.4rem 0.8rem rgba(0, 0, 0, 0.12);\n box-shadow: 0 0 0 1px rgba(var(--text-color), 0.2) inset, 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.4rem 0.8rem rgba(0, 0, 0, 0.12);\n }\n}\n@media (hover: none){\n :host(:not([disabled])) .button:active{\n -webkit-box-shadow: 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.2rem 0.8rem rgba(0, 0, 0, 0.2);\n box-shadow: 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.2rem 0.8rem rgba(0, 0, 0, 0.2);\n }\n :host([variant='outlined']) .button:active{\n -webkit-box-shadow: 0 0 0 1px rgba(var(--text-color), 0.2) inset, 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.4rem 0.8rem rgba(0, 0, 0, 0.2);\n box-shadow: 0 0 0 1px rgba(var(--text-color), 0.2) inset, 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.4rem 0.8rem rgba(0, 0, 0, 0.2);\n }\n}\n</style>\n<button part=\"button\" class=\"button\">\n <slot></slot> \n</button>",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()})}});
const smButton=document.createElement("template");smButton.innerHTML="\n<style> \n*{\n padding: 0;\n margin: 0;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n} \n:host{\n display: -webkit-inline-box;\n display: -ms-inline-flexbox;\n display: inline-flex;\n --padding: 0.6rem 1.2rem;\n --border-radius: 0.3rem;\n --background: rgba(var(--text-color), 0.1);\n}\n:host([disabled]) .button{\n cursor: not-allowed;\n opacity: 0.6;\n background: rgba(var(--text-color), 0.3) !important;\n color: rgba(var(--foreground-color), 0.6);\n}\n:host([disabled][variant=\"primary\"]) .button{\n color: rgba(var(--text-color), 1);\n}\n:host([variant='primary']) .button{\n background: var(--accent-color);\n color: rgba(var(--foreground-color), 1);\n}\n:host([variant='outlined']) .button{\n -webkit-box-shadow: 0 0 0 1px rgba(var(--text-color), 0.2) inset;\n box-shadow: 0 0 0 1px rgba(var(--text-color), 0.2) inset;\n background: transparent; \n color: var(--accent-color);\n}\n:host([variant='no-outline']) .button{\n background: rgba(var(--foreground-color), 1); \n color: var(--accent-color);\n}\n:host(.small) .button{\n padding: 0.4rem 0.8rem;\n}\n:host(.round) .button{\n border-radius: 10rem;\n}\n.button {\n position: relative;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n width: 100%;\n padding: var(--padding);\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n border-radius: var(--border-radius); \n -webkit-box-pack: center; \n -ms-flex-pack: center; \n justify-content: center;\n transition: box-shadow 0.3s, background-color 0.3s;\n font-family: inherit;\n font-size: 0.9rem;\n font-weight: 500;\n background-color: var(--background); \n -webkit-tap-highlight-color: transparent;\n outline: none;\n overflow: hidden;\n border: none;\n color: inherit;\n align-items: center;\n}\n:host(:not([disabled])) .button:focus-visible{\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:host([variant='outlined']) .button:focus-visible{\n -webkit-box-shadow: 0 0 0 1px rgba(var(--text-color), 0.2) inset, 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0 0 0.1rem var(--accent-color);\n box-shadow: 0 0 0 1px rgba(var(--text-color), 0.2) inset, 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0 0 0.1rem var(--accent-color);\n}\n@media (hover: hover){\n :host(:not([disabled])) .button:hover{\n -webkit-box-shadow: 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.2rem 0.8rem rgba(0, 0, 0, 0.12);\n box-shadow: 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.2rem 0.8rem rgba(0, 0, 0, 0.12);\n }\n :host([variant='outlined']) .button:hover{\n -webkit-box-shadow: 0 0 0 1px rgba(var(--text-color), 0.2) inset, 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.4rem 0.8rem rgba(0, 0, 0, 0.12);\n box-shadow: 0 0 0 1px rgba(var(--text-color), 0.2) inset, 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.4rem 0.8rem rgba(0, 0, 0, 0.12);\n }\n}\n@media (hover: none){\n :host(:not([disabled])) .button:active{\n -webkit-box-shadow: 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.2rem 0.8rem rgba(0, 0, 0, 0.2);\n box-shadow: 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.2rem 0.8rem rgba(0, 0, 0, 0.2);\n }\n :host([variant='outlined']) .button:active{\n -webkit-box-shadow: 0 0 0 1px rgba(var(--text-color), 0.2) inset, 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.4rem 0.8rem rgba(0, 0, 0, 0.2);\n box-shadow: 0 0 0 1px rgba(var(--text-color), 0.2) inset, 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.4rem 0.8rem rgba(0, 0, 0, 0.2);\n }\n}\n</style>\n<button part=\"button\" class=\"button\">\n <slot></slot> \n</button>",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()})}});

View File

@ -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;

View File

@ -1 +1 @@
const smCheckbox=document.createElement("template");smCheckbox.innerHTML='\n<style>\n *{\n padding: 0;\n margin: 0;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n } \n :host{\n display: -webkit-inline-box;\n display: -ms-inline-flexbox;\n display: inline-flex;\n --height: 1.4rem;\n --width: 1.4rem;\n --border-radius: 0.2rem;\n --border-color: rgba(var(--text-color), 0.7);\n }\n :host([disabled]) {\n opacity: 0.6;\n user-select: none;\n pointer-events: none;\n }\n .checkbox {\n position: relative;\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 cursor: pointer;\n height: 1.5rem;\n outline: none;\n -webkit-tap-highlight-color: transparent;\n }\n \n .checkbox:focus-visible{\n outline: auto;\n }\n .checkbox:active .icon,\n .checkbox:focus-within .icon{\n box-shadow: 0 0 0 0.2rem var(--accent-color) inset;\n }\n \n input {\n display: none;\n }\n \n .checkmark {\n stroke-dashoffset: -65;\n stroke-dasharray: 65;\n -webkit-transition: stroke-dashoffset 0.3s; \n -o-transition: stroke-dashoffset 0.3s; \n transition: stroke-dashoffset 0.3s;\n }\n \n :host([checked]) .checkmark {\n stroke-dashoffset: 0;\n stroke: rgba(var(--foreground-color), 1);\n }\n :host([checked]) .icon {\n stroke-width: 8; \n stroke: var(--accent-color);\n background: var(--accent-color);\n }\n :host(:not([checked])) .icon {\n box-shadow: 0 0 0 0.2rem var(--border-color) inset;\n }\n \n .icon {\n fill: none;\n height: var(--height);\n width: var(--width);\n padding: 0.2rem;\n stroke: rgba(var(--text-color), 0.7);\n stroke-width: 6;\n overflow: visible;\n stroke-linecap: round;\n stroke-linejoin: round;\n -webkit-transition: background 0.3s;\n -o-transition: background 0.3s;\n transition: background 0.3s;\n border-radius: var(--border-radius);\n }\n</style>\n<label class="checkbox">\n <svg class="icon" viewBox="0 0 64 64">\n <title>checkbox</title>\n <path class="checkmark" d="M50.52,19.56,26,44.08,13.48,31.56" />\n </svg>\n <slot></slot>\n</label>',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)}});
const smCheckbox=document.createElement("template");smCheckbox.innerHTML='\n<style>\n *{\n padding: 0;\n margin: 0;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n } \n :host{\n display: -webkit-inline-box;\n display: -ms-inline-flexbox;\n display: inline-flex;\n --height: 1.2rem;\n --width: 1.2rem;\n --border-radius: 0.2rem;\n --border-color: rgba(var(--text-color), 0.7);\n }\n :host([disabled]) {\n opacity: 0.6;\n user-select: none;\n pointer-events: none;\n }\n .checkbox {\n position: relative;\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 cursor: pointer;\n outline: none;\n -webkit-tap-highlight-color: transparent;\n }\n \n .checkbox:focus-visible{\n outline: auto;\n }\n .checkbox:active .icon,\n .checkbox:focus-within .icon{\n box-shadow: 0 0 0 0.1rem var(--accent-color) inset;\n }\n \n input {\n display: none;\n }\n \n .checkmark {\n stroke-dashoffset: -65;\n stroke-dasharray: 65;\n -webkit-transition: stroke-dashoffset 0.3s; \n -o-transition: stroke-dashoffset 0.3s; \n transition: stroke-dashoffset 0.3s;\n }\n \n :host([checked]) .checkmark {\n stroke-dashoffset: 0;\n stroke: rgba(var(--foreground-color), 1);\n }\n :host([checked]) .icon {\n stroke-width: 8; \n stroke: var(--accent-color);\n background: var(--accent-color);\n }\n :host(:not([checked])) .icon {\n box-shadow: 0 0 0 0.1rem var(--border-color) inset;\n }\n \n .icon {\n fill: none;\n height: var(--height);\n width: var(--width);\n padding: 0.1rem;\n stroke: rgba(var(--text-color), 0.7);\n stroke-width: 6;\n overflow: visible;\n stroke-linecap: round;\n stroke-linejoin: round;\n -webkit-transition: background 0.3s;\n -o-transition: background 0.3s;\n transition: background 0.3s;\n border-radius: var(--border-radius);\n }\n</style>\n<label class="checkbox">\n <svg class="icon" viewBox="0 0 64 64">\n <title>checkbox</title>\n <path class="checkmark" d="M50.52,19.56,26,44.08,13.48,31.56" />\n </svg>\n <slot></slot>\n</label>',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)}});

View File

@ -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 = `
</style>
<ul class="files-preview-wrapper"></ul>
<label tabindex="0" class="file-input">
<div class="file-picker"><slot>Choose file</slot></div>
<div class="file-picker-button"><slot>Choose file</slot></div>
<input type="file">
</label>
`
@ -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) : '')
}

View File

@ -1 +1 @@
const fileInput=document.createElement("template");fileInput.innerHTML='\n \t<style>\n\t\t*{\n\t\t\tpadding: 0;\n\t\t\tmargin: 0;\n\t\t\tbox-sizing: border-box;\n\t\t}\n\t\t:host{\n\t\t\t--border-radius: 0.3rem;\n\t\t\t--button-color: inherit;\n\t\t\t--button-font-weight: 500;\n\t\t\t--button-background-color: var(--accent-color);\n\t\t}\n\t\t.file-input {\n\t\t\tdisplay: flex;\n\t\t}\n\t\t\n\t\t.file-picker {\n display: flex;\n\t\t\tcursor: pointer;\n\t\t\tuser-select: none;\n align-items: center;\n\t\t\tpadding: 0.5rem 0.8rem;\n\t\t\tcolor: var(--button-color);\n\t\t\tborder-radius: var(--border-radius);\n\t\t\tfont-weight: var(--button-font-weigh);\n\t\t\tbackground-color: var(--button-background-color);\n\t\t}\n\t\t.files-preview-wrapper{\n\t\t\tdisplay: grid;\n\t\t\tgap: 0.5rem;\n\t\t\tlist-style: none;\n\t\t}\n\t\t.files-preview-wrapper:not(:empty){\n margin-bottom: 1rem;\n\t\t}\n\t\t.file-preview{\n\t\t\tdisplay: grid;\n gap: 0.5rem;\n align-items: center;\n\t\t\tpadding: 0.5rem 0.8rem;\n\t\t\tborder-radius: var(--border-radius);\n\t\t\tbackground-color: rgba(var(--text-color), 0.06)\n\t\t}\n\t\t.file-name{\n\t\t}\n .file-size{\n font-size: 0.8rem;\n font-weight: 400;\n color: rgba(var(--text-color), 0.8);\n }\n\t\tinput[type=file] {\n\t\t\tdisplay: none;\n\t\t}\n \t</style>\n\t<ul class="files-preview-wrapper"></ul>\n \t<label tabindex="0" class="file-input">\n\t\t<div class="file-picker"><slot>Choose file</slot></div>\n\t\t<input type="file">\n\t</label>\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<div class="file-name">${n}</div>\n <h5 class="file-size">${this.formatBytes(i)}</h5>\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)}});
const fileInput=document.createElement("template");fileInput.innerHTML='\n \t<style>\n\t\t*{\n\t\t\tpadding: 0;\n\t\t\tmargin: 0;\n\t\t\tbox-sizing: border-box;\n\t\t}\n\t\t:host{\n\t\t\t--border-radius: 0.3rem;\n\t\t\t--button-color: var(--background-color);\n\t\t\t--button-font-weight: 500;\n\t\t\t--button-background-color: var(--accent-color);\n\t\t}\n\t\t.file-input {\n\t\t\tdisplay: flex;\n\t\t}\n\t\t\n\t\t.file-picker-button {\n display: flex;\n\t\t\tcursor: pointer;\n\t\t\tuser-select: none;\n align-items: center;\n\t\t\tpadding: 0.5rem 0.8rem;\n\t\t\tcolor: var(--button-color);\n\t\t\tborder-radius: var(--border-radius);\n\t\t\tfont-weight: var(--button-font-weigh);\n\t\t\tbackground-color: var(--button-background-color);\n\t\t}\n\t\t.files-preview-wrapper{\n\t\t\tdisplay: grid;\n\t\t\tgap: 0.5rem;\n\t\t\tlist-style: none;\n\t\t}\n\t\t.files-preview-wrapper:not(:empty){\n margin-bottom: 1rem;\n\t\t}\n\t\t.file-preview{\n\t\t\tdisplay: grid;\n gap: 0.5rem;\n align-items: center;\n\t\t\tpadding: 0.5rem 0.8rem;\n\t\t\tborder-radius: var(--border-radius);\n\t\t\tbackground-color: rgba(var(--text-color), 0.06)\n\t\t}\n\t\t.file-name{\n\t\t}\n .file-size{\n font-size: 0.8rem;\n font-weight: 400;\n color: rgba(var(--text-color), 0.8);\n }\n\t\tinput[type=file] {\n\t\t\tdisplay: none;\n\t\t}\n \t</style>\n\t<ul class="files-preview-wrapper"></ul>\n \t<label tabindex="0" class="file-input">\n\t\t<div class="file-picker-button"><slot>Choose file</slot></div>\n\t\t<input type="file">\n\t</label>\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<div class="file-name">${n}</div>\n <h5 class="file-size">${this.formatBytes(i)}</h5>\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)}});

View File

@ -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)
}
})

View File

@ -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{
<label part="input" class="input">
<slot name="icon"></slot>
<div class="container">
<input/>
<input type="text"/>
<div part="placeholder" class="label"></div>
</div>
<svg class="icon clear hide" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-11.414L9.172 7.757 7.757 9.172 10.586 12l-2.829 2.828 1.415 1.415L12 13.414l2.828 2.829 1.415-1.415L13.414 12l2.829-2.828-1.415-1.415L12 10.586z"/></svg>
</label>
<div class="feedback-text"></div>
<p class="feedback-text"></p>
</div>
`;
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 = `
<svg class="status-icon status-icon--error" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-7v2h2v-2h-2zm0-8v6h2V7h-2z"/></svg>
${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')

File diff suppressed because one or more lines are too long

View File

@ -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()

File diff suppressed because one or more lines are too long

View File

@ -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 += `
<p>${messageBody}</p>
<button class="close">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></svg>
</button>`
<div class="icon-container">${icon}</div>
<p>${message}</p>
`
if (pinned) {
notification.classList.add('pinned')
composition += `
<button class="close">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></svg>
</button>
`
}
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, {

File diff suppressed because one or more lines are too long

View File

@ -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 => {

File diff suppressed because one or more lines are too long

View File

@ -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 => {

File diff suppressed because one or more lines are too long

View File

@ -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()

View File

@ -1 +1 @@
const tagsInput=document.createElement("template");tagsInput.innerHTML='\n <style>\n *{\n padding: 0;\n margin: 0;\n box-sizing: border-box;\n }\n :host{\n --border-radius: 0.3rem;\n }\n.hide{\n display: none !important;\n}\n.tags-wrapper{\n position: relative;\n display: flex;\n cursor: text;\n flex-wrap: wrap;\n justify-items: flex-start;\n align-items: center;\n padding: 0.5rem 0.5rem 0 0.5rem;\n border-radius: var(--border-radius);\n background-color: rgba(var(--text-color), 0.06);\n }\n .tags-wrapper:focus-within{\n box-shadow: 0 0 0 0.1rem var(--accent-color) inset !important;\n }\n \n .tag {\n cursor: pointer;\n user-select: none;\n align-items: center;\n display: inline-flex;\n border-radius: 0.3rem;\n padding: 0.3rem 0.5rem;\n margin: 0 0.5rem 0.5rem 0;\n background-color: rgba(var(--text-color), 0.06);\n }\n \n .icon {\n height: 1.2rem;\n width: 1.2rem;\n margin-left: 0.3rem;\n fill: rgba(var(--text-color), 0.8);\n }\n \n input,\n input:focus {\n outline: none;\n border: none;\n }\n \n input {\n display: inline-flex;\n width: auto;\n color: inherit;\n max-width: inherit;\n font-size: inherit;\n font-family: inherit;\n padding: 0.4rem 0.5rem;\n margin: 0 0.5rem 0.5rem 0;\n background-color: transparent;\n }\n .placeholder{\n position: absolute;\n padding: 0 0.5rem;\n top: 50%;\n font-weight: 500;\n transform: translateY(-50%);\n color: rgba(var(--text-color), 0.6);\n }\n </style>\n <div class="tags-wrapper">\n <input type="text" size="3"/>\n <p class="placeholder"></p>\n </div>\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 <span class="tag-text">${t}</span>\n <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></svg>\n `,this.input.before(e),this.tags.add(t)}if(e.target.value="",e.target.setAttribute("size","3"),this.limit&&this.limit<this.tags.size+1)return void(this.input.readOnly=!0)}}else"Backspace"===e.key&&this.input.previousElementSibling&&this.removeTag(this.input.previousElementSibling),this.limit&&this.limit>this.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)}});
const tagsInput=document.createElement("template");tagsInput.innerHTML='\n <style>\n *{\n padding: 0;\n margin: 0;\n box-sizing: border-box;\n }\n :host{\n --border-radius: 0.3rem;\n }\n.hide{\n display: none !important;\n}\n.tags-wrapper{\n position: relative;\n display: flex;\n cursor: text;\n flex-wrap: wrap;\n justify-items: flex-start;\n align-items: center;\n padding: 0.5rem 0.5rem 0 0.5rem;\n border-radius: var(--border-radius);\n background-color: rgba(var(--text-color), 0.06);\n }\n .tags-wrapper:focus-within{\n box-shadow: 0 0 0 0.1rem var(--accent-color) inset !important;\n }\n \n .tag {\n cursor: pointer;\n user-select: none;\n align-items: center;\n display: inline-flex;\n border-radius: 0.3rem;\n padding: 0.3rem 0.5rem;\n margin: 0 0.5rem 0.5rem 0;\n background-color: rgba(var(--text-color), 0.06);\n }\n \n .icon {\n height: 1.2rem;\n width: 1.2rem;\n margin-left: 0.3rem;\n fill: rgba(var(--text-color), 0.8);\n }\n \n input,\n input:focus {\n outline: none;\n border: none;\n }\n \n input {\n display: inline-flex;\n width: auto;\n color: inherit;\n max-width: inherit;\n font-size: inherit;\n font-family: inherit;\n padding: 0.4rem 0.5rem;\n margin: 0 0.5rem 0.5rem 0;\n background-color: transparent;\n }\n .placeholder{\n position: absolute;\n padding: 0 0.5rem;\n top: 50%;\n font-weight: 500;\n transform: translateY(-50%);\n color: rgba(var(--text-color), 0.6);\n }\n </style>\n <div class="tags-wrapper">\n <input type="text" size="3"/>\n <p class="placeholder"></p>\n </div>\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 <span class="tag-text">${t}</span>\n <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></svg>\n `,this.input.before(e),this.tags.add(t)}if(e.target.value="",e.target.setAttribute("size","3"),this.limit&&this.limit<this.tags.size+1)return void(this.input.readOnly=!0)}}else"Backspace"===e.key&&this.input.previousElementSibling&&this.removeTag(this.input.previousElementSibling),this.limit&&this.limit>this.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)}});

View File

@ -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) : '')
}

View File

@ -1 +1 @@
const smTextarea=document.createElement("template");smTextarea.innerHTML='\n<style>\n*,\n*::before,\n*::after { \n padding: 0;\n margin: 0;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n} \n::-moz-focus-inner{\n border: none;\n}\n.hide{\n opacity: 0 !important;\n}\n:host{\n display: grid;\n --border-radius: 0.3rem;\n --background: rgba(var(--text-color), 0.06);\n --padding-right: initial;\n --padding-left: initial;\n --max-height: 8rem;\n}\n:host(.outlined) .textarea {\n box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 0.4) inset;\n background: rgba(var(--foreground-color), 1);\n}\n.textarea{\n display: grid;\n position: relative;\n cursor: text;\n min-width: 0;\n text-align: left;\n overflow: hidden auto;\n grid-template-columns: 1fr;\n align-items: stretch;\n max-height: var(--max-height);\n background: var(--background);\n border-radius: var(--border-radius);\n padding-left: var(--padding-left);\n padding-right: var(--padding-right);\n}\n.textarea::after,\ntextarea{\n padding: 0.7rem 1rem;\n width: 100%;\n min-width: 1em;\n font: inherit;\n color: inherit;\n resize: none;\n grid-area: 2/1;\n justify-self: stretch;\n background: none;\n appearance: none;\n border: none;\n outline: none;\n line-height: 1.5;\n overflow: hidden;\n}\n.textarea::after{\n content: attr(data-value) \' \';\n visibility: hidden;\n white-space: pre-wrap;\n overflow-wrap: break-word;\n word-wrap: break-word;\n hyphens: auto;\n}\n.readonly{\n pointer-events: none;\n}\n.textarea:focus-within:not(.readonly){\n box-shadow: 0 0 0 0.1rem var(--accent-color) inset;\n}\n.disabled{\n pointer-events: none;\n opacity: 0.6;\n}\n.placeholder{\n position: absolute;\n margin: 0.7rem 1rem;\n opacity: .7;\n font-weight: 400;\n font-size: 1rem;\n line-height: 1.5;\n pointer-events: none;\n user-select: none;\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<label class="textarea" part="textarea">\n <span class="placeholder"></span>\n <textarea rows="1"></textarea>\n</label>\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())}});
const smTextarea=document.createElement("template");smTextarea.innerHTML='\n<style>\n*,\n*::before,\n*::after { \n padding: 0;\n margin: 0;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n} \n::-moz-focus-inner{\n border: none;\n}\n.hide{\n opacity: 0 !important;\n}\n:host{\n display: grid;\n --border-radius: 0.3rem;\n --background: rgba(var(--text-color), 0.06);\n --padding-right: initial;\n --padding-left: initial;\n --max-height: 8rem;\n}\n:host(.outlined) .textarea {\n box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 0.4) inset;\n background: rgba(var(--foreground-color), 1);\n}\n.textarea{\n display: grid;\n position: relative;\n cursor: text;\n min-width: 0;\n text-align: left;\n overflow: hidden auto;\n grid-template-columns: 1fr;\n align-items: stretch;\n max-height: var(--max-height);\n background: var(--background);\n border-radius: var(--border-radius);\n padding-left: var(--padding-left);\n padding-right: var(--padding-right);\n}\n.textarea::after,\ntextarea{\n padding: 0.7rem 1rem;\n width: 100%;\n min-width: 1em;\n font: inherit;\n color: inherit;\n resize: none;\n grid-area: 2/1;\n justify-self: stretch;\n background: none;\n appearance: none;\n border: none;\n outline: none;\n line-height: 1.5;\n overflow: hidden;\n}\n.textarea::after{\n content: attr(data-value) \' \';\n visibility: hidden;\n white-space: pre-wrap;\n overflow-wrap: break-word;\n word-wrap: break-word;\n hyphens: auto;\n}\n.readonly{\n pointer-events: none;\n}\n.textarea:focus-within:not(.readonly){\n box-shadow: 0 0 0 0.1rem var(--accent-color) inset;\n}\n.disabled{\n pointer-events: none;\n opacity: 0.6;\n}\n.placeholder{\n position: absolute;\n margin: 0.7rem 1rem;\n opacity: .7;\n font-weight: 400;\n font-size: 1rem;\n line-height: 1.5;\n pointer-events: none;\n user-select: none;\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<label class="textarea" part="textarea">\n <span class="placeholder"></span>\n <textarea rows="1"></textarea>\n</label>\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())}});

View File

@ -104,7 +104,7 @@
<p class="description">
To start using SM Components, Select components you want to download.
</p>
<div class="grid grid-3 gap-0-5">
<div class="grid grid-3 gap-0-5 align-center">
<sm-checkbox id="get_minified" checked>
<span class="comp-checkbox__title">
Get minified
@ -201,7 +201,8 @@
To start using SM Components
</p>
<sm-form>
<sm-input placeholder="Enter name" required animate></sm-input>
<sm-input placeholder="Email" type="email" error-text="please enter correct email" required animate></sm-input>
<sm-input placeholder="Password" type="password" required animate></sm-input>
<sm-button variant="primary" disabled>Submit</sm-button>
</sm-form>
<p id="insert_text"></p>
@ -211,7 +212,7 @@
<p class="description">
To start using SM Components
</p>
<sm-input id="my_input" placeholder="something" type="email" helper-text="please enter correct email"
<sm-input placeholder="something" type="email" error-text="please enter correct email"
animate></sm-input>
<p id="insert_text"></p>
</section>
@ -237,9 +238,9 @@
<h4>Example</h4>
<sm-button
onclick="notify('Lorem ipsum dolor, consectetur adipisicing elit.')">
onclick="notify('Lorem ipsum dolor, consectetur adipisicing elit.', 'success')">
push success notification</sm-button>
<sm-button onclick="notify('Lorem ipsum dolor, sit amet.')">
<sm-button onclick="notify('Lorem ipsum dolor, sit amet.', 'error')">
push error notification</sm-button>
<sm-button
onclick="notify('Lorem ipsum dolor, sit amet consectetur adipisicing elit.', '', {pinned: true})">
@ -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.
</p>
<sm-radio name="abc" value="1" checked></sm-radio>
<sm-radio name="abc" value="2"></sm-radio>
<sm-radio name="abc" value="3"></sm-radio>
<sm-radio name="abc" value="4"></sm-radio>
<div class="grid gap-0-5">
<sm-radio name="abc" value="on" checked>
<div class="flex">&nbsp;&nbsp;On</div>
</sm-radio>
<sm-radio name="abc" value="off">
<div class="flex">&nbsp;&nbsp;Off</div>
</sm-radio>
<sm-radio name="abc" value="🤷">
<div class="flex">&nbsp;&nbsp;🤷</div>
</sm-radio>
</div>
</section>
<section id="switch_page" class="page hide-completely">
@ -307,7 +315,7 @@
<p class="description">
To start using SM Components
</p>
<strip-select id="browse_category_selector">
<strip-select id="browse_category_selector" multiline>
<strip-option value="movie" selected>Movie</strip-option>
<strip-option value="tv series">TV series</strip-option>
<strip-option value="video">Video</strip-option>
@ -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 = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 15.172l9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z"/></svg>`
break;
case 'error':
icon = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-7v2h2v-2h-2zm0-8v6h2V7h-2z"/></svg>`
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();