Dark mode

People use your apps at night, too.

Introduction to dark mode

bslib::input_dark_mode()

You can add input_dark_mode() anywhere in the app. By default it uses the system profile, or you can explicitly choose the mode.

#| standalone: true
#| components: [editor, viewer]
library(shiny)
library(bslib)

ui <- page_navbar(
  nav_spacer(),
  nav_item(input_dark_mode()), #<<
  title = "Dark mode switch in navbar"
)

server <- function(input, output) {

}

shinyApp(ui = ui, server = server)

Dark mode in action

#| standalone: true
#| components: [editor, viewer]
#| editorHeight: 500
## file: app.R
library(shiny)
library(bslib)
library(dplyr)
library(ggplot2)
library(collegeScorecard)

thematic::thematic_on()

ui <- page_sidebar(
  title = "Dark mode demo",
  sidebar = sidebar(
    checkboxGroupInput("school_type", "School type", levels(school$control)),
    sliderInput("cost_max", "Max cost", min = 0, max = 70000, value = 70000, step = 500, ticks = FALSE),
    actionButton("button", "Do Something"),
    input_dark_mode()
  ),
  card(
    card_header("School Size"),
    plotOutput("plot_school_size")
  )
)

server <- function(input, output, session) {
  schools <- reactive({
    schools <- scorecard |>
      slice_max(academic_year, by = id, n = 1) |>
      filter(cost_avg <= input$cost_max) |>
      inner_join(school, y = _, by = "id")

    if (length(input$school_type)) {
      schools <- schools |> filter(control %in% input$school_type)
    }

    schools
  })

  output$plot_school_size <- renderPlot({
    ggplot(schools()) +
      aes(x = n_undergrads) +
      geom_histogram(bins = 10) +
      theme_minimal(18)
  })
}

shinyApp(ui, server)
  • input_dark_mode()
  • Styling for dark mode
    • what are css variables?
    • Bootstrap CSS vars
    • Your own CSS variables