feat(ui): responsive sidebar (breakoff: 1024px)
This commit is contained in:
parent
bd840a4ba6
commit
7296a352d9
|
@ -28,7 +28,13 @@ onKeyboardShortcut('h', () => isShortcutsModalOpen.value = !isShortcutsModalOpen
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.grid {
|
.grid {
|
||||||
display: grid !important;
|
display: grid !important;
|
||||||
grid-template-columns: 300px 5fr;
|
grid-template-columns: 100%;
|
||||||
|
grid-template-rows: min-content;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
|
|
||||||
|
@media screen and (min-width: 1024px) {
|
||||||
|
grid-template-columns: 300px 5fr;
|
||||||
|
grid-template-rows: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted, watch } from 'vue'
|
||||||
import { useUploadsStore } from '../stores/upload'
|
import { useUploadsStore } from '../stores/upload'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useStore } from '~/store'
|
import { useStore } from '~/store'
|
||||||
|
@ -12,6 +12,22 @@ import UserMenu from './UserMenu.vue'
|
||||||
import Button from '~/components/ui/Button.vue'
|
import Button from '~/components/ui/Button.vue'
|
||||||
import Layout from '~/components/ui/Layout.vue'
|
import Layout from '~/components/ui/Layout.vue'
|
||||||
import Spacer from '~/components/ui/layout/Spacer.vue'
|
import Spacer from '~/components/ui/layout/Spacer.vue'
|
||||||
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Sidebar on slim screen
|
||||||
|
|
||||||
|
- While screen is slim, sidebar is drawn on top of screen
|
||||||
|
- While screen is slim, When new route is loaded, top-sidebar is auto-collapsed: `watch(() => route.path, () => (isCollapsed.value = true))`
|
||||||
|
- While screen is slim, top-sidebar can be expanded and collapsed with additional hamburger button on top-right
|
||||||
|
|
||||||
|
*/
|
||||||
|
const isCollapsed = ref(false)
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
watch(() => route.path, () => ( isCollapsed.value = true ))
|
||||||
|
|
||||||
const { openShortcutsModal } = defineProps<{ openShortcutsModal: ()=> void }>()
|
const { openShortcutsModal } = defineProps<{ openShortcutsModal: ()=> void }>()
|
||||||
|
|
||||||
|
@ -29,7 +45,7 @@ const uploads = useUploadsStore()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<aside :class="[$style.sidebar, $style['sticky-content']]" v-bind="color('default solid raised')">
|
<Layout aside :class="[$style.sidebar, $style['sticky-content']]" v-bind="color('default solid raised')">
|
||||||
<Layout flex no-gap header style="justify-content:space-between; padding-right:8px;">
|
<Layout flex no-gap header style="justify-content:space-between; padding-right:8px;">
|
||||||
<Link to="/"
|
<Link to="/"
|
||||||
:class="$style['logo']"
|
:class="$style['logo']"
|
||||||
|
@ -70,9 +86,11 @@ const uploads = useUploadsStore()
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<UserMenu :showShortcutsModal="openShortcutsModal"/>
|
<UserMenu :showShortcutsModal="openShortcutsModal"/>
|
||||||
|
|
||||||
|
<Button round ghost icon="bi-list large" class="hide-on-desktop" @click="isCollapsed=!isCollapsed"/>
|
||||||
</Layout>
|
</Layout>
|
||||||
</Layout>
|
</Layout>
|
||||||
<Layout no-gap stack :class="$style['button-list']">
|
<Layout no-gap stack :class="$style['menu-links']" v-if="!isCollapsed">
|
||||||
<div :class="$style.search">
|
<div :class="$style.search">
|
||||||
<Input
|
<Input
|
||||||
v-model="searchQuery"
|
v-model="searchQuery"
|
||||||
|
@ -81,6 +99,28 @@ const uploads = useUploadsStore()
|
||||||
:placeholder="t('components.audio.SearchBar.placeholder.search')"
|
:placeholder="t('components.audio.SearchBar.placeholder.search')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Sign up, Log in -->
|
||||||
|
<div style="display:contents;" class="hide-on-desktop" v-if="!store.state.auth.authenticated">
|
||||||
|
<Layout flex no-gap>
|
||||||
|
<Link :to="{ name: 'login' }"
|
||||||
|
primary solid ful
|
||||||
|
icon="bi-box-arrow-in-right"
|
||||||
|
style="flex-grow:1"
|
||||||
|
>
|
||||||
|
{{ t('components.common.UserMenu.link.login') }}
|
||||||
|
</Link>
|
||||||
|
<Link :to="{ name: 'signup' }"
|
||||||
|
secondary solid
|
||||||
|
icon="bi-person-square"
|
||||||
|
style="flex-grow:1"
|
||||||
|
>
|
||||||
|
{{ t('components.common.UserMenu.link.signup') }}
|
||||||
|
</Link>
|
||||||
|
</Layout>
|
||||||
|
<Spacer :size="32" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<nav style="display:contents;">
|
<nav style="display:contents;">
|
||||||
<Link to="/library"
|
<Link to="/library"
|
||||||
ghost
|
ghost
|
||||||
|
@ -143,19 +183,16 @@ const uploads = useUploadsStore()
|
||||||
</Link>
|
</Link>
|
||||||
</nav>
|
</nav>
|
||||||
</Layout>
|
</Layout>
|
||||||
</aside>
|
</Layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style module lang="scss">
|
<style module lang="scss">
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
height: 100%;
|
|
||||||
display:flex;
|
display:flex;
|
||||||
flex-direction:column;
|
flex-direction:column;
|
||||||
|
|
||||||
&.sticky-content {
|
&.sticky-content {
|
||||||
position: sticky;
|
|
||||||
height: 100%;
|
|
||||||
max-height: 100vh;
|
max-height: 100vh;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
@ -239,8 +276,22 @@ const uploads = useUploadsStore()
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
.button-list {
|
.menu-links {
|
||||||
padding: 0 16px 32px;
|
padding: 0 16px 32px;
|
||||||
|
flex-grow: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 1024px) {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
:global(.hide-on-desktop){
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.sticky-content {
|
||||||
|
position: sticky;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue