-
Notifications
You must be signed in to change notification settings - Fork 9
Component Popover
MeowLynxSea edited this page Jan 24, 2026
·
6 revisions
Popover is a click-triggered floating container for menus or small panels, anchored under the trigger element.
Implementation model:
- The
Popoveritself is a.relative()container. - The menu/panel is an
.absolute()child, drawn on top with higher priority viagpui::deferred(...).
- Avatar menus, "more actions" menus
- Lightweight settings panels (for example: sort / view / filter)
- Hosting
DropdownMenu(DropdownMenuis built on top ofPopover)
Not a good fit:
- Cases that require full-screen overlay, focus trapping, Esc-to-dismiss, and other "dialog" behaviors (these typically belong in the app/widget layer).
-
popover(): constructor (by default uses caller location to generate an id) -
id(...) / key(...): stable identity (usekey(...)in lists/repeated rendering) -
open(bool): controlled by the caller -
placement(PopoverPlacement):-
BottomStart: align to trigger's bottom-left -
BottomEnd: align to trigger's bottom-right
-
-
width(px(...)): fixed width (otherwise sizes to content) -
bg(...) / border(...): override default theme colors -
trigger(...): trigger element (button/icon/any element) -
content(...): popover content -
on_close(|window, cx| ...): triggered when clicking outside (typically used to setopen = false)
open(false)- Placement:
BottomStart - Background:
theme.surface.raised - Border:
theme.border.default
- Popover does not implement open/toggle logic: how clicking the trigger changes
openis entirely up to the caller. - Clicking outside triggers
on_close(if you don't provideon_close, Popover will not auto-close). - Closing typically requires
window.refresh()(becauseuse_keyed_stateupdates need a frame refresh).
use gpui::{ElementId, px};
use yororen_ui::component::{button, label, popover, PopoverPlacement};
// In a view render:
let open = window.use_keyed_state(("demo", "popover-open"), cx, |_, _| false);
let is_open = *open.read(cx);
let view = popover()
.id(ElementId::from(("demo", "popover")))
.open(is_open)
.placement(PopoverPlacement::BottomStart)
.width(px(260.))
.on_close({
let open = open.clone();
move |window, cx| {
open.update(cx, |v, _| *v = false);
window.refresh();
}
})
.trigger(
button().child("Open").on_click({
let open = open.clone();
move |_ev, window, cx| {
open.update(cx, |v, _| *v = !*v);
window.refresh();
}
}),
)
.content(label("Popover content"));use yororen_ui::component::{button, popover, PopoverPlacement};
let view = popover()
.open(true)
.placement(PopoverPlacement::BottomEnd)
.trigger(button().child("..."))
.content("Right aligned popover");Yororen UI v0.3.0 · repository · Apache-2.0 · This wiki documents Yororen UI v0.3.0.
This wiki documents Yororen UI v0.3.0 — the headless-core, swappable-renderer build.