Popovers

#| standalone: true
#| components: [viewer]
#| viewerHeight: 200

library(shiny)
library(bslib)

ui <- page_fluid(
  popover( 
    actionButton("show", "Click to enter name"),
    title = "A popover", 
    id = "popover", 
    placement = "right", 
    textInput("text", "Enter a name"),
    actionButton("done", "Done")
  ), 
  verbatimTextOutput("state"),
  textOutput("name")
)

server <- function(input, output, session) {
  output$state <- renderText({
    paste("Popover state:", input$popover)
  })

  output$name <- renderText({
    paste("Name:", input$text)
  })

  
  observe({
    toggle_popover("popover")
  }) |>
    bindEvent(input$done)
}

shinyApp(ui, server)
library(shiny)
library(bslib)

ui <- page_fluid(
  popover( 
    actionButton("show", "Click to enter name"),
    title = "A popover", 
    id = "popover", 
    placement = "right", 
    textInput("text", "Enter a name"),
    actionButton("done", "Done")
  ), 
  verbatimTextOutput("state"),
  textOutput("name")
)

server <- function(input, output, session) {
  output$state <- renderText({
    paste("Popover state:", input$popover)
  })

  output$name <- renderText({
    paste("Name:", input$text)
  })

  
  observe({
    toggle_popover("popover")
  }) |>
    bindEvent(input$done)
}

shinyApp(ui, server)
No matching items

Relevant Functions

  • popover
    popover(trigger, ..., title = NULL, id = NULL, placement = c("auto", "top", "right", "bottom", "left"), options = list())

  • toggle_popover
    toggle_popover(id, show = NULL, session = get_current_session())

  • update_popover
    update_popover(id, ..., title = NULL, session = get_current_session())

No matching items

Details

A popover is a panel that appears next to an element when a user clicks on the element. To add a popover to a UI component, wrap the component in bslib::popover(). Then pass popover() one or more elements to display, such as a simple string that contains a message, a bsicon, or an input widget.

Optionally assign the popover an id to trigger reactions when the popover becomes visible or to programmatically update the contents of the popover with bslib::update_popover() as your user navigates the app, or to programatically toggle the popover open or closed with bslib::toggle_popover(). A boolean that describes whether or not the popover is visible will be accessible as a reactive variable within the server function as input$<id>.

Control the placement of the popover relative to the item it highlights with the placement argument. placement defaults to 'auto', but can be set to one of 'top', 'bottom', 'left', or 'right'.

Accessibility of popover Triggers

Because the user needs to interact with the trigger element to see the popover, it’s best practice to use an element that is typically accessible via keyboard interactions, like a button or a link. If you use a non-interactive element, like a <span> or text, bslib will automatically add the tabindex="0" attribute to the trigger element to make sure that users can reach the element with the keyboard. This means that in most cases you can use any element you want as the trigger.

One place where it’s important to consider the accessibility of the trigger is when using an icon without any accompanying text. In these cases, many R packages that provide icons will create an icon element with the assumption that the icon is decorative, which will make it inaccessible to users of assistive technologies.

When using an icon as the primary trigger, ensure that the icon does not have aria-hidden="true" or role="presentation" attributes. Icon packages typically provide a way to specify a title for the icon, as well as a way to specify that the icon is not decorative. The title should be a short description of the purpose of the trigger, rather than a description of the icon itself.

If you’re using bsicons::bs_icon(), provide a title.

If you’re using fontawesome::fa(), set a11y = "sem" and provide a title.

For example:

popover(
  bsicons::bs_icon("gear", title = "Settings"),
  title = "Settings",
  sliderInput("n", "Number of points", 1, 100, 50)
)
popover(
  fontawesome::fa("gear", a11y = "sem", title = "Settings"),
  title = "Settings",
  sliderInput("n", "Number of points", 1, 100, 50)
)

Compare popovers to tooltips, which are a similar device for organizing the layout of a Shiny app.

See also