Code refactoring and bug fixes
This commit is contained in:
parent
b03fa10c7a
commit
d114979baa
@ -1,5 +1,5 @@
|
||||
// Global variables
|
||||
const appPages = ['dashboard', 'settings'];
|
||||
const appPages = ['dashboard', 'updates', 'settings'];
|
||||
const domRefs = {};
|
||||
let timerId;
|
||||
const currentYear = new Date().getFullYear();
|
||||
|
||||
7
components/dist/button.js
vendored
7
components/dist/button.js
vendored
@ -30,9 +30,13 @@ smButton.innerHTML = `
|
||||
color: var(--accent-color);
|
||||
}
|
||||
:host([variant='no-outline']) .button{
|
||||
background: rgba(var(--background-color), 1);
|
||||
background: inherit;
|
||||
color: var(--accent-color);
|
||||
}
|
||||
:host([disabled]){
|
||||
pointer-events: none;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.button {
|
||||
position: relative;
|
||||
display: -webkit-box;
|
||||
@ -62,6 +66,7 @@ smButton.innerHTML = `
|
||||
align-items: center;
|
||||
}
|
||||
:host([disabled]) .button{
|
||||
pointer-events: none;
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6;
|
||||
color: rgba(var(--text-color), 1);
|
||||
|
||||
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 width: auto;\n --accent-color: #4d2588;\n --text-color: 17, 17, 17;\n --background-color: 255, 255, 255;\n --padding: 0.6rem 1.2rem;\n --border-radius: 0.3rem;\n --background: rgba(var(--text-color), 0.1);\n}\n:host([variant='primary']) .button{\n background: var(--accent-color);\n color: rgba(var(--background-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(--background-color), 1); \n color: var(--accent-color);\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([disabled]) .button{\n cursor: not-allowed;\n opacity: 0.6;\n color: rgba(var(--text-color), 1);\n background-color: rgba(var(--text-color), 0.3);\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<div part=\"button\" class=\"button\">\n <slot></slot> \n</div>",customElements.define("sm-button",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smButton.content.cloneNode(!0))}static get observedAttributes(){return["disabled"]}get disabled(){return this.hasAttribute("disabled")}set disabled(e){e?this.setAttribute("disabled",""):this.removeAttribute("disabled")}handleKeyDown(e){this.hasAttribute("disabled")||"Enter"!==e.key&&"Space"!==e.code||(e.preventDefault(),this.click())}connectedCallback(){this.hasAttribute("disabled")||this.setAttribute("tabindex","0"),this.setAttribute("role","button"),this.addEventListener("keydown",this.handleKeyDown)}attributeChangedCallback(e,t,n){"disabled"===e?(this.removeAttribute("tabindex"),this.setAttribute("aria-disabled","true")):(this.setAttribute("tabindex","0"),this.setAttribute("aria-disabled","false"))}});
|
||||
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 width: auto;\n --accent-color: #4d2588;\n --text-color: 17, 17, 17;\n --background-color: 255, 255, 255;\n --padding: 0.6rem 1.2rem;\n --border-radius: 0.3rem;\n --background: rgba(var(--text-color), 0.1);\n}\n:host([variant='primary']) .button{\n background: var(--accent-color);\n color: rgba(var(--background-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: inherit; \n color: var(--accent-color);\n}\n:host([disabled]){\n pointer-events: none;\n cursor: not-allowed;\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([disabled]) .button{\n pointer-events: none;\n cursor: not-allowed;\n opacity: 0.6;\n color: rgba(var(--text-color), 1);\n background-color: rgba(var(--text-color), 0.3);\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<div part=\"button\" class=\"button\">\n <slot></slot> \n</div>",customElements.define("sm-button",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smButton.content.cloneNode(!0))}static get observedAttributes(){return["disabled"]}get disabled(){return this.hasAttribute("disabled")}set disabled(e){e?this.setAttribute("disabled",""):this.removeAttribute("disabled")}handleKeyDown(e){this.hasAttribute("disabled")||"Enter"!==e.key&&"Space"!==e.code||(e.preventDefault(),this.click())}connectedCallback(){this.hasAttribute("disabled")||this.setAttribute("tabindex","0"),this.setAttribute("role","button"),this.addEventListener("keydown",this.handleKeyDown)}attributeChangedCallback(e,n,t){"disabled"===e?(this.removeAttribute("tabindex"),this.setAttribute("aria-disabled","true")):(this.setAttribute("tabindex","0"),this.setAttribute("aria-disabled","false"))}});
|
||||
1
components/dist/checkbox.js
vendored
1
components/dist/checkbox.js
vendored
@ -84,7 +84,6 @@ smCheckbox.innerHTML = `
|
||||
</style>
|
||||
<label class="checkbox">
|
||||
<svg class="icon" viewBox="0 0 64 64">
|
||||
<title>checkbox</title>
|
||||
<path class="checkmark" d="M50.52,19.56,26,44.08,13.48,31.56" />
|
||||
</svg>
|
||||
<slot></slot>
|
||||
|
||||
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 --accent-color: #4d2588;\n --text-color: 17, 17, 17;\n --background-color: 255, 255, 255;\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(--background-color), 1);\n }\n :host([checked]) .icon {\n background: var(--accent-color);\n box-shadow: 0 0 0 0.1rem var(--accent-color) inset;\n } \n .icon {\n fill: none;\n height: var(--height);\n width: var(--width);\n padding: 0.1rem;\n stroke-width: 8; \n stroke: var(--border-color);\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 box-shadow: 0 0 0 0.1rem var(--border-color) inset;\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.handleKeyDown=this.handleKeyDown.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}))}handleKeyDown(e){"Space"===e.code&&(e.preventDefault(),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("keydown",this.handleKeyDown),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("keydown",this.handleKeyDown),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 --accent-color: #4d2588;\n --text-color: 17, 17, 17;\n --background-color: 255, 255, 255;\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(--background-color), 1);\n }\n :host([checked]) .icon {\n background: var(--accent-color);\n box-shadow: 0 0 0 0.1rem var(--accent-color) inset;\n } \n .icon {\n fill: none;\n height: var(--height);\n width: var(--width);\n padding: 0.1rem;\n stroke-width: 8; \n stroke: var(--border-color);\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 box-shadow: 0 0 0 0.1rem var(--border-color) inset;\n }\n</style>\n<label class="checkbox">\n <svg class="icon" viewBox="0 0 64 64">\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.handleKeyDown=this.handleKeyDown.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}))}handleKeyDown(e){"Space"===e.code&&(e.preventDefault(),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("keydown",this.handleKeyDown),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("keydown",this.handleKeyDown),this.removeEventListener("change",this.handleClick)}});
|
||||
6
components/dist/copy.js
vendored
6
components/dist/copy.js
vendored
@ -21,11 +21,15 @@ smCopy.innerHTML = `
|
||||
}
|
||||
.copy{
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
gap: 0.5rem;
|
||||
padding: var(--padding);
|
||||
align-items: center;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
}
|
||||
.copy-content{
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.copy-button{
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
|
||||
2
components/dist/copy.min.js
vendored
2
components/dist/copy.min.js
vendored
@ -1 +1 @@
|
||||
const smCopy=document.createElement("template");smCopy.innerHTML='\n<style> \n*{\n padding: 0;\n margin: 0;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n} \n:host{\n display: -webkit-inline-box;\n display: -ms-inline-flexbox;\n display: inline-flex;\n --accent-color: #4d2588;\n --text-color: 17, 17, 17;\n --background-color: 255, 255, 255;\n --padding: 0;\n --background-color: inherit;\n --button-background-color: rgba(var(--text-color), 0.2);\n --button-border-radius: 0.3rem;\n}\n.copy{\n display: grid;\n gap: 1rem;\n padding: var(--padding);\n align-items: center;\n grid-template-columns: minmax(0, 1fr) auto;\n}\n.copy-button{\n display: inline-flex;\n justify-content: center;\n cursor: pointer;\n border: none;\n padding: 0.4rem;\n background-color: inherit;\n border-radius: var(--button-border-radius);\n}\n.copy-button:active{\n background-color: var(--button-background-color);\n}\n.icon{\n height: 1.2rem;\n width: 1.2rem;\n fill: rgba(var(--text-color), 0.8);\n}\n@media (any-hover: hover){\n .copy:hover .copy-button{\n opacity: 1;\n }\n .copy-button{\n opacity: 0.6;\n }\n .copy-button:hover{\n background-color: var(--button-background-color);\n }\n}\n</style>\n</style>\n<section class="copy">\n <p class="copy-content"></p>\n <button part="button" class="copy-button" title="copy">\n <slot name="copy-icon">\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="M7 6V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1.001 1.001 0 0 1 3 21l.003-14c0-.552.45-1 1.007-1H7zM5.003 8L5 20h10V8H5.003zM9 6h8v10h2V4H9v2z"/></svg>\n </slot>\n </button>\n</section>\n',customElements.define("sm-copy",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smCopy.content.cloneNode(!0)),this.copyContent=this.shadowRoot.querySelector(".copy-content"),this.copyButton=this.shadowRoot.querySelector(".copy-button"),this.copy=this.copy.bind(this)}static get observedAttributes(){return["value"]}set value(n){this.setAttribute("value",n)}get value(){return this.getAttribute("value")}fireEvent(){this.dispatchEvent(new CustomEvent("copy",{composed:!0,bubbles:!0,cancelable:!0}))}copy(){navigator.clipboard.writeText(this.copyContent.textContent).then(n=>this.fireEvent()).catch(n=>console.error(n))}connectedCallback(){this.copyButton.addEventListener("click",this.copy)}attributeChangedCallback(n,t,o){"value"===n&&(this.copyContent.textContent=o)}disconnectedCallback(){this.copyButton.removeEventListener("click",this.copy)}});
|
||||
const smCopy=document.createElement("template");smCopy.innerHTML='\n<style> \n*{\n padding: 0;\n margin: 0;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n} \n:host{\n display: -webkit-inline-box;\n display: -ms-inline-flexbox;\n display: inline-flex;\n --accent-color: #4d2588;\n --text-color: 17, 17, 17;\n --background-color: 255, 255, 255;\n --padding: 0;\n --background-color: inherit;\n --button-background-color: rgba(var(--text-color), 0.2);\n --button-border-radius: 0.3rem;\n}\n.copy{\n display: grid;\n gap: 0.5rem;\n padding: var(--padding);\n align-items: center;\n grid-template-columns: minmax(0, 1fr) auto;\n}\n.copy-content{\n overflow-wrap: break-word;\n word-wrap: break-word;\n}\n.copy-button{\n display: inline-flex;\n justify-content: center;\n cursor: pointer;\n border: none;\n padding: 0.4rem;\n background-color: inherit;\n border-radius: var(--button-border-radius);\n}\n.copy-button:active{\n background-color: var(--button-background-color);\n}\n.icon{\n height: 1.2rem;\n width: 1.2rem;\n fill: rgba(var(--text-color), 0.8);\n}\n@media (any-hover: hover){\n .copy:hover .copy-button{\n opacity: 1;\n }\n .copy-button{\n opacity: 0.6;\n }\n .copy-button:hover{\n background-color: var(--button-background-color);\n }\n}\n</style>\n</style>\n<section class="copy">\n <p class="copy-content"></p>\n <button part="button" class="copy-button" title="copy">\n <slot name="copy-icon">\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="M7 6V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1.001 1.001 0 0 1 3 21l.003-14c0-.552.45-1 1.007-1H7zM5.003 8L5 20h10V8H5.003zM9 6h8v10h2V4H9v2z"/></svg>\n </slot>\n </button>\n</section>\n',customElements.define("sm-copy",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smCopy.content.cloneNode(!0)),this.copyContent=this.shadowRoot.querySelector(".copy-content"),this.copyButton=this.shadowRoot.querySelector(".copy-button"),this.copy=this.copy.bind(this)}static get observedAttributes(){return["value"]}set value(n){this.setAttribute("value",n)}get value(){return this.getAttribute("value")}fireEvent(){this.dispatchEvent(new CustomEvent("copy",{composed:!0,bubbles:!0,cancelable:!0}))}copy(){navigator.clipboard.writeText(this.copyContent.textContent).then(n=>this.fireEvent()).catch(n=>console.error(n))}connectedCallback(){this.copyButton.addEventListener("click",this.copy)}attributeChangedCallback(n,t,o){"value"===n&&(this.copyContent.textContent=o)}disconnectedCallback(){this.copyButton.removeEventListener("click",this.copy)}});
|
||||
19
components/dist/form.js
vendored
19
components/dist/form.js
vendored
@ -7,6 +7,7 @@ smForm.innerHTML = `
|
||||
box-sizing: border-box;
|
||||
}
|
||||
:host{
|
||||
display: flex;
|
||||
--gap: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
@ -60,23 +61,13 @@ customElements.define('sm-form', class extends HTMLElement {
|
||||
}
|
||||
}
|
||||
handleKeydown(e) {
|
||||
if (e.key === 'Enter') {
|
||||
if (e.key === 'Enter' && e.target.tagName !== 'SM-TEXTAREA' ) {
|
||||
if (this.allRequiredValid) {
|
||||
this.submitButton.click()
|
||||
}
|
||||
/* 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'
|
||||
})
|
||||
} */
|
||||
else {
|
||||
this.requiredElements.find(elem => !elem.isValid).vibrate()
|
||||
}
|
||||
}
|
||||
}
|
||||
reset() {
|
||||
|
||||
2
components/dist/form.min.js
vendored
2
components/dist/form.min.js
vendored
@ -1 +1 @@
|
||||
const smForm=document.createElement("template");smForm.innerHTML='\n <style>\n *{\n padding: 0;\n margin: 0;\n box-sizing: border-box;\n }\n :host{\n --gap: 1rem;\n width: 100%;\n }\n form{\n display: grid;\n gap: var(--gap);\n width: 100%;\n }\n </style>\n\t<form onsubmit="return false">\n\t\t<slot></slot>\n\t</form>\n',customElements.define("sm-form",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smForm.content.cloneNode(!0)),this.form=this.shadowRoot.querySelector("form"),this.formElements,this.requiredElements,this.submitButton,this.resetButton,this.allRequiredValid=!1,this.debounce=this.debounce.bind(this),this.handleInput=this.handleInput.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.reset=this.reset.bind(this)}debounce(t,e){let n=null;return(...s)=>{window.clearTimeout(n),n=window.setTimeout(()=>{t.apply(null,s)},e)}}handleInput(t){this.allRequiredValid=this.requiredElements.every(t=>t.isValid),this.submitButton&&(this.allRequiredValid?this.submitButton.disabled=!1:this.submitButton.disabled=!0)}handleKeydown(t){"Enter"===t.key&&this.allRequiredValid&&this.submitButton.click()}reset(){this.formElements.forEach(t=>t.reset())}connectedCallback(){const t=this.shadowRoot.querySelector("slot");t.addEventListener("slotchange",t=>{this.formElements=[...this.querySelectorAll("sm-input, sm-textarea, sm-checkbox, tags-input, file-input, sm-switch, sm-radio")],this.requiredElements=this.formElements.filter(t=>t.hasAttribute("required")),this.submitButton=t.target.assignedElements().find(t=>"primary"===t.getAttribute("variant")||"submit"===t.getAttribute("type")),this.resetButton=t.target.assignedElements().find(t=>"reset"===t.getAttribute("type")),this.resetButton&&this.resetButton.addEventListener("click",this.reset)}),this.addEventListener("input",this.debounce(this.handleInput,100)),this.addEventListener("keydown",this.debounce(this.handleKeydown,100))}disconnectedCallback(){this.removeEventListener("input",this.debounce(this.handleInput,100)),this.removeEventListener("keydown",this.debounce(this.handleKeydown,100))}});
|
||||
const smForm=document.createElement("template");smForm.innerHTML='\n <style>\n *{\n padding: 0;\n margin: 0;\n box-sizing: border-box;\n }\n :host{\n display: flex;\n --gap: 1rem;\n width: 100%;\n }\n form{\n display: grid;\n gap: var(--gap);\n width: 100%;\n }\n </style>\n\t<form onsubmit="return false">\n\t\t<slot></slot>\n\t</form>\n',customElements.define("sm-form",class extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(smForm.content.cloneNode(!0)),this.form=this.shadowRoot.querySelector("form"),this.formElements,this.requiredElements,this.submitButton,this.resetButton,this.allRequiredValid=!1,this.debounce=this.debounce.bind(this),this.handleInput=this.handleInput.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.reset=this.reset.bind(this)}debounce(t,e){let s=null;return(...n)=>{window.clearTimeout(s),s=window.setTimeout(()=>{t.apply(null,n)},e)}}handleInput(t){this.allRequiredValid=this.requiredElements.every(t=>t.isValid),this.submitButton&&(this.allRequiredValid?this.submitButton.disabled=!1:this.submitButton.disabled=!0)}handleKeydown(t){"Enter"===t.key&&"SM-TEXTAREA"!==t.target.tagName&&(this.allRequiredValid?this.submitButton.click():this.requiredElements.find(t=>!t.isValid).vibrate())}reset(){this.formElements.forEach(t=>t.reset())}connectedCallback(){const t=this.shadowRoot.querySelector("slot");t.addEventListener("slotchange",t=>{this.formElements=[...this.querySelectorAll("sm-input, sm-textarea, sm-checkbox, tags-input, file-input, sm-switch, sm-radio")],this.requiredElements=this.formElements.filter(t=>t.hasAttribute("required")),this.submitButton=t.target.assignedElements().find(t=>"primary"===t.getAttribute("variant")||"submit"===t.getAttribute("type")),this.resetButton=t.target.assignedElements().find(t=>"reset"===t.getAttribute("type")),this.resetButton&&this.resetButton.addEventListener("click",this.reset)}),this.addEventListener("input",this.debounce(this.handleInput,100)),this.addEventListener("keydown",this.debounce(this.handleKeydown,100))}disconnectedCallback(){this.removeEventListener("input",this.debounce(this.handleInput,100)),this.removeEventListener("keydown",this.debounce(this.handleKeydown,100))}});
|
||||
76
components/dist/input.js
vendored
76
components/dist/input.js
vendored
@ -190,7 +190,7 @@ input{
|
||||
text-align: left;
|
||||
font-size: 0.9rem;
|
||||
align-items: center;
|
||||
padding: 0.8rem 1rem;
|
||||
padding: 0.8rem 0;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
}
|
||||
.success{
|
||||
@ -240,6 +240,7 @@ customElements.define('sm-input',
|
||||
this.clearBtn = this.shadowRoot.querySelector('.clear')
|
||||
this.label = this.shadowRoot.querySelector('.label')
|
||||
this.feedbackText = this.shadowRoot.querySelector('.feedback-text')
|
||||
this.outerContainer = this.shadowRoot.querySelector('.outer-container')
|
||||
this._helperText
|
||||
this._errorText
|
||||
this.isRequired = false
|
||||
@ -251,6 +252,7 @@ customElements.define('sm-input',
|
||||
this.focusOut = this.focusOut.bind(this)
|
||||
this.fireEvent = this.fireEvent.bind(this)
|
||||
this.checkInput = this.checkInput.bind(this)
|
||||
this.vibrate = this.vibrate.bind(this)
|
||||
}
|
||||
|
||||
static get observedAttributes() {
|
||||
@ -283,15 +285,6 @@ customElements.define('sm-input',
|
||||
this.setAttribute('type', val)
|
||||
}
|
||||
|
||||
get isValid() {
|
||||
const _isValid = this.input.checkValidity()
|
||||
let _customValid = true
|
||||
if (this.customValidation) {
|
||||
_customValid = this.validationFunction(this.input.value)
|
||||
}
|
||||
return (_isValid && _customValid)
|
||||
}
|
||||
|
||||
get validity() {
|
||||
return this.input.validity
|
||||
}
|
||||
@ -310,6 +303,7 @@ customElements.define('sm-input',
|
||||
}
|
||||
}
|
||||
set customValidation(val) {
|
||||
|
||||
this.validationFunction = val
|
||||
}
|
||||
set errorText(val) {
|
||||
@ -318,6 +312,30 @@ customElements.define('sm-input',
|
||||
set helperText(val) {
|
||||
this._helperText = val
|
||||
}
|
||||
get isValid() {
|
||||
if (this.input.value !== '') {
|
||||
const _isValid = this.input.checkValidity()
|
||||
let _customValid = true
|
||||
if (this.validationFunction) {
|
||||
_customValid = Boolean(this.validationFunction(this.input.value))
|
||||
}
|
||||
if (_isValid && _customValid) {
|
||||
this.feedbackText.classList.remove('error')
|
||||
this.feedbackText.classList.add('success')
|
||||
this.feedbackText.textContent = ''
|
||||
} else {
|
||||
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}
|
||||
`
|
||||
}
|
||||
}
|
||||
return (_isValid && _customValid)
|
||||
}
|
||||
}
|
||||
reset(){
|
||||
this.value = ''
|
||||
}
|
||||
@ -341,7 +359,7 @@ customElements.define('sm-input',
|
||||
|
||||
checkInput(e){
|
||||
if (!this.hasAttribute('readonly')) {
|
||||
if (this.input.value !== '') {
|
||||
if (this.input.value.trim() !== '') {
|
||||
this.clearBtn.classList.remove('hide')
|
||||
} else {
|
||||
this.clearBtn.classList.add('hide')
|
||||
@ -349,20 +367,6 @@ customElements.define('sm-input',
|
||||
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').trim() === '') return;
|
||||
if (this.input.value !== '') {
|
||||
@ -377,10 +381,23 @@ customElements.define('sm-input',
|
||||
this.label.classList.remove('hide')
|
||||
}
|
||||
}
|
||||
vibrate() {
|
||||
this.outerContainer.animate([
|
||||
{ transform: 'translateX(-1rem)' },
|
||||
{ transform: 'translateX(1rem)' },
|
||||
{ transform: 'translateX(-0.5rem)' },
|
||||
{ transform: 'translateX(0.5rem)' },
|
||||
{ transform: 'translateX(0)' },
|
||||
], {
|
||||
duration: 300,
|
||||
easing: 'ease'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
connectedCallback() {
|
||||
this.animate = this.hasAttribute('animate')
|
||||
this.setAttribute('role', 'textbox')
|
||||
this.input.addEventListener('input', this.checkInput)
|
||||
this.clearBtn.addEventListener('click', this.reset)
|
||||
}
|
||||
@ -415,7 +432,14 @@ customElements.define('sm-input',
|
||||
}
|
||||
else if (name === 'required') {
|
||||
this.isRequired = this.hasAttribute('required')
|
||||
this.feedbackText.textContent = '* required'
|
||||
if (this.isRequired) {
|
||||
this.feedbackText.textContent = '* required'
|
||||
this.setAttribute('aria-required', 'true')
|
||||
}
|
||||
else {
|
||||
this.feedbackText.textContent = ''
|
||||
this.setAttribute('aria-required', 'false')
|
||||
}
|
||||
}
|
||||
else if (name === 'readonly') {
|
||||
if (this.hasAttribute('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
5
components/dist/popup.js
vendored
5
components/dist/popup.js
vendored
@ -327,7 +327,6 @@ customElements.define('sm-popup', class extends HTMLElement {
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
|
||||
this.popupBodySlot.addEventListener('slotchange', () => {
|
||||
this.forms = this.querySelectorAll('sm-form')
|
||||
})
|
||||
@ -345,7 +344,7 @@ customElements.define('sm-popup', class extends HTMLElement {
|
||||
if (entry.contentBoxSize) {
|
||||
// Firefox implements `contentBoxSize` as a single content rect, rather than an array
|
||||
const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;
|
||||
this.threshold = entry.blockSize.height * 0.3
|
||||
this.threshold = contentBoxSize.blockSize.height * 0.3
|
||||
} else {
|
||||
this.threshold = entry.contentRect.height * 0.3
|
||||
}
|
||||
@ -371,4 +370,4 @@ customElements.define('sm-popup', class extends HTMLElement {
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
2
components/dist/popup.min.js
vendored
2
components/dist/popup.min.js
vendored
File diff suppressed because one or more lines are too long
43
components/dist/select.js
vendored
43
components/dist/select.js
vendored
@ -8,9 +8,9 @@ smSelect.innerHTML = `
|
||||
box-sizing: border-box;
|
||||
}
|
||||
:host{
|
||||
display: -webkit-inline-box;
|
||||
display: -ms-inline-flexbox;
|
||||
display: inline-flex;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
--accent-color: #4d2588;
|
||||
--text-color: 17, 17, 17;
|
||||
--background-color: 255, 255, 255;
|
||||
@ -186,8 +186,20 @@ customElements.define('sm-select', class extends HTMLElement {
|
||||
this.setAttribute('value', val)
|
||||
}
|
||||
|
||||
reset() {
|
||||
|
||||
reset(fire = true) {
|
||||
if (this.availableOptions[0] && this.previousOption !== this.availableOptions[0]) {
|
||||
const firstElement = this.availableOptions[0];
|
||||
if (this.previousOption) {
|
||||
this.previousOption.classList.remove('check-selected')
|
||||
}
|
||||
firstElement.classList.add('check-selected')
|
||||
this.value = firstElement.getAttribute('value')
|
||||
this.selectedOptionText.textContent = firstElement.textContent
|
||||
this.previousOption = firstElement;
|
||||
if (fire) {
|
||||
this.fireEvent()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open() {
|
||||
@ -295,16 +307,7 @@ customElements.define('sm-select', class extends HTMLElement {
|
||||
let slot = this.shadowRoot.querySelector('slot')
|
||||
slot.addEventListener('slotchange', e => {
|
||||
this.availableOptions = slot.assignedElements()
|
||||
if (this.availableOptions[0]) {
|
||||
let firstElement = this.availableOptions[0];
|
||||
this.previousOption = firstElement;
|
||||
firstElement.classList.add('check-selected')
|
||||
this.value = firstElement.getAttribute('value')
|
||||
this.selectedOptionText.textContent = firstElement.textContent
|
||||
this.availableOptions.forEach((element) => {
|
||||
element.setAttribute('tabindex', "0");
|
||||
})
|
||||
}
|
||||
this.reset(false)
|
||||
});
|
||||
this.addEventListener('click', this.handleClick)
|
||||
this.addEventListener('keydown', this.handleKeydown)
|
||||
@ -342,13 +345,13 @@ smOption.innerHTML = `
|
||||
display: flex;
|
||||
}
|
||||
.option{
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
display: grid;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
min-width: 100%;
|
||||
gap: 0.5rem;
|
||||
grid-template-columns: max-content minmax(0, 1fr);
|
||||
padding: 0.8rem 1.2rem;
|
||||
cursor: pointer;
|
||||
overflow-wrap: break-word;
|
||||
@ -363,7 +366,6 @@ smOption.innerHTML = `
|
||||
opacity: 0;
|
||||
height: 1.2rem;
|
||||
width: 1.2rem;
|
||||
margin-right: 0.5rem;
|
||||
fill: rgba(var(--text-color), 0.8);
|
||||
}
|
||||
:host(:focus) .option .icon{
|
||||
@ -395,5 +397,6 @@ customElements.define('sm-option', class extends HTMLElement {
|
||||
|
||||
connectedCallback() {
|
||||
this.setAttribute('role', 'option')
|
||||
this.setAttribute('tabindex', '0')
|
||||
}
|
||||
})
|
||||
})
|
||||
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
63
components/dist/strip-select.js
vendored
63
components/dist/strip-select.js
vendored
@ -12,6 +12,7 @@ stripSelect.innerHTML = `
|
||||
--text-color: 17, 17, 17;
|
||||
--background-color: 255, 255, 255;
|
||||
--gap: 0.5rem;
|
||||
padding: 1rem 0;
|
||||
}
|
||||
.hide{
|
||||
display: none !important;
|
||||
@ -23,7 +24,6 @@ stripSelect.innerHTML = `
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 1rem 0;
|
||||
}
|
||||
.strip-select{
|
||||
position: relative;
|
||||
@ -64,13 +64,6 @@ stripSelect.innerHTML = `
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
.cover--left{
|
||||
background: linear-gradient(90deg, rgba(var(--background-color), 1) 60%, transparent);
|
||||
}
|
||||
.cover--right{
|
||||
right: 0;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(var(--background-color), 1) 40%);
|
||||
}
|
||||
.nav-button--right::before{
|
||||
background-color: red;
|
||||
}
|
||||
@ -89,6 +82,13 @@ stripSelect.innerHTML = `
|
||||
.cover{
|
||||
width: 2rem;
|
||||
}
|
||||
.cover--left{
|
||||
background: linear-gradient(90deg, rgba(var(--background-color), 1), transparent);
|
||||
}
|
||||
.cover--right{
|
||||
right: 0;
|
||||
background: linear-gradient(90deg, transparent, rgba(var(--background-color), 1));
|
||||
}
|
||||
}
|
||||
@media (hover: hover){
|
||||
::-webkit-scrollbar-track {
|
||||
@ -101,6 +101,13 @@ stripSelect.innerHTML = `
|
||||
.strip-select{
|
||||
overflow: hidden;
|
||||
}
|
||||
.cover--left{
|
||||
background: linear-gradient(90deg, rgba(var(--background-color), 1) 60%, transparent);
|
||||
}
|
||||
.cover--right{
|
||||
right: 0;
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(var(--background-color), 1) 40%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<section class="scrolling-container">
|
||||
@ -118,7 +125,7 @@ stripSelect.innerHTML = `
|
||||
</section>
|
||||
|
||||
`
|
||||
customElements.define('strip-select', class extends HTMLElement{
|
||||
customElements.define('strip-select', class extends HTMLElement {
|
||||
constructor() {
|
||||
super()
|
||||
this.attachShadow({
|
||||
@ -136,20 +143,20 @@ customElements.define('strip-select', class extends HTMLElement{
|
||||
get value() {
|
||||
return this._value
|
||||
}
|
||||
scrollLeft(){
|
||||
scrollLeft() {
|
||||
this.stripSelect.scrollBy({
|
||||
left: -this.scrollDistance,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
}
|
||||
|
||||
scrollRight(){
|
||||
scrollRight() {
|
||||
this.stripSelect.scrollBy({
|
||||
left: this.scrollDistance,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
}
|
||||
fireEvent(){
|
||||
fireEvent() {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("change", {
|
||||
bubbles: true,
|
||||
@ -193,14 +200,14 @@ customElements.define('strip-select', class extends HTMLElement{
|
||||
})
|
||||
const resObs = new ResizeObserver(entries => {
|
||||
entries.forEach(entry => {
|
||||
if(entry.contentBoxSize) {
|
||||
if (entry.contentBoxSize) {
|
||||
// Firefox implements `contentBoxSize` as a single content rect, rather than an array
|
||||
const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;
|
||||
|
||||
|
||||
this.scrollDistance = contentBoxSize.inlineSize * 0.6
|
||||
} else {
|
||||
this.scrollDistance = entry.contentRect.width * 0.6
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
resObs.observe(this)
|
||||
@ -225,10 +232,10 @@ customElements.define('strip-select', class extends HTMLElement{
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
threshold: 0.9,
|
||||
root: this
|
||||
})
|
||||
{
|
||||
threshold: 0.9,
|
||||
root: this
|
||||
})
|
||||
const lastOptionObserver = new IntersectionObserver(entries => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
@ -241,16 +248,16 @@ customElements.define('strip-select', class extends HTMLElement{
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
threshold: 0.9,
|
||||
root: this
|
||||
})
|
||||
{
|
||||
threshold: 0.9,
|
||||
root: this
|
||||
})
|
||||
navButtonLeft.addEventListener('click', this.scrollLeft)
|
||||
navButtonRight.addEventListener('click', this.scrollRight)
|
||||
}
|
||||
disconnectedCallback() {
|
||||
navButtonLeft.removeEventListener('click', this.scrollLeft)
|
||||
navButtonRight.removeEventListener('click', this.scrollRight)
|
||||
navButtonRight.removeEventListener('click', this.scrollRight)
|
||||
}
|
||||
})
|
||||
|
||||
@ -299,7 +306,7 @@ stripOption.innerHTML = `
|
||||
<slot></slot>
|
||||
</label>
|
||||
`
|
||||
customElements.define('strip-option', class extends HTMLElement{
|
||||
customElements.define('strip-option', class extends HTMLElement {
|
||||
constructor() {
|
||||
super()
|
||||
this.attachShadow({
|
||||
@ -307,14 +314,14 @@ customElements.define('strip-option', class extends HTMLElement{
|
||||
}).append(stripOption.content.cloneNode(true))
|
||||
this._value
|
||||
this.radioButton = this.shadowRoot.querySelector('input')
|
||||
|
||||
|
||||
this.fireEvent = this.fireEvent.bind(this)
|
||||
this.handleKeyDown = this.handleKeyDown.bind(this)
|
||||
}
|
||||
get value() {
|
||||
return this._value
|
||||
}
|
||||
fireEvent(){
|
||||
fireEvent() {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("option-clicked", {
|
||||
bubbles: true,
|
||||
@ -325,7 +332,7 @@ customElements.define('strip-option', class extends HTMLElement{
|
||||
})
|
||||
)
|
||||
}
|
||||
handleKeyDown(e){
|
||||
handleKeyDown(e) {
|
||||
if (e.key === 'Enter' || e.key === 'Space') {
|
||||
this.fireEvent()
|
||||
}
|
||||
|
||||
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
34
components/dist/tabs.js
vendored
34
components/dist/tabs.js
vendored
@ -14,6 +14,8 @@ smTabHeader.innerHTML = `
|
||||
--accent-color: #4d2588;
|
||||
--text-color: 17, 17, 17;
|
||||
--background-color: 255, 255, 255;
|
||||
--gap: 1rem;
|
||||
--justify-content: flex-start;
|
||||
--tab-indicator-border-radius: 0.3rem;
|
||||
}
|
||||
.tabs{
|
||||
@ -26,10 +28,8 @@ smTabHeader.innerHTML = `
|
||||
display: -ms-grid;
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
-webkit-box-pack: start;
|
||||
-ms-flex-pack: start;
|
||||
justify-content: flex-start;
|
||||
gap: 1rem;
|
||||
justify-content: var(--justify-content);
|
||||
gap: var(--gap);
|
||||
position: relative;
|
||||
overflow: auto hidden;
|
||||
max-width: 100%;
|
||||
@ -73,7 +73,7 @@ smTabHeader.innerHTML = `
|
||||
color: var(--accent-color);
|
||||
opacity: 1;
|
||||
}
|
||||
@media (hover: none){
|
||||
@media (any-hover: none){
|
||||
.tab-header::-webkit-scrollbar-track {
|
||||
-webkit-box-shadow: none !important;
|
||||
background-color: transparent !important;
|
||||
@ -83,6 +83,11 @@ smTabHeader.innerHTML = `
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
@media (any-hover: hover){
|
||||
.tab-header{
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div part="tab-container" class="tabs">
|
||||
<div part="tab-header" class="tab-header">
|
||||
@ -110,6 +115,7 @@ customElements.define('sm-tab-header', class extends HTMLElement {
|
||||
this.changeTab = this.changeTab.bind(this)
|
||||
this.handleClick = this.handleClick.bind(this)
|
||||
this.handlePanelChange = this.handlePanelChange.bind(this)
|
||||
this.moveIndiactor = this.moveIndiactor.bind(this)
|
||||
}
|
||||
|
||||
fireEvent(index) {
|
||||
@ -135,10 +141,9 @@ customElements.define('sm-tab-header', class extends HTMLElement {
|
||||
this.prevTab.classList.remove('active')
|
||||
target.classList.add('active')
|
||||
|
||||
target.scrollIntoView({
|
||||
this.tabHeader.scrollTo({
|
||||
behavior: 'smooth',
|
||||
block: 'nearest',
|
||||
inline: 'center'
|
||||
left: target.getBoundingClientRect().left - this.tabHeader.getBoundingClientRect().left + this.tabHeader.scrollLeft
|
||||
})
|
||||
this.moveIndiactor(target.getBoundingClientRect())
|
||||
this.prevTab = target;
|
||||
@ -222,6 +227,7 @@ smTab.innerHTML = `
|
||||
display: -ms-inline-flexbox;
|
||||
display: inline-flex;
|
||||
z-index: 1;
|
||||
--padding: 0.8rem 1rem;
|
||||
}
|
||||
.tab{
|
||||
position: relative;
|
||||
@ -235,7 +241,7 @@ smTab.innerHTML = `
|
||||
cursor: pointer;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
white-space: nowrap;
|
||||
padding: 0.4rem 0.8rem;
|
||||
padding: var(--padding);
|
||||
font-weight: 500;
|
||||
word-spacing: 0.1rem;
|
||||
text-align: center;
|
||||
@ -329,7 +335,6 @@ customElements.define('sm-tab-panels', class extends HTMLElement {
|
||||
this.isTransitioning = false
|
||||
|
||||
this.panelContainer = this.shadowRoot.querySelector('.panel-container');
|
||||
this.panelSlot = this.shadowRoot.querySelector('slot');
|
||||
this.handleTabChange = this.handleTabChange.bind(this)
|
||||
}
|
||||
handleTabChange(e) {
|
||||
@ -353,8 +358,9 @@ customElements.define('sm-tab-panels', class extends HTMLElement {
|
||||
)
|
||||
}
|
||||
connectedCallback() {
|
||||
this.panelSlot.addEventListener('slotchange', () => {
|
||||
this.allPanels = this.panelSlot.assignedElements()
|
||||
const slot = this.shadowRoot.querySelector('slot');
|
||||
slot.addEventListener('slotchange', (e) => {
|
||||
this.allPanels = e.target.assignedElements()
|
||||
this.allPanels.forEach((panel, index) => {
|
||||
panel.dataset.index = index
|
||||
intersectionObserver.observe(panel)
|
||||
@ -366,7 +372,7 @@ customElements.define('sm-tab-panels', class extends HTMLElement {
|
||||
|
||||
entries.forEach(entry => {
|
||||
if (!this.isTransitioning && entry.isIntersecting) {
|
||||
this.fireEvent(entry.target.dataset.index), 3000
|
||||
this.fireEvent(entry.target.dataset.index)
|
||||
}
|
||||
})
|
||||
}, {
|
||||
@ -377,4 +383,4 @@ customElements.define('sm-tab-panels', class extends HTMLElement {
|
||||
intersectionObserver.disconnect()
|
||||
document.removeEventListener(`switchedtab${this.id}`, this.handleTabChange)
|
||||
}
|
||||
})
|
||||
})
|
||||
2
components/dist/tabs.min.js
vendored
2
components/dist/tabs.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user