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
pub type Size {
  Small
  Medium
  Large
}

Constructors

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

Constructors

  • Default
  • Muted

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