Tiroir
Panneau latéral coulissant depuis le bord de l'écran, adapté aux interactions temporaires plus proches du bord qu'un Dialog (détails, filtres, étapes d'un assistant). Comme le Dialog, il repose sur role="dialog" + aria-modal="true", avec un piège de focus à l'intérieur du panneau ; Échap et le clic sur le masque ferment tous deux le tiroir.
Utilisation de base
<template>
<LhButton @click="basic = true">Ouvrir le tiroir</LhButton>
<LhDrawer v-model="basic" title="Détail de la commande">
<p>Le contenu principal du tiroir se place ici.</p>
</LhDrawer>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const basic = ref(false)
</script><script>
export default {
data() {
return { basic: false }
},
}
</script>
<template>
<LhButton @click="basic = true">Ouvrir le tiroir</LhButton>
<LhDrawer v-model="basic" title="Détail de la commande">
<p>Le contenu principal du tiroir se place ici.</p>
</LhDrawer>
</template>Quatre directions
<script setup lang="ts">
import { ref } from 'vue'
const dirVisible = ref(false)
const direction = ref<'right' | 'left' | 'top' | 'bottom'>('right')
const size = ref('40%')
function openDir(d: 'right' | 'left' | 'top' | 'bottom') {
direction.value = d
dirVisible.value = true
}
</script>
<template>
<!-- Ouvrir le tiroir droit -->
<LhButton @click="openDir('right')">right</LhButton>
<!-- Ouvrir le tiroir gauche -->
<LhButton @click="openDir('left')">left</LhButton>
<!-- Ouvrir le tiroir supérieur -->
<LhButton @click="openDir('top')">top</LhButton>
<!-- Ouvrir le tiroir inférieur -->
<LhButton @click="openDir('bottom')">bottom</LhButton>
<!-- Coulissement dans la direction spécifiée -->
<LhDrawer v-model="dirVisible" :title="`Tiroir ${direction}`" :direction="direction" :size="size">
<p>Direction actuelle : {{ direction }}</p>
</LhDrawer>
</template><script>
export default {
data() {
return { dirVisible: false, direction: 'right', size: '40%' }
},
methods: {
openDir(d) {
this.direction = d
this.dirVisible = true
},
},
}
</script>
<template>
<!-- Ouvrir le tiroir droit -->
<LhButton @click="openDir('right')">right</LhButton>
<!-- Ouvrir le tiroir gauche -->
<LhButton @click="openDir('left')">left</LhButton>
<!-- Ouvrir le tiroir supérieur -->
<LhButton @click="openDir('top')">top</LhButton>
<!-- Ouvrir le tiroir inférieur -->
<LhButton @click="openDir('bottom')">bottom</LhButton>
<!-- Coulissement dans la direction spécifiée -->
<LhDrawer v-model="dirVisible" :title="`Tiroir ${direction}`" :direction="direction" :size="size">
<p>Direction actuelle : {{ direction }}</p>
</LhDrawer>
</template>Taille personnalisée et pied de panneau
<script setup lang="ts">
import { ref } from 'vue'
const sized = ref(false)
</script>
<template>
<!-- Ouvrir un tiroir de 480 px de large -->
<LhButton @click="sized = true">Tiroir de 480 px de large</LhButton>
<!-- Tiroir à taille fixée, le pied de panneau sert de zone d'actions -->
<LhDrawer v-model="sized" title="Filtres" :size="480">
<LhInput placeholder="Filtrer par nom" />
<LhInput placeholder="Filtrer par étiquette" />
<template #footer>
<LhButton @click="sized = false">Annuler</LhButton>
<LhButton type="primary" @click="sized = false">Appliquer les filtres</LhButton>
</template>
</LhDrawer>
</template><script>
export default {
data() {
return { sized: false }
},
}
</script>
<template>
<!-- Ouvrir un tiroir de 480 px de large -->
<LhButton @click="sized = true">Tiroir de 480 px de large</LhButton>
<!-- Tiroir à taille fixée, le pied de panneau sert de zone d'actions -->
<LhDrawer v-model="sized" title="Filtres" :size="480">
<LhInput placeholder="Filtrer par nom" />
<LhInput placeholder="Filtrer par étiquette" />
<template #footer>
<LhButton @click="sized = false">Annuler</LhButton>
<LhButton type="primary" @click="sized = false">Appliquer les filtres</LhButton>
</template>
</LhDrawer>
</template>
sizeest en px lorsqu'un nombre est transmis, et accepte les pourcentages sous forme de chaîne (par exemple'40%'). Il s'applique à la largeur pour les directions gauche/droite, et à la hauteur pour haut/bas.
Comportements
mask-closable empêche la fermeture par clic sur le masque, show-close masque le bouton de fermeture en haut à droite, close-on-esc désactive la fermeture avec Échap, lock-scroll empêche le verrouillage du défilement de la page à l'ouverture, et teleport-target désigne le conteneur de montage.
<script setup lang="ts">
import { ref } from 'vue'
const adv1 = ref(false)
const adv2 = ref(false)
const adv3 = ref(false)
</script>
<template>
<!-- Ouvrir le tiroir « Boutons uniquement » -->
<LhButton @click="adv1 = true">Boutons uniquement</LhButton>
<!-- Ouvrir le tiroir « Défilement non verrouillé » -->
<LhButton @click="adv2 = true">Défilement non verrouillé</LhButton>
<!-- Le clic sur le masque et Échap ne ferment pas -->
<LhDrawer
v-model="adv1"
title="Boutons uniquement"
:mask-closable="false"
:show-close="false"
:close-on-esc="false"
>
<p>Le clic sur le masque et Échap ne ferment pas le panneau, seule la fermeture par bouton est possible.</p>
<template #footer>
<LhButton type="primary" @click="adv1 = false">Fermer</LhButton>
</template>
</LhDrawer>
<!-- La page reste défilable à l'ouverture -->
<LhDrawer v-model="adv2" title="Défilement non verrouillé" :lock-scroll="false">
<p>La page reste défilable lorsque le tiroir est ouvert.</p>
</LhDrawer>
<!-- Montage dans le conteneur désigné -->
<LhDrawer v-model="adv3" title="Conteneur de montage désigné" teleport-target="#drawer-host">
<p>Le panneau est téléporté dans le conteneur d'id drawer-host.</p>
</LhDrawer>
</template><script>
export default {
data() {
return { adv1: false, adv2: false, adv3: false }
},
}
</script>
<template>
<!-- Ouvrir le tiroir « Boutons uniquement » -->
<LhButton @click="adv1 = true">Boutons uniquement</LhButton>
<!-- Ouvrir le tiroir « Défilement non verrouillé » -->
<LhButton @click="adv2 = true">Défilement non verrouillé</LhButton>
<!-- Le clic sur le masque et Échap ne ferment pas -->
<LhDrawer
v-model="adv1"
title="Boutons uniquement"
:mask-closable="false"
:show-close="false"
:close-on-esc="false"
>
<p>Le clic sur le masque et Échap ne ferment pas le panneau, seule la fermeture par bouton est possible.</p>
<template #footer>
<LhButton type="primary" @click="adv1 = false">Fermer</LhButton>
</template>
</LhDrawer>
<!-- La page reste défilable à l'ouverture -->
<LhDrawer v-model="adv2" title="Défilement non verrouillé" :lock-scroll="false">
<p>La page reste défilable lorsque le tiroir est ouvert.</p>
</LhDrawer>
<!-- Montage dans le conteneur désigné -->
<LhDrawer v-model="adv3" title="Conteneur de montage désigné" teleport-target="#drawer-host">
<p>Le panneau est téléporté dans le conteneur d'id drawer-host.</p>
</LhDrawer>
</template>Drawer API
Props
| Propriété | Description | Type | Valeur par défaut |
|---|---|---|---|
| modelValue | Affichage (v-model) | boolean | — |
| title | Titre (le slot header convient également) | string | — |
| direction | Direction | "right" | "left" | "top" | "bottom" | 'right' |
| size | Taille : nombre en px, la chaîne accepte les pourcentages | string | number | '30%' |
| maskClosable | Fermer lors d'un clic sur le masque | boolean | true |
| showClose | Afficher le bouton de fermeture | boolean | true |
| teleportTarget | Cible du Teleport (sélecteur ou élément, body par défaut) | string | HTMLElement | 'body' |
| lockScroll | Verrouiller le défilement de la page | boolean | true |
| closeOnEsc | Répondre à Échap pour fermer | boolean | true |
| themeVars | Variables de thème au niveau du composant, surchargeant la configuration de ConfigProvider | { [x: string]: string; } | — |
| bgPattern | Motif d'arrière-plan au niveau du composant, surchargeant la configuration de ConfigProvider | string | — |
| sx | Propriétés de mise en page rapide sx (appliquées au panneau) | LhSxProps | — |
Events
| Événement | Description | Paramètre |
|---|---|---|
| update:model-value | Changement de visibilité | (value: boolean) |
| open | Déclenché après l'ouverture | — |
| close | Déclenché après la fermeture | — |
Slots
| Slot | Description |
|---|---|
| default | Contenu principal |
| header | En-tête personnalisé (incluant la zone de titre) |
| footer | Zone d'actions personnalisée en pied de panneau |
Methods
| Méthode | Description |
|---|---|
| open | Ouverture programmatique |
| close | Fermeture programmatique |
Accessibilité
role="dialog"+aria-modal="true"; avec un titre, l'association se fait viaaria-labelledby, sans titre le pack de languedrawer.titlesert de aria-label de repli- À l'ouverture, le focus se déplace sur le premier élément focusable du panneau, Tab boucle à l'intérieur du panneau, et le focus est rendu au déclencheur après fermeture
- Fermeture par Échap (désactivable avec
close-on-esc) ; le masque est décoratif (aria-hidden) - Le bouton de fermeture est un véritable
<button>, son aria-label est issu du pack de languedrawer.close - L'animation de coulissement est réduite à un simple fondu lorsque
prefers-reduced-motionest actif
Définitions de types
Les structures de types TypeScript exportées par ce composant sont présentées ci-dessous (extraction automatique à partir des sources packages/components/drawer/src/types.ts et @lh-ui/share/core/* ; cliquez sur chaque entrée pour afficher la définition complète ; la description des propriétés se trouve dans le tableau Props ci-dessus) :
LhDrawerProps
/**
* Props du composant Drawer
*/
export interface LhDrawerProps {
/** Affichage (v-model) */
modelValue?: boolean
/** Titre */
title?: string
/** Direction */
direction?: LhDrawerDirection
/** Taille : nombre en px, la chaîne accepte les pourcentages */
size?: string | number
/** Fermer lors d'un clic sur le masque */
maskClosable?: boolean
/** Afficher le bouton de fermeture */
showClose?: boolean
/** Cible du Teleport (sélecteur ou élément, body par défaut) */
teleportTarget?: string | HTMLElement
/** Verrouiller le défilement de la page */
lockScroll?: boolean
/** Répondre à Échap pour fermer */
closeOnEsc?: boolean
/** Variables de thème au niveau du composant, surchargeant la configuration de ConfigProvider */
themeVars?: Record<string, string>
/** Motif d'arrière-plan au niveau du composant, surchargeant la configuration de ConfigProvider */
bgPattern?: string
/** Propriétés de mise en page rapide sx (appliquées au panneau) */
sx?: LhSxProps
}LhDrawerDirection (provient de @lh-ui/share/core/drawer (logic.ts))
/**
* Logique en fonctions pures du Drawer (sans dépendance de framework)
*/
/** Direction du tiroir */
export type LhDrawerDirection = 'right' | 'left' | 'top' | 'bottom'