library("htmltools")
library("bsplus")

An accordion-sidebar can be useful to provide another dimension for your shiny apps. For example, you can use shiny navbarPage() for major groupings, then bs_accordion_sidebar() panels for minor groupings within each major grouping.

There are three functions in this family:

  • bs_accordion_sidebar(), used to establish the accordion-sidebar framework
  • bs_append(), used to add a side panel (title_side and content_side) and a main panel (content_main) to the accordion sidebar
  • bs_set_opts(), used to set options for the panel-sets to follow

The bs_accordion_sidebar() function is used to instantiate the accordion sidebar. Its argument, are a unique id, Boostrap column-specifications spec_side and spec_main, and an indication of the relative position of the side panel to the main panel.

To add a panel set to an accordion sidebar, use the bs_append() function. Its arguments are the tag of the accordion sidebar, the title_side of the side panel, which will generally be text, the content_side of the side panel, which can be HTML (might be shiny inputs), and the content_main of the main panel, which can also be HTML (might be shiny outputs).

The appearance of panel sets can be modified using the bs_set_opts() function. Its first argument is the accordion sidebar tag, its other arguments are panel_type_active and panel_type_inactive, which control the appearance of following panels, and use_main_enclosure, which, if TRUE, encloses the content of the main panel in an HTML <panel/>.

The default panel_type_active is "success", for panel_type_inactive it is "primary", the default for use_main_enclosure is TRUE.

All of these functions return an accordion tag; thus, you can build an accordion sidebar using a pipe.

bs_accordion_sidebar(id = "beatles") %>%
  bs_append(
    title_side = "John Lennon", 
    content_side = "Rhythm guitar, vocals",
    content_main = "Dear Prudence"
  ) %>%
  bs_append(
    title_side = "Paul McCartney", 
    content_side = "Bass guitar, vocals",
    content_main = "Blackbird"
  ) %>%
  bs_append(
    title_side = "George Harrison", 
    content_side = "Lead guitar, vocals",
    content_main = "While My Guitar Gently Weeps"
  ) %>%
  bs_append(
    title_side = "Ringo Starr", 
    content_side = "Drums, vocals",
    content_main = "Don't Pass Me By"
  ) 
Rhythm guitar, vocals
Bass guitar, vocals
Lead guitar, vocals
Drums, vocals
Dear Prudence
Blackbird
While My Guitar Gently Weeps
Don't Pass Me By

As you can see, the sidebar acts like a bs_accordion(), but there are a couple of important differences. First, a sidebar panel’s class changes according to its being open or not. Second, the state (show-hide) of each component’s main panel is determined by the state of its side panel.

When showing him a preview of this work, Carson Sievert asked a crazy question, “can you nest those things?” Well, apparently you can.

Note that the outer accordion-sidebar has use_main_enclosure set to FALSE, while each inner accordion-sidebar has it set to TRUE.

bs_accordion_sidebar(id = "the_beatles") %>%
  bs_set_opts(use_main_enclosure = FALSE) %>%
  bs_append(
    title_side = "John Lennon", 
    content_side = NULL,
    content_main = 
      bs_accordion_sidebar(id = "john") %>%
      bs_append(
        title_side = "Beatles",
        content_side = "1960-1969",
        content_main = "Help!"
      ) %>%
      bs_append(
        title_side = "Solo",
        content_side = "1968-1980",
        content_main = "Love"
      )
  ) %>%
  bs_append(
    title_side = "Paul McCartney", 
    content_side = NULL,
    content_main =
      bs_accordion_sidebar(id = "paul") %>%
      bs_append(
        title_side = "Beatles",
        content_side = "1960-1970",
        content_main = "Yesterday"
      ) %>%
      bs_append(
        title_side = "Solo",
        content_side = "1970-",
        content_main = "Maybe I'm Amazed"
      )
  ) %>%
  bs_append(
    title_side = "George Harrison", 
    content_side = NULL,
    content_main = 
      bs_accordion_sidebar(id = "george") %>%
      bs_append(
        title_side = "Beatles",
        content_side = "1960-1970",
        content_main = "Here Comes the Sun"
      ) %>%
      bs_append(
        title_side = "Solo",
        content_side = "1968-2001",
        content_main = "My Sweet Lord"
      )
  ) %>%
  bs_append(
    title_side = "Ringo Starr", 
    content_side = NULL,
    content_main = 
      bs_accordion_sidebar(id = "ringo") %>%
      bs_append(
        title_side = "Beatles",
        content_side = "1962-1970",
        content_main = "Octopus' Garden"
      ) %>%
      bs_append(
        title_side = "Solo",
        content_side = "1970-",
        content_main = "Photograph"
      )
  ) 
1960-1969
1968-1980
Help!
Love
1960-1970
1970-
Yesterday
Maybe I'm Amazed
1960-1970
1968-2001
Here Comes the Sun
My Sweet Lord
1962-1970
1970-
Octopus' Garden
Photograph

To use an accordion sidebar, you will need to insert some JavaScript code into your page using the use_bs_accordion_sidebar() function. You will have to do this only once per page; I have found that it works best to include after all of the accordion-sidebars are defined, perhaps as one of the last elements in a shiny UI.