diff --git a/R/bs-theme-preset-bootswatch.R b/R/bs-theme-preset-bootswatch.R index a670ad6eb..f7a9e76a0 100644 --- a/R/bs-theme-preset-bootswatch.R +++ b/R/bs-theme-preset-bootswatch.R @@ -96,9 +96,14 @@ bootswatch_bundle <- function(bootswatch, version) { # Use local fonts (this path is relative to the bootstrap HTML dependency dir) '$web-font-path: "font.css" !default;', bootswatch_sass_file(bootswatch, "variables", version), - # Unless we change navbarPage()'s markup, BS4+ will likely want BS3 compatibility + # BS4 navbars are matched with BS3 for compatibility switch_version( - version, three = "", default = bs3compat_navbar_defaults(bootswatch) + version, + three = "", + four = bs3compat_navbar_defaults(bootswatch), + # BS5 uses more neutral defaults (navbar that flips in light/dark mode) + # or requires a bit more user input + default = list() ) ), rules = list( diff --git a/inst/bs3compat/_navbar_compat.scss b/inst/bs3compat/_navbar_compat.scss index 9322d1863..bad66a8cd 100644 --- a/inst/bs3compat/_navbar_compat.scss +++ b/inst/bs3compat/_navbar_compat.scss @@ -72,42 +72,58 @@ ul.nav.navbar-nav { } } +:root { + --bslib-navbar-light-bg: var(--bslib-navbar-default-bg, var(--#{$prefix}light)); + --bslib-navbar-dark-bg: var(--bslib-navbar-inverse-bg, var(--#{$prefix}black)); +} + +@mixin navbar-background-dark($important: false) { + background-color: var(--bslib-navbar-dark-bg) if($important, !important, null); +} + +@mixin navbar-background-light($important: false) { + background-color: var(--bslib-navbar-light-bg) if($important, !important, null); +} .navbar { // Defaults to null (and in that case, we don't want to define the CSS var) @if $navbar-light-bg { - --bslib-navbar-default-bg: #{$navbar-light-bg}; + --bslib-navbar-light-bg: #{$navbar-light-bg}; } @if $navbar-dark-bg { - --bslib-navbar-inverse-bg: #{$navbar-dark-bg}; - } - - // BS3 .navbar-default -> BS4 .navbar-light - &.navbar-default { - // Sets a variety of fg colors which are configurable via $navbar-light-* options - @extend .navbar-light; - background-color: var(--bslib-navbar-default-bg, var(--#{$prefix}light)) !important; + --bslib-navbar-dark-bg: #{$navbar-dark-bg}; } - // BS3 .navbar-inverse -> BS4 .navbar-dark - &.navbar-inverse { - // Sets a variety of fg colors which are configurable via $navbar-dark-* options - @extend .navbar-dark; - background-color: var(--bslib-navbar-inverse-bg, var(--#{$prefix}dark)) !important; - // For BS5+ lean on emphasis-color - --bs-emphasis-color: white; - --bs-emphasis-color-rgb: 255, 255, 255; + @if $bootstrap-version < 5 { + // BS3 .navbar-default -> BS4 .navbar-light + &.navbar-default { + // Sets a variety of fg colors which are configurable via $navbar-light-* options + @extend .navbar-light; + @include navbar-background-light($important: true); + } + + // BS3 .navbar-inverse -> BS4 .navbar-dark + &.navbar-inverse { + // Sets a variety of fg colors which are configurable via $navbar-dark-* options + @extend .navbar-dark; + @include navbar-background-dark($important: true); + } } } -$enable-dark-mode: false !default; -@if $enable-dark-mode { - @include color-mode(dark) { - .navbar.navbar-default { - background-color: var(--bslib-navbar-default-bg, var(--#{$prefix}dark)) !important; - } +@if $bootstrap-version >= 5 { + .navbar { + background-color: $navbar-bg; } + + [data-bs-theme="dark"] :where(.navbar) { @include navbar-background-dark(); } + [data-bs-theme="light"] :where(.navbar), :where(.navbar) { @include navbar-background-light(); } + + // These are defined *after* the above rules because we want the local version + // to win without having to resort to specificity tricks. + :where(.navbar)[data-bs-theme="dark"] { @include navbar-background-dark(); } + :where(.navbar)[data-bs-theme="light"] { @include navbar-background-light(); } } // Implement bs3 navbar toggler; used in Rmd websites, i.e. diff --git a/inst/builtin/bs5/shiny/_rules.scss b/inst/builtin/bs5/shiny/_rules.scss index 64f3316ca..64f022e9e 100644 --- a/inst/builtin/bs5/shiny/_rules.scss +++ b/inst/builtin/bs5/shiny/_rules.scss @@ -173,14 +173,15 @@ $bslib-checkbox-radio-margin-right: 0.35em !default; background-color: var(--bslib-dashboard-main-bg); } + .navbar { + // Add border-bottom for general navbars (primarily in non-bslib contexts) + border-bottom: $card-border-width solid $card-border-color; + } + .bslib-page-navbar, .bslib-page-dashboard { - > .navbar { - @if not $navbar-light-bg and not $navbar-bg { - --bslib-navbar-default-bg: var(--#{$prefix}body-bg); - } - @if not $navbar-dark-bg and not $navbar-bg { - --bslib-navbar-inverse-bg: var(--#{$prefix}body-color); - } + // Inside bslib we only add the border on the top-level navbar + .navbar { + border-bottom: none; } > .navbar + div { diff --git a/inst/builtin/bs5/shiny/_variables.scss b/inst/builtin/bs5/shiny/_variables.scss index 71d44d4d4..c7d45a002 100644 --- a/inst/builtin/bs5/shiny/_variables.scss +++ b/inst/builtin/bs5/shiny/_variables.scss @@ -148,6 +148,21 @@ $bslib-sidebar-fg: null !default; $bslib-sidebar-fg: color-contrast($bslib-sidebar-bg); } +// From inst/lib/bs5/scss/_variables.scss +// Repeated here so that we can set navbar light/dark to `--bs-body-bg` +$navbar-bg: null !default; // Background color for any navbarPage() +$navbar-light-bg: $navbar-bg !default; // Background color for navbarPage(inverse = FALSE) +$navbar-dark-bg: $navbar-bg !default; // Background color for navbarPage(inverse = TRUE) + +@if $bslib-dashboard-design and $navbar-bg == null { + @if $navbar-light-bg == null { + $navbar-light-bg: var(--#{$prefix}body-bg); + } + @if $navbar-dark-bg == null { + $navbar-dark-bg: var(--#{$prefix}body-bg); + } +} + $border-color-translucent: if($bslib-dashboard-design, rgba(40, 70, 94, 0.1), null) !default; $border-color-translucent-dark: if($bslib-dashboard-design, rgba(255, 255, 255, 0.1), null) !default; diff --git a/inst/lib/bs5/scss/_navbar.scss b/inst/lib/bs5/scss/_navbar.scss index 988bbe09c..ec497278c 100644 --- a/inst/lib/bs5/scss/_navbar.scss +++ b/inst/lib/bs5/scss/_navbar.scss @@ -3,7 +3,8 @@ // Provide a static navbar from which we expand to create full-width, fixed, and // other navbar variations. -.navbar { +.navbar, +:where([data-bs-theme="light"]) .navbar { // bslib-patched: explicitly set navbar props in light mode regions // scss-docs-start navbar-css-vars --#{$prefix}navbar-padding-x: #{if($navbar-padding-x == null, 0, $navbar-padding-x)}; --#{$prefix}navbar-padding-y: #{$navbar-padding-y}; @@ -26,7 +27,9 @@ --#{$prefix}navbar-toggler-focus-width: #{$navbar-toggler-focus-width}; --#{$prefix}navbar-toggler-transition: #{$navbar-toggler-transition}; // scss-docs-end navbar-css-vars +} +.navbar { position: relative; display: flex; display: -webkit-flex; @@ -296,6 +299,7 @@ } .navbar-dark, +:where([data-bs-theme="dark"]) .navbar, // bslib-patched: dark mode inside dark regions .navbar[data-bs-theme="dark"] { // scss-docs-start navbar-dark-css-vars --#{$prefix}navbar-color: #{$navbar-dark-color}; @@ -309,10 +313,32 @@ // scss-docs-end navbar-dark-css-vars } +:where(.navbar[data-bs-theme="dark"] .navbar-toggler-icon) { + // bslib-patched: toggler icon should follow closest navbar color mode over global mode + --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-dark-toggler-icon-bg)}; +} + @if $enable-dark-mode { @include color-mode(dark) { - .navbar-toggler-icon { + // bslib-patched: toggler follows global theme unless in a light region + :where(.navbar:not([data-bs-theme="light"]) .navbar-toggler-icon) { --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-dark-toggler-icon-bg)}; } } } + +.navbar[data-bs-theme="light"] { + // bslib-patched: Make sure local light navbar overrides page global + --#{$prefix}navbar-color: #{$navbar-light-color}; + --#{$prefix}navbar-hover-color: #{$navbar-light-hover-color}; + --#{$prefix}navbar-disabled-color: #{$navbar-light-disabled-color}; + --#{$prefix}navbar-active-color: #{$navbar-light-active-color}; + --#{$prefix}navbar-brand-color: #{$navbar-light-brand-color}; + --#{$prefix}navbar-brand-hover-color: #{$navbar-light-brand-hover-color}; + --#{$prefix}navbar-toggler-border-color: #{$navbar-light-toggler-border-color}; + + .navbar-toggler-icon { + // bslib-patched: Make sure toggler icon follows local light mode, too + --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-light-toggler-icon-bg)}; + } +} diff --git a/tools/patches/034-bs5-navbar-bg.patch b/tools/patches/034-bs5-navbar-bg.patch new file mode 100644 index 000000000..d8a57b5ca --- /dev/null +++ b/tools/patches/034-bs5-navbar-bg.patch @@ -0,0 +1,66 @@ +diff --git a/inst/lib/bs5/scss/_navbar.scss b/inst/lib/bs5/scss/_navbar.scss +index 988bbe09..ec497278 100644 +--- a/inst/lib/bs5/scss/_navbar.scss ++++ b/inst/lib/bs5/scss/_navbar.scss +@@ -3,7 +3,8 @@ + // Provide a static navbar from which we expand to create full-width, fixed, and + // other navbar variations. + +-.navbar { ++.navbar, ++:where([data-bs-theme="light"]) .navbar { // bslib-patched: explicitly set navbar props in light mode regions + // scss-docs-start navbar-css-vars + --#{$prefix}navbar-padding-x: #{if($navbar-padding-x == null, 0, $navbar-padding-x)}; + --#{$prefix}navbar-padding-y: #{$navbar-padding-y}; +@@ -26,7 +27,9 @@ + --#{$prefix}navbar-toggler-focus-width: #{$navbar-toggler-focus-width}; + --#{$prefix}navbar-toggler-transition: #{$navbar-toggler-transition}; + // scss-docs-end navbar-css-vars ++} + ++.navbar { + position: relative; + display: flex; + display: -webkit-flex; +@@ -296,6 +299,7 @@ + } + + .navbar-dark, ++:where([data-bs-theme="dark"]) .navbar, // bslib-patched: dark mode inside dark regions + .navbar[data-bs-theme="dark"] { + // scss-docs-start navbar-dark-css-vars + --#{$prefix}navbar-color: #{$navbar-dark-color}; +@@ -309,10 +313,32 @@ + // scss-docs-end navbar-dark-css-vars + } + ++:where(.navbar[data-bs-theme="dark"] .navbar-toggler-icon) { ++ // bslib-patched: toggler icon should follow closest navbar color mode over global mode ++ --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-dark-toggler-icon-bg)}; ++} ++ + @if $enable-dark-mode { + @include color-mode(dark) { +- .navbar-toggler-icon { ++ // bslib-patched: toggler follows global theme unless in a light region ++ :where(.navbar:not([data-bs-theme="light"]) .navbar-toggler-icon) { + --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-dark-toggler-icon-bg)}; + } + } + } ++ ++.navbar[data-bs-theme="light"] { ++ // bslib-patched: Make sure local light navbar overrides page global ++ --#{$prefix}navbar-color: #{$navbar-light-color}; ++ --#{$prefix}navbar-hover-color: #{$navbar-light-hover-color}; ++ --#{$prefix}navbar-disabled-color: #{$navbar-light-disabled-color}; ++ --#{$prefix}navbar-active-color: #{$navbar-light-active-color}; ++ --#{$prefix}navbar-brand-color: #{$navbar-light-brand-color}; ++ --#{$prefix}navbar-brand-hover-color: #{$navbar-light-brand-hover-color}; ++ --#{$prefix}navbar-toggler-border-color: #{$navbar-light-toggler-border-color}; ++ ++ .navbar-toggler-icon { ++ // bslib-patched: Make sure toggler icon follows local light mode, too ++ --#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-light-toggler-icon-bg)}; ++ } ++}