Skip to content

Drawer

A floating panel that slides out from the edge of the screen, typically used for temporary operations while maintaining the current task state.

Basic Usage

The simplest way to call the component; it slides out from the right by default.

vue
<script setup>
import { ref } from 'vue'

const visible = ref(false)
</script>

<template>
  <TuiButton @click="visible = true">Open Drawer</TuiButton>

  <TuiDrawer v-model="visible">
    <div style="padding: 20px;">
      This is a basic drawer.
    </div>
  </TuiDrawer>
</template>

Slide-out Direction

Four slide-out directions are supported via the direction property:

  • rtl: Right to Left (Default)
  • ltr: Left to Right
  • ttb: Top to Bottom
  • btt: Bottom to Top
vue
<script setup>
import { reactive } from 'vue'

const state = reactive({
  rtl: false,
  ltr: false,
  ttb: false,
  btt: false
})
</script>

<template>
  <div class="demo-box">
    <TuiButton @click="state.rtl = true">Slide from Right (Default)</TuiButton>
    <TuiButton @click="state.ltr = true">Slide from Left</TuiButton>
    <TuiButton @click="state.ttb = true">Slide from Top</TuiButton>
    <TuiButton @click="state.btt = true">Slide from Bottom</TuiButton>
  </div>

  <TuiDrawer v-model="state.rtl" direction="rtl">
    <p>Right to Left</p>
  </TuiDrawer>

  <TuiDrawer v-model="state.ltr" direction="ltr">
    <p>Left to Right</p>
  </TuiDrawer>

  <TuiDrawer v-model="state.ttb" direction="ttb" size="40%">
    <p>Top to Bottom</p>
  </TuiDrawer>

  <TuiDrawer v-model="state.btt" direction="btt" size="40%">
    <p>Bottom to Top</p>
  </TuiDrawer>
</template>

Dimensions and Padding

The size property controls the width (for horizontal modes) or height (for vertical modes), supporting pixel values or percentage strings. The padding property uniformly controls the internal margins of the content area.

vue
<script setup>
import { reactive } from 'vue'

const state = reactive({
  customPx: false,
  customPercent: false
})
</script>

<template>
  <TuiButton @click="state.customPx = true">Fixed Width 400px</TuiButton>
  <TuiButton @click="state.customPercent = true">Percentage 60%</TuiButton>

  <TuiDrawer 
    v-model="state.customPx" 
    :size="400" 
    :padding="50"
  >
    <p>Width: 400px</p>
    <p>Padding: 50px</p>
  </TuiDrawer>

  <TuiDrawer v-model="state.customPercent" size="60%">
    <p>Width: 60%</p>
  </TuiDrawer>
</template>

Interaction Behavior

Rich Props are provided to control the drawer's closing logic and backdrop behavior, suitable for different interaction scenarios.

  • showClose: Whether to display the close button in the top right corner.
  • closeOnBackdrop: Whether clicking the backdrop triggers a close.
  • closeOnEsc: Whether pressing the ESC key triggers a close.
  • modal: Whether to display the dark backdrop layer.
vue
<script setup>
import { ref } from 'vue'

const visible = ref(false)
const config = {
  showClose: true,       // Display close button
  closeOnBackdrop: false, // Prohibit clicking backdrop to close
  closeOnEsc: true        // Allow ESC to close
}
</script>

<template>
  <TuiButton @click="visible = true">Open High-Interaction Drawer</TuiButton>

  <TuiDrawer v-model="visible" v-bind="config">
    <h3>Mandatory Operation</h3>
    <p>Clicking the backdrop will not close this. Please use the top-right button or press ESC.</p>
  </TuiDrawer>
</template>

API Reference

Props

PropertyDescriptionTypeDefault
modelValue(v-model) Whether to show the drawerBoolean
directionOpening direction; options: 'rtl', 'ltr', 'ttb', 'btt'String'rtl'
sizeDimensions (width or height); supports numbers (px) or percentage stringsString / Number'auto'
titleDrawer title (use Slot for complex titles)String
paddingInner padding of the drawer body (px)Number30
modalWhether to show the backdrop layerBooleantrue
showCloseWhether to show the close buttonBooleanfalse
closeOnBackdropWhether clicking the backdrop triggers closeBooleantrue
closeOnEscWhether pressing the Esc key triggers closeBooleantrue
appendToDOM node selector for mountingString
zIndexSets the z-index levelNumber2001
classNameCustom class nameString

Emits

Event NameDescriptionCallback Parameters
update:modelValueTriggered when the bound value changesvalue: boolean
openTriggered when the drawer opens
closeTriggered when the drawer closes

Slots

Slot NameDescription
defaultMain content of the drawer

Global Interaction Monitoring

The TuiDrawer component achieves intelligent closing management by integrating with the TechUI global service (TuiService), utilizing two core parameters: escCounter and clickCounter:

  • ESC Response (escCounter): The component monitors global ESC signals in real-time. When closeOnEsc is true, pressing the Esc key updates the escCounter, automatically closing the currently active drawer.
  • Intelligent Click Detection (clickCounter):
  • Backdrop Click: When modal and closeOnBackdrop are both true, the component detects if the click target is the backdrop itself to trigger closing.
  • External Click (No-modal Mode): When modal is false, the component uses the global clickTarget for precise containment detection. A close logic is only triggered if the click target is neither inside the drawer panel nor inside the trigger element. This ensures that drawers without backdrops still possess a natural "click outside to close" experience.

Released under the MIT License.