bslib
bslib copied to clipboard
navsets not rendering correctly with quarto
navsets are rendering correctly in rmarkdown but not quarto. The tab/pill/etc appears as plain html, regardless of which navset_*
is used.
rmarkdown
---
title: "bslib rmarkdown"
output:
html_document:
theme:
version: 5
---
```{r message = FALSE}
library(bslib)
library(ggplot2)
library(plotly)
p1 <- ggplot(mpg, aes(displ, hwy)) +
geom_point()
p2 <- ggplot(mpg, aes(cty, hwy)) +
geom_point()
navset_tab(nav_panel(title = 'one', ggplotly(p1)),
nav_panel(title = 'two', ggplotly(p2)))
```
quarto
---
title: "bslib quarto"
format: html
---
```{r message = FALSE}
library(bslib)
library(ggplot2)
library(plotly)
p1 <- ggplot(mpg, aes(displ, hwy)) +
geom_point()
p2 <- ggplot(mpg, aes(cty, hwy)) +
geom_point()
navset_tab(nav_panel(title = 'one', ggplotly(p1)),
nav_panel(title = 'two', ggplotly(p2)))
```
Versions
- bslib 0.5.1.9000
- quarto 1.3.450
Thanks for opening this issue with such a clear reprex, @kelly-sovacool! At the moment, this is a known problem and something that we're actively thinking about how to solve.
The issue stems from how bslib creates the tab HTML, which follows the syntax of older versions of Bootstrap so that we can provide backwards compatibility for Shiny apps. In bslib and shiny we solve this by aligning the CSS of newer versions of Bootstrap with the older syntax.
But Quarto uses its own version of Bootstrap and suppresses anything from bslib, so our fixes can't currently be loaded in Quarto documents.
@cpsievert I'm starting to think that the bs3compat
bundle should be a separate set of dependencies that we could attach directly to specific components, like navset_tab()
. It's also worth noting that calling bs_theme_dependencies(bs_theme(preset = "bootstrap"))
in a Quarto doc will add everything from our theme dependencies except Bootstrap, which is very specifically suppressed.
In fact, I can get pretty reasonable results by adding the following to the document (but note to anyone trying this that it loads Bootstrap twice, which isn't ideal):
bs_theme_dependencies(bs_theme(preset = "bootstrap")) |>
lapply(function(x) {
if (x$name == "bootstrap") {
x$name <- "bootstrap-from-bslib"
}
x
}) |>
htmltools::tagList()
I'm starting to think that the bs3compat bundle should be a separate set of dependencies that we could attach directly to specific components,
I agree that we should probably separate it out (and include it with the return value of bs_theme_dependencies()
). Especially since the JS for it is already in a separate HTML dependency.
I'm not sure how I feel about attaching it at the component level, though. It'd obviously be useful for getting this particular example working, but a good chunk of the bs3compat is to target HTML/components that we aren't in control of.
I was thinking/hoping that we could detect whether tabs are being created in a Quarto doc (is there something like isTRUE(getOption('knitr.in.progress'))
for Quarto?), then emit markup for BS5+ in that case. This would have the added benefit of working better with CSS written with BS5+ in mind (e.g., Bootswatch, Quarto styles, user code, etc)
Here are the options set by quarto during render: https://github.com/quarto-dev/quarto-cli/blob/749a3527a8a79ccc1f601ce1f2b62dd2b90a7528/src/resources/rmd/execute.R#L255-L279
It looks like we could rely on !is.null(knitr::opts_knit$get("quarto.version"))
as the signal that we're in the process of rendering for Quarto.
EDIT: This is only occurring within the RStudio browser. When I view in a web browser the issue resolves. Maybe need to update my version of RStudio.
I'm having the same issue with shiny when running bslib::bs_theme_preview() or when running any other bslib themed shiny app.
Is there a temporary workaround using something along the lines of @gadenbuie's quarto code?
bs_theme_dependencies(bs_theme(preset = "bootstrap")) |>
lapply(function(x) {
if (x$name == "bootstrap") {
x$name <- "bootstrap-from-bslib"
}
x
}) |>
htmltools::tagList()
I'm not sure how to include/add that to how I currently make my theme
my_theme <- function(...) {
style <- normalizePath("www/styles.scss")
theme <- bslib::bs_theme(
version = 5,
preset = "bootstrap"
)
theme <- bslib::bs_add_rules(theme, sass::sass_file(style))
theme
}