diff --git a/website/modules/asset/ui/src/clientSideFiltering.js b/website/modules/asset/ui/src/clientSideFiltering.js index 51a2738b..98fa2307 100644 --- a/website/modules/asset/ui/src/clientSideFiltering.js +++ b/website/modules/asset/ui/src/clientSideFiltering.js @@ -1,5 +1,46 @@ // Client-side filtering for case studies with page reload +// No persistence needed for current requirement ("open if tag is selected"). + +const hasSelectedTagsInCategory = function (filterType) { + const selectedTags = document.querySelectorAll( + `#filter-content-${filterType} .tag-item.active`, + ); + return selectedTags.length > 0; +}; + +const isDesktop = function () { + return window.innerWidth > 1024; +}; + +const updateCategoriesVisibility = function () { + const checkboxes = document.querySelectorAll('.filter-category__toggle'); + checkboxes.forEach(function (checkbox) { + const filterType = checkbox.id.replace('filter-toggle-', ''); + const hasSelectedTags = hasSelectedTagsInCategory(filterType); + const isIndustryCategory = filterType === 'industry'; + + const shouldBeOpen = hasSelectedTags || (isIndustryCategory && isDesktop()); + if (shouldBeOpen && !checkbox.checked) { + checkbox.checked = true; + const button = document.querySelector(`label[for="${checkbox.id}"]`); + if (button) { + button.setAttribute('aria-expanded', 'true'); + } + } else if (!shouldBeOpen && checkbox.checked) { + checkbox.checked = false; + const button = document.querySelector(`label[for="${checkbox.id}"]`); + if (button) { + button.setAttribute('aria-expanded', 'false'); + } + } + }); +}; + +const initializeCategoriesVisibility = function () { + updateCategoriesVisibility(); +}; + const shouldInterceptClick = function (link) { const href = link.getAttribute('href'); return ( @@ -32,7 +73,6 @@ const handleFilterClick = function (event) { history.pushState({ clientSideFilter: true, url: newUrl }, '', newUrl); window.location.reload(); } catch { - // Fallback to default navigation if URL construction fails window.location.href = href; } }; @@ -43,11 +83,34 @@ const handlePopState = function (event) { } }; +const handleResize = function () { + updateCategoriesVisibility(); +}; + export const initClientSideFiltering = function () { if (!document.querySelector('.cs_list')) { return; } + initializeCategoriesVisibility(); + window.addEventListener('popstate', handlePopState); + window.addEventListener('resize', handleResize); document.addEventListener('click', handleFilterClick); + + // Keep aria-expanded in sync with checkbox state + document.addEventListener('change', function (event) { + const checkbox = event.target.closest('.filter-category__toggle'); + if (!checkbox) { + return; + } + const button = document.querySelector(`label[for="${checkbox.id}"]`); + if (button) { + if (checkbox.checked) { + button.setAttribute('aria-expanded', 'true'); + } else { + button.setAttribute('aria-expanded', 'false'); + } + } + }); }; diff --git a/website/modules/asset/ui/src/scss/_cases.scss b/website/modules/asset/ui/src/scss/_cases.scss index 87bba548..98b53b69 100644 --- a/website/modules/asset/ui/src/scss/_cases.scss +++ b/website/modules/asset/ui/src/scss/_cases.scss @@ -1286,14 +1286,14 @@ } &__content { - position: absolute; - left: 50%; - top: 50%; + position: sticky; + left: 20px; + right: 20px; + top: 90px; width: 90vw; max-width: 400px; - min-width: 320px; + min-width: 300px; background: #fff; - transform: translate(-50%, -50%); z-index: 2; padding: 0 16px 24px; max-height: 90vh; diff --git a/website/modules/case-studies-page/views/index.html b/website/modules/case-studies-page/views/index.html index 80e6780b..ef6ab143 100644 --- a/website/modules/case-studies-page/views/index.html +++ b/website/modules/case-studies-page/views/index.html @@ -95,11 +95,13 @@ tags and tags.length %}
+ {% set hasActiveFilter = data.query[filterType] %} + {% set shouldBeOpen = loop.first or hasActiveFilter %}
@@ -109,7 +111,7 @@ class="filter-category__expand-button" role="button" tabindex="0" - aria-expanded="{% if loop.first %}true{% else %}false{% endif %}" + aria-expanded="{% if shouldBeOpen %}true{% else %}false{% endif %}" aria-controls="filter-content-{{ filterType }}" aria-label="Toggle {{ filterLabel }} filter section" onkeydown="return true;"