Description
Background
We currently give users two ways to set the colors of a navbar: inverse = TRUE | FALSE | "auto"
and bg
. Personally, I find inverse
to be counter-intuitive and need to read the docs every time I use it:
inverse: Either
TRUE
for a light text color orFALSE
for a dark text color. If"auto"
(the default), the best contrast tobg
is chosen.
There are too many interactoins with inverse
and bg
; a much simpler interface would be to set fg
, bg
or a combination of both. That said, if the colors are being provided by the Bootstrap theme, it's burdensome to find the fully resolved CSS color when a class-based approach would be more portable (setting bg-primary
vs finding the color for $primary
).
Unfortunately, it's very hard for a user to modify the classes or attributes of the navbar, since they'll need to resort to JavaScript:
page_navbar(class = "bg-light")
#> Error in buildTabset(..., ulClass = ulClass, id = id, selected = selected) :
#> Tabs should all be unnamed arguments, but some are named: class
page_navbar(`data-bs-theme` = "dark")
#> Error in buildTabset(..., ulClass = ulClass, id = id, selected = selected) :
#> Tabs should all be unnamed arguments, but some are named: data-bs-theme
Furthermore, our choices for navbar color for Bootswatch themes often don't match the options presented on Bootswatch, leading to confusion. Here's the default navbar color we use for flatly:
and here are the options presented on Bootswatch:
In the above case, setting page_navbar(theme = bs_theme(preset = "flatly"), inverse = FALSE
achieves the first example in the list, but it's not clear how or why that works.
Ideas
With BS 5, the best way to control the navbar colors is via a combination of classes, e.g. bg-light
, bg-primary
, etc. and the data-bs-theme
attribute.
<!-- examples from bootswatch docs -->
<nav class="navbar navbar-expand-lg bg-primary" data-bs-theme="dark">
<nav class="navbar navbar-expand-lg bg-dark" data-bs-theme="dark">
<nav class="navbar navbar-expand-lg bg-light" data-bs-theme="light">
<nav class="navbar navbar-expand-lg bg-body-tertiary">
That said, we need to disambiguate between page-level attributes and those intended for the navbar.
Attributes Arguments
We could add page_attributes
and navbar_attributes
arguments that take a list (possibly created via helper functions):
page_navbar(
theme = bs_theme(preset = "flatly"),
page_attributes = list(class = "my-page-class"),
navbar_attributes = list(class = "bg-primary", "data-bs-theme" = "dark"),
# ...
)
Attributes Functions
We could add page_attributes()
and navbar_attributes()
functions that can be added anywhere as children of page_navbar()
or navset_bar()
, etc. These attributes would be collected from the page/navset children and applied to the correct part of the markup.
page_navbar(
theme = bs_theme(preset = "flatly"),
page_attributes(class = "my-page-class"),
navbar_attributes(class = "bg-primary", "data-bs-theme" = "dark"),
# ...
)
An advantage of this approach is that it could also work for py-shiny to help avoid the named-argument-last problem.
Attribute-setting Component
The API would look like the previous option, but instead of actually modifying the markup during rendering, the attribute functions would emit a component that would apply the attributes to the correct element in the client.
We've considered a similar feature (apply attributes to arbitrary selectors), but we wouldn't want users to need to know the correct selectors for these functions. We'd also have to be careful that we correctly apply these attributes to the right parent element in nested page/navset contexts.