0
0
mirror of https://github.com/twbs/bootstrap.git synced 2024-12-01 13:24:25 +01: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
commit 8c7fe6cf14
20 changed files with 294 additions and 220 deletions

View File

@ -9,6 +9,7 @@
"html-valid-content-model": false,
"id-class-ignore-regex": "(onclick|content|[a-z]+([A-Z][a-z])+)",
"id-class-style": "dash",
"img-req-src": false,
"img-req-alt": false,
"indent-style": "spaces",
"indent-width": 2,

View File

@ -225,9 +225,7 @@ Bootstrap's collapse class exposes a few events for hooking into collapse functi
</tr>
<tr>
<td>hide.bs.collapse</td>
<td>
This event is fired immediately when the <code>hide</code> method has been called.
</td>
<td>This event is fired immediately when the <code>hide</code> method has been called.</td>
</tr>
<tr>
<td>hidden.bs.collapse</td>

View File

@ -376,7 +376,7 @@ Be sure to add `.col-form-label` to your `<label>`s as well so they're verticall
</div>
</fieldset>
<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="form-check">
<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
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 %}
<form>
<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">
<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 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 %}
<form class="form-inline">
<div class="form-group">
<label class="sr-only">Email</label>
<p class="form-control-static">email@example.com</p>
<label for="staticEmail2" class="sr-only">Email</label>
<input type="text" readonly class="form-control-static" id="staticEmail2" value="email@example.com">
</div>
<div class="form-group mx-sm-3">
<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
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 %}
<input class="form-control" id="disabledInput" type="text" placeholder="Disabled input here..." disabled>

View File

@ -5,7 +5,7 @@ description: Details on how to use Bootstrap's included build tools to compile s
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

View File

@ -96,8 +96,6 @@ On the rare occasion you need to override it, use something like the following:
{% highlight scss %}
.selector-for-some-widget {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
{% endhighlight %}

View File

@ -90,6 +90,12 @@ const Button = (($) => {
}
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).trigger('change')
}

View File

@ -56,9 +56,8 @@ const Collapse = (($) => {
}
const Selector = {
ACTIVES : '.card > .show, .card > .collapsing',
DATA_TOGGLE : '[data-toggle="collapse"]',
DATA_CHILDREN : 'data-children'
ACTIVES : '.show, .collapsing',
DATA_TOGGLE : '[data-toggle="collapse"]'
}
@ -78,20 +77,13 @@ const Collapse = (($) => {
`[data-toggle="collapse"][href="#${element.id}"],` +
`[data-toggle="collapse"][data-target="#${element.id}"]`
))
this._parent = this._config.parent ? this._getParent() : null
if (!this._config.parent) {
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) {
this.toggle()
}
@ -129,7 +121,7 @@ const Collapse = (($) => {
let activesData
if (this._parent) {
actives = $.makeArray($(this._parent).find(this._selectorActives))
actives = $.makeArray($(this._parent).children().children(Selector.ACTIVES))
if (!actives.length) {
actives = null
}

View File

@ -140,7 +140,7 @@ const Tab = (($) => {
}
dispose() {
$.removeClass(this._element, DATA_KEY)
$.removeData(this._element, DATA_KEY)
this._element = null
}

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')
})
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')
})
})

View File

@ -491,27 +491,85 @@ $(function () {
})
QUnit.test('should allow accordion to use children other than card', function (assert) {
assert.expect(2)
assert.expect(4)
var done = assert.async()
var accordionHTML = '<div id="accordion" data-children=".item">'
var accordionHTML = '<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>'
+ '</div>'
+ '<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>'
+ '</div>'
$(accordionHTML).appendTo('#qunit-fixture')
var $target = $('#linkTrigger')
$('#collapseOne').on('shown.bs.collapse', function () {
assert.ok($(this).hasClass('show'))
assert.ok(!$('#collapseTwo').hasClass('show'))
var $trigger = $('#linkTrigger')
var $triggerTwo = $('#linkTriggerTwo')
var $collapseOne = $('#collapseOne')
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()
})
$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) {

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-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-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-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",
@ -38,7 +38,9 @@
"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-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-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/",
@ -51,7 +53,10 @@
"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 ..",
"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",
"sass": "scss/bootstrap.scss",
@ -76,11 +81,10 @@
"babel-preset-es2015": "^7.0.0-alpha.7",
"clean-css-cli": "^4.0.12",
"eslint": "^3.19.0",
"grunt": "^1.0.1",
"grunt-saucelabs": "^9.0.0",
"htmlhint": "^0.9.13",
"htmllint-cli": "^0.0.6",
"node-sass": "^4.5.2",
"nodemon": "^1.11.0",
"npm-run-all": "^4.0.2",
"phantomjs-prebuilt": "^2.1.14",
"postcss-cli": "^3.1.1",