Skip to content

Instantly share code, notes, and snippets.

@codemonkey76
Created August 4, 2020 04:26
Show Gist options
  • Save codemonkey76/e4b63883c0f90390498c45a7059eeed1 to your computer and use it in GitHub Desktop.
Save codemonkey76/e4b63883c0f90390498c45a7059eeed1 to your computer and use it in GitHub Desktop.
<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