added a sidebar drawer to improve mobile responsiveness

This commit is contained in:
wea_ondara
2023-09-28 17:26:40 +02:00
parent f551ad10ca
commit f839730ebb
8 changed files with 218 additions and 51 deletions

View File

@@ -5,6 +5,7 @@ import DocumentLocaleSetter from '@/components/locale/DocumentLocaleSetter.vue';
import NavBar from '@/components/NavBar.vue';
import LocaleSaver from '@/components/locale/LocaleSaver.vue';
import StoragePersist from '@/components/StoragePersist.vue';
import SideBar from '@/components/SideBar.vue';
@Options({
name: 'App',
@@ -13,20 +14,26 @@ import StoragePersist from '@/components/StoragePersist.vue';
LocaleSaver,
NavBar,
RouterView,
SideBar,
StoragePersist,
},
})
export default class App extends Vue {
sidebarToggled = false;
}
</script>
<template>
<div class="d-flex flex-column h-100 w-100">
<div class="h-100 w-100">
<LocaleSaver/>
<DocumentLocaleSetter/>
<StoragePersist/>
<NavBar/>
<SideBar ref="sidebar" class="h-100 w-100" :toggled="sidebarToggled"
@close="sidebarToggled=false"/>
<div class="d-flex flex-column h-100 w-100">
<NavBar @toggleSidebar="sidebarToggled = !sidebarToggled"/>
<RouterView class="flex-grow-1"/>
</div>
</div>
</template>

View File

@@ -13,6 +13,9 @@ import LocaleSelector from '@/components/locale/LocaleSelector.vue';
LocaleSelector,
MangaUpdatesUpdater,
},
emits: {
'toggleSidebar': undefined,
},
})
export default class NavBar extends Vue {
}
@@ -20,51 +23,52 @@ export default class NavBar extends Vue {
</script>
<template>
<nav class="navbar navbar-expand border-bottom shadow">
<div class="container-fluid">
<!-- <a class="navbar-brand" href="#">Navbar</a>-->
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<!-- <ul class="navbar-nav me-auto mb-2 mb-lg-0">-->
<!-- <li class="nav-item">-->
<!-- <a class="nav-link active" aria-current="page" href="#">Home</a>-->
<!-- </li>-->
<!-- <li class="nav-item">-->
<!-- <a class="nav-link" href="#">Link</a>-->
<!-- </li>-->
<!-- <li class="nav-item dropdown">-->
<!-- <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">-->
<!-- Dropdown-->
<!-- </a>-->
<!-- <ul class="dropdown-menu">-->
<!-- <li><a class="dropdown-item" href="#">Action</a></li>-->
<!-- <li><a class="dropdown-item" href="#">Another action</a></li>-->
<!-- <li>-->
<!-- <hr class="dropdown-divider">-->
<!-- </li>-->
<!-- <li><a class="dropdown-item" href="#">Something else here</a></li>-->
<!-- </ul>-->
<!-- </li>-->
<!-- <li class="nav-item">-->
<!-- <a class="nav-link disabled">Disabled</a>-->
<!-- </li>-->
<!-- </ul>-->
<div class="mx-auto">
<!-- z-index needed, otherwise shadow not showing -->
<nav class="navbar border-bottom shadow flex-nowrap" style="z-index: 1">
<div>
<div class="navbar-sidebar-toggler mx-1 c-pointer">
<i class="fa fa-bars me-2" @click="$emit('toggleSidebar')"/>
</div>
</div>
<div>
<div class="d-flex flex-row">
<AniListUserSearch class="mx-1"/>
<MangaUpdatesUpdater class="mx-1"/>
<AniListUserSearch class="me-2"/>
<MangaUpdatesUpdater class=""/>
</div>
</div>
<div>
<div class="d-flex flex-row align-items-center">
<LocaleSelector class="ms-2"/>
<BootstrapThemeSwitch class="ms-2"/>
</div>
</div>
<LocaleSelector class="navbar-locale-select"/>
<BootstrapThemeSwitch class="navbar-theme-switch ms-2"/>
</div>
</div>
</nav>
</template>
<style lang="scss">
@import 'bootstrap/scss/functions';
@import 'bootstrap/scss/variables';
@import 'bootstrap/scss/mixins/breakpoints';
@include media-breakpoint-down(sm) {
nav.navbar {
--bs-navbar-padding-x: 0.5rem;
}
nav.navbar .navbar-locale-select,
nav.navbar .navbar-theme-switch {
display: none;
}
}
@include media-breakpoint-up(sm) {
nav.navbar {
--bs-navbar-padding-x: 1rem;
}
nav.navbar .navbar-sidebar-toggler {
display: none;
}
}
</style>

View File

@@ -0,0 +1,87 @@
<script lang="ts">
import {Options, Vue} from 'vue-class-component';
import SideBarNavItem from '@/components/SideBarNavItem.vue';
import {Prop} from 'vue-property-decorator';
import LocaleSelector from '@/components/locale/LocaleSelector.vue';
import BootstrapThemeSwitch from '@/components/bootstrapThemeSwitch/BootstrapThemeSwitch.vue';
import SideBarHead from '@/components/SideBarHead.vue';
@Options({
name: 'SideBar',
components: {
BootstrapThemeSwitch,
LocaleSelector,
SideBarHead,
SideBarNavItem,
},
emits: {
'close': undefined,
},
})
export default class SideBar extends Vue {
@Prop({default: false})
toggled!: boolean;
}
</script>
<template>
<div :class="{ toggled: toggled }" class="sidebar border-right shadow bg-body">
<div class="d-flex flex-column">
<ul class="nav flex-column mb-auto">
<li>
<SideBarHead @close="$emit('close')"/>
</li>
<SideBarNavItem :text="$t('locale')" faIcon="fa-language">
<template #end>
<LocaleSelector class="navbar-locale-select me-1"/>
</template>
</SideBarNavItem>
<SideBarNavItem :text="$t('design')" faIcon="fa-moon">
<template #end>
<BootstrapThemeSwitch class="navbar-theme-switch"/>
</template>
</SideBarNavItem>
</ul>
</div>
</div>
</template>
<style lang="scss">
@import 'bootstrap/scss/functions';
@import 'bootstrap/scss/variables';
@import 'bootstrap/scss/mixins/breakpoints';
$width: 15em;
@include media-breakpoint-down(sm) {
.sidebar {
position: fixed;
top: 0;
left: 0;
width: $width;
max-width: #{'clamp(0em, '}$width#{', 100%)'};
transition: width ease-in-out 0.25s;
overflow-x: hidden;
overflow-y: auto;
z-index: 10000;
height: 100%;
&:not(.toggled) {
width: 0 !important;
}
.sidebar-nav-item {
border-top: 0;
border-bottom: 0;
}
}
}
@include media-breakpoint-up(sm) {
.sidebar {
display: none;
}
}
</style>

View File

@@ -0,0 +1,24 @@
<script lang="ts">
import {Options, Vue} from 'vue-class-component';
@Options({
name: 'SideBar',
components: {},
emits: {
'close': undefined,
},
})
export default class SideBar extends Vue {
}
</script>
<template>
<nav class="navbar border-bottom shadow flex-nowrap">
<div class="sidebar-closer mx-1 c-pointer">
<i class="fa fa-arrow-left me-2" @click="$emit('close')"/>
<!-- 'hack' to ensure this nav is the same height as the navbar -->
<input class="form-control d-inline mx-0 px-0" style="visibility: hidden; width: 0;"/>
</div>
</nav>
</template>

View File

@@ -0,0 +1,41 @@
<script lang="ts">
import {Options, Vue} from 'vue-class-component';
import {Prop} from 'vue-property-decorator';
@Options({
name: 'SideBarNavItem',
components: {},
})
export default class SideBarNavItem extends Vue {
@Prop({required: false})
faIcon!: string;
@Prop({required: false})
text!: string;
}
</script>
<template>
<li class="nav-item sidebar-nav-item">
<slot>
<div class="d-flex flex-row p-2 align-items-center">
<i :class="[faIcon]" class="sidebar-nav-item-icon text-center fa"></i>
<span class="sidebar-nav-item-text me-auto">{{ text }}</span>
<slot name="end"/>
</div>
</slot>
</li>
</template>
<style lang="scss" scoped>
.sidebar-nav-item-text {
opacity: 1;
overflow: hidden;
max-width: 10em;
transition: display ease-in-out 0.25s, opacity ease-in-out 0.25s, max-width ease-in-out 0.25s;
}
.sidebar-nav-item-icon {
width: 2em;
text-align: center;
}
</style>

View File

@@ -13,8 +13,8 @@ export default class LocaleSelector extends Vue {
get supportedLocales(): { value: string, text: string } [] {
return [
{value: 'en', text: this.$t('locale.en')},
{value: 'de', text: this.$t('locale.de')},
{value: 'en', text: this.$t('locales.en')},
{value: 'de', text: this.$t('locales.de')},
];
}
}

View File

@@ -1,6 +1,7 @@
import {messagesEn} from '@/locale/en';
export const messagesDe = {
design: 'Design',
fetch: {
mangaUpdates: {
chapters: 'Kapitel',
@@ -10,7 +11,8 @@ export const messagesDe = {
starting: 'Starte',
},
},
locale: messagesEn.locale,
locale: 'Sprache',
locales: messagesEn.locales,
localStoragePersistNotSupported: 'Lokaler Speicher wird nicht permanent. Das könnte in längere Wartezeiten verursachen!',
manga: {
chapters: {

View File

@@ -1,4 +1,5 @@
export const messagesEn = {
design: 'Design',
fetch: {
mangaUpdates: {
chapters: 'Chapters',
@@ -8,7 +9,8 @@ export const messagesEn = {
starting: 'Starting',
},
},
locale: {
locale: 'Language',
locales: {
'de': 'Deutsch',
'en': 'English',
},