rstudio / bslib

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

feat: Sidebar toggle position on smaller screens #1085

Closed gadenbuie closed 1 month ago

gadenbuie commented 1 month ago

This PR builds on #1084 and fixes a few more things:

  1. The main area of a sidebar layout would scroll under a toggle button. We now place the toggle button in a new grid row so that the main content scrolls without being underneath the toggle button. This also means that we don't need to preserve the gutter space on the sidebar side for the collapse toggle when the sidebar is collapsed.

    Before

    https://github.com/rstudio/bslib/assets/5420529/5ad9a549-a4f7-4ce7-9be0-e45b9a9a5b16

    After

    https://github.com/rstudio/bslib/assets/5420529/4991725a-630c-4637-8bba-f419a0ac451e

  2. On medium-sized screens, we now take away some padding on the non-sidebar side to save space.

    Before AFter
    image image
  3. We previously added minumum height and width to the main area of a page_sidebar() (or page_navbar() with a sidebar), but this could cause the main content to scroll underneath the sidebar toggle button. We now apply the min-width only when the sidebar is expanded (or expanding), which avoids content overlap while still preserving the min width behavior we want.

    Before

    https://github.com/rstudio/bslib/assets/5420529/39e8f51f-f50a-470f-b2ce-24f9c6543ec8

    After

    https://github.com/rstudio/bslib/assets/5420529/d7209f26-92a1-43cf-b232-ce7727fc356c

Example App ```r library(shiny) # library(bslib) pkgload::load_all() lorem_markdown <- function(n_sections = 3) { make_section <- function() { paste( paste("##", tools::toTitleCase(lorem::ipsum_words(sample(3:5, 1)))), "", paste(lorem::ipsum(3), collapse = "\n\n"), "", sep = "\n\n" ) } markdown(vapply(seq_len(n_sections), \(x) make_section(), character(1))) } make_card <- function( class = NULL, sidebar_bg = NULL, main_bg = NULL, n = 1, title = "Card header" ) { card( card_header(title), class = class, max_height = "300px", layout_sidebar( sidebar = sidebar( width = NULL, bg = sidebar_bg, position = "right", lorem::ipsum(5, 2, 8) ), bg = main_bg, lorem_markdown(n) ) ) } use_page_navbar <- FALSE sb_position <- "right" page_args <- list( theme = bs_theme(5, "shiny"), title = "Sidebar Mobile Layout", sidebar = sidebar( title = "Page Sidebar", open = "desktop", position = sb_position, input_dark_mode(), div(lorem_markdown()) ) ) content <- list( make_card(), make_card(class = "text-bg-primary"), make_card(class = "text-bg-dark") ) ui <- if (!use_page_navbar) { rlang::exec(page_sidebar, !!!page_args, !!!content) } else { rlang::exec(page_navbar, !!!page_args, nav_panel("Page", !!!content)) } server <- function(input, output, session) { } shinyApp(ui, server) ```