DocsComposantsSheet
Sheet
A panel that slides in from an edge of the screen.
Alpine.jsdépend de button6 fichiers
<pb-ui.sheet name="profile">
<pb-slot:trigger><pb-ui.button variant="outline">Ouvrir</pb-ui.button></pb-slot:trigger>
<pb-ui.sheet-header>
<pb-ui.sheet-title>Modifier le profil</pb-ui.sheet-title>
<pb-ui.sheet-description>Enregistrez quand vous avez terminé.</pb-ui.sheet-description>
</pb-ui.sheet-header>
<div class="grid gap-4 px-4">
<div class="grid gap-2"><pb-ui.label for="sname">Nom</pb-ui.label><pb-ui.input id="sname" value="Ada Lovelace" /></div>
<div class="grid gap-2"><pb-ui.label for="suser">Utilisateur</pb-ui.label><pb-ui.input id="suser" value="@ada" /></div>
</div>
<pb-ui.sheet-footer>
<pb-ui.button>Enregistrer</pb-ui.button>
<pb-ui.sheet-close><pb-ui.button variant="outline">Fermer</pb-ui.button></pb-ui.sheet-close>
</pb-ui.sheet-footer>
</pb-ui.sheet>Installation
pyblade-ui add sheet- Installez les dépendances
button et Alpine.js, chargé dans votre
<head>. - Copiez ces fichiers dans votre projetcomponents/ui/sheet.html
@props({'name': '', 'trigger': '', 'side': 'right', 'open': False}) <div data-slot="sheet" x-data="{ open: {{ str(bool(open)).lower() }} }" x-on:keydown.escape.window="open = false" x-on:sheet-open.window="$event.detail === '{{ name }}' && (open = true)" x-on:sheet-close.window="$event.detail === '{{ name }}' && (open = false)" x-effect="document.body.classList.toggle('overflow-hidden', open)" class="contents"> <span data-slot="sheet-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="sheet-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="sheet-content" x-show="open" x-transition:enter="transition duration-300 ease-out" x-transition:leave="transition duration-200 ease-in" x-transition:enter-start="{{ {'right': 'translate-x-full', 'left': '-translate-x-full', 'top': '-translate-y-full', 'bottom': 'translate-y-full'}[side] }}" x-transition:leave-end="{{ {'right': 'translate-x-full', 'left': '-translate-x-full', 'top': '-translate-y-full', 'bottom': 'translate-y-full'}[side] }}" {{ attributes.cn( "fixed z-50 flex flex-col gap-4 bg-background shadow-lg", { 'right': 'inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm', 'left': 'inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm', 'top': 'inset-x-0 top-0 h-auto border-b', 'bottom': 'inset-x-0 bottom-0 h-auto border-t', }[side], ) }}> {{ slot }} <button type="button" x-on:click="open = false" class="absolute top-4 right-4 cursor-pointer rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden [&_svg]:size-4"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg> <span class="sr-only">Close</span> </button> </div> </div> </div>components/ui/sheet_header.html<div data-slot="sheet-header" {{ attributes.cn("flex flex-col gap-1.5 p-4") }}>{{ slot }}</div>components/ui/sheet_footer.html<div data-slot="sheet-footer" {{ attributes.cn("mt-auto flex flex-col gap-2 p-4") }}>{{ slot }}</div>components/ui/sheet_title.html<h2 data-slot="sheet-title" {{ attributes.cn("font-semibold text-foreground") }}>{{ slot }}</h2>components/ui/sheet_description.html<p data-slot="sheet-description" {{ attributes.cn("text-sm text-muted-foreground") }}>{{ slot }}</p>components/ui/sheet_close.html<span data-slot="sheet-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.sheet> <pb-ui.sheet-header> <pb-ui.sheet-footer> <pb-ui.sheet-title> <pb-ui.sheet-description> <pb-ui.sheet-close> sont disponibles dans tous vos templates.
<pb-ui.sheet side="right">
<pb-slot:trigger><pb-ui.button variant="outline">Open</pb-ui.button></pb-slot:trigger>
<pb-ui.sheet-header>
<pb-ui.sheet-title>Edit profile</pb-ui.sheet-title>
<pb-ui.sheet-description>Save when you are done.</pb-ui.sheet-description>
</pb-ui.sheet-header>
<pb-ui.sheet-footer>
<pb-ui.sheet-close><pb-ui.button variant="outline">Close</pb-ui.button></pb-ui.sheet-close>
</pb-ui.sheet-footer>
</pb-ui.sheet>
{# Or from anywhere: $dispatch('sheet-open', 'name') #}Exemples
Côtés
<div class="grid grid-cols-2 gap-2">
@for(side in ['top', 'right', 'bottom', 'left'])
<pb-ui.sheet :side="side">
<pb-slot:trigger><pb-ui.button variant="outline" class="w-full">{{ side }}</pb-ui.button></pb-slot:trigger>
<pb-ui.sheet-header>
<pb-ui.sheet-title>Panneau {{ side }}</pb-ui.sheet-title>
<pb-ui.sheet-description>Il glisse depuis ce bord de l'écran.</pb-ui.sheet-description>
</pb-ui.sheet-header>
</pb-ui.sheet>
@endfor
</div>Props
| Prop | Défaut |
|---|---|
| name | '' |
| trigger | '' |
| side | 'right' |
| 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.