ui/modal
Modal component with focus trap support.
Usage with Focus Trap
import glizzy/ui/modal
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("modal-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:
fn view(model: Model) {
modal.modal([
attribute("id", "modal-container"),
], [
modal.underlay([]),
modal.content([
attribute("id", "modal-content"),
attribute("data-state", case model.is_open {
True -> "open"
False -> "closed"
}),
], [
// ... modal content
])
])
}
Types
Values
pub fn aria_describedby(id: String) -> attribute.Attribute(a)
pub fn aria_label(label: String) -> attribute.Attribute(a)
pub fn aria_labelledby(id: String) -> attribute.Attribute(a)
pub fn content(
attributes: List(attribute.Attribute(a)),
children: List(element.Element(a)),
) -> element.Element(a)
pub fn description(
attributes: List(attribute.Attribute(a)),
children: List(element.Element(a)),
) -> element.Element(a)
pub fn modal(
attributes: List(attribute.Attribute(a)),
children: List(element.Element(a)),
) -> element.Element(a)
pub fn size(s: Size) -> attribute.Attribute(a)
pub fn title(
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)