How to "combine" page_sidebar() and page_fluid() parts

I sense that page_sidebar() is meant for single pages (non-fluid, i.e. not more than one monitor's size). But I love its header styling, and how it places the the sidebar flush against the left side, and fills the monitor in general. However, I'd like to be able to have a scrollable page (because of my fixed width column layout).

How can I completely mimic the style of page_sidebar() using page_fluid()? This is the closest I got to mimicing page_sidebar(), which is commented out as a reference point:

library(shiny)
library(bslib)

ui <- bslib::page_fluid(
  h4("My Title"),
  layout_sidebar(
    layout_column_wrap(
      layout_column_wrap(
        width = 1,
        card(),
        card(),
        heights_equal = "row",
      ),
      width = "600px",
      card(),
    ),
    sidebar = selectInput("input", "input", "text")
  ),
)

# ui <- bslib::page_sidebar(
#   title = "My Title",
#   sidebar = selectInput("input", "input", "text"),
#   layout_column_wrap(
#     layout_column_wrap(
#       width = 1,
#       card(),
#       card(),
#       heights_equal = "row",
#     ),
#     width = "600px",
#     card(),
#   ),
# )

server <- function(input, output, session) {
}

shinyApp(ui, server)

This may get you a little closer. I looked at the source code for page_sidebar and stole some styling done there. Then I just played around in the developer console to get things as close as possible

ui <- bslib::page_fluid(
  div(class="navbar navbar-static-top",style="border-bottom-style: solid !important; 
      border-bottom-width: 1px !important; border-bottom-color:rgba(40, 70, 94, 0.1) !important;",
      div(class="container-fluid",
          h1("My Title",class = "bslib-page-title navbar-brand", style = "margin:0px"))),
  style = "padding:0;gap:0",
  layout_sidebar(
    border = FALSE, border_radius = FALSE,
    layout_column_wrap(
      layout_column_wrap(
        width = 1,
        card("card"),
        card("card"),
        card("card"),
        card("card"),
        card("card"),
        card("card"),
        heights_equal = "row",
      ),
      width = "600px",
      card("card")
    ),
    sidebar = selectInput("input", "input", "text"))
)
1 Like

Taking this customization further, how would you place the input to the right of My Title, such that it reads: "My Title input [text v]"?

Almost like:

ui <- bslib::page_fluid(
  div(class="navbar navbar-static-top",style="border-bottom-style: solid !important; 
      border-bottom-width: 1px !important; border-bottom-color:rgba(40, 70, 94, 0.1) !important;",
      div(class="container-fluid",
          h1("My Title", class = "bslib-page-title navbar-brand", style = "margin:0px"),
          selectInput("hey", "hey", "hey"),
          selectInput("hey", "hey", "hey"),
          selectInput("hey", "hey", "hey"))),
  style = "padding:0;gap:0",
  layout_sidebar(
    border = FALSE, border_radius = FALSE,
    layout_column_wrap(
      layout_column_wrap(
        width = 1,
        card("card"),
        card("card"),
        card("card"),
        card("card"),
        card("card"),
        card("card"),
        heights_equal = "row",
      ),
      width = "600px",
      card("card")
    ),
    sidebar = selectInput("input", "input", "text"))
)


server <- function(input, output, session) {
}

shinyApp(ui, server)

Hm, I wonder if you would benefit from switching to bslib::page_navbar() and utilizing bslib::nav_item() to hold the select input. That way you can remove all of the custom styling.

ui <- bslib::page_navbar(
  title = "My Title",
  fillable = FALSE,
  collapsible = FALSE,
  underline = FALSE,
  sidebar = selectInput("input", "input", "text"),
  nav_panel(
    title = NULL,
    value = "main_tab",
    layout_column_wrap(
      layout_column_wrap(
        width = 1,
        card("card"),
        card("card"),
        card("card"),
        card("card"),
        card("card"),
        card("card"),
        heights_equal = "row",
      ),
      width = "600px",
      card("card")
    )
  ),
  nav_item(selectInput("hey", "hey", "hey")),
)

I get an error with that I don't quite understand: Error in buildTabset(..., ulClass = "nav navbar-nav", id = id, selected = selected) :
Tabs should all be unnamed arguments, but some are named: underline

Perhaps you are using an older version of bslib? The underline argument was added in v0.6.0 Changelog • bslib

1 Like

I was, thanks!

This is so close to what I'd like. I'd like the input label to show on the left (instead of on top). I think it will require custom HTML/CSS?

It seems like this takes coming to grips with custom CSS. Answers like the below aren't satisfactory stylistically.

It would be great to have a simple inline = TRUE argument, like for radioButtons().

make selectInput's label inline · Issue #1737 · rstudio/shiny (github.com)
r - Is there a way to put labels next to an input box in Shiny? - Stack Overflow.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.