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

pub type Size {
  Small
  Medium
  Large
}

Constructors

  • Small
  • Medium
  • Large
pub type Variant {
  Default
  Muted
}

Constructors

  • Default
  • Muted

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)
Search Document