rstudio / bslib

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

feat: Set min height/width of main content area of `page_sidebar()` #1057

Closed gadenbuie closed 1 month ago

gadenbuie commented 1 month ago

Fixes #1040

Adds an additional wrapper element around the main sidebar content of page_sidebar() and page_navbar() with a sidebar. The wrapper gets a .bslib-page-sidebar-main class that sets min-width and min-height, currently both to the sm breakpoint width, i.e. 576px.

The width and height can be customized in two ways:

  1. Via Sass by settings $bslib-page-sidebar-main-min-width or $bslib-page-sidebar-main-min-height. Both are map_get($grid-breakpoints, sm) !default;

  2. Via CSS variables --bslib-page-sidebar-main-min-width and --bslib-page-sidebar-main-min-height.

Demo

Demo app ```r # https://shiny.posit.co/blog/posts/bslib-dashboards/#hello-dashboards library(shiny) # library(bslib) pkgload::load_all() library(ggplot2) # Setup ------------------------------------------------------------------- data(penguins, package = "palmerpenguins") # Turn on thematic for theme-matched plots thematic::thematic_shiny(font = "auto") theme_set(theme_bw(base_size = 16)) # Calculate column means for the value boxes means <- colMeans( penguins[c("bill_length_mm", "bill_length_mm", "body_mass_g")], na.rm = TRUE ) # UI ---------------------------------------------------------------------- ui <- page_navbar( title = "Penguins dashboard", fillable = TRUE, sidebar = sidebar( varSelectInput( "color_by", "Color by", penguins[c("species", "island", "sex")], selected = "species" ) ), nav_panel( "Penguins!", layout_columns( fill = FALSE, value_box( title = "Average bill length", value = scales::unit_format(unit = "mm")(means[[1]]), showcase = bsicons::bs_icon("align-bottom") ), value_box( title = "Average bill depth", value = scales::unit_format(unit = "mm")(means[[2]]), showcase = bsicons::bs_icon("align-center"), theme_color = "dark" ), value_box( title = "Average body mass", value = scales::unit_format(unit = "g", big.mark = ",")(means[[3]]), showcase = bsicons::bs_icon("handbag"), theme_color = "secondary" ) ), layout_columns( card( full_screen = TRUE, card_header("Bill Length"), plotOutput("bill_length") ), card( full_screen = TRUE, card_header("Bill depth"), plotOutput("bill_depth") ) ), card( full_screen = TRUE, card_header("Body Mass"), plotOutput("body_mass") ) ) ) # Server ------------------------------------------------------------------ server <- function(input, output) { gg_plot <- reactive({ ggplot(penguins) + geom_density(aes(fill = !!input$color_by), alpha = 0.2) + theme_bw(base_size = 16) + theme(axis.title = element_blank()) }) output$bill_length <- renderPlot(gg_plot() + aes(bill_length_mm)) output$bill_depth <- renderPlot(gg_plot() + aes(bill_depth_mm)) output$body_mass <- renderPlot(gg_plot() + aes(body_mass_g)) } # Shiny App --------------------------------------------------------------- shinyApp(ui, server) ```

https://github.com/rstudio/bslib/assets/5420529/8641468e-fa0d-45bb-9ae2-d4e0a8766fc4

cpsievert commented 1 month ago

I'm slightly concerned about the min-height not being quite what you want when fillable_mobile = TRUE (e.g., if I just have one plot that can be very small it might be annoying that it is now ~600px). Maybe it makes sense for fillable_mobile to also gain support for a numeric that would take priority over this default behavior?

Also, regardless, let's make sure to have good note about this (in both bslib and py-shiny)

gadenbuie commented 1 month ago

I'm slightly concerned about the min-height not being quite what you want when fillable_mobile = TRUE (e.g., if I just have one plot that can be very small it might be annoying that it is now ~600px). Maybe it makes sense for fillable_mobile to also gain support for a numeric that would take priority over this default behavior?

Oh shoot, thanks for catching this. I meant to limit this change to only apply above the sm break point. That avoids the issue you rightly pointed out with fillable mobile layouts.