Skip to content

Commit

Permalink
Bootstrap 5 support (#304)
Browse files Browse the repository at this point in the history
* Init Bootstrap 5 support

* Apply navbar-bg patch to BS5

* First pass at BS3 compatibility

* Import utility classes

* Make sure utilities are imported; make note to eventually shim Tab logic (and prevent error for now)

* Get bs_themer() somewhat functional (except for colorpicker)

* Introduce $bootstrap-version Sass variable and use it for better shiming

* Resave data (GitHub Action)

* Gut stale inst/lib/bootstrap folder

* Resave data (GitHub Action)

* Reduce build noise

* Combine BS4 code style patches into one patch

* Also patch code styles in BS5

* Resave data (GitHub Action)

* Add BS5 version patch for more intelligent auto color contrasting

* Apply blockquote styling patch to BS5, too

* Apply btn-outline-* patch to BS5, too

* More consistent naming of patch files

* Translate bg utility contrast patch to BS5

* Fix bs_base_colors() bug; demo app updates for BS5 changes

* Shiny input shims

* Bootswatch cerulean bs5 patch

* Bootswatch lux bs5 patch

* Bootswatch yeti bs5 patch

* Bootswatch sketchy bs5 patch

* Bootswatch spacelab bs5 patch

* Bootswatch minty bs5 patch

* Bootswatch simplex bs5 patch

* Bootswatch cyborg bs5 patch

* Bootswatch darkly bs5 patch

* Bootswatch superhero bs5 patch

* Bootswatch materia bs5 patch

* Bootswatch slate bs5 patch

* Resave data (GitHub Action)

* Bootswatch flatly navbar bs5 patch

* Remove BS5's color-contrast() since bslib always provides one with a superset of functionality

* Restore default theme color via direct patch instead of BS3compat layer

* Fix cerulean's BS5 patch

* Get unit tests passing; R CMD check fixes

* simplify; bs3compat comments

* Resave data (GitHub Action)

* Add BS5 variables table; fix url() display values; update docs

* Update Rmd skeletons and hyperlinks to BS docs

* Ensure variables-table.R script can be found

* sr-only was renamed to visually-hidden

* update to 5.0.1; resolve Bootswatch patch conflicts

* Patch bootstrap-colorpicker to work with Bootstrap 5 method

Hopefully this patch can be removed eventually itsjavi/bootstrap-colorpicker#329

* Resave data (GitHub Action)

* Legacy nav logic needs data-bs-* prefix

* Fix skeleton tests

* Update snapshot

* set git to use LF on Windows

* Remove monkey-patch of Bootstrap to support dropup menus in fixed bottom navbars

* Don't add margin-bottom to fixed bottom navbars

* Resave data (GitHub Action)

* Fix BS4 patch for li dropdown items

* Fix tab shim for Bootstrap 5 case

* Throw warning if version = 5 is being used with older version of shiny

* bump shiny version and add to remotes (for testing)

* Document (GitHub Actions)

* bump required shiny version for nav snapshot testing

* Better legacy nav support

* Fix pkgdown workflow; update readme basic usage

* Re-build README.Rmd (GitHub Action)

* Actually fix pkgdown workflow

* Try without rprojroot

* uggh

* Add comments about data-bs-

* this is fun

* hopefully resource_files gets it working

* try again

* fix the .gitignore issue

* revert default version to Bootstrap 4

* revert/edit documentation changes as well

* revert Rd doc version changes

* Re-build README.Rmd (GitHub Action)

* Restore .navbar .active > .nav-link color rule in Bootstrap source scss since legacy navbars are effected by its removal

https://github.com/twbs/bootstrap/compare/v4.6.0...v5.0.0-beta3\#diff-79ba9b9a30350fc4b7c7b6d70d7bff6e6c67d4c9747c6a684df03ea964f27075L216

* Resave data (GitHub Action)

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
  • Loading branch information
cpsievert and cpsievert authored Jun 14, 2021
1 parent ae5e994 commit 08be7ca
Show file tree
Hide file tree
Showing 539 changed files with 21,342 additions and 797 deletions.
4 changes: 2 additions & 2 deletions .Rbuildignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
^bootswatch\.Rproj$
^\.Rproj\.user$
inst/lib/bsw/.github
inst/lib/bs-sass/assets/images/.keep
inst/lib/bsw4/.github
inst/lib/bs3/assets/images/.keep
inst/lib/bsw3/.npmignore
^inst/lib/bs-a11y-p/\.jshintrc$
^inst/lib/bs-a11y-p/\.npmignore$
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ jobs:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}

steps:
# https://github.com/actions/checkout/issues/135
- name: Set git to use LF
if: runner.os == 'Windows'
run: |
git config --system core.autocrlf false
git config --system core.eol lf
- uses: actions/checkout@v2

- uses: r-lib/actions/setup-r@master
Expand Down
8 changes: 5 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Imports:
rlang,
magrittr
Suggests:
shiny (>= 1.6.0),
shiny (>= 1.6.0.9001),
rmarkdown (>= 2.7),
thematic,
knitr,
Expand All @@ -54,9 +54,9 @@ Collate:
'deprecated.R'
'files.R'
'imports.R'
'nav-items.R'
'nav-update.R'
'navs-legacy.R'
'nav-items.R'
'navs.R'
'onLoad.R'
'page.R'
Expand All @@ -69,4 +69,6 @@ Collate:
'versions.R'
URL: https://rstudio.github.io/bslib/, https://github.com/rstudio/bslib
BugReports: https://github.com/rstudio/bslib/issues
Remotes: rstudio/htmltools
Remotes:
rstudio/htmltools,
rstudio/shiny
3 changes: 2 additions & 1 deletion R/bootswatch.R
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ theme_version <- function(theme) {
bootswatch_dist <- function(version) {
switch_version(
version,
four = lib_file("bsw", "dist"),
five = lib_file("bsw5", "dist"),
four = lib_file("bsw4", "dist"),
three = lib_file("bsw3")
)
}
2 changes: 1 addition & 1 deletion R/bs-dependencies.R
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ as_bs_theme <- function(theme) {
# Also support `bs_theme_dependencies(version = '4')` and
# `bs_theme_dependencies(theme = 'bootswatch')`
if (length(theme) == 1) {
if (theme %in% c("4", "4-3", "4+3", "3")) {
if (theme %in% c(versions(), "4-3", "4+3")) {
return(bs_theme(version = theme))
} else {
return(bs_theme(bootswatch = theme))
Expand Down
53 changes: 37 additions & 16 deletions R/bs-theme-preview.R
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,17 @@ colorpicker_deps <- function() {
)
}

opts_metadata <- function() {
jsonlite::fromJSON(
opts_metadata <- function(theme) {
opts <- jsonlite::fromJSON(
system_file("themer/options.json", package = "bslib"),
simplifyDataFrame = FALSE
)
themes <- bootswatch_themes(theme_version(theme))
opts[[1]]$bootswatch$choices <- c("default", themes)
opts
}

bs_themer_ui <- function(opts, vals) {
bs_themer_ui <- function(opts, vals, theme) {

make_control <- function(id, opts) {
value <- vals[[id]]
Expand Down Expand Up @@ -106,24 +109,40 @@ bs_themer_ui <- function(opts, vals) {
)
}

version <- theme_version(theme)
accordion <- lapply(seq_along(opts), function(i) {
opt_name <- names(opts)[[i]]
elId <- paste0("bsthemerCollapse", i)
btn <- tags$button(
class = "btn btn-link px-3 py-2 w-100 text-left border-0",
"data-toggle" = "collapse", "data-target" = paste0("#", elId),
class = if (version >= 5) "accordion-button" else "btn btn-link px-3 py-2 w-100 text-left border-0",
class = if (i != 1) "collapsed",
"data-toggle" = "collapse",
"data-target" = paste0("#", elId),
# data-bs-* is for BS5+
"data-bs-toggle" = "collapse",
"data-bs-target" = paste0("#", elId),
"aria-expanded" = "true", "aria-controls" = elId,
opt_name
)
controls <- lapply(seq_along(opts[[i]]), function(j) {
make_control(names(opts[[i]])[[j]], opts[[i]][[j]])
})
tagList(
div(class = "card-header p-0 border-0", btn),
div(
class = if (version >= 5) "accordion-item",
div(
class = if (version >= 5) "accordion-header" else "card-header p-0 border-0",
btn
),
div(
id = elId, class = if (i == 1) "show" else "collapse",
"data-parent" = "#bsthemerAccordion",
div(class = "card-body", controls)
# data-bs-* is for BS5+
"data-bs-parent" = "#bsthemerAccordion",
class = if (version >= 5) "accordion-collapse",
div(
class = if (version >= 5) "accordion-body" else "card-body",
controls
)
)
)
})
Expand Down Expand Up @@ -155,7 +174,11 @@ bs_themer_ui <- function(opts, vals) {
class = "card-header font-weight-bold bg-dark text-light px-3 py-2",
"Theme customizer",
tags$div(id = "bsthemerToggle", class = "float-right",
"data-toggle" = "collapse", "data-target" = "#bsthemerAccordion",
"data-toggle" = "collapse",
"data-target" = "#bsthemerAccordion",
# data-bs-* is for BS5+
"data-bs-toggle" = "collapse",
"data-bs-target" = "#bsthemerAccordion",
style = css(cursor = "pointer"),
tags$span(),
bs_dependency_defer(themer_css_dependency)
Expand All @@ -164,6 +187,7 @@ bs_themer_ui <- function(opts, vals) {

div(
id = "bsthemerAccordion", class = "collapse show",
class = if (version >= 5) "accordion",
style = css(overflow_y = "auto"),
accordion
)
Expand Down Expand Up @@ -220,11 +244,8 @@ themer_css_dependency <- function(theme) {
#' @examples
#' library(shiny)
#'
#' # Initialize Bootstrap 4 with Bootstrap 3 compatibility shim
#' theme <- bs_theme(version = 4, bg = "black", fg = "white")
#'
#' ui <- fluidPage(
#' theme = theme,
#' theme = bs_theme(bg = "black", fg = "white"),
#' h1("Heading 1"),
#' h2("Heading 2"),
#' p(
Expand Down Expand Up @@ -309,12 +330,12 @@ bs_themer <- function(gfonts = TRUE, gfonts_update = FALSE) {
gfont_info <- if (isTRUE(gfonts)) get_gfont_info(gfonts_update)

# Insert the theming control panel with values informed by the theme settings
themer_opts <- opts_metadata()
themer_opts <- opts_metadata(theme)
themer_vars <- unlist(unname(lapply(themer_opts, names)))
sass_vars <- setdiff(themer_vars, "bootswatch")
themer_vals <- as.list(get_themer_vals(theme, sass_vars))
themer_vals$bootswatch <- bootswatch
shiny::insertUI("body", where = "beforeEnd", ui = bs_themer_ui(themer_opts, themer_vals))
shiny::insertUI("body", where = "beforeEnd", ui = bs_themer_ui(themer_opts, themer_vals, theme))

input <- session$input

Expand Down Expand Up @@ -478,7 +499,7 @@ spinner_overlay <- function() {
class = "spinner-border",
style = "width:5rem; height:5rem; color: rgba(0,0,0,0.8);",
role = "status",
span(class = "sr-only", "Refreshing stylesheets...")
span(class = "sr-only visually-hidden", "Refreshing stylesheets...")
),
span(class = "lead mt-1", style = "color: rgba(0,0,0,0.8);", "Refreshing stylesheets...")
)
Expand Down
3 changes: 1 addition & 2 deletions R/bs-theme-update.R
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ bs_base_colors <- function(theme, bg = NULL, fg = NULL) {
args <- rename2(args, !!!get_base_color_map(theme))
}

# TODO: Bootstrap 5 will be different (no more $yiq-text-light/$yiq-text-dark)
switch_add_variables(
theme, args,
four = if (use_body) identity else bs4_base_colors,
default = if (use_body) identity else bs4_base_colors,
three = if (use_body) identity else bs3_base_colors
)
}
Expand Down
62 changes: 45 additions & 17 deletions R/bs-theme.R
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ bs_theme <- function(version = version_default(), bootswatch = NULL, ...,
success = NULL, info = NULL, warning = NULL, danger = NULL,
base_font = NULL, code_font = NULL, heading_font = NULL,
font_scale = NULL) {

if (version >= 5 && !is_available("shiny", "1.6.0.9001")) {
warning("`bs_theme(version = 5)` is designed to work with shiny v1.6.0.9001 or higher", call. = FALSE)
}

theme <- bs_bundle(
bs_theme_init(version, bootswatch),
bootstrap_bundle(version),
Expand Down Expand Up @@ -214,7 +219,7 @@ is_bs_theme <- function(x) {
# theme_version() & theme_bootswatch() search for
bs_theme_init <- function(version, bootswatch = NULL) {
add_class(
sass_bundle(),
sass_layer(defaults = list("bootstrap-version" = version)),
c(
bootswatch_class(bootswatch),
paste0("bs_version_", version),
Expand Down Expand Up @@ -250,17 +255,46 @@ color_contrast_layer <- function() {
# -----------------------------------------------------------------

bootstrap_bundle <- function(version) {
pandoc_tables <- list(
# Pandoc uses align attribute to align content but BS4 styles take precedence...
# we may want to consider adopting this more generally in "strict" BS4 mode as well
".table th[align=left] { text-align: left; }",
".table th[align=right] { text-align: right; }",
".table th[align=center] { text-align: center; }"
)

res <- switch_version(
version,
four = sass_bundle(
five = sass_bundle(
# Don't name this "core" bundle so it can't easily be removed
sass_layer(
defaults = bs5_sass_files(c("functions", "variables")),
declarations = bs5_sass_files(c("mixins", "utilities"))
),
# Returns a _named_ list of bundles (i.e., these should be easily removed)
!!!rule_bundles(
# Names here should match https://github.com/twbs/bs5/blob/master/scss/bootstrap.scss
bs5_sass_files(c(
"root", "reboot", "type", "images", "containers", "grid",
"tables", "forms", "buttons", "transitions", "dropdown",
"button-group", "nav", "navbar", "card", "accordion", "breadcrumb",
"pagination", "badge", "alert", "progress", "list-group", "close",
"toasts", "modal", "tooltip", "popover", "carousel", "spinners",
"offcanvas", "helpers", "utilities/api"
))
),
# Additions to BS5 that are always included (i.e., not a part of compatibility)
sass_layer(rules = pandoc_tables),
bs3compat = bs3compat_bundle()
),
four = sass_bundle(
sass_layer(
defaults = bs4_sass_files(c("deprecated", "functions", "variables")),
mixins = bs4_sass_files("mixins")
),
# Returns a _named_ list of bundles (i.e., these should be easily removed)
!!!rule_bundles(
# Names here should match https://github.com/twbs/bootstrap/blob/master/scss/bootstrap.scss
# Names here should match https://github.com/twbs/bs4/blob/master/scss/bootstrap.scss
bs4_sass_files(c(
"root", "reboot", "type", "images", "code", "grid", "tables",
"forms", "buttons", "transitions", "dropdown", "button-group",
Expand All @@ -271,15 +305,7 @@ bootstrap_bundle <- function(version) {
))
),
# Additions to BS4 that are always included (i.e., not a part of compatibility)
sass_layer(
rules = list(
# Pandoc uses align attribute to align content but BS4 styles take precedence...
# we may want to consider adopting this more generally in "strict" BS4 mode as well
".table th[align=left] { text-align: left; }",
".table th[align=right] { text-align: right; }",
".table th[align=center] { text-align: center; }"
)
),
sass_layer(rules = pandoc_tables),
bs3compat = bs3compat_bundle()
),
three = sass_bundle(
Expand All @@ -302,7 +328,7 @@ bootstrap_bundle <- function(version) {
glyphicon_font_files = sass_layer(
defaults = list("icon-font-path" = "'glyphicon-fonts/'"),
file_attachments = c(
"glyphicon-fonts" = lib_file("bs-sass", "assets", "fonts", "bootstrap")
"glyphicon-fonts" = lib_file("bs3", "assets", "fonts", "bootstrap")
)
)
)
Expand All @@ -319,14 +345,16 @@ bootstrap_bundle <- function(version) {
bootstrap_javascript_map <- function(version) {
switch_version(
version,
four = lib_file("bs", "dist", "js", "bootstrap.bundle.min.js.map")
five = lib_file("bs5", "dist", "js", "bootstrap.bundle.min.js.map"),
four = lib_file("bs4", "dist", "js", "bootstrap.bundle.min.js.map")
)
}
bootstrap_javascript <- function(version) {
switch_version(
version,
four = lib_file("bs", "dist", "js", "bootstrap.bundle.min.js"),
three = lib_file("bs-sass", "assets", "javascripts", "bootstrap.min.js")
five = lib_file("bs5", "dist", "js", "bootstrap.bundle.min.js"),
four = lib_file("bs4", "dist", "js", "bootstrap.bundle.min.js"),
three = lib_file("bs3", "assets", "javascripts", "bootstrap.min.js")
)
}

Expand All @@ -342,7 +370,7 @@ bs3compat_bundle <- function() {
rules = sass_file(system_file("bs3compat", "_rules.scss", package = "bslib")),
# Gyliphicon font files
file_attachments = c(
fonts = lib_file("bs-sass", "assets", "fonts")
fonts = lib_file("bs3", "assets", "fonts")
),
html_deps = htmltools::htmlDependency(
"bs3compat", packageVersion("bslib"),
Expand Down
16 changes: 13 additions & 3 deletions R/files.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,28 @@ bs4_sass_files <- function(x) {
bs_sass_files(x, version = 4)
}

bs5_sass_files <- function(x) {
bs_sass_files(x, version = 5)
}

bs_sass_files <- function(files, version) {
lapply(files, bs_sass_file, version = version)
}

# Search for one file at a time so we can throw informative errors
bs_sass_file <- function(file, version) {
if (length(file) != 1) stop("file should be of length 1")
file <- paste0("_", file, ".scss")

file <- file.path(
dirname(file),
paste0("_", basename(file), ".scss")
)

f <- switch_version(
version,
four = lib_file("bs", "scss", file),
three = lib_file("bs-sass", "assets", "stylesheets", "bootstrap", file)
five = lib_file("bs5", "scss", file),
four = lib_file("bs4", "scss", file),
three = lib_file("bs3", "assets", "stylesheets", "bootstrap", file)
)
if (f == "") stop("The bootstrap stylesheet '", file, "' doesn't exist.", call. = FALSE)
sass_file(f)
Expand Down
Loading

0 comments on commit 08be7ca

Please sign in to comment.