From 53a7212dfe0632c92eabc2d97d43317af18320f5 Mon Sep 17 00:00:00 2001 From: ulfrxdev Date: Wed, 22 Apr 2026 22:53:24 +0200 Subject: [PATCH] Redesign menu --- index.html | 105 +++++++++++++++++++++++++++++---------- js/ui/bottomNav.js | 25 +++++++--- js/views/Pantry.js | 97 +++++++++++++++++++++++++++--------- js/views/RecipeList.js | 98 ++++++++++++++++++++++++++---------- js/views/ShoppingList.js | 47 ++++++++++-------- 5 files changed, 271 insertions(+), 101 deletions(-) diff --git a/index.html b/index.html index b9e455d..29d4a0d 100644 --- a/index.html +++ b/index.html @@ -472,7 +472,8 @@ } #recipe-bottom-controls, #recipe-bottom-default-actions, - #pantry-bottom-controls { + #pantry-bottom-controls, + #shopping-bottom-controls { bottom: calc(1.58rem + env(safe-area-inset-bottom) + var(--recipe-controls-lift, 0.335rem)) !important; height: var(--recipe-control-size, 3.05rem) !important; background: transparent !important; @@ -483,12 +484,14 @@ transition: opacity 160ms ease; } html.is-nav-menu-open #recipe-bottom-controls, - html.is-nav-menu-open #pantry-bottom-controls { + html.is-nav-menu-open #pantry-bottom-controls, + html.is-nav-menu-open #shopping-bottom-controls { opacity: 0; pointer-events: none; } html.is-nav-menu-open #recipe-bottom-controls *, - html.is-nav-menu-open #pantry-bottom-controls * { + html.is-nav-menu-open #pantry-bottom-controls *, + html.is-nav-menu-open #shopping-bottom-controls * { pointer-events: none !important; } #recipe-search-shell.recipe-search-field, @@ -496,7 +499,7 @@ #pantry-search-shell.recipe-search-field, #pantry-search-shell.recipe-search-field:focus-within { position: absolute !important; - left: calc(var(--catalog-menu-left, 1rem) + var(--catalog-menu-width, 3.72rem) + 0.5rem); + left: var(--catalog-menu-left, 1rem); right: var(--catalog-search-right, calc(1rem + var(--recipe-control-size, 3.05rem) + 0.5rem)); bottom: 0; min-width: 0; @@ -578,6 +581,7 @@ } #main-view .recipe-glass-btn, #pantry-view .recipe-glass-btn, + #shopping-view .recipe-glass-btn, #app-bottom-nav .recipe-nav-toggle { position: relative; border: 1px solid rgba(255, 255, 255, 0.32) !important; @@ -594,6 +598,7 @@ } .dark #main-view .recipe-glass-btn, .dark #pantry-view .recipe-glass-btn, + .dark #shopping-view .recipe-glass-btn, .dark #app-bottom-nav .recipe-nav-toggle { border: 1px solid rgba(255, 255, 255, 0.12) !important; background: rgba(255, 255, 255, 0.04) !important; @@ -607,6 +612,7 @@ } #main-view .recipe-glass-btn:hover, #pantry-view .recipe-glass-btn:hover, + #shopping-view .recipe-glass-btn:hover, #app-bottom-nav .recipe-nav-toggle:hover { background: rgba(var(--overlay-rgb), 0.1) !important; color: rgb(var(--text-emphasis-rgb)); @@ -614,6 +620,7 @@ } .dark #main-view .recipe-glass-btn:hover, .dark #pantry-view .recipe-glass-btn:hover, + .dark #shopping-view .recipe-glass-btn:hover, .dark #app-bottom-nav .recipe-nav-toggle:hover { background: rgba(255, 255, 255, 0.09) !important; } @@ -635,15 +642,23 @@ right: auto !important; bottom: 0; } + #main-view #recipe-search-wrap, + #pantry-view #pantry-search-wrap { + left: var(--catalog-search-btn-left, calc(100vw - 7.6rem)) !important; + right: auto !important; + bottom: 0; + } #main-view .recipe-bottom-action, - #pantry-view .recipe-bottom-action { + #pantry-view .recipe-bottom-action, + #shopping-view .recipe-bottom-action { width: var(--recipe-control-size, 3.05rem); height: var(--recipe-control-size, 3.05rem); border-radius: 999px; font-size: 0.95rem; } #main-view .recipe-bottom-action i, - #pantry-view .recipe-bottom-action i { + #pantry-view .recipe-bottom-action i, + #shopping-view .recipe-bottom-action i { font-size: 0.95rem; line-height: 1; } @@ -853,6 +868,11 @@ pointer-events: none; transition: opacity 260ms cubic-bezier(0.2, 0.8, 0.2, 1), transform 260ms cubic-bezier(0.2, 0.8, 0.2, 1); } + html.is-inline-search-open #app-bottom-nav { + opacity: 0; + pointer-events: none; + transform: translateY(0.45rem) scale(0.985); + } #app-bottom-nav .recipe-nav-toggle { display: none; position: absolute; @@ -926,16 +946,24 @@ transform: translateY(0); pointer-events: auto; } + #app-bottom-nav.is-compact-tab .bottom-dock { + width: calc(var(--recipe-dock-width) - var(--nav-compact-extra-width, 0px)); + transform: translate( + var(--nav-compact-translate-x, 0px), + calc(var(--recipe-controls-lift, 0px) * -1) + ); + border-radius: 999px; + } #app-bottom-nav .bottom-dock { position: relative; box-sizing: border-box; width: var(--dock-width); - height: 3.72rem; + height: var(--recipe-control-size, 3.05rem); display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); align-items: stretch; - gap: var(--dock-gap); - padding: var(--dock-pad); + gap: 0.02rem; + padding: 0.28rem; border-radius: var(--dock-radius); background: rgba(255, 255, 255, 0.2); background-image: none; @@ -992,8 +1020,8 @@ border: 0; background: transparent !important; box-shadow: none !important; - width: 2.18rem; - height: 2.18rem; + width: 1.82rem; + height: 1.82rem; margin: 0; padding: 0; border-radius: 999px; @@ -1001,7 +1029,7 @@ align-items: center; justify-content: center; flex-direction: column; - gap: 0.24rem; + gap: 0.16rem; flex: 0 0 auto; color: rgba(var(--text-primary-rgb), 0.94); cursor: pointer; @@ -1013,7 +1041,7 @@ } #app-bottom-nav .nav-tab i, #app-bottom-nav .nav-action i { - font-size: 0.95rem; + font-size: 0.88rem; line-height: 1; } #app-bottom-nav .nav-label { @@ -1048,9 +1076,9 @@ background: var(--hover-overlay) !important; } #app-bottom-nav .nav-tab.is-active { - width: min(100%, 5.2rem); - height: 2.82rem; - padding: 0.34rem 0.28rem 0.3rem; + width: min(100%, 4rem); + height: 2.46rem; + padding: 0.24rem 0.2rem 0.22rem; color: rgb(var(--text-primary-rgb)); background: rgba(var(--overlay-rgb), 0.38) !important; border-radius: 999px; @@ -1062,7 +1090,19 @@ display: none; } #app-bottom-nav .nav-tab.is-active i { - font-size: 0.8rem; + font-size: 0.78rem; + } + #app-bottom-nav .nav-tab.is-active::after { + font-size: 0.58rem; + line-height: 1.1; + } + #app-bottom-nav.is-double-compact .nav-tab.is-active::after { + font-size: 0.52rem; + line-height: 1.24; + } + #app-bottom-nav.is-double-compact .nav-tab.is-active { + height: 2.54rem; + padding: 0.22rem 0.2rem 0.28rem; } .dark #app-bottom-nav .nav-tab.is-active { color: #fff; @@ -1094,21 +1134,21 @@ } #app-bottom-nav .bottom-dock { width: var(--dock-width); - height: 3.48rem; - gap: var(--dock-gap); - padding: var(--dock-pad); + height: var(--recipe-control-size, 2.95rem); + gap: 0.01rem; + padding: 0.24rem; border-radius: var(--dock-radius); } #app-bottom-nav .nav-tab, #app-bottom-nav .nav-action { - width: 2.02rem; - height: 2.02rem; + width: 1.7rem; + height: 1.7rem; border-radius: 999px; } #app-bottom-nav .nav-tab.is-active { - width: min(100%, 4.4rem); - height: 2.65rem; - padding: 0.3rem 0.22rem 0.27rem; + width: min(100%, 3.72rem); + height: 2.25rem; + padding: 0.2rem 0.18rem 0.18rem; border-radius: 999px; } #app-bottom-nav .nav-label { @@ -1117,6 +1157,21 @@ #app-bottom-nav .nav-tab.is-active::after { font-size: 0.56rem; } + #app-bottom-nav.is-double-compact .nav-tab.is-active::after { + font-size: 0.5rem; + line-height: 1.24; + } + #app-bottom-nav.is-double-compact .nav-tab.is-active { + height: 2.3rem; + padding: 0.18rem 0.18rem 0.24rem; + } + #app-bottom-nav.is-compact-tab .bottom-dock { + width: calc(var(--recipe-dock-width) - var(--nav-compact-extra-width, 0px)); + transform: translate( + var(--nav-compact-translate-x, 0px), + calc(var(--recipe-controls-lift, 0px) * -1) + ); + } } /* Planner and common interactive surfaces */ diff --git a/js/ui/bottomNav.js b/js/ui/bottomNav.js index 4f3c6ba..6f1ccca 100644 --- a/js/ui/bottomNav.js +++ b/js/ui/bottomNav.js @@ -43,10 +43,13 @@ export function setupBottomNav({ refreshPantry, refreshShoppingList } = {}) { if (!main || !planner || !pantry || !shopping || !nav) return; const TABS = ['recipes', 'planner', 'pantry', 'shopping']; - const COLLAPSED_TABS = new Set(['recipes', 'pantry']); + const COLLAPSED_TABS = new Set(); + const EXTRA_CONTROL_SLOTS = { recipes: 2, pantry: 2, shopping: 1 }; + const DOUBLE_COMPACT_TABS = new Set(['recipes', 'pantry']); const COLLAPSED_TAB_ICON = { recipes: 'fa-book-open', pantry: 'fa-warehouse' }; const COLLAPSED_TAB_LABEL = { recipes: 'Otwórz menu katalogu', pantry: 'Otwórz menu spiżarni' }; let isRecipeMenuOpen = false; + let activeTab = 'planner'; let previousTab = 'planner'; let collapseTimer = null; @@ -67,24 +70,27 @@ export function setupBottomNav({ refreshPantry, refreshShoppingList } = {}) { const columnGap = (isCompact ? 0.05 : 0.06) * rootFontSize; const dockLeft = navPadLeft + ((navContentWidth - dockWidth) / 2); const controlSize = (isCompact ? 2.95 : 3.05) * rootFontSize; - const expandedDockHeight = (isCompact ? 3.48 : 3.72) * rootFontSize; + const expandedDockHeight = controlSize; const controlGap = 0.5 * rootFontSize; const controlsLift = Math.max(0, (expandedDockHeight - controlSize) / 2); const collapsedDockWidth = controlSize; const collapsedSlotWidth = Math.max(32, collapsedDockWidth - padLeft - padRight); - const filterLeft = Math.max( - dockLeft + collapsedDockWidth + controlGap, - dockLeft + dockWidth - padRight - controlSize, - ); + const controlCluster = controlSize + controlGap; + const compactExtraWidth = (EXTRA_CONTROL_SLOTS[activeTab] || 0) * controlCluster; + const filterLeft = dockLeft + dockWidth - controlSize; + const searchButtonLeft = filterLeft - controlGap - controlSize; const searchRight = Math.max(16, nav.clientWidth - filterLeft + controlGap); nav.style.setProperty('--recipe-dock-width', `${dockWidth}px`); nav.style.setProperty('--recipe-collapsed-dock-width', `${collapsedDockWidth}px`); nav.style.setProperty('--recipe-toggle-size', `${collapsedSlotWidth}px`); + nav.style.setProperty('--nav-compact-extra-width', `${compactExtraWidth}px`); + nav.style.setProperty('--nav-compact-translate-x', `${compactExtraWidth * -0.5}px`); document.documentElement.style.setProperty('--recipe-dock-width', `${dockWidth}px`); document.documentElement.style.setProperty('--catalog-menu-left', `${dockLeft}px`); document.documentElement.style.setProperty('--catalog-menu-width', `${collapsedDockWidth}px`); document.documentElement.style.setProperty('--catalog-filter-left', `${filterLeft}px`); + document.documentElement.style.setProperty('--catalog-search-btn-left', `${searchButtonLeft}px`); document.documentElement.style.setProperty('--catalog-search-right', `${searchRight}px`); document.documentElement.style.setProperty('--recipe-control-size', `${controlSize}px`); document.documentElement.style.setProperty('--recipe-controls-lift', `${controlsLift}px`); @@ -115,11 +121,16 @@ export function setupBottomNav({ refreshPantry, refreshShoppingList } = {}) { const apply = (tab) => { const wasCollapsedTab = COLLAPSED_TABS.has(previousTab); const isCollapsedTab = COLLAPSED_TABS.has(tab); + const isCompactTab = (EXTRA_CONTROL_SLOTS[tab] || 0) > 0; + const isDoubleCompact = DOUBLE_COMPACT_TABS.has(tab); main.classList.toggle('hidden', tab !== 'recipes'); planner.classList.toggle('hidden', tab !== 'planner'); pantry.classList.toggle('hidden', tab !== 'pantry'); shopping.classList.toggle('hidden', tab !== 'shopping'); nav.classList.toggle('is-collapsed-tab', isCollapsedTab); + nav.classList.toggle('is-compact-tab', isCompactTab); + nav.classList.toggle('is-double-compact', isDoubleCompact); + activeTab = tab; updateToggleForTab(tab); syncRecipeNavMetrics(); setRecipeMenuOpen(false); @@ -167,6 +178,8 @@ export function setupBottomNav({ refreshPantry, refreshShoppingList } = {}) { window.closeRecipeSearch?.(); window.closePantrySearch?.(); window.closePantryFilter?.(); + window.closeShoppingCalendar?.(); + window.closeShoppingBoughtPopup?.(); window.closeFilters?.(); return; } diff --git a/js/views/Pantry.js b/js/views/Pantry.js index 92bef0e..68b42aa 100644 --- a/js/views/Pantry.js +++ b/js/views/Pantry.js @@ -97,6 +97,8 @@ let isFilterOpen = false; let calendarMonthAnchor = startOfMonth(horizonEndDate); let pantryGlobalListenersBound = false; let pantryCalendar = null; +let pantrySearchQuery = ''; +let pantrySearchOpen = false; let pantryFilters = { categories: [], sections: [], @@ -206,7 +208,7 @@ export function getPantryHTML() { -
+
@@ -221,19 +223,22 @@ export function getPantryHTML() {
-
-
+
+
+ +
+
-
@@ -250,6 +255,11 @@ function syncHorizonUI() { const popover = document.getElementById('pantry-calendar-popover'); const filterPopover = document.getElementById('pantry-filter-popover'); const filterCount = document.getElementById('pantry-filter-count'); + const searchWrap = document.getElementById('pantry-search-wrap'); + const searchShell = document.getElementById('pantry-search-shell'); + const rightBtn = document.getElementById('pantry-filter-bottom-btn'); + const rightIcon = document.getElementById('pantry-right-btn-icon'); + const searchDot = document.getElementById('pantry-search-active-dot'); const compactLabel = document.getElementById('pantry-horizon-compact-label'); const compactPill = document.getElementById('pantry-horizon-compact'); const chevron = document.getElementById('pantry-horizon-chevron'); @@ -277,9 +287,18 @@ function syncHorizonUI() { } if (filterCount) { filterCount.textContent = String(activeFilterCount); - filterCount.classList.toggle('hidden', activeFilterCount === 0); - filterCount.classList.toggle('flex', activeFilterCount > 0); + filterCount.classList.toggle('hidden', pantrySearchOpen || activeFilterCount === 0); + filterCount.classList.toggle('flex', !pantrySearchOpen && activeFilterCount > 0); } + if (searchWrap) searchWrap.classList.toggle('hidden', pantrySearchOpen); + if (searchShell) { + searchShell.style.opacity = pantrySearchOpen ? '1' : '0'; + searchShell.style.pointerEvents = pantrySearchOpen ? 'auto' : 'none'; + searchShell.style.transform = pantrySearchOpen ? 'translateY(0) scale(1)' : 'translateY(0.45rem) scale(0.98)'; + } + if (rightIcon) rightIcon.className = `fas ${pantrySearchOpen ? 'fa-xmark' : 'fa-sliders-h'}`; + if (rightBtn) rightBtn.setAttribute('aria-label', pantrySearchOpen ? 'Zamknij wyszukiwanie' : 'Otwórz filtry'); + if (searchDot) searchDot.classList.toggle('hidden', !pantrySearchQuery); renderCalendarPopover(); renderFilterPopover(); @@ -370,15 +389,32 @@ function renderFilterPopover() { } function clearSearchInput() { - const input = document.getElementById('pantry-search-input'); - const hadQuery = Boolean(input?.value); - if (input) { - input.value = ''; - input.blur(); - } + const hadQuery = Boolean(pantrySearchQuery); + pantrySearchQuery = ''; if (hadQuery) renderBoard(); } +function setPantrySearchOpen(open, { clearQuery = false, focusInput = false } = {}) { + const hadQuery = Boolean(pantrySearchQuery); + pantrySearchOpen = open; + document.documentElement.classList.toggle('is-inline-search-open', pantrySearchOpen); + if (clearQuery) pantrySearchQuery = ''; + const input = document.getElementById('pantry-search-input'); + if (input) { + if (open) { + input.value = pantrySearchQuery; + if (focusInput) { + input.focus(); + input.setSelectionRange(input.value.length, input.value.length); + } + } else { + input.blur(); + } + } + syncHorizonUI(); + if (clearQuery && hadQuery) renderBoard(); +} + function closeCalendar() { if (!isCalendarOpen) return; isCalendarOpen = false; @@ -405,9 +441,9 @@ function closeFilter() { } function toggleFilterPanel() { + if (pantrySearchOpen) return; isCalendarOpen = false; isFilterOpen = !isFilterOpen; - document.getElementById('pantry-search-input')?.blur(); syncHorizonUI(); } @@ -571,7 +607,7 @@ function renderBoard() { const root = document.getElementById('pantry-board'); if (!root) return; - const q = document.getElementById('pantry-search-input')?.value || ''; + const q = pantrySearchQuery; const hasFilters = hasActivePantryFilters(); const { shortfalls, sufficient, notPlanned } = classifyIngredients(q); @@ -661,15 +697,25 @@ export function setupPantry() { renderBoard(); // Search - document.getElementById('pantry-search-input')?.addEventListener('input', () => renderBoard()); + document.getElementById('pantry-search-btn')?.addEventListener('click', (event) => { + event.stopPropagation(); + setPantrySearchOpen(true, { focusInput: true }); + }); + document.getElementById('pantry-search-input')?.addEventListener('input', (event) => { + pantrySearchQuery = event.target.value.trim(); + renderBoard(); + }); document.getElementById('pantry-search-input')?.addEventListener('keydown', (event) => { if (event.key !== 'Escape') return; - if (event.target.value) clearSearchInput(); - else event.target.blur(); + event.stopPropagation(); + setPantrySearchOpen(false, { clearQuery: true }); }); - document.getElementById('pantry-search-close')?.addEventListener('click', () => clearSearchInput()); document.getElementById('pantry-filter-bottom-btn')?.addEventListener('click', (event) => { event.stopPropagation(); + if (pantrySearchOpen) { + setPantrySearchOpen(false, { clearQuery: true }); + return; + } toggleFilterPanel(); }); document.getElementById('pantry-filter-clear')?.addEventListener('click', (event) => { @@ -729,15 +775,20 @@ export function setupPantry() { }); document.addEventListener('keydown', (event) => { if (event.key !== 'Escape') return; + if (pantrySearchOpen) { + setPantrySearchOpen(false, { clearQuery: true }); + return; + } + if (pantrySearchQuery) clearSearchInput(); if (isFilterOpen) closeFilter(); }); window.addEventListener('app-tab-change', () => { - document.getElementById('pantry-search-input')?.blur(); + if (pantrySearchOpen) setPantrySearchOpen(false); closeFilter(); closeCalendar(); }); window.closePantrySearch = () => { - document.getElementById('pantry-search-input')?.blur(); + if (pantrySearchOpen) setPantrySearchOpen(false); }; window.closePantryFilter = () => { closeFilter(); diff --git a/js/views/RecipeList.js b/js/views/RecipeList.js index ea67326..b19a870 100644 --- a/js/views/RecipeList.js +++ b/js/views/RecipeList.js @@ -13,6 +13,7 @@ let filterState = { }; let recipeListDocListenersBound = false; +let recipeSearchOpen = false; function matchesFilters(recipe) { const { query, slots, tags, minMinutes, maxMinutes } = filterState; @@ -43,29 +44,62 @@ function getFilteredRecipes() { } function syncRecipeScrollShadow() { - const searchShell = document.getElementById('recipe-search-shell'); - if (searchShell) { - searchShell.style.boxShadow = 'var(--shadow-shell)'; - } + syncRecipeTopbarUI(); } function syncRecipeTopbarUI() { + const searchWrap = document.getElementById('recipe-search-wrap'); const searchShell = document.getElementById('recipe-search-shell'); + const rightBtn = document.getElementById('recipe-filter-btn'); + const rightIcon = document.getElementById('recipe-right-btn-icon'); + const filterCount = document.getElementById('recipe-filter-count'); + const dot = document.getElementById('recipe-search-active-dot'); + const isOpen = recipeSearchOpen; + if (searchWrap) searchWrap.classList.toggle('hidden', isOpen); if (searchShell) { - searchShell.style.boxShadow = 'var(--shadow-shell)'; + searchShell.style.opacity = isOpen ? '1' : '0'; + searchShell.style.pointerEvents = isOpen ? 'auto' : 'none'; + searchShell.style.transform = isOpen ? 'translateY(0) scale(1)' : 'translateY(0.45rem) scale(0.98)'; + } + if (rightIcon) { + rightIcon.className = `fas ${isOpen ? 'fa-xmark' : 'fa-sliders-h'}`; + } + if (rightBtn) { + rightBtn.setAttribute('aria-label', isOpen ? 'Zamknij wyszukiwanie' : 'Otwórz filtry'); + } + if (filterCount) { + const activeCount = Number.parseInt(filterCount.textContent || '0', 10) || 0; + const showCount = !isOpen && activeCount > 0; + filterCount.classList.toggle('hidden', !showCount); + filterCount.classList.toggle('flex', showCount); + } + if (dot) { + const hasQuery = Boolean(filterState.query); + dot.classList.toggle('hidden', !hasQuery); } } -function closeSearch() { - const input = document.getElementById('recipe-search-input'); - const hadQuery = Boolean(input?.value); - if (input) { - input.value = ''; - input.blur(); +function setSearchOpen(open, { clearQuery = false, focusInput = false } = {}) { + const hadQuery = Boolean(filterState.query); + recipeSearchOpen = open; + document.documentElement.classList.toggle('is-inline-search-open', recipeSearchOpen); + if (clearQuery) { + filterState.query = ''; + } + const input = document.getElementById('recipe-search-input'); + if (input) { + if (open) { + input.value = filterState.query; + if (focusInput) { + input.focus(); + input.setSelectionRange(input.value.length, input.value.length); + } + } else { + input.blur(); + } } - filterState.query = ''; syncRecipeTopbarUI(); - if (hadQuery) renderGrid(); + if (clearQuery && hadQuery) renderGrid(); } function renderGrid() { @@ -96,19 +130,22 @@ export function getRecipeListHTML() { emptyTitle: 'Brak wyników', emptyMessage: 'Zmień kryteria wyszukiwania lub filtry', })} -
-
+
+
+ +
+
-
@@ -137,20 +174,25 @@ export function refreshRecipeList() { export function setupRecipeList() { renderGrid(); + document.getElementById('recipe-search-btn')?.addEventListener('click', (e) => { + e.stopPropagation(); + setSearchOpen(true, { focusInput: true }); + }); document.getElementById('recipe-search-input')?.addEventListener('input', (e) => { filterState.query = e.target.value.trim(); renderGrid(); }); document.getElementById('recipe-search-input')?.addEventListener('keydown', (e) => { if (e.key !== 'Escape') return; - if (e.target.value) closeSearch(); - else e.target.blur(); + e.stopPropagation(); + setSearchOpen(false, { clearQuery: true }); }); - - document.getElementById('recipe-search-close')?.addEventListener('click', () => closeSearch()); document.getElementById('recipe-filter-btn')?.addEventListener('click', (e) => { e.stopPropagation(); - document.getElementById('recipe-search-input')?.blur(); + if (recipeSearchOpen) { + setSearchOpen(false, { clearQuery: true }); + return; + } window.openFilters?.('recipes'); }); @@ -167,16 +209,18 @@ export function setupRecipeList() { const isRecipeViewVisible = !document.getElementById('main-view')?.classList.contains('hidden'); if (e.key !== 'Escape') return; if (isRecipeViewVisible) { - document.getElementById('recipe-search-input')?.blur(); + if (recipeSearchOpen) setSearchOpen(false, { clearQuery: true }); } }); window.addEventListener('app-tab-change', () => { - document.getElementById('recipe-search-input')?.blur(); + if (recipeSearchOpen) setSearchOpen(false); + syncRecipeTopbarUI(); }); window.closeRecipeSearch = () => { - document.getElementById('recipe-search-input')?.blur(); + if (recipeSearchOpen) setSearchOpen(false); + syncRecipeTopbarUI(); }; } } diff --git a/js/views/ShoppingList.js b/js/views/ShoppingList.js index a088544..1bcf06a 100644 --- a/js/views/ShoppingList.js +++ b/js/views/ShoppingList.js @@ -18,6 +18,7 @@ import { addDays, startOfDay, startOfMonth } from '../services/dateUtils.js'; import { createSwipePopoverCalendarHTML, initSwipePopoverCalendar } from '../ui/swipePopoverCalendar.js'; import { createCalendarPopoverController, createCalendarPopoverHTML } from '../ui/calendarPopover.js'; import { showAppToast } from '../ui/toast.js'; +import { ensureFilterPopoverStyles } from '../ui/filterPopover.js?v=1'; /* ── helpers ── */ @@ -118,20 +119,13 @@ function groupByCategory(items) { export function getShoppingListHTML() { return `