mirror of
https://github.com/badlogic/heissepreise.git
synced 2024-06-30 12:27:15 +02:00
Add sticky chart and sticky search, see badlogic/heissepreise#89
This commit is contained in:
parent
d85311c4b5
commit
94a8eb2b1c
|
@ -11,6 +11,8 @@ class Settings extends Model {
|
||||||
this[store] = stores[store].defaultChecked;
|
this[store] = stores[store].defaultChecked;
|
||||||
});
|
});
|
||||||
this.onlyAvailable = true;
|
this.onlyAvailable = true;
|
||||||
|
this.stickyChart = true;
|
||||||
|
this.stickySearch = false;
|
||||||
|
|
||||||
let settings = localStorage.getItem("settings");
|
let settings = localStorage.getItem("settings");
|
||||||
if (settings) {
|
if (settings) {
|
||||||
|
|
|
@ -38,6 +38,8 @@ class SettingsView extends View {
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<custom-checkbox x-id="onlyAvailable" x-state x-change label="Nur verfügbare Produkte anzeigen" checked></custom-checkbox>
|
<custom-checkbox x-id="onlyAvailable" x-state x-change label="Nur verfügbare Produkte anzeigen" checked></custom-checkbox>
|
||||||
|
<custom-checkbox x-id="stickyChart" x-state x-change label="Diagramm immer anzeigen (wenn verfügbar)" checked></custom-checkbox>
|
||||||
|
<custom-checkbox x-id="stickySearch" x-state x-change label="Suche immer anzeigen (wenn verfügbar)"></custom-checkbox>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
this.setupEventHandlers();
|
this.setupEventHandlers();
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
*.hidden {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Product table */
|
/* Product table */
|
||||||
thead > tr {
|
thead > tr {
|
||||||
@apply bg-primary text-white text-left hidden md:table-row uppercase text-sm;
|
@apply bg-primary text-white text-left hidden md:table-row uppercase text-sm;
|
||||||
|
@ -208,6 +204,38 @@ thead > tr {
|
||||||
font-weight: 900 !important;
|
font-weight: 900 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
*.hidden,
|
||||||
|
.hidden,
|
||||||
|
.toggle--hidden {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0 auto;
|
||||||
|
gap: 0.5em;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.wrapper--search label {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.wrapper--search abbr {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.wrapper--sticky {
|
||||||
|
flex-direction: column;
|
||||||
|
position: sticky;
|
||||||
|
top: 4em;
|
||||||
|
z-index: 1;
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle:not(:checked) ~ .wrapper--sticky,
|
||||||
|
.toggle:not(:checked) ~ .wrapper--sticky * {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ class ItemsChart extends View {
|
||||||
|
|
||||||
this.unitPrice = false;
|
this.unitPrice = false;
|
||||||
this.innerHTML = /*html*/ `
|
this.innerHTML = /*html*/ `
|
||||||
<div class="bg-stone-200 p-4 mx-auto md:rounded-none md:mb-0 rounded-xl mb-4">
|
<div class="bg-stone-200 p-4 mx-auto md:rounded-none md:mb-0 rounded-xl mb-4w ${settings.stickyChart ? "sticky top-0" : ""}">
|
||||||
<div class="w-full h-[calc(100vh*0.50)] md:h-[calc(100vh*0.60)] lg:h-[calc(100vh*0.60)]" style="position: relative;">
|
<div class="w-full h-[calc(100vh*0.50)] md:h-[calc(100vh*0.60)] lg:h-[calc(100vh*0.60)]" style="position: relative;">
|
||||||
<canvas x-id="canvas" class="bg-white rounded-lg"></canvas>
|
<canvas x-id="canvas" class="bg-white rounded-lg"></canvas>
|
||||||
<div x-id="noData" class="hidden flex items-center justify-center h-full">Keine Daten ausgewählt</div>
|
<div x-id="noData" class="hidden flex items-center justify-center h-full">Keine Daten ausgewählt</div>
|
||||||
|
|
|
@ -24,7 +24,20 @@ class ItemsFilter extends View {
|
||||||
const placeholder = this.hasAttribute("placeholder") ? this.getAttribute("placeholder") : "Produkte suchen... (min. 3 Zeichen)";
|
const placeholder = this.hasAttribute("placeholder") ? this.getAttribute("placeholder") : "Produkte suchen... (min. 3 Zeichen)";
|
||||||
|
|
||||||
this.innerHTML = /*html*/ `
|
this.innerHTML = /*html*/ `
|
||||||
|
${
|
||||||
|
settings.stickySearch
|
||||||
|
? `
|
||||||
|
<div class="wrapper wrapper--search">
|
||||||
<input x-id="query" x-state x-input-debounce class="rounded-lg px-2 py-1 w-full" type="text" placeholder="${placeholder}" />
|
<input x-id="query" x-state x-input-debounce class="rounded-lg px-2 py-1 w-full" type="text" placeholder="${placeholder}" />
|
||||||
|
<label for="filter-toggle-search"><abbr title="Filter anzeigen/ausblenden">🎚</abbr></label>
|
||||||
|
</div>
|
||||||
|
<input class="toggle toggle--hidden" type="checkbox" id="filter-toggle-search" />
|
||||||
|
<div class="wrapper wrapper--sticky">
|
||||||
|
`
|
||||||
|
: `
|
||||||
|
<input x-id="query" x-state x-input-debounce class="rounded-lg px-2 py-1 w-full" type="text" placeholder="${placeholder}" />
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
<div x-id="sqlError" class="hidden mt-4 p-4">
|
<div x-id="sqlError" class="hidden mt-4 p-4">
|
||||||
</div>
|
</div>
|
||||||
|
@ -88,9 +101,21 @@ class ItemsFilter extends View {
|
||||||
)
|
)
|
||||||
.join("")}
|
.join("")}
|
||||||
</div>
|
</div>
|
||||||
|
${
|
||||||
|
settings.stickySearch
|
||||||
|
? `
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: ""
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
this.classList.add("items-filter");
|
this.classList.add("items-filter");
|
||||||
|
|
||||||
|
if (settings.stickySearch) {
|
||||||
|
this.classList.add("sticky");
|
||||||
|
this.style = "top: -1px;z-index:20;";
|
||||||
|
}
|
||||||
|
|
||||||
const elements = this.elements;
|
const elements = this.elements;
|
||||||
|
|
||||||
elements.query.addEventListener("input", () => {
|
elements.query.addEventListener("input", () => {
|
||||||
|
@ -132,9 +157,11 @@ class ItemsFilter extends View {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setupEventHandlers();
|
this.setupEventHandlers();
|
||||||
|
this.setupStickyChart();
|
||||||
|
|
||||||
this.addEventListener("x-change", () => {
|
this.addEventListener("x-change", () => {
|
||||||
this.filter();
|
this.filter();
|
||||||
|
this.observe();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,6 +188,35 @@ class ItemsFilter extends View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setupStickyChart() {
|
||||||
|
if (!settings.stickySearch) return;
|
||||||
|
this.observer = new IntersectionObserver(
|
||||||
|
(entries) => {
|
||||||
|
for (const entry of entries) {
|
||||||
|
const clientRect = entry.target.getBoundingClientRect();
|
||||||
|
console.log(entry.target, entry.intersectionRatio);
|
||||||
|
if (entry.intersectionRatio < 0.999 && clientRect.top + clientRect.height < window.innerHeight) {
|
||||||
|
// Fix Edge issue
|
||||||
|
entry.target.classList.add("wrapper--pinned");
|
||||||
|
} else {
|
||||||
|
entry.target.classList.remove("wrapper--pinned");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rootMargin: "0px",
|
||||||
|
threshold: 0.999,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
this.observe();
|
||||||
|
}
|
||||||
|
|
||||||
|
observe() {
|
||||||
|
if (this.observer == null) return;
|
||||||
|
this.observer.unobserve(this);
|
||||||
|
this.observer.observe(this);
|
||||||
|
}
|
||||||
|
|
||||||
filter() {
|
filter() {
|
||||||
if (!this.model) return;
|
if (!this.model) return;
|
||||||
|
|
||||||
|
|
|
@ -479,13 +479,13 @@
|
||||||
"code": "32"
|
"code": "32"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "schweinefleisch-spezialitaten",
|
"id": "faschiertes",
|
||||||
"url": "https://www.roksh.at/hofer/angebot/schweinefleisch-spezialitaten",
|
"url": "https://www.roksh.at/hofer/angebot/faschiertes",
|
||||||
"code": "32"
|
"code": "32"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "faschiertes",
|
"id": "schweinefleisch-spezialitaten",
|
||||||
"url": "https://www.roksh.at/hofer/angebot/faschiertes",
|
"url": "https://www.roksh.at/hofer/angebot/schweinefleisch-spezialitaten",
|
||||||
"code": "32"
|
"code": "32"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user