Sheet
Ein Panel, das von jeder Kante hereingleitet, mit Wischen zum Schließen, Scroll-Sperre und gestapelter Verschachtelung.
pnpm dlx shadcn@latest add https://hextaui.com/r/sheet.jsonFügt die Komponente, die HextaUI-Theme-Tokens und alle HextaUI-Komponenten hinzu, von denen sie abhängt.
Füge die Theme-Tokens zu deinem globalen CSS hinzu, falls du das noch nicht getan hast.
Installiere die Abhängigkeiten.
pnpm add @base-ui/react @tabler/icons-react class-variance-authority cnKopiere den folgenden Code und füge ihn in dein Projekt ein.
components/ui/sheet.tsx components/ui/button.tsx Passe die Importpfade an dein Projekt-Setup an.
Seiten
Setze side, damit es von einem beliebigen Rand hereingleitet. Jedes Sheet lässt sich zu seinem eigenen Rand zurückwischen, und die Schließgeste folgt deinem Finger mit Schwung.
Langer Inhalt
<SheetBody /> scrollt für sich, sodass Header und Footer an Ort und Stelle bleiben, egal wie lang der Inhalt wird.
Ohne Schließen-Button
Setze showCloseButton={false}, wenn der Footer schon einen Ausweg bietet. Escape, der Backdrop und Wischen schließen es weiterhin.
Verschachtelt
Ein Sheet oder Alert dialog, der aus einem Sheet geöffnet wird, legt sich darüber. Das Elternteil skaliert leicht zurück, und jede weitere Ebene fügt einen helleren Backdrop hinzu, sodass der Stapel lesbar bleibt. Escape schließt nur die oberste Ebene.
Kontrolliert
Übergib open und onOpenChange, um ihn von überall ohne Trigger zu öffnen.
Losgelöste Trigger
Teile ein Sheet zwischen mehreren Triggern mit createSheetHandle. Jeder Trigger übergibt einen payload, den das Sheet über ein Funktions-Child rendert.
Rechts nach links
Mit dir="rtl" spiegelt sich die rechte Seite an den linken Rand, gleitet von dort herein und wird genauso hinausgewischt.
| Taste | Aktion |
|---|---|
| EnterSpace | Am Trigger öffnet es das Sheet und setzt den Fokus hinein. |
| TabShift + Tab | Wechselt zwischen fokussierbaren Elementen. Der Fokus bleibt im Sheet. |
| Esc | Schließt das oberste Sheet und gibt den Fokus an seinen Trigger zurück. |
- Das Sheet ist ein modaler Dialog.
<SheetTitle />beschriftet es und<SheetDescription />beschreibt es, füge also immer einen Titel hinzu. - Seitenscroll ist gesperrt, und Inhalt dahinter ist vor assistiver Technik verborgen, solange es offen ist.
- Der Schließen-Button trägt das Label „Close“. Der Griff am inneren Rand zeigt, dass das Sheet gezogen werden kann, und ist vor assistiver Technik verborgen.
- Bei aktivierter reduzierter Bewegung blendet das Sheet ein und aus, statt zu gleiten.
Basiert auf dem Base UI Drawer. Jeder Teil akzeptiert die Props der Primitive, die er umschließt.
| Prop | Typ | Standard |
|---|---|---|
defaultOpen | boolean | false |
open | boolean | – |
onOpenChange | (open: boolean, details) => void | – |
onOpenChangeCompleteWird aufgerufen, nachdem die Öffnen- oder Schließen-Animation endet. | (open: boolean) => void | – |
modal | boolean | "trap-focus" | true |
disablePointerDismissalOffen halten, wenn auf den Backdrop geklickt wird. | boolean | false |
swipeDirectionWird automatisch aus Seite und Richtung des Inhalts gesetzt. | "up" | "down" | "left" | "right" | – |
handle | SheetHandle<Payload> | – |
children | ReactNode | ({ payload }) => ReactNode | – |
| Prop | Typ | Standard |
|---|---|---|
handle | SheetHandle<Payload> | – |
payload | Payload | – |
render | ReactElement | (props, state) => ReactElement | <button> |
| Attribut | Beschreibung |
|---|---|
data-slot="sheet-trigger" | Den Trigger in CSS ansprechen. |
data-popup-open | Vorhanden, solange sein Sheet offen ist. |
Rendert Portal, Backdrop, Viewport und Popup sowie Ziehgriff und Schließen-Button.
| Prop | Typ | Standard |
|---|---|---|
side | "top" | "right" | "bottom" | "left" | "right" |
showCloseButton | boolean | true |
dirLegt die Richtung für das Sheet fest. right und left spiegeln sich in rtl. | "ltr" | "rtl" | – |
initialFocus | boolean | RefObject | (type) => HTMLElement | boolean | – |
finalFocus | boolean | RefObject | (type) => HTMLElement | boolean | – |
classNameSeiten-Sheets sind 75% breit, ab dem sm-Breakpoint bis zu 24rem. | string | (state) => string | – |
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribut | Beschreibung |
|---|---|
data-slot="sheet-content" | Das Sheet-Panel. |
data-side | Die Seite, von der es öffnet. |
data-open | Vorhanden, solange das Sheet offen ist. |
data-starting-style | Vorhanden, während es einanimiert. |
data-ending-style | Vorhanden, während es ausanimiert. |
data-swiping | Vorhanden, solange er gezogen wird. |
data-swipe-direction | Die Richtung, die es schließt. |
data-nested-drawer-open | Vorhanden, solange oben ein verschachteltes Sheet offen ist. |
data-slot="sheet-handle" | Der Ziehgriff am inneren Rand. |
data-slot="sheet-close-button" | Der eingebaute Schließen-Button. |
--drawer-swipe-movement-x | Horizontale Ziehstrecke. Es gibt auch eine -y-Variable. |
--nested-drawers | Wie viele verschachtelte Sheets oben offen sind. |
Wird von <SheetContent /> gerendert. Verschachtelte Ebenen erhalten einen helleren Backdrop.
| Attribut | Beschreibung |
|---|---|
data-slot="sheet-overlay" | Der Hintergrund. |
data-nested | Vorhanden bei Backdrops verschachtelter Ebenen. |
Einfache <div>-Elemente, die das Sheet anordnen. Der Header lässt Platz für den Schließen-Button, der Body scrollt und nimmt die restliche Höhe ein, und der Footer stapelt seine Aktionen auf kleinen Bildschirmen und richtet sie ab dem sm-Breakpoint am Ende aus.
| Attribut | Beschreibung |
|---|---|
data-slot="sheet-header" | Titel und Beschreibung. |
data-slot="sheet-body" | Scrollbarer Inhalt. |
data-slot="sheet-footer" | Aktionen. |
| Prop | Typ | Standard |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <h2> |
| Attribut | Beschreibung |
|---|---|
data-slot="sheet-title" | Beschriftet das Sheet. |
| Prop | Typ | Standard |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <p> |
| Attribut | Beschreibung |
|---|---|
data-slot="sheet-description" | Beschreibt das Sheet. |
| Prop | Typ | Standard |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <button> |
| Attribut | Beschreibung |
|---|---|
data-slot="sheet-close" | Schließt das Sheet beim Drücken. |
createSheetHandle<Payload>() gibt ein Handle zurück, das einen <Sheet /> mit an anderer Stelle gerenderten Triggern verbindet. Erstelle es einmal, außerhalb deiner Komponente.
- ButtonButtons in allen Varianten und Größen, mit eingebautem Lade-, Erfolgs- und Fehlerablauf, der den Spinner bei schnellen Anfragen überspringt.
- Alert dialogEin Bestätigungsdialog für destruktive oder wichtige Aktionen, der auf asynchrone Arbeit wartet und auf Smartphones zum Bottom Sheet wird.
- CommandEine durchsuchbare Liste von Aktionen, inline oder als ⌘K-Palette, mit Seiten, Tastenkürzeln und hervorgehobenen Treffern.
- Context menuEin Menü mit Aktionen per Rechtsklick oder langem Drücken, mit Untermenüs, Checkbox- und Radio-Einträgen sowie Halte-Feedback auf Touch-Geräten.
- DialogEin Fenster über der Seite für Formulare und fokussierte Aufgaben, mit fixiertem Header und Footer, Verschachtelung und einem wischbaren Bottom Sheet auf Smartphones.
- DrawerEin Panel, das von jeder Kante hereingleitet und deinem Finger folgt, mit Snap-Punkten, einem funktionierenden Griff und verschachtelten Drawern, die sich stapeln.
In Blocks verwendet
Blocks, die auf Sheet aufbauen.