Skip to contents

Floating mascots sit in a window corner (by default, "bottom-right"), 1rem from the window edges, above fixed navigation bars and below modals. Bottom-right mascots move above Shiny notifications while they are visible. A floating mascot hides when the tab or container it was placed in hides. Inline mascots sit where mascot() is placed in the page flow. Switching back to inline returns the mascot to its original place in the UI.

Usage

mascot_placement(
  position = "bottom-right",
  ...,
  minimise = TRUE,
  drag = "none"
)

Arguments

position

A corner to float the mascot ("bottom-right", the default; "top-left", "top-right" or "bottom-left"), or "inline" to sit where the mascot is placed in the UI. NULL is not accepted.

...

Must be empty. Forces the arguments after it to be named.

minimise

A logical flag, defaulting to TRUE, to show a minimise control on a floating mascot. Has no effect inline; if you set it yourself there, a message says so, and the default gives none. NULL is not accepted.

drag

"none" (the default) for no dragging, "snap" to let visitors drag the mascot and move it to the nearest corner on release, or "free" to keep it where it is dropped, including while minimised. Experimental "free" is experimental: the position it reports and how to restore it may change. Has no effect inline; if you set it yourself there, a message says so. TRUE, FALSE and NULL are not accepted. See the Dragging section.

Value

A mascot_placement object. Its fields are internal; pass it on rather than reading them.

Details

Floating mascots show a minimise control by default; set minimise = FALSE to hide it. The neutral control appears on hover or keyboard focus. Touch screens keep it visible; an open mascot menu hides it. Its border has a quiet glow. A minimised mascot is a round restore button in the character's colours. Its status remains available to screen readers. Updates still apply, and bubble countdowns pause until it is restored. Click, Enter or Space restores the mascot. On hover or keyboard focus the restore button glows and grows slightly; with reduced motion it only glows.

Dragging

With drag = "snap" or drag = "free", visitors can drag a floating mascot by its drawing, with a mouse, pen or finger. A click without movement still opens the mascot's menu. While minimised, drag the round restore button: a click without movement restores the mascot, but a drag never restores it. After a snap, restoring shows the mascot in the new corner. The minimise button, the bubble's close button and links in the bubble do not start a drag. The bubble and menu move with the mascot.

  • "snap": on release the mascot moves to the nearest corner, which becomes its position, so its bubble opens towards the page centre. Reduced motion, or motion = FALSE, makes the move instant.

  • "free": the mascot stays where it is dropped, at least 1rem inside the window, and stays inside when the window is resized.

In Shiny each drop sets input$<id>_position, which you read in the module that owns the mascot, as with input$<id>_menu. After a snap it is the corner name, such as "top-left"; after a free drop it is a list with x and y, the mascot's top-left corner in CSS pixels from the window's top-left. A later update_mascot() with placement replaces the dragged position. Dragging has no keyboard alternative; the minimise control stays reachable by keyboard. Remembering a position between visits is the app's job: for example, save the corner and pass it back as position next time. In Shiny, minimising or restoring sets input$<id>_minimised to a logical flag in the module that owns the mascot.

Experimental free dragging

Experimental "free" is experimental: the position it reports and how to restore it may change.

Examples

mascot_placement()
#> mascot_placement()
mascot_placement("top-left")
#> mascot_placement("top-left")
mascot_placement("bottom-right", minimise = TRUE)
#> mascot_placement()
mascot_placement("bottom-right", drag = "snap")
#> mascot_placement(drag = "snap")
ui <- mascot("helper", placement = list(position = "top-left", drag = "free"))
if (FALSE) { # interactive()
shiny::shinyApp(
  shiny::fluidPage(
    mascot("helper", placement = mascot_placement("bottom-right", drag = "snap")),
    shiny::textOutput("where")
  ),
  function(input, output, session) {
    output$where <- shiny::renderText(paste("Dropped in", input$helper_position))
  }
)
}