584 lines
25 KiB
Vue
584 lines
25 KiB
Vue
// src/components/Header.vue
|
|
<template>
|
|
<header
|
|
v-if="appStore.headerData"
|
|
:style="`background-image: url('${appStore.imageBaseUrl}${appStore.headerData.header_background.url}'); background-size: cover; background-position: center;`"
|
|
class="relative z-10"
|
|
>
|
|
<nav ref="navbarRef" class="navbar p-2 md:p-4 shadow-md" :style="{ backgroundColor: appStore.headerData.mainColor }">
|
|
<div class="container mx-auto flex items-center justify-between w-full">
|
|
|
|
<div class="navbar-start w-auto flex-shrink-0">
|
|
<router-link to="/home" class="flex flex-col items-start leading-tight">
|
|
<span class="text-white text-lg font-bold">
|
|
{{ appStore.checkLang.isTh ? 'ฮิวแมนเทคไทยแลนด์' : 'HumanTech' }}
|
|
</span>
|
|
<span class="text-white text-xs opacity-80">
|
|
{{ appStore.checkLang.isTh ? 'HumanTech' : 'ฮิวแมนเทคไทยแลนด์' }}
|
|
</span>
|
|
</router-link>
|
|
</div>
|
|
|
|
<div class="navbar-center hidden md:flex flex-1 items-center justify-end space-x-2 lg:space-x-4">
|
|
<ul class="menu menu-horizontal px-1 flex-nowrap">
|
|
<li v-for="menu in orderedMainMenus" :key="menu.id" class="relative">
|
|
<template v-if="menu.sub_menu_groups && menu.sub_menu_groups.length || (menu.sub_menus && menu.sub_menus.length)">
|
|
<button
|
|
class="text-white font-semibold text-base hover:bg-gray-700 hover:text-white py-2 px-3 rounded-md flex items-center gap-1"
|
|
:ref="el => menuButtonRefs.set(menu.id, el)"
|
|
@click="toggleDropdown(menu.id, menu.sub_menu_groups, menu.sub_menus)"
|
|
>
|
|
<span>{{ appStore.checkLang.isTh ? menu.main_menu : menu.main_menu_en }}</span>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
viewBox="0 0 20 20"
|
|
fill="currentColor"
|
|
class="w-4 h-4 transition-transform duration-200"
|
|
:class="{ 'rotate-180': activeMenuId === menu.id }"
|
|
>
|
|
<path fill-rule="evenodd" d="M5.23 7.21a.75.75 0 011.06.02L10 10.94l3.71-3.71a.75.75 0 111.06 1.06l-4.25 4.25a.75.75 0 01-1.06 0L5.23 8.27a.75.75 0 01.02-1.06z" clip-rule="evenodd" />
|
|
</svg>
|
|
</button>
|
|
</template>
|
|
<template v-else>
|
|
<router-link
|
|
:to="menu.link"
|
|
class="text-white font-semibold text-base hover:bg-gray-700 hover:text-white py-2 px-3 rounded-md"
|
|
:ref="el => menuButtonRefs.set(menu.id, el)"
|
|
@click="activeMenuId = null"
|
|
>
|
|
{{ appStore.checkLang.isTh ? menu.main_menu : menu.main_menu_en }}
|
|
</router-link>
|
|
</template>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="flex items-center space-x-0 ml-4">
|
|
<button class="btn btn-sm rounded-l-lg rounded-r-none normal-case text-base font-bold px-4 py-2"
|
|
:class="isLangButtonActive('th') ? 'active-lang-button' : 'inactive-lang-button'"
|
|
:disabled="isLangButtonActive('th')"
|
|
@click="switchLanguageToThai">TH</button>
|
|
<button class="btn btn-sm rounded-r-lg rounded-l-none normal-case text-base font-bold px-4 py-2"
|
|
:class="isLangButtonActive('en') ? 'active-lang-button' : 'inactive-lang-button'"
|
|
:disabled="isLangButtonActive('en')"
|
|
@click="switchLanguageToEnglish">EN</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="navbar-end md:hidden">
|
|
<div class="dropdown dropdown-end relative">
|
|
<div role="button" class="btn btn-ghost text-white hover:bg-gray-700" ref="mobileMenuToggleButtonRef" @click="isMobileMenuOpen = !isMobileMenuOpen">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none"
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M4 6h16M4 12h16M4 18h16"/>
|
|
</svg>
|
|
</div>
|
|
<ul
|
|
v-if="isMobileMenuOpen"
|
|
class="absolute top-full right-0 z-[9999] mt-2 w-screen max-w-xs bg-base-100 shadow rounded-box p-4 text-black max-h-[80vh] overflow-y-auto"
|
|
ref="mobileMenuDropdownRef"
|
|
>
|
|
<li v-for="menu in orderedMainMenus" :key="menu.id" class="mb-2">
|
|
<template v-if="menu.sub_menu_groups && menu.sub_menu_groups.length > 0">
|
|
<details :open="activeMobileMenuId === menu.id" @toggle="handleMobileDetailsToggle(menu.id, $event)">
|
|
<summary class="cursor-pointer py-2 font-semibold text-base hover:bg-gray-200 rounded px-2 flex items-center justify-between">
|
|
<span>{{ appStore.checkLang.isTh ? menu.main_menu : menu.main_menu_en }}</span>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
viewBox="0 0 20 20"
|
|
fill="currentColor"
|
|
class="w-4 h-4 transition-transform duration-200"
|
|
:class="{ 'rotate-180': activeMobileMenuId === menu.id }"
|
|
>
|
|
<path fill-rule="evenodd" d="M5.23 7.21a.75.75 0 011.06.02L10 10.94l3.71-3.71a.75.75 0 111.06 1.06l-4.25 4.25a.75.75 0 01-1.06 0L5.23 8.27a.75.75 0 01.02-1.06z" clip-rule="evenodd" />
|
|
</svg>
|
|
</summary>
|
|
<ul class="pl-4 py-2 bg-base-100">
|
|
<template v-for="group in orderedSubMenuGroups(menu.sub_menu_groups)" :key="group.group_title_th">
|
|
<li v-if="group.group_title_th || group.group_title_en" class="font-bold text-sm text-gray-700 mt-2 mb-1">
|
|
{{ appStore.checkLang.isTh ? group.group_title_th : group.group_title_en }}
|
|
</li>
|
|
<li v-for="subMenu in (appStore.checkLang.isTh ? orderedSubMenuItems(group.items) : orderedSubMenuItemsEng(group.items))"
|
|
:key="subMenu.id">
|
|
<router-link :to="subMenu.link" class="block py-1 px-2 rounded mobile-submenu-item" @click="closeMobileMenu">
|
|
{{ appStore.checkLang.isTh ? subMenu.title_th : subMenu.title_en }}
|
|
</router-link>
|
|
</li>
|
|
</template>
|
|
</ul>
|
|
</details>
|
|
</template>
|
|
|
|
<template v-else-if="menu.sub_menus && menu.sub_menus.length > 0">
|
|
<details :open="activeMobileMenuId === menu.id" @toggle="handleMobileDetailsToggle(menu.id, $event)">
|
|
<summary class="cursor-pointer py-2 font-semibold text-base hover:bg-gray-200 rounded px-2 flex items-center justify-between">
|
|
<span>{{ appStore.checkLang.isTh ? menu.main_menu : menu.main_menu_en }}</span>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
viewBox="0 0 20 20"
|
|
fill="currentColor"
|
|
class="w-4 h-4 transition-transform duration-200"
|
|
:class="{ 'rotate-180': activeMobileMenuId === menu.id }"
|
|
>
|
|
<path fill-rule="evenodd" d="M5.23 7.21a.75.75 0 011.06.02L10 10.94l3.71-3.71a.75.75 0 111.06 1.06l-4.25 4.25a.75.75 0 01-1.06 0L5.23 8.27a.75.75 0 01.02-1.06z" clip-rule="evenodd" />
|
|
</svg>
|
|
</summary>
|
|
<ul class="pl-4 py-2 bg-base-100">
|
|
<li v-for="subMenu in (appStore.checkLang.isTh ? orderedSubMenuItems(menu.sub_menus) : orderedSubMenuItemsEng(menu.sub_menus))"
|
|
:key="subMenu.id">
|
|
<router-link :to="subMenu.link" class="block py-1 px-2 rounded mobile-submenu-item" @click="closeMobileMenu">
|
|
{{ appStore.checkLang.isTh ? subMenu.title_th : subMenu.title_en }}
|
|
</router-link>
|
|
</li>
|
|
</ul>
|
|
</details>
|
|
</template>
|
|
|
|
<template v-else>
|
|
<router-link
|
|
:to="menu.link"
|
|
class="block py-2 px-2 font-semibold text-base hover:bg-gray-200 rounded"
|
|
@click="closeMobileMenu">
|
|
{{ appStore.checkLang.isTh ? menu.main_menu : menu.main_menu_en }}
|
|
</router-link>
|
|
</template>
|
|
</li>
|
|
|
|
<li class="mt-4">
|
|
<div class="flex items-center justify-around w-full p-2">
|
|
<button
|
|
class="btn btn-sm rounded-l-lg rounded-r-none normal-case text-base font-bold px-4 py-2 w-1/2"
|
|
:class="isLangButtonActive('th') ? 'active-lang-button' : 'inactive-lang-button-mobile'"
|
|
:disabled="isLangButtonActive('th')"
|
|
@click="switchLanguageToThai"
|
|
>
|
|
TH
|
|
</button>
|
|
<button
|
|
class="btn btn-sm rounded-r-lg rounded-l-none normal-case text-base font-bold px-4 py-2 w-1/2"
|
|
:class="isLangButtonActive('en') ? 'active-lang-button' : 'inactive-lang-button-mobile'"
|
|
:disabled="isLangButtonActive('en')"
|
|
@click="switchLanguageToEnglish"
|
|
>
|
|
EN
|
|
</button>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
</nav>
|
|
|
|
<div
|
|
v-if="activeMenuId !== null"
|
|
class="absolute bg-white shadow-lg rounded p-4 z-50 desktop-dropdown"
|
|
:style="dropdownStyles"
|
|
ref="desktopDropdownRef"
|
|
>
|
|
<template v-if="activeDropdownData.sub_menu_groups && activeDropdownData.sub_menu_groups.length">
|
|
<div class="multi-column-dropdown-content">
|
|
<div
|
|
v-for="(group, groupIndex) in orderedSubMenuGroups(activeDropdownData.sub_menu_groups)"
|
|
:key="groupIndex"
|
|
class="flex flex-col"
|
|
>
|
|
<h3 v-if="group.group_title_th || group.group_title_en" class="font-bold text-lg mb-2 text-gray-700 whitespace-nowrap">
|
|
{{ appStore.checkLang.isTh ? group.group_title_th : group.group_title_en }}
|
|
</h3>
|
|
<ul class="space-y-1">
|
|
<li
|
|
v-for="subMenu in (appStore.checkLang.isTh ? orderedSubMenuItems(group.items) : orderedSubMenuItemsEng(group.items))"
|
|
:key="subMenu.id"
|
|
>
|
|
<router-link :to="subMenu.link" class="desktop-submenu-item block py-1 px-0 text-sm whitespace-nowrap" @click="closeDropdown">
|
|
{{ appStore.checkLang.isTh ? subMenu.title_th : subMenu.title_en }}
|
|
</router-link>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template v-else-if="activeDropdownData.sub_menus && activeDropdownData.sub_menus.length">
|
|
<ul class="single-column-dropdown-content">
|
|
<li
|
|
v-for="subMenu in (appStore.checkLang.isTh ? orderedSubMenuItems(activeDropdownData.sub_menus) : orderedSubMenuItemsEng(activeDropdownData.sub_menus))"
|
|
:key="subMenu.id"
|
|
>
|
|
<router-link :to="subMenu.link" class="desktop-submenu-item block py-1 px-0 text-sm whitespace-nowrap" @click="closeDropdown">
|
|
{{ appStore.checkLang.isTh ? subMenu.title_th : subMenu.title_en }}
|
|
</router-link>
|
|
</li>
|
|
</ul>
|
|
</template>
|
|
</div>
|
|
</header>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, onMounted, nextTick, watch } from 'vue';
|
|
import { useAppStore } from '@/stores/app';
|
|
import _ from 'lodash';
|
|
|
|
const appStore = useAppStore();
|
|
|
|
// State for active desktop menu dropdown
|
|
const activeMenuId = ref(null);
|
|
const activeDropdownData = ref({}); // Stores the data (sub_menu_groups/sub_menus) for the active dropdown
|
|
const dropdownStyles = ref({}); // Stores the dynamic CSS styles for the active dropdown
|
|
|
|
// Refs for DOM elements
|
|
const navbarRef = ref(null); // Reference to the <nav> element
|
|
const menuButtonRefs = new Map(); // Map to store references to each menu button (summary/router-link)
|
|
const desktopDropdownRef = ref(null); // Reference to the floating desktop dropdown container
|
|
|
|
// State for active mobile menu dropdown (uses DaisyUI details behavior)
|
|
const activeMobileMenuId = ref(null);
|
|
// New state for controlling mobile menu visibility
|
|
const isMobileMenuOpen = ref(false); // <--- NEW STATE
|
|
|
|
// New refs for mobile menu elements
|
|
const mobileMenuDropdownRef = ref(null); // Reference to the <ul> element that acts as the mobile dropdown container
|
|
const mobileMenuToggleButtonRef = ref(null); // Reference to the button that toggles the mobile menu (hamburger icon)
|
|
|
|
|
|
// --- Computed Properties for Menu Ordering ---
|
|
const orderedMainMenus = computed(() => {
|
|
const menus = appStore.allMainMenus || [];
|
|
const active = menus.filter(m => appStore.checkLang.isTh ? m.active : m.active_en);
|
|
const home = active.find(m => m.id === 1); // Assuming ID 1 is always Home
|
|
const others = active.filter(m => m.id !== 1);
|
|
return home ? [home, ..._.orderBy(others, 'order')] : _.orderBy(active, 'order');
|
|
});
|
|
|
|
const orderedSubMenuGroups = groups => _.orderBy(groups || [], 'order');
|
|
const orderedSubMenuItems = items => _.orderBy((items || []).filter(f => f.active), 'order');
|
|
const orderedSubMenuItemsEng = items => _.orderBy((items || []).filter(f => f.active_en), 'order');
|
|
|
|
|
|
// --- Desktop Dropdown Logic ---
|
|
const toggleDropdown = async (menuId, subMenuGroups, subMenus) => {
|
|
// If clicking the same menu, close it
|
|
if (activeMenuId.value === menuId) {
|
|
activeMenuId.value = null;
|
|
activeDropdownData.value = {};
|
|
return;
|
|
}
|
|
|
|
activeMenuId.value = menuId;
|
|
activeDropdownData.value = {
|
|
sub_menu_groups: subMenuGroups,
|
|
sub_menus: subMenus
|
|
};
|
|
|
|
// Wait for DOM to update with the new active dropdown
|
|
await nextTick();
|
|
|
|
const button = menuButtonRefs.get(menuId); // Get the specific button ref
|
|
if (button && navbarRef.value && desktopDropdownRef.value) {
|
|
const buttonRect = button.getBoundingClientRect();
|
|
const navbarRect = navbarRef.value.getBoundingClientRect();
|
|
const dropdownRect = desktopDropdownRef.value.getBoundingClientRect();
|
|
|
|
const dropdownTop = navbarRect.bottom + window.scrollY; // Position right below the navbar
|
|
|
|
let dropdownLeft = buttonRect.left + window.scrollX; // Default align to button left
|
|
let transform = 'translateX(0)';
|
|
|
|
// Adjust for overflow on right side
|
|
const spaceToRight = window.innerWidth - (buttonRect.left + dropdownRect.width);
|
|
if (spaceToRight < 20) { // If less than 20px space to right, align right
|
|
dropdownLeft = buttonRect.right + window.scrollX - dropdownRect.width;
|
|
}
|
|
|
|
// Adjust for overflow on left side
|
|
if (dropdownLeft < 10) { // If less than 10px from left edge
|
|
dropdownLeft = 10 + window.scrollX;
|
|
}
|
|
|
|
dropdownStyles.value = {
|
|
top: `${dropdownTop}px`,
|
|
left: `${dropdownLeft}px`,
|
|
minWidth: `${buttonRect.width}px`,
|
|
transform: transform,
|
|
maxWidth: `calc(100vw - 40px)`,
|
|
};
|
|
}
|
|
};
|
|
|
|
const closeDropdown = () => {
|
|
activeMenuId.value = null;
|
|
activeDropdownData.value = {};
|
|
};
|
|
|
|
|
|
// --- Mobile Dropdown Logic (uses DaisyUI details behavior) ---
|
|
const handleMobileDetailsToggle = (menuId, event) => {
|
|
if (event.target.open) {
|
|
// Close other open details elements in the same mobile menu list
|
|
document.querySelectorAll('ul[ref="mobileMenuDropdownRef"] details[open]').forEach(detail => { // Corrected selector
|
|
if (detail !== event.target) detail.open = false;
|
|
});
|
|
activeMobileMenuId.value = menuId;
|
|
} else {
|
|
activeMobileId.value = null; // Changed from activeMobileMenuId.value = null; due to typo, ensure consistent
|
|
}
|
|
};
|
|
|
|
const closeMobileMenu = () => {
|
|
isMobileMenuOpen.value = false; // <--- NEW: Set state to close the main menu
|
|
activeMobileMenuId.value = null; // Close any open details within the mobile menu
|
|
// Also, close any open details by iterating directly
|
|
// This line is often not strictly necessary if `activeMobileMenuId` is properly managed,
|
|
// but acts as a fallback to ensure all <details> are closed.
|
|
document.querySelectorAll('ul[ref="mobileMenuDropdownRef"] details[open]').forEach(detail => {
|
|
detail.open = false;
|
|
});
|
|
};
|
|
|
|
|
|
// --- Language Switch Logic ---
|
|
const switchLanguageToThai = () => {
|
|
// Only switch if not already Thai
|
|
if (!appStore.checkLang.isTh) {
|
|
appStore.toggleLanguage('th');
|
|
closeMobileMenu(); // Use the new function for mobile
|
|
closeDropdown();
|
|
}
|
|
};
|
|
const switchLanguageToEnglish = () => {
|
|
// Only switch if not already English (i.e., if currently Thai)
|
|
if (appStore.checkLang.isTh) {
|
|
appStore.toggleLanguage('en');
|
|
closeMobileMenu(); // Use the new function for mobile
|
|
closeDropdown();
|
|
}
|
|
};
|
|
const isLangButtonActive = computed(() => lang => {
|
|
return (lang === 'th' && appStore.checkLang.isTh) || (lang === 'en' && !appStore.checkLang.isTh);
|
|
});
|
|
|
|
|
|
// --- Lifecycle Hooks and Watchers ---
|
|
onMounted(() => {
|
|
// Set initial language from localStorage
|
|
const savedLang = localStorage.getItem('lang');
|
|
if (savedLang === 'en') {
|
|
appStore.isTh = false;
|
|
} else {
|
|
appStore.isTh = true;
|
|
}
|
|
|
|
// Event listener for clicks outside dropdowns to close them
|
|
document.addEventListener('click', (event) => {
|
|
// Desktop dropdown close logic
|
|
if (activeMenuId.value !== null && desktopDropdownRef.value) {
|
|
const dropdownElement = desktopDropdownRef.value;
|
|
const clickedButton = menuButtonRefs.get(activeMenuId.value);
|
|
|
|
// Check if click is inside the desktop dropdown or the button that opened it
|
|
if (!dropdownElement.contains(event.target) && (!clickedButton || !clickedButton.contains(event.target))) {
|
|
closeDropdown();
|
|
}
|
|
}
|
|
|
|
// Mobile dropdown close logic
|
|
// Only check if mobile menu is currently open
|
|
if (isMobileMenuOpen.value && mobileMenuDropdownRef.value && mobileMenuToggleButtonRef.value) {
|
|
const mobileDropdownElement = mobileMenuDropdownRef.value;
|
|
const mobileToggleButton = mobileMenuToggleButtonRef.value;
|
|
|
|
// Check if click is outside the mobile dropdown container AND outside the toggle button
|
|
if (!mobileDropdownElement.contains(event.target) && !mobileToggleButton.contains(event.target)) {
|
|
closeMobileMenu();
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
// Watch for window resize to adjust desktop dropdown position
|
|
window.addEventListener('resize', () => {
|
|
if (activeMenuId.value !== null) {
|
|
// Re-calculate position for the currently open desktop dropdown
|
|
const currentMenu = orderedMainMenus.value.find(m => m.id === activeMenuId.value);
|
|
if (currentMenu) {
|
|
toggleDropdown(activeMenuId.value, currentMenu.sub_menu_groups, currentMenu.sub_menus);
|
|
}
|
|
}
|
|
// For mobile, if the screen size changes to desktop, close mobile menu
|
|
if (window.innerWidth >= 768 && isMobileMenuOpen.value) { // 768px is Tailwind's 'md' breakpoint
|
|
closeMobileMenu();
|
|
}
|
|
});
|
|
});
|
|
|
|
// Watch for activeMenuId change to trigger position adjustment
|
|
watch(activeMenuId, (newId, oldId) => {
|
|
if (newId !== null) {
|
|
// Re-trigger toggleDropdown to recalculate position if the menu data itself is needed
|
|
// The actual data is passed into toggleDropdown
|
|
}
|
|
});
|
|
|
|
// Watch for language change to adjust dropdown position if needed (due to text width changes)
|
|
watch(() => appStore.checkLang.isTh, () => {
|
|
if (activeMenuId.value !== null) {
|
|
const currentMenu = orderedMainMenus.value.find(m => m.id === activeMenuId.value);
|
|
if (currentMenu) {
|
|
toggleDropdown(activeMenuId.value, currentMenu.sub_menu_groups, currentMenu.sub_menus);
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
/*
|
|
GLOBAL STYLES FOR DESKTOP DROPDOWN CONTAINER (The one that floats)
|
|
*/
|
|
.desktop-dropdown {
|
|
background-color: white;
|
|
padding: 1.5rem; /* p-4 in example template was p-6 for multi-column originally */
|
|
border-radius: 0.5rem;
|
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06);
|
|
z-index: 1000; /* Ensure it's above other content */
|
|
}
|
|
|
|
/*
|
|
STYLES FOR MULTI-COLUMN CONTENT INSIDE THE FLOATING DROPDOWN
|
|
*/
|
|
.multi-column-dropdown-content {
|
|
display: grid;
|
|
grid-auto-flow: column; /* Force content into columns first */
|
|
grid-auto-columns: max-content; /* Each column takes only as much width as its widest content */
|
|
gap: 2rem; /* Gap between columns */
|
|
overflow-x: auto; /* Allow horizontal scrolling if columns still overflow */
|
|
min-width: 200px; /* Base min width for the content area itself */
|
|
}
|
|
|
|
/*
|
|
STYLES FOR SINGLE-COLUMN CONTENT INSIDE THE FLOATING DROPDOWN
|
|
*/
|
|
.single-column-dropdown-content {
|
|
min-width: 200px; /* Base min width for the content area itself */
|
|
}
|
|
|
|
/* --- NEW: Desktop Submenu Item Hover Effect --- */
|
|
.desktop-submenu-item {
|
|
color: #333; /* Default text color for desktop submenu items */
|
|
padding: 0.25rem 0.5rem; /* py-1 px-2 */
|
|
display: block;
|
|
white-space: nowrap; /* Prevent menu item text from wrapping */
|
|
position: relative; /* Needed for pseudo-elements if used, or for absolute child */
|
|
transition: all 0.2s ease-in-out; /* Smooth transition for all properties */
|
|
border: 1px solid transparent; /* Start with transparent border */
|
|
border-radius: 0.25rem; /* Match rounded-md */
|
|
}
|
|
|
|
.desktop-submenu-item:hover {
|
|
background-color: #EBF8FF; /* blue-100 for light background */
|
|
color: #2563EB; /* blue-600 for text */
|
|
border-color: #60A5FA; /* blue-400 for border */
|
|
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
}
|
|
|
|
/* --- NEW: Mobile Submenu Item Hover Effect --- */
|
|
.mobile-submenu-item {
|
|
color: #333; /* Default text color for mobile submenu items */
|
|
padding: 0.25rem 0.5rem; /* block py-1 px-2 */
|
|
display: block;
|
|
border-radius: 0.25rem; /* Match rounded */
|
|
transition: all 0.2s ease-in-out; /* Smooth transition */
|
|
border: 1px solid transparent; /* Start with transparent border */
|
|
}
|
|
|
|
.mobile-submenu-item:hover {
|
|
background-color: #EBF8FF; /* blue-100 for light background */
|
|
color: #2563EB; /* blue-600 for text */
|
|
border-color: #60A5FA; /* blue-400 for border */
|
|
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
}
|
|
|
|
|
|
/* --- Language Button Styles --- */
|
|
.active-lang-button {
|
|
background-color: #e0e0e0;
|
|
color: #333;
|
|
border: 1px solid #ccc;
|
|
cursor: default; /* Change cursor to indicate it's not clickable */
|
|
}
|
|
|
|
.inactive-lang-button {
|
|
background-color: transparent;
|
|
color: #fff;
|
|
border: 1px solid rgba(255, 255, 255, 0.5);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.inactive-lang-button:hover {
|
|
background-color: rgba(255, 255, 255, 0.1);
|
|
color: #fff;
|
|
}
|
|
|
|
/* Styles for disabled state to reduce visual clutter */
|
|
.active-lang-button[disabled] {
|
|
opacity: 0.7; /* Make it slightly transparent */
|
|
cursor: default; /* Ensure cursor is default */
|
|
background-color: #e0e0e0; /* Maintain active background */
|
|
color: #333; /* Maintain active text color */
|
|
}
|
|
|
|
|
|
/* Specific border adjustments for the language buttons to match the image */
|
|
.active-lang-button:first-child, .inactive-lang-button:first-child { border-right: none; }
|
|
.active-lang-button:last-child, .inactive-lang-button:last-child { border-left: none; }
|
|
.flex.items-center.space-x-0 > .btn:not(:first-child) { margin-left: 0; }
|
|
.flex.items-center.space-x-0 > .btn:not(:last-child) { margin-right: 0; }
|
|
|
|
.inactive-lang-button-mobile {
|
|
background-color: transparent;
|
|
color: #333;
|
|
border: 1px solid #ccc;
|
|
cursor: pointer;
|
|
}
|
|
.inactive-lang-button-mobile:first-child { border-right: none; }
|
|
.inactive-lang-button-mobile:last-child { border-left: none; }
|
|
|
|
/* Styles for disabled state on mobile buttons */
|
|
.inactive-lang-button-mobile[disabled] {
|
|
opacity: 0.7;
|
|
cursor: default;
|
|
background-color: #e0e0e0; /* Match active-lang-button */
|
|
color: #333;
|
|
}
|
|
|
|
/*
|
|
MOBILE MENU STYLES (largely unchanged, using DaisyUI dropdown-end behavior)
|
|
*/
|
|
.navbar-end.md\:hidden .dropdown-content {
|
|
position: absolute;
|
|
top: 100%; /* Relative to the dropdown-end parent */
|
|
right: 0;
|
|
width: screen; /* Full width on small screens */
|
|
max-width: 280px; /* Constrain max width for mobile dropdown */
|
|
margin-top: 0.5rem; /* mt-2 */
|
|
z-index: 9999;
|
|
padding: 1rem; /* p-4 */
|
|
box-sizing: border-box;
|
|
max-height: 80vh;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.navbar-end.md\:hidden .dropdown-content .font-bold.text-sm.text-gray-700 { /* This targets the group title */
|
|
margin-top: 0.5rem; /* mt-2 */
|
|
margin-bottom: 0.25rem; /* mb-1 */
|
|
padding-left: 0.5rem; /* Consistent padding */
|
|
padding-right: 0.5rem;
|
|
}
|
|
.navbar-end.md\:hidden .dropdown-content ul.pl-4 { /* Targets the ul for sub-items in mobile */
|
|
padding-left: 1rem; /* Indent mobile sub-items */
|
|
}
|
|
|
|
</style> |