mirror of
https://github.com/wahyd4/links.git
synced 2026-08-09 05:06:16 +10:00
Update dropdown style
This commit is contained in:
@@ -6,18 +6,29 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
const languageOptions = document.getElementById('language-options');
|
const languageOptions = document.getElementById('language-options');
|
||||||
|
|
||||||
const isMobile = () => window.innerWidth < 768; // matches Tailwind's md breakpoint
|
const isMobile = () => window.innerWidth < 768; // matches Tailwind's md breakpoint
|
||||||
|
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||||
|
const ANIM_MS = reduceMotion ? 0 : 320;
|
||||||
|
|
||||||
|
function isOpen(dropdown) {
|
||||||
|
return dropdown ? dropdown.classList.contains('menu-open') : false;
|
||||||
|
}
|
||||||
|
|
||||||
function openDropdown(dropdown) {
|
function openDropdown(dropdown) {
|
||||||
dropdown.classList.remove('hidden');
|
dropdown.classList.add('menu-open');
|
||||||
if (isMobile()) {
|
if (isMobile()) {
|
||||||
document.body.style.overflow = 'hidden';
|
document.body.style.overflow = 'hidden';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeDropdown(dropdown) {
|
function closeDropdown(dropdown) {
|
||||||
dropdown.classList.add('hidden');
|
dropdown.classList.remove('menu-open');
|
||||||
if (isMobile()) {
|
if (isMobile()) {
|
||||||
document.body.style.overflow = '';
|
// Release body scroll only after the slide-up animation finishes
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!isOpen(moreMenuDropdown) && !isOpen(languageOptions)) {
|
||||||
|
document.body.style.overflow = '';
|
||||||
|
}
|
||||||
|
}, ANIM_MS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,12 +36,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
button.addEventListener('click', function(e) {
|
button.addEventListener('click', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (dropdown.classList.contains('hidden')) {
|
if (!isOpen(dropdown)) {
|
||||||
// Close other dropdown first
|
// Close other dropdown first
|
||||||
if (dropdown === moreMenuDropdown && languageOptions && !languageOptions.classList.contains('hidden')) {
|
if (dropdown === moreMenuDropdown && isOpen(languageOptions)) {
|
||||||
closeDropdown(languageOptions);
|
closeDropdown(languageOptions);
|
||||||
}
|
}
|
||||||
if (dropdown === languageOptions && moreMenuDropdown && !moreMenuDropdown.classList.contains('hidden')) {
|
if (dropdown === languageOptions && isOpen(moreMenuDropdown)) {
|
||||||
closeDropdown(moreMenuDropdown);
|
closeDropdown(moreMenuDropdown);
|
||||||
}
|
}
|
||||||
openDropdown(dropdown);
|
openDropdown(dropdown);
|
||||||
@@ -58,31 +69,25 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
// Close dropdowns when clicking outside
|
// Close dropdowns when clicking outside
|
||||||
document.addEventListener('click', function(e) {
|
document.addEventListener('click', function(e) {
|
||||||
if (moreMenuDropdown && !moreMenuButton.contains(e.target) && !moreMenuDropdown.contains(e.target)) {
|
if (moreMenuDropdown && !moreMenuButton.contains(e.target) && !moreMenuDropdown.contains(e.target)) {
|
||||||
closeDropdown(moreMenuDropdown);
|
if (isOpen(moreMenuDropdown)) closeDropdown(moreMenuDropdown);
|
||||||
}
|
}
|
||||||
if (languageOptions && !languageSelectorButton.contains(e.target) && !languageOptions.contains(e.target)) {
|
if (languageOptions && !languageSelectorButton.contains(e.target) && !languageOptions.contains(e.target)) {
|
||||||
closeDropdown(languageOptions);
|
if (isOpen(languageOptions)) closeDropdown(languageOptions);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Close dropdowns on Escape key
|
// Close dropdowns on Escape key
|
||||||
document.addEventListener('keydown', function(e) {
|
document.addEventListener('keydown', function(e) {
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
if (moreMenuDropdown && !moreMenuDropdown.classList.contains('hidden')) {
|
if (isOpen(moreMenuDropdown)) closeDropdown(moreMenuDropdown);
|
||||||
closeDropdown(moreMenuDropdown);
|
if (isOpen(languageOptions)) closeDropdown(languageOptions);
|
||||||
}
|
|
||||||
if (languageOptions && !languageOptions.classList.contains('hidden')) {
|
|
||||||
closeDropdown(languageOptions);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle window resize: close mobile overlay if resizing to desktop
|
// Handle window resize: close mobile overlay if resizing to desktop
|
||||||
window.addEventListener('resize', function() {
|
window.addEventListener('resize', function() {
|
||||||
if (!isMobile()) {
|
if (!isMobile()) {
|
||||||
if (moreMenuDropdown && !moreMenuDropdown.classList.contains('hidden')) {
|
document.body.style.overflow = '';
|
||||||
document.body.style.overflow = '';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -112,4 +117,4 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
lastScrollTop = scrollTop;
|
lastScrollTop = scrollTop;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
+35
-2
@@ -46,6 +46,39 @@
|
|||||||
transition: top 0.3s ease-in-out;
|
transition: top 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Animated nav dropdowns.
|
||||||
|
We toggle a `.menu-open` class instead of `hidden` so that CSS
|
||||||
|
opacity/transform transitions run on open and close. */
|
||||||
|
#more-menu-dropdown,
|
||||||
|
#language-options {
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
transform: translateY(-10px);
|
||||||
|
transition: opacity 0.22s ease, transform 0.22s cubic-bezier(0.28, 0.11, 0.32, 1);
|
||||||
|
}
|
||||||
|
#more-menu-dropdown.menu-open,
|
||||||
|
#language-options.menu-open {
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: auto;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
/* Mobile: full-screen overlay slides down from the top */
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
#more-menu-dropdown {
|
||||||
|
transform: translateY(-12px);
|
||||||
|
transition: opacity 0.28s ease, transform 0.32s cubic-bezier(0.28, 0.11, 0.32, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
#more-menu-dropdown,
|
||||||
|
#language-options,
|
||||||
|
#more-menu-dropdown.menu-open,
|
||||||
|
#language-options.menu-open {
|
||||||
|
transition: none;
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Line clamp utilities for truncating text */
|
/* Line clamp utilities for truncating text */
|
||||||
.line-clamp-2 {
|
.line-clamp-2 {
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
@@ -71,7 +104,7 @@
|
|||||||
<i class="fas fa-bars mr-2"></i>
|
<i class="fas fa-bars mr-2"></i>
|
||||||
{% trans "Menu" %}
|
{% trans "Menu" %}
|
||||||
</button>
|
</button>
|
||||||
<div id="more-menu-dropdown" class="fixed inset-0 top-[57px] w-full rounded-none overflow-y-auto md:absolute md:inset-auto md:top-auto md:right-0 md:mt-2 md:w-48 md:rounded-md md:overflow-visible bg-white shadow-xl z-20 hidden">
|
<div id="more-menu-dropdown" class="fixed inset-0 top-[57px] w-full rounded-none overflow-y-auto md:absolute md:inset-auto md:top-auto md:right-0 md:mt-2 md:w-48 md:rounded-md md:overflow-visible bg-white shadow-xl z-20">
|
||||||
<div class="grid grid-cols-3 gap-0.5 p-1.5 md:grid-cols-1 md:gap-0 md:p-0">
|
<div class="grid grid-cols-3 gap-0.5 p-1.5 md:grid-cols-1 md:gap-0 md:p-0">
|
||||||
<a href="{% url 'search' %}" class="flex flex-col items-center justify-center p-2.5 rounded-lg md:flex-row md:justify-start md:px-4 md:py-2 md:rounded-none transition-colors text-gray-700 hover:bg-gray-100">
|
<a href="{% url 'search' %}" class="flex flex-col items-center justify-center p-2.5 rounded-lg md:flex-row md:justify-start md:px-4 md:py-2 md:rounded-none transition-colors text-gray-700 hover:bg-gray-100">
|
||||||
<svg class="w-6 h-6 mb-1 md:w-5 md:h-5 md:mr-2 md:mb-0 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-6 h-6 mb-1 md:w-5 md:h-5 md:mr-2 md:mb-0 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
@@ -233,7 +266,7 @@
|
|||||||
{% get_language_info for LANGUAGE_CODE as current_language %}
|
{% get_language_info for LANGUAGE_CODE as current_language %}
|
||||||
{{ current_language.code|upper }}
|
{{ current_language.code|upper }}
|
||||||
</button>
|
</button>
|
||||||
<div id="language-options" class="absolute right-0 mt-2 py-2 w-48 bg-white rounded-md shadow-xl z-20 hidden">
|
<div id="language-options" class="absolute right-0 mt-2 py-2 w-48 bg-white rounded-md shadow-xl z-20">
|
||||||
<form action="{% url 'set_language' %}" method="post" id="language-form">
|
<form action="{% url 'set_language' %}" method="post" id="language-form">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<input name="next" type="hidden" value="{{ request.path }}">
|
<input name="next" type="hidden" value="{{ request.path }}">
|
||||||
|
|||||||
Reference in New Issue
Block a user