adding UI for user orders
This commit is contained in:
parent
d1bb6e6d2e
commit
d6df6e523c
@ -2247,8 +2247,9 @@ smSelect.innerHTML = `
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.icon {
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
height: 1.2rem;
|
||||
width: 1.2rem;
|
||||
margin-left: 0.5rem;
|
||||
fill: rgba(var(--text-color), 0.7);
|
||||
}
|
||||
.selected-option-text{
|
||||
@ -2265,7 +2266,7 @@ smSelect.innerHTML = `
|
||||
-ms-grid-columns: 1fr auto;
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-template-areas: 'heading heading' '. .';
|
||||
padding: 0.4rem 1rem;
|
||||
padding: 0.4rem 0.8rem;
|
||||
background: rgba(var(--text-color), 0.06);
|
||||
border: solid 1px rgba(var(--text-color), 0.2);
|
||||
-webkit-box-align: center;
|
||||
@ -2277,9 +2278,6 @@ smSelect.innerHTML = `
|
||||
-webkit-box-shadow: 0 0 0 0.1rem var(--accent-color);
|
||||
box-shadow: 0 0 0 0.1rem var(--accent-color)
|
||||
}
|
||||
.icon{
|
||||
margin-left: 1rem;
|
||||
}
|
||||
:host([align-select="left"]) .options{
|
||||
left: 0;
|
||||
}
|
||||
@ -2558,12 +2556,13 @@ smOption.innerHTML = `
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
min-width: 100%;
|
||||
min-width: max-content;
|
||||
width: 100%;
|
||||
gap: 0.5rem;
|
||||
grid-template-columns: max-content minmax(0, 1fr);
|
||||
padding: 0.8rem 1.2rem;
|
||||
cursor: pointer;
|
||||
overflow-wrap: break-word;
|
||||
white-space: nowrap;
|
||||
outline: none;
|
||||
user-select: none;
|
||||
}
|
||||
@ -2609,3 +2608,584 @@ customElements.define('sm-option', class extends HTMLElement {
|
||||
this.setAttribute('tabindex', '0')
|
||||
}
|
||||
})
|
||||
|
||||
const smCheckbox = document.createElement('template')
|
||||
smCheckbox.innerHTML = `
|
||||
<style>
|
||||
*{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
:host{
|
||||
display: -webkit-inline-box;
|
||||
display: -ms-inline-flexbox;
|
||||
display: inline-flex;
|
||||
--accent-color: #4d2588;
|
||||
--text-color: 17, 17, 17;
|
||||
--background-color: 255, 255, 255;
|
||||
--height: 1.2rem;
|
||||
--width: 1.2rem;
|
||||
--border-radius: 0.2rem;
|
||||
--border-color: rgba(var(--text-color), 0.7);
|
||||
}
|
||||
:host([disabled]) {
|
||||
opacity: 0.6;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
.checkbox {
|
||||
position: relative;
|
||||
display:-webkit-box;
|
||||
display:-ms-flexbox;
|
||||
display:flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
.checkbox:focus-visible{
|
||||
outline: auto;
|
||||
}
|
||||
.checkbox:active .icon,
|
||||
.checkbox:focus-within .icon{
|
||||
box-shadow: 0 0 0 0.1rem var(--accent-color) inset;
|
||||
}
|
||||
|
||||
input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.checkmark {
|
||||
stroke-dashoffset: -65;
|
||||
stroke-dasharray: 65;
|
||||
-webkit-transition: stroke-dashoffset 0.3s;
|
||||
-o-transition: stroke-dashoffset 0.3s;
|
||||
transition: stroke-dashoffset 0.3s;
|
||||
}
|
||||
|
||||
:host([checked]) .checkmark {
|
||||
stroke-dashoffset: 0;
|
||||
stroke: rgba(var(--background-color), 1);
|
||||
}
|
||||
:host([checked]) .icon {
|
||||
background: var(--accent-color);
|
||||
box-shadow: 0 0 0 0.1rem var(--accent-color) inset;
|
||||
}
|
||||
.icon {
|
||||
fill: none;
|
||||
height: var(--height);
|
||||
width: var(--width);
|
||||
padding: 0.1rem;
|
||||
stroke-width: 8;
|
||||
stroke: var(--border-color);
|
||||
overflow: visible;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
-webkit-transition: background 0.3s;
|
||||
-o-transition: background 0.3s;
|
||||
transition: background 0.3s;
|
||||
border-radius: var(--border-radius);
|
||||
box-shadow: 0 0 0 0.1rem var(--border-color) inset;
|
||||
}
|
||||
</style>
|
||||
<label class="checkbox">
|
||||
<svg class="icon" viewBox="0 0 64 64">
|
||||
<path class="checkmark" d="M50.52,19.56,26,44.08,13.48,31.56" />
|
||||
</svg>
|
||||
<slot></slot>
|
||||
</label>`
|
||||
customElements.define('sm-checkbox', class extends HTMLElement {
|
||||
constructor() {
|
||||
super()
|
||||
this.attachShadow({
|
||||
mode: 'open'
|
||||
}).append(smCheckbox.content.cloneNode(true))
|
||||
|
||||
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(val) {
|
||||
if (val) {
|
||||
this.setAttribute('disabled', '')
|
||||
} else {
|
||||
this.removeAttribute('disabled')
|
||||
}
|
||||
}
|
||||
|
||||
get checked() {
|
||||
return this.hasAttribute('checked')
|
||||
}
|
||||
|
||||
set checked(value) {
|
||||
if (value) {
|
||||
this.setAttribute('checked', '')
|
||||
}
|
||||
else {
|
||||
this.removeAttribute('checked')
|
||||
}
|
||||
}
|
||||
|
||||
set value(val) {
|
||||
this.setAttribute('value', val)
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.getAttribute('value')
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.removeAttribute('checked')
|
||||
}
|
||||
|
||||
dispatch() {
|
||||
this.dispatchEvent(new CustomEvent('change', {
|
||||
bubbles: true,
|
||||
composed: true
|
||||
}))
|
||||
}
|
||||
handleKeyDown(e) {
|
||||
if (e.code === "Space") {
|
||||
e.preventDefault()
|
||||
this.click()
|
||||
}
|
||||
}
|
||||
handleClick(e) {
|
||||
this.toggleAttribute('checked')
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
if (!this.hasAttribute('disabled')) {
|
||||
this.setAttribute('tabindex', '0')
|
||||
}
|
||||
this.setAttribute('role', 'checkbox')
|
||||
if (!this.hasAttribute('checked')) {
|
||||
this.setAttribute('aria-checked', 'false')
|
||||
}
|
||||
this.addEventListener('keydown', this.handleKeyDown)
|
||||
this.addEventListener('click', this.handleClick)
|
||||
}
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
if (oldValue !== newValue) {
|
||||
if (name === 'checked') {
|
||||
this.setAttribute('aria-checked', this.hasAttribute('checked'))
|
||||
this.dispatch()
|
||||
}
|
||||
else if (name === 'disabled') {
|
||||
if (this.hasAttribute('disabled')) {
|
||||
this.removeAttribute('tabindex')
|
||||
}
|
||||
else {
|
||||
this.setAttribute('tabindex', '0')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
disconnectedCallback() {
|
||||
this.removeEventListener('keydown', this.handleKeyDown)
|
||||
this.removeEventListener('change', this.handleClick)
|
||||
}
|
||||
})
|
||||
const smTabHeader = document.createElement('template')
|
||||
smTabHeader.innerHTML = `
|
||||
<style>
|
||||
*{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
:host{
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
--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{
|
||||
position: relative;
|
||||
display: -ms-grid;
|
||||
display: grid;
|
||||
width: 100%;
|
||||
}
|
||||
.tab-header{
|
||||
display: -ms-grid;
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
justify-content: var(--justify-content);
|
||||
gap: var(--gap);
|
||||
position: relative;
|
||||
overflow: auto hidden;
|
||||
max-width: 100%;
|
||||
scrollbar-width: 0;
|
||||
}
|
||||
.indicator{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
height: 0.15rem;
|
||||
border-radius: 1rem 1rem 0 0;
|
||||
background: var(--accent-color);
|
||||
-webkit-transition: width 0.3s, -webkit-transform 0.3s;
|
||||
transition: width 0.3s, -webkit-transform 0.3s;
|
||||
-o-transition: transform 0.3s, width 0.3s;
|
||||
transition: transform 0.3s, width 0.3s;
|
||||
transition: transform 0.3s, width 0.3s, -webkit-transform 0.3s;
|
||||
pointer-events: none;
|
||||
}
|
||||
:host([variant="tab"]) .indicator{
|
||||
height: 100%;
|
||||
border-radius: var(--tab-indicator-border-radius);
|
||||
}
|
||||
:host([variant="tab"]) .tab-header{
|
||||
border-bottom: none;
|
||||
}
|
||||
.hide-completely{
|
||||
display: none;
|
||||
}
|
||||
:host([variant="tab"]) .tab-header{
|
||||
gap: 0.2rem;
|
||||
display: -ms-inline-grid;
|
||||
display: inline-grid;
|
||||
justify-self: flex-start;
|
||||
border-radius: 0.3rem;
|
||||
}
|
||||
:host([variant="tab"]) slot::slotted(.active){
|
||||
color: rgba(var(--background-color), 1);
|
||||
}
|
||||
slot::slotted(.active){
|
||||
color: var(--accent-color);
|
||||
opacity: 1;
|
||||
}
|
||||
@media (any-hover: none){
|
||||
.tab-header::-webkit-scrollbar-track {
|
||||
-webkit-box-shadow: none !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
.tab-header::-webkit-scrollbar {
|
||||
height: 0;
|
||||
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">
|
||||
<slot></slot>
|
||||
<div part="indicator" class="indicator"></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
customElements.define('sm-tab-header', class extends HTMLElement {
|
||||
constructor() {
|
||||
super()
|
||||
this.attachShadow({
|
||||
mode: 'open'
|
||||
}).append(smTabHeader.content.cloneNode(true))
|
||||
|
||||
this.prevTab
|
||||
this.allTabs
|
||||
this.activeTab
|
||||
|
||||
this.indicator = this.shadowRoot.querySelector('.indicator');
|
||||
this.tabSlot = this.shadowRoot.querySelector('slot');
|
||||
this.tabHeader = this.shadowRoot.querySelector('.tab-header');
|
||||
|
||||
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) {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent(`switchedtab${this.target}`, {
|
||||
bubbles: true,
|
||||
detail: {
|
||||
index: parseInt(index)
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
moveIndiactor(tabDimensions) {
|
||||
this.indicator.setAttribute('style', `width: ${tabDimensions.width}px; transform: translateX(${tabDimensions.left - this.tabHeader.getBoundingClientRect().left + this.tabHeader.scrollLeft}px)`)
|
||||
}
|
||||
|
||||
|
||||
changeTab(target) {
|
||||
if (target === this.prevTab || !target.closest('sm-tab'))
|
||||
return
|
||||
if (this.prevTab)
|
||||
this.prevTab.classList.remove('active')
|
||||
target.classList.add('active')
|
||||
|
||||
this.tabHeader.scrollTo({
|
||||
behavior: 'smooth',
|
||||
left: target.getBoundingClientRect().left - this.tabHeader.getBoundingClientRect().left + this.tabHeader.scrollLeft
|
||||
})
|
||||
this.moveIndiactor(target.getBoundingClientRect())
|
||||
this.prevTab = target;
|
||||
this.activeTab = target;
|
||||
}
|
||||
handleClick(e) {
|
||||
if (e.target.closest('sm-tab')) {
|
||||
this.changeTab(e.target)
|
||||
this.fireEvent(e.target.dataset.index)
|
||||
}
|
||||
}
|
||||
|
||||
handlePanelChange(e) {
|
||||
this.changeTab(this.allTabs[e.detail.index])
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
if (!this.hasAttribute('target') || this.getAttribute('target').value === '') return;
|
||||
this.target = this.getAttribute('target')
|
||||
|
||||
this.tabSlot.addEventListener('slotchange', () => {
|
||||
this.allTabs = this.tabSlot.assignedElements();
|
||||
this.allTabs.forEach((tab, index) => {
|
||||
tab.dataset.index = index
|
||||
})
|
||||
})
|
||||
|
||||
this.addEventListener('click', this.handleClick)
|
||||
document.addEventListener(`switchedpanel${this.target}`, this.handlePanelChange)
|
||||
|
||||
let resizeObserver = new ResizeObserver(entries => {
|
||||
entries.forEach((entry) => {
|
||||
if (this.prevTab) {
|
||||
let tabDimensions = this.activeTab.getBoundingClientRect();
|
||||
this.moveIndiactor(tabDimensions)
|
||||
}
|
||||
})
|
||||
})
|
||||
resizeObserver.observe(this)
|
||||
let observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
this.indicator.style.transition = 'none'
|
||||
if (this.activeTab) {
|
||||
let tabDimensions = this.activeTab.getBoundingClientRect();
|
||||
this.moveIndiactor(tabDimensions)
|
||||
} else {
|
||||
this.allTabs[0].classList.add('active')
|
||||
let tabDimensions = this.allTabs[0].getBoundingClientRect();
|
||||
this.moveIndiactor(tabDimensions)
|
||||
this.fireEvent(0)
|
||||
this.prevTab = this.tabSlot.assignedElements()[0];
|
||||
this.activeTab = this.prevTab;
|
||||
}
|
||||
}
|
||||
})
|
||||
}, {
|
||||
threshold: 1.0
|
||||
})
|
||||
observer.observe(this)
|
||||
}
|
||||
disconnectedCallback() {
|
||||
this.removeEventListener('click', this.handleClick)
|
||||
document.removeEventListener(`switchedpanel${this.target}`, this.handlePanelChange)
|
||||
}
|
||||
})
|
||||
|
||||
// tab
|
||||
const smTab = document.createElement('template')
|
||||
smTab.innerHTML = `
|
||||
<style>
|
||||
*{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
:host{
|
||||
position: relative;
|
||||
display: -webkit-inline-box;
|
||||
display: -ms-inline-flexbox;
|
||||
display: inline-flex;
|
||||
z-index: 1;
|
||||
--padding: 0.8rem 1rem;
|
||||
}
|
||||
.tab{
|
||||
position: relative;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
white-space: nowrap;
|
||||
padding: var(--padding);
|
||||
font-weight: 500;
|
||||
word-spacing: 0.1rem;
|
||||
text-align: center;
|
||||
-webkit-transition: color 0.3s;
|
||||
-o-transition: color 0.3s;
|
||||
transition: color 0.3s;
|
||||
text-transform: capitalize;
|
||||
height: 100%;
|
||||
}
|
||||
@media (hover: hover){
|
||||
:host(.active) .tab{
|
||||
opacity: 1;
|
||||
}
|
||||
.tab{
|
||||
opacity: 0.7
|
||||
}
|
||||
.tab:hover{
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div part="tab" class="tab">
|
||||
<slot></slot>
|
||||
</div>
|
||||
`;
|
||||
|
||||
customElements.define('sm-tab', class extends HTMLElement {
|
||||
constructor() {
|
||||
super()
|
||||
this.shadow = this.attachShadow({
|
||||
mode: 'open'
|
||||
}).append(smTab.content.cloneNode(true))
|
||||
}
|
||||
})
|
||||
|
||||
// tab-panels
|
||||
|
||||
const smTabPanels = document.createElement('template')
|
||||
smTabPanels.innerHTML = `
|
||||
<style>
|
||||
*{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
:host{
|
||||
width: 100%;
|
||||
}
|
||||
.panel-container{
|
||||
position: relative;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
scroll-snap-type: x mandatory;
|
||||
content-visibility: auto;
|
||||
}
|
||||
::slotted(*){
|
||||
min-width: 100%;
|
||||
scroll-snap-align: center;
|
||||
}
|
||||
@media (any-hover: none) {
|
||||
.panel-container{
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.container {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div part="panel-container" class="panel-container">
|
||||
<slot>Nothing to see here.</slot>
|
||||
</div>
|
||||
`;
|
||||
|
||||
customElements.define('sm-tab-panels', class extends HTMLElement {
|
||||
constructor() {
|
||||
super()
|
||||
this.attachShadow({
|
||||
mode: 'open'
|
||||
}).append(smTabPanels.content.cloneNode(true))
|
||||
|
||||
this.isTransitioning = false
|
||||
|
||||
this.panelContainer = this.shadowRoot.querySelector('.panel-container');
|
||||
this.handleTabChange = this.handleTabChange.bind(this)
|
||||
}
|
||||
handleTabChange(e) {
|
||||
this.isTransitioning = true
|
||||
this.panelContainer.scrollTo({
|
||||
left: this.allPanels[e.detail.index].getBoundingClientRect().left - this.panelContainer.getBoundingClientRect().left + this.panelContainer.scrollLeft,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
setTimeout(() => {
|
||||
this.isTransitioning = false
|
||||
}, 300);
|
||||
}
|
||||
fireEvent(index) {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent(`switchedpanel${this.id}`, {
|
||||
bubbles: true,
|
||||
detail: {
|
||||
index: parseInt(index)
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
connectedCallback() {
|
||||
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)
|
||||
})
|
||||
})
|
||||
document.addEventListener(`switchedtab${this.id}`, this.handleTabChange)
|
||||
|
||||
const intersectionObserver = new IntersectionObserver(entries => {
|
||||
|
||||
entries.forEach(entry => {
|
||||
if (!this.isTransitioning && entry.isIntersecting) {
|
||||
this.fireEvent(entry.target.dataset.index)
|
||||
}
|
||||
})
|
||||
}, {
|
||||
threshold: 0.6
|
||||
})
|
||||
}
|
||||
disconnectedCallback() {
|
||||
intersectionObserver.disconnect()
|
||||
document.removeEventListener(`switchedtab${this.id}`, this.handleTabChange)
|
||||
}
|
||||
})
|
||||
@ -23,7 +23,7 @@ body {
|
||||
body,
|
||||
body * {
|
||||
--accent-color: #504dff;
|
||||
--accent-color--light: #f4f4ff;
|
||||
--accent-color--light: #eeeeff;
|
||||
--text-color: 36, 36, 36;
|
||||
--background-color: 255, 255, 255;
|
||||
--foreground-color: rgb(250, 252, 255);
|
||||
@ -93,16 +93,19 @@ button,
|
||||
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;
|
||||
}
|
||||
|
||||
.button {
|
||||
white-space: nowrap;
|
||||
padding: 0.6rem 1rem;
|
||||
border-radius: 0.3rem;
|
||||
font-weight: 500;
|
||||
font-size: 0.8rem;
|
||||
background-color: var(--accent-color--light);
|
||||
color: var(--accent-color);
|
||||
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;
|
||||
@ -319,13 +322,7 @@ ul {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.stretch {
|
||||
-webkit-box-pack: stretch;
|
||||
-ms-flex-pack: stretch;
|
||||
justify-content: stretch;
|
||||
justify-items: stretch;
|
||||
}
|
||||
.stretch > * {
|
||||
.w-100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@ -484,9 +481,7 @@ strip-select {
|
||||
}
|
||||
|
||||
strip-option {
|
||||
text-transform: uppercase;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.05em;
|
||||
font-size: 0.8rem;
|
||||
--border-radius: 0;
|
||||
--active-option-color: rgba(var(--background-color), 1);
|
||||
@ -499,6 +494,11 @@ strip-option:last-of-type {
|
||||
--border-radius: 0 0.3rem 0.3rem 0;
|
||||
}
|
||||
|
||||
sm-select,
|
||||
sm-option {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.warning {
|
||||
background-color: khaki;
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
@ -519,15 +519,6 @@ strip-option:last-of-type {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.table__row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--table-columns), auto);
|
||||
}
|
||||
.table__header {
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
#landing {
|
||||
grid-template-rows: auto 1fr;
|
||||
}
|
||||
@ -632,7 +623,100 @@ strip-option:last-of-type {
|
||||
}
|
||||
|
||||
#orders_section {
|
||||
padding: 1.5rem;
|
||||
padding: 1.5rem 0;
|
||||
}
|
||||
#orders_section .icon {
|
||||
height: 1.2rem;
|
||||
width: 1.2rem;
|
||||
}
|
||||
|
||||
#orders_section__header {
|
||||
min-height: 2.8rem;
|
||||
padding: 0 1.5rem;
|
||||
}
|
||||
|
||||
#orders_section__header--primary {
|
||||
-ms-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
z-index: 1;
|
||||
}
|
||||
#orders_section__header--primary sm-tab-header {
|
||||
--gap: 1.5rem;
|
||||
}
|
||||
#orders_section__header--primary sm-tab {
|
||||
font-size: 0.9rem;
|
||||
--padding: 0.8rem 0;
|
||||
}
|
||||
|
||||
.table {
|
||||
display: grid;
|
||||
}
|
||||
.table__header {
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.table__row {
|
||||
padding: 0.5rem 1.5rem;
|
||||
display: grid;
|
||||
grid-template-columns: -webkit-min-content repeat(3, 1fr) -webkit-min-content;
|
||||
grid-template-columns: min-content repeat(3, 1fr) min-content;
|
||||
}
|
||||
|
||||
.order-card {
|
||||
position: relative;
|
||||
outline: none;
|
||||
-webkit-user-select: none;
|
||||
-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;
|
||||
}
|
||||
.order-card[data-type=buy] .order-card__type, .order-card[data-type=sell] .order-card__type {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
.order-card[data-type=buy] .order-card__type {
|
||||
color: var(--green);
|
||||
}
|
||||
.order-card[data-type=sell] .order-card__type {
|
||||
color: var(--danger-color);
|
||||
}
|
||||
.order-card--selected {
|
||||
background-color: rgba(var(--text-color), 0.08);
|
||||
}
|
||||
.order-card--selected .cancel-order {
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
.order-card sm-checkbox {
|
||||
--height: 1rem;
|
||||
--width: 1rem;
|
||||
padding: 1rem;
|
||||
cursor: pointer;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.order-card__quantity, .order-card__price {
|
||||
font-size: 0.9rem;
|
||||
color: rgba(var(--text-color), 0.9);
|
||||
}
|
||||
.order-card__time {
|
||||
font-size: 0.8rem;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
}
|
||||
|
||||
.cancel-order {
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
padding: 0.4rem 0.6rem;
|
||||
}
|
||||
.cancel-order span {
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
|
||||
#user_section {
|
||||
@ -653,6 +737,12 @@ strip-option:last-of-type {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 0.8rem;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
|
||||
.balance-card {
|
||||
display: grid;
|
||||
-webkit-box-align: center;
|
||||
@ -666,10 +756,6 @@ strip-option:last-of-type {
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 1rem;
|
||||
}
|
||||
.balance-card.is-locked .label {
|
||||
font-size: 0.8rem;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
}
|
||||
.balance-card:not(.is-locked) {
|
||||
grid-template-columns: auto 1fr auto;
|
||||
}
|
||||
@ -774,18 +860,12 @@ strip-option:last-of-type {
|
||||
.page-layout {
|
||||
grid-template-columns: 1fr 90vw 1fr;
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 64rem) {
|
||||
.page-layout {
|
||||
grid-template-columns: 1fr 80vw 1fr;
|
||||
}
|
||||
|
||||
#home {
|
||||
-webkit-box-align: start;
|
||||
-ms-flex-align: start;
|
||||
align-items: flex-start;
|
||||
padding: 1.5vmax 3vmax;
|
||||
grid-template-columns: 24rem minmax(0, 1fr) 20rem;
|
||||
padding: 1.5vmax;
|
||||
gap: 1rem;
|
||||
}
|
||||
#home > * {
|
||||
@ -798,6 +878,26 @@ strip-option:last-of-type {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 48rem) {
|
||||
#home {
|
||||
grid-template-rows: -webkit-min-content 1fr;
|
||||
grid-template-rows: min-content 1fr;
|
||||
grid-template-columns: 24rem minmax(0, 1fr);
|
||||
}
|
||||
|
||||
#orders_section {
|
||||
grid-row: span 2;
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 72rem) {
|
||||
.page-layout {
|
||||
grid-template-columns: 1fr 80vw 1fr;
|
||||
}
|
||||
|
||||
#home {
|
||||
grid-template-columns: 24rem minmax(0, 1fr) 20rem;
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 120rem) {
|
||||
.page-layout {
|
||||
grid-template-columns: 1fr 70vw 1fr;
|
||||
@ -817,15 +917,44 @@ strip-option:last-of-type {
|
||||
background: rgba(var(--text-color), 0.5);
|
||||
}
|
||||
|
||||
.nav-item,
|
||||
.interact {
|
||||
.interact {
|
||||
-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;
|
||||
}
|
||||
.nav-item:hover,
|
||||
.interact:hover {
|
||||
.interact:hover {
|
||||
background-color: var(--accent-color--light);
|
||||
}
|
||||
|
||||
.order-card .cancel-order {
|
||||
justify-self: flex-end;
|
||||
overflow: hidden;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.order-card:hover .cancel-order .icon, .order-card:focus-within .cancel-order .icon {
|
||||
opacity: 1;
|
||||
}
|
||||
.order-card .cancel-order:hover .icon,
|
||||
.order-card .cancel-order:hover span {
|
||||
opacity: 1;
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
2
public/css/main.min.css
vendored
2
public/css/main.min.css
vendored
File diff suppressed because one or more lines are too long
@ -19,7 +19,7 @@ body {
|
||||
&,
|
||||
* {
|
||||
--accent-color: #504dff;
|
||||
--accent-color--light: #f4f4ff;
|
||||
--accent-color--light: #eeeeff;
|
||||
--text-color: 36, 36, 36;
|
||||
--background-color: 255, 255, 255;
|
||||
--foreground-color: rgb(250, 252, 255);
|
||||
@ -87,15 +87,16 @@ button,
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
align-items: center;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
.button {
|
||||
white-space: nowrap;
|
||||
padding: 0.6rem 1rem;
|
||||
border-radius: 0.3rem;
|
||||
font-weight: 500;
|
||||
font-size: 0.8rem;
|
||||
background-color: var(--accent-color--light);
|
||||
color: var(--accent-color);
|
||||
background-color: rgba(var(--text-color), 0.06);
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
justify-content: center;
|
||||
&--primary {
|
||||
background-color: var(--accent-color);
|
||||
@ -129,7 +130,6 @@ sm-button {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
@ -289,13 +289,8 @@ ul {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.stretch {
|
||||
justify-content: stretch;
|
||||
justify-items: stretch;
|
||||
|
||||
& > * {
|
||||
width: 100%;
|
||||
}
|
||||
.w-100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.interact {
|
||||
@ -430,9 +425,7 @@ strip-select {
|
||||
border-radius: 0.3rem;
|
||||
}
|
||||
strip-option {
|
||||
text-transform: uppercase;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.05em;
|
||||
font-size: 0.8rem;
|
||||
--border-radius: 0;
|
||||
--active-option-color: rgba(var(--background-color), 1);
|
||||
@ -444,6 +437,10 @@ strip-option {
|
||||
--border-radius: 0 0.3rem 0.3rem 0;
|
||||
}
|
||||
}
|
||||
sm-select,
|
||||
sm-option {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.warning {
|
||||
background-color: khaki;
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
@ -461,16 +458,6 @@ strip-option {
|
||||
.page {
|
||||
height: 100%;
|
||||
}
|
||||
.table {
|
||||
&__row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--table-columns), auto);
|
||||
}
|
||||
&__header {
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
}
|
||||
#landing {
|
||||
grid-template-rows: auto 1fr;
|
||||
header {
|
||||
@ -562,8 +549,94 @@ strip-option {
|
||||
min-width: 8ch;
|
||||
}
|
||||
#orders_section {
|
||||
padding: 1.5rem;
|
||||
padding: 1.5rem 0;
|
||||
.icon {
|
||||
height: 1.2rem;
|
||||
width: 1.2rem;
|
||||
}
|
||||
}
|
||||
#orders_section__header {
|
||||
min-height: 2.8rem;
|
||||
padding: 0 1.5rem;
|
||||
}
|
||||
#orders_section__header--primary {
|
||||
flex-wrap: wrap;
|
||||
z-index: 1;
|
||||
sm-tab-header {
|
||||
--gap: 1.5rem;
|
||||
}
|
||||
sm-tab {
|
||||
font-size: 0.9rem;
|
||||
--padding: 0.8rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
.table {
|
||||
display: grid;
|
||||
&__header {
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
&__row {
|
||||
padding: 0.5rem 1.5rem;
|
||||
display: grid;
|
||||
grid-template-columns: min-content repeat(3, 1fr) min-content;
|
||||
}
|
||||
}
|
||||
.order-card {
|
||||
position: relative;
|
||||
outline: none;
|
||||
user-select: none;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.5rem 1.5rem 0.5rem 0.5rem;
|
||||
&[data-type="buy"] &__type,
|
||||
&[data-type="sell"] &__type {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
&[data-type="buy"] &__type {
|
||||
color: var(--green);
|
||||
}
|
||||
|
||||
&[data-type="sell"] &__type {
|
||||
color: var(--danger-color);
|
||||
}
|
||||
&--selected {
|
||||
background-color: rgba(var(--text-color), 0.08);
|
||||
.cancel-order {
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
sm-checkbox {
|
||||
--height: 1rem;
|
||||
--width: 1rem;
|
||||
padding: 1rem;
|
||||
cursor: pointer;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
&__quantity,
|
||||
&__price {
|
||||
font-size: 0.9rem;
|
||||
color: rgba(var(--text-color), 0.9);
|
||||
}
|
||||
|
||||
&__time {
|
||||
font-size: 0.8rem;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
}
|
||||
}
|
||||
.cancel-order {
|
||||
align-items: center;
|
||||
padding: 0.4rem 0.6rem;
|
||||
span {
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
}
|
||||
|
||||
#user_section {
|
||||
gap: 1.5rem;
|
||||
padding: 1.5rem;
|
||||
@ -579,6 +652,11 @@ strip-option {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
.label {
|
||||
font-size: 0.8rem;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
.balance-card {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
@ -588,10 +666,6 @@ strip-option {
|
||||
&.is-locked {
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 1rem;
|
||||
.label {
|
||||
font-size: 0.8rem;
|
||||
color: rgba(var(--text-color), 0.8);
|
||||
}
|
||||
}
|
||||
&:not(.is-locked) {
|
||||
grid-template-columns: auto 1fr auto;
|
||||
@ -675,17 +749,9 @@ strip-option {
|
||||
.page-layout {
|
||||
grid-template-columns: 1fr 90vw 1fr;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 64rem) {
|
||||
}
|
||||
@media screen and (min-width: 64rem) {
|
||||
.page-layout {
|
||||
grid-template-columns: 1fr 80vw 1fr;
|
||||
}
|
||||
#home {
|
||||
align-items: flex-start;
|
||||
padding: 1.5vmax 3vmax;
|
||||
grid-template-columns: 24rem minmax(0, 1fr) 20rem;
|
||||
padding: 1.5vmax;
|
||||
gap: 1rem;
|
||||
& > * {
|
||||
border-radius: 0.5rem;
|
||||
@ -697,6 +763,25 @@ strip-option {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 48rem) {
|
||||
#home {
|
||||
grid-template-rows: min-content 1fr;
|
||||
grid-template-columns: 24rem minmax(0, 1fr);
|
||||
}
|
||||
#orders_section {
|
||||
grid-row: span 2;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 64rem) {
|
||||
}
|
||||
@media screen and (min-width: 72rem) {
|
||||
.page-layout {
|
||||
grid-template-columns: 1fr 80vw 1fr;
|
||||
}
|
||||
#home {
|
||||
grid-template-columns: 24rem minmax(0, 1fr) 20rem;
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 120rem) {
|
||||
.page-layout {
|
||||
grid-template-columns: 1fr 70vw 1fr;
|
||||
@ -716,11 +801,43 @@ strip-option {
|
||||
background: rgba(var(--text-color), 0.5);
|
||||
}
|
||||
}
|
||||
.nav-item,
|
||||
.interact {
|
||||
transition: background-color 0.3s, transform 0.3s;
|
||||
&:hover {
|
||||
background-color: var(--accent-color--light);
|
||||
}
|
||||
}
|
||||
.order-card {
|
||||
.cancel-order {
|
||||
justify-self: flex-end;
|
||||
overflow: hidden;
|
||||
.icon,
|
||||
span {
|
||||
transition: opacity 0.3s, transform 0.3s;
|
||||
}
|
||||
.icon {
|
||||
opacity: 0;
|
||||
transform: translateX(100%);
|
||||
}
|
||||
span {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
&:hover,
|
||||
&:focus-within {
|
||||
.cancel-order {
|
||||
.icon {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.cancel-order:hover {
|
||||
.icon,
|
||||
span {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,7 +165,7 @@
|
||||
<sm-form id="trade_form">
|
||||
<div class="flex space-between align-center">
|
||||
<h4>Trade FLO</h4>
|
||||
<strip-select id="trade_type_selector">
|
||||
<strip-select id="trade_type_selector" class="tab">
|
||||
<strip-option value="buy" selected>Buy</strip-option>
|
||||
<strip-option value="sell">Sell</strip-option>
|
||||
</strip-select>
|
||||
@ -187,21 +187,56 @@
|
||||
</sm-form>
|
||||
</section>
|
||||
<section id="orders_section" class="grid gap-1-5">
|
||||
<div class="flex space-between align-center">
|
||||
<h4>My orders</h4>
|
||||
<strip-select id="orders_scope_selector">
|
||||
<strip-option value="active" selected>Open</strip-option>
|
||||
<strip-option value="completed">Completed</strip-option>
|
||||
</strip-select>
|
||||
</div>
|
||||
<div class="table" style="--table-columns: 4;">
|
||||
<div class="table__header table__row">
|
||||
<div></div>
|
||||
<div>Quantity</div>
|
||||
<div>At price</div>
|
||||
<div>Order placed</div>
|
||||
<div id="orders_section__header" class="flex">
|
||||
<div id="orders_section__header--primary" class="flex w-100 align-center space-between">
|
||||
<sm-tab-header target="orders_tab">
|
||||
<sm-tab>My orders</sm-tab>
|
||||
<sm-tab>Market orders</sm-tab>
|
||||
</sm-tab-header>
|
||||
<sm-select id="orders_scope_selector" class="tab" align-select="right">
|
||||
<sm-option value="active" selected>Open</sm-option>
|
||||
<sm-option value="completed">Completed</sm-option>
|
||||
</sm-select>
|
||||
</div>
|
||||
<div id="orders_section__header--secondary"
|
||||
class="flex w-100 align-center space-between hide-completely">
|
||||
<button class="" onclick="clearSelection()" title="Clear all selection">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon button__icon--left" height="24px"
|
||||
viewBox="0 0 24 24" width="24px">
|
||||
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||
<path
|
||||
d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
|
||||
</svg>
|
||||
<span id="selected_orders"></span>
|
||||
</button>
|
||||
<div class="options">
|
||||
<button class="button" title="Cancel selected orders" onclick="cancelAll()">
|
||||
Cancel selected
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<sm-tab-panels id="orders_tab">
|
||||
<div class="table">
|
||||
<ul id="my_order_list"></ul>
|
||||
</div>
|
||||
<div class="table">
|
||||
<ul id="market_order_list">
|
||||
sdgkmsdg <br>
|
||||
sdgkmsdg <br>
|
||||
sdgkmsdg <br>
|
||||
sdgkmsdg <br>
|
||||
sdgkmsdg <br>
|
||||
sdgkmsdg <br>
|
||||
sdgkmsdg <br>
|
||||
sdgkmsdg <br>
|
||||
sdgkmsdg <br>
|
||||
sdgkmsdg <br>
|
||||
sdgkmsdg <br>
|
||||
sdgkmsdg <br>
|
||||
</ul>
|
||||
</div>
|
||||
</sm-tab-panels>
|
||||
</section>
|
||||
<section id="user_section" class="grid">
|
||||
<h4 class="flex align-center user_section__header">
|
||||
@ -215,7 +250,7 @@
|
||||
My wallet
|
||||
</h4>
|
||||
<div id="wallet_actions">
|
||||
<p>Select asset</p>
|
||||
<p class="label">Select asset</p>
|
||||
<sm-select id="wallet_asset_selector">
|
||||
<sm-option value="FLO">FLO</sm-option>
|
||||
<sm-option value="Rupee">Rupee</sm-option>
|
||||
@ -415,6 +450,28 @@
|
||||
<span class="available-balance"></span>
|
||||
</div>
|
||||
</template>
|
||||
<template id="order_template">
|
||||
<li class="table__row order-card">
|
||||
<sm-checkbox></sm-checkbox>
|
||||
<div class="grid">
|
||||
<div class="order-card__type capitalize"></div>
|
||||
<div class="order-card__quantity"></div>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<span class="label order-card__price-type">Unit price</span>
|
||||
<div class="order-card__price"></div>
|
||||
</div>
|
||||
<time class="order-card__time"></time>
|
||||
<button class="cancel-order" title="Cancel this order">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" height="24px" viewBox="0 0 24 24" width="24px">
|
||||
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||
<path
|
||||
d="M16 9v10H8V9h8m-1.5-6h-5l-1 1H5v2h14V4h-3.5l-1-1zM18 7H6v12c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7z" />
|
||||
</svg>
|
||||
<span>Cancel</span>
|
||||
</button>
|
||||
</li>
|
||||
</template>
|
||||
<script id="ui_utils">
|
||||
// Global variables
|
||||
const domRefs = {};
|
||||
@ -654,7 +711,7 @@
|
||||
return `${month} ${year}`;
|
||||
}
|
||||
else
|
||||
return `${month} ${date} ${year}, ${finalHours}`;
|
||||
return `${finalHours}, ${month} ${date} ${year}`;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return time;
|
||||
@ -962,6 +1019,51 @@
|
||||
getRef(containerId).append(card)
|
||||
}
|
||||
|
||||
const myBuyOrders = [
|
||||
{
|
||||
id: 'dfs5g16sdg1',
|
||||
time_placed: generateRandomDate(),
|
||||
quantity: 14.5,
|
||||
maxPrice: 1.36,
|
||||
},
|
||||
{
|
||||
id: 'f4gd1d56fg1',
|
||||
time_placed: generateRandomDate(),
|
||||
quantity: 78.3,
|
||||
maxPrice: 1.26,
|
||||
},
|
||||
{
|
||||
id: 's4dg5s4d1g98',
|
||||
time_placed: generateRandomDate(),
|
||||
quantity: 14.5,
|
||||
maxPrice: 1.28,
|
||||
},
|
||||
]
|
||||
const mySellOrders = [
|
||||
{
|
||||
id: 'sd8g45g419s6',
|
||||
time_placed: generateRandomDate(),
|
||||
quantity: 15,
|
||||
minPrice: 1.16,
|
||||
},
|
||||
{
|
||||
id: 's59d1g9ws18d',
|
||||
time_placed: generateRandomDate(),
|
||||
quantity: 8.3,
|
||||
minPrice: 1.86,
|
||||
},
|
||||
{
|
||||
id: 'w899e1g4d1g98',
|
||||
time_placed: generateRandomDate(),
|
||||
quantity: 18.5,
|
||||
minPrice: 1.64,
|
||||
},
|
||||
]
|
||||
|
||||
function generateRandomDate() {
|
||||
return new Date() - Math.floor(Math.random() * 10000000000);
|
||||
}
|
||||
|
||||
function account() {
|
||||
getAccount().then(acc => {
|
||||
console.debug(acc);
|
||||
@ -983,28 +1085,9 @@
|
||||
let rupee_net = rupee_total - rupee_locked;
|
||||
console.debug("RUPEE", rupee_total, rupee_locked, rupee_net);
|
||||
showBalance("rupee_balance", rupee_net, rupee_locked)
|
||||
//My buy orders
|
||||
let container = document.getElementById("my-buy-orders").getElementsByTagName("tbody")[0];
|
||||
container.innerHTML = '';
|
||||
acc.buyOrders.forEach(o => {
|
||||
let row = container.insertRow();
|
||||
row.insertCell().innerHTML = `<input type="checkbox">`;
|
||||
row.insertCell().textContent = o.quantity;
|
||||
row.insertCell().textContent = o.maxPrice;
|
||||
row.insertCell().textContent = new Date(o.time_placed);
|
||||
row.dataset["id"] = o.id;
|
||||
});
|
||||
//My sell orders
|
||||
container = document.getElementById("my-sell-orders").getElementsByTagName("tbody")[0];
|
||||
container.innerHTML = '';
|
||||
acc.sellOrders.forEach(o => {
|
||||
let row = container.insertRow();
|
||||
row.insertCell().innerHTML = `<input type="checkbox">`;
|
||||
row.insertCell().textContent = o.quantity;
|
||||
row.insertCell().textContent = o.minPrice;
|
||||
row.insertCell().textContent = new Date(o.time_placed);
|
||||
row.dataset["id"] = o.id;
|
||||
});
|
||||
//My orders
|
||||
renderOpenOrders(acc.buyOrders, acc.sellOrders)
|
||||
|
||||
//My Transactions
|
||||
container = document.getElementById("my-transactions").getElementsByTagName("tbody")[0];
|
||||
container.innerHTML = '';
|
||||
@ -1098,6 +1181,21 @@
|
||||
refresh(true);
|
||||
</script>
|
||||
<script>
|
||||
const render = {
|
||||
orderCard(orderDetails = {}) {
|
||||
const { id, quantity, price, time, type } = orderDetails
|
||||
const card = getRef('order_template').content.cloneNode(true).firstElementChild
|
||||
card.dataset.id = id
|
||||
card.dataset.type = type
|
||||
card.querySelector('.order-card__type').textContent = type
|
||||
card.querySelector('.order-card__quantity').textContent = `${quantity} FLO`
|
||||
card.querySelector('.order-card__price-type').textContent = type === 'buy' ? 'Max price' : 'Min price'
|
||||
card.querySelector('.order-card__price').textContent = `₹${price}`
|
||||
card.querySelector('.order-card__time').textContent = getFormattedTime(time, true)
|
||||
return card
|
||||
}
|
||||
}
|
||||
|
||||
function showProcess(id) {
|
||||
getRef(id).children[0].classList.add('clip')
|
||||
getRef(id).append(document.createElement('sm-spinner'))
|
||||
@ -1202,6 +1300,160 @@
|
||||
hideProcess('wallet_popup__cta_wrapper')
|
||||
}
|
||||
})
|
||||
const selectedOrders = new Map()
|
||||
const slideInLeft = [
|
||||
{
|
||||
opacity: 0,
|
||||
transform: 'translateX(1.5rem)'
|
||||
},
|
||||
{
|
||||
opacity: 1,
|
||||
transform: 'translateX(0)'
|
||||
}
|
||||
]
|
||||
const slideOutLeft = [
|
||||
{
|
||||
opacity: 1,
|
||||
transform: 'translateX(0)'
|
||||
},
|
||||
{
|
||||
opacity: 0,
|
||||
transform: 'translateX(-1.5rem)'
|
||||
},
|
||||
]
|
||||
const slideInRight = [
|
||||
{
|
||||
opacity: 0,
|
||||
transform: 'translateX(-1.5rem)'
|
||||
},
|
||||
{
|
||||
opacity: 1,
|
||||
transform: 'translateX(0)'
|
||||
}
|
||||
]
|
||||
const slideOutRight = [
|
||||
{
|
||||
opacity: 1,
|
||||
transform: 'translateX(0)'
|
||||
},
|
||||
{
|
||||
opacity: 0,
|
||||
transform: 'translateX(1.5rem)'
|
||||
},
|
||||
]
|
||||
getRef('my_order_list').addEventListener('change', e => {
|
||||
const animOptions = {
|
||||
duration: 150,
|
||||
easing: 'ease',
|
||||
fill: 'forwards'
|
||||
}
|
||||
const target = e.target.parentNode;
|
||||
target.classList.toggle('order-card--selected')
|
||||
if (e.target.checked) {
|
||||
selectedOrders.set(target.dataset.id, target.dataset.type)
|
||||
} else {
|
||||
selectedOrders.delete(target.dataset.id)
|
||||
}
|
||||
getRef('selected_orders').textContent = `${selectedOrders.size} selected`
|
||||
if (selectedOrders.size === 1 && !getRef('orders_section__header').children[0].classList.contains('hide-completely')) {
|
||||
getRef('orders_section__header').children[0].animate(slideOutLeft, animOptions)
|
||||
.onfinish = () => {
|
||||
getRef('orders_section__header').children[0].classList.add('hide-completely')
|
||||
getRef('orders_section__header').children[1].classList.remove('hide-completely')
|
||||
getRef('orders_section__header').children[1].animate(slideInLeft, animOptions)
|
||||
}
|
||||
} else if (selectedOrders.size === 0 && getRef('orders_section__header').children[0].classList.contains('hide-completely')) {
|
||||
getRef('orders_section__header').children[1].animate(slideOutRight, animOptions)
|
||||
.onfinish = () => {
|
||||
getRef('orders_section__header').children[1].classList.add('hide-completely')
|
||||
getRef('orders_section__header').children[0].classList.remove('hide-completely')
|
||||
getRef('orders_section__header').children[0].animate(slideInRight, animOptions)
|
||||
}
|
||||
}
|
||||
})
|
||||
function clearSelection() {
|
||||
getRef('my_order_list').querySelectorAll('sm-checkbox[checked]').forEach(elem => elem.checked = false)
|
||||
}
|
||||
getRef('my_order_list').addEventListener('click', e => {
|
||||
if (e.target.closest('.cancel-order')) {
|
||||
getConfirmation('Cancel this order?').then(res => {
|
||||
if (res) {
|
||||
const target = e.target.closest('.order-card')
|
||||
const id = target.dataset.id
|
||||
const type = target.dataset.type
|
||||
cancelOrder(type, id, proxy.secret)
|
||||
.then(() => {
|
||||
notify('Order cancelled', 'success')
|
||||
target.remove()
|
||||
})
|
||||
.catch(err => notify(err, 'error'))
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
function cancelAll() {
|
||||
getConfirmation('Cancel all selected orders?').then(res => {
|
||||
if (res) {
|
||||
try {
|
||||
selectedOrders.forEach(async (type, id) => {
|
||||
await cancelOrder(type, id, proxy.secret)
|
||||
.then(() => {
|
||||
getRef('my_order_list').querySelector(`data-id="${id}"`).remove()
|
||||
})
|
||||
})
|
||||
notify('All selected orders cancelled', 'success')
|
||||
}
|
||||
catch (err) {
|
||||
notify(err, 'error')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function renderAllOrders(buyOrders, sellOrders) {
|
||||
getRef('my_order_list').innerHTML = '';
|
||||
const frag = document.createDocumentFragment()
|
||||
const allOpenOrders = [...(buyOrders || myBuyOrders), ...(sellOrders || mySellOrders)].sort((a, b) => b.time_placed - a.time_placed)
|
||||
console.log(allOpenOrders)
|
||||
allOpenOrders.forEach(order => {
|
||||
const { id, quantity, minPrice = undefined, maxPrice = undefined, time_placed } = order
|
||||
const orderDetails = {
|
||||
id,
|
||||
quantity,
|
||||
type: minPrice ? 'sell' : 'buy',
|
||||
price: minPrice || maxPrice,
|
||||
time: time_placed
|
||||
}
|
||||
frag.append(render.orderCard(orderDetails))
|
||||
})
|
||||
getRef('my_order_list').append(frag)
|
||||
}
|
||||
function renderOpenOrders(buyOrders, sellOrders) {
|
||||
getRef('my_order_list').innerHTML = '';
|
||||
const frag = document.createDocumentFragment()
|
||||
const allOpenOrders = [...(buyOrders || myBuyOrders), ...(sellOrders || mySellOrders)].sort((a, b) => b.time_placed - a.time_placed)
|
||||
allOpenOrders.forEach(order => {
|
||||
const { id, quantity, minPrice = undefined, maxPrice = undefined, time_placed } = order
|
||||
const orderDetails = {
|
||||
id,
|
||||
quantity,
|
||||
type: minPrice ? 'sell' : 'buy',
|
||||
price: minPrice || maxPrice,
|
||||
time: time_placed
|
||||
}
|
||||
frag.append(render.orderCard(orderDetails))
|
||||
})
|
||||
getRef('my_order_list').append(frag)
|
||||
}
|
||||
renderOpenOrders()
|
||||
getRef('orders_scope_selector').addEventListener('change', e => {
|
||||
if (e.target.value === 'open') {
|
||||
renderOpenOrders()
|
||||
} else {
|
||||
renderCompletedOrders()
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user