class: middle, center, inverse # Theming Shiny & R Markdown with `{thematic}` & `{bslib}` ### Carson Sievert, Software Engineer @ RStudio ### Slides: https://bit.ly/nhs-r2020
[@cpsievert](https://twitter.com/cpsievert)
[@cpsievert](https://github.com/cpsievert)
[cpsievert.me](https://cpsievert.me)
<cpsievert1@gmail.com> <style type="text/css"> @import url(https://fonts.googleapis.com/css?family=IBM+Plex+Sans);@import url(https://fonts.googleapis.com/css?family=Roboto+Slab);@import url(https://fonts.googleapis.com/css?family=Open+Sans);body{font-family:Open Sans, sans-serif}h1,h2,h3{font-family:Roboto Slab, serif}.remark-slide-content.large{font-size:1.5rem}.remark-slide-content.dark-mode{font-family:Roboto Slab;background-color:#444;color:#e4e4e4}.remark-slide-content.dark-mode a{color:#e39777} </style> --- class: large, middle ### New R 📦s for theming Shiny & R Markdown __`{bslib}`__: simplified theming of web content via Bootstrap * [rstudio.github.io/bslib](https://rstudio.github.io/bslib) __`{thematic}`__: simplified theming of R plots (`{ggplot2}`, `{lattice}`, & `{base}`) * [rstudio.github.io/thematic](https://rstudio.github.io/thematic) Not yet on CRAN (give it about a month or so) ```r remotes::install_github(c("rstudio/bslib", "rstudio/thematic")) ``` --- class: large ### Start using `{bslib}` with Shiny ```r library(shiny) library(bslib) ui <- fluidPage( * theme = bs_theme(), ... ) ``` * `fluidPage()`, `navbarPage()`, `bootstrapPage()`, etc. all have this `theme` argument. * You may already be using `theme` with `{shinythemes}` or your own custom Bootstrap CSS. * `bs_theme()` is way more powerful! --- class: large ### By default, upgrades app from Bootstrap 3 to 4 ```r library(shiny) library(bslib) ui <- fluidPage( * theme = bs_theme(version = 4), ... ) ``` * Special compatibility layer helps most Shiny apps & R Markdown docs upgrade to Bootstrap 4. * Upgrading may break some apps (try `version = 3` in that case). --- class: large ### Continue using Bootswatch themes ```r library(shiny) library(bslib) # In the past, this was shinythemes::shinythemes("darkly") ui <- fluidPage( * theme = bs_theme(bootswatch = "darkly"), ... ) ``` * Now you can use [Bootswatch](https://bootswatch.com/3/darkly) with BS4 or BS3 (just change `version`). * Bootswatch 4 has some new themes (e.g., [solar](https://bootswatch.com/solar) and [minty](https://bootswatch.com/minty)) --- #### Preview a theme ```r bs_theme_preview( bs_theme(bootswatch = "darkly") ) ``` <img src="darkly-preview.png" width="100%" style="display: block; margin: auto;" /> --- #### Create your own theme! ```r bs_theme( bg = "black", fg = "white", primary = "red", base_font = font_google("Grandstander") ) ``` <img src="custom1.png" width="100%" style="display: block; margin: auto;" /> --- #### `font_google()` makes it easy to import Google Font files ```r bs_theme( bg = "black", fg = "white", primary = "red", * base_font = font_google("Grandstander") ) ``` <img src="custom1.png" width="100%" style="display: block; margin: auto;" /> --- #### All Shiny UI is now (properly) themable! ```r bs_theme( bg = "black", fg = "white", primary = "red", base_font = font_google("Grandstander") ) ``` <img src="custom2.png" width="100%" style="display: block; margin: auto;" /> --- #### Use a better palette (e.g., [material dark](https://material.io/design/color/dark-theme.html)) ```r bs_theme( bg = "#202123", fg = "#B8BCC2", primary = "#EA80FC", base_font = font_google("Grandstander") ) ``` <img src="material.png" width="100%" style="display: block; margin: auto;" /> --- ### Use with `rmarkdown::html_document` ```yaml --- output: html_document: theme: bg: "#202123" fg: "#B8BCC2" primary: "#EA80FC" base_font: !expr bslib::font_google("Grandstander") --- ``` Currently requires an experimental version of R Markdown `remotes::install_github("rstudio/rmarkdown#1706")` --- class: inverse, large ### Not everything is themable, but it's getting better! * Currently themable (in next CRAN release): * The `{shiny}` package * `rmarkdown::html_document()` and `DT::datatable()` * Any "Bootstrap compatible" HTML/CSS --- class: inverse, large ### Not everything is themable, but it's getting better! * Currently themable (in next CRAN release): * The `{shiny}` package * `rmarkdown::html_document()` and `DT::datatable()` * Any "Bootstrap compatible" HTML/CSS * Soon to be themable ([we'd love your help](https://rstudio.github.io/bslib/articles/theming.html#themable-components-1)!): * Other HTML-based R Markdown output formats * Other `{htmlwidgets}` packages (e.g., `{plotly}`, `{reactable}`, etc) * Other extension packages (e.g., `{shinyWidgets}`, etc) --- class: inverse, large ### Not everything is themable, but it's getting better! * Currently themable (in next CRAN release): * The `{shiny}` package * `rmarkdown::html_document()` and `DT::datatable()` * Any "Bootstrap compatible" HTML/CSS * Soon to be themable ([we'd love your help](https://rstudio.github.io/bslib/articles/theming.html#themable-components-1)!): * Other HTML-based R Markdown output formats * Other `{htmlwidgets}` packages (e.g., `{plotly}`, `{reactable}`, etc) * Other extension packages (e.g., `{shinyWidgets}`, etc) * Fundamentally un-themable via CSS: * `plotOutput()`: use `{thematic}` to "translate" CSS to R plots! --- #### Plots don't reflect `bs_theme()` 😠```r fluidPage( theme = bs_theme(bg = "#002B36", fg = "#EEE8D5", primary = "#2AA198", base_fonts = font_google(("Pacifico")), tabsetPanel(type = "pills", tabPanel("ggplot", plotOutput("ggplot")), tabPanel("lattice", plotOutput("lattice")), tabPanel("base", plotOutput("base"))) ) ``` <img src="thematic-before.png" width="70%" style="display: block; margin: auto;" /> --- #### `{thematic}` to the rescue! 🎉 ```r *thematic::thematic_shiny() fluidPage( theme = bs_theme(bg = "#002B36", fg = "#EEE8D5", primary = "#2AA198", base_fonts = font_google("Pacifico")), tabsetPanel(type = "pills", tabPanel("ggplot", plotOutput("ggplot")), tabPanel("lattice", plotOutput("lattice")), tabPanel("base", plotOutput("base"))) ) ``` <img src="thematic-after.png" width="70%" style="display: block; margin: auto;" /> --- ### The `{thematic}` package, in general * `{thematic}` alters R plotting defaults using a few simple settings. Use `thematic_on()` to enable globally (until `thematic_off()` is called). .pull-left[ ```r library(thematic) library(ggplot2) thematic_on( bg = "black", fg = "white", accent = "red", font = "Indie Flower" ) ggplot(mtcars, aes(wt, mpg)) + geom_point() + geom_smooth() ``` ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-9-1.png" width="100%" style="display: block; margin: auto;" /> ] --- ### The `{thematic}` package, in general * `{thematic}` alters R plotting defaults using a few simple settings. Use `thematic_on()` to enable globally (until `thematic_off()` is called). .pull-left[ ```r library(thematic) library(ggplot2) thematic_on( bg = "black", fg = "white", accent = "red", * font = "Indie Flower" ) ggplot(mtcars, aes(wt, mpg)) + geom_point() + geom_smooth() ``` .bg-light-red.b--red.ba.bw2.br3.shadow-5.ph4.mt5[ Since Indie Flower is a Google Font, `{thematic}` installs it if needed! ] ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-10-1.png" width="100%" style="display: block; margin: auto;" /> ] --- class: dark-mode ### [Auto-theming](https://rstudio.github.io/thematic/articles/auto.html) with `{thematic}` * Main colors and fonts can be `"auto"`-detected! .pull-left[ ```r library(thematic) library(ggplot2) thematic_on( bg = "auto", fg = "auto", accent = "auto", font = "auto" ) ggplot(mtcars, aes(wt, mpg)) + geom_point() + geom_smooth() ``` ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-11-1.png" width="100%" style="display: block; margin: auto;" /> ] --- class: dark-mode ### [Auto-theming](https://rstudio.github.io/thematic/articles/auto.html) with `{thematic}` * Main colors and fonts can be `"auto"`-detected! .pull-left[ ```r library(thematic) library(ggplot2) thematic_on( bg = "auto", fg = "auto", accent = "auto", font = "auto" ) ggplot(mtcars, aes(wt, mpg)) + geom_point() + geom_smooth() ``` .bg-light-yellow.black-70.b--yellow.ba.bw2.br3.shadow-5.ph4.mt5[ `"auto"` works best via `shiny::renderPlot()` (works with any CSS, not just `bs_theme()`)! ] ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-12-1.png" width="100%" style="display: block; margin: auto;" /> ] --- class: dark-mode ### [Auto-theming](https://rstudio.github.io/thematic/articles/auto.html) with `{thematic}` * Main colors and fonts can be `"auto"`-detected! .pull-left[ ```r library(thematic) library(ggplot2) thematic_on( bg = "auto", fg = "auto", accent = "auto", font = "auto" ) ggplot(mtcars, aes(wt, mpg)) + geom_point() + geom_smooth() ``` .bg-light-yellow.black-70.b--yellow.ba.bw2.br3.shadow-5.ph4.mt5[ `"auto"` can work with `{bslib}` in `rmarkdown::html_document()` ] ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-13-1.png" width="100%" style="display: block; margin: auto;" /> ] --- class: dark-mode ### [Auto-theming](https://rstudio.github.io/thematic/articles/auto.html) with `{thematic}` * Main colors and fonts can be `"auto"`-detected! .pull-left[ ```r library(thematic) library(ggplot2) thematic_on( bg = "auto", fg = "auto", accent = "auto", font = "auto" ) ggplot(mtcars, aes(wt, mpg)) + geom_point() + geom_smooth() ``` .bg-light-yellow.black-70.b--yellow.ba.bw2.br3.shadow-5.ph4.mt5[ `"auto"` detects your RStudio Theme inside RStudio ] ] .pull-right[ <img src="index_files/figure-html/unnamed-chunk-14-1.png" width="100%" style="display: block; margin: auto;" /> ] --- class: inverse, middle, center ## Demo `bs_theme_preview()` overlays a real-time theming widget, let's see it action! --- ### Use real-time theming w/ any Shiny app Call `bs_themer()` in the server code (also works with a `runtime: shiny` R Markdown doc)
--- ### Implement your own theming widgets w/ `setCurrentTheme()` ```r dark <- bs_theme(bg = "black", fg = "white", primary = "purple") light <- bs_theme() ui <- fluidPage( theme = light, checkboxInput("dark_mode", "Dark mode", FALSE) ) server <- function(input, output, session) { observe({ * new_theme <- if (input$dark_mode) dark else light * session$setCurrentTheme(new_theme) }) } shinyApp(ui, server) ``` <img src="dark-mode.gif" width="50%" style="display: block; margin: auto;" /> --- class: large ### Summary * Use `bslib::bs_theme()` to theme Shiny & R Markdown. * Upgrades to Bootstrap 4 by default (can also `version = 3`). * Use Bootswatch and/or design your own custom themes. * Use `bs_theme_preview()`/`bs_themer()` to quickly preview and update themes. * See [this theming article](https://rstudio.github.io/bslib/articles/theming.html) for more detailed theming tips & tricks. * Use `{thematic}` for easier theming of R plots * Works with `{ggplot2}`, `plotly::ggplotly()`, `{lattice}`, and `{base}` R graphics. * Auto-theming (i.e., translating CSS to R defaults) works great on Shiny, but can also specify colors and fonts directly in `{thematic}`. --- class: center, middle ## Thank you! Any questions? ### Slides: [bit.ly/nhs-r2020](https://bit.ly/nhs-r2020) ### [rstudio.github.io/bslib](https://rstudio.github.io/bslib) ### [rstudio.github.io/thematic](https://rstudio.github.io/thematic)
<a href='https://twitter.com/cpsievert'>@cpsievert</a> <br />
<a href='https://github.com/cpsievert'>@cpsievert</a> <br />
<cpsievert1@gmail.com> <br />
<https://cpsievert.me/> .footnote[ <br> Slides made possible thanks to [`{xaringan}`](https://github.com/yihui/xaringan) and [`{xaringanExtra}`](https://github.com/gadenbuie/xaringanExtra) ]