The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Introduction to micromodal

Getting started

The goal of micromodal is to create simple and elegant modal dialogs which are WAI-ARIA guidelines compliant with minimal configuration.

Things to keep in mind:

  1. The modal’s trigger (usually a button or a link) must have the attribute data-micromodal-trigger with a value of the modal’s id. So if the modal has the id “modal-1”, then you will have:
`data-micromodal-trigger` = "modal-1"
  1. If you need to add something to dismiss the modal (eg. button or link), give it the attribute data-micromodal-close. In {shiny} this is the equivalent of:
`data-micromodal-close` = NA

Examples

See live demo here.

Simple usage

Though a bit long, this example clearly depicts all there is to know about using {micromodal}.

library(shiny)
library(micromodal)

server <- \(input, output, session) {
  
}

ui <- bslib::page(
  title = "Micromodal",
  theme = bslib::bs_theme(version = 5),
  # inform shiny to use {micromodal}:
  use_micromodal(),
  # your normal UI code:
  tags$div(
    class = "container",
    tags$div(
      class = "container my-5",
      tags$h1("Micromodal.js in Shiny", class = "mb-5"),
      # trigger for "modal-1"
      actionButton(
        inputId = "show_modal_1",
        label = "Exhibit 1",
        class = "btn-outline-primary px-3",
        `data-micromodal-trigger` = "modal-1"
      ),
      # trigger for "modal-2"
      actionButton(
        inputId = "show_modal_2",
        label = "Exhibit 2",
        class = "btn-outline-primary px-3",
        `data-micromodal-trigger` = "modal-2"
      )
    ),
    # modal-1:
    micromodal(
      id = "modal-1",
      title = "Login",
      content = tagList(
        textInput(
          inputId = "name",
          label = "Name",
          width = "400px"
        ),
        passwordInput(
          inputId = "password",
          label = tags$div(
            tags$span("Password"),
            tags$span("(required)", class = "text-muted fw-light")
          ),
          width = "400px"
        ) |> tagAppendAttributes(class = "mb-0"),
        tags$div(
          "Must be atleast 6 characters long.",
          class = "text-muted fw-light"
        )
      ),
      footer = tagList(
        tags$button(
          class = "modal__btn modal__btn-primary",
          "Continue"
        ),
        tags$a(
          href = "#",
          class = "ms-3",
          `data-micromodal-close` = NA,
          `aria-label` = "Close this dialog window",
          "Cancel"
        )
      )
    ),
    # modal-2:
    micromodal(
      id = "modal-2",
      title = "Micromodal",
      content = tagList(
        tags$p("This is a completely accessible modal."),
        tags$p(
          "Try hitting the",
          tags$code("tab"),
          "key* and notice how the focus stays",
          "within the modal itself. To close modal hit the",
          tags$code("esc"),
          "button, click on the overlay or just click the close button."
        ),
        tags$p("*", tags$code("alt + tab"), "in safari")
      ),
      footer = tagList(
        tags$button(
          class = "modal__btn modal__btn-primary",
          "Continue"
        ),
        tags$button(
          class = "modal__btn ms-2",
          `data-micromodal-close` = NA,
          `aria-label` = "Close this dialog window",
          "Close"
        )
      )
    )
  )
)

shinyApp(ui, server)

With uiOutput + renderUI

If need be, you can render the modal and it’s trigger dynamically.

I. Render modal

library(shiny)
library(micromodal)

ui <- fluidPage(
  use_micromodal(),
  selectInput(
    inputId = "selector",
    label = "Pick a letter",
    choices = letters
  ),
  actionButton(
    inputId = "trigger",
    label = "Trigger modal",
    `data-micromodal-trigger` = "modal-1"
  ),
  uiOutput(outputId = "mymodal")
)

server <- \(input, output, session) {
  output$mymodal <- renderUI({
    tagList(
      micromodal(
        id = "modal-1",
        title = "Rendered serverside",
        content = tagList(
          tags$p(
            "You selected the letter '",
            input$selector,
            "'"
          )
        )
      )
    )
  })
}

shinyApp(ui, server)

II. Render modal + trigger

library(shiny)
library(micromodal)

ui <- fluidPage(
  use_micromodal(),
  selectInput(
    inputId = "selector",
    label = "Pick a letter",
    choices = letters
  ),
  uiOutput(outputId = "mymodal")
)

server <- \(input, output, session) {
  output$mymodal <- renderUI({
    tagList(
      actionButton(
        inputId = "trigger",
        label = "Trigger modal",
        `data-micromodal-trigger` = "modal-1"
      ),
      micromodal(
        id = "modal-1",
        title = "Rendered serverside",
        content = tagList(
          tags$p(
            "You selected the letter '",
            input$selector,
            "'"
          )
        )
      )
    )
  })
}

shinyApp(ui, server)

NB: micromodal might not work with other *Output + render* eg. plotOutput()

Inside modules

As far as usage of {micromodal} in modules is concerned, I only need to remind you of one thing:

It’s always a missing call to NS()

Thank me later.

library(shiny)
library(micromodal)

# module UI:
sayhi_ui <- \(id) {
  ns <- NS(id)
  tagList(
    tags$h1("Hello"),
    actionLink(
      inputId = ns("sayhi"),
      label = "Say Hi",
      `data-micromodal-trigger` = ns("greetings_modal")
    ),
    micromodal(
      id = ns("greetings_modal"),
      title = "Greetings folks!",
      content = tags$p(
        "I'd like to thank you for joining us here today."
      )
    )
  )
}

# module server is not necessary in our case, just putting it here 
# for formality:
sayhi_server <- \(id) {
  moduleServer(
    id = id,
    module = \(input, output, session) {
      
    }
  )
}

ui <- bslib::page(
  title = "In Modules",
  theme = bslib::bs_theme(version = 5),
  use_micromodal(),
  tags$div(
    class = "container",
    sayhi_ui("hi")
  )
)

server <- \(input, output, session) {}

shinyApp(ui, server)

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.