codecheck
135 строк · 2.8 Кб
1<script setup lang="ts">
2interface dropdownItem {
3name: String;
4to: String;
5}
6
7interface Props {
8items: dropdownItem[];
9}
10
11const props = defineProps<Props>();
12const dropdown = ref();
13const open = ref(false);
14
15const handleOpen = () => {
16const closeListerner = (e: Event) => {
17if (!(e.target === dropdown.value || dropdown.value?.contains(e.target)))
18window.removeEventListener("click", closeListerner), (open.value = false);
19};
20window.addEventListener("click", closeListerner);
21open.value = !open.value;
22};
23
24const logout = async () => {
25await useFetch("/api/auth/logout", {
26method: "POST",
27});
28const user = useUser();
29user.value = null;
30// console.log(user.value, userAuth.value);
31await navigateTo("/login");
32};
33</script>
34
35<template>
36<div
37ref="dropdown"
38@click="handleOpen()"
39class="nav__item_dropdown"
40:aria-expanded="open"
41>
42<button class="nav__btn">
43<span> <slot /> </span>
44
45<svg
46xmlns="http://www.w3.org/2000/svg"
47viewBox="0 0 20 20"
48fill="currentColor"
49class="nav__icon"
50>
51<path
52fill-rule="evenodd"
53d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z"
54clip-rule="evenodd"
55/>
56</svg>
57</button>
58
59<div class="dropdown">
60<NuxtLink
61v-for="item in props.items"
62:to="item.to"
63class="dropdown__item"
64>{{ item.name }}</NuxtLink
65>
66<button class="dropdown__item" @click="logout">Выйти</button>
67</div>
68</div>
69</template>
70
71<style scoped lang="scss">
72.nav {
73&__btn {
74padding: 1rem 0;
75display: flex;
76align-items: center;
77position: relative;
78text-decoration: none;
79color: var(--color-text-link);
80// &:hover {
81// color: var(--color-primary);
82// }
83
84// .dropdown & {
85// padding: 1rem 2rem;
86// min-width: 100%;
87// }
88}
89&__item_dropdown {
90font-size: 1rem;
91position: relative;
92cursor: pointer;
93&[aria-expanded="true"] .dropdown {
94display: flex;
95opacity: 1;
96visibility: visible;
97}
98}
99&__icon {
100width: 1.5rem;
101height: 1.5rem;
102}
103}
104.dropdown {
105position: absolute;
106background: white;
107// display: none;
108opacity: 0;
109visibility: hidden;
110flex-direction: column;
111// align-items: flex-start;
112top: 100%;
113right: 0;
114left: 0;
115min-width: fit-content;
116overflow: hidden;
117transition: all 0.3s ease 0s;
118&__item {
119white-space: nowrap;
120padding: 0.5rem;
121display: flex;
122align-items: center;
123position: relative;
124background: none;
125// font-size: 1rem;
126// font-weight: 600;
127text-decoration: none;
128color: var(--color-text-link);
129// width: 100%;
130&:hover {
131background: rgba(128, 128, 128, 0.057);
132}
133}
134}
135</style>
136