mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-01-19 05:33:31 +01:00
POS Cart: Horizontal scrollable filters (#5391)
This commit is contained in:
parent
e82281d273
commit
c979c4774c
@ -28,8 +28,8 @@
|
||||
}
|
||||
|
||||
<div id="PosCart">
|
||||
<div id="content" class="public-page-wrap">
|
||||
<div class="container-xl">
|
||||
<div id="content">
|
||||
<div class="public-page-wrap container-xl">
|
||||
<header class="sticky-top bg-body d-flex flex-column py-3 py-lg-4 gap-3">
|
||||
<div class="d-flex align-items-center justify-content-center gap-3 pe-5 position-relative">
|
||||
<h1 class="mb-0">@(string.IsNullOrEmpty(Model.Title) ? Model.StoreName : Model.Title)</h1>
|
||||
@ -39,11 +39,13 @@
|
||||
</button>
|
||||
</div>
|
||||
<input id="SearchTerm" class="form-control rounded-pill" placeholder="Search…" v-model="searchTerm">
|
||||
<div v-if="allCategories" class="btcpay-pills d-flex flex-wrap align-items-center justify-content-center gap-3">
|
||||
<div id="Categories" ref="categories" v-if="allCategories" :class="{ 'scrollable': categoriesScrollable }">
|
||||
<nav class="btcpay-pills d-flex align-items-center gap-3" ref="categoriesNav">
|
||||
<template v-for="cat in allCategories">
|
||||
<input :id="`Category-${cat.value}`" type="radio" name="category" autocomplete="off" v-model="displayCategory" :value="cat.value">
|
||||
<label :for="`Category-${cat.value}`" class="btcpay-pill">{{ cat.text }}</label>
|
||||
<label :for="`Category-${cat.value}`" class="btcpay-pill text-nowrap">{{ cat.text }}</label>
|
||||
</template>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
<main>
|
||||
@ -122,8 +124,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<aside id="cart" ref="cart" tabindex="-1" aria-labelledby="cartLabel">
|
||||
<div class="public-page-wrap" v-cloak>
|
||||
<div class="container-xl">
|
||||
<div class="public-page-wrap container-xl" v-cloak>
|
||||
<header class="sticky-top bg-tile offcanvas-header py-3 py-lg-4 d-flex align-items-baseline justify-content-center gap-3 px-5 pe-lg-0">
|
||||
<h1 class="mb-0" id="cartLabel">Cart</h1>
|
||||
<button id="CartClear" type="reset" v-on:click="clearCart" class="btn btn-text text-primary p-1" v-if="cartCount > 0">
|
||||
@ -243,6 +244,5 @@
|
||||
<p id="CartItems" v-else class="text-muted text-center my-0">There are no items in your cart yet.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
|
@ -3,7 +3,13 @@
|
||||
}
|
||||
|
||||
#PosCart .public-page-wrap {
|
||||
padding: 0 0 var(--btcpay-space-l);
|
||||
padding-top: 0;
|
||||
}
|
||||
@media (max-width: 400px) {
|
||||
#PosCart .public-page-wrap {
|
||||
padding-left: var(--btcpay-space-s);
|
||||
padding-right: var(--btcpay-space-s);
|
||||
}
|
||||
}
|
||||
|
||||
#PosCart .offcanvas-backdrop {
|
||||
@ -11,6 +17,48 @@
|
||||
transition-duration: var(--btcpay-transition-duration-fast);
|
||||
}
|
||||
|
||||
#Categories nav {
|
||||
justify-content: center;
|
||||
}
|
||||
#Categories.scrollable {
|
||||
--scroll-bar-spacing: var(--btcpay-space-m);
|
||||
--scroll-indicator-spacing: var(--btcpay-space-m);
|
||||
position: relative;
|
||||
margin-bottom: calc(var(--scroll-bar-spacing) * -1);
|
||||
}
|
||||
#Categories.scrollable nav {
|
||||
justify-content: start;
|
||||
overflow: auto visible;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
margin-left: calc(var(--scroll-indicator-spacing) * -1);
|
||||
margin-right: calc(var(--scroll-indicator-spacing) * -1);
|
||||
padding: 0 var(--scroll-indicator-spacing) var(--scroll-bar-spacing);
|
||||
}
|
||||
|
||||
#Categories.scrollable nav::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Horizontal scroll indicators */
|
||||
#Categories.scrollable:before,
|
||||
#Categories.scrollable:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: var(--btcpay-space-m);
|
||||
}
|
||||
|
||||
#Categories.scrollable:before {
|
||||
background-image: linear-gradient(to right, var(--btcpay-body-bg), rgba(var(--btcpay-body-bg-rgb), 0));
|
||||
left: calc(var(--scroll-indicator-spacing) * -1);
|
||||
}
|
||||
|
||||
#Categories.scrollable:after {
|
||||
background-image: linear-gradient(to left, var(--btcpay-body-bg), rgba(var(--btcpay-body-bg-rgb), 0));
|
||||
right: calc(var(--scroll-indicator-spacing) * -1);
|
||||
}
|
||||
|
||||
.cart-toggle-btn {
|
||||
--button-width: 40px;
|
||||
--button-height: 40px;
|
||||
|
@ -44,6 +44,7 @@ document.addEventListener("DOMContentLoaded",function () {
|
||||
displayCategory: '*',
|
||||
searchTerm: null,
|
||||
cart: loadState('cart'),
|
||||
categoriesScrollable: false,
|
||||
$cart: null
|
||||
}
|
||||
},
|
||||
@ -180,6 +181,28 @@ document.addEventListener("DOMContentLoaded",function () {
|
||||
mounted() {
|
||||
this.$cart = new bootstrap.Offcanvas(this.$refs.cart, { backdrop: false })
|
||||
|
||||
if (this.$refs.categories) {
|
||||
const getInnerNavWidth = () => {
|
||||
// set to inline display, get width to get the real inner width, then set back to flex
|
||||
this.$refs.categoriesNav.classList.remove('d-flex');
|
||||
this.$refs.categoriesNav.classList.add('d-inline-flex');
|
||||
const navWidth = this.$refs.categoriesNav.clientWidth - 32; // 32 is the margin
|
||||
this.$refs.categoriesNav.classList.remove('d-inline-flex');
|
||||
this.$refs.categoriesNav.classList.add('d-flex');
|
||||
return navWidth;
|
||||
}
|
||||
const adjustCategories = () => {
|
||||
const navWidth = getInnerNavWidth();
|
||||
Vue.set(this, 'categoriesScrollable', this.$refs.categories.clientWidth < navWidth);
|
||||
const activeEl = document.querySelector('#Categories .btcpay-pills input:checked + label')
|
||||
if (activeEl) activeEl.scrollIntoView({ block: 'end', inline: 'center' })
|
||||
}
|
||||
window.addEventListener('resize', e => {
|
||||
debounce('resize', adjustCategories, 50)
|
||||
});
|
||||
adjustCategories();
|
||||
}
|
||||
|
||||
window.addEventListener('pagehide', () => {
|
||||
if (this.payButtonLoading) {
|
||||
this.unsetPayButtonLoading();
|
||||
|
Loading…
Reference in New Issue
Block a user