/*-- scss:rules --*/ @import "ionrangeslider/_rules.scss"; @import "tables/_rules.scss"; $web-font-path: "https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;1,300;1,400;1,500;1,600;1,700;1,800&family=Source+Code+Pro:ital,wght@0,400;0,600;1,400;1,600&display=swap" !default; @if $web-font-path { @import url($web-font-path); } // Variables :root { --bslib-box-shadow-color-rgb: #{$bslib-box-shadow-color-rgb}; } @include color-mode(dark) { --bslib-box-shadow-color-rgb: #{$bslib-box-shadow-color-rgb-dark}; } // For radioButtons()/checkboxGroupInput(), move text slightly to the right $bslib-checkbox-radio-margin-right: 0.35em !default; .checkbox, .radio { input { margin-right: $bslib-checkbox-radio-margin-right; } } // Alignment fixes for radioButtons(inline=TRUE)/checkboxGroupInput(inline=TRUE) // TODO: It would be nice to do this for all inline groups, but that would // require updating the input markup to use
and . .shiny-input-container-inline { .shiny-options-group { display: flex; flex-wrap: wrap; flex-direction: row; column-gap: 1em; .checkbox-inline, .radio-inline { position: relative; padding-left: calc(#{$form-check-input-width} + #{$bslib-checkbox-radio-margin-right} * 2); input { position: absolute; margin-top: 0; left: 0; top: calc(#{($line-height-base - $form-check-input-width) * .5} + #{$input-btn-border-width}); } } } } // For shiny::dateRangeInput(), fix "to" width in the middle of the date picker .shiny-date-range-input .input-daterange .input-group-addon { margin-right: -1px; } // Make the default shiny::actionButton() an outline variant, but not others .btn-outline-default, .btn-default:not(.btn-primary, .btn-secondary, .btn-info, .btn-success, .btn-danger, .btn-warning, .btn-light, .btn-dark, .btn-link, [class*="btn-outline-"]) { @include button-outline-variant($secondary); } // ... and make it look better in dark mode @if $enable-dark-mode { @include color-mode(dark) { .btn-outline-default, .btn-default:not(.btn-primary, .btn-secondary, .btn-info, .btn-success, .btn-danger, .btn-warning, .btn-light, .btn-dark, .btn-link, [class*="btn-outline-"]) { @include button-outline-variant($dark-text-emphasis-dark); } } } // For selectizeInput(options = list(plugins = "remove_button")) // TODO: we should probably make this the default behavior in shiny .selectize-control.plugin-remove_button .item { align-items: flex-start !important; .remove { border-left: none !important; } } @if ($bslib-enable-shadows) { // These shadows are disabled because we use `enable-shadows: false` in the // theme to avoid enabling *all* shadows. This is why we can't use the // built-in `@include box-shadow()` mixin. // Add box-shadow & remove border from 'top-level' card()/layout_sidebar() .bslib-card { // BS doesn't include a box-shadow rule for .card when `enable-shadows: false` box-shadow: var(--bslib-card-box-shadow, #{$box-shadow-sm}); border-color: var(--bslib-card-border-color, transparent); &.bslib-value-box.default { --bslib-value-box-border-color-default: var(--bslib-card-border-color, transparent); } // Restore borders without shadows for nested cards/value boxes .bslib-card { --bslib-card-box-shadow: ; // unset our shadow --bslib-card-border-color: var(--#{$prefix}card-border-color); &.bslib-value-box.default { --bslib-value-box-border-color-default: var(--#{$prefix}card-border-color, #{$card-border-color}); } } } .bslib-card-box-shadow-sm { --bslib-card-box-shadow: var(--bslib-card-box-shadow-sm, #{$box-shadow-sm}); } .bslib-card-box-shadow-md { --bslib-card-box-shadow: var(--bslib-card-box-shadow-md, #{$box-shadow}); } .bslib-card-box-shadow-lg { --bslib-card-box-shadow: var(--bslib-card-box-shadow-lg, #{$box-shadow-lg}); } .bslib-card-box-shadow-none { --bslib-card-box-shadow: none; --bslib-card-border-color: var(--#{$prefix}card-border-color); } .popover { --#{$prefix}popover-shadow: #{$popover-box-shadow}; box-shadow: var(--#{$prefix}popover-shadow); } } // TODO: move this logic into a "core" bundle that comes with any theme // (but you only get the shadows by default in the preset theme) @if $bslib-dashboard-design { :root { --bslib-dashboard-sidebar-bg: var(--#{$prefix}body-bg); --bslib-dashboard-sidebar-main-bg: var(--#{$prefix}body-bg); --bslib-dashboard-main-bg: rgb(247, 247, 247); --#{$prefix}card-border-color: var(--bslib-dashboard-border-color-translucent, var(--#{$prefix}border-color-translucent)); --bslib-dashboard-card-header-font-weight: #{$font-weight-semibold}; --bslib-sidebar-bg: RGBA(var(--#{$prefix}body-bg-rgb), 0.05); } @include color-mode(dark) { --bslib-dashboard-main-bg: rgb(20, 20, 24); } .bslib-card { // We don't want to get in the way of $card-cap-bg, which is used by the shiny preset // when the dashboard design is disabled. This next line disables the default background // color of the card header, giving us the white card headers we want, without also // blocking inheritence via `.text-bg-{theme}` classes or others. --#{$prefix}card-cap-bg: ; .card-header, .card-footer { font-size: 0.9rem; } .card-header { font-weight: var(--bslib-dashboard-card-header-font-weight); line-height: 1.375rem; } } // Set the background color of page dashboard class with a sidebar layout... .bslib-sidebar-layout { &:has(> .bslib-page-dashboard), // or of global main content area in a page_navbar() with a global sidebar &:has(.tab-content > .bslib-page-dashboard.active) { // or of main area of a page_sidebar() --_main-bg: var(--bslib-dashboard-main-bg); ; } } // ... or `page_navbar(nav_panel(class = "bslib-page-dashboard"), sidebar = NULL)` .bslib-page-navbar .tab-content > .bslib-page-dashboard.active { background-color: var(--bslib-dashboard-main-bg); } .bslib-page-navbar, .bslib-page-dashboard { > .navbar { --bslib-navbar-default-bg: var(--#{$prefix}body-bg); --bslib-navbar-inverse-bg: var(--#{$prefix}body-color); } > .navbar + div { // Since we're using a transparent navbar, we need to (generally) add a border-top border-top: $card-border-width solid $card-border-color; // Case 1: page_navbar(sidebar = ...) // Case 2: page_navbar(nav_panel(layout_sidebar())) > .bslib-sidebar-layout, > .tab-content > .tab-pane.active.html-fill-container > .bslib-sidebar-layout.html-fill-item { border-top: none !important; // Make sure we don't end up w/ a double border } } } .bslib-page-sidebar { --bslib-page-sidebar-title-bg: var(--#{$prefix}body-bg); --bslib-page-sidebar-title-color: var(--#{$prefix}body-color); .bslib-page-title { border-color: var(--#{$prefix}border-color-translucent); } } } // By default, non-active .nav links reflect the primary color. This styling // tweak brings them closer to how they'll appear in a navbar. .nav-underline { --#{$prefix}link-color: rgba(var(--bs-body-color-rgb), 0.65); --#{$prefix}link-hover-color: rgba(var(--bs-body-color-rgb), 0.8); --#{$prefix}nav-link-font-size: 0.875rem; .nav-link { padding-left: 5px !important; padding-right: 5px !important; &.active { font-weight: 500; } } } // When the navbar is collapsed (or collapsing) on mobile, remove the // .nav-underline border .navbar-collapse.show, .navbar-collapse.collapsing { .nav-underline { --#{$prefix}nav-underline-border-width: 0; --#{$prefix}nav-underline-gap: 0; } } // Align the bottom of .nav-link w/ the bottom of the navbar (when underlined) .navbar .nav-underline .nav-link { padding-bottom: calc(var(--#{$prefix}navbar-padding-y, #{$navbar-padding-y}) * 2); margin-bottom: calc(var(--#{$prefix}navbar-padding-y, #{$navbar-padding-y}) * -1); } // For value_box(), apply a gradient to the icon (by default) $icon-classes: ("bi", "fa", "fas", "far", "fab", "material-icons") !default; .bslib-value-box.default .value-box-showcase { > i { @each $icon-class in $icon-classes { &.#{$icon-class} { background: linear-gradient(140deg, $blue 36%, $purple 180%) $blue; -webkit-background-clip: text; -webkit-text-fill-color: transparent; } } } > svg { @each $icon-class in $icon-classes { &.#{$icon-class} { // Requires icon-gradient.svg which is added in the value_box() dependency fill: url('#bslib---icon-gradient') $blue !important; } } } } // For value_box(), improve contrast of text colors .bslib-value-box { $cyan: #028097; // Contrast 4.63 $warning: #A87600; // Contrast 4 (okay for 16px+ text) &.text-info { &, &.text-cyan { --bslib-color-fg: $cyan !important; } color: $cyan !important; } &.text-light { --bslib-color-fg: $gray-600 !important; } &.text-warning { &, &.text-yellow { --bslib-color-fg: $warning !important; } color: $warning !important; } &.text-teal.text-teal { --bslib-color-fg: #008558; // Contrast 4.67 } } // Modals .modal-body, .modal-footer { padding: 1.5rem; } .modal-header .btn-close { align-self: start; display: flex; } #shiny-modal-wrapper:has( ~ .modal-backdrop) .modal { // Blur the background when the modal has a backdrop backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); } // Progress Bars & Notifications // FIXME: Use css layers (dynamic themeing issue) #shiny-notification-panel#shiny-notification-panel { position: fixed; bottom: calc(var(--bslib-spacer, 1rem) / 2); right: calc(var(--bslib-spacer, 1rem) / 2); width: 450px; z-index: $zindex-toast; } .progress-message { margin-right: .6rem; } // FIXME: Use css layers (dynamic themeing issue) .shiny-notification.shiny-notification { position: relative; opacity: 0.96; padding: 2rem; margin: var(--bslib-spacer, 1rem); border: $border-width solid var(--#{$prefix}border-color-translucent); border-radius: $card-border-radius; box-shadow: $box-shadow; .shiny-notification-close { position: absolute; font-size: 1.5em; width: 2rem; height: 2rem; top: 0; right: 0; bottom: unset; display: flex; align-items: center; justify-content: center; padding: 0.25rem; cursor: pointer; font-weight: 200; color: currentColor; &:hover { font-weight: normal; } } .shiny-notification-content-text :last-child { margin-bottom: 0; } }