Appearance
ExDrawer
html
<ExDrawer
v-model="drawerModel" // false
:persistent="persistent" // false
:allow-body-scroll="allowBodyScroll" // false
>
<ExDrawerOverlay
v-if="enableOverlay" // true
class="bg-black/25"
/>
<ExDrawerContent v-if="drawerModel">
...
<ExDrawerClose class="gap-y-1 group inline-flex flex-col transform rotate-180">
<span class="h-0.5 bg-body/60 group-hover:bg-yellow-600 w-4 group-hover:w-2.5 transition-all inline-block"></span>
<span class="h-0.5 bg-body/60 group-hover:bg-yellow-600 group-hover:w-4 transition-all w-2.5 inline-block"></span>
<span class="h-0.5 bg-body/60 group-hover:bg-yellow-600 w-4 group-hover:w-2.5 transition-all inline-block"></span>
</ExDrawerClose>
...
</ExDrawerContent>
</ExDrawer>
<script setup lang="ts">
import { ref, computed } from 'vue'
import {
ExDrawer,
ExDrawerContent,
ExDrawerClose,
ExAvatar,
MiAwitch,
img
} from 'mi-components'
const drawerModel = ref(false)
const toggleModal = () => {
drawerModel.value = !drawerModel.value
}
const darkMode = ref(false)
const currentMenu = ref('home')
const menus = ['home', 'dashboard', 'users', 'configuration', 'roles', 'settings'] as const
const isActive = (menu: typeof menus[number]) => currentMenu.value === menu
const setActiveMenu = (menu: typeof menus[number]) => (currentMenu.value = menu)
</script>
Interact
Props: ExDrawer
as
Type | Default | Required |
---|---|---|
string component | div | false |
Description: Sets the element type of ex-drawer. Any custom vue component can also be passed.
modelValue
Type | Default | Required |
---|---|---|
boolean | false | true |
Description: Controls the display of drawer component.
focusFirst
Type | Default | Required |
---|---|---|
boolean | false | false |
Description: Sets the focus on the first focusable element once the drawer is visible.
persistent
Type | Default | Required |
---|---|---|
boolean | false | false |
Description: Disables closing the drawer on outside click or Esc
key
allowBodyScroll
Type | Default | Required |
---|---|---|
boolean | false | false |
Description: By default, when the drawer is open, the entire body is locked from scrolling. You can disable this behviour by passing false
to this property.
Emits
Name | Description |
| This is emits event for v-model html
|
| This is emitted when the drawer is closed html
|
Slots
Name | Description |
| The default Vue slot. js
|
Props: ExDrawerContent
as
Type | Default | Required |
---|---|---|
string component | div | false |
Description: Sets the element type of ex-drawer-content. Any custom vue component can also be passed.
Slots
Name | Description |
| The default Vue slot. |
Props: ExDrawerOverlay
as
Type | Default | Required |
---|---|---|
string component | div | false |
Description: Sets the element type of ex-drawer-overlay. Any custom vue component can also be passed.
Slots
Name | Description |
| The default Vue slot. |
Props: ExDrawerClose
as
Type | Default | Required |
---|---|---|
string component | button | false |
Description: Sets the element type of ex-drawer-close. Any custom vue component can also be passed.
disabled
Type | Default | Required |
---|---|---|
boolean | false | false |
Description: Enables / Disables ex-drawer-close element. No events will be emitted if the value is true
.
Slots
Name | Description |
| The default Vue slot. js
|
Examples
Sidebar
html
<ExDrawer v-model="drawerModel">
<Transition name="fade" appear mode="out-in">
<ExDrawerOverlay
v-if="drawerModel"
class="bg-black/25"
/>
</Transition>
<Transition name="slide-fade" appear>
<ExDrawerContent v-if="drawerModel" class="fixed left-6 top-6 overflow-y-auto min-w-80 min-h-[calc(100vh-48px)] max-h-[calc(100vh-48px)] bg-primary shadow-xl rounded-lg pb-6">
<div class="backdrop-blur-xl sticky top-0 z-10 flex items-center justify-between px-6 pt-6 pb-3">
<div class="gap-x-3 flex items-center">
<ExAvatar :size="40">
<img src="/assets/moon-knight.png" />
</ExAvatar>
<div>
<h3 class="text-body text-base leading-none">John Wick</h3>
<h4 class="text-body mt-1 text-sm leading-none">Superadmin</h4>
</div>
</div>
<ExDrawerClose class="gap-y-1 group inline-flex flex-col transform rotate-180">
<span class="h-0.5 bg-body/60 group-hover:bg-yellow-600 w-4 group-hover:w-2.5 transition-all inline-block"></span>
<span class="h-0.5 bg-body/60 group-hover:bg-yellow-600 group-hover:w-4 transition-all w-2.5 inline-block"></span>
<span class="h-0.5 bg-body/60 group-hover:bg-yellow-600 w-4 group-hover:w-2.5 transition-all inline-block"></span>
</ExDrawerClose>
</div>
<div class="mx-3 mt-3">
<h4 class="border-border p-3 mb-4 text-xs font-medium leading-none tracking-widest text-yellow-600 uppercase border-b">
Theme
</h4>
<button class="gap-x-3 bg-zinc-200 dark:bg-zinc-800 flex items-center px-3 py-2 rounded-lg cursor-pointer" @click="darkMode = !darkMode">
<span v-if="darkMode">Switch to Light</span>
<span v-else>Switch to Dark</span>
</button>
</div>
<div class="mx-3 mt-6">
<h4 class="border-border p-3 mb-4 text-xs font-medium leading-none tracking-widest text-yellow-600 uppercase border-b">
Navigation
</h4>
<ul class="space-y-2">
<template v-for="(menu) in menus" :key="menu">
<li
@click="setActiveMenu(menu)"
:class="[isActive(menu) ? 'text-violet-700 dark:text-violet-300' : 'hover:text-violet-500 dark:hover:text-violet-200 text-body/70']"
class="active:text-gray-400 px-3 font-medium capitalize transition-all duration-100 rounded cursor-pointer"
>
<a href="#/">{{ menu }}</a>
</li>
</template>
</ul>
</div>
<div class="mx-3 mt-4">
<h4 class="border-border p-3 mb-4 text-xs font-medium leading-none tracking-widest text-yellow-600 uppercase border-b">
Gallery
</h4>
<div class="grid grid-cols-2 gap-6 pt-1 mx-3">
<div class="overflow-hidden transition-all rounded-md shadow-xl">
<img
class="text-primary bg-body border-border hover:scale-125 place-items-center grid tracking-tight transition-all"
src="https://picsum.photos/150/150.webp"
:size="150"
:radius="8"
/>
</div>
<div
v-for="i in [100,200,237,400,500, 420, 520]"
:key="i"
class="overflow-hidden transition-all rounded-md shadow-xl"
>
<img
class="text-primary bg-body border-border hover:scale-125 place-items-center grid tracking-tight transition-all"
:src="`https://picsum.photos/id/${i}/150/150.webp`"
:size="150"
:radius="8"
/>
</div>
</div>
</div>
</ExDrawerContent>
</Transition>
</ExDrawer>
ts
import { nextTick, ref, watch } from 'vue'
import ExDrawer from 'ExDrawer/ExDrawer.vue' // import is for demo purpose, make sure the correct package reference is used
import ExDrawerContent from 'ExDrawer/ExDrawerContent.vue'
import ExDrawerOverlay from 'ExDrawer/ExDrawerOverlay.vue'
import ExDrawerClose from 'ExDrawer/ExDrawerClose.vue'
const darkMode = ref(false)
const drawerModel = ref(false)
const menus = ['home', 'dashboard', 'users', 'configuration', 'roles', 'settings'] as const
const currentMenu = ref('home')
const isActive = (menu: typeof menus[number]) => currentMenu.value === menu
const setActiveMenu = (menu: typeof menus[number]) => (currentMenu.value = menu)
css
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
.slide-fade-enter-active {
transition: all 0.25s ease-out;
}
.slide-fade-leave-active {
transition: all 0.2s cubic-bezier(1, 0.5, 0.8, 1);
}
.slide-fade-enter-from,
.slide-fade-leave-to {
transform: translateX(20px);
opacity: 0;
}