rstudio / bslib

Tools for theming Shiny and R Markdown via Bootstrap 3, 4, or 5.
https://rstudio.github.io/bslib/
Other
463 stars 56 forks source link

Nested navset in nav_item() prevents accessing from server via id argument #657

Open chrisbrownlie opened 1 year ago

chrisbrownlie commented 1 year ago

Describe the problem

When nesting a navset_ element inside a nav_item within another nav container, the selected tab of the outer nav container doesn't seem to be accessible from the server using the id argument.

For the reprexes below, I would expect the value of input$main_nav that is printed to the console to reflect the selected tab, but it seems to be NULL and doesn't register any changes. The inner, nested nav is still accessible from the server with input$inner_nav however.

Removing the nav_item that it is wrapped in seems to make it work again, but gives a warning

Navigation containers expect a collection of `bslib::nav_panel()`/`shiny::tabPanel()`s
and/or `bslib::nav_menu()`/`shiny::navbarMenu()`s. Consider using `header` or `footer`
if you wish to place content above (or below) every panel's contents.

and usually ends up being formatted differently.

Is there an alternative way to achieve what I'm looking for?

library(shiny)
library(bslib)

ui <- function() {
  page_navbar(
    id = "main_nav",
    nav_panel("first"),
    nav_panel("second"),
    # Nested navset
    nav_item(
      navset_pill(
        id = "inner_nav",
        nav_panel("in_first"),
        nav_panel("in_second")
      )
    )
  )
}

server <- function(input, output) {
  observe(print(paste("main:", input$main_nav)))
  observe(print(paste("inner:", input$inner_nav)))
}

shinyApp(ui, server)

Created on 2023-07-05 with reprex v2.0.2

the same behaviour with different navset/page elements:

library(shiny)
library(bslib)

ui <- function() {
  page(
    navset_pill(
      id = "main_nav",
      nav_panel("first"),
      nav_panel("second"),
      nav_item(
        navset_pill(
          id = "inner_nav",
          nav_panel("in_first"),
          nav_panel("in_second")
        )
      )
    )
  )
}

server <- function(input, output) {
  observe(print(paste("main:", input$main_nav)))
  observe(print(paste("inner:", input$inner_nav)))
}

shinyApp(ui, server)

Created on 2023-07-05 with reprex v2.0.2

Session Info


─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.2.3 (2023-03-15 ucrt)
 os       Windows 10 x64 (build 19044)
 system   x86_64, mingw32
 ui       RStudio
 language (EN)
 collate  English_United Kingdom.utf8
 ctype    English_United Kingdom.utf8
 tz       Europe/London
 date     2023-07-05
 rstudio  2023.06.0+421 Mountain Hydrangea (desktop)
 pandoc   3.1.1 @ C:/Program Files/RStudio/resources/app/bin/quarto/bin/tools/ (via rmarkdown)

─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 ! package          * version    date (UTC) lib source
   assertthat         0.2.1      2019-03-21 [1] CRAN (R 4.2.3)
   AzureAppInsights   0.3.1      2023-06-13 [1] CRAN (R 4.2.3)
 P bit                4.0.5      2022-11-15 [?] CRAN (R 4.2.2)
 P bit64              4.0.5      2020-08-30 [?] CRAN (R 4.2.1)
 P blob               1.2.4      2023-03-17 [?] CRAN (R 4.2.3)
 P brio               1.1.3      2021-11-30 [?] CRAN (R 4.2.1)
 P bsicons            0.1        2022-11-22 [?] CRAN (R 4.2.2)
 P bslib              0.5.0      2023-06-09 [?] CRAN (R 4.2.3)
   bwlogs             1.1.1      2023-07-05 [1] xgit (https://dev.azure.com/BarnettWaddingham/MDA/_git/bwlogs@1873d11)
 P BWStyles           1.2.2      2023-02-23 [?] xgit (https://dev.azure.com/BarnettWaddingham/MDA/_git/BWStyles@)
 P BWux               0.1.1      2023-05-23 [?] xgit (https://dev.azure.com/BarnettWaddingham/MDA/_git/BWux@0c9c6e4)
 P cachem             1.0.8      2023-05-01 [?] CRAN (R 4.2.3)
 P callr              3.7.3      2022-11-02 [?] CRAN (R 4.2.2)
 P cli                3.6.1      2023-03-23 [?] CRAN (R 4.2.3)
 P clipr              0.8.0      2022-02-22 [?] CRAN (R 4.2.1)
 P colorspace         2.1-0      2023-01-23 [?] CRAN (R 4.2.2)
 P config             0.3.1      2020-12-17 [?] CRAN (R 4.2.1)
 P crayon             1.5.2      2022-09-29 [?] CRAN (R 4.2.1)
 P crosstalk          1.2.0      2021-11-04 [?] CRAN (R 4.2.1)
 P data.table         1.14.8     2023-02-17 [?] CRAN (R 4.2.2)
 P DBI                1.1.3      2022-06-18 [?] CRAN (R 4.2.2)
   dbplyr             2.3.2      2023-03-21 [1] CRAN (R 4.2.3)
 P desc               1.4.2      2022-09-08 [?] CRAN (R 4.2.1)
 P devtools           2.4.5      2022-10-11 [?] CRAN (R 4.2.1)
   digest             0.6.32     2023-06-26 [1] CRAN (R 4.2.3)
 R DN4SApp          * 2.3.0.9000        [?] 
 P dplyr              1.1.2      2023-04-20 [?] CRAN (R 4.2.3)
 P ellipsis           0.3.2      2021-04-29 [?] CRAN (R 4.2.1)
 P evaluate           0.21       2023-05-05 [?] CRAN (R 4.2.3)
 P fansi              1.0.4      2023-01-22 [?] CRAN (R 4.2.2)
 P fastmap            1.1.1      2023-02-24 [?] CRAN (R 4.2.2)
 P fontawesome        0.5.1      2023-04-18 [?] CRAN (R 4.2.3)
 P forcats            1.0.0      2023-01-29 [?] CRAN (R 4.2.2)
 P fs                 1.6.2      2023-04-25 [?] CRAN (R 4.2.3)
 P generics           0.1.3      2022-07-05 [?] CRAN (R 4.2.1)
 P ggplot2            3.4.2      2023-04-03 [?] CRAN (R 4.2.3)
 P glue               1.6.2      2022-02-24 [?] CRAN (R 4.2.1)
 P gtable             0.3.3      2023-03-21 [?] CRAN (R 4.2.2)
 P hms                1.1.3      2023-03-21 [?] CRAN (R 4.2.2)
 P htmltools          0.5.5      2023-03-23 [?] CRAN (R 4.2.3)
 P htmlwidgets        1.6.2      2023-03-17 [?] CRAN (R 4.2.3)
 P httpuv             1.6.11     2023-05-11 [?] CRAN (R 4.2.3)
 P httr               1.4.6      2023-05-08 [?] CRAN (R 4.2.3)
 P jquerylib          0.1.4      2021-04-26 [?] CRAN (R 4.2.1)
   jsonlite           1.8.7      2023-06-29 [1] CRAN (R 4.2.3)
   knitr              1.43       2023-05-25 [1] CRAN (R 4.2.3)
 P later              1.3.1      2023-05-02 [?] CRAN (R 4.2.3)
 P lazyeval           0.2.2      2019-03-15 [?] CRAN (R 4.2.1)
 P lifecycle          1.0.3      2022-10-07 [?] CRAN (R 4.2.1)
   logger             0.2.2      2021-10-19 [1] CRAN (R 4.2.3)
 P lubridate          1.9.2      2023-02-10 [?] CRAN (R 4.2.2)
 P magrittr           2.0.3      2022-03-30 [?] CRAN (R 4.2.1)
 P memoise            2.0.1      2021-11-26 [?] CRAN (R 4.2.1)
 P mime               0.12       2021-09-28 [?] CRAN (R 4.2.0)
 P miniUI             0.1.1.1    2018-05-18 [?] CRAN (R 4.2.1)
 P munsell            0.5.0      2018-06-12 [?] CRAN (R 4.2.1)
 P odbc               1.3.4      2023-01-17 [?] CRAN (R 4.2.3)
 P pillar             1.9.0      2023-03-22 [?] CRAN (R 4.2.2)
 P pkgbuild           1.4.0      2022-11-27 [?] CRAN (R 4.2.2)
 P pkgconfig          2.0.3      2019-09-22 [?] CRAN (R 4.2.1)
 P pkgload            1.3.2      2022-11-16 [?] CRAN (R 4.2.2)
 P plotly             4.10.1     2022-11-07 [?] CRAN (R 4.2.2)
 P prettyunits        1.1.1      2020-01-24 [?] CRAN (R 4.2.1)
 P processx           3.8.1      2023-04-18 [?] CRAN (R 4.2.3)
 P profvis            0.3.8      2023-05-02 [?] CRAN (R 4.2.3)
 P promises           1.2.0.1    2021-02-11 [?] CRAN (R 4.2.1)
 P ps                 1.7.5      2023-04-18 [?] CRAN (R 4.2.3)
 P purrr              1.0.1      2023-01-10 [?] CRAN (R 4.2.2)
 P R6                 2.5.1      2021-08-19 [?] CRAN (R 4.2.1)
 P Rcpp               1.0.10     2023-01-22 [?] CRAN (R 4.2.2)
 P reactable          0.4.4      2023-03-12 [?] CRAN (R 4.2.2)
 P reactR             0.4.4      2021-02-22 [?] CRAN (R 4.2.2)
 P readr              2.1.4      2023-02-10 [?] CRAN (R 4.2.2)
 P remotes            2.4.2      2021-11-30 [?] CRAN (R 4.2.1)
 P renv               0.17.3     2023-04-06 [?] CRAN (R 4.2.3)
 P reprex             2.0.2      2022-08-17 [?] CRAN (R 4.2.2)
 P rlang              1.1.1      2023-04-28 [?] CRAN (R 4.2.3)
 P rmarkdown          2.21       2023-03-26 [?] CRAN (R 4.2.3)
 P rprojroot          2.0.3      2022-04-02 [?] CRAN (R 4.2.1)
 P rstudioapi         0.14       2022-08-22 [?] CRAN (R 4.2.1)
 P sass               0.4.6      2023-05-03 [?] CRAN (R 4.2.3)
 P scales             1.2.1      2022-08-20 [?] CRAN (R 4.2.1)
 P sessioninfo        1.2.2      2021-12-06 [?] CRAN (R 4.2.1)
 P shiny            * 1.7.4      2022-12-15 [?] CRAN (R 4.2.2)
 P shinyalert         3.0.0      2021-12-20 [?] CRAN (R 4.2.2)
   shinybrowser       1.0.0      2022-05-18 [1] CRAN (R 4.2.3)
 P shinyjs            2.1.0      2021-12-23 [?] CRAN (R 4.2.1)
 P shinyWidgets       0.7.6      2023-01-08 [?] CRAN (R 4.2.2)
 P stringi            1.7.12     2023-01-11 [?] CRAN (R 4.2.2)
 P stringr            1.5.0      2022-12-02 [?] CRAN (R 4.2.2)
 P testthat         * 3.1.8      2023-05-04 [?] CRAN (R 4.2.3)
 P tibble             3.2.1      2023-03-20 [?] CRAN (R 4.2.2)
 P tidyr              1.3.0      2023-01-24 [?] CRAN (R 4.2.2)
 P tidyselect         1.2.0      2022-10-10 [?] CRAN (R 4.2.1)
 P timechange         0.2.0      2023-01-11 [?] CRAN (R 4.2.2)
 P tzdb               0.4.0      2023-05-12 [?] CRAN (R 4.2.3)
 P urlchecker         1.0.1      2021-11-30 [?] CRAN (R 4.2.1)
 P usethis            2.1.6      2022-05-25 [?] CRAN (R 4.2.1)
 P utf8               1.2.3      2023-01-31 [?] CRAN (R 4.2.2)
 P uuid               1.1-0      2022-04-19 [?] CRAN (R 4.2.0)
   vctrs              0.6.3      2023-06-14 [1] CRAN (R 4.2.3)
 P viridisLite        0.4.2      2023-05-02 [?] CRAN (R 4.2.3)
 P waiter             0.2.5      2022-01-03 [?] CRAN (R 4.2.2)
 P withr              2.5.0      2022-03-03 [?] CRAN (R 4.2.1)
 P xfun               0.39       2023-04-20 [?] CRAN (R 4.2.3)
 P xtable             1.8-4      2019-04-21 [?] CRAN (R 4.2.1)
 P yaml               2.3.7      2023-01-23 [?] CRAN (R 4.2.2)

 [1] C:/Users/CBROWNLIE/AppData/Local/R/cache/R/renv/library/DN4S-App-b1a01b2a/R-4.2/x86_64-w64-mingw32
 [2] C:/Users/CBROWNLIE/AppData/Local/R/cache/R/renv/sandbox/R-4.2/x86_64-w64-mingw32/8bdc0957

 P ── Loaded and on-disk path mismatch.
 R ── Package was removed from disk.

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gadenbuie commented 1 year ago

Is there an alternative way to achieve what I'm looking for?

Hi @chrisbrownlie and thanks for the posting your question! Can you explain a bit more about what you're looking to achieve with the navsets? I'm happy to help but I'm having a hard time seeing what effect you're wanting.

chrisbrownlie commented 1 year ago

Thanks for replying. This was an oversimplified example, in an app I'm working on we are using a similiar pattern to have a dropdown in the navbar of a page_navbar(). The dropdown itself contains a card() with a navset in it. Its dynamically rendered if that makes a difference so at the moment it essentially looks like nav_item(uiOutput("dropdown")) where the uiOutput contains a dropdown with a card that has a nav within it.

Hope that helps clarify, let me know if you need any more info!

gadenbuie commented 1 year ago

That does help, thanks! Unfortunately, the official answer for now is that using dropdowns with nested navsets in the navbar are not supported. The good news is that we are working on a new interface to popovers that may very well address your use case. Stay tuned for more in that department.

I played around a bit with your example and was able to find something that mostly works using the functions we have now, basically using nav_menu(nav_item(navset_card_pill())), or a card nested in a nav_item() nested in a nav_menu(). This mostly works on the user-side but the navbar logic doesn't anticipate separately nested navsets and the selected nav_panel() is not returned back to the server.

Here's the app code with a short screen recording of how it works.

https://github.com/rstudio/bslib/assets/5420529/a2f1c50d-012f-457f-9c10-0a3a4cbe6db6

App Code ```r library(shiny) library(bslib) ui <- function() { page_navbar( id = "main_nav", nav_panel("first", "First content"), nav_panel("second", "Second content"), # Dropdown with card nav_menu( title = "Card", nav_item( card( card_title("Hey it's a card!"), card_body("And it has a body!"), class = "border-0", style = css(width = "25rem") ) ) ), # Dropdown with navset card nav_menu( title = "Nav Card", nav_item( navset_card_pill( id = "inner_nav", nav_panel("in_first", "Inner first content"), nav_panel("in_second", "Inner second content") ) |> tagAppendAttributes( # Remove the border from the card class = "border-0", # Force the card to be at least 25rem wide style = css(min_width = "25rem"), # Prevent the menu from closing when clicking on the card tab onclick = "event.stopPropagation();" ) ) ), # Remove the vertical padding from the nav card dropdown menu footer = tags$style(HTML( '[data-value="Nav Card"] ~ .dropdown-menu { --bs-dropdown-padding-y: 0; }' )) ) } server <- function(input, output) { # These observers are broken because of the nested navset card observe(cli::cli_inform("{.strong main:} {input$main_nav}")) observe(cli::cli_inform("{.strong inner:} {input$inner_nav}")) } shinyApp(ui, server) ```
chrisbrownlie commented 1 year ago

Thanks @gadenbuie, although I was specifically looking for a solution that returned the selected panel to the server-side so I'll keep an eye out for the new popovers feature and hopefully that will resolve the issue!