Drawer
A panel that slides out from the edge of the screen.
Basic Usage
html
<template>
<HLDrawer id="drawer-basic-example" v-model:show="show" :placement="placement" :width="502">
<HLDrawerContent id="drawer-content-basic">
Dragon Ball is a Japanese media franchise created by Akira Toriyama in 1984. The initial manga, written and illustrated by Toriyama,
was serialized in Weekly Shōnen Jump from 1984 to 1995, with the 519 individual chapters collected in 42 tankōbon volumes by its
publisher Shueisha.
</HLDrawerContent>
</HLDrawer>
</template>
<script setup>
import { ref } from 'vue'
import { HLDrawer, HLDrawerContent } from '@platform-ui/highrise'
const show = ref(false)
const placement = ref('right')
const activate = place => {
placement.value = place
show.value = true
}
</script>With Default Header
The default header is shown when the title, description, or icon props are provided and the showHeader prop is set to true. You can also use the header slot to customize the header.
html
<HLButton id="drawer-default-header-btn" ghost @click="showDefaultHeader = true">Open Drawer</HLButton>
<HLDrawer id="drawer-default-header-example" v-model:show="showDefaultHeader" placement="right">
<HLDrawerContent
id="drawer-content-default-header"
title="Header Title"
description="Header subtitle"
:icon="AlertCircleIcon"
show-header
closable
@update:show="showDefaultHeader = $event"
/>
<!-- @update:show is handled in the DrawerContent component -->
</HLDrawer>Using Custom Header and Footer Slots
html
<template>
<HLButton id="drawer-with-slots-btn" ghost @click="showWithSlots = true">Open Drawer</HLButton>
<HLDrawer id="drawer-with-slots-example" v-model:show="showWithSlots" placement="right">
<HLDrawerContent id="drawer-content-basic">
<template #header>
<HLHeaderLite title="Header Title" subtitle="Header subtitle" @update:close="showWithSlots = false">
<template #header-icons>
<HLIcon>
<Share01Icon />
</HLIcon>
</template>
<template #header-content>
<HLHeaderLiteItem justify="end" size="sm">
<HLButton variant="ghost" size="xs" color="gray"> Button </HLButton>
</HLHeaderLiteItem>
</template>
</HLHeaderLite>
</template>
Main content goes here
<template #footer>
<HLSectionFooter id="footer" :top-padding="false" :bottom-padding="false" :horizontal-padding="false">
<HLSectionFooterItem>
<HLButton id="cancel" @click="showWithSlots = false">Cancel</HLButton>
<HLButton id="save" color="blue" variant="primary">Save</HLButton>
</HLSectionFooterItem>
</HLSectionFooter>
</template>
</HLDrawerContent>
</HLDrawer>
</template>
<script setup>
import { ref } from 'vue'
import {
HLDrawer,
HLDrawerContent,
HLHeaderLite,
HLHeaderLiteItem,
HLSectionFooter,
,
HLIcon,
} from '@platform-ui/highrise'
import { Share01Icon } from '@gohighlevel/ghl-icons/24/outline'
const showWithSlots = ref(false)
</script>Using :to prop
Target Area
html
<template>
<HLButton id="btn-to-prop" ghost @click="showToPropDrawer=true">Open Drawer</HLButton>
<div id="drawer-target">Target Area</div>
<HLDrawer v-model:show="showToPropDrawer" :width="400" :placement="placement" :trapFocus="false" to="#drawer-target">
<HLDrawerContent> Stoner is a 1965 novel by the American writer John Williams. </HLDrawerContent>
</HLDrawer>
</template>
<script setup>
import { ref } from 'vue'
import { HLDrawer, HLDrawerContent } from '@platform-ui/highrise'
const showToPropDrawer = ref(false)
const placement = ref('right')
</script>Error State
html
<template>
<HLButton id="drawer-error-btn" ghost @click="showErrorDrawer = true">Show Error State</HLButton>
<HLDrawer id="drawer-error-example" v-model:show="showErrorDrawer" placement="right">
<HLDrawerContent id="drawer-content-error">
<div class="flex items-center justify-center h-full">
<HLEmpty
id="error-state"
size="md"
icon="error"
title="Something went wrong while fetching your appointments"
description="You can try again now or after 10 minutes"
negative-text="Retry"
positive-text=""
/>
</div>
</HLDrawerContent>
</HLDrawer>
</template>
<script setup>
import { ref } from 'vue'
import { HLDrawer, HLDrawerContent, HLEmpty } from '@platform-ui/highrise'
const showErrorDrawer = ref(false)
const placement = ref('right')
</script>Loading State
html
<template>
<HLButton id="drawer-loading-btn" ghost @click="showLoadingDrawer = true">Show Loading State</HLButton>
<HLDrawer id="drawer-loading-example" v-model:show="showLoadingDrawer" placement="right">
<HLDrawerContent id="drawer-content-loading">
<div class="flex items-center justify-center h-full">
<HLSpin id="spin">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text
ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived
not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.
</HLSpin>
</div>
</HLDrawerContent>
</HLDrawer>
</template>
<script setup>
import { ref } from 'vue'
import { HLDrawer, HLDrawerContent, HLSpin } from '@platform-ui/highrise'
const showLoadingDrawer = ref(false)
const placement = ref('right')
</script>Loading with Header and Footer
html
<template>
<HLButton id="drawer-loading-combined-btn" ghost @click="showLoadingCombinedDrawer = true"> Show Loading with Header & Footer </HLButton>
<HLDrawer id="drawer-loading-combined-example" v-model:show="showLoadingCombinedDrawer" placement="right">
<HLDrawerContent id="drawer-content-loading-combined">
<template #header>
<HLHeaderLite title="Dragon Ball" subtitle="Last updated 2m ago" @update:close="showLoadingCombinedDrawer = false">
<template #header-icons>
<HLIcon>
<Share01Icon />
</HLIcon>
</template>
<template #header-content>
<HLHeaderLiteItem justify="end" size="sm">
<HLButton variant="ghost" size="xs" color="gray"> test </HLButton>
</HLHeaderLiteItem>
</template>
</HLHeaderLite>
</template>
<div class="flex items-center justify-center h-full">
<HLSpin id="spin-combined">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text
ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived
not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.
</HLSpin>
</div>
<template #footer>
<HLSectionFooter id="footer-combined" :top-padding="false" :bottom-padding="false" :horizontal-padding="false">
<HLSectionFooterItem justify="start">
<HLButton id="cancel-combined" @click="showLoadingCombinedDrawer = false">Cancel</HLButton>
<HLButton id="save-combined" color="blue" variant="primary">Save</HLButton>
</HLSectionFooterItem>
</HLSectionFooter>
</template>
</HLDrawerContent>
</HLDrawer>
</template>
<script setup>
import { ref } from 'vue'
import {
HLDrawer,
HLDrawerContent,
HLHeaderLite,
HLHeaderLiteItem,
HLSectionFooter,
HLSectionFooterItem,
HLIcon,
HLSpin,
} from '@platform-ui/highrise'
import { Share01Icon } from '@gohighlevel/ghl-icons/24/outline'
const showLoadingCombinedDrawer = ref(false)
const placement = ref('right')
</script>Imports
ts
import { HLDrawer, HLDrawerContent } from '@platform-ui/highrise'
//based on the need, refer props
import type { ScrollbarProps } from 'naive-ui'
import type { CSSProperties } from 'vue'Props
Drawer
| Prop | Type | Default | Description |
|---|---|---|---|
| id * | string | undefined | undefined | Unique identifier for the drawer |
| autoFocus | boolean | true | Whether to focus the first focusable element inside drawer. |
| blockScroll | boolean | true | Whether to disabled body scrolling when it's active. |
| closeOnEsc | boolean | true | Whether to close drawer on Esc is pressed. |
| contentClass | string | undefined | undefined | Class of drawer's scrollable content node. |
| contentStyle | string | CSSProperties | undefined | undefined | Style of drawer's scrollable content node. |
| defaultHeight | number | string | 251 | Default width of the drawer, works when placement is left and right. |
| defaultWidth | number | string | 251 | Default height of the drawer, works when placement is top and bottom. |
| displayDirective | 'if' | 'show' | 'if' | The display directive to use when n-drawer is rendered. 'if' corresponds to v-if and 'show' corresponds to v-show. |
| height | number | string | undefined | undefined | Height of the Drawer. Works when placement is top and bottom. |
| maskClosable | boolean | true | Ability to close on clicking the mask and to emit hide event. |
| maxHeight | boolean | true | Max height of draggable drawer |
| maxWidth | number | undefined | undefined | Max width of draggable drawer. |
| minHeight | number | undefined | undefined | Min height of draggable drawer. |
| minWidth | number | undefined | undefined | Min width of draggable drawer. |
| placement | 'top' | 'right' | 'bottom' | 'left' | 'right' | Drawer placement. |
| resizable | boolean | false | Whether to resize the width / height of drawer. |
| scrollbarProps | ScrollbarProps | undefined | undefined | See Scrollbar props. |
| show | boolean | false | Whether to show drawer. |
| showMask | boolean | true | Whether to show mask. If set to 'transparent', transparent mask would be shown. If set to false, trap-focus will be disabled. |
| to | string | HTMLElement | 'body' | Container node of the drawer. |
| trapFocus | boolean | true | Whether to trap focus inside drawer. |
| width | number | string | undefined | undefined | Width of the drawer. Works when placement is left and right. |
| zIndex | number | undefined | undefined | Z index of the drawer. |
Note
If you're facing issues with unfocusable input elements when you have multiple instances open, try setting :trapFocus="false" on the underlying instance of the component.
DrawerContent
| Prop | Type | Default | Description |
|---|---|---|---|
| id * | string | undefined | Unique identifier for the drawer content |
| bodyClass | string | undefined | Drawer content's body class. |
| bodyContentClass | string | undefined | Class of body's scrollable content node. |
| bodyContentStyle | string | CSSProperties | undefined | Style of body's scrollable content node. |
| bodyStyle | string | CSSProperties | undefined | Drawer content's body style. |
| closable | boolean | true | Whether to show the close button. Handle the update:show event in DrawerContent to close the drawer. |
| description | string | undefined | Drawer content's header description. |
| footerClass | string | undefined | Drawer content's footer class. |
| footerStyle | string | CSSProperties | undefined | Drawer content's footer style. |
| headerClass | string | undefined | Drawer content's header class. |
| headerStyle | string | CSSProperties | undefined | Drawer content's header style. |
| icon | Component | undefined | Drawer content's header icon. |
| nativeScrollbar | boolean | true | Whether to use native scrollbar on body part. |
| scrollbarProps | ScrollbarProps | undefined | See Scrollbar props |
| showHeader | boolean | true | Whether to show the header. |
| title | string | undefined | Drawer content's header title. |
Emits
Drawer
| Name | Parameters | Description |
|---|---|---|
@after-enter | () => void | Callback after drawer is opened. |
@after-leave | () => void | Callback after drawer is closed. |
@esc | () => void | Callback fired when the escape key is pressed and focus is within drawer. |
@mask-click | (e: MouseEvent) => void | Callback triggered on mask clicked. |
@update:height | (height: number) => void | Callback trigger on drawer height change. |
@update:show | (show: boolean) => void | Callback triggered on drawer display status would change. |
@update:width | (width: number) => void | Callback trigger on drawer width change. |
DrawerContent
| Name | Parameters | Description |
|---|---|---|
@update:show | (show: boolean) => void | Callback triggered on drawer display status would change. To be handled when default header is used. |
Slots
Drawer
| Name | Parameters | Description |
|---|---|---|
| default | () | The default content slot |
DrawerContent
| Name | Parameters | Description |
|---|---|---|
| default | () | The default content slot |
| header | () | Custom header content slot |
| footer | () | The footer content slot |