Announcing new R Shiny UI components

I’m thrilled to share that the latest release of the {bslib} R package introduces new a Card API, Value boxes, and a responsive grid-like layout. These new UI components work in Shiny, R Markdown, Quarto (or really any R-based HTML project) and work best alongside the new {bsicons} package (an R interface to Bootstrap icons) as well as the latest versions of {htmlwidgets} and {shiny}:

install.packages("bslib")
install.packages("bsicons")
install.packages("htmlwidgets")
install.packages("shiny")

In the video below, I walk-through a Shiny app which quickly illustrates what’s possible with these components. Note the responsive full screen behavior of the cards and the “sidebar” layout made possible by the new layout_column_wrap(). It also makes use of the new {histoslider} package for the histogram sliders in the sidebar. See here for the live app and here for the source code.


Cards

At their most basic level, cards simply provide borders and padding around content, but {bslib} adds on some additional functionality like expanding to full screen, integration with tab panels, static images, and more.

Learn more about cards
A card, holding a bar chart, expanding to a full screen view

Value boxes

At their most basic level, value boxes provide a simple way to highlight single value with a caption. Optionally, value boxes can showcase some HTML content like an icon or even a plotly graph. In addition, value boxes can also be expanded to full screen which, with some clever usage, can be leveraged to implement “expandable spark lines”, like shown below.

Learn more about value boxes
A value box becoming fullscreen to show more detail

Responsive grid-like layout

The new layout_column_wrap() function is designed for wrapping a 1d sequence of UI elements into a responsive 2d grid (powered by CSS Grid).

Its defaults are optimized for a grid that has equal column widths and row heights, but it’s also fairly straightforward to vary heights and widths. In addition, layout_column_wrap() can be nested inside another layout_column_wrap(), which is helpful for more sophisticated layouts, like the motivating example (the one with a “sidebar” at the top of this post). That example also leverages responsive sizing and a clever bit of CSS on the outermost layout_column_wrap() to effectively fit contents to the viewport (minus some space for the navbar height). By the way, without that specified height, the contents would just use their natural height (thanks to the underlying bindFillRole() mechanics there’s no need for tedious setting of height="100%" everywhere to get children to fill their parent height).

Learn more about layouts
Wrapping a 1d sequence of UI elements into a responsive 2d grid.

Fill items and containers

Underneath the hood, cards, value boxes, and layout_column_wrap() all make use of the new bindFillRole() function from {htmltools} (in fact, the newest shiny::plotOutput() and htmlwidgets::shinyWidgetOutput() do as well) to achieve their intelligent responsive fill sizing behavior. We decided to expose the mechanism behind this fill behavior in {htmltools} since it isn’t specific to Bootstrap (it’s based on CSS flexbox), and as a result, could be leveraged in any Shiny (or RMarkdown/Quarto) project.

bindFillRole() works by marking a UI element (i.e., a htmltools::tag) as either a fill container or a fill item (or both). When a fill item appears as a direct child of a fill container with an opinionated height, it grows and/or shrinks to fit the containers height. For a concrete example and more explanation, visit the reference page for bindFillRole().


More to come

Keep an eye out for more UI components coming in future releases of {bslib}. We’re hoping {bslib} can eventually be a “one-stop shop” of tools for building custom and modern looking Shiny UI. Obviously, to meet that goal, we need to at least match the set of functionality that projects like {shinydashboard} provide, so be on the look out for things a new sidebar layout, accordions, and more.


If you have questions about this article or would like to discuss ideas presented here, please post on Posit Community. Our developers monitor these forums and answer questions periodically. See help for more help with all things Shiny.