components update
This commit is contained in:
parent
5c3d8359dd
commit
e858394b03
@ -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 {
|
||||
|
||||
2
components/css/main.min.css
vendored
2
components/css/main.min.css
vendored
File diff suppressed because one or more lines are too long
@ -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;
|
||||
|
||||
8
components/dist/button.js
vendored
8
components/dist/button.js
vendored
@ -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;
|
||||
|
||||
2
components/dist/button.min.js
vendored
2
components/dist/button.min.js
vendored
@ -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()})}});
|
||||
11
components/dist/checkbox.js
vendored
11
components/dist/checkbox.js
vendored
@ -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;
|
||||
|
||||
2
components/dist/checkbox.min.js
vendored
2
components/dist/checkbox.min.js
vendored
@ -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)}});
|
||||
10
components/dist/file-input.js
vendored
10
components/dist/file-input.js
vendored
@ -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) : '')
|
||||
}
|
||||
|
||||
2
components/dist/file-input.min.js
vendored
2
components/dist/file-input.min.js
vendored
@ -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)}});
|
||||
22
components/dist/form.js
vendored
22
components/dist/form.js
vendored
@ -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)
|
||||
}
|
||||
})
|
||||
|
||||
112
components/dist/input.js
vendored
112
components/dist/input.js
vendored
@ -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')
|
||||
|
||||
2
components/dist/input.min.js
vendored
2
components/dist/input.min.js
vendored
File diff suppressed because one or more lines are too long
16
components/dist/menu.js
vendored
16
components/dist/menu.js
vendored
@ -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()
|
||||
|
||||
2
components/dist/menu.min.js
vendored
2
components/dist/menu.min.js
vendored
File diff suppressed because one or more lines are too long
55
components/dist/notifications.js
vendored
55
components/dist/notifications.js
vendored
@ -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, {
|
||||
|
||||
2
components/dist/notifications.min.js
vendored
2
components/dist/notifications.min.js
vendored
File diff suppressed because one or more lines are too long
7
components/dist/select.js
vendored
7
components/dist/select.js
vendored
@ -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 => {
|
||||
|
||||
2
components/dist/select.min.js
vendored
2
components/dist/select.min.js
vendored
File diff suppressed because one or more lines are too long
48
components/dist/strip-select.js
vendored
48
components/dist/strip-select.js
vendored
@ -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 => {
|
||||
|
||||
2
components/dist/strip-select.min.js
vendored
2
components/dist/strip-select.min.js
vendored
File diff suppressed because one or more lines are too long
2
components/dist/tags-input.js
vendored
2
components/dist/tags-input.js
vendored
@ -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()
|
||||
|
||||
|
||||
2
components/dist/tags-input.min.js
vendored
2
components/dist/tags-input.min.js
vendored
@ -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)}});
|
||||
4
components/dist/textarea.js
vendored
4
components/dist/textarea.js
vendored
@ -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) : '')
|
||||
}
|
||||
|
||||
2
components/dist/textarea.min.js
vendored
2
components/dist/textarea.min.js
vendored
@ -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())}});
|
||||
@ -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"> On</div>
|
||||
</sm-radio>
|
||||
<sm-radio name="abc" value="off">
|
||||
<div class="flex"> Off</div>
|
||||
</sm-radio>
|
||||
<sm-radio name="abc" value="🤷">
|
||||
<div class="flex"> 🤷</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();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user