Popover
Overlay ancorado, dirigido por clique, para conteúdo contextual interativo. Construído sobre o Radix Popover.
Visão geral
Popover é o primitivo certo para conteúdo ancorado que responde a um clique intencional: date pickers, color pickers, mini formulários, menus de compartilhamento, ações inline de compartilhar/curtir. É distinto do Tooltip (apenas hover, apenas texto, nunca interativo) e do HoverCard (previews apenas em hover de conteúdo não crítico). Quando o conteúdo é muito longo ou justifica bloquear a página, escale para Dialog ou Sheet.
A superfície padrão é w-72, com padding p-4, com um transform-origin dirigido pelo Radix para que a animação de abertura pareça ancorada ao trigger.
Preview
'use client';import { Button } from '@gremorie/rx-forms';import { Popover, PopoverContent, PopoverTrigger } from '@gremorie/rx-overlays';export function PopoverPreview() { return ( <Popover> <PopoverTrigger asChild> <Button variant="outline">Open popover</Button> </PopoverTrigger> <PopoverContent> <div className="flex flex-col gap-2"> <h4 className="text-sm font-medium">Quick settings</h4> <p className="text-xs text-muted-foreground"> Toggle preferences for this session. </p> </div> </PopoverContent> </Popover> );}Anatomia
Popover raiz Radix que mantém o estado de abertura
├─ PopoverTrigger abre o popover no clique
├─ PopoverAnchor âncora alternativa de posicionamento
└─ PopoverContent superfície em portal (align, sideOffset)
└─ PopoverHeader envolve título + descrição
├─ PopoverTitle heading
└─ PopoverDescription texto de apoioInstalação
bash npx gremorie@latest add rx-popover bash pnpm dlx gremorie@latest add rx-popover bash yarn dlx gremorie@latest add rx-popover bash bunx --bun gremorie@latest add rx-popover Uso
import { Button } from "@gremorie/rx-forms";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@gremorie/rx-overlays";
export function Example() {
return (
<Popover>
<PopoverTrigger asChild>
<Button variant="outline">Open</Button>
</PopoverTrigger>
<PopoverContent>
<p className="text-sm">Anchored interactive content.</p>
</PopoverContent>
</Popover>
);
}A edição Angular deste componente hoje é distribuída a partir do source (veja o workbench para o lado a lado); a entrada no registry vem a seguir.
API
<Popover>
Estende o Radix Popover.Root. Props notáveis:
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | - | Estado de abertura controlado. |
defaultOpen | boolean | false | Estado de abertura inicial quando não controlado. |
onOpenChange | (open: boolean) => void | - | Disparado quando o estado de abertura muda. |
modal | boolean | false | Quando true, trava o scroll do body e a interação externa. |
<PopoverTrigger>
Estende o Radix Popover.Trigger. Emparelhe com asChild para encaminhar estilos a um Button ou qualquer trigger customizado.
<PopoverContent>
| Prop | Type | Default | Description |
|---|---|---|---|
align | "start" | "center" | "end" | "center" | Alinhamento relativo ao eixo do trigger. |
sideOffset | number | 4 | Espaçamento em pixels entre trigger e content. |
side | "top" | "right" | "bottom" | "left" | "bottom" | Lado preferido; vira automaticamente quando não há espaço. |
alignOffset | number | 0 | Offset ao longo do eixo de alinhamento. |
avoidCollisions | boolean | true | Reposiciona automaticamente para permanecer na viewport. |
collisionPadding | number | object | 0 | Distância das bordas da viewport a manter. |
Envolvido em um Portal do Radix. Todas as demais props do Radix Popover.Content são encaminhadas.
<PopoverAnchor>
Opcional. Ancora o content a um elemento diferente do trigger. Útil quando a âncora visual e o alvo do clique não são o mesmo elemento.
<Popover>
<PopoverAnchor asChild>
<span>Visual anchor</span>
</PopoverAnchor>
<PopoverTrigger asChild>
<Button>Click me</Button>
</PopoverTrigger>
<PopoverContent>Anchored to the span, not the button.</PopoverContent>
</Popover><PopoverHeader>, <PopoverTitle>, <PopoverDescription>
Helpers de layout opcionais. O header empilha título e descrição; o título é font-medium; a descrição é text-muted-foreground.
Composição
<Popover>detém o estado de aberto/fechado.<PopoverTrigger asChild>envolve o elemento focável que o abre.<PopoverContent>monta via Portal, ancorado ao trigger (ou aoPopoverAnchor).- Dentro do content: qualquer UI interativa - formulários, listas de comandos, color pickers, sliders.
- Dispensa: clique fora, pressione
Escou feche programaticamente.
Variações
Popover de formulário
Um mini formulário ancorado ao trigger. O popover permanece aberto enquanto o usuário edita os inputs.
'use client';import { Button, Input, Label } from '@gremorie/rx-forms';import { Popover, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger,} from '@gremorie/rx-overlays';export function PopoverFormPreview() { return ( <Popover> <PopoverTrigger asChild> <Button variant="outline">Set dimensions</Button> </PopoverTrigger> <PopoverContent className="w-80"> <PopoverHeader> <PopoverTitle>Dimensions</PopoverTitle> <PopoverDescription> Set the width and height for the layer. </PopoverDescription> </PopoverHeader> <div className="mt-3 grid gap-3"> <div className="grid grid-cols-3 items-center gap-3"> <Label htmlFor="width">Width</Label> <Input id="width" defaultValue="320" className="col-span-2 h-8" /> </div> <div className="grid grid-cols-3 items-center gap-3"> <Label htmlFor="height">Height</Label> <Input id="height" defaultValue="240" className="col-span-2 h-8" /> </div> <Button size="sm" className="mt-1 justify-self-end"> Apply </Button> </div> </PopoverContent> </Popover> );}Popover de configurações
Mini formulário com header. Permanece aberto enquanto o usuário alterna preferências.
<Popover>
<PopoverTrigger asChild>
<Button variant="outline">Quick settings</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverHeader>
<PopoverTitle>Quick settings</PopoverTitle>
<PopoverDescription>
Tweak preferences for this session.
</PopoverDescription>
</PopoverHeader>
<div className="mt-3 flex flex-col gap-3">
<Field>
<FieldLabel htmlFor="theme">Theme</FieldLabel>
<Select id="theme" defaultValue="system">
<option value="light">Light</option>
<option value="dark">Dark</option>
<option value="system">System</option>
</Select>
</Field>
</div>
</PopoverContent>
</Popover>Alinhado ao fim do trigger
Alinhe o popover à direita sob um ícone de toolbar para que ele não estoure a viewport.
<Popover>
<PopoverTrigger asChild>
<Button variant="ghost" size="icon" aria-label="More">
<MoreHorizontalIcon />
</Button>
</PopoverTrigger>
<PopoverContent align="end" sideOffset={8}>
{/* menu content */}
</PopoverContent>
</Popover>Com âncora customizada
Use PopoverAnchor para desacoplar a âncora visual do alvo do clique (comum em UIs dirigidas por seleção, onde um trecho destacado abre o popover).
<Popover open={open} onOpenChange={setOpen}>
<PopoverAnchor virtualRef={selectionRef} />
<PopoverContent>Formatting toolbar</PopoverContent>
</Popover>Acessibilidade
- Role:
role="dialog"para o content (padrão do Radix). - Teclado:
Escfecha;Tabcircula o foco dentro do content; clicar fora fecha (configurável). - Gestão de foco: o foco entra no content na abertura e retorna ao trigger ao fechar.
- Clique fora: fecha por padrão. Desative via
onInteractOutsidese o popover precisar persistir. aria-expanded: definido no trigger automaticamente;aria-controlsliga ao id do content.- Reduced motion: as animações de abrir/fechar respeitam
prefers-reduced-motion.
Relacionados
- Tooltip - rótulo de texto apenas em hover, não interativo.
- Hover Card - preview rico apenas em hover, não interativo.
- Dropdown Menu - popover com semântica de menu e navegação por setas.
- Dialog - modal bloqueante quando o conteúdo é grande ou crítico demais.