bslib
bslib copied to clipboard
Offcanvas Element
In the documentation on popovers vs modals, you mention that offcanvas elements are on the roadmap, but I couldn't find it anywhere here on GitHub.
For an internal project I implemented a quick-and-dirty solution like this and I didn't want it to go to "waste".
Let me know if something like this is what you had in mind for an offcanvas bslib implementation.
offcanvas <- function(el,
header,
body,
header_btn_close = TRUE,
width = "600px",
position = c("start", "end", "top", "bottom"),
ns = identity) {
position <- match.arg(position)
id <- ns("offcanvas")
el <- el |>
shiny::tagAppendAttributes(
"data-bs-toggle" = "offcanvas",
"data-bs-target" = paste0("#", id),
"aria-controls" = "offcanvasExample"
)
shiny::tagList(
el,
shiny::div(
class = sprintf("offcanvas offcanvas-%s", position),
style = sprintf("width: %s;", width),
tabindex = "-1",
id = id,
shiny::div(
class = "offcanvas-header",
shiny::div(
class = "offcanvas-title",
header
),
if (header_btn_close) {
shiny::actionButton(ns("btn_close"), NULL, class = "btn-close") |>
shiny::tagAppendAttributes(
"data-bs-dismiss" = id,
"data-bs-toggle" = "offcanvas",
"aria-label" = "Close"
)
}
),
shiny::div(
class = "offcanvas-body",
body
)
)
)
}
Which you can then use like this:
library(shiny)
# source("R/offcanvas.R") # to get the function above...
offcanvas_element <- offcanvas(
width = "30vw",
position = "end",
el = actionButton("go", bsicons::bs_icon("gear")),
header = "This is an offcanvas",
body = tagList(
textInput("mytext", "Text Input"),
hr(),
actionButton("cncl", "Cancel") |>
shiny::tagAppendAttributes(
"data-bs-dismiss" = "offcanvas",
"data-bs-toggle" = "offcanvas",
"aria-label" = "Close"
)
)
)
ui <- bslib::page_fillable(
bslib::card(
bslib::card_header("My Card", offcanvas_element),
"Some content that may be affected by the offcanvas."
)
)
server <- function(input, output, session) {}
shinyApp(ui, server)
Which results in an app like this