ui/popover
Popover component with focus trap support.
Popovers can be modal (focus trapped) or non-modal using non_modal().
Usage with Focus Trap (Modal Popover)
import glizzy/ui/popover
import glizzy/ui/focus
import lustre/effect.{type Effect, batch}
type Model {
Model(is_open: Bool, focus_scope_id: String)
}
type Msg {
Open
Close
FocusScopeCreated(String)
}
// In init:
fn init() -> #(Model, Effect(Msg)) {
#(
Model(is_open: False, focus_scope_id: ""),
focus.create_scope("popover-content", FocusScopeCreated),
)
}
// In update:
fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) {
case msg {
Open -> #(
Model(..model, is_open: True),
batch([
focus.trap_focus(model.focus_scope_id, True),
focus.focus_first(model.focus_scope_id),
])
)
Close -> #(
Model(..model, is_open: False),
focus.trap_focus(model.focus_scope_id, False)
)
FocusScopeCreated(scope_id) -> #(
Model(..model, focus_scope_id: scope_id),
effect.none()
)
}
}
// In view (modal popover):
fn view(model: Model) {
popover.popover([], [
popover.underlay([]),
popover.content([
attribute("id", "popover-content"),
attribute("data-state", case model.is_open {
True -> "open"
False -> "closed"
}),
], [
// ... popover content
])
])
}
// In view (non-modal popover - no focus trap):
fn view(model: Model) {
popover.popover([
popover.non_modal(),
], [
popover.content([], [
// ... popover content (no focus trap)
])
])
}
Types
pub type Placement {
Top
Bottom
Left
Right
Start
End
}
Constructors
-
Top -
Bottom -
Left -
Right -
Start -
End
Values
pub fn arrow(
attributes: List(attribute.Attribute(a)),
) -> element.Element(a)
pub fn content(
attributes: List(attribute.Attribute(a)),
children: List(element.Element(a)),
) -> element.Element(a)
pub fn controls(id: String) -> attribute.Attribute(a)
pub fn expanded(expanded: Bool) -> attribute.Attribute(a)
pub fn non_modal() -> attribute.Attribute(a)
pub fn placement(p: Placement) -> attribute.Attribute(a)
pub fn popover(
attributes: List(attribute.Attribute(a)),
children: List(element.Element(a)),
) -> element.Element(a)
pub fn size(s: Size) -> attribute.Attribute(a)
pub fn trigger(
attributes: List(attribute.Attribute(a)),
children: List(element.Element(a)),
) -> element.Element(a)
pub fn underlay(
attributes: List(attribute.Attribute(a)),
) -> element.Element(a)
pub fn variant(v: Variant) -> attribute.Attribute(a)