Close shared header dropdowns on outside click and Escape
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
{% set _uiux_full_width_header = ('System Admin' in (ui_roles|default([], true))) or ('Firm Admin' in (ui_roles|default([], true))) or ('Partner' in (ui_roles|default([], true))) or ('Manager' in (ui_roles|default([], true))) or ('Branch Manager' in (ui_roles|default([], true))) or ('Staff' in (ui_roles|default([], true))) or ('Employee' in (ui_roles|default([], true))) or ('Client' in (ui_roles|default([], true))) or ('Consultant' in (ui_roles|default([], true))) %}
|
||||
<header class="sticky top-0 z-40 border-b border-slate-200/70 {{ 'bg-white/95' if _uiux_full_width_header else 'bg-slate-100/85' }} backdrop-blur-xl">
|
||||
<header data-uiux-shared-header="true" class="sticky top-0 z-40 border-b border-slate-200/70 {{ 'bg-white/95' if _uiux_full_width_header else 'bg-slate-100/85' }} backdrop-blur-xl">
|
||||
<div class="{{ 'w-full px-4 py-3 sm:px-6 lg:px-8' if _uiux_full_width_header else 'mx-auto max-w-[1500px] px-3 py-3 sm:px-6 lg:px-8' }}">
|
||||
<div class="{{ 'border-0 bg-transparent px-0 py-0 shadow-none' if _uiux_full_width_header else 'rounded-3xl border border-slate-200 bg-white/95 px-3 py-3 shadow-soft sm:px-4' }}">
|
||||
<div class="flex items-center gap-2 sm:gap-3">
|
||||
@@ -141,3 +141,85 @@
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
if (window.__uiuxSharedHeaderDropdownAutoCloseV1) {
|
||||
return;
|
||||
}
|
||||
window.__uiuxSharedHeaderDropdownAutoCloseV1 = true;
|
||||
|
||||
function getHeader() {
|
||||
return document.querySelector('[data-uiux-shared-header="true"]');
|
||||
}
|
||||
|
||||
function getDropdowns() {
|
||||
var header = getHeader();
|
||||
return header ? Array.prototype.slice.call(header.querySelectorAll('details')) : [];
|
||||
}
|
||||
|
||||
function closeDropdown(dropdown) {
|
||||
if (dropdown && dropdown.open) {
|
||||
dropdown.open = false;
|
||||
}
|
||||
}
|
||||
|
||||
function closeAll(exceptDropdown) {
|
||||
getDropdowns().forEach(function (dropdown) {
|
||||
if (dropdown !== exceptDropdown) {
|
||||
closeDropdown(dropdown);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('click', function (event) {
|
||||
var header = getHeader();
|
||||
if (!header) {
|
||||
return;
|
||||
}
|
||||
|
||||
var clickedDropdown = event.target.closest('details');
|
||||
if (!clickedDropdown || !header.contains(clickedDropdown)) {
|
||||
closeAll(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.target.closest('a[href]')) {
|
||||
closeDropdown(clickedDropdown);
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', function (event) {
|
||||
if (event.key !== 'Escape') {
|
||||
return;
|
||||
}
|
||||
|
||||
var openDropdowns = getDropdowns().filter(function (dropdown) {
|
||||
return dropdown.open;
|
||||
});
|
||||
|
||||
if (!openDropdowns.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
openDropdowns.forEach(closeDropdown);
|
||||
|
||||
var lastDropdown = openDropdowns[openDropdowns.length - 1];
|
||||
var summary = lastDropdown.querySelector('summary');
|
||||
if (summary && typeof summary.focus === 'function') {
|
||||
summary.focus();
|
||||
}
|
||||
});
|
||||
|
||||
getDropdowns().forEach(function (dropdown) {
|
||||
dropdown.addEventListener('toggle', function () {
|
||||
if (dropdown.open) {
|
||||
closeAll(dropdown);
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user