Skip to content
Closed
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 @@ -3,8 +3,11 @@
## Breaking changes

* `value_box()` no longer defaults to `theme_color = "primary"`. To restore the previous behavior, please use `theme = "primary"`. In addition to the default style change, the `theme_color` is now deprecated in favor of `theme`. (#758)

* `page_navbar()` now defaults to `underline = TRUE`, meaning that navigation links in the navbar now have underline styling by default (set `underline = FALSE` to revert to previous behavior). (#784)

* `layout_column_wrap()` no longer requires `width` and `width` is no longer the first argument, meaning that `width` must be named if used. The new default is `width = "200px"`, which combines with `fixed_width = FALSE`, and produces an automatically responsive layout where each column is at least 200px wide. This means that, in most cases, `layout_column_wrap()` can layout an unknown number of items without you having to set `width`. (#799)

## New features

* Upgraded the default version of Bootstrap from v5.2.2 to v5.3.1. The most notable thing that comes with the update is the ability to toggle between light/dark [color modes](https://getbootstrap.com/docs/5.3/customize/color-modes/) purely client-side (i.e., no calls to Sass required). (#749, #764)
Expand Down
67 changes: 54 additions & 13 deletions R/layout.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
#'
#' Wraps a 1d sequence of UI elements into a 2d grid. The number of columns (and
#' rows) in the grid dependent on the column `width` as well as the size of the
#' display. For more explanation and illustrative examples, see [here](https://rstudio.github.io/bslib/articles/cards.html#multiple-cards)
#' display. For more explanation and illustrative examples, see
#' [here](https://rstudio.github.io/bslib/articles/cards.html#multiple-cards).
#'
#' @param ... Unnamed arguments should be UI elements (e.g., [card()])
#' Named arguments become attributes on the containing [htmltools::tag] element.
#' @param ... Unnamed arguments should be UI elements (e.g., [card()]). Named
#' arguments become attributes on the containing [htmltools::tag] element.
#' @param width The desired width of each card, which can be any of the
#' following:
#' * A (unit-less) number between 0 and 1.
Expand All @@ -17,9 +18,14 @@
#' * `NULL`
#' * Allows power users to set the `grid-template-columns` CSS property
#' manually, either via a `style` attribute or a CSS stylesheet.
#' @param fixed_width Whether or not to interpret the `width` as a minimum
#' (`fixed_width=FALSE`) or fixed (`fixed_width=TRUE`) width when it is a CSS
#' length unit.
#' @param fixed_width When `width` is greater than 1 or is a CSS length unit,
#' e.g. `"200px"`, `fixed_width` indicates whether that `width` value
#' represents the absolute size of each column (`fixed_width=TRUE`) or the
#' minimum size of a column (`fixed_width=FALSE`). When `fixed_width=FALSE`,
#' new columns are added to a row when `width` space is available and columns
#' will never exceed the container or viewport size. When `fixed_width=TRUE`,
#' all columns will be exactly `width` wide, which may result in columns
#' overflowing the parent container.
#' @param heights_equal If `"all"` (the default), every card in every row of the
#' grid will have the same height. If `"row"`, then every card in _each_ row
#' of the grid will have the same height, but heights may vary between rows.
Expand All @@ -31,18 +37,23 @@
#' @inheritParams card
#' @inheritParams card_body
#'
#' @export
#' @examples
#'
#' x <- card("A simple card")
#' # Always has 2 columns (on non-mobile)
#' layout_column_wrap(1/2, x, x, x)
#' # Has three columns when viewport is wider than 750px
#' layout_column_wrap("250px", x, x, x)
#' layout_column_wrap(width = 1/2, x, x, x)
#'
#' # Automatically lays out three cards into columns
#' # such that each column is at least 200px wide:
#' layout_column_wrap(x, x, x)
#'
#' # To use larger column widths by default, set `width`.
#' # This example has 3 columns when the screen is at least 900px wide:
#' layout_column_wrap(width = "300px", x, x, x)
#'
#' @export
layout_column_wrap <- function(
width,
...,
width = "200px",
fixed_width = FALSE,
heights_equal = c("all", "row"),
fill = TRUE,
Expand All @@ -59,6 +70,23 @@ layout_column_wrap <- function(
attribs <- args$attribs
children <- args$children

if (missing(width)) {
first_is_width <-
is.null(children[[1]]) ||
is_probably_a_css_unit(children[[1]])

if (first_is_width) {
# Assume an unnamed first argument that matches our expectations for
# `width` is actually the width argument, with a warning
lifecycle::deprecate_warn(
"0.6.0",
"layout_column_wrap(width = 'must be named')"
)
width <- children[[1]]
children <- children[-1]
}
}

if (length(width) > 1) {
stop("`width` of length greater than 1 is not currently supported.")
}
Expand All @@ -74,7 +102,10 @@ layout_column_wrap <- function(
if (fixed_width) {
paste0("repeat(auto-fit, ", validateCssUnit(width), ")")
} else {
paste0("repeat(auto-fit, minmax(", validateCssUnit(width), ", 1fr))")
sprintf(
"repeat(auto-fit, minmax(min(%s, 100%%), 1fr))",
validateCssUnit(width)
)
}
}
}
Expand Down Expand Up @@ -107,6 +138,16 @@ layout_column_wrap <- function(
)
}

is_probably_a_css_unit <- function(x) {
if (length(x) != 1) return(FALSE)
if (is.numeric(x)) return(TRUE)
if (!is.character(x)) return(FALSE)
tryCatch(
{ validateCssUnit(x); TRUE },
error = function(e) FALSE
)
}

#' Responsive column-based grid layouts
#'
#' Create responsive, column-based grid layouts, based on a 12-column grid.
Expand Down
Binary file modified R/sysdata.rda
Binary file not shown.
Binary file modified inst/fonts/1Ptxg8zYS_SKggPN4iEgvnHyvveLxVs9pbCIPrc.woff
Binary file not shown.
Binary file modified inst/fonts/1Ptxg8zYS_SKggPN4iEgvnHyvveLxVvaorCIPrc.woff
Binary file not shown.
Binary file modified inst/fonts/HI_diYsKILxRpg3hIP6sJ7fM7PqPMcMnZFqUwX28DBKXhM0.woff
Binary file not shown.
Binary file modified inst/fonts/HI_diYsKILxRpg3hIP6sJ7fM7PqPMcMnZFqUwX28DMyQhM0.woff
Binary file not shown.
Binary file modified inst/fonts/HI_jiYsKILxRpg3hIP6sJ7fM7PqlOPHYvDP_W9O7GQTTbI1rSg.woff
Binary file not shown.
Binary file modified inst/fonts/HI_jiYsKILxRpg3hIP6sJ7fM7PqlOPHYvDP_W9O7GQTTsoprSg.woff
Binary file not shown.
Binary file modified inst/fonts/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtZ6Ew9.woff
Binary file not shown.
Binary file modified inst/fonts/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Ew9.woff
Binary file not shown.
Binary file modified inst/fonts/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCuM70w9.woff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified inst/fonts/XRXI3I6Li01BKofiOc5wtlZ2di8HDFwmRTA.woff
Binary file not shown.
Binary file modified inst/fonts/XRXI3I6Li01BKofiOc5wtlZ2di8HDGUmRTA.woff
Binary file not shown.
Binary file modified inst/fonts/XRXI3I6Li01BKofiOc5wtlZ2di8HDLshRTA.woff
Binary file not shown.
35 changes: 23 additions & 12 deletions man/layout_column_wrap.Rd

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

4 changes: 2 additions & 2 deletions man/layout_columns.Rd

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

48 changes: 48 additions & 0 deletions tests/testthat/test-layout.R
Original file line number Diff line number Diff line change
Expand Up @@ -344,3 +344,51 @@ test_that("row_heights_css_vars() decides fr/px for numeric, passes character",
"--bslib-grid--row-heights--md:10px 1fr;"
)
})

test_that("layout_column_wrap() handles deprecated width as first arg", {
# first arg is fractional
lifecycle::expect_deprecated(
lc_implicit_width_frac <- layout_column_wrap(1/2, "one", "two")
)

expect_equal(
as.character(lc_implicit_width_frac),
as.character(layout_column_wrap(width = 1/2, "one", "two"))
)

# first arg is explicitly px character
lifecycle::expect_deprecated(
lc_implicit_width_px <- layout_column_wrap("400px", "one", "two")
)

expect_equal(
as.character(lc_implicit_width_px),
as.character(layout_column_wrap(width = "400px", "one", "two"))
)

# first arg is px, but numeric
lifecycle::expect_deprecated(
lc_implicit_width_px_implied <- layout_column_wrap(365, "one", "two")
)

expect_equal(
as.character(lc_implicit_width_px_implied),
as.character(layout_column_wrap(width = 365, "one", "two"))
)

# first arg is NULL
lifecycle::expect_deprecated(
lc_implicit_width_null <- layout_column_wrap(NULL, "one", "two")
)

expect_equal(
as.character(lc_implicit_width_null),
as.character(layout_column_wrap(width = NULL, "one", "two"))
)

# first arg is not a CSS unit
rlang::local_options(lifecycle_verbosity = "warning")
testthat::expect_silent(
as.character(layout_column_wrap("1ft", "one", "two"))
)
})