| // Form control focus state |
| // |
| // Generate a customized focus state and for any input with the specified color, |
| // which defaults to the `$input-focus-border-color` variable. |
| // |
| // We highly encourage you to not customize the default value, but instead use |
| // this to tweak colors on an as-needed basis. This aesthetic change is based on |
| // WebKit's default styles, but applicable to a wider range of browsers. Its |
| // usability and accessibility should be taken into account with any change. |
| // |
| // Example usage: change the default blue border and shadow to white for better |
| // contrast against a dark gray background. |
| @mixin form-control-focus($ignore-warning: false) { |
| &:focus { |
| color: $input-focus-color; |
| background-color: $input-focus-bg; |
| border-color: $input-focus-border-color; |
| outline: 0; |
| @if $enable-shadows { |
| @include box-shadow($input-box-shadow, $input-focus-box-shadow); |
| } @else { |
| // Avoid using mixin so we can pass custom focus shadow properly |
| box-shadow: $input-focus-box-shadow; |
| } |
| } |
| @include deprecate("The `form-control-focus()` mixin", "v4.4.0", "v5", $ignore-warning); |
| } |
| |
| // This mixin uses an `if()` technique to be compatible with Dart Sass |
| // See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details |
| @mixin form-validation-state-selector($state) { |
| @if ($state == "valid" or $state == "invalid") { |
| .was-validated #{if(&, "&", "")}:#{$state}, |
| #{if(&, "&", "")}.is-#{$state} { |
| @content; |
| } |
| } @else { |
| #{if(&, "&", "")}.is-#{$state} { |
| @content; |
| } |
| } |
| } |
| |
| @mixin form-validation-state($state, $color, $icon) { |
| .#{$state}-feedback { |
| display: none; |
| width: 100%; |
| margin-top: $form-feedback-margin-top; |
| @include font-size($form-feedback-font-size); |
| color: $color; |
| } |
| |
| .#{$state}-tooltip { |
| position: absolute; |
| top: 100%; |
| left: 0; |
| z-index: 5; |
| display: none; |
| max-width: 100%; // Contain to parent when possible |
| padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x; |
| margin-top: .1rem; |
| @include font-size($form-feedback-tooltip-font-size); |
| line-height: $form-feedback-tooltip-line-height; |
| color: color-yiq($color); |
| background-color: rgba($color, $form-feedback-tooltip-opacity); |
| @include border-radius($form-feedback-tooltip-border-radius); |
| |
| // See https://github.com/twbs/bootstrap/pull/31557 |
| // Align tooltip to form elements |
| .form-row > .col > &, |
| .form-row > [class*="col-"] > & { |
| left: $form-grid-gutter-width * .5; |
| } |
| } |
| |
| @include form-validation-state-selector($state) { |
| ~ .#{$state}-feedback, |
| ~ .#{$state}-tooltip { |
| display: block; |
| } |
| } |
| |
| .form-control { |
| @include form-validation-state-selector($state) { |
| border-color: $color; |
| |
| @if $enable-validation-icons { |
| padding-right: $input-height-inner !important; // stylelint-disable-line declaration-no-important |
| background-image: escape-svg($icon); |
| background-repeat: no-repeat; |
| background-position: right $input-height-inner-quarter center; |
| background-size: $input-height-inner-half $input-height-inner-half; |
| } |
| |
| &:focus { |
| border-color: $color; |
| box-shadow: 0 0 0 $input-focus-width rgba($color, .25); |
| } |
| } |
| } |
| |
| // stylelint-disable-next-line selector-no-qualifying-type |
| select.form-control { |
| @include form-validation-state-selector($state) { |
| @if $enable-validation-icons { |
| padding-right: $input-padding-x * 4 !important; // stylelint-disable-line declaration-no-important |
| background-position: right $input-padding-x * 2 center; |
| } |
| } |
| } |
| |
| // stylelint-disable-next-line selector-no-qualifying-type |
| textarea.form-control { |
| @include form-validation-state-selector($state) { |
| @if $enable-validation-icons { |
| padding-right: $input-height-inner; |
| background-position: top $input-height-inner-quarter right $input-height-inner-quarter; |
| } |
| } |
| } |
| |
| .custom-select { |
| @include form-validation-state-selector($state) { |
| border-color: $color; |
| |
| @if $enable-validation-icons { |
| padding-right: $custom-select-feedback-icon-padding-right !important; // stylelint-disable-line declaration-no-important |
| background: $custom-select-background, $custom-select-bg escape-svg($icon) $custom-select-feedback-icon-position / $custom-select-feedback-icon-size no-repeat; |
| } |
| |
| &:focus { |
| border-color: $color; |
| box-shadow: 0 0 0 $input-focus-width rgba($color, .25); |
| } |
| } |
| } |
| |
| .form-check-input { |
| @include form-validation-state-selector($state) { |
| ~ .form-check-label { |
| color: $color; |
| } |
| |
| ~ .#{$state}-feedback, |
| ~ .#{$state}-tooltip { |
| display: block; |
| } |
| } |
| } |
| |
| .custom-control-input { |
| @include form-validation-state-selector($state) { |
| ~ .custom-control-label { |
| color: $color; |
| |
| &::before { |
| border-color: $color; |
| } |
| } |
| |
| &:checked { |
| ~ .custom-control-label::before { |
| border-color: lighten($color, 10%); |
| @include gradient-bg(lighten($color, 10%)); |
| } |
| } |
| |
| &:focus { |
| ~ .custom-control-label::before { |
| box-shadow: 0 0 0 $input-focus-width rgba($color, .25); |
| } |
| |
| &:not(:checked) ~ .custom-control-label::before { |
| border-color: $color; |
| } |
| } |
| } |
| } |
| |
| // custom file |
| .custom-file-input { |
| @include form-validation-state-selector($state) { |
| ~ .custom-file-label { |
| border-color: $color; |
| } |
| |
| &:focus { |
| ~ .custom-file-label { |
| border-color: $color; |
| box-shadow: 0 0 0 $input-focus-width rgba($color, .25); |
| } |
| } |
| } |
| } |
| } |