Nested navset in nav_item() prevents accessing from server via id argument
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 <NA> [?] <NA>
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.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
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.
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!
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
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)
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!