---
title: "How to: use shiny.fluent with Shiny modules"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{How to: use shiny.fluent with Shiny modules}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

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

Shiny.fluent components work in [Shiny modules](https://shiny.rstudio.com/articles/modules.html)
out of the box.
In this example, a calculator module defined by `calcUI()` and `calcServer()`
allows the user to choose a mathematical operation and input two numeric values.
The server function returns a reactive value with the result.

A few things to note:

* The `ns()` function is used to wrap the IDs of the inputs in the module UI,
  but not when accessing them via `input$` in the module server.
* The `calcUI()` and `calcServer()` are called with the same ID
  in the UI and server parts of the Shiny app.

```r
library(shiny)
library(shiny.fluent)

calcModes <- list(
  list(key = "add", text = "Addition"),
  list(key = "mul", text = "Multiplication")
)

calcUI <- function(id) {
  ns <- NS(id)
  div(style = "margin: 15px 0px 15px",
    ChoiceGroup(ns("mode"), label = "Operation", value = "add", options = calcModes),
    Label("Values"),
    flowLayout(
      SpinButton(ns("a"), label = "A = ", value = 3),
      SpinButton(ns("b"), label = "B = ", value = 5)
    )
  )
}

calcServer <- function(id) {
  moduleServer(id, function(input, output, session) {
    result <- reactive({
      switch(req(input$mode),
        add = input$a + input$b,
        mul = input$a * input$b
      )
    })
    return(result)
  })
}

shinyApp(
  ui = fluidPage(
    calcUI("calc"),
    textOutput("result")
  ),
  server = function(input, output) {
    result <- calcServer("calc")
    output$result <- renderText(
      paste("The module returned", result())
    )
  }
)
```

![](images/calc_module.png)
