Skip to content

Commit b8e5d43

Browse files
committed
feat(components): добавить навигацию на мобиле
1 parent a839145 commit b8e5d43

File tree

4 files changed

+222
-81
lines changed

4 files changed

+222
-81
lines changed

src/app.vue

Lines changed: 214 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,118 @@
11
<script setup lang="ts">
2-
import { RouterView } from 'vue-router'
2+
import { RouterView, useRoute } from 'vue-router'
33
import { ERoutes } from '@/router/routes.ts'
4+
import { onMounted, ref, watch } from 'vue'
5+
6+
const routesMap = {
7+
[ERoutes.Main]: 'Главная',
8+
[ERoutes.List]: 'Связный список',
9+
[ERoutes.Stack]: 'Стек',
10+
[ERoutes.Queue]: 'Очередь',
11+
[ERoutes.Tree]: 'Дерево',
12+
[ERoutes.Graph]: 'Граф',
13+
[ERoutes.Set]: 'Множество',
14+
[ERoutes.Array]: 'Массив',
15+
[ERoutes.Map]: 'Карта',
16+
}
17+
18+
const routesArray = [
19+
ERoutes.Main,
20+
ERoutes.List,
21+
ERoutes.Stack,
22+
ERoutes.Queue,
23+
ERoutes.Tree,
24+
ERoutes.Graph,
25+
ERoutes.Set,
26+
ERoutes.Array,
27+
ERoutes.Map,
28+
]
29+
30+
const isNavbarActive = ref<boolean>(false)
31+
32+
const toggleNavbarState = () => {
33+
isNavbarActive.value = !isNavbarActive.value
34+
}
35+
36+
const route = useRoute()
37+
const prev = ref<{ name: string; link: string } | null>(null)
38+
const next = ref<{ name: string; link: string } | null>(null)
39+
40+
const updatePrevAndNextRoutes = () => {
41+
const currentRoute = route.path
42+
const currentRouteIndex = routesArray.indexOf(currentRoute as ERoutes)
43+
const _prev = routesArray[currentRouteIndex - 1] ?? routesArray[routesArray.length - 1]
44+
const _next = routesArray[currentRouteIndex + 1] ?? routesArray[0]
45+
46+
prev.value = { name: routesMap[_prev], link: _prev }
47+
next.value = { name: routesMap[_next], link: _next }
48+
}
49+
50+
onMounted(() => {
51+
updatePrevAndNextRoutes()
52+
})
53+
54+
watch(
55+
() => route.path,
56+
() => {
57+
updatePrevAndNextRoutes()
58+
},
59+
)
460
</script>
561

662
<template>
763
<main class="main">
864
<aside class="sidebar">
9-
<router-link class="sidebar__item" :to="ERoutes.Main">
10-
<span>Главная</span>
11-
</router-link>
12-
<router-link class="sidebar__item" :to="ERoutes.List">
13-
<span>Связный список</span>
14-
</router-link>
15-
<router-link class="sidebar__item" :to="ERoutes.Stack">
16-
<span>Стек</span>
17-
</router-link>
18-
<router-link class="sidebar__item" :to="ERoutes.Queue">
19-
<span>Очередь</span>
20-
</router-link>
21-
<router-link class="sidebar__item" :to="ERoutes.Tree">
22-
<span>Дерево</span>
23-
</router-link>
24-
<router-link class="sidebar__item" :to="ERoutes.Graph">
25-
<span>Граф</span>
26-
</router-link>
27-
<router-link class="sidebar__item" :to="ERoutes.Array">
28-
<span>Массив</span>
29-
</router-link>
30-
<router-link class="sidebar__item" :to="ERoutes.Map">
31-
<span>Карта</span>
32-
</router-link>
33-
<router-link class="sidebar__item" :to="ERoutes.Set">
34-
<span>Множество</span>
65+
<router-link v-for="(value, key) in routesMap" :key="key" class="sidebar__item" :to="key">
66+
<span>{{ value }}</span>
3567
</router-link>
3668
</aside>
3769

3870
<div class="content container">
3971
<RouterView />
4072
</div>
73+
74+
<div class="navigation">
75+
<router-link v-if="prev" :to="prev.link" class="navigation__prev"
76+
>◀️ {{ prev.name }}</router-link
77+
>
78+
<router-link v-if="next" :to="next.link" class="navigation__next"
79+
>{{ next.name }} ▶️</router-link
80+
>
81+
</div>
82+
83+
<div
84+
class="navbar"
85+
:class="{ 'navbar--active': isNavbarActive }"
86+
@click="isNavbarActive = false"
87+
>
88+
<div class="navbar__content" @click.stop="toggleNavbarState">
89+
<div class="navbar__container container">
90+
<div v-if="isNavbarActive" class="navbar__routes" @click.stop="toggleNavbarState">
91+
<router-link
92+
v-for="(value, key) in routesMap"
93+
:key="key"
94+
class="navbar__routes__item"
95+
:to="key"
96+
>
97+
<span>{{ value }}</span>
98+
</router-link>
99+
</div>
100+
<div class="navbar__actions">
101+
<span v-if="!isNavbarActive">🔼 Меню</span>
102+
<span v-else>🔽 Меню</span>
103+
104+
<div class="navbar__links">
105+
<a target="_blank" href="https://t.me/anti_pode"
106+
><img src="@/assets/icons/tg.svg" alt="" />Тимофей</a
107+
>
108+
<a target="_blank" href="https://t.me/anotherUselessNickname"
109+
><img src="@/assets/icons/tg.svg" alt="" />Руслан</a
110+
>
111+
</div>
112+
</div>
113+
</div>
114+
</div>
115+
</div>
41116
</main>
42117
</template>
43118

@@ -118,4 +193,116 @@ import { ERoutes } from '@/router/routes.ts'
118193
padding: 10px 10px 40px 10px;
119194
}
120195
}
196+
197+
.navigation {
198+
position: fixed;
199+
left: 0;
200+
right: 0;
201+
bottom: 42px;
202+
display: flex;
203+
background-color: $app-background;
204+
205+
@include from-mobile {
206+
display: none;
207+
}
208+
209+
&__prev,
210+
&__next {
211+
width: 50%;
212+
padding: 4px 6px;
213+
outline: 1px solid #ccc;
214+
color: $color-black-text;
215+
text-align: center;
216+
text-decoration: none;
217+
}
218+
219+
&__prev {
220+
margin-right: auto;
221+
}
222+
223+
&__next {
224+
margin-left: auto;
225+
}
226+
}
227+
228+
.navbar {
229+
position: fixed;
230+
top: 0;
231+
left: 0;
232+
right: 0;
233+
bottom: 0;
234+
pointer-events: none;
235+
236+
@include from-mobile {
237+
display: none;
238+
}
239+
240+
&--active {
241+
pointer-events: auto;
242+
}
243+
244+
&__container {
245+
padding: 10px;
246+
border-top: 1px solid #ccc;
247+
}
248+
249+
&__content {
250+
position: fixed;
251+
left: 0;
252+
right: 0;
253+
bottom: 0;
254+
background-color: $app-background;
255+
pointer-events: auto;
256+
}
257+
258+
&__routes {
259+
display: flex;
260+
flex-direction: column;
261+
width: 100%;
262+
margin-bottom: 10px;
263+
padding-bottom: 4px;
264+
border-bottom: 1px solid #ccc;
265+
266+
&__item {
267+
padding: 4px 0;
268+
color: #909090;
269+
text-decoration: none;
270+
271+
&.router-link-active {
272+
color: $color-black-text;
273+
}
274+
275+
&:first-child {
276+
padding-top: 0;
277+
}
278+
}
279+
}
280+
281+
&__actions {
282+
display: flex;
283+
align-items: center;
284+
width: 100%;
285+
286+
img {
287+
display: inline-block;
288+
}
289+
290+
a {
291+
white-space: nowrap;
292+
293+
img {
294+
width: 1.2em;
295+
height: 1.2em;
296+
margin-right: 4px;
297+
margin-bottom: -4px;
298+
}
299+
}
300+
}
301+
302+
&__links {
303+
display: flex;
304+
margin-left: auto;
305+
gap: 10px;
306+
}
307+
}
121308
</style>

src/assets/styles/_breakpoints.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ $from_mobile: #{$mobile + 1px};
3232

3333
// from
3434
@mixin from-tablet {
35-
@media (min-width: $tablet) {
35+
@media (min-width: $from_tablet) {
3636
@content;
3737
}
3838
}
3939

4040
@mixin from-mobile {
41-
@media (min-width: $mobile) {
41+
@media (min-width: $from_mobile) {
4242
@content;
4343
}
4444
}

src/components/section/app-section.vue

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ defineProps({
2020
<template>
2121
<section class="section">
2222
<section class="section__header">
23-
<div v-if="hasBreadcrumbs" class="section__header__breadcrumbs">
24-
<router-link :to="ERoutes.Main">Главная</router-link>
25-
<span>/</span>
26-
<span>{{ title }}</span>
27-
</div>
23+
<!-- <div v-if="hasBreadcrumbs" class="section__header__breadcrumbs">-->
24+
<!-- <router-link :to="ERoutes.Main">Главная</router-link>-->
25+
<!-- <span>/</span>-->
26+
<!-- <span>{{ title }}</span>-->
27+
<!-- </div>-->
2828

2929
<h2 v-if="title" class="section__header__title">
3030
{{ title }}
@@ -134,6 +134,7 @@ defineProps({
134134
}
135135
136136
&__source {
137+
flex-shrink: 0;
137138
white-space: nowrap;
138139
font-size: 18px;
139140
font-weight: 400;

src/views/page-home.vue

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,9 @@
11
<script setup lang="ts">
22
import AppSection from '@/components/section/app-section.vue'
3-
import { ERoutes } from '@/router/routes.ts'
43
</script>
54

65
<template>
76
<div>
8-
<div class="menu">
9-
<div class="menu__items">
10-
<router-link :to="ERoutes.List">
11-
<span>Связный список</span>
12-
</router-link>
13-
<router-link :to="ERoutes.Stack">
14-
<span>Стек</span>
15-
</router-link>
16-
<router-link :to="ERoutes.Queue">
17-
<span>Очередь</span>
18-
</router-link>
19-
<router-link :to="ERoutes.Tree">
20-
<span>Дерево</span>
21-
</router-link>
22-
<router-link :to="ERoutes.Graph">
23-
<span>Граф</span>
24-
</router-link>
25-
<router-link :to="ERoutes.Array">
26-
<span>Массив</span>
27-
</router-link>
28-
<router-link :to="ERoutes.Map">
29-
<span>Карта</span>
30-
</router-link>
31-
<router-link :to="ERoutes.Set">
32-
<span>Множество</span>
33-
</router-link>
34-
</div>
35-
</div>
36-
377
<app-section title="О чем эта статья?" :has-breadcrumbs="false">
388
<div class="about">
399
<p>
@@ -106,21 +76,4 @@ import { ERoutes } from '@/router/routes.ts'
10676
padding-left: 0;
10777
}
10878
}
109-
110-
.menu {
111-
margin-bottom: 10px;
112-
113-
@include from-mobile {
114-
display: none;
115-
}
116-
117-
&__items {
118-
display: flex;
119-
flex-direction: column;
120-
}
121-
122-
p {
123-
margin: 0 0 4px 0;
124-
}
125-
}
12679
</style>

0 commit comments

Comments
 (0)