Skip to content

Accessibility: Partial

Translations: Not Needed

Drawer

A panel that slides out from the edge of the screen.

Basic Usage

Vue
html
<template>
  <HLDrawer v-model:show="show" :placement="placement" :width="502">
    <HLDrawerContent id="drawer-content-basic">
      <div>Content goes here</div>
    </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.

Vue
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>
Vue
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>
      <div class="p-4">Main content goes here</div>
      <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
Vue
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

Vue
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

Vue
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>
Vue
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

PropTypeDefaultDescription
id *string | undefinedundefinedUnique identifier for the drawer
autoFocusbooleantrueWhether to focus the first focusable element inside drawer.
blockScrollbooleantrueWhether to disabled body scrolling when it's active.
closeOnEscbooleantrueWhether to close drawer on Esc is pressed.
contentClassstring | undefinedundefinedClass of drawer's scrollable content node.
contentStylestring | CSSProperties | undefinedundefinedStyle of drawer's scrollable content node.
defaultHeightnumber | string251Default width of the drawer, works when placement is left and right.
defaultWidthnumber | string251Default 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.
heightnumber | string | undefinedundefinedHeight of the Drawer. Works when placement is top and bottom.
maskClosablebooleantrueAbility to close on clicking the mask and to emit hide event.
maxHeightbooleantrueMax height of draggable drawer
maxWidthnumber | undefinedundefinedMax width of draggable drawer.
minHeightnumber | undefinedundefinedMin height of draggable drawer.
minWidthnumber | undefinedundefinedMin width of draggable drawer.
placement'top' | 'right' | 'bottom' | 'left''right'Drawer placement.
resizablebooleanfalseWhether to resize the width / height of drawer.
scrollbarPropsScrollbarProps | undefinedundefinedSee Scrollbar props.
showbooleanfalseWhether to show drawer.
showMaskbooleantrueWhether to show mask. If set to 'transparent', transparent mask would be shown. If set to false, trap-focus will be disabled.
tostring | HTMLElement'body'Container node of the drawer.
trapFocusbooleantrueWhether to trap focus inside drawer.
widthnumber | string | undefinedundefinedWidth of the drawer. Works when placement is left and right.
zIndexnumber | undefinedundefinedZ index of the drawer.

DrawerContent

PropTypeDefaultDescription
id *stringundefinedUnique identifier for the drawer content
bodyClassstringundefinedDrawer content's body class.
bodyStylestring | CSSPropertiesundefinedDrawer content's body style.
bodyContentClassstringundefinedClass of body's scrollable content node.
bodyContentStylestring | CSSPropertiesundefinedStyle of body's scrollable content node.
footerClassstringundefinedDrawer content's footer class.
footerStylestring | CSSPropertiesundefinedDrawer content's footer style.
headerClassstringundefinedDrawer content's header class.
headerStylestring | CSSPropertiesundefinedDrawer content's header style.
nativeScrollbarbooleantrueWhether to use native scrollbar on body part.
scrollbarPropsScrollbarPropsundefinedSee Scrollbar props
titlestringundefinedDrawer content's header title.
descriptionstringundefinedDrawer content's header description.
iconComponentundefinedDrawer content's header icon.
closablebooleantrueWhether to show the close button. Handle the update:show event in DrawerContent to close the drawer.
showHeaderbooleantrueWhether to show the header.

Emits

Drawer

NameParametersDescription
@after-enter() => voidCallback after drawer is opened.
@after-leave() => voidCallback after drawer is closed.
@esc() => voidCallback fired when the escape key is pressed and focus is within drawer.
@mask-click(e: MouseEvent) => voidCallback triggered on mask clicked.
@update:height(height: number) => voidCallback trigger on drawer height change.
@update:show(show: boolean) => voidCallback triggered on drawer display status would change.
@update:width(width: number) => voidCallback trigger on drawer width change.

DrawerContent

NameParametersDescription
@update:show(show: boolean) => voidCallback triggered on drawer display status would change. To be handled when default header is used.

Slots

Drawer

NameParametersDescription
default()The default content slot

DrawerContent

NameParametersDescription
default()The default content slot
header()Custom header content slot
footer()The footer content slot