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/keys*.json
*test*
args/app-config.json

View File

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

View File

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

View File

@ -57,7 +57,7 @@
</div>
</div>
<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"
fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
@ -66,7 +66,7 @@
</svg>
</button>
</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-">
<div class="grid gap-0-5">
<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
// function required for popups or modals to appear
function showPopup(popupId, pinned) {
zIndex++
getRef(popupId).setAttribute('style', `z-index: ${zIndex}`)
popupStack = getRef(popupId).show({ pinned, popupStack })
getRef(popupId).show({ pinned })
return getRef(popupId);
}
@ -819,7 +785,7 @@
document.body.classList.remove('hide-completely')
document.querySelectorAll('sm-input[data-private-key]').forEach(input => input.customValidation = floCrypto.getPubKeyHex)
document.addEventListener('keyup', (e) => {
if (e.code === 'Escape') {
if (e.key === 'Escape') {
hidePopup()
}
})
@ -1435,7 +1401,7 @@
})
} else {
transactions.forEach(transaction => {
const {asset, quantity, unitValue, tx_time, buyer, seller } = transaction
const { asset, quantity, unitValue, tx_time, buyer, seller } = transaction
let type, other;
if (seller === proxy.userID) {
type = 'Sold';
@ -1570,17 +1536,17 @@
this.private = null;
this.public = null;
},
get sinkID(){
get sinkID() {
return getRef("sink_id").value;
},
set userID(id){
set userID(id) {
localStorage.setItem("exchange-user_ID", id);
this.user = id;
},
get userID(){
if(this.user)
get userID() {
if (this.user)
return this.user;
else{
else {
let id = localStorage.getItem('exchange-user_ID');
return id ? this.user = id : undefined;
}
@ -1636,14 +1602,14 @@
function updateRate(init = false) {
getRates().then(rates => {
console.debug(rates);
if(init){
if (init) {
let assetList = getRef('get_asset');
let walletList = getRef('wallet_asset_selector');
let c = document.createElement('sm-option');
c.setAttribute('value', floGlobals.currency);
c.innerText = floGlobals.currency;
walletList.appendChild(c);
for(let asset in rates){
for (let asset in rates) {
let e = document.createElement('sm-option');
e.setAttribute('value', asset);
e.innerText = asset;
@ -1659,9 +1625,9 @@
}
function refresh(init = false) {
if (init){
if (init) {
console.info("init");
if(!proxy.userID){
if (!proxy.userID) {
getRef('home').classList.remove('signed-in');
getLoginCode().then(response => {
getRef("login_form").classList.remove('hide-completely');
@ -1675,7 +1641,7 @@
console.info("refresh");
updateRate(init);
renderMarketOrders();
if(proxy.userID)
if (proxy.userID)
account();
}
@ -1699,6 +1665,7 @@
getAccount(proxy.userID, await proxy.secret).then(acc => {
getRef("login_form").classList.add('hide-completely')
getRef('home').classList.add('signed-in')
getRef('user_popup_button').classList.remove('hide-completely')
accountDetails = acc
console.debug(acc);
//Element display