fix: sidebar menu collapse/expand on mobile

This commit is contained in:
Phan An 2024-08-18 17:06:06 +02:00
parent b994f2dc94
commit bb47d5fb3b
4 changed files with 53 additions and 39 deletions

View file

@ -10,7 +10,9 @@
py-0 px-6 h-k-header-height"
>
<div class="btn-group">
<SidebarMenuToggleButton />
<ExtraDrawerButton @click.prevent="expandSidebar">
<Icon :icon="faBars" fixed-width />
</ExtraDrawerButton>
<ExtraDrawerTabHeader v-if="songPlaying" v-model="activeTab" />
</div>
@ -70,16 +72,17 @@
<script lang="ts" setup>
import isMobile from 'ismobilejs'
import { faBars } from '@fortawesome/free-solid-svg-icons'
import { computed, defineAsyncComponent, onMounted, ref, Ref, watch } from 'vue'
import { albumStore, artistStore, preferenceStore } from '@/stores'
import { useErrorHandler, useThirdPartyServices } from '@/composables'
import { isSong, requireInjection } from '@/utils'
import { eventBus, isSong, requireInjection } from '@/utils'
import { CurrentPlayableKey } from '@/symbols'
import ProfileAvatar from '@/components/ui/ProfileAvatar.vue'
import SidebarMenuToggleButton from '@/components/ui/SidebarMenuToggleButton.vue'
import AboutKoelButton from '@/components/layout/main-wrapper/extra-drawer/AboutKoelButton.vue'
import LogoutButton from '@/components/layout/main-wrapper/extra-drawer/LogoutButton.vue'
import ExtraDrawerButton from '@/components/layout/main-wrapper/extra-drawer/ExtraDrawerButton.vue'
const LyricsPane = defineAsyncComponent(() => import('@/components/ui/LyricsPane.vue'))
const ArtistInfo = defineAsyncComponent(() => import('@/components/artist/ArtistInfo.vue'))
@ -119,6 +122,7 @@ watch(playable, song => {
watch(activeTab, tab => (preferenceStore.active_extra_panel_tab = tab))
const onProfileLinkClick = () => isMobile.any && (activeTab.value = null)
const expandSidebar = () => eventBus.emit('TOGGLE_SIDEBAR')
onMounted(() => isMobile.any || (activeTab.value = preferenceStore.active_extra_panel_tab))
</script>

View file

@ -3,7 +3,7 @@
exports[`renders without a current song 1`] = `
<aside data-v-847f0b60="" class="fixed sm:relative top-0 w-screen md:w-auto flex flex-col md:flex-row-reverse z-[2] text-k-text-secondary">
<div data-v-847f0b60="" class="controls flex md:flex-col justify-between items-center md:w-[64px] md:py-6 tw:px-0 bg-black/5 md:border-l border-solid md:border-l-white/5 md:border-b-0 md:shadow-none z-[2] w-screen flex-row border-b border-b-white/5 border-l-0 shadow-xl py-0 px-6 h-k-header-height">
<div data-v-847f0b60="" class="btn-group"><button data-v-5e31283f="" data-v-847f0b60="" class="relative flex items-center justify-center h-[42px] aspect-square rounded-full bg-none md:bg-black/30 text-xl opacity-70 transition-opacity duration-200 ease-in-out text-current cursor-pointer hover:active-state active:scale-90 block md:hidden" type="button"><br data-testid="Icon" icon="[object Object]" fixed-width=""></button>
<div data-v-847f0b60="" class="btn-group"><button data-v-5e31283f="" data-v-847f0b60="" class="relative flex items-center justify-center h-[42px] aspect-square rounded-full bg-none md:bg-black/30 text-xl opacity-70 transition-opacity duration-200 ease-in-out text-current cursor-pointer hover:active-state active:scale-90" type="button"><br data-v-847f0b60="" data-testid="Icon" icon="[object Object]" fixed-width=""></button>
<!--v-if-->
</div>
<div data-v-847f0b60="" class="btn-group"><button data-v-5e31283f="" data-v-847f0b60="" class="relative flex items-center justify-center h-[42px] aspect-square rounded-full bg-none md:bg-black/30 text-xl opacity-70 transition-opacity duration-200 ease-in-out text-current cursor-pointer hover:active-state active:scale-90" type="button" title="About Koel"><br data-testid="Icon" icon="[object Object]">

View file

@ -1,45 +1,55 @@
<template>
<nav
:class="{ collapsed: !expanded, 'tmp-showing': tmpShowing, showing: mobileShowing }"
class="group flex flex-col fixed md:relative w-full md:w-k-sidebar-width z-10"
@mouseenter="onMouseEnter"
@mouseleave="onMouseLeave"
>
<section class="home-search-block p-6 flex gap-2">
<HomeButton />
<SearchForm class="flex-1" />
</section>
<nav
:class="{ collapsed: !expanded, 'tmp-showing': tmpShowing, showing: mobileShowing }"
class="group left-0 top-0 flex flex-col fixed h-full w-full md:relative md:w-k-sidebar-width z-[999] md:z-10"
@mouseenter="onMouseEnter"
@mouseleave="onMouseLeave"
>
<section class="btn-collapse-block flex md:hidden items-center border-b border-b-white/5 h-k-header-height px-6">
<div class="bg-white/5 rounded-full">
<ExtraDrawerButton @click.prevent="collapseSidebar">
<Icon :icon="faTimes" fixed-width />
</ExtraDrawerButton>
</div>
</section>
<section v-koel-overflow-fade class="pt-2 pb-10 overflow-y-auto space-y-8">
<SidebarYourMusicSection />
<SidebarPlaylistsSection />
<SidebarManageSection v-if="showManageSection" />
</section>
<section class="home-search-block p-6 flex gap-2">
<HomeButton />
<SearchForm class="flex-1" />
</section>
<section v-if="!isPlus && isAdmin" class="p-6 flex-1 flex flex-col-reverse">
<BtnUpgradeToPlus />
</section>
<section v-koel-overflow-fade class="pt-2 pb-10 overflow-y-auto space-y-8">
<SidebarYourMusicSection />
<SidebarPlaylistsSection />
<SidebarManageSection v-if="showManageSection" />
</section>
<SidebarToggleButton
class="opacity-0 no-hover:hidden group-hover:opacity-100 transition"
v-model="expanded"
:class="expanded || 'opacity-100'"
/>
</nav>
<section v-if="!isPlus && isAdmin" class="p-6 flex-1 flex flex-col-reverse">
<BtnUpgradeToPlus />
</section>
<SidebarToggleButton
class="opacity-0 no-hover:hidden group-hover:opacity-100 transition"
v-model="expanded"
:class="expanded || 'opacity-100'"
/>
</nav>
</template>
<script lang="ts" setup>
import { faTimes } from '@fortawesome/free-solid-svg-icons'
import { computed, ref, watch } from 'vue'
import { eventBus } from '@/utils'
import { useAuthorization, useKoelPlus, useLocalStorage, useRouter, useUpload } from '@/composables'
import SidebarPlaylistsSection from './SidebarPlaylistsSection.vue'
import SearchForm from '@/components/ui/SearchForm.vue'
import BtnUpgradeToPlus from '@/components/koel-plus/BtnUpgradeToPlus.vue'
import SidebarYourMusicSection from './SidebarYourLibrarySection.vue'
import SidebarManageSection from './SidebarManageSection.vue'
import SidebarToggleButton from '@/components/layout/main-wrapper/sidebar/SidebarToggleButton.vue'
import ExtraDrawerButton from '@/components/layout/main-wrapper/extra-drawer/ExtraDrawerButton.vue'
import HomeButton from '@/components/layout/main-wrapper/sidebar/HomeButton.vue'
import SearchForm from '@/components/ui/SearchForm.vue'
import SidebarManageSection from './SidebarManageSection.vue'
import SidebarPlaylistsSection from './SidebarPlaylistsSection.vue'
import SidebarToggleButton from '@/components/layout/main-wrapper/sidebar/SidebarToggleButton.vue'
import SidebarYourMusicSection from './SidebarYourLibrarySection.vue'
const { onRouteChanged } = useRouter()
const { isAdmin } = useAuthorization()
@ -81,6 +91,8 @@ const onMouseLeave = (e: MouseEvent) => {
onRouteChanged(_ => (mobileShowing.value = false))
const collapseSidebar = () => (mobileShowing.value = false)
/**
* Listen to toggle sidebar event to show or hide the sidebar.
* This should only be triggered on a mobile device.
@ -104,9 +116,9 @@ nav {
}
&.tmp-showing {
@apply absolute h-screen z-50 bg-k-bg-primary w-k-sidebar-width shadow-2xl;
@apply fixed h-screen bg-k-bg-primary w-k-sidebar-width shadow-2xl z-[999];
> *:not(.btn-toggle) {
> *:not(.btn-toggle, .btn-collapse-block) {
@apply block;
}
@ -118,11 +130,9 @@ nav {
@media screen and (max-width: 768px) {
@mixin themed-background;
z-index: 999;
transform: translateX(-100vw);
transition: transform .2s ease-in-out;
height: calc(100vh - var(--header-height));
&.showing {
transform: translateX(0);

View file

@ -20,8 +20,8 @@ new class extends UnitTestCase {
expect(screen.getByTestId('sidebar-item').classList.contains('current')).toBe(true)
})
it ('emits the sidebar toggle event when clicked', async () => {
const mock = this.mock(eventBus, 'emit')
it('emits the sidebar toggle event when clicked', async () => {
const mock = this.mock(eventBus, 'emit')
this.renderComponent()
await this.user.click(screen.getByTestId('sidebar-item'))