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.
<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 Rightttb: Top to Bottombtt: Bottom to Top
<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.
<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.
<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
| Property | Description | Type | Default |
|---|---|---|---|
| modelValue | (v-model) Whether to show the drawer | Boolean | — |
| direction | Opening direction; options: 'rtl', 'ltr', 'ttb', 'btt' | String | 'rtl' |
| size | Dimensions (width or height); supports numbers (px) or percentage strings | String / Number | 'auto' |
| title | Drawer title (use Slot for complex titles) | String | — |
| padding | Inner padding of the drawer body (px) | Number | 30 |
| modal | Whether to show the backdrop layer | Boolean | true |
| showClose | Whether to show the close button | Boolean | false |
| closeOnBackdrop | Whether clicking the backdrop triggers close | Boolean | true |
| closeOnEsc | Whether pressing the Esc key triggers close | Boolean | true |
| appendTo | DOM node selector for mounting | String | — |
| zIndex | Sets the z-index level | Number | 2001 |
| className | Custom class name | String | — |
Emits
| Event Name | Description | Callback Parameters |
|---|---|---|
| update:modelValue | Triggered when the bound value changes | value: boolean |
| open | Triggered when the drawer opens | — |
| close | Triggered when the drawer closes | — |
Slots
| Slot Name | Description |
|---|---|
| default | Main 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. WhencloseOnEscistrue, pressing the Esc key updates theescCounter, automatically closing the currently active drawer. - Intelligent Click Detection (
clickCounter): - Backdrop Click: When
modalandcloseOnBackdropare bothtrue, the component detects if the click target is the backdrop itself to trigger closing. - External Click (No-modal Mode): When
modalisfalse, the component uses the globalclickTargetfor 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.