bslib icon indicating copy to clipboard operation
bslib copied to clipboard

Footer does not stick to bottom of the page in fillable layout using page_navbar()

Open SokolovAnatoliy opened this issue 1 year ago • 3 comments

Describe the problem

When using the footer option in page_navbar() with a fillable layout, the footer does not adjust to the changing page size. Instead, it just stays under the UI elements in the location where the bottom of the initial page was.

If you use the fillable = FALSE argument, then the footer is always present right below your last UI element, instead of at the bottom of the page. However, it does stay below all elements, and does adjust as new elements are added.

I coded this up on the shinylive website so that people could play with the fillable = TRUE or fillable = FALSE options and could see the behavior of the footer text.

I just repeated the example text to create a very large UI as the example. Here is the code that is also shown on the shinylive site.


library(shiny)
library(bslib)

ui <- page_navbar( #<<
  nav_panel("A", tagList("Page A content",
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content", 
                         br(), "Page A content")), #<<
  nav_panel("B", "Page B content"), #<<
  nav_panel("C", "Page C content"), #<<
  title = "App with navbar", #<<
  id = "page",
  footer = "my footer",
  fillable = TRUE#<<
) #<<

server <- function(input, output) {

}

shinyApp(ui = ui, server = server)

https://shinylive.io/r/editor/#code=NobwRAdghgtgpmAXGKAHVA6ASmANGAYwHsIAXOMpMAGwEsAjAJykYE8AKAZwAtaJWAlAB0IdJiw71OY4RBEBXWgAIAPAFolqKAHM4AfWgA3ei3ZKAxCpUilSo3q0Q41dkLABBN7iWkdAGVpOUlcwAAUdOCV3JWIyClIvG1tklNS0lKZ2AW83cN0omJJyMi8lJPSKiszssrCIgtjihLwyiEr2tOqcuvzoxvjS8o6Ortq8yL6igZah4crR3PrJuJKZtrmRxizu8Yap1Zz1jfmtmsXewpXmw+P2hZ6Jy6bBo9vO052lp+mbt-T73bLZ5rP7-D5jL79A6tUHvbYQi5Q64w2EZcHnR5Il6otHwjF7K7YnG2AGQ-bI2aw0mI8lE4nUzG0kHEpQMgnA3709EPdk-FFcvE8oF8ymgtnC6Giv7i76S16omVY5kCs5C2UU+VU7mA9V0nGKpmc-XasmE5XGwU6pVGhUmmlmm1ay2mjn8i2qq2Gt2253211St4Gh3ep0el0izViu2M4MB25B-2R6XR3lylmslMSjXphMRnOZ3Xmn1hv15lm5tPlgvWkNR30xxP5+up7NV5tZvXFz6l1YCGqWazreyOZwhABCgx5Y8L-asSWHUCcLjcAGFJ7sVzPvAOkqRaKRqJEALy1dzoJQAd333DsUGMLFKO-WtAAJkoT24tLpEusAGZEIhyEYd9ahgVglH-QC4EYH9bF-WhqGoKB6EPECABUsAAVQAUSfAQLDnOQIE4aDDGg1QNF-eQIAIPcSHYPhUHkUhvCIZimNIfCQBEEQAF8eOI3h+DPVB2EUEDFG8EjGDI4CT2k2TZDAXiAF0gA

I added the sessionInfo() from the shinylive site, for completeness.

Session Info


R version 4.4.1 (2024-06-14)
Platform: wasm32-unknown-emscripten (32-bit)
Running under: emscripten

Matrix products: default

locale: [1] en_US.UTF-8 C en_US.UTF-8 en_US.UTF-8 en_US.UTF-8 C

time zone: America/New_York tzcode source: internal

attached base packages: [1] stats graphics grDevices utils datasets methods base

other attached packages: [1] bslib_0.8.0 shiny_1.9.1.8002

loaded via a namespace (and not attached): [1] digest_0.6.37 later_1.3.2 R6_2.5.1 codetools_0.2-20 [5] httpuv_1.6.6.9000 fastmap_1.2.0 webr_0.4.2 magrittr_2.0.3
[9] cachem_1.1.0 glue_1.7.0 memoise_2.0.1 htmltools_0.5.8.1 [13] lifecycle_1.0.4 promises_1.3.0 cli_3.6.3 xtable_1.8-4
[17] sass_0.4.9 jquerylib_0.1.4 withr_3.0.1 renv_1.0.7
[21] tools_4.4.1 mime_0.12 Rcpp_1.0.13 fs_1.6.3.9000
[25] rlang_1.1.4 jsonlite_1.8.8

SokolovAnatoliy avatar Nov 01 '24 19:11 SokolovAnatoliy

Thanks for the issue @SokolovAnatoliy. I do think we should take a look at this to see if we can make things a bit more automatic, but here's a relatively simple solution: wrap the contents of Tab A in a div() with class = "overflow-auto". This causes the content in that tab to scroll rather than to overflow underneath the page footer.

library(shiny)
library(bslib)

ui <- page_navbar(
  nav_panel("A", div("Page A content", lorem::ipsum(20)), class="overflow-auto"),
  nav_panel("B", "Page B content"),
  nav_panel("C", "Page C content"),
  title = "App with navbar",
  id = "page",
  footer = "my footer",
  fillable = TRUE
)

server <- function(input, output) {

}

shinyApp(ui = ui, server = server)

Example app on shinylive

gadenbuie avatar Nov 06 '24 18:11 gadenbuie

Hi @gadenbuie, thanks for the suggestion. I'm trying to replicate your example, but my "Page A content" consists of a card() nested in a layout_column_wrap(). See example app. I've tried putting the div() container basically everywhere, but it doesn't help. Is there a limitation to the above approach?

fzenoni avatar Apr 29 '25 07:04 fzenoni

Put the class="overflow-auto" on the nav_panel(), not inside an additional div -- like this

cpsievert avatar Apr 29 '25 15:04 cpsievert