Popover
Ein schwebendes Panel, das an einem Trigger verankert ist, sich sanft mit seinem Inhalt in der Größe ändert und der Richtung des Triggers folgt.
pnpm dlx shadcn@latest add https://hextaui.com/r/popover.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 cnKopiere den folgenden Code und füge ihn in dein Projekt ein.
components/ui/popover.tsx Passe die Importpfade an dein Projekt-Setup an.
Inhalt, der die Größe ändert
Wächst oder schrumpft der Inhalt, animiert das Popup seine Höhe, statt zu springen. Kontinuierliche Änderungen wie Tippen folgen dem Inhalt direkt, sodass nichts hinterherhinkt.
Kontrolliert
Übergib open und onOpenChange, um es aus deinem eigenen State zu steuern. Das zweite Argument nennt den Grund der Änderung, etwa trigger-press, outside-press oder escape-key.
Platzierung
side und align legen die bevorzugte Position fest. Ist kein Platz, klappt das Popup auf die andere Seite und verschiebt sich, um auf dem Bildschirm zu bleiben, mit 8px Abstand zu den Rändern.
Per Hover öffnen
Setze openOnHover am Trigger für Vorschaukarten. delay und closeDelay verhindern Flackern, wenn der Zeiger darüberfährt.
Losgelöste Trigger
Erstelle mit createPopoverHandle ein Handle, um ein Popover zwischen mehreren Triggern an beliebiger Stelle im Baum zu teilen. Jeder Trigger übergibt einen payload, und das Popup rendert ihn über ein Funktions-Child.
Mit einem Kalender
Verwende className="w-auto p-0" für Inhalt, der sein eigenes Padding mitbringt. Das Popup folgt dem Kalender, wenn er den Monat wechselt.
Verschachtelt
Ein Popover in einem anderen Popover oder einem Sheet liegt über seinem Elternteil. Klicks im Kind lassen das Elternteil offen, und Escape schließt nur die oberste Ebene.
Langer Inhalt
Ununterbrochener Text bricht im Popup um. Ist der Inhalt höher als der verfügbare Platz, scrollt das Popup in sich, statt aus dem Bildschirm zu laufen.
Modal
Mit modal ist das Scrollen der Seite gesperrt, und Klicks außerhalb schließen nur das Popover. Rendere darin ein <PopoverClose />, damit der Fokus gefangen werden kann und Touch-Screenreader einen Ausweg haben.
Deaktiviert
Ein disabled Trigger öffnet sein Popover nie.
Rechts nach links
Das Popup übernimmt die Richtung des Triggers, der es geöffnet hat, obwohl es in einem Portal rendert. Logische Seiten wie inline-end drehen sich mit.
| Taste | Aktion |
|---|---|
| EnterSpace | Am Trigger öffnet oder schließt es das Popover. Der Fokus wandert ins Popup. |
| Tab | Bewegt sich durch den Inhalt des Popups. Wer ein nicht-modales Popover per Tab verlässt, schließt es. |
| Esc | Schließt das Popover und gibt den Fokus an den Trigger zurück. |
<PopoverTitle />und<PopoverDescription />beschriften und beschreiben das Popup für Screenreader. Füge einen Titel hinzu, sobald das Popup mehr als einen Satz enthält.- Der Fokus wandert beim Öffnen auf das erste fokussierbare Element und beim Schließen zurück zum Trigger. Ändere das mit
initialFocusundfinalFocus. - Bei aktivierter reduzierter Bewegung blendet das Popup ohne Skalierung ein.
Gebaut auf dem Base UI Popover. Jeder Teil akzeptiert die Props des Primitivs, das er umschließt.
| Prop | Typ | Standard |
|---|---|---|
defaultOpen | boolean | false |
open | boolean | – |
onOpenChangedetails.reason gibt an, was die Änderung ausgelöst hat. | (open: boolean, details) => void | – |
onOpenChangeCompleteWird aufgerufen, nachdem die Öffnen- oder Schließen-Animation endet. | (open: boolean) => void | – |
modaltrue sperrt Seitenscroll und Interaktion außerhalb. trap-focus fängt nur den Fokus. | boolean | "trap-focus" | false |
handleVerbindet losgelöste Trigger. | PopoverHandle<Payload> | – |
children | ReactNode | ({ payload }) => ReactNode | – |
| Prop | Typ | Standard |
|---|---|---|
openOnHover | boolean | false |
delayMillisekunden bis zum Öffnen bei Hover. | number | 300 |
closeDelayMillisekunden bis zum Schließen, nachdem der Hover endet. | number | 0 |
handle | PopoverHandle<Payload> | – |
payloadWird an das Popup übergeben, wenn dieser Trigger es öffnet. | Payload | – |
disabled | boolean | false |
render | ReactElement | (props, state) => ReactElement | <button> |
| Attribut | Beschreibung |
|---|---|
data-slot="popover-trigger" | Den Trigger in CSS ansprechen. |
data-popup-open | Vorhanden, solange sein Popover offen ist. |
data-pressed | Vorhanden, solange der Trigger gedrückt ist. |
data-disabled | Vorhanden, wenn der Trigger deaktiviert ist. |
Rendert Portal, Positioner und Popup in einem Teil.
| Prop | Typ | Standard |
|---|---|---|
side | "top" | "right" | "bottom" | "left" | "inline-start" | "inline-end" | "bottom" |
align | "start" | "center" | "end" | "center" |
sideOffsetAbstand zwischen Trigger und Popup. | number | (data) => number | 6 |
alignOffset | number | (data) => number | 0 |
collisionPaddingAbstand, der zu den Rändern des Viewports eingehalten wird. | number | Rect | 8 |
collisionAvoidanceOb umgeklappt, verschoben oder keins von beidem, wenn der Platz ausgeht. | CollisionAvoidance | – |
collisionBoundary | Boundary | – |
anchorAn etwas anderem als dem Trigger positionieren. | Element | RefObject | VirtualElement | () => Element | – |
sticky | boolean | false |
positionMethod | "absolute" | "fixed" | "absolute" |
initialFocusWohin der Fokus geht, wenn das Popover öffnet. | boolean | RefObject | (type) => HTMLElement | boolean | – |
finalFocusWohin der Fokus geht, wenn das Popover schließt. | boolean | RefObject | (type) => HTMLElement | boolean | – |
portalPropsProps für das Portal, etwa container. | PortalProps | – |
classNameDas Popup ist standardmäßig w-72. | string | (state) => string | – |
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribut | Beschreibung |
|---|---|
data-slot="popover-content" | Das Popup. |
data-slot="popover-positioner" | Das Element, das das Popup positioniert. |
data-open | Vorhanden, solange das Popover offen ist. |
data-starting-style | Vorhanden, solange das Popup einblendet. |
data-ending-style | Vorhanden, solange das Popup ausblendet. |
data-side | Die Seite, auf der das Popup am Ende gelandet ist. |
data-align | Die Ausrichtung, die das Popup am Ende erhalten hat. |
data-instant | Vorhanden, wenn die Änderung nicht animiert werden soll. |
--transform-origin | Der Punkt am Trigger, von dem aus das Popup skaliert. |
--available-width | Abstand zwischen Trigger und Viewport-Rand. |
--available-height | Abstand zwischen Trigger und Viewport-Rand. Die maximale Höhe des Popups. |
--anchor-width | Die Breite des Triggers. |
--anchor-height | Die Höhe des Triggers. |
Ein einfaches <div>, das Titel und Beschreibung stapelt.
| Attribut | Beschreibung |
|---|---|
data-slot="popover-header" | Den Header in CSS ansprechen. |
| Prop | Typ | Standard |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <h2> |
| Attribut | Beschreibung |
|---|---|
data-slot="popover-title" | Beschriftet das Popup. |
| Prop | Typ | Standard |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <p> |
| Attribut | Beschreibung |
|---|---|
data-slot="popover-description" | Beschreibt das Popup. |
| Prop | Typ | Standard |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <button> |
| Attribut | Beschreibung |
|---|---|
data-slot="popover-close" | Schließt das Popover beim Drücken. |
createPopoverHandle<Payload>() gibt ein Handle zurück, das einen <Popover /> mit an anderer Stelle gerenderten Triggern verbindet. Erstelle es einmal, außerhalb deiner Komponente.
- 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.
- Dropdown menuEin Menü mit Aktionen und Optionen hinter einem Button, mit Gruppen, Untermenüs, Checkbox- und Radio-Einträgen sowie Tastenkürzeln.
In Blocks verwendet
Blocks, die auf Popover 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.
- Agent TodosZeige den Plan eines Agenten, während er arbeitet. Jeder Schritt wandert von Backlog über To do und In Arbeit zu Erledigt, mit Live-Zeiten, Fehlern und den dahinterliegenden Tool-Aufrufen. Eine Status-Pille für über dem Composer, sichtbare Planänderungen und ein Review-Schritt, um den Plan vor der Ausführung zu bearbeiten.
- Diff ReviewPrüfe die Änderungen eines Agenten über mehrere Dateien, bevor sie übernommen werden. Ein Dateibaum mit Zählern, jede Änderung, jede Datei oder alles annehmen oder ablehnen, Kommentare zu jeder Zeile oder jedem Bereich, die an den Agenten zurückgehen, Unified- und Split-Ansicht, Hervorhebung auf Wortebene, Rückgängig, streamende Änderungen und eine Zusammenfassung „4 Dateien bearbeitet“ für den Chat.
- Voice ModeSprich mit deinem Assistenten. Acht audioreaktive Stile, von einem wolkigen Himmel und einem Ferrofluid-Blob über gedithertes Pixelwerk, ASCII, einen CRT-Planeten und Halbton-Punkte bis zu einem einzelnen Ring und einer weichen Aura, dazu vier reaktive Punkte. Eine Vollbild-Sitzung mit Stummschalten, Unterbrechen und Untertiteln, eine Voice-Pille im Chat, ein Stimmenwähler und eine Browser-Engine, die zuhört, wartet, bis du fertig bist, und antwortet.