diff --git a/app/app.vue b/app/app.vue index f616b54..e775de4 100644 --- a/app/app.vue +++ b/app/app.vue @@ -1,698 +1,22 @@ - - - diff --git a/app/components/layout/AppNavbar.vue b/app/components/layout/AppNavbar.vue new file mode 100644 index 0000000..50eacb5 --- /dev/null +++ b/app/components/layout/AppNavbar.vue @@ -0,0 +1,368 @@ + + + + + diff --git a/app/composables/useNavDropdown.ts b/app/composables/useNavDropdown.ts new file mode 100644 index 0000000..be15873 --- /dev/null +++ b/app/composables/useNavDropdown.ts @@ -0,0 +1,65 @@ +import { ref, watch, onUnmounted } from 'vue' +import { useRoute } from '#imports' + +export function useNavDropdown() { + const openDropdown = ref(null) + let dropdownCloseTimer: ReturnType | null = null + const route = useRoute() + + const setDropdown = (name: string) => { + if (dropdownCloseTimer) { + clearTimeout(dropdownCloseTimer) + dropdownCloseTimer = null + } + if (openDropdown.value !== name) { + openDropdown.value = name + } + } + + const scheduleDropdownClose = (name: string) => { + if (dropdownCloseTimer) { + clearTimeout(dropdownCloseTimer) + } + dropdownCloseTimer = setTimeout(() => { + if (openDropdown.value === name) { + openDropdown.value = null + } + dropdownCloseTimer = null + }, 200) + } + + const closeDropdownNow = () => { + if (dropdownCloseTimer) { + clearTimeout(dropdownCloseTimer) + dropdownCloseTimer = null + } + openDropdown.value = null + } + + const toggleDropdown = (name: string) => { + if (openDropdown.value === name) { + closeDropdownNow() + return + } + setDropdown(name) + } + + watch(() => route.fullPath, () => { + closeDropdownNow() + }) + + onUnmounted(() => { + if (dropdownCloseTimer) { + clearTimeout(dropdownCloseTimer) + dropdownCloseTimer = null + } + }) + + return { + openDropdown, + setDropdown, + scheduleDropdownClose, + closeDropdownNow, + toggleDropdown, + } +}