DocsComposantsDrawer
Drawer
A panel that rises from the bottom; drag its handle down to close it.
Alpine.jsdépend de button6 fichiers
<pb-ui.drawer>
<pb-slot:trigger><pb-ui.button variant="outline">Ouvrir le drawer</pb-ui.button></pb-slot:trigger>
<div class="mx-auto w-full max-w-sm">
<pb-ui.drawer-header>
<pb-ui.drawer-title>Objectif du jour</pb-ui.drawer-title>
<pb-ui.drawer-description>Faites glisser la poignée vers le bas pour fermer.</pb-ui.drawer-description>
</pb-ui.drawer-header>
<div class="flex items-center justify-center gap-4 p-4" x-data="{ goal: 350 }">
<pb-ui.button variant="outline" size="icon" class="rounded-full" x-on:click="goal = Math.max(200, goal - 10)" aria-label="Moins">−</pb-ui.button>
<div class="text-center"><div class="text-6xl font-bold tracking-tighter" x-text="goal"></div><div class="text-xs text-muted-foreground uppercase">calories / jour</div></div>
<pb-ui.button variant="outline" size="icon" class="rounded-full" x-on:click="goal = Math.min(500, goal + 10)" aria-label="Plus">+</pb-ui.button>
</div>
<pb-ui.drawer-footer>
<pb-ui.button>Valider</pb-ui.button>
<pb-ui.drawer-close><pb-ui.button variant="outline" class="w-full">Annuler</pb-ui.button></pb-ui.drawer-close>
</pb-ui.drawer-footer>
</div>
</pb-ui.drawer>Installation
pyblade-ui add drawer- Installez les dépendances
button et Alpine.js, chargé dans votre
<head>. - Copiez ces fichiers dans votre projetcomponents/ui/drawer.html
@props({'name': '', 'trigger': '', 'open': False}) <div data-slot="drawer" x-data="{ open: {{ str(bool(open)).lower() }}, drag: 0, start: null, down(e) { this.start = e.clientY; e.target.setPointerCapture(e.pointerId) }, move(e) { if (this.start !== null) this.drag = Math.max(0, e.clientY - this.start) }, up() { if (this.drag > 100) this.open = false; this.drag = 0; this.start = null }, }" x-on:keydown.escape.window="open = false" x-on:drawer-open.window="$event.detail === '{{ name }}' && (open = true)" x-on:drawer-close.window="$event.detail === '{{ name }}' && (open = false)" x-effect="document.body.classList.toggle('overflow-hidden', open)" class="contents"> <span data-slot="drawer-trigger" class="contents" x-on:click="open = true">{{ trigger }}</span> <div x-show="open" x-cloak class="fixed inset-0 z-50"> <div data-slot="drawer-overlay" x-show="open" x-transition.opacity.duration.300ms class="fixed inset-0 bg-black/50" x-on:click="open = false"></div> <div role="dialog" aria-modal="true" data-slot="drawer-content" x-show="open" x-transition:enter="transition duration-300 ease-out" x-transition:enter-start="translate-y-full" x-transition:enter-end="translate-y-0" x-transition:leave="transition duration-200 ease-in" x-transition:leave-start="translate-y-0" x-transition:leave-end="translate-y-full" x-bind:style="{ transform: drag ? `translateY(${drag}px)` : '', transition: drag ? 'none' : '' }" {{ attributes.cn("fixed inset-x-0 bottom-0 z-50 mt-24 flex max-h-[80vh] flex-col rounded-t-lg border-t bg-background") }}> <div class="flex shrink-0 cursor-grab touch-none justify-center py-4 active:cursor-grabbing" x-on:pointerdown="down($event)" x-on:pointermove="move($event)" x-on:pointerup="up()" x-on:pointercancel="up()"> <div class="h-2 w-[100px] rounded-full bg-muted"></div> </div> {{ slot }} </div> </div> </div>components/ui/drawer_header.html<div data-slot="drawer-header" {{ attributes.cn("flex flex-col gap-1.5 p-4 text-center md:text-left") }}>{{ slot }}</div>components/ui/drawer_footer.html<div data-slot="drawer-footer" {{ attributes.cn("mt-auto flex flex-col gap-2 p-4") }}>{{ slot }}</div>components/ui/drawer_title.html<h2 data-slot="drawer-title" {{ attributes.cn("font-semibold text-foreground") }}>{{ slot }}</h2>components/ui/drawer_description.html<p data-slot="drawer-description" {{ attributes.cn("text-sm text-muted-foreground") }}>{{ slot }}</p>components/ui/drawer_close.html<span data-slot="drawer-close" x-on:click="open = false" {{ attributes.cn("contents") }}>{{ slot }}</span> - Adaptez le chemin à votre projet
Le dossier
componentsest celui déclaré danspyblade.toml.
Utilisation
Les balises <pb-ui.drawer> <pb-ui.drawer-header> <pb-ui.drawer-footer> <pb-ui.drawer-title> <pb-ui.drawer-description> <pb-ui.drawer-close> sont disponibles dans tous vos templates.
<pb-ui.drawer>
<pb-slot:trigger><pb-ui.button variant="outline">Open</pb-ui.button></pb-slot:trigger>
<pb-ui.drawer-header>
<pb-ui.drawer-title>Move goal</pb-ui.drawer-title>
<pb-ui.drawer-description>Set your daily activity goal.</pb-ui.drawer-description>
</pb-ui.drawer-header>
<pb-ui.drawer-footer>
<pb-ui.drawer-close><pb-ui.button variant="outline">Cancel</pb-ui.button></pb-ui.drawer-close>
</pb-ui.drawer-footer>
</pb-ui.drawer>Props
| Prop | Défaut |
|---|---|
| name | '' |
| trigger | '' |
| open | False |
Tout autre attribut (class, id, x-on:click, hx-post…) est transmis à l'élément racine ; vos classes Tailwind l'emportent sur celles du composant.