stylized filter offcanvas and added placeholder for active facets, added back to top button component

This commit is contained in:
zach
2026-03-01 20:04:35 -05:00
parent 752a4880e3
commit 516c223322
6 changed files with 96 additions and 14 deletions

View File

@@ -20,7 +20,7 @@
@import 'bootstrap/scss/nav';
// @import 'bootstrap/scss/accordion';
@import 'bootstrap/scss/alert';
// @import 'bootstrap/scss/badge';
@import 'bootstrap/scss/badge';
// @import 'bootstrap/scss/breadcrumb';
// @import 'bootstrap/scss/button-group';
@import 'bootstrap/scss/buttons';
@@ -30,7 +30,7 @@
@import 'bootstrap/scss/dropdown';
@import 'bootstrap/scss/forms';
@import 'bootstrap/scss/grid';
// @import 'bootstrap/scss/list-group';
@import 'bootstrap/scss/list-group';
@import 'bootstrap/scss/modal';
@import 'bootstrap/scss/navbar';
@import 'bootstrap/scss/offcanvas';

View File

@@ -8,6 +8,10 @@
--radius: 40px; /* Circle radius */
}
html {
scroll-behavior: smooth;
}
/* --------------------------------------------------
Layout
-------------------------------------------------- */
@@ -259,12 +263,41 @@ $tiers: (
stroke: rgba(255,255,255,0.87);
}
.form-check-input:checked {
background-color: var(--bs-success);
border-color: var(--bs-success-border-subtle);
}
.form-check-input:focus {
border-color: var(--bs-success);
box-shadow: 0 0 0 0.25rem rgba(var(--bs-success-rgb), 0.25);
}
.search-button {
width: 2rem;
fill: rgba(255,255,255,0.87);
stroke: rgba(255,255,255,0.87);
}
#btn-back-to-top {
position: fixed;
bottom: 5vh;
right: 5vw;
display: none;
}
.top-icon svg {
width: 2rem;
height:2rem;
fill: var(--bs-info-bg-subtle);
stroke: var(--bs-info-bg-subtle);
}
#btn-back-to-top:hover .top-icon svg {
fill: var(--bs-info-border-subtle);
stroke: var(--bs-info-border-subtle);
}
.energy-icon svg {
margin-top: -0.25rem;
margin-right: -0.25rem;
@@ -314,6 +347,10 @@ $tiers: (
font-weight: 700;
}
.fs-7 {
font-size: 0.9rem !important;
}
.price-label {
font-size: 0.7rem;
font-weight: 600;

View File

@@ -0,0 +1,35 @@
---
---
<button type="button" class="btn btn-info p-2 rounded-circle" aria-label="Back to Top" id="btn-back-to-top">
<span class="top-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M232 64C201.1 64 176 89.1 176 120L176 320.6C172.8 322.6 169.6 324.8 166.5 327.1L144 344C123.9 359.1 112 382.8 112 408L112 427.5C112 480.5 141.1 529.2 187.7 554.3L196 558.8C217 570.1 240.4 576 264.3 576L400 576C461.9 576 512 525.9 512 464L512 368C512 332.7 483.3 304 448 304C445.2 304 442.4 304.2 439.7 304.5C428.7 285.1 407.9 272 384 272C378.7 272 373.5 272.7 368.5 273.9C357.7 253.7 336.5 240 312 240C303.5 240 295.4 241.7 288 244.7L288 120C288 89.1 262.9 64 232 64zM208 120C208 106.7 218.7 96 232 96C245.3 96 256 106.7 256 120L256 277.5C256 284.6 260.6 290.8 267.4 292.8C274.2 294.8 281.4 292.2 285.4 286.3C291.2 277.6 301 272 312.1 272C327.7 272 340.7 283.2 343.5 297.9C344.5 303 347.9 307.4 352.7 309.5C357.5 311.6 363 311.3 367.5 308.6C372.3 305.7 378 304 384.1 304C398.8 304 411.3 314 415 327.6C416.2 332 419.2 335.7 423.3 337.7C427.4 339.7 432.1 339.9 436.4 338.3C440 336.9 444 336.1 448.2 336.1C465.9 336.1 480.2 350.4 480.2 368.1L480.2 464.1C480.2 508.3 444.4 544.1 400.2 544.1L264.5 544.1C246 544.1 227.7 539.5 211.4 530.7L211.4 530.7L203.1 526.2C166.6 506.6 144 468.7 144 427.5L144 408C144 392.9 151.1 378.7 163.2 369.6L176 360L176 408C176 416.8 183.2 424 192 424C200.8 424 208 416.8 208 408L208 120z"/></svg></span>
</button>
<script>
//Get the button
let mybutton = document.getElementById("btn-back-to-top");
// When the user scrolls down 20px from the top of the document, show the button
window.onscroll = function () {
scrollFunction();
};
function scrollFunction() {
if (
document.body.scrollTop > 20 ||
document.documentElement.scrollTop > 20
) {
mybutton.style.display = "block";
} else {
mybutton.style.display = "none";
}
}
// When the user clicks on the button, scroll to the top of the document
mybutton.addEventListener("click", backToTop);
function backToTop() {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
}
</script>

View File

@@ -1,12 +1,12 @@
---
import BackToTop from "./BackToTop.astro"
---
<div class="row mb-4">
<div class="col-md-3 display-sm-none">
<div class="h5 d-none">Inventory management placeholder</div>
<div class="offcanvas offcanvas-start" data-bs-backdrop="static" tabindex="-1" id="offcanvasExample" aria-labelledby="offcanvasExampleLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="offcanvasExampleLabel">Filters</h5>
<h5 class="offcanvas-title" id="offcanvasExampleLabel">Filter by:</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body px-3 pt-0">
@@ -15,6 +15,15 @@
</div>
</div>
<div class="col-sm-12 col-md-9 mt-0">
<div id="activeFilters" class="mb-2 d-flex align-items-center justify-content-end small">
<span class="me-1">Filtered by:</span>
<ul class="list-group list-group-horizontal">
<li class="list-group-item border-0">Filter 1</li>
<li class="list-group-item border-0">Filter 2</li>
<li class="list-group-item border-0">Filter 3</li>
</ul>
<span class="ms-2"><button type="button" class="btn-close" aria-label="Clear all filters"></button></span>
</div>
<div id="cardGrid" class="row g-xxl-3 g-2 row-cols-2 row-cols-lg-3 row-cols-xxl-4 row-cols-xxxl-5">
</div>
<div id="notfound"></div>
@@ -26,3 +35,4 @@
</div>
</div>
</div>
<BackToTop>

View File

@@ -25,11 +25,11 @@ import { SignedIn } from "@clerk/astro/components";
<SignedIn>
<form class="d-flex ms-2" role="search" id="searchform" hx-post="/partials/cards" hx-target="#cardGrid" hx-trigger="load, submit" hx-vals='{"start":"0"}' hx-on--after-request="afterUpdate()" hx-on--before-request="beforeSearch()">
<a class="btn btn-secondary btn-lg me-2" data-bs-toggle="offcanvas" href="#offcanvasExample" role="button" aria-controls="offcanvasExample"><span class="d-block d-md-none filter-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path opacity=".4" d="M96 160L283.3 347.3C286.3 350.3 288 354.4 288 358.6L288 480L352 544L352 358.6C352 354.4 353.7 350.3 356.7 347.3L544 160L96 160z"/><path d="M66.4 147.8C71.4 135.8 83.1 128 96 128L544 128C556.9 128 568.6 135.8 573.6 147.8C578.6 159.8 575.8 173.5 566.7 182.7L384 365.3L384 544C384 556.9 376.2 568.6 364.2 573.6C352.2 578.6 338.5 575.8 329.3 566.7L265.3 502.7C259.3 496.7 255.9 488.6 255.9 480.1L256 365.3L73.4 182.6C64.2 173.5 61.5 159.7 66.4 147.8zM544 160L96 160L283.3 347.3C286.3 350.3 288 354.4 288 358.6L288 480L352 544L352 358.6C352 354.4 353.7 350.3 356.7 347.3L544 160z"/></svg></span><span class="d-none d-md-block">Filters</span></a>
<a class="btn btn-secondary btn-lg me-2" data-bs-toggle="offcanvas" href="#offcanvasExample" role="button" aria-controls="offcanvasExample"><span class="d-block d-md-none filter-icon mt-1"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path opacity=".4" d="M96 160L283.3 347.3C286.3 350.3 288 354.4 288 358.6L288 480L352 544L352 358.6C352 354.4 353.7 350.3 356.7 347.3L544 160L96 160z"/><path d="M66.4 147.8C71.4 135.8 83.1 128 96 128L544 128C556.9 128 568.6 135.8 573.6 147.8C578.6 159.8 575.8 173.5 566.7 182.7L384 365.3L384 544C384 556.9 376.2 568.6 364.2 573.6C352.2 578.6 338.5 575.8 329.3 566.7L265.3 502.7C259.3 496.7 255.9 488.6 255.9 480.1L256 365.3L73.4 182.6C64.2 173.5 61.5 159.7 66.4 147.8zM544 160L96 160L283.3 347.3C286.3 350.3 288 354.4 288 358.6L288 480L352 544L352 358.6C352 354.4 353.7 350.3 356.7 347.3L544 160z"/></svg></span><span class="d-none d-md-block">Filters</span></a>
<div class="input-group">
<input type="hidden" name="start" id="start" value="0" />
<input type="search" name="q" class="form-control form-control-lg form-outline" placeholder="Search cards..." />
<button type="submit" class="btn btn-danger btn-lg" value="" onclick="const q = document.querySelector('[name=q]').value; dataLayer.push({ event: 'view_search_results', search_term: q });">
<input type="search" name="q" class="form-control form-control-lg" placeholder="Search cards..." />
<button type="submit" class="btn btn-danger btn-lg border border-danger-subtle border-start-0" value="" onclick="const q = document.querySelector('[name=q]').value; dataLayer.push({ event: 'view_search_results', search_term: q });">
<svg class="search-button d-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M432 272C432 183.6 360.4 112 272 112C183.6 112 112 183.6 112 272C112 360.4 183.6 432 272 432C360.4 432 432 360.4 432 272zM401.1 435.1C365.7 463.2 320.8 480 272 480C157.1 480 64 386.9 64 272C64 157.1 157.1 64 272 64C386.9 64 480 157.1 480 272C480 320.8 463.2 365.7 435.1 401.1L569 535C578.4 544.4 578.4 558.1 569 567.5C559.6 575.9 544.4 575.9 536 567.5L401.1 435.1z"/></svg>
</button>
</div>

View File

@@ -122,21 +122,21 @@ const facets = searchResults.results.slice(1).map((result: any) => {
<div id="facetContainer" hx-swap-oob="true">
<div class="bg-dark sticky-top p-2 d-flex justify-content-end align-items-center">
<button type="reset" form="" class="btn btn-secondary btn-sm me-2">Clear</button>
<button type="submit" form="searchform" class="btn btn-secondary btn-sm">Apply Filters</button>
<button type="reset" data-bs-dismiss="offcanvas" class="btn btn-danger me-2">Clear</button>
<button type="submit" form="searchform" data-bs-dismiss="offcanvas" class="btn btn-success">Apply Filters</button>
</div>
{facets.map((facet) => (
<div class="mt-2 mb-4 facet-group row align-items-center justify-content-between">
<div class="h6 m-0 col-auto">{facetNames(facet.field_name)}</div>
<div class="fs-5 m-0 col-auto pb-1 border-bottom border-light-subtle">{facetNames(facet.field_name)}</div>
{(facet.counts.length > 20) &&
<input class="facet-filter form-control col-auto me-3" type="text" id={`filter_${facet.field_name}`} placeholder="Search..." />
}
<div class="facet-list col-11 mt-2">
{facet.counts.map((count:any) => (
<div class="facet-item form-check" data-facet-value={count.value.toLowerCase()}>
<label class="form-check-label">
<div class="facet-item form-check form-switch" data-facet-value={count.value.toLowerCase()}>
<label class="form-check-label fs-7">
<input type="checkbox" name={facet.field_name} value={count.value} checked={filterChecked(facet.field_name, count.value)} class="form-check-input" form="searchform" />
{count.value} ({count.count})
{count.value} <span class="badge text-bg-light align-baseline">{count.count}</span>
</label>
</div>
))}