Skip to content

Commit cf5e99e

Browse files
committed
Merge branch 'v4-dev' of https://github.com/twbs/bootstrap into v4-dev
2 parents 6fd11a6 + b01e81e commit cf5e99e

File tree

7 files changed

+90
-146
lines changed

7 files changed

+90
-146
lines changed

docs/4.0/components/forms.md

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -899,31 +899,37 @@ Our example forms show native textual `<input>`s above, but form validation styl
899899

900900
{% example html %}
901901
<form class="was-validated">
902-
<div class="custom-control custom-checkbox">
902+
<div class="custom-control custom-checkbox mb-3">
903903
<input type="checkbox" class="custom-control-input" id="customControlValidation1" required>
904904
<label class="custom-control-label" for="customControlValidation1">Check this custom checkbox</label>
905+
<div class="invalid-feedback">Example invalid feedback text</div>
905906
</div>
906907

907908
<div class="custom-control custom-radio">
908909
<input type="radio" class="custom-control-input" id="customControlValidation2" name="radio-stacked" required>
909910
<label class="custom-control-label" for="customControlValidation2">Toggle this custom radio</label>
910911
</div>
911-
<div class="custom-control custom-radio">
912+
<div class="custom-control custom-radio mb-3">
912913
<input type="radio" class="custom-control-input" id="customControlValidation3" name="radio-stacked" required>
913914
<label class="custom-control-label" for="customControlValidation3">Or toggle this other custom radio</label>
915+
<div class="invalid-feedback">More example invalid feedback text</div>
914916
</div>
915917

916-
<select class="custom-select d-block my-3" required>
917-
<option value="">Open this select menu</option>
918-
<option value="1">One</option>
919-
<option value="2">Two</option>
920-
<option value="3">Three</option>
921-
</select>
918+
<div class="form-group">
919+
<select class="custom-select" required>
920+
<option value="">Open this select menu</option>
921+
<option value="1">One</option>
922+
<option value="2">Two</option>
923+
<option value="3">Three</option>
924+
</select>
925+
<div class="invalid-feedback">Example invalid custom select feedback</div>
926+
</div>
922927

923-
<label class="custom-file">
924-
<input type="file" id="file" class="custom-file-input" required>
925-
<span class="custom-file-control"></span>
926-
</label>
928+
<div class="custom-file">
929+
<input type="file" class="custom-file-input" id="validatedCustomFile" required>
930+
<label class="custom-file-label" for="validatedCustomFile">Choose file...</label>
931+
<div class="invalid-feedback">Example invalid custom file feedback</div>
932+
</div>
927933
</form>
928934
{% endexample %}
929935

@@ -1062,24 +1068,16 @@ As is the `size` attribute:
10621068

10631069
### File browser
10641070

1065-
The file input is the most gnarly of the bunch and require additional JavaScript if you'd like to hook them up with functional *Choose file...* and selected file name text.
1071+
The file input is the most gnarly of the bunch and requires additional JavaScript if you'd like to hook them up with functional *Choose file...* and selected file name text.
10661072

10671073
{% example html %}
1068-
<label class="custom-file">
1069-
<input type="file" id="file2" class="custom-file-input">
1070-
<span class="custom-file-control"></span>
1071-
</label>
1074+
<div class="custom-file">
1075+
<input type="file" class="custom-file-input" id="customFile">
1076+
<label class="custom-file-label" for="customFile">Choose file</label>
1077+
</div>
10721078
{% endexample %}
10731079

1074-
Here's how it works:
1075-
1076-
- We wrap the `<input>` in a `<label>` so the custom control properly triggers the file browser.
1077-
- We hide the default file `<input>` via `opacity`.
1078-
- We use `::after` to generate a custom background and directive (*Choose file...*).
1079-
- We use `::before` to generate and position the *Browse* button.
1080-
- We declare a `height` on the `<input>` for proper spacing for surrounding content.
1081-
1082-
In other words, it's an entirely custom element, all generated via CSS.
1080+
We hide the default file `<input>` via `opacity` and instead style the `<label>`. The button is generated and positioned with `::after`. Lastly, we declare a `width` and `height` on the `<input>` for proper spacing for surrounding content.
10831081

10841082
#### Translating or customizing the strings
10851083

docs/4.0/migration.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ While Beta 2 saw the bulk of our breaking changes during the beta phase, but we
3535

3636
- Sizing classes must be on the parent `.input-group` and not the individual form elements.
3737

38-
- Due to limitations in how CSS selectors work, all buttons must be the same element (e.g., `<a>` or `<button>`).
39-
4038
## Beta 2 changes
4139

4240
While in beta, we aim to have no breaking changes. However, things don't always go as planned. Below are the breaking changes to bear in mind when moving from Beta 1 to Beta 2.

scss/_button-group.scss

Lines changed: 12 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -44,46 +44,18 @@
4444
}
4545

4646
.btn-group {
47-
> .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
48-
border-radius: 0;
49-
}
50-
51-
// Set corners individual because sometimes a single button can be in a .btn-group
52-
// and we need :first-child and :last-child to both match
5347
> .btn:first-child {
5448
margin-left: 0;
55-
56-
&:not(:last-child):not(.dropdown-toggle) {
57-
@include border-right-radius(0);
58-
}
59-
}
60-
61-
62-
// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu
63-
// immediately after it
64-
> .btn:last-child:not(:first-child),
65-
> .dropdown-toggle:not(:first-child) {
66-
@include border-left-radius(0);
67-
}
68-
69-
// Custom edits for including btn-groups within btn-groups (useful for including
70-
// dropdown buttons within a btn-group)
71-
> .btn-group {
72-
float: left;
73-
}
74-
75-
> .btn-group:not(:first-child):not(:last-child) > .btn {
76-
border-radius: 0;
7749
}
7850

79-
> .btn-group:first-child:not(:last-child) {
80-
> .btn:last-child,
81-
> .dropdown-toggle {
82-
@include border-right-radius(0);
83-
}
51+
// Reset rounded corners
52+
> .btn:not(:last-child):not(.dropdown-toggle),
53+
> .btn-group:not(:last-child) > .btn {
54+
@include border-right-radius(0);
8455
}
8556

86-
> .btn-group:last-child:not(:first-child) > .btn:first-child {
57+
> .btn:not(:first-child),
58+
> .btn-group:not(:first-child) > .btn {
8759
@include border-left-radius(0);
8860
}
8961
}
@@ -154,32 +126,14 @@
154126
margin-left: 0;
155127
}
156128

157-
> .btn {
158-
&:not(:first-child):not(:last-child) {
159-
border-radius: 0;
160-
}
161-
162-
&:first-child:not(:last-child) {
163-
@include border-bottom-radius(0);
164-
}
165-
166-
&:last-child:not(:first-child) {
167-
@include border-top-radius(0);
168-
}
169-
}
170-
171-
> .btn-group:not(:first-child):not(:last-child) > .btn {
172-
border-radius: 0;
173-
}
174-
175-
> .btn-group:first-child:not(:last-child) {
176-
> .btn:last-child,
177-
> .dropdown-toggle {
178-
@include border-bottom-radius(0);
179-
}
129+
// Reset rounded corners
130+
> .btn:not(:last-child):not(.dropdown-toggle),
131+
> .btn-group:not(:last-child) > .btn {
132+
@include border-bottom-radius(0);
180133
}
181134

182-
> .btn-group:last-child:not(:first-child) > .btn:first-child {
135+
> .btn:not(:first-child),
136+
> .btn-group:not(:first-child) > .btn {
183137
@include border-top-radius(0);
184138
}
185139
}

scss/_custom-forms.scss

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,9 @@
225225
}
226226

227227
.custom-file-input {
228-
max-width: 100%;
228+
position: relative;
229+
z-index: 2;
230+
width: 100%;
229231
height: $custom-file-height;
230232
margin: 0;
231233
opacity: 0;
@@ -238,49 +240,43 @@
238240
border-color: $custom-file-focus-border-color;
239241
}
240242
}
243+
244+
@each $lang, $value in $custom-file-text {
245+
&:lang(#{$lang}) ~ .custom-file-label::after {
246+
content: $value;
247+
}
248+
}
241249
}
242250

243-
.custom-file-control {
251+
.custom-file-label {
244252
position: absolute;
245253
top: 0;
246254
right: 0;
247255
left: 0;
256+
z-index: 1;
248257
height: $custom-file-height;
249258
padding: $custom-file-padding-y $custom-file-padding-x;
250259
line-height: $custom-file-line-height;
251260
color: $custom-file-color;
252-
pointer-events: none;
253-
user-select: none;
254261
background-color: $custom-file-bg;
255262
border: $custom-file-border-width solid $custom-file-border-color;
256263
@include border-radius($custom-file-border-radius);
257264
@include box-shadow($custom-file-box-shadow);
258265

259-
@each $lang, $text in map-get($custom-file-text, placeholder) {
260-
&:lang(#{$lang}):empty::after {
261-
content: $text;
262-
}
263-
}
264-
265-
&::before {
266+
&::after {
266267
position: absolute;
267-
top: -$custom-file-border-width;
268-
right: -$custom-file-border-width;
269-
bottom: -$custom-file-border-width;
270-
z-index: 1;
268+
top: 0;
269+
right: 0;
270+
bottom: 0;
271+
z-index: 3;
271272
display: block;
272-
height: $custom-file-height;
273+
height: calc(#{$custom-file-height} - #{$custom-file-border-width} * 2);
273274
padding: $custom-file-padding-y $custom-file-padding-x;
274275
line-height: $custom-file-line-height;
275276
color: $custom-file-button-color;
277+
content: "Browse";
276278
@include gradient-bg($custom-file-button-bg);
277-
border: $custom-file-border-width solid $custom-file-border-color;
279+
border-left: $custom-file-border-width solid $custom-file-border-color;
278280
@include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);
279281
}
280-
281-
@each $lang, $text in map-get($custom-file-text, button-label) {
282-
&:lang(#{$lang})::before {
283-
content: $text;
284-
}
285-
}
286282
}

scss/_input-group.scss

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,8 @@
3333

3434
.form-control,
3535
.custom-select {
36-
&:not(:first-child):not(:last-of-type) { @include border-radius(0); }
37-
&:first-child { @include border-right-radius(0); }
38-
&:last-of-type:not(:first-child) { @include border-left-radius(0); }
36+
&:not(:last-child) { @include border-right-radius(0); }
37+
&:not(:first-child) { @include border-left-radius(0); }
3938
}
4039

4140
// Custom file inputs have more complex markup, thus requiring different
@@ -44,12 +43,10 @@
4443
display: flex;
4544
align-items: center;
4645

47-
&:not(:first-child):not(:last-of-type) .custom-file-control,
48-
&:not(:first-child):not(:last-of-type) .custom-file-control::before { @include border-radius(0); }
49-
&:first-child .custom-file-control,
50-
&:first-child .custom-file-control::before { @include border-right-radius(0); }
51-
&:last-of-type:not(:first-child) .custom-file-control,
52-
&:last-of-type:not(:first-child) .custom-file-control::before { @include border-left-radius(0); }
46+
&:not(:last-child) .custom-file-control,
47+
&:not(:last-child) .custom-file-control::before { @include border-right-radius(0); }
48+
&:not(:first-child) .custom-file-control,
49+
&:not(:first-child) .custom-file-control::before { @include border-left-radius(0); }
5350
}
5451
}
5552

@@ -139,28 +136,21 @@
139136
// border-radius values when extending. They're more specific than we'd like
140137
// with the `.input-group >` part, but without it, we cannot override the sizing.
141138

139+
142140
.input-group > .input-group-prepend > .btn,
143-
.input-group > .input-group-prepend > .input-group-text {
144-
// All prepended buttons have no right border-radius
141+
.input-group > .input-group-prepend > .input-group-text,
142+
.input-group > .input-group-append:not(:last-child) > .btn,
143+
.input-group > .input-group-append:not(:last-child) > .input-group-text,
144+
.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),
145+
.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {
145146
@include border-right-radius(0);
146-
147-
+ .btn,
148-
+ .input-group-text {
149-
@include border-left-radius(0);
150-
}
151147
}
152148

153-
// We separate out the button and input resets here because `.input-group-text`
154-
// can be any HTML element, but buttons are always inputs, buttons, or anchors.
155-
.input-group > .input-group-append {
156-
// Everything but the last one have no rounded corners
157-
.btn:not(:last-of-type),
158-
.input-group-text:not(:last-child) {
159-
@include border-radius(0);
160-
}
161-
162-
.btn:last-of-type,
163-
.input-group-text:last-child {
164-
@include border-left-radius(0);
165-
}
149+
.input-group > .input-group-append > .btn,
150+
.input-group > .input-group-append > .input-group-text,
151+
.input-group > .input-group-prepend:not(:first-child) > .btn,
152+
.input-group > .input-group-prepend:not(:first-child) > .input-group-text,
153+
.input-group > .input-group-prepend:first-child > .btn:not(:first-child),
154+
.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {
155+
@include border-left-radius(0);
166156
}

scss/_variables.scss

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -509,12 +509,7 @@ $custom-file-box-shadow: $input-box-shadow !default;
509509
$custom-file-button-color: $custom-file-color !default;
510510
$custom-file-button-bg: $input-group-addon-bg !default;
511511
$custom-file-text: (
512-
placeholder: (
513-
en: "Choose file..."
514-
),
515-
button-label: (
516-
en: "Browse"
517-
)
512+
en: "Browse"
518513
) !default;
519514

520515

scss/mixins/_forms.scss

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,18 @@
8888
background-color: lighten($color, 25%);
8989
}
9090
}
91+
92+
~ .#{$state}-feedback,
93+
~ .#{$state}-tooltip {
94+
display: block;
95+
}
96+
9197
&:checked {
9298
~ .custom-control-label::before {
9399
@include gradient-bg(lighten($color, 10%));
94100
}
95101
}
102+
96103
&:focus {
97104
~ .custom-control-label::before {
98105
box-shadow: 0 0 0 1px $body-bg, 0 0 0 $input-focus-width rgba($color, .25);
@@ -105,13 +112,19 @@
105112
.custom-file-input {
106113
.was-validated &:#{$state},
107114
&.is-#{$state} {
108-
~ .custom-file-control {
115+
~ .custom-file-label {
109116
border-color: $color;
110117

111118
&::before { border-color: inherit; }
112119
}
120+
121+
~ .#{$state}-feedback,
122+
~ .#{$state}-tooltip {
123+
display: block;
124+
}
125+
113126
&:focus {
114-
~ .custom-file-control {
127+
~ .custom-file-label {
115128
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
116129
}
117130
}

0 commit comments

Comments
 (0)