Skip to content

page_navbar()and navset_*() functions should provide easier access to navbar attributes #940

Closed
@gadenbuie

Description

@gadenbuie

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 or FALSE for a dark text color. If "auto" (the default), the best contrast to bg 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:

image

and here are the options presented on Bootswatch:

image

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions