2
0
mirror of https://github.com/tenrok/bootstrap.git synced 2026-06-17 19:21:23 +03:00

Merge branch 'v4-dev' into form-tweaks

This commit is contained in:
Mark Otto
2017-05-01 21:54:50 -07:00
committed by GitHub
20 changed files with 294 additions and 220 deletions
+1
View File
@@ -9,6 +9,7 @@
"html-valid-content-model": false, "html-valid-content-model": false,
"id-class-ignore-regex": "(onclick|content|[a-z]+([A-Z][a-z])+)", "id-class-ignore-regex": "(onclick|content|[a-z]+([A-Z][a-z])+)",
"id-class-style": "dash", "id-class-style": "dash",
"img-req-src": false,
"img-req-alt": false, "img-req-alt": false,
"indent-style": "spaces", "indent-style": "spaces",
"indent-width": 2, "indent-width": 2,
+1 -3
View File
@@ -225,9 +225,7 @@ Bootstrap's collapse class exposes a few events for hooking into collapse functi
</tr> </tr>
<tr> <tr>
<td>hide.bs.collapse</td> <td>hide.bs.collapse</td>
<td> <td>This event is fired immediately when the <code>hide</code> method has been called.</td>
This event is fired immediately when the <code>hide</code> method has been called.
</td>
</tr> </tr>
<tr> <tr>
<td>hidden.bs.collapse</td> <td>hidden.bs.collapse</td>
+7 -7
View File
@@ -376,7 +376,7 @@ Be sure to add `.col-form-label` to your `<label>`s as well so they're verticall
</div> </div>
</fieldset> </fieldset>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-2">Checkbox</label> <div class="col-sm-2">Checkbox</div>
<div class="col-sm-10"> <div class="col-sm-10">
<div class="form-check"> <div class="form-check">
<label class="form-check-label"> <label class="form-check-label">
@@ -569,14 +569,14 @@ Should you have no text within the `<label>`, the input is positioned as you'd e
## Static controls ## Static controls
When you need to place plain text next to a form label within a form, use the `.form-control-static` class on an element of your choice. If you want to have read-only fields in your form styled as plain text, use the `.form-control-static` class to remove the default form field styling and preserve the correct margin and padding.
{% example html %} {% example html %}
<form> <form>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-2 col-form-label">Email</label> <label for="staticEmail" class="col-sm-2 col-form-label">Email</label>
<div class="col-sm-10"> <div class="col-sm-10">
<p class="form-control-static">email@example.com</p> <input type="text" readonly class="form-control-static" id="staticEmail" value="email@example.com">
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
@@ -591,8 +591,8 @@ When you need to place plain text next to a form label within a form, use the `.
{% example html %} {% example html %}
<form class="form-inline"> <form class="form-inline">
<div class="form-group"> <div class="form-group">
<label class="sr-only">Email</label> <label for="staticEmail2" class="sr-only">Email</label>
<p class="form-control-static">email@example.com</p> <input type="text" readonly class="form-control-static" id="staticEmail2" value="email@example.com">
</div> </div>
<div class="form-group mx-sm-3"> <div class="form-group mx-sm-3">
<label for="inputPassword2" class="sr-only">Password</label> <label for="inputPassword2" class="sr-only">Password</label>
@@ -604,7 +604,7 @@ When you need to place plain text next to a form label within a form, use the `.
## Disabled states ## Disabled states
Add the `disabled` boolean attribute on an input to prevent user interactions. Disabled inputs appear lighter and add a `not-allowed` cursor. Add the `disabled` boolean attribute on an input to prevent user interactions and make it appear lighter.
{% highlight html %} {% highlight html %}
<input class="form-control" id="disabledInput" type="text" placeholder="Disabled input here..." disabled> <input class="form-control" id="disabledInput" type="text" placeholder="Disabled input here..." disabled>
+1 -1
View File
@@ -5,7 +5,7 @@ description: Details on how to use Bootstrap's included build tools to compile s
group: getting-started group: getting-started
--- ---
Bootstrap uses [NPM scripts](https://docs.npmjs.com/misc/scripts) for its build system. Our [package.json](https://github.com/twbs/bootstrap/blob/master/package.json) includes convenient methods for working with the framework, including compiling code, running tests, and more. Bootstrap uses [NPM scripts](https://docs.npmjs.com/misc/scripts) for its build system. Our [package.json](https://github.com/twbs/bootstrap/blob/v4-dev/package.json) includes convenient methods for working with the framework, including compiling code, running tests, and more.
## Contents ## Contents
-2
View File
@@ -96,8 +96,6 @@ On the rare occasion you need to override it, use something like the following:
{% highlight scss %} {% highlight scss %}
.selector-for-some-widget { .selector-for-some-widget {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box; box-sizing: content-box;
} }
{% endhighlight %} {% endhighlight %}
+6
View File
@@ -90,6 +90,12 @@ const Button = (($) => {
} }
if (triggerChangeEvent) { if (triggerChangeEvent) {
if (input.hasAttribute('disabled') ||
rootElement.hasAttribute('disabled') ||
input.classList.contains('disabled') ||
rootElement.classList.contains('disabled')) {
return
}
input.checked = !$(this._element).hasClass(ClassName.ACTIVE) input.checked = !$(this._element).hasClass(ClassName.ACTIVE)
$(input).trigger('change') $(input).trigger('change')
} }
+4 -12
View File
@@ -56,9 +56,8 @@ const Collapse = (($) => {
} }
const Selector = { const Selector = {
ACTIVES : '.card > .show, .card > .collapsing', ACTIVES : '.show, .collapsing',
DATA_TOGGLE : '[data-toggle="collapse"]', DATA_TOGGLE : '[data-toggle="collapse"]'
DATA_CHILDREN : 'data-children'
} }
@@ -78,20 +77,13 @@ const Collapse = (($) => {
`[data-toggle="collapse"][href="#${element.id}"],` + `[data-toggle="collapse"][href="#${element.id}"],` +
`[data-toggle="collapse"][data-target="#${element.id}"]` `[data-toggle="collapse"][data-target="#${element.id}"]`
)) ))
this._parent = this._config.parent ? this._getParent() : null this._parent = this._config.parent ? this._getParent() : null
if (!this._config.parent) { if (!this._config.parent) {
this._addAriaAndCollapsedClass(this._element, this._triggerArray) this._addAriaAndCollapsedClass(this._element, this._triggerArray)
} }
this._selectorActives = Selector.ACTIVES
if (this._parent) {
const childrenSelector = this._parent.hasAttribute(Selector.DATA_CHILDREN) ? this._parent.getAttribute(Selector.DATA_CHILDREN) : null
if (childrenSelector !== null) {
this._selectorActives = `${childrenSelector} > .show, ${childrenSelector} > .collapsing`
}
}
if (this._config.toggle) { if (this._config.toggle) {
this.toggle() this.toggle()
} }
@@ -129,7 +121,7 @@ const Collapse = (($) => {
let activesData let activesData
if (this._parent) { if (this._parent) {
actives = $.makeArray($(this._parent).find(this._selectorActives)) actives = $.makeArray($(this._parent).children().children(Selector.ACTIVES))
if (!actives.length) { if (!actives.length) {
actives = null actives = null
} }
+1 -1
View File
@@ -140,7 +140,7 @@ const Tab = (($) => {
} }
dispose() { dispose() {
$.removeClass(this._element, DATA_KEY) $.removeData(this._element, DATA_KEY)
this._element = null this._element = null
} }
+17
View File
@@ -156,4 +156,21 @@ $(function () {
assert.ok($btn2.is(':not([aria-pressed])'), 'label for nested radio input has not been given an aria-pressed attribute') assert.ok($btn2.is(':not([aria-pressed])'), 'label for nested radio input has not been given an aria-pressed attribute')
}) })
QUnit.test('should handle disabled attribute on non-button elements', function (assert) {
assert.expect(2)
var groupHTML = ' <div class="btn-group disabled" data-toggle="buttons" aria-disabled="true" disabled>'
+ '<label class="btn btn-danger disabled" aria-disabled="true" disabled>'
+ '<input type="checkbox" aria-disabled="true" autocomplete="off" disabled class="disabled"/>'
+ '</label>'
+ '</div>'
var $group = $(groupHTML).appendTo('#qunit-fixture')
var $btn = $group.children().eq(0)
var $input = $btn.children().eq(0)
$btn.trigger('click')
assert.ok($btn.is(':not(.active)'), 'button did not become active')
assert.ok(!$input.is(':checked'), 'checkbox did not get checked')
})
}) })
+66 -8
View File
@@ -491,27 +491,85 @@ $(function () {
}) })
QUnit.test('should allow accordion to use children other than card', function (assert) { QUnit.test('should allow accordion to use children other than card', function (assert) {
assert.expect(2) assert.expect(4)
var done = assert.async() var done = assert.async()
var accordionHTML = '<div id="accordion" data-children=".item">' var accordionHTML = '<div id="accordion">'
+ '<div class="item">' + '<div class="item">'
+ '<a id="linkTrigger" data-parent="#accordion" data-toggle="collapse" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>' + '<a id="linkTrigger" data-parent="#accordion" data-toggle="collapse" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>'
+ '<div id="collapseOne" class="collapse" role="tabpanel" aria-labelledby="headingThree"></div>' + '<div id="collapseOne" class="collapse" role="tabpanel" aria-labelledby="headingThree"></div>'
+ '</div>' + '</div>'
+ '<div class="item">' + '<div class="item">'
+ '<a data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>' + '<a id="linkTriggerTwo" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>'
+ '<div id="collapseTwo" class="collapse show" role="tabpanel" aria-labelledby="headingTwo"></div>' + '<div id="collapseTwo" class="collapse show" role="tabpanel" aria-labelledby="headingTwo"></div>'
+ '</div>' + '</div>'
+ '</div>' + '</div>'
$(accordionHTML).appendTo('#qunit-fixture') $(accordionHTML).appendTo('#qunit-fixture')
var $target = $('#linkTrigger') var $trigger = $('#linkTrigger')
$('#collapseOne').on('shown.bs.collapse', function () { var $triggerTwo = $('#linkTriggerTwo')
assert.ok($(this).hasClass('show')) var $collapseOne = $('#collapseOne')
assert.ok(!$('#collapseTwo').hasClass('show')) var $collapseTwo = $('#collapseTwo')
$collapseOne.on('shown.bs.collapse', function () {
assert.ok($collapseOne.hasClass('show'), '#collapseOne is shown')
assert.ok(!$collapseTwo.hasClass('show'), '#collapseTwo is not shown')
$collapseTwo.on('shown.bs.collapse', function () {
assert.ok(!$collapseOne.hasClass('show'), '#collapseOne is not shown')
assert.ok($collapseTwo.hasClass('show'), '#collapseTwo is shown')
done() done()
}) })
$target.trigger($.Event('click')) $triggerTwo.trigger($.Event('click'))
})
$trigger.trigger($.Event('click'))
})
QUnit.test('should collapse accordion children but not nested accordion children', function (assert) {
assert.expect(9)
var done = assert.async()
$('<div id="accordion">'
+ '<div class="item">'
+ '<a id="linkTrigger" data-parent="#accordion" data-toggle="collapse" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"></a>'
+ '<div id="collapseOne" class="collapse" role="tabpanel" aria-labelledby="headingThree">'
+ '<div id="nestedAccordion">'
+ '<div class="item">'
+ '<a id="nestedLinkTrigger" data-parent="#nestedAccordion" data-toggle="collapse" href="#nestedCollapseOne" aria-expanded="false" aria-controls="nestedCollapseOne"></a>'
+ '<div id="nestedCollapseOne" class="collapse" role="tabpanel" aria-labelledby="headingThree">'
+ '</div>'
+ '</div>'
+ '</div>'
+ '</div>'
+ '</div>'
+ '<div class="item">'
+ '<a id="linkTriggerTwo" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"></a>'
+ '<div id="collapseTwo" class="collapse show" role="tabpanel" aria-labelledby="headingTwo"></div>'
+ '</div>'
+ '</div>').appendTo('#qunit-fixture')
var $trigger = $('#linkTrigger')
var $triggerTwo = $('#linkTriggerTwo')
var $nestedTrigger = $('#nestedLinkTrigger')
var $collapseOne = $('#collapseOne')
var $collapseTwo = $('#collapseTwo')
var $nestedCollapseOne = $('#nestedCollapseOne')
$collapseOne.one('shown.bs.collapse', function () {
assert.ok($collapseOne.hasClass('show'), '#collapseOne is shown')
assert.ok(!$collapseTwo.hasClass('show'), '#collapseTwo is not shown')
assert.ok(!$('#nestedCollapseOne').hasClass('show'), '#nestedCollapseOne is not shown')
$nestedCollapseOne.one('shown.bs.collapse', function () {
assert.ok($collapseOne.hasClass('show'), '#collapseOne is shown')
assert.ok(!$collapseTwo.hasClass('show'), '#collapseTwo is not shown')
assert.ok($nestedCollapseOne.hasClass('show'), '#nestedCollapseOne is shown')
$collapseTwo.one('shown.bs.collapse', function () {
assert.ok(!$collapseOne.hasClass('show'), '#collapseOne is not shown')
assert.ok($collapseTwo.hasClass('show'), '#collapseTwo is shown')
assert.ok($nestedCollapseOne.hasClass('show'), '#nestedCollapseOne is shown')
done()
})
$triggerTwo.trigger($.Event('click'))
})
$nestedTrigger.trigger($.Event('click'))
})
$trigger.trigger($.Event('click'))
}) })
QUnit.test('should not prevent event for input', function (assert) { QUnit.test('should not prevent event for input', function (assert) {
+9 -5
View File
@@ -25,7 +25,7 @@
"css-compile": "node-sass --output-style expanded --source-map true --precision 6 scss/bootstrap.scss dist/css/bootstrap.css && node-sass --output-style expanded --source-map true --precision 6 scss/bootstrap-grid.scss dist/css/bootstrap-grid.css && node-sass --output-style expanded --source-map true --precision 6 scss/bootstrap-reboot.scss dist/css/bootstrap-reboot.css", "css-compile": "node-sass --output-style expanded --source-map true --precision 6 scss/bootstrap.scss dist/css/bootstrap.css && node-sass --output-style expanded --source-map true --precision 6 scss/bootstrap-grid.scss dist/css/bootstrap-grid.css && node-sass --output-style expanded --source-map true --precision 6 scss/bootstrap-reboot.scss dist/css/bootstrap-reboot.css",
"css-compile-docs": "node-sass --output-style expanded --source-map true --precision 6 docs/assets/scss/docs.scss docs/assets/css/docs.min.css", "css-compile-docs": "node-sass --output-style expanded --source-map true --precision 6 docs/assets/scss/docs.scss docs/assets/css/docs.min.css",
"css-prefix": "postcss --config build/ --replace dist/css/*.css", "css-prefix": "postcss --config build/ --replace dist/css/*.css",
"css-prefix-docs": "postcss --config build/ --no-map --replace docs/assets/css/docs.min.css docs/examples/**/*.css", "css-prefix-docs": "postcss --config build/ --no-map --replace docs/assets/css/docs.min.css",
"css-minify": "cleancss --level 1 --source-map --output dist/css/bootstrap.min.css dist/css/bootstrap.css && cleancss --level 1 --source-map --output dist/css/bootstrap-grid.min.css dist/css/bootstrap-grid.css && cleancss --level 1 --source-map --output dist/css/bootstrap-reboot.min.css dist/css/bootstrap-reboot.css", "css-minify": "cleancss --level 1 --source-map --output dist/css/bootstrap.min.css dist/css/bootstrap.css && cleancss --level 1 --source-map --output dist/css/bootstrap-grid.min.css dist/css/bootstrap-grid.css && cleancss --level 1 --source-map --output dist/css/bootstrap-reboot.min.css dist/css/bootstrap-reboot.css",
"css-minify-docs": "cleancss --level 1 --source-map --output docs/assets/css/docs.min.css docs/assets/css/docs.min.css", "css-minify-docs": "cleancss --level 1 --source-map --output docs/assets/css/docs.min.css docs/assets/css/docs.min.css",
"js": "npm-run-all js-compile js-minify", "js": "npm-run-all js-compile js-minify",
@@ -38,7 +38,9 @@
"js-minify": "uglifyjs --compress warnings=false --mangle --comments '/^!/' --output dist/js/bootstrap.min.js dist/js/bootstrap.js", "js-minify": "uglifyjs --compress warnings=false --mangle --comments '/^!/' --output dist/js/bootstrap.min.js dist/js/bootstrap.js",
"js-minify-docs": "uglifyjs --compress warnings=false --mangle --comments '/^!/' --output docs/assets/js/docs.min.js docs/assets/js/vendor/anchor.min.js docs/assets/js/vendor/clipboard.min.js docs/assets/js/vendor/holder.min.js docs/assets/js/src/application.js", "js-minify-docs": "uglifyjs --compress warnings=false --mangle --comments '/^!/' --output docs/assets/js/docs.min.js docs/assets/js/vendor/anchor.min.js docs/assets/js/vendor/clipboard.min.js docs/assets/js/vendor/holder.min.js docs/assets/js/src/application.js",
"js-test": "phantomjs ./node_modules/qunit-phantomjs-runner/runner.js js/tests/index.html 60", "js-test": "phantomjs ./node_modules/qunit-phantomjs-runner/runner.js js/tests/index.html 60",
"js-test-cloud": "ruby -run -ehttpd . -p3000 > /dev/null & grunt saucelabs-qunit", "js-test-dep": "npm install grunt && npm install grunt-saucelabs",
"js-launch-cloud": "ruby -run -ehttpd . -p3000 > /dev/null & grunt saucelabs-qunit",
"js-test-cloud": "npm-run-all js-test-dep js-launch-cloud",
"docs": "npm-run-all docs-compile docs-lint", "docs": "npm-run-all docs-compile docs-lint",
"docs-lint": "htmlhint --config docs/.htmlhintrc _gh_pages/ js/tests/visual/ && htmllint --rc docs/.htmllintrc _gh_pages/*.html _gh_pages/**/*.html js/tests/visual/*.html", "docs-lint": "htmlhint --config docs/.htmlhintrc _gh_pages/ js/tests/visual/ && htmllint --rc docs/.htmllintrc _gh_pages/*.html _gh_pages/**/*.html js/tests/visual/*.html",
"docs-clean": "shx rm -r docs/dist/* && shx cp -r dist/* docs/dist/", "docs-clean": "shx rm -r docs/dist/* && shx cp -r dist/* docs/dist/",
@@ -51,7 +53,10 @@
"release-version": "node build/change-version.js", "release-version": "node build/change-version.js",
"release-zip": "cd dist/ && zip -r9 bootstrap-$npm_package_version-dist.zip * && shx mv bootstrap-$npm_package_version-dist.zip ..", "release-zip": "cd dist/ && zip -r9 bootstrap-$npm_package_version-dist.zip * && shx mv bootstrap-$npm_package_version-dist.zip ..",
"dist": "npm-run-all --parallel css js", "dist": "npm-run-all --parallel css js",
"test": "npm-run-all dist docs" "test": "npm-run-all dist js-test docs",
"watch-css": "nodemon --ignore js/ --ignore dist/ -e scss -x \"npm run css && npm run css-docs\"",
"watch-js": "nodemon --ignore scss/ --ignore js/dist/ --ignore dist/ -e js -x \"npm run js-compile\"",
"watch": "npm-run-all --parallel watch-css watch-js"
}, },
"style": "dist/css/bootstrap.css", "style": "dist/css/bootstrap.css",
"sass": "scss/bootstrap.scss", "sass": "scss/bootstrap.scss",
@@ -76,11 +81,10 @@
"babel-preset-es2015": "^7.0.0-alpha.7", "babel-preset-es2015": "^7.0.0-alpha.7",
"clean-css-cli": "^4.0.12", "clean-css-cli": "^4.0.12",
"eslint": "^3.19.0", "eslint": "^3.19.0",
"grunt": "^1.0.1",
"grunt-saucelabs": "^9.0.0",
"htmlhint": "^0.9.13", "htmlhint": "^0.9.13",
"htmllint-cli": "^0.0.6", "htmllint-cli": "^0.0.6",
"node-sass": "^4.5.2", "node-sass": "^4.5.2",
"nodemon": "^1.11.0",
"npm-run-all": "^4.0.2", "npm-run-all": "^4.0.2",
"phantomjs-prebuilt": "^2.1.14", "phantomjs-prebuilt": "^2.1.14",
"postcss-cli": "^3.1.1", "postcss-cli": "^3.1.1",