diff --git a/bundlesize.config.json b/bundlesize.config.json new file mode 100644 index 000000000..33ef147c9 --- /dev/null +++ b/bundlesize.config.json @@ -0,0 +1,52 @@ +{ + "files": [ + { + "path": "./dist/css/bootstrap-grid.css", + "maxSize": "8 kB" + }, + { + "path": "./dist/css/bootstrap-grid.min.css", + "maxSize": "7.2 kB" + }, + { + "path": "./dist/css/bootstrap-reboot.css", + "maxSize": "2 kB" + }, + { + "path": "./dist/css/bootstrap-reboot.min.css", + "maxSize": "2 kB" + }, + { + "path": "./dist/css/bootstrap.css", + "maxSize": "25 kB" + }, + { + "path": "./dist/css/bootstrap.min.css", + "maxSize": "23 kB" + }, + { + "path": "./dist/js/bootstrap.bundle.js", + "maxSize": "51 kB" + }, + { + "path": "./dist/js/bootstrap.bundle.min.js", + "maxSize": "24 kB" + }, + { + "path": "./dist/js/bootstrap.esm.js", + "maxSize": "28 kB" + }, + { + "path": "./dist/js/bootstrap.esm.min.js", + "maxSize": "19 kB" + }, + { + "path": "./dist/js/bootstrap.js", + "maxSize": "29 kB" + }, + { + "path": "./dist/js/bootstrap.min.js", + "maxSize": "17.5 kB" + } + ] +} diff --git a/js/src/tab.js b/js/src/tab.js index 8e51c0728..a1f7d5afd 100644 --- a/js/src/tab.js +++ b/js/src/tab.js @@ -105,6 +105,7 @@ class Tab { } let hideEvent = null + this.isTransitioning = true if (previous) { hideEvent = EventHandler.trigger(previous, Event.HIDE, { @@ -137,6 +138,7 @@ class Tab { EventHandler.trigger(this._element, Event.SHOWN, { relatedTarget: previous }) + this.isTransitioning = false } if (target) { @@ -229,7 +231,8 @@ class Tab { tabListOrientation = Orientation.HORIZONTAL } - if ((tabListOrientation === Orientation.HORIZONTAL && event.which !== ARROW_LEFT_KEYCODE && event.which !== ARROW_RIGHT_KEYCODE) || (tabListOrientation === Orientation.VERTICAL && event.which !== ARROW_UP_KEYCODE && event.which !== ARROW_DOWN_KEYCODE)) { + if ((tabListOrientation === Orientation.HORIZONTAL && event.which !== ARROW_LEFT_KEYCODE && event.which !== ARROW_RIGHT_KEYCODE) || + (tabListOrientation === Orientation.VERTICAL && event.which !== ARROW_UP_KEYCODE && event.which !== ARROW_DOWN_KEYCODE)) { return } @@ -247,12 +250,19 @@ class Tab { } let index = tabs.indexOf(event.target) + const tabInstance = Data.getData(tabs[index], DATA_KEY) || new Tab(tabs[index]) - if ((event.which === ARROW_LEFT_KEYCODE || event.which === ARROW_UP_KEYCODE) && index > 0) { // Left / Up + if (tabInstance.isTransitioning) { + return + } + + // Left / Up + if ((event.which === ARROW_LEFT_KEYCODE || event.which === ARROW_UP_KEYCODE) && index > 0) { index-- } - if ((event.which === ARROW_RIGHT_KEYCODE || event.which === ARROW_DOWN_KEYCODE) && index < tabs.length - 1) { // Right / Down + // Right / Down + if ((event.which === ARROW_RIGHT_KEYCODE || event.which === ARROW_DOWN_KEYCODE) && index < tabs.length - 1) { index++ } @@ -276,27 +286,28 @@ class Tab { */ EventHandler.on(window, Event.LOAD_DATA_API, () => { - makeArray(SelectorEngine.find(Selector.TABLIST)).forEach(tablist => { - const tabs = makeArray(SelectorEngine.find(Selector.DATA_TOGGLE, tablist)) - let selectedTabFound = false + makeArray(SelectorEngine.find(Selector.TABLIST)) + .forEach(tablist => { + const tabs = makeArray(SelectorEngine.find(Selector.DATA_TOGGLE, tablist)) + let selectedTabFound = false - // iterate over each tab in the tablist, make sure they have correct tabindex/aria-selected - tabs.forEach(tab => { - if (tab.getAttribute('aria-selected') === 'true' && !selectedTabFound) { - tab.setAttribute('tabindex', '0') - selectedTabFound = true - } else { - tab.setAttribute('tabindex', '-1') - tab.setAttribute('aria-selected', 'false') + // iterate over each tab in the tablist, make sure they have correct tabindex/aria-selected + tabs.forEach(tab => { + if (tab.getAttribute('aria-selected') === 'true' && !selectedTabFound) { + tab.setAttribute('tabindex', '0') + selectedTabFound = true + } else { + tab.setAttribute('tabindex', '-1') + tab.setAttribute('aria-selected', 'false') + } + }) + + // if none of the tabs were explicitly marked as selected, pick first one + if (!selectedTabFound) { + tabs[0].setAttribute('tabindex', '0') + tabs[0].setAttribute('aria-selected', 'true') } }) - - // if none of the tabs were explicitly marked as selected, pick first one - if (!selectedTabFound) { - tabs[0].setAttribute('tabindex', '0') - tabs[0].setAttribute('aria-selected', 'true') - } - }) }) EventHandler.on(document, Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Tab._dataApiKeydownHandler) EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { diff --git a/package-lock.json b/package-lock.json index 3db0d8409..5854ceb89 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1348,9 +1348,9 @@ "dev": true }, "axios": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz", - "integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", + "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", "dev": true, "requires": { "follow-redirects": "1.5.10", @@ -1860,76 +1860,21 @@ "dev": true }, "bundlesize": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/bundlesize/-/bundlesize-0.17.2.tgz", - "integrity": "sha512-cJAZ6wvs6IHQCnUn9kTme4GL+ahoICjcS0QPcGTj61Hl4bCc8wKkkVLUote4k/1yxa0+kUIrIo9wyNJ+XIciEw==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/bundlesize/-/bundlesize-0.18.0.tgz", + "integrity": "sha512-GZURr25umfYxZYZUyOlOtJRbYjAn0VfbjbnS0NBcOiF8VcjmhoEhmx8Gw4va8HeQb8j7Ra0ZltY/IeHgSHFXFw==", "dev": true, "requires": { - "axios": "^0.18.0", + "axios": "^0.19.0", "brotli-size": "0.1.0", "bytes": "^3.1.0", "ci-env": "^1.4.0", "commander": "^2.20.0", + "cosmiconfig": "^5.2.1", "github-build": "^1.2.0", "glob": "^7.1.4", "gzip-size": "^4.0.0", - "prettycli": "^1.4.3", - "read-pkg-up": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - } - } + "prettycli": "^1.4.3" } }, "bytes": { @@ -2151,15 +2096,15 @@ } }, "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", + "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", "dev": true }, "ci-env": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/ci-env/-/ci-env-1.8.0.tgz", - "integrity": "sha512-OKShe5VZpuvVfJhiadgix/+lnOVJIcNLdLOrUwbllNfvHPAQzJxuNjefH3xfw3yHxAV8CDbLqXT9C4ygDtg8ow==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ci-env/-/ci-env-1.9.0.tgz", + "integrity": "sha512-GKMUVeOunoGplUXmIr3ss2OpYvp7JUwTTZ2wiVV8JtUy6U8r7MaDWuV1vjJdf7yxqs9AbELHXQGW4b/L60COdA==", "dev": true }, "ci-info": { @@ -4846,24 +4791,6 @@ "dev": true, "requires": { "axios": "0.19.0" - }, - "dependencies": { - "axios": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", - "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", - "dev": true, - "requires": { - "follow-redirects": "1.5.10", - "is-buffer": "^2.0.2" - } - }, - "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", - "dev": true - } } }, "github-from-package": { @@ -7086,9 +7013,9 @@ } }, "node-abi": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.8.0.tgz", - "integrity": "sha512-1/aa2clS0pue0HjckL62CsbhWWU35HARvBDXcJtYKbYR7LnIutmpxmXbuDMV9kEviD2lP/wACOgWmmwljghHyQ==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.9.0.tgz", + "integrity": "sha512-jmEOvv0eanWjhX8dX1pmjb7oJl1U1oR4FOh0b2GnvALwSYoOdU7sj+kLDSAyjo4pfC9aj/IxkloxdLJQhSSQBA==", "dev": true, "requires": { "semver": "^5.4.1" diff --git a/package.json b/package.json index b9db53104..cb2a216a7 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,7 @@ "autoprefixer": "^9.6.0", "babel-eslint": "^10.0.2", "babel-plugin-istanbul": "^5.1.4", - "bundlesize": "^0.17.2", + "bundlesize": "^0.18.0", "clean-css-cli": "^4.3.0", "coveralls": "^3.0.4", "cross-env": "^5.2.0", @@ -162,56 +162,6 @@ "js/{src,dist}/**/*.{js,map}", "scss/**/*.scss" ], - "bundlesize": [ - { - "path": "./dist/css/bootstrap-grid.css", - "maxSize": "8 kB" - }, - { - "path": "./dist/css/bootstrap-grid.min.css", - "maxSize": "7.2 kB" - }, - { - "path": "./dist/css/bootstrap-reboot.css", - "maxSize": "2 kB" - }, - { - "path": "./dist/css/bootstrap-reboot.min.css", - "maxSize": "2 kB" - }, - { - "path": "./dist/css/bootstrap.css", - "maxSize": "25 kB" - }, - { - "path": "./dist/css/bootstrap.min.css", - "maxSize": "23 kB" - }, - { - "path": "./dist/js/bootstrap.bundle.js", - "maxSize": "51 kB" - }, - { - "path": "./dist/js/bootstrap.bundle.min.js", - "maxSize": "24 kB" - }, - { - "path": "./dist/js/bootstrap.esm.js", - "maxSize": "28 kB" - }, - { - "path": "./dist/js/bootstrap.esm.min.js", - "maxSize": "19 kB" - }, - { - "path": "./dist/js/bootstrap.js", - "maxSize": "29 kB" - }, - { - "path": "./dist/js/bootstrap.min.js", - "maxSize": "17.5 kB" - } - ], "jspm": { "registry": "npm", "main": "js/bootstrap", diff --git a/site/content/docs/4.3/components/toasts.md b/site/content/docs/4.3/components/toasts.md index ae53d9d45..73abee96e 100644 --- a/site/content/docs/4.3/components/toasts.md +++ b/site/content/docs/4.3/components/toasts.md @@ -16,6 +16,10 @@ Things to know when using the toast plugin: - **Please note that you are responsible for positioning toasts.** - Toasts will automatically hide if you do not specify `autohide: false`. +{{< callout info >}} +{{< partial "callout-info-prefersreducedmotion.md" >}} +{{< /callout >}} + ## Examples ### Basic