Make a click on the mascot open a menu in a Shiny app. Pass it as click to
mascot() or update_mascot(). Clicking or tapping the mascot opens the
menu, and clicking outside or pressing Escape closes it. While the menu is
open, the mascot looks towards it, on the side where it actually opened (see
"Where the menu opens" below). You provide the menu choices and handle the
selected item in your Shiny server. For a single action, use
mascot_action() instead.
Usage
mascot_popup_menu(
items = NULL,
...,
disabled = FALSE,
direction = "auto",
label = NULL,
tooltip = TRUE
)Arguments
- items
A named character vector of plain-text labels. Names are unique, non-empty item IDs without whitespace (for example
c(about = "About", help = "Help")). Defaults toNULL, which gives an empty helper; inupdate_mascot()it removes the click, so the mascot is a picture again. An empty vector is not accepted. Labels are always escaped. Withitems = NULL, settingdisabled,direction,labelortooltipyourself is an error; usemascot_popup_menu()without options to remove the click.- ...
Must be empty. Forces the arguments after it to be named.
- disabled
A flag.
TRUEkeeps the menu button reachable by keyboard, but opens nothing and sends no input. Screen readers announce it as unavailable.FALSE(the default) allows the menu to open.- direction
Which side of the mascot the menu opens on:
"auto"(the default),"top","bottom","left"or"right"."auto"picks the side with room (preferring above, then below, then the side towards the page centre). A chosen side is a preference: see "Where the menu opens" below.- label
The name screen readers announce for the mascot's menu button, such as
"Help and settings": one string that is not blank.NULL(the default) uses the character's name, such as "Tessa, menu".- tooltip
A flag.
TRUE(the default) shows the label in a tooltip when the pointer rests on the mascot or the keyboard focuses it, provided alabelis set.FALSEhides the tooltip; screen readers still announce the label.
Details
Bubble or menu? A menu lets the visitor ask the app to do something: attach
it with click = and read the choice from input$<id>_menu. For a message the
app sends to the visitor, use mascot_bubble() and update_mascot(id, bubble = ...).
Where the menu opens. The menu must fit in the space where it can show. For
an inline mascot, that space is bounded by the nearest container that scrolls
or clips (such as a bslib::card() body or a sidebar), not the whole window.
For a floating mascot, it uses the window. When the chosen direction has no
room there, the menu opens on the opposite side; when neither side has room, it
opens wherever "auto" finds space. So direction = "bottom" on a mascot near
the bottom of a card opens above it. Give the mascot room on the chosen side,
or use "auto".
Keyboard navigation. Enter or Space on the focused mascot opens or closes the menu and moves the focus to its first item; holding the key down toggles it once. After opening it with a click, the down and up arrows move from the mascot to the first or last item. Use the arrow keys, Home and End to move between items, and press Escape to close the menu and return focus to the mascot.
Reading the selection in Shiny. Choosing an item sets input$<id>_menu to
the item ID (for example, input$helper_menu for mascot("helper")).
Choosing the same item twice triggers the input twice. Opening and closing the
menu never set input$<id>_click; that input is only for mascot_action().
In a module, use ns("helper") in the UI and read input$helper_menu
inside that module's server:
helper_ui <- function(id) {
ns <- shiny::NS(id)
mascot(ns("helper"), click = mascot_popup_menu(
c(about = "About this app")))
}
helper_server <- function(id) {
shiny::moduleServer(id, function(input, output, session) {
shiny::observeEvent(input$helper_menu, {
if (input$helper_menu == "about") {
shiny::showModal(shiny::modalDialog("About this app"))
}
})
})
}
shiny::shinyApp(
shiny::fluidPage(helper_ui("demo")),
function(input, output, session) helper_server("demo")
)The menu opens next to the mascot, on the side you asked for. It is sized to fit the space on screen, and can change side or scroll when room is short. Action controls hide while the menu is open. Opening the menu closes any speech bubble that is showing. The restore button only restores a minimised mascot; it does not open the menu. On static pages the mascot stays an image. Run the Shiny example below to try the menu.
See also
mascot(), update_mascot(), mascot_action(), mascot_bubble()
Other mascot helpers:
mascot_action(),
mascot_anchors(),
mascot_bubble(),
mascot_character(),
mascot_characters(),
mascot_check_character(),
mascot_colour_roles(),
mascot_families(),
mascot_gesture(),
mascot_gestures(),
mascot_mood(),
mascot_moods(),
mascot_motion_settings(),
mascot_palettes(),
mascot_placement(),
mascot_preview(),
mascot_read_character(),
mascot_size(),
mascot_status(),
mascot_theme()
Examples
mascot_popup_menu(c(about = "About this app", help = "Help"))
#> mascot_popup_menu(c(about = "About this app", help = "Help"))
mascot_popup_menu(c(about = "About this app"), direction = "top")
#> mascot_popup_menu(c(about = "About this app"), direction = "top")
mascot_popup_menu(c(about = "About this app"), label = "Help and settings")
#> mascot_popup_menu(c(about = "About this app"), label = "Help and settings")
mascot_popup_menu(c(about = "About this app"), label = "Help and settings", tooltip = FALSE)
#> mascot_popup_menu(c(about = "About this app"), label = "Help and settings", tooltip = FALSE)
mascot_popup_menu()
#> mascot_popup_menu()
ui <- mascot("helper", click = mascot_popup_menu(c(about = "About this app")))
if (FALSE) { # interactive()
shiny::shinyApp(
shiny::fluidPage(mascot("helper", click = mascot_popup_menu(
c(about = "About this app")))),
function(input, output, session) {
shiny::observeEvent(input$helper_menu, {
shiny::showModal(shiny::modalDialog(paste("Selected", input$helper_menu)))
})
}
)
}
