Pricing & Conversion

Popover

Built for conversion, not consent.

The obtrusive newsletter modal every AI startup deploys. Takes over the entire viewport with a blurred backdrop. By design, neither the Escape key nor backdrop clicks close it; the visitor either submits the form inside or clicks the tiny dismissal link at the bottom. Pair with `timer` to auto-open after the visitor has skimmed a few paragraphs.

Install

Copy this owned-code component into your app from the registry.

pnpm dlx shadcn-svelte@latest add https://benjamin-brady.github.io/performative-ui-svelte/registry/popover.json

Examples

Newsletter signup nag
const [open, setOpen] = useState(false);

return (
  <>
    <Button onClick={() => setOpen(true)}>Open the popover</Button>
    <Popover
      open={open}
      onOpenChange={setOpen}
      title="Subscribe to my newsletter"
      closeLabel="No thanks, I haven't raised my seed round yet."
    >
      <WaitlistForm
        ctaLabel="Subscribe"
        footnote="Weekly. Reasonably unhinged."
        onSubmit={(email) => {
          subscribe(email);
          setOpen(false); // submitting closes it
        }}
      />
    </Popover>
  </>
);
Auto-open after a timer (arm to demo)
<Popover
  timer={3000}
  title="You've been here 3 seconds"
  closeLabel="No thanks, I haven't raised my seed round yet."
>
  <WaitlistForm onSubmit={…} />
</Popover>

Props

PropTypeDefaultDescription
openboolean-Controlled open state.
defaultOpenboolean-Uncontrolled initial state.
onOpenChange(open: boolean) => void-Open-state callback.
timernumber0ms before auto-opening once mounted. 0 disables.
titleSnippet-Title at the top of the popover.
childrenSnippet-Body content (e.g. a WaitlistForm).
closeLabelSnippet | false"Maybe later"Small dismissal link rendered under the body. false to hide.
closeOnEscapebooleanfalseAllow the Escape key to close. Default false (obtrusive by design).
closeOnBackdropbooleanfalseAllow backdrop clicks to close. Default false.
containerHTMLElement | null-Portal target. Defaults to document.body so the popover covers the viewport.