---
title: "Introduction to micromodal"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Introduction to micromodal}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

## Getting started

The goal of micromodal is to create simple and elegant modal dialogs which are 
[WAI-ARIA guidelines](https://www.w3.org/TR/wai-aria-practices-1.1/#dialog_modal) 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:

```r
`data-micromodal-trigger` = "modal-1"
```

2. 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:

```r
`data-micromodal-close` = NA
```
    
## Examples

See [live demo here](https://mwavu.shinyapps.io/micromodal/).

### Simple usage

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

```r
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

```r
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

```r
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.

```r
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)
```
