bootstrap 4.0.0 → 4.6.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +15 -1
  3. data/CHANGELOG.md +4 -4
  4. data/README.md +8 -2
  5. data/Rakefile +18 -4
  6. data/assets/javascripts/bootstrap/alert.js +77 -66
  7. data/assets/javascripts/bootstrap/button.js +138 -76
  8. data/assets/javascripts/bootstrap/carousel.js +289 -152
  9. data/assets/javascripts/bootstrap/collapse.js +150 -128
  10. data/assets/javascripts/bootstrap/dropdown.js +249 -160
  11. data/assets/javascripts/bootstrap/modal.js +280 -199
  12. data/assets/javascripts/bootstrap/popover.js +99 -58
  13. data/assets/javascripts/bootstrap/scrollspy.js +123 -102
  14. data/assets/javascripts/bootstrap/tab.js +110 -98
  15. data/assets/javascripts/bootstrap/toast.js +267 -0
  16. data/assets/javascripts/bootstrap/tooltip.js +401 -183
  17. data/assets/javascripts/bootstrap/util.js +106 -55
  18. data/assets/javascripts/bootstrap-sprockets.js +7 -6
  19. data/assets/javascripts/bootstrap.js +1903 -1441
  20. data/assets/javascripts/bootstrap.min.js +4 -4
  21. data/assets/stylesheets/_bootstrap-grid.scss +6 -8
  22. data/assets/stylesheets/_bootstrap-reboot.scss +4 -4
  23. data/assets/stylesheets/_bootstrap.scss +6 -4
  24. data/assets/stylesheets/bootstrap/_alert.scss +2 -1
  25. data/assets/stylesheets/bootstrap/_badge.scss +8 -1
  26. data/assets/stylesheets/bootstrap/_breadcrumb.scss +10 -6
  27. data/assets/stylesheets/bootstrap/_button-group.scss +17 -20
  28. data/assets/stylesheets/bootstrap/_buttons.scss +20 -21
  29. data/assets/stylesheets/bootstrap/_card.scss +77 -61
  30. data/assets/stylesheets/bootstrap/_carousel.scss +72 -63
  31. data/assets/stylesheets/bootstrap/_close.scss +14 -8
  32. data/assets/stylesheets/bootstrap/_code.scss +6 -14
  33. data/assets/stylesheets/bootstrap/_custom-forms.scss +274 -45
  34. data/assets/stylesheets/bootstrap/_dropdown.scss +70 -9
  35. data/assets/stylesheets/bootstrap/_forms.scss +56 -42
  36. data/assets/stylesheets/bootstrap/_functions.scss +117 -13
  37. data/assets/stylesheets/bootstrap/_grid.scss +32 -11
  38. data/assets/stylesheets/bootstrap/_images.scss +4 -4
  39. data/assets/stylesheets/bootstrap/_input-group.scss +68 -16
  40. data/assets/stylesheets/bootstrap/_jumbotron.scss +2 -1
  41. data/assets/stylesheets/bootstrap/_list-group.scss +63 -24
  42. data/assets/stylesheets/bootstrap/_mixins.scss +9 -4
  43. data/assets/stylesheets/bootstrap/_modal.scss +96 -24
  44. data/assets/stylesheets/bootstrap/_nav.scss +14 -7
  45. data/assets/stylesheets/bootstrap/_navbar.scss +64 -43
  46. data/assets/stylesheets/bootstrap/_pagination.scss +7 -10
  47. data/assets/stylesheets/bootstrap/_popover.scss +55 -68
  48. data/assets/stylesheets/bootstrap/_print.scss +24 -16
  49. data/assets/stylesheets/bootstrap/_progress.scss +20 -6
  50. data/assets/stylesheets/bootstrap/_reboot.scss +88 -86
  51. data/assets/stylesheets/bootstrap/_spinners.scss +65 -0
  52. data/assets/stylesheets/bootstrap/_tables.scss +19 -14
  53. data/assets/stylesheets/bootstrap/_toasts.scss +46 -0
  54. data/assets/stylesheets/bootstrap/_tooltip.scss +5 -5
  55. data/assets/stylesheets/bootstrap/_transitions.scss +10 -20
  56. data/assets/stylesheets/bootstrap/_type.scss +19 -19
  57. data/assets/stylesheets/bootstrap/_utilities.scss +4 -0
  58. data/assets/stylesheets/bootstrap/_variables.scss +462 -207
  59. data/assets/stylesheets/bootstrap/mixins/_background-variant.scss +5 -3
  60. data/assets/stylesheets/bootstrap/mixins/_badge.scss +8 -3
  61. data/assets/stylesheets/bootstrap/mixins/_border-radius.scss +51 -10
  62. data/assets/stylesheets/bootstrap/mixins/_box-shadow.scss +16 -1
  63. data/assets/stylesheets/bootstrap/mixins/_breakpoints.scss +3 -3
  64. data/assets/stylesheets/bootstrap/mixins/_buttons.scss +20 -19
  65. data/assets/stylesheets/bootstrap/mixins/_caret.scss +13 -16
  66. data/assets/stylesheets/bootstrap/mixins/_deprecate.scss +10 -0
  67. data/assets/stylesheets/bootstrap/mixins/_float.scss +6 -3
  68. data/assets/stylesheets/bootstrap/mixins/_forms.scss +96 -38
  69. data/assets/stylesheets/bootstrap/mixins/_gradients.scss +7 -7
  70. data/assets/stylesheets/bootstrap/mixins/_grid-framework.scss +31 -18
  71. data/assets/stylesheets/bootstrap/mixins/_grid.scss +34 -17
  72. data/assets/stylesheets/bootstrap/mixins/_hover.scss +7 -9
  73. data/assets/stylesheets/bootstrap/mixins/_image.scss +4 -4
  74. data/assets/stylesheets/bootstrap/mixins/_list-group.scss +2 -2
  75. data/assets/stylesheets/bootstrap/mixins/_lists.scss +1 -1
  76. data/assets/stylesheets/bootstrap/mixins/_nav-divider.scss +3 -2
  77. data/assets/stylesheets/bootstrap/mixins/_pagination.scss +1 -1
  78. data/assets/stylesheets/bootstrap/mixins/_reset-text.scss +3 -3
  79. data/assets/stylesheets/bootstrap/mixins/_screen-reader.scss +5 -6
  80. data/assets/stylesheets/bootstrap/mixins/_size.scss +1 -0
  81. data/assets/stylesheets/bootstrap/mixins/_table-row.scss +11 -2
  82. data/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss +7 -4
  83. data/assets/stylesheets/bootstrap/mixins/_text-hide.scss +3 -1
  84. data/assets/stylesheets/bootstrap/mixins/_transition.scss +20 -3
  85. data/assets/stylesheets/bootstrap/mixins/_visibility.scss +1 -0
  86. data/assets/stylesheets/bootstrap/utilities/_background.scss +2 -2
  87. data/assets/stylesheets/bootstrap/utilities/_borders.scss +17 -1
  88. data/assets/stylesheets/bootstrap/utilities/_display.scss +6 -18
  89. data/assets/stylesheets/bootstrap/utilities/_embed.scss +7 -20
  90. data/assets/stylesheets/bootstrap/utilities/_flex.scss +5 -0
  91. data/assets/stylesheets/bootstrap/utilities/_float.scss +5 -3
  92. data/assets/stylesheets/bootstrap/utilities/_interactions.scss +5 -0
  93. data/assets/stylesheets/bootstrap/utilities/_overflow.scss +5 -0
  94. data/assets/stylesheets/bootstrap/utilities/_position.scss +0 -4
  95. data/assets/stylesheets/bootstrap/utilities/_shadows.scss +6 -0
  96. data/assets/stylesheets/bootstrap/utilities/_sizing.scss +8 -0
  97. data/assets/stylesheets/bootstrap/utilities/_spacing.scss +23 -1
  98. data/assets/stylesheets/bootstrap/utilities/_stretched-link.scss +19 -0
  99. data/assets/stylesheets/bootstrap/utilities/_text.scss +28 -8
  100. data/assets/stylesheets/bootstrap/utilities/_visibility.scss +4 -2
  101. data/assets/stylesheets/bootstrap/vendor/_rfs.scss +228 -0
  102. data/bootstrap.gemspec +5 -4
  103. data/lib/bootstrap/engine.rb +19 -0
  104. data/lib/bootstrap/version.rb +4 -2
  105. data/lib/bootstrap.rb +10 -7
  106. data/tasks/updater/js.rb +18 -6
  107. data/tasks/updater/network.rb +8 -2
  108. data/test/dummy_rails/app/assets/config/manifest.js +3 -0
  109. data/test/dummy_rails/app/assets/stylesheets/.browserslistrc +1 -0
  110. data/test/gemfiles/rails_6_0.gemfile +7 -0
  111. data/test/gemfiles/rails_7_0_dartsass.gemfile +8 -0
  112. data/test/gemfiles/rails_7_0_sassc.gemfile +8 -0
  113. data/test/support/dummy_rails_integration.rb +3 -1
  114. data/test/test_helper.rb +21 -15
  115. metadata +28 -25
  116. data/assets/stylesheets/bootstrap/mixins/_navbar-align.scss +0 -10
@@ -2,20 +2,22 @@
2
2
 
3
3
  // Contextual backgrounds
4
4
 
5
- @mixin bg-variant($parent, $color) {
5
+ @mixin bg-variant($parent, $color, $ignore-warning: false) {
6
6
  #{$parent} {
7
7
  background-color: $color !important;
8
8
  }
9
9
  a#{$parent},
10
10
  button#{$parent} {
11
- @include hover-focus {
11
+ @include hover-focus() {
12
12
  background-color: darken($color, 10%) !important;
13
13
  }
14
14
  }
15
+ @include deprecate("The `bg-variant` mixin", "v4.4.0", "v5", $ignore-warning);
15
16
  }
16
17
 
17
- @mixin bg-gradient-variant($parent, $color) {
18
+ @mixin bg-gradient-variant($parent, $color, $ignore-warning: false) {
18
19
  #{$parent} {
19
20
  background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important;
20
21
  }
22
+ @include deprecate("The `bg-gradient-variant` mixin", "v4.5.0", "v5", $ignore-warning);
21
23
  }
@@ -2,11 +2,16 @@
2
2
  color: color-yiq($bg);
3
3
  background-color: $bg;
4
4
 
5
- &[href] {
6
- @include hover-focus {
5
+ @at-root a#{&} {
6
+ @include hover-focus() {
7
7
  color: color-yiq($bg);
8
- text-decoration: none;
9
8
  background-color: darken($bg, 10%);
10
9
  }
10
+
11
+ &:focus,
12
+ &.focus {
13
+ outline: 0;
14
+ box-shadow: 0 0 0 $badge-focus-width rgba($bg, .5);
15
+ }
11
16
  }
12
17
  }
@@ -1,35 +1,76 @@
1
+ // stylelint-disable property-disallowed-list
1
2
  // Single side border-radius
2
3
 
3
- @mixin border-radius($radius: $border-radius) {
4
+ // Helper function to replace negative values with 0
5
+ @function valid-radius($radius) {
6
+ $return: ();
7
+ @each $value in $radius {
8
+ @if type-of($value) == number {
9
+ $return: append($return, max($value, 0));
10
+ } @else {
11
+ $return: append($return, $value);
12
+ }
13
+ }
14
+ @return $return;
15
+ }
16
+
17
+ @mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {
4
18
  @if $enable-rounded {
5
- border-radius: $radius;
19
+ border-radius: valid-radius($radius);
20
+ }
21
+ @else if $fallback-border-radius != false {
22
+ border-radius: $fallback-border-radius;
6
23
  }
7
24
  }
8
25
 
9
26
  @mixin border-top-radius($radius) {
10
27
  @if $enable-rounded {
11
- border-top-left-radius: $radius;
12
- border-top-right-radius: $radius;
28
+ border-top-left-radius: valid-radius($radius);
29
+ border-top-right-radius: valid-radius($radius);
13
30
  }
14
31
  }
15
32
 
16
33
  @mixin border-right-radius($radius) {
17
34
  @if $enable-rounded {
18
- border-top-right-radius: $radius;
19
- border-bottom-right-radius: $radius;
35
+ border-top-right-radius: valid-radius($radius);
36
+ border-bottom-right-radius: valid-radius($radius);
20
37
  }
21
38
  }
22
39
 
23
40
  @mixin border-bottom-radius($radius) {
24
41
  @if $enable-rounded {
25
- border-bottom-right-radius: $radius;
26
- border-bottom-left-radius: $radius;
42
+ border-bottom-right-radius: valid-radius($radius);
43
+ border-bottom-left-radius: valid-radius($radius);
27
44
  }
28
45
  }
29
46
 
30
47
  @mixin border-left-radius($radius) {
31
48
  @if $enable-rounded {
32
- border-top-left-radius: $radius;
33
- border-bottom-left-radius: $radius;
49
+ border-top-left-radius: valid-radius($radius);
50
+ border-bottom-left-radius: valid-radius($radius);
51
+ }
52
+ }
53
+
54
+ @mixin border-top-left-radius($radius) {
55
+ @if $enable-rounded {
56
+ border-top-left-radius: valid-radius($radius);
57
+ }
58
+ }
59
+
60
+ @mixin border-top-right-radius($radius) {
61
+ @if $enable-rounded {
62
+ border-top-right-radius: valid-radius($radius);
63
+ }
64
+ }
65
+
66
+ @mixin border-bottom-right-radius($radius) {
67
+ @if $enable-rounded {
68
+ border-bottom-right-radius: valid-radius($radius);
69
+ }
70
+ }
71
+
72
+ @mixin border-bottom-left-radius($radius) {
73
+ @if $enable-rounded {
74
+ border-bottom-left-radius: valid-radius($radius);
34
75
  }
35
76
  }
@@ -1,5 +1,20 @@
1
1
  @mixin box-shadow($shadow...) {
2
2
  @if $enable-shadows {
3
- box-shadow: $shadow;
3
+ $result: ();
4
+
5
+ @if (length($shadow) == 1) {
6
+ // We can pass `@include box-shadow(none);`
7
+ $result: $shadow;
8
+ } @else {
9
+ // Filter to avoid invalid properties for example `box-shadow: none, 1px 1px black;`
10
+ @for $i from 1 through length($shadow) {
11
+ @if nth($shadow, $i) != "none" {
12
+ $result: append($result, nth($shadow, $i), "comma");
13
+ }
14
+ }
15
+ }
16
+ @if (length($result) > 0) {
17
+ box-shadow: $result;
18
+ }
4
19
  }
5
20
  }
@@ -16,7 +16,7 @@
16
16
  // md
17
17
  @function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {
18
18
  $n: index($breakpoint-names, $name);
19
- @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);
19
+ @return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);
20
20
  }
21
21
 
22
22
  // Minimum breakpoint width. Null for the smallest (first) breakpoint.
@@ -39,10 +39,10 @@
39
39
  // 767.98px
40
40
  @function breakpoint-max($name, $breakpoints: $grid-breakpoints) {
41
41
  $next: breakpoint-next($name, $breakpoints);
42
- @return if($next, breakpoint-min($next, $breakpoints) - .02px, null);
42
+ @return if($next, breakpoint-min($next, $breakpoints) - .02, null);
43
43
  }
44
44
 
45
- // Returns a blank string if smallest breakpoint, otherwise returns the name with a dash infront.
45
+ // Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.
46
46
  // Useful for making responsive utilities.
47
47
  //
48
48
  // >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
@@ -9,7 +9,7 @@
9
9
  border-color: $border;
10
10
  @include box-shadow($btn-box-shadow);
11
11
 
12
- @include hover {
12
+ @include hover() {
13
13
  color: color-yiq($hover-background);
14
14
  @include gradient-bg($hover-background);
15
15
  border-color: $hover-border;
@@ -17,11 +17,14 @@
17
17
 
18
18
  &:focus,
19
19
  &.focus {
20
- // Avoid using mixin so we can pass custom focus shadow properly
20
+ color: color-yiq($hover-background);
21
+ @include gradient-bg($hover-background);
22
+ border-color: $hover-border;
21
23
  @if $enable-shadows {
22
- box-shadow: $btn-box-shadow, 0 0 0 $btn-focus-width rgba($border, .5);
24
+ @include box-shadow($btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));
23
25
  } @else {
24
- box-shadow: 0 0 0 $btn-focus-width rgba($border, .5);
26
+ // Avoid using mixin so we can pass custom focus shadow properly
27
+ box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);
25
28
  }
26
29
  }
27
30
 
@@ -31,6 +34,10 @@
31
34
  color: color-yiq($background);
32
35
  background-color: $background;
33
36
  border-color: $border;
37
+ // Remove CSS gradients if they're enabled
38
+ @if $enable-gradients {
39
+ background-image: none;
40
+ }
34
41
  }
35
42
 
36
43
  &:not(:disabled):not(.disabled):active,
@@ -44,11 +51,11 @@
44
51
  border-color: $active-border;
45
52
 
46
53
  &:focus {
47
- // Avoid using mixin so we can pass custom focus shadow properly
48
- @if $enable-shadows {
49
- box-shadow: $btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($border, .5);
54
+ @if $enable-shadows and $btn-active-box-shadow != none {
55
+ @include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));
50
56
  } @else {
51
- box-shadow: 0 0 0 $btn-focus-width rgba($border, .5);
57
+ // Avoid using mixin so we can pass custom focus shadow properly
58
+ box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);
52
59
  }
53
60
  }
54
61
  }
@@ -56,11 +63,9 @@
56
63
 
57
64
  @mixin button-outline-variant($color, $color-hover: color-yiq($color), $active-background: $color, $active-border: $color) {
58
65
  color: $color;
59
- background-color: transparent;
60
- background-image: none;
61
66
  border-color: $color;
62
67
 
63
- &:hover {
68
+ @include hover() {
64
69
  color: $color-hover;
65
70
  background-color: $active-background;
66
71
  border-color: $active-border;
@@ -85,10 +90,10 @@
85
90
  border-color: $active-border;
86
91
 
87
92
  &:focus {
88
- // Avoid using mixin so we can pass custom focus shadow properly
89
93
  @if $enable-shadows and $btn-active-box-shadow != none {
90
- box-shadow: $btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5);
94
+ @include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5));
91
95
  } @else {
96
+ // Avoid using mixin so we can pass custom focus shadow properly
92
97
  box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);
93
98
  }
94
99
  }
@@ -98,12 +103,8 @@
98
103
  // Button sizes
99
104
  @mixin button-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {
100
105
  padding: $padding-y $padding-x;
101
- font-size: $font-size;
106
+ @include font-size($font-size);
102
107
  line-height: $line-height;
103
108
  // Manually declare to provide an override to the browser default
104
- @if $enable-rounded {
105
- border-radius: $border-radius;
106
- } @else {
107
- border-radius: 0;
108
- }
109
+ @include border-radius($border-radius, 0);
109
110
  }
@@ -1,24 +1,25 @@
1
- @mixin caret-down {
1
+ @mixin caret-down() {
2
2
  border-top: $caret-width solid;
3
3
  border-right: $caret-width solid transparent;
4
4
  border-bottom: 0;
5
5
  border-left: $caret-width solid transparent;
6
6
  }
7
7
 
8
- @mixin caret-up {
8
+ @mixin caret-up() {
9
9
  border-top: 0;
10
10
  border-right: $caret-width solid transparent;
11
11
  border-bottom: $caret-width solid;
12
12
  border-left: $caret-width solid transparent;
13
13
  }
14
14
 
15
- @mixin caret-right {
15
+ @mixin caret-right() {
16
16
  border-top: $caret-width solid transparent;
17
+ border-right: 0;
17
18
  border-bottom: $caret-width solid transparent;
18
19
  border-left: $caret-width solid;
19
20
  }
20
21
 
21
- @mixin caret-left {
22
+ @mixin caret-left() {
22
23
  border-top: $caret-width solid transparent;
23
24
  border-right: $caret-width solid;
24
25
  border-bottom: $caret-width solid transparent;
@@ -28,17 +29,15 @@
28
29
  @if $enable-caret {
29
30
  &::after {
30
31
  display: inline-block;
31
- width: 0;
32
- height: 0;
33
- margin-left: $caret-width * .85;
34
- vertical-align: $caret-width * .85;
32
+ margin-left: $caret-spacing;
33
+ vertical-align: $caret-vertical-align;
35
34
  content: "";
36
35
  @if $direction == down {
37
- @include caret-down;
36
+ @include caret-down();
38
37
  } @else if $direction == up {
39
- @include caret-up;
38
+ @include caret-up();
40
39
  } @else if $direction == right {
41
- @include caret-right;
40
+ @include caret-right();
42
41
  }
43
42
  }
44
43
 
@@ -49,12 +48,10 @@
49
48
 
50
49
  &::before {
51
50
  display: inline-block;
52
- width: 0;
53
- height: 0;
54
- margin-right: $caret-width * .85;
55
- vertical-align: $caret-width * .85;
51
+ margin-right: $caret-spacing;
52
+ vertical-align: $caret-vertical-align;
56
53
  content: "";
57
- @include caret-left;
54
+ @include caret-left();
58
55
  }
59
56
  }
60
57
 
@@ -0,0 +1,10 @@
1
+ // Deprecate mixin
2
+ //
3
+ // This mixin can be used to deprecate mixins or functions.
4
+ // `$enable-deprecation-messages` is a global variable, `$ignore-warning` is a variable that can be passed to
5
+ // some deprecated mixins to suppress the warning (for example if the mixin is still be used in the current version of Bootstrap)
6
+ @mixin deprecate($name, $deprecate-version, $remove-version, $ignore-warning: false) {
7
+ @if ($enable-deprecation-messages != false and $ignore-warning != true) {
8
+ @warn "#{$name} has been deprecated as of #{$deprecate-version}. It will be removed entirely in #{$remove-version}.";
9
+ }
10
+ }
@@ -1,11 +1,14 @@
1
1
  // stylelint-disable declaration-no-important
2
2
 
3
- @mixin float-left {
3
+ @mixin float-left() {
4
4
  float: left !important;
5
+ @include deprecate("The `float-left` mixin", "v4.3.0", "v5");
5
6
  }
6
- @mixin float-right {
7
+ @mixin float-right() {
7
8
  float: right !important;
9
+ @include deprecate("The `float-right` mixin", "v4.3.0", "v5");
8
10
  }
9
- @mixin float-none {
11
+ @mixin float-none() {
10
12
  float: none !important;
13
+ @include deprecate("The `float-none` mixin", "v4.3.0", "v5");
11
14
  }
@@ -10,67 +10,133 @@
10
10
  //
11
11
  // Example usage: change the default blue border and shadow to white for better
12
12
  // contrast against a dark gray background.
13
- @mixin form-control-focus() {
13
+ @mixin form-control-focus($ignore-warning: false) {
14
14
  &:focus {
15
15
  color: $input-focus-color;
16
16
  background-color: $input-focus-bg;
17
17
  border-color: $input-focus-border-color;
18
18
  outline: 0;
19
- // Avoid using mixin so we can pass custom focus shadow properly
20
19
  @if $enable-shadows {
21
- box-shadow: $input-box-shadow, $input-focus-box-shadow;
20
+ @include box-shadow($input-box-shadow, $input-focus-box-shadow);
22
21
  } @else {
22
+ // Avoid using mixin so we can pass custom focus shadow properly
23
23
  box-shadow: $input-focus-box-shadow;
24
24
  }
25
25
  }
26
+ @include deprecate("The `form-control-focus()` mixin", "v4.4.0", "v5", $ignore-warning);
26
27
  }
27
28
 
29
+ // This mixin uses an `if()` technique to be compatible with Dart Sass
30
+ // See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details
31
+ @mixin form-validation-state-selector($state) {
32
+ @if ($state == "valid" or $state == "invalid") {
33
+ .was-validated #{if(&, "&", "")}:#{$state},
34
+ #{if(&, "&", "")}.is-#{$state} {
35
+ @content;
36
+ }
37
+ } @else {
38
+ #{if(&, "&", "")}.is-#{$state} {
39
+ @content;
40
+ }
41
+ }
42
+ }
28
43
 
29
- @mixin form-validation-state($state, $color) {
44
+ @mixin form-validation-state($state, $color, $icon) {
30
45
  .#{$state}-feedback {
31
46
  display: none;
32
47
  width: 100%;
33
48
  margin-top: $form-feedback-margin-top;
34
- font-size: $form-feedback-font-size;
49
+ @include font-size($form-feedback-font-size);
35
50
  color: $color;
36
51
  }
37
52
 
38
53
  .#{$state}-tooltip {
39
54
  position: absolute;
40
55
  top: 100%;
56
+ left: 0;
41
57
  z-index: 5;
42
58
  display: none;
43
59
  max-width: 100%; // Contain to parent when possible
44
- padding: .5rem;
60
+ padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;
45
61
  margin-top: .1rem;
46
- font-size: .875rem;
47
- line-height: 1;
48
- color: #fff;
49
- background-color: rgba($color, .8);
50
- border-radius: .2rem;
62
+ @include font-size($form-feedback-tooltip-font-size);
63
+ line-height: $form-feedback-tooltip-line-height;
64
+ color: color-yiq($color);
65
+ background-color: rgba($color, $form-feedback-tooltip-opacity);
66
+ @include border-radius($form-feedback-tooltip-border-radius);
67
+
68
+ // See https://github.com/twbs/bootstrap/pull/31557
69
+ // Align tooltip to form elements
70
+ .form-row > .col > &,
71
+ .form-row > [class*="col-"] > & {
72
+ left: $form-grid-gutter-width * .5;
73
+ }
51
74
  }
52
75
 
53
- .form-control,
54
- .custom-select {
55
- .was-validated &:#{$state},
56
- &.is-#{$state} {
76
+ @include form-validation-state-selector($state) {
77
+ ~ .#{$state}-feedback,
78
+ ~ .#{$state}-tooltip {
79
+ display: block;
80
+ }
81
+ }
82
+
83
+ .form-control {
84
+ @include form-validation-state-selector($state) {
57
85
  border-color: $color;
58
86
 
87
+ @if $enable-validation-icons {
88
+ padding-right: $input-height-inner !important; // stylelint-disable-line declaration-no-important
89
+ background-image: escape-svg($icon);
90
+ background-repeat: no-repeat;
91
+ background-position: right $input-height-inner-quarter center;
92
+ background-size: $input-height-inner-half $input-height-inner-half;
93
+ }
94
+
59
95
  &:focus {
60
96
  border-color: $color;
61
97
  box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
62
98
  }
99
+ }
100
+ }
63
101
 
64
- ~ .#{$state}-feedback,
65
- ~ .#{$state}-tooltip {
66
- display: block;
102
+ // stylelint-disable-next-line selector-no-qualifying-type
103
+ select.form-control {
104
+ @include form-validation-state-selector($state) {
105
+ @if $enable-validation-icons {
106
+ padding-right: $input-padding-x * 4 !important; // stylelint-disable-line declaration-no-important
107
+ background-position: right $input-padding-x * 2 center;
108
+ }
109
+ }
110
+ }
111
+
112
+ // stylelint-disable-next-line selector-no-qualifying-type
113
+ textarea.form-control {
114
+ @include form-validation-state-selector($state) {
115
+ @if $enable-validation-icons {
116
+ padding-right: $input-height-inner;
117
+ background-position: top $input-height-inner-quarter right $input-height-inner-quarter;
118
+ }
119
+ }
120
+ }
121
+
122
+ .custom-select {
123
+ @include form-validation-state-selector($state) {
124
+ border-color: $color;
125
+
126
+ @if $enable-validation-icons {
127
+ padding-right: $custom-select-feedback-icon-padding-right !important; // stylelint-disable-line declaration-no-important
128
+ background: $custom-select-background, $custom-select-bg escape-svg($icon) $custom-select-feedback-icon-position / $custom-select-feedback-icon-size no-repeat;
129
+ }
130
+
131
+ &:focus {
132
+ border-color: $color;
133
+ box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
67
134
  }
68
135
  }
69
136
  }
70
137
 
71
138
  .form-check-input {
72
- .was-validated &:#{$state},
73
- &.is-#{$state} {
139
+ @include form-validation-state-selector($state) {
74
140
  ~ .form-check-label {
75
141
  color: $color;
76
142
  }
@@ -83,30 +149,29 @@
83
149
  }
84
150
 
85
151
  .custom-control-input {
86
- .was-validated &:#{$state},
87
- &.is-#{$state} {
152
+ @include form-validation-state-selector($state) {
88
153
  ~ .custom-control-label {
89
154
  color: $color;
90
155
 
91
156
  &::before {
92
- background-color: lighten($color, 25%);
157
+ border-color: $color;
93
158
  }
94
159
  }
95
160
 
96
- ~ .#{$state}-feedback,
97
- ~ .#{$state}-tooltip {
98
- display: block;
99
- }
100
-
101
161
  &:checked {
102
162
  ~ .custom-control-label::before {
163
+ border-color: lighten($color, 10%);
103
164
  @include gradient-bg(lighten($color, 10%));
104
165
  }
105
166
  }
106
167
 
107
168
  &:focus {
108
169
  ~ .custom-control-label::before {
109
- box-shadow: 0 0 0 1px $body-bg, 0 0 0 $input-focus-width rgba($color, .25);
170
+ box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
171
+ }
172
+
173
+ &:not(:checked) ~ .custom-control-label::before {
174
+ border-color: $color;
110
175
  }
111
176
  }
112
177
  }
@@ -114,21 +179,14 @@
114
179
 
115
180
  // custom file
116
181
  .custom-file-input {
117
- .was-validated &:#{$state},
118
- &.is-#{$state} {
182
+ @include form-validation-state-selector($state) {
119
183
  ~ .custom-file-label {
120
184
  border-color: $color;
121
-
122
- &::before { border-color: inherit; }
123
- }
124
-
125
- ~ .#{$state}-feedback,
126
- ~ .#{$state}-tooltip {
127
- display: block;
128
185
  }
129
186
 
130
187
  &:focus {
131
188
  ~ .custom-file-label {
189
+ border-color: $color;
132
190
  box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
133
191
  }
134
192
  }
@@ -11,7 +11,7 @@
11
11
  // Horizontal gradient, from left to right
12
12
  //
13
13
  // Creates two color stops, start and end, by specifying a color and position for each color stop.
14
- @mixin gradient-x($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {
14
+ @mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {
15
15
  background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);
16
16
  background-repeat: repeat-x;
17
17
  }
@@ -19,27 +19,27 @@
19
19
  // Vertical gradient, from top to bottom
20
20
  //
21
21
  // Creates two color stops, start and end, by specifying a color and position for each color stop.
22
- @mixin gradient-y($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {
22
+ @mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {
23
23
  background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);
24
24
  background-repeat: repeat-x;
25
25
  }
26
26
 
27
- @mixin gradient-directional($start-color: #555, $end-color: #333, $deg: 45deg) {
27
+ @mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) {
28
28
  background-image: linear-gradient($deg, $start-color, $end-color);
29
29
  background-repeat: repeat-x;
30
30
  }
31
- @mixin gradient-x-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {
31
+ @mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {
32
32
  background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);
33
33
  background-repeat: no-repeat;
34
34
  }
35
- @mixin gradient-y-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {
35
+ @mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {
36
36
  background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);
37
37
  background-repeat: no-repeat;
38
38
  }
39
- @mixin gradient-radial($inner-color: #555, $outer-color: #333) {
39
+ @mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) {
40
40
  background-image: radial-gradient(circle, $inner-color, $outer-color);
41
41
  background-repeat: no-repeat;
42
42
  }
43
- @mixin gradient-striped($color: rgba(255,255,255,.15), $angle: 45deg) {
43
+ @mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) {
44
44
  background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);
45
45
  }