This commit is contained in:
sairaj mote 2022-02-19 16:36:59 +05:30
parent 2e209372a3
commit 9939beb555
6 changed files with 324 additions and 355 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@
/args/param.json /args/param.json
/args/keys*.json /args/keys*.json
*test* *test*
args/app-config.json

View File

@ -74,11 +74,13 @@ smButton.innerHTML = `
background-color: rgba(var(--text-color), 0.3); background-color: rgba(var(--text-color), 0.3);
} }
@media (hover: hover){ @media (hover: hover){
:host(:not([disabled])) .button:hover{ :host(:not([disabled])) .button:hover,
:host(:focus-within:not([disabled])) .button{
-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); -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);
box-shadow: 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.2rem 0.8rem rgba(0, 0, 0, 0.12); box-shadow: 0 0.1rem 0.1rem rgba(0, 0, 0, 0.1), 0 0.2rem 0.8rem rgba(0, 0, 0, 0.12);
} }
:host([variant='outlined']) .button:hover{ :host([variant='outlined']:not([disabled])) .button:hover,
:host(:focus-within[variant='outlined']:not([disabled])) .button:hover{
-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); -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);
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); 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);
} }
@ -120,9 +122,12 @@ customElements.define('sm-button',
this.removeAttribute('disabled'); this.removeAttribute('disabled');
} }
} }
focusIn() {
this.focus();
}
handleKeyDown(e) { handleKeyDown(e) {
if (!this.hasAttribute('disabled') && (e.key === 'Enter' || e.code === 'Space')) { if (!this.hasAttribute('disabled') && (e.key === 'Enter' || e.key === ' ')) {
e.preventDefault(); e.preventDefault();
this.click(); this.click();
} }
@ -986,6 +991,24 @@ customElements.define('sm-notifications', class extends HTMLElement {
}); });
} }
}); });
class Stack {
constructor() {
this.items = [];
}
push(element) {
this.items.push(element);
}
pop() {
if (this.items.length == 0)
return "Underflow";
return this.items.pop();
}
peek() {
return this.items[this.items.length - 1];
}
}
const popupStack = new Stack();
const smPopup = document.createElement('template'); const smPopup = document.createElement('template');
smPopup.innerHTML = ` smPopup.innerHTML = `
<style> <style>
@ -1007,7 +1030,6 @@ smPopup.innerHTML = `
--height: auto; --height: auto;
--min-width: auto; --min-width: auto;
--min-height: auto; --min-height: auto;
--body-padding: 1.5rem;
--backdrop-background: rgba(0, 0, 0, 0.6); --backdrop-background: rgba(0, 0, 0, 0.6);
--border-radius: 0.8rem 0.8rem 0 0; --border-radius: 0.8rem 0.8rem 0 0;
} }
@ -1020,10 +1042,6 @@ smPopup.innerHTML = `
left: 0; left: 0;
right: 0; right: 0;
place-items: center; place-items: center;
background: var(--backdrop-background);
-webkit-transition: opacity 0.3s;
-o-transition: opacity 0.3s;
transition: opacity 0.3s;
z-index: 10; z-index: 10;
touch-action: none; touch-action: none;
} }
@ -1031,6 +1049,18 @@ smPopup.innerHTML = `
-webkit-transform: scale(0.9) translateY(-2rem) !important; -webkit-transform: scale(0.9) translateY(-2rem) !important;
transform: scale(0.9) translateY(-2rem) !important; transform: scale(0.9) translateY(-2rem) !important;
} }
.background{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
pointer-events: none;
background: var(--backdrop-background);
-webkit-transition: opacity 0.3s;
-o-transition: opacity 0.3s;
transition: opacity 0.3s;
}
.popup{ .popup{
display: -webkit-box; display: -webkit-box;
display: -ms-flexbox; display: -ms-flexbox;
@ -1050,17 +1080,9 @@ smPopup.innerHTML = `
min-height: var(--min-height); min-height: var(--min-height);
max-height: 90vh; max-height: 90vh;
border-radius: var(--border-radius); border-radius: var(--border-radius);
-webkit-transform: scale(1) translateY(100%);
transform: scale(1) translateY(100%);
-webkit-transition: -webkit-transform 0.3s;
transition: -webkit-transform 0.3s;
-o-transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
transition: transform 0.3s;
background: rgba(var(--background-color), 1); background: rgba(var(--background-color), 1);
-webkit-box-shadow: 0 -1rem 2rem #00000020; -webkit-box-shadow: 0 -1rem 2rem #00000020;
box-shadow: 0 -1rem 2rem #00000020; box-shadow: 0 -1rem 2rem #00000020;
content-visibility: auto;
} }
.container-header{ .container-header{
display: -webkit-box; display: -webkit-box;
@ -1087,17 +1109,15 @@ smPopup.innerHTML = `
-ms-flex: 1; -ms-flex: 1;
flex: 1; flex: 1;
width: 100%; width: 100%;
padding: var(--body-padding); padding: var(--body-padding, 1.5rem);
overflow-y: auto; overflow-y: auto;
} }
.hide{ .hide{
opacity: 0; display:none;
pointer-events: none;
visiblity: none;
} }
@media screen and (min-width: 640px){ @media screen and (min-width: 640px){
:host{ :host{
--border-radius: 0.4rem; --border-radius: 0.5rem;
} }
.popup{ .popup{
-ms-flex-item-align: center; -ms-flex-item-align: center;
@ -1105,8 +1125,6 @@ smPopup.innerHTML = `
align-self: center; align-self: center;
border-radius: var(--border-radius); border-radius: var(--border-radius);
height: var(--height); height: var(--height);
-webkit-transform: scale(1) translateY(3rem);
transform: scale(1) translateY(3rem);
-webkit-box-shadow: 0 3rem 2rem -0.5rem #00000040; -webkit-box-shadow: 0 3rem 2rem -0.5rem #00000040;
box-shadow: 0 3rem 2rem -0.5rem #00000040; box-shadow: 0 3rem 2rem -0.5rem #00000040;
} }
@ -1141,7 +1159,8 @@ smPopup.innerHTML = `
} }
} }
</style> </style>
<div part="background" class="popup-container hide" role="dialog"> <div class="popup-container hide" role="dialog">
<div part="background" class="background"></div>
<div part="popup" class="popup"> <div part="popup" class="popup">
<div part="popup-header" class="popup-top"> <div part="popup-header" class="popup-top">
<div class="handle"></div> <div class="handle"></div>
@ -1163,26 +1182,30 @@ customElements.define('sm-popup', class extends HTMLElement {
this.allowClosing = false; this.allowClosing = false;
this.isOpen = false; this.isOpen = false;
this.pinned = false; this.pinned = false;
this.popupStack = undefined;
this.offset = 0; this.offset = 0;
this.touchStartY = 0; this.touchStartY = 0;
this.touchEndY = 0; this.touchEndY = 0;
this.touchStartTime = 0; this.touchStartTime = 0;
this.touchEndTime = 0; this.touchEndTime = 0;
this.touchEndAnimataion = undefined; this.touchEndAnimation = undefined;
this.focusable
this.autoFocus
this.mutationObserver
this.popupContainer = this.shadowRoot.querySelector('.popup-container'); this.popupContainer = this.shadowRoot.querySelector('.popup-container');
this.backdrop = this.shadowRoot.querySelector('.background');
this.popup = this.shadowRoot.querySelector('.popup'); this.popup = this.shadowRoot.querySelector('.popup');
this.popupBodySlot = this.shadowRoot.querySelector('.popup-body slot'); this.popupBodySlot = this.shadowRoot.querySelector('.popup-body slot');
this.popupHeader = this.shadowRoot.querySelector('.popup-top'); this.popupHeader = this.shadowRoot.querySelector('.popup-top');
this.resumeScrolling = this.resumeScrolling.bind(this); this.resumeScrolling = this.resumeScrolling.bind(this);
this.setStateOpen = this.setStateOpen.bind(this);
this.show = this.show.bind(this); this.show = this.show.bind(this);
this.hide = this.hide.bind(this); this.hide = this.hide.bind(this);
this.handleTouchStart = this.handleTouchStart.bind(this); this.handleTouchStart = this.handleTouchStart.bind(this);
this.handleTouchMove = this.handleTouchMove.bind(this); this.handleTouchMove = this.handleTouchMove.bind(this);
this.handleTouchEnd = this.handleTouchEnd.bind(this); this.handleTouchEnd = this.handleTouchEnd.bind(this);
this.movePopup = this.movePopup.bind(this); this.detectFocus = this.detectFocus.bind(this);
} }
static get observedAttributes() { static get observedAttributes() {
@ -1193,135 +1216,208 @@ customElements.define('sm-popup', class extends HTMLElement {
return this.isOpen; return this.isOpen;
} }
animateTo(element, keyframes, options) {
const anime = element.animate(keyframes, { ...options, fill: 'both' })
anime.finished.then(() => {
anime.commitStyles()
anime.cancel()
})
return anime
}
resumeScrolling() { resumeScrolling() {
const scrollY = document.body.style.top; const scrollY = document.body.style.top;
window.scrollTo(0, parseInt(scrollY || '0') * -1); window.scrollTo(0, parseInt(scrollY || '0') * -1);
setTimeout(() => { document.body.style.overflow = '';
document.body.style.overflow = 'auto'; document.body.style.top = 'initial';
document.body.style.top = 'initial'; }
}, 300);
setStateOpen() {
if (!this.isOpen || this.offset) {
const animOptions = {
duration: 300,
easing: 'ease'
}
const initialAnimation = (window.innerWidth > 640) ? 'scale(1.1)' : `translateY(${this.offset ? `${this.offset}px` : '100%'})`
this.animateTo(this.popup, [
{
opacity: this.offset ? 1 : 0,
transform: initialAnimation
},
{
opacity: 1,
transform: 'none'
},
], animOptions)
}
} }
show(options = {}) { show(options = {}) {
const { pinned = false, popupStack } = options; const { pinned = false } = options;
if (popupStack) if (!this.isOpen) {
this.popupStack = popupStack; const animOptions = {
if (this.popupStack && !this.hasAttribute('open')) { duration: 300,
this.popupStack.push({ easing: 'ease'
}
popupStack.push({
popup: this, popup: this,
permission: pinned permission: pinned
}); });
if (this.popupStack.items.length > 1) { if (popupStack.items.length > 1) {
this.popupStack.items[this.popupStack.items.length - 2].popup.classList.add('stacked'); this.animateTo(popupStack.items[popupStack.items.length - 2].popup.shadowRoot.querySelector('.popup'), [
{ transform: 'none' },
{ transform: (window.innerWidth > 640) ? 'scale(0.95)' : 'translateY(-1.5rem)' },
], animOptions)
} }
this.popupContainer.classList.remove('hide');
if (!this.offset)
this.backdrop.animate([
{ opacity: 0 },
{ opacity: 1 },
], animOptions)
this.setStateOpen()
this.dispatchEvent( this.dispatchEvent(
new CustomEvent("popupopened", { new CustomEvent("popupopened", {
bubbles: true, bubbles: true,
detail: { detail: {
popup: this, popup: this,
popupStack: this.popupStack
} }
}) })
); );
this.setAttribute('open', '');
this.pinned = pinned; this.pinned = pinned;
this.isOpen = true; this.isOpen = true;
document.body.style.overflow = 'hidden';
document.body.style.top = `-${window.scrollY}px`;
const elementToFocus = this.autoFocus || this.focusable[0];
elementToFocus.tagName.includes('SM-') ? elementToFocus.focusIn() : elementToFocus.focus();
if (!this.hasAttribute('open'))
this.setAttribute('open', '');
} }
this.popupContainer.classList.remove('hide');
this.popup.style.transform = 'none';
document.body.style.overflow = 'hidden';
document.body.style.top = `-${window.scrollY}px`;
return this.popupStack;
} }
hide() { hide() {
if (window.innerWidth < 640) const animOptions = {
this.popup.style.transform = 'translateY(100%)'; duration: 150,
else easing: 'ease'
this.popup.style.transform = 'translateY(3rem)'; }
this.popupContainer.classList.add('hide'); this.backdrop.animate([
this.removeAttribute('open'); { opacity: 1 },
if (typeof this.popupStack !== 'undefined') { { opacity: 0 }
this.popupStack.pop(); ], animOptions)
if (this.popupStack.items.length) { this.animateTo(this.popup, [
this.popupStack.items[this.popupStack.items.length - 1].popup.classList.remove('stacked'); {
} else { opacity: 1,
this.resumeScrolling(); transform: (window.innerWidth > 640) ? 'none' : `translateY(${this.offset ? `${this.offset}px` : '0'})`
} },
{
opacity: 0,
transform: (window.innerWidth > 640) ? 'scale(1.1)' : 'translateY(100%)'
},
], animOptions).finished
.finally(() => {
this.popupContainer.classList.add('hide');
this.popup.style = ''
this.removeAttribute('open');
if (this.forms.length) {
this.forms.forEach(form => form.reset());
}
this.dispatchEvent(
new CustomEvent("popupclosed", {
bubbles: true,
detail: {
popup: this,
}
})
);
this.isOpen = false;
})
popupStack.pop();
if (popupStack.items.length) {
this.animateTo(popupStack.items[popupStack.items.length - 1].popup.shadowRoot.querySelector('.popup'), [
{ transform: (window.innerWidth > 640) ? 'scale(0.95)' : 'translateY(-1.5rem)' },
{ transform: 'none' },
], animOptions)
} else { } else {
this.resumeScrolling(); this.resumeScrolling();
} }
if (this.forms.length) {
setTimeout(() => {
this.forms.forEach(form => form.reset());
}, 300);
}
setTimeout(() => {
this.dispatchEvent(
new CustomEvent("popupclosed", {
bubbles: true,
detail: {
popup: this,
popupStack: this.popupStack
}
})
);
this.isOpen = false;
}, 300);
} }
handleTouchStart(e) { handleTouchStart(e) {
this.offset = 0
this.popupHeader.addEventListener('touchmove', this.handleTouchMove, { passive: true });
this.popupHeader.addEventListener('touchend', this.handleTouchEnd, { passive: true });
this.touchStartY = e.changedTouches[0].clientY; this.touchStartY = e.changedTouches[0].clientY;
this.popup.style.transition = 'transform 0.1s';
this.touchStartTime = e.timeStamp; this.touchStartTime = e.timeStamp;
} }
handleTouchMove(e) { handleTouchMove(e) {
if (this.touchStartY < e.changedTouches[0].clientY) { if (this.touchStartY < e.changedTouches[0].clientY) {
this.offset = e.changedTouches[0].clientY - this.touchStartY; this.offset = e.changedTouches[0].clientY - this.touchStartY;
this.touchEndAnimataion = window.requestAnimationFrame(() => this.movePopup()); this.touchEndAnimation = window.requestAnimationFrame(() => {
this.popup.style.transform = `translateY(${this.offset}px)`;
});
} }
} }
handleTouchEnd(e) { handleTouchEnd(e) {
this.touchEndTime = e.timeStamp; this.touchEndTime = e.timeStamp;
cancelAnimationFrame(this.touchEndAnimataion); cancelAnimationFrame(this.touchEndAnimation);
this.touchEndY = e.changedTouches[0].clientY; this.touchEndY = e.changedTouches[0].clientY;
this.popup.style.transition = 'transform 0.3s';
this.threshold = this.popup.getBoundingClientRect().height * 0.3; this.threshold = this.popup.getBoundingClientRect().height * 0.3;
if (this.touchEndTime - this.touchStartTime > 200) { if (this.touchEndTime - this.touchStartTime > 200) {
if (this.touchEndY - this.touchStartY > this.threshold) { if (this.touchEndY - this.touchStartY > this.threshold) {
if (this.pinned) { if (this.pinned) {
this.show(); this.setStateOpen();
return; return;
} else } else
this.hide(); this.hide();
} else { } else {
this.show(); this.setStateOpen();
} }
} else { } else {
if (this.touchEndY > this.touchStartY) if (this.touchEndY > this.touchStartY)
if (this.pinned) { if (this.pinned) {
this.show(); this.setStateOpen();
return; return;
} }
else else
this.hide(); this.hide();
} }
this.popupHeader.removeEventListener('touchmove', this.handleTouchMove, { passive: true });
this.popupHeader.removeEventListener('touchend', this.handleTouchEnd, { passive: true });
} }
movePopup() {
this.popup.style.transform = `translateY(${this.offset}px)`; detectFocus(e) {
if (e.key === 'Tab') {
const lastElement = this.focusable[this.focusable.length - 1];
const firstElement = this.focusable[0];
if (e.shiftKey && document.activeElement === firstElement) {
e.preventDefault();
lastElement.tagName.includes('SM-') ? lastElement.focusIn() : lastElement.focus();
} else if (!e.shiftKey && document.activeElement === lastElement) {
e.preventDefault();
firstElement.tagName.includes('SM-') ? firstElement.focusIn() : firstElement.focus();
}
}
}
updateFocusableList() {
this.focusable = this.querySelectorAll('sm-button:not([disabled]), button:not([disabled]), [href], sm-input, input, sm-select, select, sm-checkbox, sm-textarea, textarea, [tabindex]:not([tabindex="-1"])')
this.autoFocus = this.querySelector('[autofocus]')
} }
connectedCallback() { connectedCallback() {
this.popupBodySlot.addEventListener('slotchange', () => { this.popupBodySlot.addEventListener('slotchange', () => {
this.forms = this.querySelectorAll('sm-form'); this.forms = this.querySelectorAll('sm-form');
this.updateFocusableList()
}); });
this.popupContainer.addEventListener('mousedown', e => { this.popupContainer.addEventListener('mousedown', e => {
if (e.target === this.popupContainer && !this.pinned) { if (e.target === this.popupContainer && !this.pinned) {
if (this.pinned) { if (this.pinned) {
this.show(); this.setStateOpen();
} else } else
this.hide(); this.hide();
} }
@ -1340,16 +1436,19 @@ customElements.define('sm-popup', class extends HTMLElement {
}); });
resizeObserver.observe(this); resizeObserver.observe(this);
this.mutationObserver = new MutationObserver(entries => {
this.updateFocusableList()
})
this.mutationObserver.observe(this, { attributes: true, childList: true, subtree: true })
this.addEventListener('keydown', this.detectFocus);
this.popupHeader.addEventListener('touchstart', this.handleTouchStart, { passive: true }); this.popupHeader.addEventListener('touchstart', this.handleTouchStart, { passive: true });
this.popupHeader.addEventListener('touchmove', this.handleTouchMove, { passive: true });
this.popupHeader.addEventListener('touchend', this.handleTouchEnd, { passive: true });
} }
disconnectedCallback() { disconnectedCallback() {
this.popupHeader.removeEventListener('touchstart', this.handleTouchStart, { passive: true }); this.removeEventListener('keydown', this.detectFocus);
this.popupHeader.removeEventListener('touchmove', this.handleTouchMove, { passive: true });
this.popupHeader.removeEventListener('touchend', this.handleTouchEnd, { passive: true });
resizeObserver.unobserve(); resizeObserver.unobserve();
this.mutationObserver.disconnect()
this.popupHeader.removeEventListener('touchstart', this.handleTouchStart, { passive: true });
} }
attributeChangedCallback(name) { attributeChangedCallback(name) {
if (name === 'open') { if (name === 'open') {
@ -2225,7 +2324,6 @@ smSelect.innerHTML = `
--accent-color: #4d2588; --accent-color: #4d2588;
--text-color: 17, 17, 17; --text-color: 17, 17, 17;
--background-color: 255, 255, 255; --background-color: 255, 255, 255;
--max-height: auto;
--min-width: 100%; --min-width: 100%;
} }
:host([disabled]) .select{ :host([disabled]) .select{
@ -2252,11 +2350,12 @@ smSelect.innerHTML = `
fill: rgba(var(--text-color), 0.7); fill: rgba(var(--text-color), 0.7);
} }
.selected-option-text{ .selected-option-text{
font-size: 0.9rem; font-size: inherit;
overflow: hidden; overflow: hidden;
-o-text-overflow: ellipsis; -o-text-overflow: ellipsis;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
font-weight: 500;
} }
.selection{ .selection{
border-radius: 0.3rem; border-radius: 0.3rem;
@ -2265,13 +2364,13 @@ smSelect.innerHTML = `
-ms-grid-columns: 1fr auto; -ms-grid-columns: 1fr auto;
grid-template-columns: 1fr auto; grid-template-columns: 1fr auto;
grid-template-areas: 'heading heading' '. .'; grid-template-areas: 'heading heading' '. .';
padding: 0.4rem 0.8rem; padding: var(--padding,0.6rem 0.8rem);
background: rgba(var(--text-color), 0.06); background: rgba(var(--text-color), 0.06);
border: solid 1px rgba(var(--text-color), 0.2);
-webkit-box-align: center; -webkit-box-align: center;
-ms-flex-align: center; -ms-flex-align: center;
align-items: center; align-items: center;
outline: none; outline: none;
z-index: 2;
} }
.selection:focus{ .selection:focus{
-webkit-box-shadow: 0 0 0 0.1rem var(--accent-color); -webkit-box-shadow: 0 0 0 0.1rem var(--accent-color);
@ -2285,6 +2384,7 @@ smSelect.innerHTML = `
} }
.options{ .options{
top: 100%; top: 100%;
padding: var(--options-padding, 0.3rem);
margin-top: 0.2rem; margin-top: 0.2rem;
overflow: hidden auto; overflow: hidden auto;
position: absolute; position: absolute;
@ -2297,11 +2397,11 @@ smSelect.innerHTML = `
-ms-flex-direction: column; -ms-flex-direction: column;
flex-direction: column; flex-direction: column;
min-width: var(--min-width); min-width: var(--min-width);
max-height: var(--max-height); max-height: var(--max-height, auto);
background: rgba(var(--background-color), 1); background: rgba(var(--background-color), 1);
border: solid 1px rgba(var(--text-color), 0.2); border: solid 1px rgba(var(--text-color), 0.2);
border-radius: 0.3rem; border-radius: var(--border-radius, 0.5rem);
z-index: 2; z-index: 1;
-webkit-box-shadow: 0.4rem 0.8rem 1.2rem #00000030; -webkit-box-shadow: 0.4rem 0.8rem 1.2rem #00000030;
box-shadow: 0.4rem 0.8rem 1.2rem #00000030; box-shadow: 0.4rem 0.8rem 1.2rem #00000030;
} }
@ -2328,7 +2428,7 @@ smSelect.innerHTML = `
} }
} }
</style> </style>
<div class="select" > <div class="select">
<div class="selection"> <div class="selection">
<div class="selected-option-text"></div> <div class="selected-option-text"></div>
<svg class="icon toggle" 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 13.172l4.95-4.95 1.414 1.414L12 16 5.636 9.636 7.05 8.222z"/></svg> <svg class="icon toggle" 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 13.172l4.95-4.95 1.414 1.414L12 16 5.636 9.636 7.05 8.222z"/></svg>
@ -2344,6 +2444,7 @@ customElements.define('sm-select', class extends HTMLElement {
mode: 'open' mode: 'open'
}).append(smSelect.content.cloneNode(true)) }).append(smSelect.content.cloneNode(true))
this.focusIn = this.focusIn.bind(this)
this.reset = this.reset.bind(this) this.reset = this.reset.bind(this)
this.open = this.open.bind(this) this.open = this.open.bind(this)
this.collapse = this.collapse.bind(this) this.collapse = this.collapse.bind(this)
@ -2356,6 +2457,7 @@ customElements.define('sm-select', class extends HTMLElement {
this.availableOptions this.availableOptions
this.previousOption this.previousOption
this.isOpen = false; this.isOpen = false;
this.label = ''
this.slideDown = [{ this.slideDown = [{
transform: `translateY(-0.5rem)`, transform: `translateY(-0.5rem)`,
opacity: 0 opacity: 0
@ -2386,13 +2488,24 @@ customElements.define('sm-select', class extends HTMLElement {
this.selectedOptionText = this.shadowRoot.querySelector('.selected-option-text') this.selectedOptionText = this.shadowRoot.querySelector('.selected-option-text')
} }
static get observedAttributes() { static get observedAttributes() {
return ['value', 'disabled'] return ['disabled', 'label']
} }
get value() { get value() {
return this.getAttribute('value') return this.getAttribute('value')
} }
set value(val) { set value(val) {
this.setAttribute('value', val) const selectedOption = this.availableOptions.find(option => option.getAttribute('value') === val)
if (selectedOption) {
this.setAttribute('value', val)
this.selectedOptionText.textContent = `${this.label}${selectedOption.textContent}`;
if (this.previousOption) {
this.previousOption.classList.remove('check-selected')
}
selectedOption.classList.add('check-selected')
this.previousOption = selectedOption
} else {
console.warn(`There is no option with ${val} as value`)
}
} }
reset(fire = true) { reset(fire = true) {
@ -2403,7 +2516,7 @@ customElements.define('sm-select', class extends HTMLElement {
} }
firstElement.classList.add('check-selected') firstElement.classList.add('check-selected')
this.value = firstElement.getAttribute('value') this.value = firstElement.getAttribute('value')
this.selectedOptionText.textContent = firstElement.textContent this.selectedOptionText.textContent = `${this.label}${firstElement.textContent}`
this.previousOption = firstElement; this.previousOption = firstElement;
if (fire) { if (fire) {
this.fireEvent() this.fireEvent()
@ -2411,6 +2524,10 @@ customElements.define('sm-select', class extends HTMLElement {
} }
} }
focusIn() {
this.selection.focus()
}
open() { open() {
this.optionList.classList.remove('hide') this.optionList.classList.remove('hide')
this.optionList.animate(this.slideDown, this.animationOptions) this.optionList.animate(this.slideDown, this.animationOptions)
@ -2444,7 +2561,7 @@ customElements.define('sm-select', class extends HTMLElement {
} }
handleOptionsNavigation(e) { handleOptionsNavigation(e) {
if (e.code === 'ArrowUp') { if (e.key === 'ArrowUp') {
e.preventDefault() e.preventDefault()
if (document.activeElement.previousElementSibling) { if (document.activeElement.previousElementSibling) {
document.activeElement.previousElementSibling.focus() document.activeElement.previousElementSibling.focus()
@ -2452,7 +2569,7 @@ customElements.define('sm-select', class extends HTMLElement {
this.availableOptions[this.availableOptions.length - 1].focus() this.availableOptions[this.availableOptions.length - 1].focus()
} }
} }
else if (e.code === 'ArrowDown') { else if (e.key === 'ArrowDown') {
e.preventDefault() e.preventDefault()
if (document.activeElement.nextElementSibling) { if (document.activeElement.nextElementSibling) {
document.activeElement.nextElementSibling.focus() document.activeElement.nextElementSibling.focus()
@ -2464,13 +2581,7 @@ customElements.define('sm-select', class extends HTMLElement {
handleOptionSelection(e) { handleOptionSelection(e) {
if (this.previousOption !== document.activeElement) { if (this.previousOption !== document.activeElement) {
this.value = document.activeElement.getAttribute('value') this.value = document.activeElement.getAttribute('value')
this.selectedOptionText.textContent = document.activeElement.textContent;
this.fireEvent() this.fireEvent()
if (this.previousOption) {
this.previousOption.classList.remove('check-selected')
}
document.activeElement.classList.add('check-selected')
this.previousOption = document.activeElement
} }
} }
handleClick(e) { handleClick(e) {
@ -2484,12 +2595,12 @@ customElements.define('sm-select', class extends HTMLElement {
} }
handleKeydown(e) { handleKeydown(e) {
if (e.target === this) { if (e.target === this) {
if (this.isOpen && e.code === 'ArrowDown') { if (this.isOpen && e.key === 'ArrowDown') {
e.preventDefault() e.preventDefault()
this.availableOptions[0].focus() this.availableOptions[0].focus()
this.handleOptionSelection(e) this.handleOptionSelection(e)
} }
else if (e.code === 'Enter' || e.code === 'Space') { else if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault() e.preventDefault()
this.toggle() this.toggle()
} }
@ -2497,7 +2608,7 @@ customElements.define('sm-select', class extends HTMLElement {
else { else {
this.handleOptionsNavigation(e) this.handleOptionsNavigation(e)
this.handleOptionSelection(e) this.handleOptionSelection(e)
if (e.code === 'Enter' || e.code === 'Space') { if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault() e.preventDefault()
this.collapse() this.collapse()
} }
@ -2534,6 +2645,8 @@ customElements.define('sm-select', class extends HTMLElement {
} else { } else {
this.selection.setAttribute('tabindex', '0') this.selection.setAttribute('tabindex', '0')
} }
} else if (name === 'label') {
this.label = this.hasAttribute('label') ? `${this.getAttribute('label')} ` : ''
} }
} }
}) })
@ -2562,11 +2675,12 @@ smOption.innerHTML = `
width: 100%; width: 100%;
gap: 0.5rem; gap: 0.5rem;
grid-template-columns: max-content minmax(0, 1fr); grid-template-columns: max-content minmax(0, 1fr);
padding: 0.8rem 1.2rem; padding: var(--padding, 0.6rem 1rem);
cursor: pointer; cursor: pointer;
white-space: nowrap; white-space: nowrap;
outline: none; outline: none;
user-select: none; user-select: none;
border-radius: var(--border-radius, 0.3rem);
} }
:host(:focus){ :host(:focus){
outline: none; outline: none;

View File

@ -1,8 +1,7 @@
* { * {
padding: 0; padding: 0;
margin: 0; margin: 0;
-webkit-box-sizing: border-box; box-sizing: border-box;
box-sizing: border-box;
font-family: "Roboto", sans-serif; font-family: "Roboto", sans-serif;
} }
@ -68,8 +67,7 @@ a:where([class]) {
text-decoration: none; text-decoration: none;
} }
a:where([class]):focus-visible { a:where([class]):focus-visible {
-webkit-box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset; box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset;
box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset;
} }
a { a {
@ -83,24 +81,19 @@ button,
-ms-user-select: none; -ms-user-select: none;
user-select: none; user-select: none;
position: relative; position: relative;
display: -webkit-inline-box;
display: -ms-inline-flexbox;
display: inline-flex; display: inline-flex;
border: none; border: none;
background-color: transparent; background-color: transparent;
overflow: hidden; overflow: hidden;
color: inherit; color: inherit;
cursor: pointer; cursor: pointer;
-webkit-transition: -webkit-transform 0.3s;
transition: -webkit-transform 0.3s;
transition: transform 0.3s; transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
-webkit-box-align: center; align-items: center;
-ms-flex-align: center;
align-items: center;
font-size: 0.9rem; font-size: 0.9rem;
font-weight: 500; font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.02em;
} }
.button { .button {
@ -109,9 +102,7 @@ button,
border-radius: 0.3rem; border-radius: 0.3rem;
background-color: rgba(var(--text-color), 0.06); background-color: rgba(var(--text-color), 0.06);
color: rgba(var(--text-color), 0.8); color: rgba(var(--text-color), 0.8);
-webkit-box-pack: center; justify-content: center;
-ms-flex-pack: center;
justify-content: center;
} }
.button--primary { .button--primary {
background-color: var(--accent-color); background-color: var(--accent-color);
@ -141,6 +132,10 @@ sm-input {
} }
sm-button { sm-button {
text-transform: uppercase;
letter-spacing: 0.02em;
font-weight: 700;
font-size: 0.9rem;
--padding: 0.7rem 1rem; --padding: 0.7rem 1rem;
} }
sm-button[variant=primary] .icon { sm-button[variant=primary] .icon {
@ -149,9 +144,6 @@ sm-button[variant=primary] .icon {
sm-button[disabled] .icon { sm-button[disabled] .icon {
fill: rgba(var(--text-color), 0.6); fill: rgba(var(--text-color), 0.6);
} }
sm-button.uppercase {
letter-spacing: 0.05em;
}
sm-button.danger { sm-button.danger {
--background: var(--danger-color); --background: var(--danger-color);
color: rgba(var(--background-color), 1); color: rgba(var(--background-color), 1);
@ -162,8 +154,6 @@ ul {
} }
.flex { .flex {
display: -webkit-box;
display: -ms-flexbox;
display: flex; display: flex;
} }
@ -230,8 +220,6 @@ ul {
} }
.flex { .flex {
display: -webkit-box;
display: -ms-flexbox;
display: flex; display: flex;
} }
@ -272,15 +260,11 @@ ul {
} }
.align-start { .align-start {
-webkit-box-align: start; align-items: flex-start;
-ms-flex-align: start;
align-items: flex-start;
} }
.align-center { .align-center {
-webkit-box-align: center; align-items: center;
-ms-flex-align: center;
align-items: center;
} }
.text-center { .text-center {
@ -288,15 +272,11 @@ ul {
} }
.justify-start { .justify-start {
-webkit-box-pack: start; justify-content: start;
-ms-flex-pack: start;
justify-content: start;
} }
.justify-center { .justify-center {
-webkit-box-pack: center; justify-content: center;
-ms-flex-pack: center;
justify-content: center;
} }
.justify-right { .justify-right {
@ -304,8 +284,7 @@ ul {
} }
.align-self-center { .align-self-center {
-ms-flex-item-align: center; align-self: center;
align-self: center;
} }
.justify-self-center { .justify-self-center {
@ -321,16 +300,11 @@ ul {
} }
.direction-column { .direction-column {
-webkit-box-orient: vertical; flex-direction: column;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
} }
.space-between { .space-between {
-webkit-box-pack: justify; justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
} }
.w-100 { .w-100 {
@ -340,20 +314,16 @@ ul {
.interact { .interact {
position: relative; position: relative;
cursor: pointer; cursor: pointer;
-webkit-transition: -webkit-transform 0.3s;
transition: -webkit-transform 0.3s;
transition: transform 0.3s; transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
} }
.empty-state { .empty-state {
display: grid; display: grid;
-webkit-box-pack: center; justify-content: center;
-ms-flex-pack: center;
justify-content: center;
text-align: center; text-align: center;
width: 100%; width: 100%;
max-width: none;
padding: 1.5rem; padding: 1.5rem;
} }
@ -396,10 +366,7 @@ ul {
#confirmation_popup, #confirmation_popup,
#prompt_popup { #prompt_popup {
-webkit-box-orient: vertical; flex-direction: column;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
} }
#confirmation_popup h4, #confirmation_popup h4,
#prompt_popup h4 { #prompt_popup h4 {
@ -428,8 +395,7 @@ ul {
button:active, button:active,
.button:active, .button:active,
.interact:active { .interact:active {
-webkit-transform: scale(0.96); transform: scale(0.96);
transform: scale(0.96);
} }
.popup__header { .popup__header {
@ -437,9 +403,7 @@ button:active,
gap: 0.5rem; gap: 0.5rem;
width: 100%; width: 100%;
padding: 0 1.5rem 0 0.5rem; padding: 0 1.5rem 0 0.5rem;
-webkit-box-align: center; align-items: center;
-ms-flex-align: center;
align-items: center;
grid-template-columns: auto 1fr auto; grid-template-columns: auto 1fr auto;
} }
@ -452,15 +416,12 @@ button:active,
padding: 1.5rem; padding: 1.5rem;
} }
#main_page > section:nth-of-type(1) { #main_page > section:nth-of-type(1) {
-ms-flex-line-pack: start; align-content: flex-start;
align-content: flex-start;
} }
.logo { .logo {
display: grid; display: grid;
-webkit-box-align: center; align-items: center;
-ms-flex-align: center;
align-items: center;
width: 100%; width: 100%;
grid-template-columns: auto 1fr; grid-template-columns: auto 1fr;
gap: 0 0.3rem; gap: 0 0.3rem;
@ -479,12 +440,8 @@ button:active,
} }
details summary { details summary {
display: -webkit-box;
display: -ms-flexbox;
display: flex; display: flex;
-webkit-box-pack: justify; justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;
-ms-user-select: none; -ms-user-select: none;
@ -495,8 +452,7 @@ details[open] > summary {
margin-bottom: 1rem; margin-bottom: 1rem;
} }
details[open] > summary .icon { details[open] > summary .icon {
-webkit-transform: rotate(180deg); transform: rotate(180deg);
transform: rotate(180deg);
} }
strip-select { strip-select {
@ -557,17 +513,14 @@ sm-checkbox {
padding: 1.5rem 0; padding: 1.5rem 0;
} }
#landing > .grid { #landing > .grid {
-ms-flex-line-pack: start; align-content: flex-start;
align-content: flex-start;
text-align: center; text-align: center;
gap: 1rem; gap: 1rem;
} }
#sign_up { #sign_up {
grid-template-rows: auto 1fr; grid-template-rows: auto 1fr;
-webkit-box-align: center; align-items: center;
-ms-flex-align: center;
align-items: center;
} }
#sign_up section { #sign_up section {
margin-top: -6rem; margin-top: -6rem;
@ -595,11 +548,8 @@ sm-checkbox {
#home { #home {
height: 100%; height: 100%;
display: grid; display: grid;
-webkit-box-align: start; align-items: flex-start;
-ms-flex-align: start; align-content: flex-start;
align-items: flex-start;
-ms-flex-line-pack: start;
align-content: flex-start;
grid-template-columns: minmax(0, 1fr); grid-template-columns: minmax(0, 1fr);
} }
@ -608,13 +558,11 @@ sm-checkbox {
} }
#main_header { #main_header {
margin-top: 2rem; margin-top: 1.5rem;
margin-bottom: 1rem; margin-bottom: 1rem;
display: grid; display: grid;
gap: 1rem; gap: 1rem;
-webkit-box-align: center; align-items: center;
-ms-flex-align: center;
align-items: center;
grid-template-columns: 1fr auto auto; grid-template-columns: 1fr auto auto;
grid-column: 1/-1; grid-column: 1/-1;
} }
@ -634,15 +582,12 @@ sm-checkbox {
#trade_form, #trade_form,
#login_form { #login_form {
-ms-flex-item-align: start; align-self: flex-start;
align-self: flex-start;
padding: 1rem 1.5rem 1.5rem 1.5rem; padding: 1rem 1.5rem 1.5rem 1.5rem;
} }
.quantity-selector .button { .quantity-selector .button {
-webkit-box-flex: 1; flex: 1;
-ms-flex: 1;
flex: 1;
padding: 0.5rem 0.6rem; padding: 0.5rem 0.6rem;
margin-left: 0.5rem; margin-left: 0.5rem;
} }
@ -697,9 +642,7 @@ sm-checkbox {
-moz-user-select: none; -moz-user-select: none;
-ms-user-select: none; -ms-user-select: none;
user-select: none; user-select: none;
-webkit-box-align: center; align-items: center;
-ms-flex-align: center;
align-items: center;
gap: 0.5rem; gap: 0.5rem;
padding: 0.5rem 1.5rem 0.5rem 0.5rem; padding: 0.5rem 1.5rem 0.5rem 0.5rem;
grid-template-columns: -webkit-min-content repeat(3, 1fr) -webkit-min-content; grid-template-columns: -webkit-min-content repeat(3, 1fr) -webkit-min-content;
@ -737,9 +680,7 @@ sm-checkbox {
} }
.cancel-order { .cancel-order {
-webkit-box-align: center; align-items: center;
-ms-flex-align: center;
align-items: center;
padding: 0.4rem 0.6rem; padding: 0.4rem 0.6rem;
} }
.cancel-order span { .cancel-order span {
@ -786,8 +727,7 @@ sm-checkbox {
#user_section { #user_section {
gap: 1.5rem; gap: 1.5rem;
padding: 1.5rem; padding: 1.5rem;
-ms-flex-line-pack: start; align-content: flex-start;
align-content: flex-start;
} }
.wallet_actions__wrapper { .wallet_actions__wrapper {
@ -796,9 +736,7 @@ sm-checkbox {
margin-top: 0.5rem; margin-top: 0.5rem;
} }
.wallet_actions__wrapper .button { .wallet_actions__wrapper .button {
-webkit-box-flex: 1; flex: 1;
-ms-flex: 1;
flex: 1;
} }
.label { .label {
@ -809,9 +747,7 @@ sm-checkbox {
.balance-card { .balance-card {
display: grid; display: grid;
-webkit-box-align: center; align-items: center;
-ms-flex-align: center;
align-items: center;
gap: 0.3rem 1rem; gap: 0.3rem 1rem;
padding: 0.5rem 0; padding: 0.5rem 0;
border-radius: 0.5rem; border-radius: 0.5rem;
@ -824,14 +760,9 @@ sm-checkbox {
grid-template-columns: auto 1fr auto; grid-template-columns: auto 1fr auto;
} }
.balance-card__icon { .balance-card__icon {
display: -webkit-box;
display: -ms-flexbox;
display: flex; display: flex;
-ms-flex-line-pack: center; align-content: center;
align-content: center; justify-content: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
padding: 0.6rem; padding: 0.6rem;
border-radius: 0.8rem; border-radius: 0.8rem;
background-color: var(--accent-color--light); background-color: var(--accent-color--light);
@ -855,14 +786,10 @@ sm-checkbox {
} }
#wallet_result { #wallet_result {
-webkit-box-pack: center; justify-content: center;
-ms-flex-pack: center;
justify-content: center;
text-align: center; text-align: center;
} }
#wallet_result__icon { #wallet_result__icon {
display: -webkit-box;
display: -ms-flexbox;
display: flex; display: flex;
padding: 1rem; padding: 1rem;
border-radius: 50%; border-radius: 50%;
@ -887,46 +814,35 @@ sm-checkbox {
@-webkit-keyframes pop-up { @-webkit-keyframes pop-up {
from { from {
-webkit-transform: translateY(3rem) scale(0.5); transform: translateY(3rem) scale(0.5);
transform: translateY(3rem) scale(0.5);
opacity: 0; opacity: 0;
} }
to { to {
-webkit-transform: translateY(0) scale(1); transform: translateY(0) scale(1);
transform: translateY(0) scale(1);
opacity: 1; opacity: 1;
} }
} }
@keyframes pop-up { @keyframes pop-up {
from { from {
-webkit-transform: translateY(3rem) scale(0.5); transform: translateY(3rem) scale(0.5);
transform: translateY(3rem) scale(0.5);
opacity: 0; opacity: 0;
} }
to { to {
-webkit-transform: translateY(0) scale(1); transform: translateY(0) scale(1);
transform: translateY(0) scale(1);
opacity: 1; opacity: 1;
} }
} }
.stateful-button-wrapper { .stateful-button-wrapper {
display: -webkit-box;
display: -ms-flexbox;
display: flex; display: flex;
position: relative; position: relative;
-webkit-box-pack: center; justify-content: center;
-ms-flex-pack: center; align-items: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
} }
.stateful-button-wrapper sm-button, .stateful-button-wrapper sm-button,
.stateful-button-wrapper slide-button { .stateful-button-wrapper slide-button {
width: 100%; width: 100%;
z-index: 1; z-index: 1;
-webkit-transition: -webkit-clip-path 0.3s;
transition: -webkit-clip-path 0.3s; transition: -webkit-clip-path 0.3s;
transition: clip-path 0.3s; transition: clip-path 0.3s;
transition: clip-path 0.3s, -webkit-clip-path 0.3s; transition: clip-path 0.3s, -webkit-clip-path 0.3s;
@ -946,15 +862,9 @@ sm-checkbox {
.stateful-result { .stateful-result {
overflow: hidden; overflow: hidden;
position: absolute; position: absolute;
display: -webkit-box;
display: -ms-flexbox;
display: flex; display: flex;
-webkit-box-pack: center; justify-content: center;
-ms-flex-pack: center; align-items: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
height: 100%; height: 100%;
width: 100%; width: 100%;
left: 0; left: 0;
@ -997,26 +907,22 @@ sm-checkbox {
@-webkit-keyframes pop { @-webkit-keyframes pop {
from { from {
opacity: 0; opacity: 0;
-webkit-transform: translateY(2rem); transform: translateY(2rem);
transform: translateY(2rem);
} }
to { to {
opacity: 1; opacity: 1;
-webkit-transform: translateY(0); transform: translateY(0);
transform: translateY(0);
} }
} }
@keyframes pop { @keyframes pop {
from { from {
opacity: 0; opacity: 0;
-webkit-transform: translateY(2rem); transform: translateY(2rem);
transform: translateY(2rem);
} }
to { to {
opacity: 1; opacity: 1;
-webkit-transform: translateY(0); transform: translateY(0);
transform: translateY(0);
} }
} }
@-webkit-keyframes ripple-reveal { @-webkit-keyframes ripple-reveal {
@ -1057,24 +963,14 @@ sm-checkbox {
} }
.bottom_nav__item { .bottom_nav__item {
display: -webkit-box;
display: -ms-flexbox;
display: flex; display: flex;
-webkit-box-orient: vertical; flex-direction: column;
-webkit-box-direction: normal; align-items: center;
-ms-flex-direction: column; flex: 1;
flex-direction: column;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
padding: 0.5rem 0; padding: 0.5rem 0;
} }
.bottom_nav__item .item__title, .bottom_nav__item .item__title,
.bottom_nav__item .icon { .bottom_nav__item .icon {
-webkit-transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
} }
.bottom_nav__item .item__title { .bottom_nav__item .item__title {
@ -1088,13 +984,11 @@ sm-checkbox {
} }
.bottom_nav__item--active .item__title { .bottom_nav__item--active .item__title {
color: var(--accent-color); color: var(--accent-color);
-webkit-transform: translateY(100%); transform: translateY(100%);
transform: translateY(100%);
opacity: 0; opacity: 0;
} }
.bottom_nav__item--active .icon { .bottom_nav__item--active .icon {
-webkit-transform: translateY(50%) scale(1.2); transform: translateY(50%) scale(1.2);
transform: translateY(50%) scale(1.2);
fill: var(--accent-color); fill: var(--accent-color);
} }
@ -1196,10 +1090,7 @@ sm-checkbox {
.interact, .interact,
button { button {
-webkit-transition: background-color 0.3s, -webkit-transform 0.3s;
transition: background-color 0.3s, -webkit-transform 0.3s;
transition: background-color 0.3s, transform 0.3s; transition: background-color 0.3s, transform 0.3s;
transition: background-color 0.3s, transform 0.3s, -webkit-transform 0.3s;
} }
.interact:hover, .interact:hover,
button:hover { button:hover {
@ -1212,19 +1103,14 @@ button:hover {
} }
.order-card .cancel-order .icon, .order-card .cancel-order .icon,
.order-card .cancel-order span { .order-card .cancel-order span {
-webkit-transition: opacity 0.3s, -webkit-transform 0.3s;
transition: opacity 0.3s, -webkit-transform 0.3s;
transition: opacity 0.3s, transform 0.3s; transition: opacity 0.3s, transform 0.3s;
transition: opacity 0.3s, transform 0.3s, -webkit-transform 0.3s;
} }
.order-card .cancel-order .icon { .order-card .cancel-order .icon {
opacity: 0; opacity: 0;
-webkit-transform: translateX(100%); transform: translateX(100%);
transform: translateX(100%);
} }
.order-card .cancel-order span { .order-card .cancel-order span {
-webkit-transform: translateX(100%); transform: translateX(100%);
transform: translateX(100%);
opacity: 0; opacity: 0;
} }
.order-card:hover .cancel-order .icon, .order-card:focus-within .cancel-order .icon { .order-card:hover .cancel-order .icon, .order-card:focus-within .cancel-order .icon {
@ -1233,13 +1119,11 @@ button:hover {
.order-card .cancel-order:hover .icon, .order-card .cancel-order:hover .icon,
.order-card .cancel-order:hover span { .order-card .cancel-order:hover span {
opacity: 1; opacity: 1;
-webkit-transform: translateX(0); transform: translateX(0);
transform: translateX(0);
} }
.transaction-card button { .transaction-card button {
opacity: 0; opacity: 0;
-webkit-transition: opacity 0.3s;
transition: opacity 0.3s; transition: opacity 0.3s;
} }
.transaction-card:hover button { .transaction-card:hover button {

File diff suppressed because one or more lines are too long

View File

@ -92,7 +92,9 @@ button,
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
align-items: center; align-items: center;
font-size: 0.9rem; font-size: 0.9rem;
font-weight: 500; font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.02em;
} }
.button { .button {
white-space: nowrap; white-space: nowrap;
@ -114,13 +116,16 @@ button:disabled {
a:any-link:focus-visible { a:any-link:focus-visible {
outline: rgba(var(--text-color), 1) 0.1rem solid; outline: rgba(var(--text-color), 1) 0.1rem solid;
} }
sm-input { sm-input {
font-size: 0.9rem; font-size: 0.9rem;
--border-radius: 0.3rem; --border-radius: 0.3rem;
--background: var(--accent-color--light); --background: var(--accent-color--light);
} }
sm-button { sm-button {
text-transform: uppercase;
letter-spacing: 0.02em;
font-weight: 700;
font-size: 0.9rem;
--padding: 0.7rem 1rem; --padding: 0.7rem 1rem;
&[variant="primary"] { &[variant="primary"] {
.icon { .icon {
@ -133,9 +138,6 @@ sm-button {
fill: rgba(var(--text-color), 0.6); fill: rgba(var(--text-color), 0.6);
} }
} }
&.uppercase {
letter-spacing: 0.05em;
}
&.danger { &.danger {
--background: var(--danger-color); --background: var(--danger-color);
color: rgba(var(--background-color), 1); color: rgba(var(--background-color), 1);
@ -315,6 +317,7 @@ ul {
justify-content: center; justify-content: center;
text-align: center; text-align: center;
width: 100%; width: 100%;
max-width: none;
padding: 1.5rem; padding: 1.5rem;
} }
@ -534,7 +537,7 @@ sm-checkbox {
} }
#main_header { #main_header {
margin-top: 2rem; margin-top: 1.5rem;
margin-bottom: 1rem; margin-bottom: 1rem;
display: grid; display: grid;
gap: 1rem; gap: 1rem;

View File

@ -57,7 +57,7 @@
</div> </div>
</div> </div>
<theme-toggle></theme-toggle> <theme-toggle></theme-toggle>
<button onclick="showPopup('user_popup')"> <button id="user_popup_button" class="hide-completely" onclick="showPopup('user_popup')">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" height="24px" viewBox="0 0 24 24" width="24px" <svg xmlns="http://www.w3.org/2000/svg" class="icon" height="24px" viewBox="0 0 24 24" width="24px"
fill="#000000"> fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" /> <path d="M0 0h24v24H0V0z" fill="none" />
@ -66,7 +66,7 @@
</svg> </svg>
</button> </button>
</header> </header>
<section id="dashboard" class="card mobile-page hide-on-mobile"> <section id="dashboard" class="card mobile-page">
<sm-form id="login_form" class="hide-"> <sm-form id="login_form" class="hide-">
<div class="grid gap-0-5"> <div class="grid gap-0-5">
<h4>Login</h4> <h4>Login</h4>
@ -645,46 +645,12 @@
}; };
} }
// Limits the rate of function execution
function throttle(func, delay) {
// If setTimeout is already scheduled, no need to do anything
if (timerId) {
return;
}
// Schedule a setTimeout after delay seconds
timerId = setTimeout(function () {
func();
// Once setTimeout function execution is finished, timerId = undefined so that in
// the next scroll event function execution can be scheduled by the setTimeout
timerId = undefined;
}, delay);
}
class Stack {
constructor() {
this.items = [];
}
push(element) {
this.items.push(element);
}
pop() {
if (this.items.length == 0)
return "Underflow";
return this.items.pop();
}
peek() {
return this.items[this.items.length - 1];
}
}
let popupStack = new Stack()
let zIndex = 10 let zIndex = 10
// function required for popups or modals to appear // function required for popups or modals to appear
function showPopup(popupId, pinned) { function showPopup(popupId, pinned) {
zIndex++ zIndex++
getRef(popupId).setAttribute('style', `z-index: ${zIndex}`) getRef(popupId).setAttribute('style', `z-index: ${zIndex}`)
popupStack = getRef(popupId).show({ pinned, popupStack }) getRef(popupId).show({ pinned })
return getRef(popupId); return getRef(popupId);
} }
@ -819,7 +785,7 @@
document.body.classList.remove('hide-completely') document.body.classList.remove('hide-completely')
document.querySelectorAll('sm-input[data-private-key]').forEach(input => input.customValidation = floCrypto.getPubKeyHex) document.querySelectorAll('sm-input[data-private-key]').forEach(input => input.customValidation = floCrypto.getPubKeyHex)
document.addEventListener('keyup', (e) => { document.addEventListener('keyup', (e) => {
if (e.code === 'Escape') { if (e.key === 'Escape') {
hidePopup() hidePopup()
} }
}) })
@ -1435,7 +1401,7 @@
}) })
} else { } else {
transactions.forEach(transaction => { transactions.forEach(transaction => {
const {asset, quantity, unitValue, tx_time, buyer, seller } = transaction const { asset, quantity, unitValue, tx_time, buyer, seller } = transaction
let type, other; let type, other;
if (seller === proxy.userID) { if (seller === proxy.userID) {
type = 'Sold'; type = 'Sold';
@ -1570,17 +1536,17 @@
this.private = null; this.private = null;
this.public = null; this.public = null;
}, },
get sinkID(){ get sinkID() {
return getRef("sink_id").value; return getRef("sink_id").value;
}, },
set userID(id){ set userID(id) {
localStorage.setItem("exchange-user_ID", id); localStorage.setItem("exchange-user_ID", id);
this.user = id; this.user = id;
}, },
get userID(){ get userID() {
if(this.user) if (this.user)
return this.user; return this.user;
else{ else {
let id = localStorage.getItem('exchange-user_ID'); let id = localStorage.getItem('exchange-user_ID');
return id ? this.user = id : undefined; return id ? this.user = id : undefined;
} }
@ -1636,14 +1602,14 @@
function updateRate(init = false) { function updateRate(init = false) {
getRates().then(rates => { getRates().then(rates => {
console.debug(rates); console.debug(rates);
if(init){ if (init) {
let assetList = getRef('get_asset'); let assetList = getRef('get_asset');
let walletList = getRef('wallet_asset_selector'); let walletList = getRef('wallet_asset_selector');
let c = document.createElement('sm-option'); let c = document.createElement('sm-option');
c.setAttribute('value', floGlobals.currency); c.setAttribute('value', floGlobals.currency);
c.innerText = floGlobals.currency; c.innerText = floGlobals.currency;
walletList.appendChild(c); walletList.appendChild(c);
for(let asset in rates){ for (let asset in rates) {
let e = document.createElement('sm-option'); let e = document.createElement('sm-option');
e.setAttribute('value', asset); e.setAttribute('value', asset);
e.innerText = asset; e.innerText = asset;
@ -1659,9 +1625,9 @@
} }
function refresh(init = false) { function refresh(init = false) {
if (init){ if (init) {
console.info("init"); console.info("init");
if(!proxy.userID){ if (!proxy.userID) {
getRef('home').classList.remove('signed-in'); getRef('home').classList.remove('signed-in');
getLoginCode().then(response => { getLoginCode().then(response => {
getRef("login_form").classList.remove('hide-completely'); getRef("login_form").classList.remove('hide-completely');
@ -1675,7 +1641,7 @@
console.info("refresh"); console.info("refresh");
updateRate(init); updateRate(init);
renderMarketOrders(); renderMarketOrders();
if(proxy.userID) if (proxy.userID)
account(); account();
} }
@ -1699,6 +1665,7 @@
getAccount(proxy.userID, await proxy.secret).then(acc => { getAccount(proxy.userID, await proxy.secret).then(acc => {
getRef("login_form").classList.add('hide-completely') getRef("login_form").classList.add('hide-completely')
getRef('home').classList.add('signed-in') getRef('home').classList.add('signed-in')
getRef('user_popup_button').classList.remove('hide-completely')
accountDetails = acc accountDetails = acc
console.debug(acc); console.debug(acc);
//Element display //Element display