Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add option to place sidebar above main content on mobile #1088

Merged
merged 7 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* `file` is designed to accept a path to a local (server-side) file, but now recognizes remote files that start with a protocol prefix, e.g. `https://`, or two slashes, e.g. `//`. Local files are base64-encoded and embedded in the HTML output, while remote files are linked directly. To use a relative path for a file that will be served by the Shiny app, use `src` instead of file, e.g. `card_image(src = "cat.jpg")` where `cat.jpg` is stored in `www/`.
* `container` is now `NULL` by default to avoid wrapping the card image in an additional card body container and `fill` is now `FALSE` by default to avoid stretching the image. These changes makes it easier to construct [cards with image caps](https://getbootstrap.com/docs/5.3/components/card/#images).

* The `open` argument of `layout_sidebar()` now includes the option to place a sidebar that's always open on mobile screens _above the main content_ with `open = list(mobile = "always-above")`. (#1088)

## Bug fixes

Expand All @@ -31,6 +32,8 @@

* When `card_body(fillable = FALSE)`, bslib now preserves flow-layout margin bottom settings. (#1073)

* Fixed a bug in `layout_sidebar()` that caused a spurious and confusing error message. (#1081)

# bslib 0.7.0

This large release includes many improvements and bug fixes for newer UI components like `layout_columns()`, `card()`, and `sidebar()`. In addition, the new `input_task_button()` offers a drop-in replacement for `shiny::actionButton()` (to prevent multiple submissions of the same operation) as well as pairing nicely with the new `shiny::ExtendedTask` for implementing truly non-blocking operations in Shiny.
Expand Down
35 changes: 23 additions & 12 deletions R/sidebar.R
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@
#' the initial sidebar state independently for `desktop` and `mobile` screen
#' sizes. In this case, `desktop` or `mobile` can use any of the above options
#' except `"desktop"`, which is equivalent to
#' `list(desktop = "open", mobile = "closed")`.
#' `list(desktop = "open", mobile = "closed")`. You can also choose to place
#' an always open sidebar above the main content on mobile devices by setting
#' `mobile = "always-above"`.
#'
#' In `sidebar_toggle()`, `open` indicates the desired state of the sidebar,
#' where the default of `open = NULL` will cause the sidebar to be toggled
Expand Down Expand Up @@ -99,12 +101,11 @@ sidebar <- function(
gap = NULL,
padding = NULL
) {

position <- rlang::arg_match(position)
gap <- validateCssUnit(gap)
padding <- validateCssPadding(padding)
width <- validateCssUnit(width)
max_height_mobile <- validateCssUnit(max_height_mobile)
width <- validateCssUnit(width)
max_height_mobile <- validateCssUnit(max_height_mobile)

if (!is.null(open)) {
open <- as_sidebar_open_on(open)
Expand Down Expand Up @@ -167,6 +168,10 @@ as.tags.bslib_sidebar <- function(x, ...) {
open <- sidebar_open_on()
}

if (x$open$mobile == "always-above") {
x$open$mobile <- "always"
}

is_always_open <- all(vapply(x$open, identical, logical(1), "always"))

if (!is_always_open && is.null(x$id)) {
Expand Down Expand Up @@ -257,14 +262,17 @@ as_sidebar_open_on <- function(open) {

#' @param desktop,mobile The initial state of the sidebar on desktop or mobile
#' screen sizes. Can be one of `"open"` (or `TRUE`), `"closed"` (or `FALSE`),
#' or `"always"` (or `NA`).
#' or `"always"` (or `NA`). `mobile` also accepts `"always-above"`.
#' @noRd
sidebar_open_on <- function(
desktop = c("open", "closed", "always"),
mobile = c("closed", "open", "always")
desktop = "open",
mobile = "closed"
) {
desktop <- sidebar_open_as_string(desktop %||% "open")
mobile <- sidebar_open_as_string(mobile %||% "closed")
desktop <- desktop %||% "open"
mobile <- mobile %||% "closed"

desktop <- sidebar_open_as_string(desktop)
mobile <- sidebar_open_as_string(mobile, extra = "always-above")

structure(
list(desktop = desktop, mobile = mobile),
Expand Down Expand Up @@ -317,7 +325,6 @@ layout_sidebar <- function(
gap = NULL,
height = NULL
) {

if (!inherits(sidebar, "sidebar")) {
sidebar <- sidebar(sidebar)
}
Expand Down Expand Up @@ -352,7 +359,11 @@ layout_sidebar <- function(
)

main <- bindFillRole(main, container = fillable)
contents <- list(main, as.tags(sidebar))
contents <- if (sidebar$open$mobile == "always-above") {
list(as.tags(sidebar), main)
} else {
list(main, as.tags(sidebar))
}

right <- identical(sidebar$position, "right")

Expand All @@ -363,7 +374,7 @@ layout_sidebar <- function(
`data-bslib-sidebar-init` = TRUE,
`data-open-desktop` = sidebar$open$desktop,
`data-open-mobile` = sidebar$open$mobile,
`data-collapsible-mobile` = tolower(!identical(sidebar$open$mobile, "always")),
`data-collapsible-mobile` = tolower(!sidebar$open$mobile %in% c("always", "always-above")),
`data-collapsible-desktop` = tolower(!identical(sidebar$open$desktop, "always")),
`data-bslib-sidebar-border` = if (!is.null(border)) tolower(border),
`data-bslib-sidebar-border-radius` = if (!is.null(border_radius)) tolower(border_radius),
Expand Down
4 changes: 3 additions & 1 deletion man/sidebar.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading