Dialog
Ein Fenster über der Seite für Formulare und fokussierte Aufgaben, mit fixiertem Header und Footer, Verschachtelung und einem wischbaren Bottom Sheet auf Smartphones.
pnpm dlx shadcn@latest add https://hextaui.com/r/dialog.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/dialog.tsx components/ui/sheet.tsx components/ui/button.tsx Passe die Importpfade an dein Projekt-Setup an.
Form
Behalte das Formular in <DialogBody /> und verweise den Submit-Button im Footer mit form darauf. Enter sendet ab, und der Dialog schließt sich über onOpenChange, sobald der Wert gespeichert ist.
Eigener Schließen-Button
Blende den Eck-Button mit showCloseButton={false} am Content aus und füge dem Footer mit showCloseButton einen Close-Button hinzu.
Kein Schließen-Button
Ohne Button schließt sich der Dialog weiterhin mit Esc, einem Klick nach außen oder auf Smartphones mit einem Wischen nach unten.
Größen
size legt auf größeren Bildschirmen die maximale Breite fest: sm, default oder lg.
Fixierter Footer
Langer Inhalt in <DialogBody /> scrollt, während Header und Footer an Ort und Stelle bleiben, sodass die Aktionen immer in Reichweite sind.
Scrollbarer Inhalt
Ohne Footer scrollt der Body unter dem Header und behält sein unteres Padding.
Kontrolliert
Übergib open und onOpenChange, um ihn ohne Trigger aus dem Code zu öffnen.
Verschachtelt
Ein Dialog oder Alert Dialog, der aus einem anderen heraus geöffnet wird, legt sich darüber. Der untere tritt zurück, und ein hellerer Backdrop deckt ihn ab. Esc schließt nur den obersten.
Losgelöste Trigger
Erstelle ein Handle mit createDialogHandle(), um einen Dialog für viele Trigger zu teilen. Jeder Trigger übergibt ein payload, das der Dialog über eine Render-Funktion liest.
Rechts nach links
Übergib dir auch an den Content, da er in einem Portal außerhalb deines RTL-Containers gerendert wird.
| Taste | Aktion |
|---|---|
| EnterSpace | Am Trigger: öffnet den Dialog und setzt den Fokus auf sein erstes Bedienelement. |
| TabShift+Tab | Bewegt den Fokus zwischen den Bedienelementen. Der Fokus bleibt im Dialog. |
| Esc | Schließt den obersten Dialog und gibt den Fokus an seinen Trigger zurück. |
- Der Content hat
role="dialog", wird durch seinen Titel beschriftet und durch seine Beschreibung beschrieben. Binde immer einen<DialogTitle />ein. - Mit Maus oder Tastatur startet der Fokus auf dem ersten Bedienelement. Bei Touch startet er auf dem Dialog selbst, damit die Bildschirmtastatur den Inhalt nicht verdeckt, bevor man ein Feld wählt. Übergib
initialFocus, um das zu ändern. - Der Schließen-Button in der Ecke ist mit „Close“ beschriftet, und die Seite dahinter ist inert und lässt sich nicht scrollen.
- Auf Smartphones wird er zu einem Bottom Sheet, das sich zum Schließen nach unten wischen lässt. Bei reduzierter Bewegung blendet er ein und aus, statt zu skalieren oder zu gleiten.
Basiert über <Sheet /> auf dem Base UI Drawer. Jeder Teil akzeptiert die Props der Primitive oder des Elements, das er umschließt.
| Prop | Typ | Standard |
|---|---|---|
open | boolean | – |
defaultOpen | boolean | false |
onOpenChange | (open: boolean, details) => void | – |
onOpenChangeCompleteWird nach der Öffnen- oder Schließen-Animation aufgerufen. | (open: boolean) => void | – |
modal | boolean | "trap-focus" | true |
disablePointerDismissalHält den Dialog bei Klicks nach außen offen. | boolean | false |
handleVerbindet losgelöste Trigger. | DialogHandle<Payload> | – |
actionsRefDen Dialog imperativ schließen oder unmounten. | RefObject<{ close, unmount }> | – |
children | ReactNode | ({ payload }) => ReactNode | – |
| Prop | Typ | Standard |
|---|---|---|
handle | DialogHandle<Payload> | – |
payloadWird an die Render-Funktion des Dialogs übergeben. | Payload | – |
render | ReactElement | (props, state) => ReactElement | <button> |
| Attribut | Beschreibung |
|---|---|
data-slot="dialog-trigger" | Trigger in CSS ansprechen. |
data-popup-open | Vorhanden, solange sein Dialog geöffnet ist. |
| Prop | Typ | Standard |
|---|---|---|
size | "sm" | "default" | "lg" | "default" |
showCloseButtonZeigt den Schließen-Button in der Ecke. | boolean | true |
initialFocus | boolean | RefObject | (openType) => HTMLElement | boolean | First control, or the dialog on touch |
finalFocus | boolean | RefObject | (closeType) => HTMLElement | boolean | The trigger |
dirSetze es, wenn der Dialog von rechts nach links laufen soll. | "ltr" | "rtl" | – |
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribut | Beschreibung |
|---|---|
data-slot="dialog-content" | Den Dialog in CSS ansprechen. |
data-size | Die aktuelle Größe. |
data-open | Vorhanden, solange geöffnet. |
data-starting-style | Vorhanden, während der Dialog eingeblendet wird. |
data-ending-style | Vorhanden, während der Dialog ausgeblendet wird. |
data-nested-drawer-open | Vorhanden, solange darüber ein verschachtelter Dialog geöffnet ist. |
data-swiping | Vorhanden, solange er auf einem Smartphone gewischt wird. |
--nested-drawers | Wie viele Dialoge über diesem geöffnet sind. |
Eine <div>, die Titel und Beschreibung stapelt. Sie lässt Platz für den Schließen-Button.
| Attribut | Beschreibung |
|---|---|
data-slot="dialog-header" | Den Header in CSS ansprechen. |
Eine <div>, die scrollt, wenn der Inhalt höher als der Bildschirm ist, und Header und Footer an Ort und Stelle hält.
| Attribut | Beschreibung |
|---|---|
data-slot="dialog-body" | Den Body in CSS ansprechen. |
Eine <div> für die Aktionen. Auf Smartphones werden Buttons in voller Breite gestapelt, der erste unten.
| Prop | Typ | Standard |
|---|---|---|
showCloseButtonFügt nach den Kindern einen Close-Button im Outline-Stil hinzu. | boolean | false |
| Attribut | Beschreibung |
|---|---|
data-slot="dialog-footer" | Den Footer in CSS ansprechen. |
| Prop | Typ | Standard |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <h2> |
| Attribut | Beschreibung |
|---|---|
data-slot="dialog-title" | Den Titel in CSS ansprechen. |
| Prop | Typ | Standard |
|---|---|---|
renderVerwende render={<div />}, wenn er mehrere Absätze enthält. | ReactElement | (props, state) => ReactElement | <p> |
| Attribut | Beschreibung |
|---|---|
data-slot="dialog-description" | Die Beschreibung in CSS ansprechen. |
| Prop | Typ | Standard |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <button> |
| Attribut | Beschreibung |
|---|---|
data-slot="dialog-close" | Schließen-Buttons in CSS ansprechen. |
<DialogContent /> rendert bereits beides. Verwende sie nur, wenn du ein eigenes Popup zusammensetzt.
| Prop | Typ | Standard |
|---|---|---|
keepMountedHält den Dialog im geschlossenen Zustand im DOM, wenn es am Portal gesetzt ist. | boolean | false |
Gibt ein Handle zurück, das <DialogTrigger />-Elemente an beliebiger Stelle der Seite mit einem <Dialog /> verbindet. Typisiere das Payload per Generic: createDialogHandle<{ name: string }>().
- ButtonButtons in allen Varianten und Größen, mit eingebautem Lade-, Erfolgs- und Fehlerablauf, der den Spinner bei schnellen Anfragen überspringt.
- SheetEin Panel, das von jeder Kante hereingleitet, mit Wischen zum Schließen, Scroll-Sperre und gestapelter Verschachtelung.
- 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.
- 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 Dialog aufbauen.
- Prompt InputEin Chat-Composer, der als ruhige einzelne Zeile beginnt, beim Schreiben zu einer Karte wächst und nach unten wandert, sobald die Unterhaltung beginnt. Enter sendet, sicher bei japanischer und chinesischer Eingabe. Dateien per Einfügen, Ablegen oder Auswählen hinzufügen, mit Vorschau, Fortschritt und Wiederholen. @ fügt Dateien hinzu und / führt Befehle aus einem Menü an der Einfügemarke aus. Ein Modellwähler mit Zifferntasten, ein Effort-Slider, der bei Max lebendig wird, ein Kontextring, Diktat mit Live-Wellenform, Tool-Chips, eine Warteschlange für Nachrichten, die während einer streamenden Antwort getippt werden, und Entwürfe, die einen Reload überstehen.
- API keysDie API-Schlüssel-Seite eines KI-Produkts, wie in den Konsolen von OpenAI und Anthropic. Schlüssel mit eingeschränkten Berechtigungen und Ablaufdatum erstellen, das Secret einmal sehen mit einem Kopieren, das sich bestätigt, mit Rückgängig widerrufen, direkt umbenennen, mit Übergangsfrist rotieren und die Nutzung pro Schlüssel sehen.
- BillingPlan & Nutzung für ein KI-Produkt, im Stil von Cursor, Claude und Vercel. Eine nach Modell aufgeteilte Nutzungsanzeige, die das Ende des Zyklus hochrechnet und warnt, bevor die Credits ausgehen, ein tägliches Diagramm zum Scrubben, ein Ausgabenlimit mit Warnungen, die du auf der Anzeige in der Vorschau siehst, Planwechsel mit exakter Anteilsberechnung, ein Kartenformular mit echter Validierung und Rechnungen als PDF-Download.
- ModelsDie Modelle-Seite in den Einstellungen eines KI-Produkts. Ein Standardmodell mit Kontext, Geschwindigkeit und Kosten auf einen Blick, ein Standard-Effort, der weiß, was jedes Modell unterstützt, eine durchsuchbare Modellliste nach Anbieter gruppiert mit Filtern, Pins und Sammelschaltern, OpenAI-kompatible Server mit echtem Verbindungstest und ein Refresh, der dir sagt, was neu ist.