Search code examples
cssrshinyshinydashboardadminlte

Style shinyWidget::dropdownButton in shinydashboard::box header


Background

I am trying to place a shinyWidget::dropdownButton in the header of a shinydashboard::box. The button should have the look and feel of the button created when using a collapsible box (box(..., collapsible = TRUE).

With the help of some JavaScript I was able to move the dropdown, which seemed to me the easier approach rather than constructing all the HTML myself.

The code below does what I want to do, however I am struggling with the css, because the elements in the dropdown are partly white on white (which makes sense I guess because they are (grand) children of class .box-tools)

What I want

I want that all controls in the dropdown look like as if I put the dropdown in the body of the box:

Dropdown in the Body

Goal: Dropdown in the body

Dropdown in the Header

Current Situation: Dropdown in the header

Questions

How can I achieve this? Which css rules do I have to use, to make sure that any kind of control looks like as if in the body of the box? Could I achieve the same behaviour even easier? (For instance by wrapping all my controls in the dropdown in another element)? I do know my basics in css but here I feel a bit at loss which rules I need to consider to get to the desired result.


Code

library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(shinyjs)

makeDropDown <- function(i) {
  dropdownButton(
    h3("Heading"),
    selectInput(paste0("sel", i), "Select:", LETTERS),
    downloadButton(paste0("down", i), "Load"),
    circle = FALSE,
    icon = icon("cog")
  )
}

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(),
  dashboardBody(
    useShinyjs(),
    box(solidHeader = TRUE,
        status = "info",
        title = "Box",
        div(
          makeDropDown(1),
          class = "box-tools pull-right",
          id = "moveme"
        ),
        makeDropDown(2)
    )
  )
)

server <- function(input, output, session) {
  runjs("$('.box-header').append($('#moveme').detach())")
}

shinyApp(ui, server)

Solution

  • You're right, some CSS rules are overwritten, you can use some inline CSS with !important to control appearance :

    makeDropDown <- function(i) {
      dropdownButton(
        tags$div(
          style = "color: black !important;", # for text
          h3("Heading"),
          selectInput(paste0("sel", i), "Select:", LETTERS),
          downloadButton(
            outputId = paste0("down", i), label = "Load", 
            style = "background-color: #f4f4f4 !important; color: #444 !important; border: 1px solid #ddd !important;" # for button
          )
        ),
        circle = FALSE,
        icon = icon("cog")
      )
    }
    

    Otherwise, maybe @DivadNojnarg have a better solution in shinydashboardPlus, I'll ask him !