Search code examples
rshinyshinymodulesbslib

Adding a bslib::nav_panel in Shiny modules


I am trying to add a bslib::nav_panel as part of a Shiny module, but I am struggling to make this happen. See a minimal reproducible example below:

library(shiny); library(bslib); library(shinyWidgets)

login_ui <- function(id) {
  ns <- NS(id)
  tagList(
         actionBttn(inputId = ns("add_tab"), label = "Add", style = "pill", color = "danger")
  )
}
login_server <- function(id) {
  moduleServer(
    id,
    function(input, output, session) {
      ns = session$ns
      observeEvent(input$add_tab, {
      nav_insert(id="nav_tab", nav=nav_panel("This is a new tab"))
      })
    })
}

#load libraries
ui <- page_fluid(
  navset_tab(id = "nav_tab", nav_panel("Add a new tab", login_ui("add_test"))))

server <- function(input, output) {
  login_server("add_test")
}

shinyApp(ui = ui, server = server)

Any advice would be appreciated.


Solution

  • The issue is that nav_insert will (try to) insert a nav panel in a navset_tab with id="nav_tab" in the module's namespace:

    enter image description here

    Instead, to insert the panel in the navset_tab created in your main app you could pass main app's session object to your module which could then be passed to the session= argument of nav_insert:

    library(shiny)
    library(bslib)
    library(shinyWidgets)
    
    login_ui <- function(id) {
      ns <- NS(id)
      tagList(
        actionBttn(
          inputId = ns("add_tab"),
          label = "Add",
          style = "pill",
          color = "danger"
        )
      )
    }
    
    login_server <- function(id, parent_session) {
      moduleServer(
        id,
        function(input, output, session) {
          observeEvent(input$add_tab, {
            nav_insert(
              id = "nav_tab",
              nav = nav_panel("This is a new tab"),
              session = parent_session
            )
          })
        }
      )
    }
    
    # load libraries
    ui <- page_fluid(
      navset_tab(
        id = "nav_tab",
        nav_panel(
          "Add a new tab",
          login_ui("add_test")
        )
      )
    )
    
    server <- function(input, output, session) {
      login_server("add_test", session)
    }
    
    shinyApp(ui = ui, server = server)
    

    enter image description here