Popover
围绕原生Popover API提供触发器、弹出层和关闭部分。
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".
| Name | Type | Default | Notes |
|---|---|---|---|
target | string | Required. `id` of the `Popover.Surface` this button acts on. | |
action | "toggle" | "show" | "hide" | "toggle" | What this trigger does to its target popover when activated. |
as | NativeButtonAs<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".
| Name | Type | Default | Notes |
|---|---|---|---|
id | string | Required. 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".
| Name | Type | Default | Notes |
|---|---|---|---|
target | string | Required. `id` of the `Popover.Surface` this button hides. | |
as | NativeButtonAs<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";