Skip to content

Commit 2617a79

Browse files
authored
fix(sidebar): upgrate left sidebar (#57)
1 parent 7b49fb1 commit 2617a79

File tree

8 files changed

+682
-712
lines changed

8 files changed

+682
-712
lines changed

src/components/Navigation/index.vue

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
/>
2222
<div
2323
class="flex z-10 absolute inset-y-0 right-0 pr-4 items-center lg:hidden md:hidden sm:hidden"
24-
:class="{ hidden: isPin }"
24+
:class="{ hidden: isSBPin }"
2525
>
2626
<el-icon
2727
:size="20"
@@ -40,14 +40,14 @@
4040
>
4141
<div class="relative inline-block lg:hidden text-white">
4242
<div class="flex items-center">
43-
<MenuIcon v-if="!isPin" class="cursor-pointer w-6 h-6" @click="setIsPin(true)" />
44-
<MenuAlt1Icon v-if="isPin" class="cursor-pointer w-6 h-6" @click="setIsPin(false)" />
43+
<MenuIcon v-if="!isSBOpen" class="cursor-pointer h-6 w-6" @click="handleMenuClick" />
44+
<MenuAlt1Icon v-else class="cursor-pointer h-6 w-6" @click="handleMenuClick" />
4545
</div>
4646
</div>
4747
<div class="relative inline-block sm:hidden">
4848
<div class="flex items-center">
4949
<SearchCircleIcon
50-
v-if="!isPin && isSearchOpen"
50+
v-if="!isSBPin && isSearchOpen"
5151
class="cursor-pointer w-4.5 h-4.5"
5252
@click="setSearchOpen(false)"
5353
/>
@@ -357,10 +357,11 @@ export default defineComponent({
357357
const closeSideMenu = () => {
358358
isSideMenuOpen.value = false
359359
}
360-
const isPin = computed(() => store.isPin)
360+
const isSBPin = computed(() => store.isSBPin)
361+
const isSBOpen = computed(() => store.isSBOpen)
361362
362-
const setIsPin = (v: boolean) => {
363-
store.setSideBar(v)
363+
const handleMenuClick = () => {
364+
store.toggleMenu()
364365
}
365366
366367
const setSearchOpen = (v: boolean) => (isSearchOpen.value = v)
@@ -369,11 +370,12 @@ export default defineComponent({
369370
isPagesMenuOpen,
370371
isSideMenuOpen,
371372
isSearchOpen,
372-
isPin,
373+
isSBPin,
374+
isSBOpen,
373375
clickIconBell,
374376
clickIconMenu,
375377
textInput,
376-
setIsPin,
378+
handleMenuClick,
377379
setSearchOpen,
378380
togglePagesMenu,
379381
closeSideMenu,

src/components/Sidebar/index.vue

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
@mouseleave="hoverLeftBar(false)"
55
aria-labelledby="primary-heading"
66
class="transition-all duration-300 fixed z-20 w-62.5 bg-white flex-shrink-0 overflow-hidden overflow-y-auto h-full items-center drop-shadow-xl"
7-
:class="{ 'hidden-aside w-15.5': !isHover && !isPin }"
7+
:class="{ 'hidden-aside w-15.5': !isSBOpen && !isSBPin }"
88
>
99
<div class="container flex flex-col mx-auto items-stretch">
1010
<div class="h-19.5 flex items-center relative">
1111
<small class="absolute left-36 top-10 italic text-cyan-800">v{{ version }}</small>
1212
<a
13-
v-if="(isHover && !isPin) || isPin"
14-
:class="{ 'opacity-0': !isHover && !isPin }"
13+
v-if="(isSBOpen && !isSBPin) || isSBPin"
14+
:class="{ 'opacity-0': !isSBOpen && !isSBPin }"
1515
class="transition-opacity duration-300 opacity-1 p-6 block"
1616
href="#index"
1717
>
@@ -25,12 +25,8 @@
2525
<div class="lg:col-span-10 xl:col-span-10 flex">
2626
<div class="hidden lg:block flex-grow">
2727
<div class="flex items-center space-x-2 2xl:space-x-4 text-black px-5">
28-
<MenuIcon v-if="!isPin" class="cursor-pointer h-6 w-5" @click="setIsPin(true)" />
29-
<MenuAlt1Icon
30-
v-if="isPin"
31-
class="cursor-pointer h-6 w-5"
32-
@click="setIsPin(false)"
33-
/>
28+
<MenuIcon v-if="!isSBPin" class="cursor-pointer h-6 w-5" @click="handleMenuClick" />
29+
<MenuAlt1Icon v-else class="cursor-pointer h-6 w-5" @click="handleMenuClick" />
3430
</div>
3531
</div>
3632
</div>
@@ -42,7 +38,7 @@
4238
>
4339
<ul class="flex flex-col -mx-6">
4440
<li
45-
class="relative flex flex-row mx-2 px-4 h-11 rounded-lg mb-px mt-0.5"
41+
class="relative flex flex-row mx-2 h-11 rounded-lg mb-px mt-0.5"
4642
:class="{ ' bg-slate-100/50 ': route.name === item.name }"
4743
v-for="(item, index) in menuItems"
4844
:key="index"
@@ -53,7 +49,7 @@
5349
aria-hidden="true"
5450
></span>
5551
<router-link
56-
class="inline-flex items-center w-full text-sm my-0.5 font-normal transition-colors duration-150 hover:text-gray-600 focus:text-gray-800"
52+
class="inline-flex px-4 items-center w-full text-sm my-0.5 font-normal transition-colors duration-150 hover:text-gray-600 focus:text-gray-800"
5753
:class="{ ' text-gray-800 ': route.name === item.name }"
5854
:to="{ name: item.name }"
5955
:title="item.title"
@@ -67,7 +63,7 @@
6763
</div>
6864
<span
6965
class="transition-opacity duration-300 opacity-1 ml-4 text-sm font-normal"
70-
:class="{ 'opacity-0': !isHover && !isPin }"
66+
:class="{ 'opacity-0': !isSBOpen && !isSBPin }"
7167
>{{ item.title }}</span
7268
>
7369
</router-link>
@@ -79,13 +75,14 @@
7975
</template>
8076

8177
<script lang="ts">
82-
import { defineComponent, ref, computed, onMounted } from 'vue'
78+
import { defineComponent, ref, computed, onMounted, watch } from 'vue'
8379
import { useRoute } from 'vue-router'
8480
import navigation from './SidebarNav'
8581
import { BellIcon, MenuIcon, MenuAlt1Icon } from '@heroicons/vue/outline'
8682
import { useDashboardStore } from '../../modules/dashboard/store'
8783
import { onClickOutside } from '@vueuse/core'
8884
import env from 'core/env'
85+
import { checkIsMobile } from 'utils/index'
8986
9087
interface MenuItem {
9188
title: string
@@ -108,52 +105,49 @@ export default defineComponent({
108105
const menuItems = ref<MenuItem[]>(navigation)
109106
const isPagesMenuOpen = ref(false)
110107
const isSideMenuOpen = ref(false)
111-
const isHover = ref<boolean>(false)
112108
const target = ref(null)
113109
const version = ref(env('VITE_APP_VERSION'))
110+
const isMobile = checkIsMobile()
114111
115112
onClickOutside(target, (_) => {
116-
const winWidth = ref<number>(window.innerWidth)
117-
if (winWidth.value < 1024 && isPin) {
118-
store.setSideBar(false)
119-
}
113+
if (window.innerWidth < 640) store.setIsSBOpen(false)
120114
})
121115
122116
onMounted(() => {
123-
if (window.innerWidth < 640) store.setSideBar(false)
117+
window.addEventListener('resize', () => {
118+
if (window.innerWidth < 1024) {
119+
store.setIsSBOpen(false)
120+
store.setIsSBPin(false)
121+
}
122+
})
124123
})
125124
126-
const isPin = computed<boolean>(() => store.isPin)
127-
128-
const setIsPin = (value: boolean) => {
129-
store.setSideBar(value)
130-
}
125+
const isSBPin = computed<boolean>(() => store.isSBPin)
126+
const isSBOpen = computed<boolean>(() => store.isSBOpen)
131127
132-
const togglePagesMenu = () => {
133-
isSideMenuOpen.value = !isSideMenuOpen.value
128+
const hoverLeftBar = (v: boolean) => {
129+
if (!isMobile) store.setIsSBOpen(v)
134130
}
135131
136-
const closeSideMenu = () => {
137-
isSideMenuOpen.value = false
132+
const handleMenuClick = () => {
133+
store.toggleMenu()
138134
}
139135
140-
const hoverLeftBar = (b: boolean) => {
141-
isHover.value = b
142-
}
136+
watch(route, () => {
137+
store.setIsSBOpen(false)
138+
})
143139
144140
return {
145141
isPagesMenuOpen,
146-
isHover,
147142
isSideMenuOpen,
148143
menuItems,
149144
route,
150-
isPin,
145+
isSBPin,
146+
isSBOpen,
151147
target,
152148
version,
153-
setIsPin,
154149
hoverLeftBar,
155-
togglePagesMenu,
156-
closeSideMenu,
150+
handleMenuClick,
157151
}
158152
},
159153
})

src/layouts/default-layout.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<sidebar />
44
<div
55
class="main-content flex flex-col flex-1 w-full overflow-auto"
6-
:class="`${!isPin ? 'ml-15.5' : 'ml-62.5 cursor-pointer lg:cursor-default'}`"
6+
:class="`${!isSBPin ? 'ml-15.5' : 'ml-62.5 cursor-pointer lg:cursor-default'}`"
77
>
88
<navigation />
99
<div class="w-full h-17 relative bg-primary-blue">
@@ -87,9 +87,9 @@ export default defineComponent({
8787
setup() {
8888
const route: any = useRoute()
8989
const store = useDashboardStore()
90-
const isPin = computed<boolean>(() => store.isPin)
91-
const setIsPin = (b: boolean) => store.setSideBar(b)
92-
return { isPin, setIsPin, route }
90+
const isSBPin = computed<boolean>(() => store.isSBPin)
91+
const setIsSBPin = (b: boolean) => store.setIsSBPin(b)
92+
return { isSBPin, setIsSBPin, route }
9393
},
9494
})
9595
</script>

src/modules/dashboard/store/actions.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,21 @@ export const useActions = defineStore('dashboard.actions', () => {
1717
state.welcomeText = value
1818
}
1919

20-
const setSideBar = (value:boolean) => state.isPin = value
20+
const setIsSBPin = (value: boolean) => (state.isSBPin = value)
21+
const setIsSBOpen = (value: boolean) => (state.isSBOpen = value)
22+
const toggleMenu = () => {
23+
if (window.innerWidth < 1024) {
24+
setIsSBOpen(!state.isSBOpen)
25+
} else {
26+
setIsSBPin(!state.isSBPin)
27+
}
28+
}
2129

2230
return {
2331
showWelcomeText,
2432
setWelcomeText,
25-
setSideBar,
33+
setIsSBPin,
34+
setIsSBOpen,
35+
toggleMenu,
2636
}
2737
})

src/modules/dashboard/store/state.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ export const useState = defineStore({
66
state: (): DashboardState => {
77
return {
88
welcomeText: 'Welcome to Dashboard! ...',
9-
isPin: true,
9+
isSBPin: true,
10+
isSBOpen: true,
1011
}
1112
},
1213
})

src/modules/dashboard/store/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export interface DashboardState {
22
welcomeText: string
3-
isPin: boolean
3+
isSBPin: boolean
4+
isSBOpen: boolean
45
}

src/utils/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@ import dayjs from 'dayjs'
22
export const formatDate = (date: Date, format: string = 'hh:mm') => {
33
return dayjs(date).format(format)
44
}
5+
6+
export const checkIsMobile = () => {
7+
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
8+
}

0 commit comments

Comments
 (0)