Instantly share code, notes, and snippets.
Created
August 4, 2020 04:26
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save codemonkey76/e4b63883c0f90390498c45a7059eeed1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div class="h-full"> | |
<!-- Off-canvas menu for mobile --> | |
<div class="lg:hidden"> | |
<transition | |
enter-active-class="transition-opacity ease-linear duration-300" | |
enter-class="opacity-0" | |
enter-to-class="opacity-100" | |
leave-active-class="transition-opacity ease-linear duration-300" | |
leave-class="opacity-100" | |
leave-to-class="opacity-0" | |
> | |
<div v-show="isOpen" class="fixed inset-0 flex z-40"> | |
<transition | |
enter-active-class="transition-opacity ease-linear duration-300" | |
enter-class="opacity-0" | |
enter-to-class="opacity-100" | |
leave-active-class="transition-opacity ease-linear duration-300" | |
leave-class="opacity-100" | |
leave-to-class="opacity-0" | |
> | |
<div v-if="isOpen" class="fixed inset-0"> | |
<div class="absolute inset-0 bg-cool-gray-600 opacity-75"></div> | |
</div> | |
</transition> | |
<transition | |
enter-active-class="transition ease-in-out duration-300 transform" | |
enter-class="-translate-x-full" | |
enter-to-class="translate-x-0" | |
leave-active-class="transition ease-in-out duration-300 transform" | |
leave-class="translate-x-0" | |
leave-to-class="-translate-x-full"> | |
<div v-if="isOpen" class="relative flex-1 flex flex-col max-w-xs w-full pt-5 pb-4" :class="bgColor"> | |
<div class="absolute top-0 right-0 -mr-14 p-1"> | |
<button @click="hideMenu()" | |
class="flex items-center justify-center h-12 w-12 rounded-full focus:outline-none focus:bg-cool-gray-600" | |
aria-label="Close sidebar"> | |
<svg class="h-6 w-6 text-white" stroke="currentColor" fill="none" | |
viewBox="0 0 24 24"> | |
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" | |
d="M6 18L18 6M6 6l12 12"/> | |
</svg> | |
</button> | |
</div> | |
<div class="flex-shrink-0 flex items-center px-4"> | |
<img v-if="logo" class="h-8 w-auto" | |
:src="logo" | |
:alt="logoAlt"> | |
</div> | |
<div class="mt-5 overflow-y-auto"> | |
<nav class="px-2 space-y-1"> | |
<a v-for="item in menu.items" href="#" | |
class="group flex items-center px-2 py-2 text-base leading-6 font-medium rounded-md focus:outline-none transition ease-in-out duration-150" | |
:class="styles(item.route)"> | |
<svg class="mr-4 h-6 w-6 text-teal-200 transition ease-in-out duration-150" | |
fill="none" viewBox="0 0 24 24" stroke="currentColor" v-html="item.icon"> | |
</svg> | |
{{item.label}} | |
</a> | |
</nav> | |
</div> | |
</div> | |
</transition> | |
<div class="flex-shrink-0 w-14"> | |
<!-- Dummy element to force sidebar to shrink to fit close icon --> | |
</div> | |
</div> | |
</transition> | |
</div> | |
<!-- Static sidebar for desktop --> | |
<div class="hidden lg:flex lg:flex-shrink-0 h-full"> | |
<div class="flex flex-col w-64"> | |
<!-- Sidebar component, swap this element with another sidebar if you like --> | |
<div class="flex flex-col flex-grow pt-5 pb-4 overflow-y-auto" :class="bgColor"> | |
<div class="flex items-center flex-shrink-0 px-4"> | |
<img v-if="logo" class="h-8 w-auto" :src="logo" | |
:alt="logoAlt"> | |
</div> | |
<div class="mt-5 flex-1 flex flex-col overflow-y-auto"> | |
<div class="overflow-y-auto"> | |
<nav class="px-2 space-y-1"> | |
<a v-for="item in menu.items" href="#" | |
class="group flex items-center px-2 py-2 text-base leading-6 font-medium rounded-md focus:outline-none transition ease-in-out duration-150" | |
:class="styles(item.route)"> | |
<svg class="mr-4 h-6 w-6 text-teal-200 transition ease-in-out duration-150" | |
fill="none" viewBox="0 0 24 24" stroke="currentColor" v-html="item.icon"> | |
</svg> | |
{{item.label}} | |
</a> | |
</nav> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</template> | |
<script> | |
export default { | |
name: "sidebar", | |
props: { | |
logo: { | |
type: String, | |
required: false | |
}, | |
logoAlt: { | |
type: String, | |
required: false, | |
default: '' | |
}, | |
menu: { | |
type: Object, | |
required: true | |
}, | |
bgColor: { | |
type: String, | |
default: 'bg-teal-600' | |
}, | |
bgFocus: { | |
type: String, | |
default: 'bg-teal-500' | |
}, | |
textColor: { | |
type: String, | |
default: 'text-teal-100' | |
}, | |
selectedTextColor: { | |
type: String, | |
default: 'text-white' | |
}, | |
bgSelectedColor: { | |
type: String, | |
default: 'bg-teal-700' | |
}, | |
hoverTextColor: { | |
type: String, | |
default: 'text-white' | |
}, | |
bgHover: { | |
type: String, | |
default: 'bg-teal-500' | |
} | |
}, | |
data: () => ({ | |
isOpen: false | |
}), | |
methods: { | |
showMenu() { | |
this.isOpen = true; | |
}, | |
hideMenu() { | |
this.isOpen = false; | |
}, | |
styles(route) { | |
return (route===window.location.pathname) ? this.active : this.inactive; | |
} | |
}, | |
computed: { | |
active() { | |
return this.selectedTextColor + " " + this.bgSelectedColor + " focus:" + this.bgFocus | |
}, | |
inactive() { | |
return this.textColor + " hover:" + this.hoverTextColor + " hover:" + this.bgHover + " focus:" + this.bgFocus | |
} | |
} | |
} | |
</script> | |
<style scoped> | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment