Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Save a dependencies.json that captures all bs_theme() (+ component-sp…
Browse files Browse the repository at this point in the history
…ecific) HTML dependencies as well as the Sass layers used to generate the relevant CSS
cpsievert committed Nov 21, 2023
1 parent ecada4b commit d273c08
Showing 16 changed files with 426 additions and 305 deletions.
89 changes: 35 additions & 54 deletions R/bs-theme.R
Original file line number Diff line number Diff line change
@@ -161,8 +161,8 @@ bs_theme <- function(
preset <- resolve_bs_preset(preset, bootswatch, version = version)

bundle <- bs_bundle(
bs_theme_init(version),
bootstrap_bundle(version),
if (version > 3) bs3compat_bundle(),
bs_preset_bundle(preset)
)

@@ -276,25 +276,12 @@ is_bs_theme <- function(x) {
inherits(x, "bs_theme")
}

# Start an empty bundle with special classes that
# theme_version() & theme_bootswatch() search for
bs_theme_init <- function(version) {
init_layer <- sass_layer(
defaults = list(
"bootstrap-version" = version,
"bslib-preset-name" = "null !default",
"bslib-preset-type" = "null !default"
),
rules = c(
":root {",
"--bslib-bootstrap-version: #{$bootstrap-version};",
"--bslib-preset-name: #{$bslib-preset-name};",
"--bslib-preset-type: #{$bslib-preset-type};",
"}"
)
)
new_bs_theme <- function(x, version) {
if (!is_sass_bundle(x)) {
stop("`theme` must be a `sass_bundle()` object")
}

add_class(init_layer, c(paste0("bs_version_", version), "bs_theme"))
add_class(x, c(paste0("bs_version_", version), "bs_theme"))
}

assert_bs_theme <- function(theme) {
@@ -309,13 +296,6 @@ assert_bs_theme <- function(theme) {
# -----------------------------------------------------------------

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; }"
)

main_bundle <- switch_version(
version,
@@ -339,13 +319,6 @@ bootstrap_bundle <- function(version) {
"toasts", "modal", "tooltip", "popover", "carousel", "spinners",
"offcanvas", "placeholders", "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(),
# Enable CSS Grid powered Bootstrap grid
sass_layer(
defaults = list("enable-cssgrid" = "true !default")
)
),
four = sass_bundle(
@@ -365,10 +338,7 @@ bootstrap_bundle <- function(version) {
"progress", "media", "list-group", "close", "toasts", "modal",
"tooltip", "popover", "carousel", "spinners", "utilities", "print"
))
),
# Additions to BS4 that are always included (i.e., not a part of compatibility)
sass_layer(rules = pandoc_tables),
bs3compat = bs3compat_bundle()
)
),
three = sass_bundle(
sass_layer(
@@ -396,10 +366,12 @@ bootstrap_bundle <- function(version) {
)
)

sass_bundle(
full_bundle <- sass_bundle(
main_bundle,
bslib_bundle()
bslib = bslib_bundle(version)
)

new_bs_theme(full_bundle, version)
}

bootstrap_javascript_map <- function(version) {
@@ -422,10 +394,16 @@ bootstrap_javascript <- function(version) {
# bslib specific Sass that gets bundled with Bootstrap
# -----------------------------------------------------------------

bslib_bundle <- function() {
# N.B. If you find yourself changing this function, be careful about what
# the implications might be for Quarto!
bslib_bundle <- function(version) {
sass_layer(
functions = sass_file(path_inst("bslib-scss", "functions.scss")),
rules = sass_file(path_inst("bslib-scss", "bslib.scss"))
defaults = list(
"bootstrap-version" = version,
sass_file(path_inst("bslib-scss", "defaults.scss"))
),
rules = sass_file(path_inst("bslib-scss", "rules.scss"))
)
}

@@ -434,21 +412,24 @@ bslib_bundle <- function() {
# -----------------------------------------------------------------

bs3compat_bundle <- function() {
sass_layer(
defaults = sass_file(system_file("bs3compat", "_defaults.scss", package = "bslib")),
mixins = sass_file(system_file("bs3compat", "_declarations.scss", package = "bslib")),
rules = sass_file(system_file("bs3compat", "_rules.scss", package = "bslib")),
# Gyliphicon font files
file_attachments = c(
fonts = path_lib("bs3", "assets", "fonts")
),
html_deps = htmltools::htmlDependency(
"bs3compat", packageVersion("bslib"),
package = "bslib",
src = "bs3compat/js",
script = c("transition.js", "tabs.js", "bs3compat.js")
sass_bundle(
bs3compat = sass_layer(
defaults = sass_file(system_file("bs3compat", "_defaults.scss", package = "bslib")),
mixins = sass_file(system_file("bs3compat", "_declarations.scss", package = "bslib")),
rules = sass_file(system_file("bs3compat", "_rules.scss", package = "bslib")),
# Gyliphicon font files
file_attachments = c(
fonts = path_lib("bs3", "assets", "fonts")
),
html_deps = htmltools::htmlDependency(
"bs3compat", packageVersion("bslib"),
package = "bslib",
src = "bs3compat/js",
script = c("transition.js", "tabs.js", "bs3compat.js")
)
)
)

}

# -----------------------------------------------------------------
25 changes: 16 additions & 9 deletions R/utils-deps.R
Original file line number Diff line number Diff line change
@@ -46,14 +46,8 @@ component_dependency_sass <- function(theme) {
}

component_dependency_sass_ <- function(theme) {
scss_dir <- path_inst("components", "scss")
scss_files <- c(
file.path(scss_dir, "mixins", "_mixins.scss"),
dir(scss_dir, pattern = "\\.scss$", full.names = TRUE)
)

# Although rare, it's possible for bs_dependency_defer() to pass
# along a NULL theme (e.g., renderTags(accordion())), so fallback
# Although rare, it's possible for bs_dependency_defer() to pass
# along a NULL theme (e.g., renderTags(accordion())), so fallback
# to the default theme if need be
theme <- theme %||% bs_theme()

@@ -65,7 +59,7 @@ component_dependency_sass_ <- function(theme) {
}

bs_dependency(
input = lapply(scss_files, sass_file),
input = component_sass_bundle(),
theme = theme,
name = "bslib-component-css",
version = get_package_version("bslib"),
@@ -75,6 +69,19 @@ component_dependency_sass_ <- function(theme) {
}


component_sass_bundle <- function() {
scss_dir <- path_inst("components", "scss")
sass_layer(
mixins = sass_file(
file.path(scss_dir, "mixins", "_mixins.scss")
),
rules = lapply(
dir(scss_dir, pattern = "\\.scss$", full.names = TRUE),
sass_file
)
)
}

web_component <- function(tagName, ...) {
deps <- component_dependencies()
args <- c(deps, rlang::list2(...))
3 changes: 0 additions & 3 deletions inst/bslib-scss/bslib.scss

This file was deleted.

74 changes: 0 additions & 74 deletions inst/bslib-scss/color-utilities.scss

This file was deleted.

9 changes: 9 additions & 0 deletions inst/bslib-scss/defaults.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Our own Sass variables that we use in our rules
$bootstrap-version: null !default; // Should always be brought in via R
$bslib-preset-name: null !default;
$bslib-preset-type: null !default;



// Bootstrap Sass defaults that we take advantage of
$enable-cssgrid: true !default;
156 changes: 156 additions & 0 deletions inst/bslib-scss/rules.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
:root {
// "Global" theming information
--bslib-bootstrap-version: #{$bootstrap-version};
--bslib-preset-name: #{$bslib-preset-name};
--bslib-preset-type: #{$bslib-preset-type};
// Controls default spacing in layout containers (e.g, layout_columns())
--bslib-spacer: #{$spacer};
--bslib-mb-spacer: var(--bslib-spacer, 1rem);
}

// ****************************************************************************
// Spacing utilities for bslib components
//
// Some things like card(), p(), inputs, etc. want some margin-bottom by default
// so you can plop them anywhere and you get spacing between rows. However, now
// that we have layout utilities like page_fillable(), layout_columns(),
// layout_sidebar(), etc. where we can control the gap between rows/columns, we
// need a way to reset those margin-bottom to 0 in those special contexts
//
// We do this by adding .bslib-mb-spacing to components like card()
// ****************************************************************************

.bslib-mb-spacing {
margin-bottom: var(--bslib-mb-spacer);
}

// ...And this class for layout containers (e.g, layout_columns())
.bslib-gap-spacing {
gap: var(--bslib-mb-spacer);
> .bslib-mb-spacing, > .form-group, > p, > pre {
margin-bottom: 0;
}
}

// We generally don't want mb spacing for _activated_ fill items
.html-fill-container > .html-fill-item.bslib-mb-spacing {
margin-bottom: 0;
}


// ****************************************************************************
// Workaround for pkgdown's CSS to make tab-pane all a consistent height
// which negatively impacts filling content in tabs
// https://github.com/r-lib/pkgdown/blob/956f07/inst/BS5/assets/pkgdown.scss#L342-L355
// ****************************************************************************

.tab-content {
>.tab-pane.html-fill-container {
display: none;
}

// Take precedence over Bootstrap's `display:block` rule
>.active.html-fill-container {
display: flex;
}

// Another workaround for pkgdown adding extra padding we didn't ask for
// https://github.com/r-lib/pkgdown/blob/956f07/inst/BS5/assets/pkgdown.scss#L335-L337
&.html-fill-container {
padding: 0;
}
}


// ****************************************************************************
// Override Bootstrap's table reboot rules which negatively impacts pandoc
// tables (which use the align attribute to align content)
// ****************************************************************************

.table {
th[align=left] { text-align: left; }
th[align=right] { text-align: right; }
th[align=center] { text-align: center; }
}

// ****************************************************************************
// Add more .bg-*, .text-*, as well as .bg-gradient-*-* utility classes.
//
// These are primarily here for `value_box(theme = "bg-purple")`, but might be
// more generally useful.
// ****************************************************************************

$bslib-enable-color-utilities: $bootstrap-version >= 5 !default;

@if ($bslib-enable-color-utilities) {
$bslib-gradient-colors: () !default;

$bslib-gradient-colors-defaults: ();
$bslib-color-names: ("blue", "indigo", "purple", "pink", "red", "orange", "yellow", "green", "teal", "cyan");

@each $name in $bslib-color-names {
@if (map-has-key($colors, $name)) {
$bslib-gradient-colors-defaults: map-merge(
$bslib-gradient-colors-defaults,
($name: map-get($colors, $name))
);
}
}

$bslib-gradient-colors: map-merge(
$bslib-gradient-colors-defaults,
$bslib-gradient-colors
);

// Named color background and foreground utility classes ---------------------
@each $name, $color in $bslib-gradient-colors {
.bg-#{$name} {
--bslib-color-bg: #{$color};
--bslib-color-fg: #{color-contrast($color)};
background-color: var(--bslib-color-bg);
color: var(--bslib-color-fg);
}

.text-#{$name} {
--bslib-color-fg: #{$color};
color: var(--bslib-color-fg);
}
}

// Fill in the `--color-*` variables
@each $name, $color in $theme-colors {
.text-#{$name} {
--bslib-color-fg: #{$color};
}
.bg-#{$name} {
--bslib-color-bg: #{$color};
--bslib-color-fg: #{color-contrast($color)};
}
}

// Gradient backgrounds ------------------------------------------------------
//
// Creates gradient background for every named color pair. Users can add
// additional colors into the mix by setting $bslib-gradient-colors to a map of
// color names to colors. Creates class names like: .bg-gradient-{from}-{to}.
@each $name1, $color1 in $bslib-gradient-colors {
@each $name2, $color2 in $bslib-gradient-colors {
@if $name1 != $name2 {
.bg-gradient-#{$name1}-#{$name2} {
$color-mid: mix($color1, $color2, 60%);
$color-fg: color-contrast($color-mid);

--bslib-color-fg: #{$color-fg};
--bslib-color-bg: #{$color-mid};

background: linear-gradient(
var(--bg-gradient-deg, 140deg),
$color1 var(--bg-gradient-start, 36%),
$color2 var(--bg-gradient-end, 180%)
) $color-mid;
color: $color-fg;
}
}
}
}
}
31 changes: 0 additions & 31 deletions inst/bslib-scss/spacer.scss

This file was deleted.

18 changes: 0 additions & 18 deletions inst/bslib-scss/tab-fill.scss

This file was deleted.

1 change: 0 additions & 1 deletion inst/css-precompiled/3/bootstrap.min.css

This file was deleted.

1 change: 0 additions & 1 deletion inst/css-precompiled/4/bootstrap.min.css

This file was deleted.

4 changes: 2 additions & 2 deletions inst/css-precompiled/5/bootstrap.min.css

Large diffs are not rendered by default.

67 changes: 0 additions & 67 deletions inst/css-precompiled/5/bootstrap.scss

This file was deleted.

96 changes: 96 additions & 0 deletions inst/css-precompiled/5/dependencies.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
[
{
"name": "jquery",
"version": "3.6.0",
"src": {
"file": "/Users/cpsievert/R/4.3/jquerylib/lib/3.6.0"
},
"script": "jquery-3.6.0.min.js",
"all_files": true
},
{
"name": "bootstrap",
"version": "5.3.1",
"src": {
"file": "/var/folders/t8/jxw4bftj35g15fcb6m4mfbc80000gn/T//RtmpCAptIJ/bslib-1102751e422cb"
},
"meta": {
"viewport": "width=device-width, initial-scale=1, shrink-to-fit=no"
},
"script": "bootstrap.bundle.min.js",
"stylesheet": "bootstrap.min.css",
"all_files": true,
"sass_layers": {
"bootstrap": {
"functions": "@import \"lib/bs5/scss/_functions.scss\";",
"defaults": ["", "", "", "@import \"lib/bs5/scss/_variables.scss\";", "@import \"lib/bs5/scss/_variables-dark.scss\";"],
"mixins": ["@import \"lib/bs5/scss/_maps.scss\";", "@import \"lib/bs5/scss/_mixins.scss\";"],
"rules": ["@import \"lib/bs5/scss/mixins/_banner.scss\";", "@include bsBanner('')", "@import \"lib/bs5/scss/_utilities.scss\";", "@import \"lib/bs5/scss/_root.scss\";", "@import \"lib/bs5/scss/_reboot.scss\";", "@import \"lib/bs5/scss/_type.scss\";", "@import \"lib/bs5/scss/_images.scss\";", "@import \"lib/bs5/scss/_containers.scss\";", "@import \"lib/bs5/scss/_grid.scss\";", "@import \"lib/bs5/scss/_tables.scss\";", "@import \"lib/bs5/scss/_forms.scss\";", "@import \"lib/bs5/scss/_buttons.scss\";", "@import \"lib/bs5/scss/_transitions.scss\";", "@import \"lib/bs5/scss/_dropdown.scss\";", "@import \"lib/bs5/scss/_button-group.scss\";", "@import \"lib/bs5/scss/_nav.scss\";", "@import \"lib/bs5/scss/_navbar.scss\";", "@import \"lib/bs5/scss/_card.scss\";", "@import \"lib/bs5/scss/_accordion.scss\";", "@import \"lib/bs5/scss/_breadcrumb.scss\";", "@import \"lib/bs5/scss/_pagination.scss\";", "@import \"lib/bs5/scss/_badge.scss\";", "@import \"lib/bs5/scss/_alert.scss\";", "@import \"lib/bs5/scss/_progress.scss\";", "@import \"lib/bs5/scss/_list-group.scss\";", "@import \"lib/bs5/scss/_close.scss\";", "@import \"lib/bs5/scss/_toasts.scss\";", "@import \"lib/bs5/scss/_modal.scss\";", "@import \"lib/bs5/scss/_tooltip.scss\";", "@import \"lib/bs5/scss/_popover.scss\";", "@import \"lib/bs5/scss/_carousel.scss\";", "@import \"lib/bs5/scss/_spinners.scss\";", "@import \"lib/bs5/scss/_offcanvas.scss\";", "@import \"lib/bs5/scss/_placeholders.scss\";", "@import \"lib/bs5/scss/_helpers.scss\";", "@import \"lib/bs5/scss/utilities/_api.scss\";"]
},
"bslib": {
"functions": "@import \"bslib-scss/functions.scss\";",
"defaults": ["$bootstrap-version: 5;", "@import \"bslib-scss/defaults.scss\";"],
"rules": "@import \"bslib-scss/rules.scss\";"
},
"bs3compat": {
"defaults": "@import \"bs3compat/_defaults.scss\";",
"mixins": "@import \"bs3compat/_declarations.scss\";",
"rules": "@import \"bs3compat/_rules.scss\";",
"file_attachments": "lib/bs3/assets/fonts"
},
"builtin": {
"defaults": ["$bslib-preset-type: builtin;", "$bslib-preset-name: shiny;", "$web-font-path: \"font.css\" !default;", "@import \"builtin/bs5/shiny/_variables.scss\";"],
"mixins": "@import \"builtin/bs5/shiny/_mixins.scss\";",
"rules": "@import \"builtin/bs5/shiny/_rules.scss\";",
"file_attachments": ["builtin/bs5/shiny/font.css", "fonts"]
}
}
},
{
"name": "bs3compat",
"version": "0.5.1.9000",
"src": {
"file": "bs3compat/js"
},
"script": ["transition.js", "tabs.js", "bs3compat.js"],
"all_files": true
},
{
"name": "bslib-component-js",
"version": "0.5.1.9000",
"src": {
"file": "components/dist"
},
"script": [
{
"src": "components.min.js"
},
{
"src": "web-components.min.js",
"type": "module"
}
],
"all_files": true
},
{
"name": "bslib-component-css",
"version": "0.5.1.9000",
"src": {
"file": "/var/folders/t8/jxw4bftj35g15fcb6m4mfbc80000gn/T//RtmpCAptIJ/bslib-component-css11027181e5294"
},
"stylesheet": "bslib-component-css.min.css",
"all_files": true,
"sass_layer": {
"bslib_components": {
"mixins": "@import \"components/scss/mixins/_mixins.scss\";",
"rules": ["@import \"components/scss/accordion.scss\";", "@import \"components/scss/card.scss\";", "@import \"components/scss/grid.scss\";", "@import \"components/scss/nav_spacer.scss\";", "@import \"components/scss/page_fillable.scss\";", "@import \"components/scss/page_navbar.scss\";", "@import \"components/scss/page_sidebar.scss\";", "@import \"components/scss/sidebar.scss\";", "@import \"components/scss/value_box.scss\";"]
},
"bootstrap_headers": {
"functions": ["@import \"lib/bs5/scss/_functions.scss\";", "@import \"bslib-scss/functions.scss\";"],
"defaults": ["", "", "", "$bslib-preset-type: builtin;", "$bslib-preset-name: shiny;", "$web-font-path: \"font.css\" !default;", "@import \"builtin/bs5/shiny/_variables.scss\";", "@import \"bs3compat/_defaults.scss\";", "$bootstrap-version: 5;", "@import \"bslib-scss/defaults.scss\";", "@import \"lib/bs5/scss/_variables.scss\";", "@import \"lib/bs5/scss/_variables-dark.scss\";"],
"mixins": ["@import \"lib/bs5/scss/_maps.scss\";", "@import \"lib/bs5/scss/_mixins.scss\";", "@import \"bs3compat/_declarations.scss\";", "@import \"builtin/bs5/shiny/_mixins.scss\";"],
"file_attachments": ["lib/bs3/assets/fonts", "builtin/bs5/shiny/font.css", "fonts"]
}
}
}
]
12 changes: 0 additions & 12 deletions tools/compile_component_sass.R

This file was deleted.

3 changes: 1 addition & 2 deletions tools/main.R
Original file line number Diff line number Diff line change
@@ -8,8 +8,7 @@ lapply(c(
"yarn_install.R",
"download_preset_fonts.R",
"update_gfont_info.R",
"expand_variables_article_template.R",
"compile_component_sass.R"
"expand_variables_article_template.R"
), function(file) {
message("Updating: ", file)
source(file.path("tools", file), local = TRUE)
142 changes: 111 additions & 31 deletions tools/yarn_install.R
Original file line number Diff line number Diff line change
@@ -402,49 +402,129 @@ unlink("inst/yarn.lock")
unlink("inst/node_modules", recursive = TRUE)

# ----------------------------------------------------------------------
# Precompile Bootstrap CSS
# Generate distributed (i.e., pre-compiled) CSS & JS assets
# ----------------------------------------------------------------------

# This generates precompiled builds of Bootstrap's css. It would be nice to do
# it at binary package build time, but I couldn't get that to work, using either
# src/install.libs.R (because the bslib functions used in this script
# aren't available yet), or by putting this code directly in the R/ directory
# (because the R/ files are evaluated only after the inst directory is copied
# over).
library(bslib)

precompiled_dir <- find_package_root_file("inst/css-precompiled")
unlink(precompiled_dir, recursive = TRUE)
dir.create(precompiled_dir, recursive = TRUE)

invisible(lapply(versions(), function(version) {
res <- bs_theme_dependencies(
bs_theme(version), precompiled = FALSE,

# -------------------------------------------------------------------------
# Get all the HTML dependencies (compiles Sass -> CSS)
# -------------------------------------------------------------------------
theme <- bs_theme(version)
deps <- bs_theme_dependencies(
theme, precompiled = FALSE,
sass_options = sass_options(output_style = "compressed"),
cache = NULL
)
# Extract the Bootstrap dependency object (as opposed to, say, jQuery)
bs_dep <- Filter(res, f = function(x) { identical(x$name, "bootstrap") })[[1]]

tmp_css <- file.path(bs_dep$src$file, bs_dep$stylesheet)
dest_dir <- file.path(precompiled_dir, version)
if (!dir.exists(dest_dir)) {
dir.create(dest_dir)
# -------------------------------------------------------------------------
# Save Bootstrap CSS to disk
# -------------------------------------------------------------------------
save_bootstrap_css <- function(deps) {
bs_idx <- which(vapply(deps, function(x) { identical(x$name, "bootstrap") }, logical(1)))
bs_dep <- deps[[bs_idx]]
tmp_css <- file.path(bs_dep$src$file, bs_dep$stylesheet)
dest_dir <- file.path(precompiled_dir, version)
if (!dir.exists(dest_dir)) {
dir.create(dest_dir)
}
file.copy(tmp_css, dest_dir, overwrite = TRUE)
}
save_bootstrap_css(deps)


# -------------------------------------------------------------------------
# What follows below is only supported for Bootstrap 5+
# -------------------------------------------------------------------------
if (version < 5) return()

# -------------------------------------------------------------------------
# Compile and save bslib component CSS to disk
# TODO: save a CSS file for every version >= 5?
# -------------------------------------------------------------------------
save_component_css <- function(theme) {
dep <- component_dependency_sass_(theme)
css <- file.path(dep$src, dep$stylesheet)
target_dir <- path_inst("components", "dist")
target_css <- file.path(target_dir, "components.css")
file.copy(css, target_css, overwrite = TRUE)
}
file.copy(tmp_css, dest_dir)

# Also save the BS5+ Sass code used to generate the pre-compiled CSS.
# This is primarily here to help Quarto more easily replicate bs_theme()'s Sass.
if (version >= 5) {
theme_sass <- gsub(
paste0("@import \"", getwd(), "/"),
"@import \"",
as_sass(bs_theme(version))
save_component_css(theme)

# -------------------------------------------------------------------------
# Quarto has a build-time dependency on bslib which pulls in it's modified
# Bootstrap source as well as (potentially) other Sass layers we add such as
# bslib, bs3compat, builtin (preset)...
#
# This function gets us a (simplified) data structure representing the Sass
# layers involved (so Quarto can ingest it)
# ------------------------------------------------------------------------
simplified_theme_layers <- function(theme) {
nms <- names(theme$layers)
# Assumes layers that are unnamed or start with '_' are Bootstrap...
bs_idx <- grepl("^_", nms) | nms == ""
bs_layers <- theme$layers[bs_idx]
other_layers <- theme$layers[!bs_idx]

bs_bundle <- sass_bundle(
bootstrap = as_sass_layer(sass_bundle(!!!bs_layers))
)
writeLines(theme_sass, file.path(dest_dir, "bootstrap.scss"))
# Sanity check that we we can compile by moving file to home dir
file.copy(file.path(dest_dir, "bootstrap.scss"), "bootstrap.scss")
on.exit(unlink("bootstrap.scss"), add = TRUE)
testthat::expect_error(sass(sass_file("bootstrap.scss")), NA)

bundle <- sass_bundle(bs_bundle, !!!other_layers)

as_serializable_bundle(bundle)
}

as_serializable_bundle <- function(bundle) {
lapply(bundle$layers, function(layer) {
# These html_deps will surface through deps, so drop them
layer$html_deps <- NULL
layer <- layer[lengths(layer) > 0]
lapply(layer, function(x) {
x <- gsub(
file.path(getwd(), "inst/"),
"",
as_sass(x)
)
strsplit(x, "\n")[[1]]
})
})
}

# -------------------------------------------------------------------------
# Save a JSON representation of the 'global' and 'component' HTML deps
#
# As well, this JSON representation includes any Sass layers used to
# create 'pre-compiled' stylesheets
# -------------------------------------------------------------------------

component_deps <- htmltools::resolveDependencies(component_dependencies())
deps <- c(deps, component_deps)

deps <- lapply(deps, function(d) {
d <- dropNulls(d)
d$src$file <- gsub(file.path(getwd(), "inst/"), "", d$src$file)
if (d$name == "bootstrap") {
d$sass_layers <- simplified_theme_layers(theme)
}
if (d$name == "bslib-component-css") {
# Essentially what sass_partial() does
headers <- as_sass_layer(theme)
headers$rules <- NULL
d$sass_layer <- as_serializable_bundle(sass_bundle(
bslib_components = component_sass_bundle(),
bootstrap_headers = headers
))
}
d
})

cat(
jsonlite::toJSON(deps, force = TRUE, pretty = TRUE, auto_unbox = TRUE),
file = file.path(precompiled_dir, version, "dependencies.json")
)
}))

0 comments on commit d273c08

Please sign in to comment.