---
title: "Improved Skins"
author: "David Granjon"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Improved Skins}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
library(bslib)
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

## A Real Time Skin Selector

`{shinydashboardPlus}` has a new feature called the `skinSelector()`. This is a JavaScript based widget allowing the end user to change the app skin. According to the `dashboardPage()`, there are 6 unique colors with 2 versions, light or dark. 
Note that the `dashboardControlbar()` is the perfect place to host the `skinSelector()` since it may be seen as a secondary input (your app may still work without :))

```{r, eval=TRUE, echo=FALSE}
card(
  shiny::tags$iframe(
    class = "html-fill-item", 
    src = "https://shinylive.io/r/app/#h=0&code=NobwRAdghgtgpmAXGKAHVA6ASmANGAYwHsIAXOMpMAGwEsAjAJykYE8AKAZwAtaJWAlAB0IdJiw48+rACZQe9IixnDRDZmy69+chUsYyACtQCunVVP4BBdOxEACRydr2AvPd3dFyw1ADmcHYQjiHccFAycIxuHvJe+jIAEuGRjOwCuA4h9py0kfQsMZ7eBgDKeXAFaRlZIYoyrEVxJTIAQkQN6ZnB2cRkjETUVU16ygDCJKQDQyzsxNTUaJxwMjEAYlYAMqUAorg5ANZ8pXDUcASkRNU1PSGktKRnMUJgpUfBJ2cXVy+1NyHLRgANyiMQAZiYIBdaCR2HxUCZSPsiIiEaQBPYQPYAL4OARgbEAXSAA", 
    height = "800", 
    width = "100%", 
    style = "border: 1px solid rgba(0,0,0,0.175); border-radius: .375rem;", 
    allowfullscreen = "", 
    allow = "autoplay", 
    `data-external` = "1"
  ),
  full_screen = TRUE,
  style = "margin: 0 auto; float: none;"
)
```

<div class="text-center mt-4">
<a class="btn btn-primary" data-bs-toggle="collapse" href="#skin-selector" role="button" aria-expanded="false" aria-controls="tabLayout">
Code
</a>
</div>

<div class="collapse" id="skin-selector">
```{r, eval=FALSE}
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
shinyApp(
   ui = dashboardPage(
     header = dashboardHeader(),
     sidebar = dashboardSidebar(),
     body = dashboardBody(),
     controlbar = dashboardControlbar(collapsed = FALSE, skinSelector()),
     title = "Skin Selector"
   ),
   server = function(input, output) { }
 )
```
</div>

## A New Dark Skin: midnight

The midnight theme is powered by the corresponding Github [project](https://github.com/anvyst/adminlte-skin-midnight). It provides a plug and play dark theme. 

```{r, eval=TRUE, echo=FALSE}
card(
  shiny::tags$iframe(
    class = "html-fill-item", 
    src = "https://shinylive.io/r/app/#h=0&code=NobwRAdghgtgpmAXGKAHVA6ASmANGAYwHsIAXOMpMAGwEsAjAJykYE8AKAZwAtaJWAlAB0IdJiw48+rACZQe9IixnDRDZmy69+chUsYyACtQCunVSKn8AgunYiABE5O0HAXge7ui5YagBzOHsIJ1DOAGs+dwchMBhaGQhaf25SWNxHUIduOCgZOEZorx8DAAlc-MZ2AQyQrM4EuHoWIvlvfRkAZUbmqprM0MUZVla9ZQAhImHgrMGiAA8Z2dDSWlJqOGjYgFkRxXnYgazVWf660OIyRiJqXtH25QBhElJr25Zq2tmAMyIickKHmKHQAYn8AZ8jg5VutNh4dgkkilSA5OpEIIdzmcwgUAG4FaLfEwQAirEjsPioEykXAOIjUqmkAQOEAOAC+jgEYDZAF0gA", 
    height = "800", 
    width = "100%", 
    style = "border: 1px solid rgba(0,0,0,0.175); border-radius: .375rem;", 
    allowfullscreen = "", 
    allow = "autoplay", 
    `data-external` = "1"
  ),
  full_screen = TRUE,
  style = "margin: 0 auto; float: none;"
)
```

<div class="text-center mt-4">
<a class="btn btn-primary" data-bs-toggle="collapse" href="#skin-midnight" role="button" aria-expanded="false" aria-controls="tabLayout">
Code
</a>
</div>

<div class="collapse" id="skin-midnight">
```{r, eval=FALSE}
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)

shinyApp(
   ui = dashboardPage(
     skin = "midnight",
     header = dashboardHeader(),
     sidebar = dashboardSidebar(),
     body = dashboardBody(
       box(
         title = "My box"
       )
     ),
     controlbar = dashboardControlbar(),
     footer = dashboardFooter(),
     title = "Midnight Skin"
   ),
   server = function(input, output) { }
 )
```
</div>


```{r midnight-skin, echo=FALSE, fig.cap='Midnight skin overview', fig.align = 'center', out.width='100%'}
knitr::include_graphics("figures/skin-midnight-overview.png")
``` 

This is the fastest option to get a dark design. You'll see below that the `{fresh}` package is able to provide a similar look and feel, with much more options (but more effort).

Important: this feature is still <a href='https://lifecycle.r-lib.org/articles/stages.html#experimental'><img src='figures/lifecycle-experimental.svg' alt='Experimental lifecycle'></a>!


## Material Design + AdminLTE
To activate the material design feature, set _md_ to TRUE in `dashboardPage()`. 
This feature is powered by [MaterialAdminLTE](https://github.com/DucThanhNguyen/MaterialAdminLTE), built on top of AdminLTE2 and [material design for Bootstrap 3](https://fezvrasta.github.io/bootstrap-material-design/)
<a href='https://lifecycle.r-lib.org/articles/stages.html#experimental'><img src='figures/lifecycle-experimental.svg' alt='Experimental lifecycle'></a>!

```{r, eval=TRUE, echo=FALSE}
card(
  shiny::tags$iframe(
    class = "html-fill-item", 
    src = "https://shinylive.io/r/app/#h=0&code=NobwRAdghgtgpmAXGKAHVA6ASmANGAYwHsIAXOMpMAGwEsAjAJykYE8AKAZwAtaJWAlAB0IdJiw48+rACZQe9IixnDRDZmy69+chUsYyACtQCunVSKn8AgunYiABE5O0HAXge7ui5YagBzOHsIJ1CYGXcHABUsAFUAUVxHUIdOAGs+SKEwelM4bKSQlO44KBk4RkivHwMACVLyxnYBQpTU2nL6Fir5b30ZAGUOuC6mluTQxRlWHr1lACEiaeC2p0UAD3ZSWlJqOCywAFkZjezVNvGi0OIyRiJqUdm+5QBhElI7h5Zm1pSAMyIRHIlQ81X6ADFAcCfhMnNtdvsPNlDlBgbQoNRPHBOLR-BBshNLqFOBUAG4VSJ-EwQAjbEjsPioEykXAOIjMpmkAQOEAOAC+jgEYD5AF0gA", 
    height = "800", 
    width = "100%", 
    style = "border: 1px solid rgba(0,0,0,0.175); border-radius: .375rem;", 
    allowfullscreen = "", 
    allow = "autoplay", 
    `data-external` = "1"
  ),
  full_screen = TRUE,
  style = "margin: 0 auto; float: none;"
)
```

<div class="text-center mt-4">
<a class="btn btn-primary" data-bs-toggle="collapse" href="#material-skin" role="button" aria-expanded="false" aria-controls="tabLayout">
Code
</a>
</div>

<div class="collapse" id="material-skin">
```{r, eval=FALSE}
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)

shinyApp(
   ui = dashboardPage(
     md = TRUE,
     skin = "blue",
     header = dashboardHeader(),
     sidebar = dashboardSidebar(),
     body = dashboardBody(
       box(title = "My box")
     ),
     controlbar = dashboardControlbar(),
     footer = dashboardFooter(),
     title = "Material design"
   ),
   server = function(input, output) { }
 )
```
</div>


## Fresh
[`{fresh}`](https://dreamrs.github.io/fresh/index.html) is developed by the [dreamRs](https://www.dreamrs.fr/) team. It is built on top of `{sass}`, which provides a solid R [API](https://github.com/rstudio/sass) to write SASS variables and compile into CSS. `{fresh}` captures most of the AdminLTE2 (as well as AdminLTE3 for Bootstrap 4) SASS variables to allow deep customization, hiding all the compilation burden under the hood.

`adminlte_color()` provides an interface to all available AdminLTE colors and allow to overwrite the default. I strongly suggest to avoid setting the default green to blue, as it might become confusing. Instead, it is better to play with color palettes. Similarly, `adminlte_sidebar` allows to re-style the sidebar component.
The fresh theme below is based on some cyberpunk color palettes.

```{r, eval=TRUE, echo=FALSE}
card(
  shiny::tags$iframe(
    class = "html-fill-item", 
    src = "https://shinylive.io/r/app/#h=0& ", 
    height = "800", 
    width = "100%", 
    style = "border: 1px solid rgba(0,0,0,0.175); border-radius: .375rem;", 
    allowfullscreen = "", 
    allow = "autoplay", 
    `data-external` = "1"
  ),
  full_screen = TRUE,
  style = "margin: 0 auto; float: none;"
)
```

<div class="text-center mt-4">
<a class="btn btn-primary" data-bs-toggle="collapse" href="#fresh" role="button" aria-expanded="false" aria-controls="tabLayout">
Code
</a>
</div>

<div class="collapse" id="fresh">
```{r, eval=FALSE}
library(fresh)
# create the theme with a cyberpunk color palette
theme <- create_theme(
  adminlte_color(
    green = "#3fff2d",
    blue = "#2635ff",
    red = "	#ff2b2b",
    yellow = "#feff6e",
    fuchsia = "#ff5bf8",
    navy = "#374c92",
    purple = "#615cbf",
    maroon = "#b659c9",
    light_blue = "#5691cc"
  ),
  adminlte_sidebar(
    dark_bg = "#D8DEE9",
    dark_hover_bg = "#81A1C1",
    dark_color = "#2E3440"
  ),
  adminlte_global(
    content_bg = "#aaaaaa"
  )
)

# create tribble for box global config
box_config <- tibble::tribble(
  ~background, ~labelStatus,
  "red", "warning",
  "purple", "success",
  "green", "primary",
  "yellow", "danger",
  "fuchsia", "info"
)

# box factory function
box_factory <- function(background, labelStatus) {
  box(
    title = "Cyberpunk Box", 
    collapsible = TRUE, 
    background = background,
    height = "200px",
    label = boxLabel(1, labelStatus)
  )
}

# pmap magic
boxes <- purrr::pmap(box_config, box_factory)

shinyApp(
   ui = dashboardPage(
     freshTheme = theme,
     skin = "blue",
     options = list(sidebarExpandOnHover = TRUE),
     header = dashboardHeader(
       dropdownMenu(
         type = "messages", 
         badgeStatus = "success",
         messageItem(
           from = "Support Team",
           message = "This is the content of a message.",
           time = "5 mins"
         ),
         messageItem(
           from = "Support Team",
           message = "This is the content of another message.",
           time = "2 hours"
         )
       )
     ),
     sidebar = dashboardSidebar(
       sidebarMenu(
         menuItem("Item 1", badgeLabel = icon("heart"), badgeColor = "light-blue"),
         menuItem("Item 2", badgeLabel = icon("poo"), badgeColor = "maroon")
       )
     ),
     body = dashboardBody(boxes),
     controlbar = dashboardControlbar(),
     title = "Fresh theming"
   ),
   server = function(input, output) { }
 )
```
</div>
