-
as_fillable_container(),as_fill_item()andas_fill_carrier()now always include the htmltools fill CSS dependency. This means that they are no longer usable with the$addAttr()htmltools::tagQuerymethod; authors should instead pass elements to theas_fillable_container()andas_fill_*()functions and use thecss_selectorargument to apply fill options to specific elements. (#946) -
A
sidebar()passed topage_sidebar()/page_navbar()is now always open (and not collapsible) by default on mobile screens. To revert to the old behavior, setopen = "desktop"in thesidebar. (#943) -
page_sidebar()now places thetitleelement in a.navbarcontainer that matches the structure ofpage_navbar(). This ensures that the title elements ofpage_sidebar()andpage_navbar()have consistent appearance. (#998)
-
Added
input_task_button(), a replacement forshiny::actionButton()that automatically prevents an operation from being submitted multiple times. It does this by, upon click, immediately transitioning to a "Processing..." visual state that does not let the button be clicked again. The button resets to its clickable state automatically after the reactive flush it causes is complete; or, for advanced scenarios,update_task_button()can be used to manually control when the button resets. -
Both
card()andvalue_box()now take anidargument that, when provided, is used to report the full screen state of the card or value box to the server. For example, when usingcard(id = "my_card", full_screen = TRUE)you can determine if the card is currently in full screen mode by reading the boolean value ofinput$my_card$full_screen. (#1006)
-
layout_columns()was rewritten in Typescript as a custom element to improve the portability of the component. (#931) -
When
layout_columns()is given arow_heightsvalue that is not abreakpoints()object, that value is used for the row heights at all breakpoints. Previously, it was used for the row heights from"sm"up. (#931) -
When
layout_columns()is given acol_widthsvalue withbreakpoints()atlgor wider, it now uses a better default column width for the smaller breakpoints not listed in thecol_widthsvalue. That said, you can always includesmormdin yourbreakpoints()definition to have complete control over column widths at those sizes. (#931) -
sidebar()now supports separate choices for theopenargument on mobile or desktop screens. You can pass a list withmobileanddesktopvalues toopento control the sidebar's initial state on each screen size, choosing from"open","closed", or"always"(for an always-open sidebar that cannot be collapsed). (#943) -
The sidebar's collapse toggle now has a high
z-indexvalue to ensure it always appears above elements in the main content area oflayout_sidebar(). The sidebar overlay also now receives the same highz-indexon mobile layouts. (#958) -
We've improved the accessibility of full screen cards created with
card(full_screen = TRUE, ...). The Expand card button is now accessible via keyboard navigation and appropriate ARIA attributes connect the card with the expand and close buttons. For JavaScript-oriented users, the expansion/collapse is now accompanied by a custombslib.cardevent with the full screen state reported in theevent.detail.fullScreenproperty. (#959) -
Full-screen cards are now supported on mobile devices: the Expand card button is revealed when a user taps on the card (thanks @Damonsoul, #961).
-
We adjusted the shadows used for cards and popovers in the Shiny preset. Cards now use a slightly smaller shadow and the same shadow style is also now used by popovers. (#998)
-
We increased the spacing between elements just slightly in the Shiny preset. This change is most noticeable in the
layout_columns()orlayout_column_wrap()component. In these and other components, you can usegapandpaddingarguments to choose your own values, or you can set the$bslib-spacer(Sass) or--bslib-spacer(CSS) variable. (#998)
-
layout_columns()now always uses a 12-unit grid when the user provides an integer value tocol_widthsfor any breakpoint. For example,breakpoints(md = 3, lg = NA)will pick a best-fitting layout for large screen sizes using the 12-column grid. Previously, the best fit algorithm might adjust the number of columns as a shortcut to an easy solution. That shortcut is only taken when an auto-fit layout is requested for every breakpoint, e.g.col_widths = breakpoints(md = NA, lg = NA)orcol_widths = NA. (#928) -
Fixed an issue where the page might be given a window title of
NAif the primarytitleargument of a page function, such aspage_sidebar(), isNULLor a suitable window title could not be inferred. (#933) -
Fixed a couple
update_popover()bugs. (#747) -
uiOutput()no longer yields unwanted double padding when it's parent container usesgapfor spacing multiple elements (e.g.,layout_columns(),page_fillable(), etc). (#992) -
page_navbar()andnavset_bar()now validate and transformpaddingandgaparguments into appropriate CSS values. (#991) -
Fixed an issue that could happen with a
card()orvalue_box()that is rendered entirely viarenderUI()when it is replaced by an updated card but the user had expanded the original card into full screen mode. Now the full screen state is reset for the new card or value box. If you want to update a card without potentially exiting the full-screen mode, update specific parts of the card usinguiOutput()ortextOutput(). (#1005)
-
Fixed the CSS for the
bslib-page-dashboardclass in the Shiny preset to correctly supportpage_sidebar(class = "bslib-page-dashboard")andpage_navbar(nav_panel(class = "bslib-page-dashboard")). (#917) -
Fixed a minor bug to allow the themer demo to be run directly, outside of
bs_theme_preview(). (#918)
-
bs_theme()now defaults topreset="shiny". This provides an additional set of theming defaults and rules that make it easier to create Shiny apps (in particular, dashboards) that look good out of the box. To revert to the previous behavior, setbs_theme(preset="bootstrap"). (#711) -
value_box()no longer defaults totheme_color = "primary". To restore the previous behavior, please usetheme = "primary". In addition to the default style change, thetheme_coloris now deprecated in favor oftheme. (#758) -
page_navbar()now defaults tounderline = TRUE, meaning that navigation links in the navbar now have underline styling by default (setunderline = FALSEto revert to previous behavior). (#784) -
page()now returns a<body>tag instead oftagList(). This change allowspage()to treat named arguments as HTML attributes for the<body>tag, making it possible to add page-level classes or other attributes. (#809) -
The JS/CSS assets behind
{bslib}components (e.g.,card(),value_box(), etc) are all now bundled into onehtmlDependency()and included with the return value ofbs_theme_dependencies()(previously they were attached at the component-level). (#810) -
layout_column_wrap()no longer requireswidthandwidthis no longer the first argument, meaning thatwidthmust be named if used. The new default iswidth = "200px", which combines withfixed_width = FALSEto produce a responsive layout where each column is at least 200px wide. This means that, in most cases,layout_column_wrap()can automatically layout an unknown number of items without you having to setwidth. (#853)
-
The default version of Bootstrap is now v5.3.1, upgraded from v5.2.2. The most notable thing that comes with the update is the ability to toggle between light/dark color modes purely client-side (i.e., no calls to Sass required). (#749, #764)
-
Added
input_dark_mode(), a new input control that provides a toggle button that can be used to switch between the dark and light modes when using Bootstrap 5.3. By default, dark mode is applied automatically if the user's operating system is also in dark mode. App authors can toggle dark mode programmatically from the server usingtoggle_dark_mode(), and if you provideinput_dark_mode()with anid, you can read the current color mode via the corresponding input value. (#787) -
Shiny's Bootstrap theme preset is now used by default in
bs_theme()and all relatedpage_*()functions in bslib. This theme brings a fresh new design to all Shiny apps and dashboards created with bslib. This dashboard design anticipates heavy use of cards for organizing content, and works best with a gray background for contrast with minimalistic white cards. This treatment can be enabled inpage_sidebar(),page_fillable()and otherpage_*()functions by adding thebslib-page-dashboardclass to the page container or body tag.The preset can also be customized using the
$bslib-dashboard-designand$bslib-enable-shadowsSass variables. Set these tofalseto disable the dashboard treatment and card shadows, respectively. These variables can be set viabs_theme(), e.g.bs_theme("bslib-dashboard-design" = "false"). (#897, #906) -
value_box()has been updated with a number of new features and improvements:-
value_box()now supports many new themes and styles, or fully customizable themes using the newvalue_box_theme()function. To reflect the new capabilities, we've replacedtheme_colorwith a newthemeargument. The previous argument will continue work as expected, but with a deprecation warning. (#758)In addition to the Bootstrap theme names (
primary,secondary, etc.), you can now use the main Boostrap colors (purple,blue,red, etc.). You can also choose to apply the color to the background or foreground by prepending abg-ortext-prefix to the theme or color name. Finally, we've also added new gradient themes allowing you to pair any two color names asbg-gradient-{from}-{to}(e.g.,bg-gradient-purple-blue).These named color themes aren't limited to value boxes: because they're powered by small utility classes, you can use them anywhere within your bslib-powered UI.
-
Added
showcase_bottom(), a newvalue_box()layout that places the showcase below the value box title and value, perfect for a full-bleed plot. (#758) -
showcase_left_center()andshowcase_top_right()no longer take two values for thewidthargument. Instead, they now take a single value (e.g.,width = "30%") representing the width of the showcase are in the value box. Furthermore, they've both gainedwidth_full_screenarguments that determine the width of the showcase area when the value box is expanded to fill the screen. (#758) -
The
showcase_layoutargument ofvalue_box()now accepts one of three character values:"left center","top right","bottom". (#758) -
A new Build a Box app is now available online or via bslib. See
?value_box()for details. The app helps preview a set of value boxes while you configure and customize their appearance and provides you with code to copy and paste into your app. (#790)
-
-
Added new
navset_underline()&navset_card_underline()functions as well as aunderlineargument topage_navbar()to leverage the new nav-underline styling on navigation links. (#784)
-
The
bs_themer()app now supports previewing the dark mode variant of Bootstrap 5 themes. (#767) -
Improved the style and appearance of the button to enter full screen in
card()s andvalue_box()es to better adapt to Bootstrap's dark mode. (#780) -
htmltools::save_html()now works as expected when applied directly to components (e.g.,card(), etc) and pages with a non-default theme. (#823, #815) -
layout_sidebar()received a new design. The button to collapse and expand the sidebar now appears at the top (instead of the bottom) of the sidebar. On mobile devices, the sidebar now fills thelayout_sidebar()area as an overlay, rather than expanding from above the main content area. Note themax_mobile_heightargument ofsidebar()determines the maximum height of the sidebar area on mobile, but it now only applies whenopen = "always". (#798) -
layout_sidebar()now uses an<aside>element for the sidebar's container and a<header>element for the sidebar title. The classes of each element remain the same, but the semantic meaning of the elements is now better reflected in the HTML markup. (#580) -
In
layout_column_wrap(), whenwidthis a CSS unit -- e.g.width = "400px"orwidth = "25%"-- andfixed_width = FALSE,layout_column_wrap()will ensure that the columns are at leastwidthwide, unless the parent container is narrower thanwidth. (#851) -
bs_global_theme()gains apresetargument to match the function signature ofbs_theme(). (#896)
-
toggle_switch()now works correctly when called from within a Shiny module.update_switch()worked as expected, buttoggle_switch()didn't apply the module's namespace to theidof the switch to be updated. (#769) -
Filter controls in the popovers of
DT::datatable()tables now better match the current Bootstrap theme and are responsive to the dark mode setting in Bootstrap 5.3. (#267, #775). -
A double border no longer appears when an accordion is used inside a
sidebar(open="always")context. (#795) -
layout_sidebar()no longer gives the sidebar main content area therole="main"attribute. (#580)
- Added
tooltip(),update_tooltip(), andtoggle_tooltip()for easy creation (and server-side updating) of Bootstrap tooltips (a way to display additional information when focusing (or hovering over) a UI element). (#662) - Added
popover(),update_popover(), andtoggle_popover()for easy creation (and server-side updating) of Bootstrap popovers. Popovers are similar to tooltips, but are more persistent, and should primarily be used with button-like UI elements (e.g.,actionButton(),bsicons::bs_icon(), etc). (#702) - Added
input_switch()andupdate_switch()for easy creation (and server-side updating) of a Bootstrap's switch input (an on-off toggle for binary input values). (#483) - Added two new toggle functions:
toggle_switch()for toggling the state of aninput_switch()element andtoggle_sidebar()for toggling the state of asidebar()element (sidebar_toggle()remains as an alias oftoggle_sidebar()). (#709)
- Closed quarto-dev/quarto-cli#6081:
{bslib}'s components (e.g.,card(),sidebar(), etc.) now work more sensibly in Quarto docs. (#664) - Closed #672:
sidebar()gainsgapandpaddingarguments to control the vertical gap between items in the sidebar and the padding around the sidebar's content. (#725)
- Closed #636: Outputs in sidebars now work as expected when an initially-closed sidebar is opened. (#624)
- Closed #640:
accordion()no longer errors when anidisn't supplied inside a Shinysessioncontext. (#646) - Closed #639:
nav_panel()'siconargument now supports genericHTML(), meaning that things likebsicons::bs_icon()andfontawesome::fa()can be used as values. (#645) - Light-styled buttons in bslib-provided Bootswatch themes are now consistent with their design in Bootswatch. Previously, they were inadvertently styled similarly to secondary buttons. (#687)
- Closed #727:
layout_column_wrap()now enforces equal column widths by avoiding layout issues caused by grid container overflow. (#729)
This significant release focuses on making dashboards with filling/responsive layouts easier. See the new Getting Started with Dashboards article to learn more. It also includes new components (accordion()) as well as many improvements and bug fixes for existing features and components.
{bslib}'s dashboarding features are still experimental at this point, but this release represents a significant step towards being our recommended way to create Shiny dashboards.
card_body()now provides the same behavior ascard_body_fill()(i.e., it is both a fillable container and fill item) by default. And, now, sincecard_body()can do everythingcard_body_fill()can do,card_body_fill()has been deprecated. The main benefit of this change is thatcard(full_screen = TRUE, ...)with output(s) passed to..."just works" in an intuitive way. To revert to the previous behavior, setfillable = FALSEandfill = FALSEin calls tocard_body()and setwrapper = function(x) card_body(x, fillable = FALSE, fill = FALSE)in calls tocard(). (#498)- Closed #375:
margin-topis no longer included on header tags that aren't created via pandoc. If this negatively impacts spacing above headers, consider adding a suitable utility class (for example, changeshiny::titlePanel("My title")totagAppendAttributes(titlePanel("My title"), class = "mt-3", .selector = "h2")). (#396) page_fill()(now calledpage_fillable()) had several breaking changes (listed below) to better accommodate filling layouts. If this breaks existing behavior, consider usingshiny::fillPage(theme = bslib::bs_theme(), ...)instead ofpage_fill().page_fill()now produces a<body>tag withdisplay:flex(instead ofdisplay:block).page_fill()no longer fills the windows height on mobile (i.e., narrow screens) by default (setfillable_mobile = TRUEto restore the old behavior).page_fill()now addspaddingandgapby default, setpadding = 0andgap = 0to restore the old behavior.
page_navbar()(and alsoshiny::navbarPage()withtheme = bs_theme()) had a couple breaking changes:- The container of each page is now
display:flex(instead ofdisplay:block). If this breaks existing behavior, setpage_navbar()'sfillableargument toFALSE. headerandfooteris no longer wrapped in an additionalshiny::fluidRow()container. If this breaks existing behavior, consider wrapping theheaderandfootervalue(s) withshiny::fluidRow()). (#479)
- The container of each page is now
layout_column_wrap()'sfillargument now controls whether or not the layout container is allowed to grow/shrink to fit a fillable container (e.g.,page_fillable()). It also gains a newfillableargument for controlling whether UI elements are allowed to fill their row height. This is more consistent with the meaning offillin other functions, likecard(),card_body(),layout_sidebar(), etc. (#498)- Defaults for the following Bootstrap 5 Sass variables were changed to
null:$accordion-button-active-bg,$accordion-button-active-color, and$accordion-icon-active-color. To restore the old behavior, dobs_add_variables(theme, "accordion-button-active-bg" = "tint-color($component-active-bg, 90%)", "accordion-button-active-color" = "shade-color($primary, 10%)", "accordion-icon-active-color" = "$accordion-button-active-color", .where = "declarations"). (#475)
- Added
page_sidebar(), for easy dashboard creation. (#588) - Added a
sidebar()API for creating sidebar layouts in various contexts. See the article to learn more. (#479) - Added
layout_columns(), for responsive column-based grid layouts. (#587) - Adds a new
accordion()API. Seehelp(accordion)for examples and details. Note alsoaccordion()is designed to work well inside asidebar(). (#475) page_navbar(),navset_card_tab(), andnavset_card_pill()gain asidebarargument for putting asidebar()on every page/tab/pill. (#479)page_navbar()gains afillableargument to make the content of particular page(s) fit the window/card. (#479)page_fillable()(aka,page_fill()) is now considered afillablecontainer, meaning thatfillitems likecard(),layout_column_wrap(), andlayout_sidebar()now grow/shrink to fit the window's height when they appear as a direct child ofpage_fillable(). (#479)page_navbar()andpage_fillable()gainfillable_mobilearguments to control whether the page should grow/shrink to fit the viewport on mobile. (#479)card(),value_box(), andcard_image()gainmax_height/min_heightandfillarguments. (#498)card_body()gains apaddingargument. (#587)- Added new
as_fill(),as_fillable(),as_fill_carrier(),is_fill(), andis_fillable()for testing and coercing potential to fill. (#498)
- Closed #558: nested cards with
fullscreen = TRUEnow correctly and individually expand to fill the window. Tab focus behavior while in full screen mode has also been improved. (#557) - Closed #573: Improved styling when a dynamic result is supplied to
value_box()'stitle/value(e.g.,value_box("Dynamic value", uiOutput("value"))). (#605)
card_body_fill()has been deprecated in favor ofcard_body(). (#498)page_fill()has been deprecated in favor ofpage_fillable(). (#498)nav()has been deprecated in favor ofnav_panel()andnav_content()in favor ofnav_panel_hidden(). (#476)- The
navs_*()family of functions have been deprecated in favor ofnavset_*()(#476):navs_tab()is nownavset_tab()navs_pill()is nownavset_pill()navs_pill_list()is nownavset_pill_list()navs_bar()is nownavset_bar()navs_tab_card()andnavs_pill_card()are nownavset_card_tab()andnavset_card_pill(), respectively.
- Upgraded Bootstrap 5 (i.e.,
bs_theme(version = 5)) from 5.1.3 to 5.2.2. (#438, #455)
-
Adds a new
card()API as well asvalue_box()andlayout_column_wrap(). To learn more about this new functionality, refer to these new pkgdown articles:
- Closed #458. This release
{bslib}now requires{memoise}2.0.1 or above.
bs_theme()now defaults toversion = 5(i.e., Bootstrap 5). If this change happens to break an existing app, consider specifyingbs_theme(version = 4)to revert the change in the Bootstrap version. (#374)- The default coloring on some Bootswatch 4+ theme's
.navbar-default/.navbar-inverseclass has changed slightly to better match their Bootswatch 3 coloring. Also, since this coloring is now based solely on$navbar-*variables, Bootswatch themes now work better in combination with custom$navbar-*values (e.g.,bs_theme("navbar-bg" = ...)can be used to provide the background color, and foreground colors will automatically contrast appropriately). (#392)
- Upgraded Bootstrap 5 (i.e.,
bs_theme(version = 5)) from 5.1.0 to 5.1.3 (#378) - Closed #369:
bs_dependency_defer()now memoisesfunc(by default), reducing the time required to render multiple instances of the same dynamically themable widget. (#405)
- Closed #393: Bootstrap 5's
$form-check-label-*variables now work as expected withshiny::radioButtons(),shiny::checkboxInput(), andshiny::checkboxGroupInput(). (#395) - Closed #382: Various fixes for using
shiny::checkboxInput(),shiny::checkboxGroupInput(), andshiny::radioButton()withbs_theme(version = 5, bootswatch = "sketchy"). (#385) - Closed #377: make sure
shiny::tabsetPanel(type = "hidden")(i.e.,bslib::navs_hidden()) stays hidden when used withbs_theme(). (#379) - Closed #424: fixed an issue with
nav_menu()appearing first in anavs_*()container with Bootstrap 4+. - Closed #431: Bootstrap 5 navbars no longer have an unwanted "Toggle Navigation" label when collapsed. (#432)
- Closed #400:
nav_menu(align="right")now works with Bootstrap 5. (#401) - Closed #390: using
bs_theme(bootswatch = "paper", version = 5)orbs_theme(bootswatch = "readable", version = 5)no longer errors. (#391)
- Upgraded Bootstrap 5 (i.e.,
bs_theme(version = 5)) from 5.0.2 to 5.1.0 (#365)
- Closed rstudio/shiny#3519:
nav_menu()(i.e.,shiny::navbarMenu()) wasn't producing an.activeclass on it's.dropdowncontainer properly. (#372)
- Closed rstudio/rmarkdown#2154:
{magrittr}'s pipe operator (%>%) is no longer re-exported by{bslib}. Eitherlibrary(magrittr)to make%>%available and/or use use R 4.1's pipe operator (|>).
- Closed #82: Added support for Bootstrap 5 (via
bs_theme(version = 5)). Bootstrap 4 remains the default in this release, but the next release, the default will likely change to Bootstrap 5.
- Closed #6: rmarkdown's .tabset-fade class now works with Bootstrap 4+ since legacy use of .nav .fade is now officially supported in Bootstrap 4+. (#325)
Small patch release to fix failing test on Solaris.
- Closed #251: New
bs_theme()options (navbar-bg,navbar-light-bg, andnavbar-dark-bg) for more easily customizing the navbar's background (and foreground) color (#253, #271). - Closed #281: New
bs_theme()argument (font_scale) for easier scaling of the base font size (#288). - Closed #256 and #282: Font file importers (
font_google(),font_link(), andfont_face()) are now re-exported from the{sass}package. As a result, they may now be used with any Sass variable (e.g.,bs_theme("input-font-family" = font_google("Pacifico"))) as well as inside Rmd yaml without!expr(e.g.,input-font-family: google: Pacifico-- see #256 for more details). A newfont_collection()function was also added for a more convenient way to specify font fallbacks (#291). - Closed #255:
bs_themer()now emits sensibleyamlfront matter when used within an Rmd document (#288). - Closed #227:
bs_themer()now overlays a spinner during Sass compilation (#243). - Closed #278:
{bslib}now includesrmarkdown::html_documenttemplates demonstrating example usage with{bslib}and{thematic}(#288). - Closed #231: Upgraded from Bootstrap 4.5.3 to 4.6.0 (#254).
- Closed #237:
<blockquote>tags now have border-left/padding styles withversion = 4(to mirror theversion = 3behavior) (#239). - Closed #279: Warnings about low color contrasts are now suppressed by default, unless
shiny::devmode()is enabled. To enable/disable these warnings, set the newoptions(bslib.color_contrast_warnings = )toTRUE/FALSE(#287). bs_theme_dependencies()now includes Sass source maps whenshiny::devmode()is enabled (#312).- Added new
bs_add_functions()/bs_add_mixins()and deprecatedbs_add_declarations()to reflectsass::sass_layer()'s new ability to placefunctionsbefore variabledefaults. As a result, variable definitions may now use functions defined withbs_add_functions(). (#311)
- Closed #236, #230, #242, #187, #215, #250: Addressed various cosmetic issues with CSS (#249).
- Closed #289: collapsed navbar toggle now correctly floats to the right (#290).
- Closed rstudio/flexdashboard#316: fixed an issue with navbar nav spacing/alignment (#286).
- Initial release of the package, see https://rstudio.github.io/bslib/