Basic Popover
A click-triggered panel anchored to its button, with Escape and outside-click dismiss.
6 frameworksIntermediate
A profile card in a dialog: gradient-initials avatar, name, role and a follow action.
<div class="relative inline-block">
<button type="button" aria-haspopup="dialog" aria-expanded="true" aria-controls="puser-panel" class="rounded-lg border border-gray-300 bg-white px-3.5 py-2 text-sm font-semibold text-gray-700 hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 dark:hover:bg-gray-800 dark:focus-visible:ring-blue-400 dark:focus-visible:ring-offset-gray-900">
Mara Lindqvist
</button>
<div id="puser-panel" role="dialog" aria-labelledby="puser-name" class="absolute left-0 top-[calc(100%+0.5rem)] z-20 w-72 max-w-[calc(100vw-2rem)] rounded-xl border border-gray-200 bg-white p-4 shadow-lg dark:border-gray-700 dark:bg-gray-900">
<div class="flex items-center gap-3">
<!-- Initials on a gradient - no external image needed. -->
<span aria-hidden="true" class="flex h-11 w-11 shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-blue-500 to-violet-500 text-sm font-semibold text-white">ML</span>
<div class="min-w-0">
<p id="puser-name" class="truncate text-sm font-semibold text-gray-900 dark:text-gray-100">Mara Lindqvist</p>
<p class="truncate text-xs text-gray-500 dark:text-gray-400">Staff Engineer - Platform</p>
</div>
</div>
<p class="mt-3 text-sm leading-relaxed text-gray-600 dark:text-gray-400">Works on the deployment pipeline and the CLI. Usually online 09:00-17:00 CET.</p>
<button type="button" class="mt-3 w-full rounded-md bg-blue-600 px-3 py-1.5 text-sm font-semibold text-white hover:bg-blue-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-blue-400 dark:focus-visible:ring-offset-gray-900">Follow</button>
</div>
</div>| Prop | Type | Default | Description |
|---|---|---|---|
namerequired | string | - | Plan name shown as the heading. |
rolerequired | string | - | Job title shown beneath the name. |
biorequired | string | - | Short biography paragraph. |
onFollow | () => void | - | On follow |
A `role="dialog"` labelled by the person's name, holding a Follow action - which is precisely why it is a dialog and not a tooltip. The avatar is initials on a gradient, so there is no external image to load or fail. Names and roles `truncate` inside a `min-w-0` column so a long value cannot force the panel wider than the viewport.