Ir al contenido

Popover

Partes de activador, superficie y cierre para la Popover API nativa.

0 kB client JS≤ 0.5 kB gzipped

Anatomy

<Popover.Trigger target="actions">Actions</Popover.Trigger>
<Popover.Surface id="actions">
  <Popover.Close target="actions">Close</Popover.Close>
</Popover.Surface>

Live demo

This demo also runs with JavaScript disabled.

Popover

Minimal

Composition — explicit show/hide

Anchored below the trigger, aligned to its start edge.

Popover.Trigger

Renders <button> (via `createElement`). Emits popoverTarget, popoverTargetAction, type="button", data-uiify-popover="", data-part="trigger".

NameTypeDefaultNotes
targetstringRequired. `id` of the `Popover.Surface` this button acts on.
action"toggle" | "show" | "hide""toggle"What this trigger does to its target popover when activated.
asNativeButtonAs<TAs>"button"See Invoker.

Popover.Surface

Renders <div popover>. Emits popover={mode}, data-side, data-align, data-positioning="native", data-uiify-popover="", data-part="surface".

NameTypeDefaultNotes
idstringRequired. Referenced by trigger and close `target`.
mode"auto" | "manual""auto"The cross-engine popover baseline; `hint` is not part of this contract.
side"top" | "right" | "bottom" | "left"Anchor side.
align"start" | "center" | "end"Anchor alignment.

Popover.Close

Renders <button> (via `createElement`). Emits popoverTargetAction="hide", data-uiify-popover="", data-part="close".

NameTypeDefaultNotes
targetstringRequired. `id` of the `Popover.Surface` this button hides.
asNativeButtonAs<TAs>"button"See Invoker.

Rendered DOM

<button data-uiify-popover="" data-part="trigger" popoverTarget="actions" popoverTargetAction="toggle" type="button">Actions</button><div id="actions" data-align="center" data-part="surface" data-positioning="native" data-side="bottom" data-uiify-popover="" popover="auto"><button data-uiify-popover="" data-part="close" popoverTarget="actions" popoverTargetAction="hide" type="button">Close</button></div>

CSS contract

[popover]:popover-open {
  /* true while the surface is shown */
}

/* the element sets data-side/data-align from side/align — style off these, not JS */

Build your own

import { Popover } from "@gunkin/uiify/elements/popover";

export function ActionMenu() {
  return (
    <>
      <Popover.Trigger target="row-actions">Actions</Popover.Trigger>
      <Popover.Surface aria-label="Row actions" id="row-actions">
        <button type="button">Rename</button>
        <button type="button">Duplicate</button>
        <button type="button">Delete</button>
      </Popover.Surface>
    </>
  );
}

Used by

Gotchas

  • `id` must be stable across server and client renders — `Popover.Trigger`/`Popover.Close`'s `target` has to match it exactly.
  • `Popover.Surface` has no implicit ARIA role, so — unlike `Dialog.Content` — it has no required accessible name.
  • `renderToStaticMarkup` keeps `popoverTarget`/`popoverTargetAction` camelCase in the raw HTML string (React doesn't special-case them for static rendering the way it does `command`/`commandfor`) — real browser behavior and hydration are unaffected, but don't be surprised reading the SSR output.

Import

import { Popover } from "@gunkin/uiify/elements/popover";