Compare commits

..

5 commits

Author SHA1 Message Date
XhmikosR
f1001c0926
Merge branch 'main' into side-modals 2020-12-08 08:39:26 +02:00
XhmikosR
deb8568064
Update modal.md 2020-12-06 09:19:29 +02:00
XhmikosR
f54d63119b
Merge branch 'main' into side-modals 2020-12-06 09:12:48 +02:00
XhmikosR
d5d42c55e5 Adapt modal.md to the recent main branch changes 2020-11-14 09:35:37 +02:00
Mark Otto
638febae4c Add side modals 2020-11-14 09:35:21 +02:00
158 changed files with 2815 additions and 2178 deletions

View file

@ -18,11 +18,11 @@
},
{
"path": "./dist/css/bootstrap-utilities.css",
"maxSize": "7.5 kB"
"maxSize": "7 kB"
},
{
"path": "./dist/css/bootstrap-utilities.min.css",
"maxSize": "6.75 kB"
"maxSize": "6.25 kB"
},
{
"path": "./dist/css/bootstrap.css",

View file

@ -43,14 +43,15 @@
],
"unicorn/consistent-function-scoping": "off",
"unicorn/explicit-length-check": "off",
"unicorn/no-array-callback-reference": "off",
"unicorn/import-index": "off",
"unicorn/no-fn-reference-in-iterator": "off",
"unicorn/no-for-loop": "off",
"unicorn/no-null": "off",
"unicorn/no-unused-properties": "error",
"unicorn/no-useless-undefined": "off",
"unicorn/prefer-dom-node-append": "off",
"unicorn/prefer-dom-node-dataset": "off",
"unicorn/prefer-dom-node-remove": "off",
"unicorn/prefer-dataset": "off",
"unicorn/prefer-node-append": "off",
"unicorn/prefer-node-remove": "off",
"unicorn/prefer-optional-catch-binding": "off",
"unicorn/prefer-query-selector": "off",
"unicorn/prevent-abbreviations": "off"

View file

@ -101,12 +101,12 @@ Example:
Sometimes bugs reported to us are actually caused by bugs in the browser(s) themselves, not bugs in Bootstrap per se.
| Vendor(s) | Browser(s) | Rendering engine | Bug reporting website(s) | Notes |
| ------------- | ---------------------------- | ---------------- | ------------------------------------------------------ | -------------------------------------------------------- |
| Mozilla | Firefox | Gecko | https://bugzilla.mozilla.org/enter_bug.cgi | "Core" is normally the right product option to choose. |
| Apple | Safari | WebKit | https://bugs.webkit.org/enter_bug.cgi?product=WebKit | In Apple's bug reporter, choose "Safari" as the product. |
| Google, Opera | Chrome, Chromium, Opera v15+ | Blink | https://bugs.chromium.org/p/chromium/issues/list | Click the "New issue" button. |
| Microsoft | Edge | Blink | https://developer.microsoft.com/en-us/microsoft-edge/ | Go to "Help > Send Feedback" from the browser |
| Vendor(s) | Browser(s) | Rendering engine | Bug reporting website(s) | Notes |
| ------------- | ---------------------------- | ---------------- | --------------------------------------------------------------------- | -------------------------------------------------------- |
| Mozilla | Firefox | Gecko | https://bugzilla.mozilla.org/enter_bug.cgi | "Core" is normally the right product option to choose. |
| Apple | Safari | WebKit | https://bugs.webkit.org/enter_bug.cgi?product=WebKit | In Apple's bug reporter, choose "Safari" as the product. |
| Google, Opera | Chrome, Chromium, Opera v15+ | Blink | https://bugs.chromium.org/p/chromium/issues/list | Click the "New issue" button. |
| Microsoft | Edge | Blink | https://developer.microsoft.com/en-us/microsoft-edge/ | Go to "Help > Send Feedback" from the browser |
## Feature requests
@ -134,9 +134,9 @@ Please adhere to the [coding guidelines](#code-guidelines) used throughout the
project (indentation, accurate comments, etc.) and any other requirements
(such as test coverage).
**Do not edit `bootstrap.css` or `bootstrap.js`, and do not commit
any dist files (`dist/` or `js/dist`).** Those files are automatically generated by our build tools. You should
edit the source files in [`/bootstrap/scss/`](https://github.com/twbs/bootstrap/tree/main/scss)
**Do not edit `bootstrap.css`, or `bootstrap.js`
directly!** Those files are automatically generated. You should edit the
source files in [`/bootstrap/scss/`](https://github.com/twbs/bootstrap/tree/main/scss)
and/or [`/bootstrap/js/src/`](https://github.com/twbs/bootstrap/tree/main/js/src) instead.
Similarly, when contributing to Bootstrap's documentation, you should edit the

View file

@ -15,10 +15,3 @@ updates:
- v5
versioning-strategy: increase
rebase-strategy: disabled
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: weekly
day: tuesday
time: "12:00"
timezone: Europe/Athens

View file

@ -4,9 +4,6 @@ prerelease: true
exclude-labels:
- 'skip-changelog'
categories:
- title: '❗ Breaking Changes'
labels:
- 'breaking-change'
- title: '🚀 Features'
labels:
- 'new-feature'
@ -17,9 +14,6 @@ categories:
- 'fix'
- 'bugfix'
- 'bug'
- title: '⚡ Performance Improvements'
labels:
- 'performance'
- title: '🎨 CSS'
labels:
- 'css'
@ -32,19 +26,11 @@ categories:
- title: '🌎 Accessibility'
labels:
- 'accessibility'
- title: '🔧 Utility API'
labels:
- 'utility API'
- 'utilities'
- title: '🏭 Tests'
labels:
- 'tests'
- title: '🧰 Misc'
labels:
- 'build'
- 'meta'
- 'chore'
- 'CI'
- title: '📦 Dependencies'
labels:
- 'dependencies'

View file

@ -4,21 +4,21 @@ on:
push:
env:
CI: true
FORCE_COLOR: 2
NODE: 14
NODE: 14.x
jobs:
browserstack:
runs-on: ubuntu-latest
if: github.repository == 'twbs/bootstrap' && (!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]'))
timeout-minutes: 30
steps:
- name: Clone repository
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v1
with:
node-version: "${{ env.NODE }}"
@ -28,8 +28,8 @@ jobs:
path: ~/.npm
key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
${{ runner.os }}-node-v${{ env.NODE }}-
${{ runner.OS }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
${{ runner.OS }}-node-v${{ env.NODE }}-
- name: Install npm dependencies
run: npm ci

View file

@ -7,8 +7,9 @@ on:
pull_request:
env:
CI: true
FORCE_COLOR: 2
NODE: 14
NODE: 14.x
jobs:
bundlewatch:
@ -19,7 +20,7 @@ jobs:
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v1
with:
node-version: "${{ env.NODE }}"
@ -29,8 +30,8 @@ jobs:
path: ~/.npm
key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
${{ runner.os }}-node-v${{ env.NODE }}-
${{ runner.OS }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
${{ runner.OS }}-node-v${{ env.NODE }}-
- name: Install npm dependencies
run: npm ci

View file

@ -22,6 +22,15 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL

View file

@ -7,8 +7,9 @@ on:
pull_request:
env:
CI: true
FORCE_COLOR: 2
NODE: 14
NODE: 14.x
jobs:
css:
@ -19,7 +20,7 @@ jobs:
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v1
with:
node-version: "${{ env.NODE }}"
@ -29,8 +30,8 @@ jobs:
path: ~/.npm
key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
${{ runner.os }}-node-v${{ env.NODE }}-
${{ runner.OS }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
${{ runner.OS }}-node-v${{ env.NODE }}-
- name: Install npm dependencies
run: npm ci

View file

@ -7,8 +7,9 @@ on:
pull_request:
env:
CI: true
FORCE_COLOR: 2
NODE: 14
NODE: 14.x
jobs:
docs:
@ -19,7 +20,7 @@ jobs:
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v1
with:
node-version: "${{ env.NODE }}"
@ -31,8 +32,8 @@ jobs:
path: ~/.npm
key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
${{ runner.os }}-node-v${{ env.NODE }}-
${{ runner.OS }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
${{ runner.OS }}-node-v${{ env.NODE }}-
- name: Install npm dependencies
run: npm ci

View file

@ -7,6 +7,7 @@ on:
pull_request:
env:
CI: true
FORCE_COLOR: 2
jobs:
@ -24,7 +25,7 @@ jobs:
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
@ -34,8 +35,8 @@ jobs:
path: ~/.npm
key: ${{ runner.os }}-node-v${{ matrix.node }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}}
restore-keys: |
${{ runner.os }}-node-v${{ matrix.node }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
${{ runner.os }}-node-v${{ matrix.node }}-
${{ runner.OS }}-node-v${{ matrix.node }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
${{ runner.OS }}-node-v${{ matrix.node }}-
- name: Install npm dependencies
run: npm ci

View file

@ -7,8 +7,9 @@ on:
pull_request:
env:
CI: true
FORCE_COLOR: 2
NODE: 14
NODE: 14.x
jobs:
lint:
@ -19,7 +20,7 @@ jobs:
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v1
with:
node-version: "${{ env.NODE }}"
@ -29,8 +30,8 @@ jobs:
path: ~/.npm
key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
${{ runner.os }}-node-v${{ env.NODE }}-
${{ runner.OS }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}
${{ runner.OS }}-node-v${{ env.NODE }}-
- name: Install npm dependencies
run: npm ci

View file

@ -7,8 +7,9 @@ on:
pull_request:
env:
CI: true
FORCE_COLOR: 2
NODE: 14
NODE: 14.x
jobs:
css:
@ -19,7 +20,7 @@ jobs:
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v1
with:
node-version: "${{ env.NODE }}"

11
.gitignore vendored
View file

@ -1,8 +1,19 @@
# Ignore docs files
/_gh_pages/
# This is the old Jekyll docs dist folder;
# keeping it here so that when we switch branches it doesn't show up
/site/docs/**/dist/
# Jekyll's cache folder; keeping it for the same reason as above
/site/.jekyll-cache/
# Hugo resources folder
/resources/
# Ignore ruby/bundler files;
# keeping them here so that when we switch branches they don't show up
/.bundle/
/vendor/
/.ruby-version
# Numerous always-ignore extensions
*.diff
*.err

View file

@ -3,10 +3,6 @@
"stylelint-config-twbs-bootstrap/scss"
],
"rules": {
"declaration-property-value-disallowed-list": {
"border": "none",
"outline": "none"
},
"function-disallowed-list": [
"calc",
"lighten",

View file

@ -1,7 +1,7 @@
The MIT License (MIT)
Copyright (c) 2011-2021 Twitter, Inc.
Copyright (c) 2011-2021 The Bootstrap Authors
Copyright (c) 2011-2020 Twitter, Inc.
Copyright (c) 2011-2020 The Bootstrap Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -236,4 +236,4 @@ Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com
## Copyright and license
Code and documentation copyright 20112021 the [Bootstrap Authors](https://github.com/twbs/bootstrap/graphs/contributors) and [Twitter, Inc.](https://twitter.com) Code released under the [MIT License](https://github.com/twbs/bootstrap/blob/main/LICENSE). Docs released under [Creative Commons](https://creativecommons.org/licenses/by/3.0/).
Code and documentation copyright 20112020 the [Bootstrap Authors](https://github.com/twbs/bootstrap/graphs/contributors) and [Twitter, Inc.](https://twitter.com) Code released under the [MIT License](https://github.com/twbs/bootstrap/blob/main/LICENSE). Docs released under [Creative Commons](https://creativecommons.org/licenses/by/3.0/).

View file

@ -2,8 +2,8 @@
/*!
* Script to build our plugins to use them separately.
* Copyright 2020-2021 The Bootstrap Authors
* Copyright 2020-2021 Twitter, Inc.
* Copyright 2020 The Bootstrap Authors
* Copyright 2020 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
@ -29,7 +29,6 @@ const bsPlugins = {
Manipulator: path.resolve(__dirname, '../js/src/dom/manipulator.js'),
SelectorEngine: path.resolve(__dirname, '../js/src/dom/selector-engine.js'),
Alert: path.resolve(__dirname, '../js/src/alert.js'),
Base: path.resolve(__dirname, '../js/src/base-component.js'),
Button: path.resolve(__dirname, '../js/src/button.js'),
Carousel: path.resolve(__dirname, '../js/src/carousel.js'),
Collapse: path.resolve(__dirname, '../js/src/collapse.js'),
@ -45,13 +44,11 @@ const bsPlugins = {
const defaultPluginConfig = {
external: [
bsPlugins.Data,
bsPlugins.Base,
bsPlugins.EventHandler,
bsPlugins.SelectorEngine
],
globals: {
[bsPlugins.Data]: 'Data',
[bsPlugins.Base]: 'Base',
[bsPlugins.EventHandler]: 'EventHandler',
[bsPlugins.SelectorEngine]: 'SelectorEngine'
}
@ -76,7 +73,6 @@ const getConfigByPluginKey = pluginKey => {
}
if (
pluginKey === 'Base' ||
pluginKey === 'Button' ||
pluginKey === 'Carousel' ||
pluginKey === 'Collapse' ||
@ -116,13 +112,11 @@ const getConfigByPluginKey = pluginKey => {
return {
external: [
bsPlugins.Data,
bsPlugins.Base,
bsPlugins.EventHandler,
bsPlugins.Manipulator
],
globals: {
[bsPlugins.Data]: 'Data',
[bsPlugins.Base]: 'Base',
[bsPlugins.EventHandler]: 'EventHandler',
[bsPlugins.Manipulator]: 'Manipulator'
}

View file

@ -2,8 +2,8 @@
/*!
* Script to update version number references in the project.
* Copyright 2017-2021 The Bootstrap Authors
* Copyright 2017-2021 Twitter, Inc.
* Copyright 2017-2020 The Bootstrap Authors
* Copyright 2017-2020 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View file

@ -5,8 +5,8 @@
* Remember to use the same vendor files as the CDN ones,
* otherwise the hashes won't match!
*
* Copyright 2017-2021 The Bootstrap Authors
* Copyright 2017-2021 Twitter, Inc.
* Copyright 2017-2020 The Bootstrap Authors
* Copyright 2017-2020 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View file

@ -2,8 +2,8 @@
/*!
* Script to run vnu-jar if Java is available.
* Copyright 2017-2021 The Bootstrap Authors
* Copyright 2017-2021 Twitter, Inc.
* Copyright 2017-2020 The Bootstrap Authors
* Copyright 2017-2020 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View file

@ -3,7 +3,7 @@
/*!
* Script to create the built examples zip archive;
* requires the `zip` command to be present!
* Copyright 2020-2021 The Bootstrap Authors
* Copyright 2020 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
@ -12,67 +12,36 @@
const path = require('path')
const sh = require('shelljs')
const pkg = require('../package.json')
const { version, version_short: versionShort } = require('../package.json')
const versionShort = pkg.config.version_short
const distFolder = `bootstrap-${pkg.version}-examples`
const rootDocsDir = '_gh_pages'
const docsDir = `${rootDocsDir}/docs/${versionShort}/`
// these are the files we need in the examples
const cssFiles = [
'bootstrap.min.css',
'bootstrap.min.css.map',
'bootstrap.rtl.min.css',
'bootstrap.rtl.min.css.map'
]
const jsFiles = [
'bootstrap.bundle.min.js',
'bootstrap.bundle.min.js.map'
]
const imgFiles = [
'bootstrap-logo.svg',
'bootstrap-logo-white.svg'
]
const folderName = `bootstrap-${version}-examples`
sh.config.fatal = true
if (!sh.test('-d', rootDocsDir)) {
throw new Error(`The "${rootDocsDir}" folder does not exist, did you forget building the docs?`)
if (!sh.test('-d', '_gh_pages')) {
throw new Error('The "_gh_pages" folder does not exist, did you forget building the docs?')
}
// switch to the root dir
sh.cd(path.join(__dirname, '..'))
// remove any previously created folder/zip with the same name
sh.rm('-rf', [distFolder, `${distFolder}.zip`])
// remove any previously created folder with the same name
sh.rm('-rf', folderName)
// create any folders so that `cp` works
sh.mkdir('-p', [
distFolder,
`${distFolder}/assets/brand/`,
`${distFolder}/assets/dist/css/`,
`${distFolder}/assets/dist/js/`
])
sh.mkdir('-p', folderName)
sh.mkdir('-p', `${folderName}/assets/brand/`)
sh.cp('-Rf', `${docsDir}/examples/*`, distFolder)
cssFiles.forEach(file => {
sh.cp('-f', `${docsDir}/dist/css/${file}`, `${distFolder}/assets/dist/css/`)
})
jsFiles.forEach(file => {
sh.cp('-f', `${docsDir}/dist/js/${file}`, `${distFolder}/assets/dist/js/`)
})
imgFiles.forEach(file => {
sh.cp('-f', `${docsDir}/assets/brand/${file}`, `${distFolder}/assets/brand/`)
})
sh.rm(`${distFolder}/index.html`)
sh.cp('-Rf', `_gh_pages/docs/${versionShort}/examples/*`, folderName)
sh.cp('-Rf', `_gh_pages/docs/${versionShort}/dist/`, `${folderName}/assets/`)
// also copy the two brand images we use in the examples
sh.cp('-f', [
`_gh_pages/docs/${versionShort}/assets/brand/bootstrap-logo.svg`,
`_gh_pages/docs/${versionShort}/assets/brand/bootstrap-logo-white.svg`
], `${folderName}/assets/brand/`)
sh.rm(`${folderName}/index.html`)
// get all examples' HTML files
sh.find(`${distFolder}/**/*.html`).forEach(file => {
sh.find(`${folderName}/**/*.html`).forEach(file => {
const fileContents = sh.cat(file)
.toString()
.replace(new RegExp(`"/docs/${versionShort}/`, 'g'), '"../')
@ -84,7 +53,7 @@ sh.find(`${distFolder}/**/*.html`).forEach(file => {
})
// create the zip file
sh.exec(`zip -r9 "${distFolder}.zip" "${distFolder}"`)
sh.exec(`zip -r9 "${folderName}.zip" "${folderName}"`, { fatal: true })
// remove the folder we created
sh.rm('-rf', distFolder)
sh.rm('-rf', folderName)

View file

@ -75,5 +75,5 @@ params:
js_hash: "sha384-pQQkAEnwaBkjpqZ8RU1fF1AKtTcHJwFl3pblpTlHXybJjHpMYo79HY3hIi4NKxyj"
js_bundle: "https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
js_bundle_hash: "sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
popper: "https://cdn.jsdelivr.net/npm/@popperjs/core@2.6.0/dist/umd/popper.min.js"
popper_hash: "sha384-KsvD1yqQ1/1+IA7gi3P0tyJcT3vR+NdBTt13hSJ2lnve8agRGXTTyNaBYmCR/Nwi"
popper: "https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js"
popper_hash: "sha384-q2kxQ16AaE6UbzuKqyBE9/u/KzioAlnx2maXQHiDX9d4/zp8Ok3f+M7DPm+Ib6IU"

View file

@ -7,6 +7,7 @@
import {
defineJQueryPlugin,
TRANSITION_END,
emulateTransitionEnd,
getElementFromSelector,
getTransitionDurationFromElement
@ -32,9 +33,9 @@ const EVENT_CLOSE = `close${EVENT_KEY}`
const EVENT_CLOSED = `closed${EVENT_KEY}`
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
const CLASS_NAME_ALERT = 'alert'
const CLASS_NAME_FADE = 'fade'
const CLASS_NAME_SHOW = 'show'
const CLASSNAME_ALERT = 'alert'
const CLASSNAME_FADE = 'fade'
const CLASSNAME_SHOW = 'show'
/**
* ------------------------------------------------------------------------
@ -65,7 +66,7 @@ class Alert extends BaseComponent {
// Private
_getRootElement(element) {
return getElementFromSelector(element) || element.closest(`.${CLASS_NAME_ALERT}`)
return getElementFromSelector(element) || element.closest(`.${CLASSNAME_ALERT}`)
}
_triggerCloseEvent(element) {
@ -73,16 +74,16 @@ class Alert extends BaseComponent {
}
_removeElement(element) {
element.classList.remove(CLASS_NAME_SHOW)
element.classList.remove(CLASSNAME_SHOW)
if (!element.classList.contains(CLASS_NAME_FADE)) {
if (!element.classList.contains(CLASSNAME_FADE)) {
this._destroyElement(element)
return
}
const transitionDuration = getTransitionDurationFromElement(element)
EventHandler.one(element, 'transitionend', () => this._destroyElement(element))
EventHandler.one(element, TRANSITION_END, () => this._destroyElement(element))
emulateTransitionEnd(element, transitionDuration)
}

View file

@ -7,11 +7,11 @@
import {
defineJQueryPlugin,
TRANSITION_END,
emulateTransitionEnd,
getElementFromSelector,
getTransitionDurationFromElement,
isVisible,
isRTL,
reflow,
triggerTransitionEnd,
typeCheckConfig
@ -93,8 +93,10 @@ const SELECTOR_INDICATORS = '.carousel-indicators'
const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]'
const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]'
const POINTER_TYPE_TOUCH = 'touch'
const POINTER_TYPE_PEN = 'pen'
const PointerType = {
TOUCH: 'touch',
PEN: 'pen'
}
/**
* ------------------------------------------------------------------------
@ -251,20 +253,12 @@ class Carousel extends BaseComponent {
// swipe left
if (direction > 0) {
if (isRTL) {
this.next()
} else {
this.prev()
}
this.prev()
}
// swipe right
if (direction < 0) {
if (isRTL) {
this.prev()
} else {
this.next()
}
this.next()
}
}
@ -285,7 +279,7 @@ class Carousel extends BaseComponent {
_addTouchEventListeners() {
const start = event => {
if (this._pointerEvent && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)) {
if (this._pointerEvent && PointerType[event.pointerType.toUpperCase()]) {
this.touchStartX = event.clientX
} else if (!this._pointerEvent) {
this.touchStartX = event.touches[0].clientX
@ -302,7 +296,7 @@ class Carousel extends BaseComponent {
}
const end = event => {
if (this._pointerEvent && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)) {
if (this._pointerEvent && PointerType[event.pointerType.toUpperCase()]) {
this.touchDeltaX = event.clientX - this.touchStartX
}
@ -346,20 +340,16 @@ class Carousel extends BaseComponent {
return
}
if (event.key === ARROW_LEFT_KEY) {
event.preventDefault()
if (isRTL) {
this.next()
} else {
switch (event.key) {
case ARROW_LEFT_KEY:
event.preventDefault()
this.prev()
}
} else if (event.key === ARROW_RIGHT_KEY) {
event.preventDefault()
if (isRTL) {
this.prev()
} else {
break
case ARROW_RIGHT_KEY:
event.preventDefault()
this.next()
}
break
default:
}
}
@ -446,9 +436,19 @@ class Carousel extends BaseComponent {
const nextElementIndex = this._getItemIndex(nextElement)
const isCycling = Boolean(this._interval)
const directionalClassName = direction === DIRECTION_NEXT ? CLASS_NAME_START : CLASS_NAME_END
const orderClassName = direction === DIRECTION_NEXT ? CLASS_NAME_NEXT : CLASS_NAME_PREV
const eventDirectionName = direction === DIRECTION_NEXT ? DIRECTION_LEFT : DIRECTION_RIGHT
let directionalClassName
let orderClassName
let eventDirectionName
if (direction === DIRECTION_NEXT) {
directionalClassName = CLASS_NAME_START
orderClassName = CLASS_NAME_NEXT
eventDirectionName = DIRECTION_LEFT
} else {
directionalClassName = CLASS_NAME_END
orderClassName = CLASS_NAME_PREV
eventDirectionName = DIRECTION_RIGHT
}
if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE)) {
this._isSliding = false
@ -484,7 +484,7 @@ class Carousel extends BaseComponent {
const transitionDuration = getTransitionDurationFromElement(activeElement)
EventHandler.one(activeElement, 'transitionend', () => {
EventHandler.one(activeElement, TRANSITION_END, () => {
nextElement.classList.remove(directionalClassName, orderClassName)
nextElement.classList.add(CLASS_NAME_ACTIVE)

View file

@ -7,6 +7,7 @@
import {
defineJQueryPlugin,
TRANSITION_END,
emulateTransitionEnd,
getSelectorFromElement,
getElementFromSelector,
@ -202,7 +203,7 @@ class Collapse extends BaseComponent {
const scrollSize = `scroll${capitalizedDimension}`
const transitionDuration = getTransitionDurationFromElement(this._element)
EventHandler.one(this._element, 'transitionend', complete)
EventHandler.one(this._element, TRANSITION_END, complete)
emulateTransitionEnd(this._element, transitionDuration)
this._element.style[dimension] = `${this._element[scrollSize]}px`
@ -252,7 +253,7 @@ class Collapse extends BaseComponent {
this._element.style[dimension] = ''
const transitionDuration = getTransitionDurationFromElement(this._element)
EventHandler.one(this._element, 'transitionend', complete)
EventHandler.one(this._element, TRANSITION_END, complete)
emulateTransitionEnd(this._element, transitionDuration)
}
@ -371,7 +372,7 @@ class Collapse extends BaseComponent {
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
// preventDefault only for <a> elements (which change the URL) not inside the collapsible element
if (event.target.tagName === 'A' || (event.delegateTarget && event.delegateTarget.tagName === 'A')) {
if (event.target.tagName === 'A') {
event.preventDefault()
}

View file

@ -112,7 +112,6 @@ function bootstrapDelegationHandler(element, selector, fn) {
event.delegateTarget = target
if (handler.oneOff) {
// eslint-disable-next-line unicorn/consistent-destructuring
EventHandler.off(element, event.type, fn)
}

View file

@ -23,8 +23,9 @@ const SelectorEngine = {
},
children(element, selector) {
return [].concat(...element.children)
.filter(child => child.matches(selector))
const children = [].concat(...element.children)
return children.filter(child => child.matches(selector))
},
parents(element, selector) {

View file

@ -84,7 +84,7 @@ const DefaultType = {
offset: '(number|string|function)',
flip: 'boolean',
boundary: '(string|element)',
reference: '(string|element|object)',
reference: '(string|element)',
display: 'string',
popperConfig: '(null|object)'
}
@ -172,8 +172,6 @@ class Dropdown extends BaseComponent {
if (typeof this._config.reference.jquery !== 'undefined') {
referenceElement = this._config.reference[0]
}
} else if (typeof this._config.reference === 'object') {
referenceElement = this._config.reference
}
this._popper = Popper.createPopper(referenceElement, this._menu, this._getPopperConfig())
@ -259,13 +257,6 @@ class Dropdown extends BaseComponent {
typeCheckConfig(NAME, config, this.constructor.DefaultType)
if (typeof config.reference === 'object' && !isElement(config.reference) &&
typeof config.reference.getBoundingClientRect !== 'function'
) {
// Popper virtual elements require a getBoundingClientRect method
throw new TypeError(`${NAME.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`)
}
return config
}
@ -307,12 +298,6 @@ class Dropdown extends BaseComponent {
altBoundary: this._config.flip,
rootBoundary: this._config.boundary
}
},
{
name: 'flip',
options: {
fallbackPlacements: ['top', 'right', 'bottom', 'left']
}
}]
}

View file

@ -7,6 +7,7 @@
import {
defineJQueryPlugin,
TRANSITION_END,
emulateTransitionEnd,
getElementFromSelector,
getTransitionDurationFromElement,
@ -183,7 +184,7 @@ class Modal extends BaseComponent {
if (transition) {
const transitionDuration = getTransitionDurationFromElement(this._element)
EventHandler.one(this._element, 'transitionend', event => this._hideModal(event))
EventHandler.one(this._element, TRANSITION_END, event => this._hideModal(event))
emulateTransitionEnd(this._element, transitionDuration)
} else {
this._hideModal()
@ -271,7 +272,7 @@ class Modal extends BaseComponent {
if (transition) {
const transitionDuration = getTransitionDurationFromElement(this._dialog)
EventHandler.one(this._dialog, 'transitionend', transitionComplete)
EventHandler.one(this._dialog, TRANSITION_END, transitionComplete)
emulateTransitionEnd(this._dialog, transitionDuration)
} else {
transitionComplete()
@ -376,7 +377,7 @@ class Modal extends BaseComponent {
const backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop)
EventHandler.one(this._backdrop, 'transitionend', callback)
EventHandler.one(this._backdrop, TRANSITION_END, callback)
emulateTransitionEnd(this._backdrop, backdropTransitionDuration)
} else if (!this._isShown && this._backdrop) {
this._backdrop.classList.remove(CLASS_NAME_SHOW)
@ -388,7 +389,7 @@ class Modal extends BaseComponent {
if (this._element.classList.contains(CLASS_NAME_FADE)) {
const backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop)
EventHandler.one(this._backdrop, 'transitionend', callbackRemove)
EventHandler.one(this._backdrop, TRANSITION_END, callbackRemove)
emulateTransitionEnd(this._backdrop, backdropTransitionDuration)
} else {
callbackRemove()
@ -412,11 +413,11 @@ class Modal extends BaseComponent {
this._element.classList.add(CLASS_NAME_STATIC)
const modalTransitionDuration = getTransitionDurationFromElement(this._dialog)
EventHandler.off(this._element, 'transitionend')
EventHandler.one(this._element, 'transitionend', () => {
EventHandler.off(this._element, TRANSITION_END)
EventHandler.one(this._element, TRANSITION_END, () => {
this._element.classList.remove(CLASS_NAME_STATIC)
if (!isModalOverflowing) {
EventHandler.one(this._element, 'transitionend', () => {
EventHandler.one(this._element, TRANSITION_END, () => {
this._element.style.overflowY = ''
})
emulateTransitionEnd(this._element, modalTransitionDuration)
@ -590,7 +591,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
data = new Modal(target, config)
}
data.toggle(this)
data.show(this)
})
/**

View file

@ -76,7 +76,7 @@ class ScrollSpy extends BaseComponent {
this._activeTarget = null
this._scrollHeight = 0
EventHandler.on(this._scrollElement, EVENT_SCROLL, () => this._process())
EventHandler.on(this._scrollElement, EVENT_SCROLL, event => this._process(event))
this.refresh()
this._process()

View file

@ -7,6 +7,7 @@
import {
defineJQueryPlugin,
TRANSITION_END,
emulateTransitionEnd,
getElementFromSelector,
getTransitionDurationFromElement,
@ -81,11 +82,13 @@ class Tab extends BaseComponent {
previous = previous[previous.length - 1]
}
const hideEvent = previous ?
EventHandler.trigger(previous, EVENT_HIDE, {
let hideEvent = null
if (previous) {
hideEvent = EventHandler.trigger(previous, EVENT_HIDE, {
relatedTarget: this._element
}) :
null
})
}
const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
relatedTarget: previous
@ -129,7 +132,7 @@ class Tab extends BaseComponent {
const transitionDuration = getTransitionDurationFromElement(active)
active.classList.remove(CLASS_NAME_SHOW)
EventHandler.one(active, 'transitionend', complete)
EventHandler.one(active, TRANSITION_END, complete)
emulateTransitionEnd(active, transitionDuration)
} else {
complete()

View file

@ -7,6 +7,7 @@
import {
defineJQueryPlugin,
TRANSITION_END,
emulateTransitionEnd,
getTransitionDurationFromElement,
reflow,
@ -115,7 +116,7 @@ class Toast extends BaseComponent {
if (this._config.animation) {
const transitionDuration = getTransitionDurationFromElement(this._element)
EventHandler.one(this._element, 'transitionend', complete)
EventHandler.one(this._element, TRANSITION_END, complete)
emulateTransitionEnd(this._element, transitionDuration)
} else {
complete()
@ -142,7 +143,7 @@ class Toast extends BaseComponent {
if (this._config.animation) {
const transitionDuration = getTransitionDurationFromElement(this._element)
EventHandler.one(this._element, 'transitionend', complete)
EventHandler.one(this._element, TRANSITION_END, complete)
emulateTransitionEnd(this._element, transitionDuration)
} else {
complete()

View file

@ -9,6 +9,7 @@ import * as Popper from '@popperjs/core'
import {
defineJQueryPlugin,
TRANSITION_END,
emulateTransitionEnd,
findShadowRoot,
getTransitionDurationFromElement,
@ -51,7 +52,7 @@ const DefaultType = {
selector: '(string|boolean)',
placement: '(string|function)',
container: '(string|element|boolean)',
fallbackPlacements: 'array',
fallbackPlacements: '(null|array)',
boundary: '(string|element)',
customClass: '(string|function)',
sanitize: 'boolean',
@ -81,7 +82,7 @@ const Default = {
selector: false,
placement: 'top',
container: false,
fallbackPlacements: ['top', 'right', 'bottom', 'left'],
fallbackPlacements: null,
boundary: 'clippingParents',
customClass: '',
sanitize: true,
@ -222,7 +223,7 @@ class Tooltip extends BaseComponent {
EventHandler.off(this._element, this.constructor.EVENT_KEY)
EventHandler.off(this._element.closest(`.${CLASS_NAME_MODAL}`), 'hide.bs.modal', this._hideModalHandler)
if (this.tip && this.tip.parentNode) {
if (this.tip) {
this.tip.parentNode.removeChild(this.tip)
}
@ -316,7 +317,7 @@ class Tooltip extends BaseComponent {
if (this.tip.classList.contains(CLASS_NAME_FADE)) {
const transitionDuration = getTransitionDurationFromElement(this.tip)
EventHandler.one(this.tip, 'transitionend', complete)
EventHandler.one(this.tip, TRANSITION_END, complete)
emulateTransitionEnd(this.tip, transitionDuration)
} else {
complete()
@ -366,7 +367,7 @@ class Tooltip extends BaseComponent {
if (this.tip.classList.contains(CLASS_NAME_FADE)) {
const transitionDuration = getTransitionDurationFromElement(tip)
EventHandler.one(tip, 'transitionend', complete)
EventHandler.one(tip, TRANSITION_END, complete)
emulateTransitionEnd(tip, transitionDuration)
} else {
complete()
@ -466,16 +467,21 @@ class Tooltip extends BaseComponent {
// Private
_getPopperConfig(attachment) {
const flipModifier = {
name: 'flip',
options: {
altBoundary: true
}
}
if (this.config.fallbackPlacements) {
flipModifier.options.fallbackPlacements = this.config.fallbackPlacements
}
const defaultBsConfig = {
placement: attachment,
modifiers: [
{
name: 'flip',
options: {
altBoundary: true,
fallbackPlacements: this.config.fallbackPlacements
}
},
flipModifier,
{
name: 'preventOverflow',
options: {

View file

@ -111,14 +111,15 @@ const typeCheckConfig = (componentName, config, configTypes) => {
Object.keys(configTypes).forEach(property => {
const expectedTypes = configTypes[property]
const value = config[property]
const valueType = value && isElement(value) ? 'element' : toType(value)
const valueType = value && isElement(value) ?
'element' :
toType(value)
if (!new RegExp(expectedTypes).test(valueType)) {
throw new TypeError(
throw new Error(
`${componentName.toUpperCase()}: ` +
`Option "${property}" provided type "${valueType}" ` +
`but expected type "${expectedTypes}".`
)
`but expected type "${expectedTypes}".`)
}
})
}
@ -204,6 +205,7 @@ const defineJQueryPlugin = (name, plugin) => {
}
export {
TRANSITION_END,
getUID,
getSelectorFromElement,
getElementFromSelector,

View file

@ -37,7 +37,7 @@ const allowedAttribute = (attr, allowedAttributeList) => {
if (allowedAttributeList.includes(attrName)) {
if (uriAttrs.has(attrName)) {
return Boolean(SAFE_URL_PATTERN.test(attr.nodeValue) || DATA_URL_PATTERN.test(attr.nodeValue))
return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))
}
return true
@ -47,7 +47,7 @@ const allowedAttribute = (attr, allowedAttributeList) => {
// Check if a regular expression validates the attribute.
for (let i = 0, len = regExp.length; i < len; i++) {
if (regExp[i].test(attrName)) {
if (attrName.match(regExp[i])) {
return true
}
}

View file

@ -5,21 +5,21 @@ const browsers = {
safariMac: {
base: 'BrowserStack',
os: 'OS X',
os_version: 'Catalina',
os_version: 'High Sierra',
browser: 'Safari',
browser_version: 'latest'
},
chromeMac: {
base: 'BrowserStack',
os: 'OS X',
os_version: 'Catalina',
os_version: 'High Sierra',
browser: 'Chrome',
browser_version: 'latest'
},
firefoxMac: {
base: 'BrowserStack',
os: 'OS X',
os_version: 'Catalina',
os_version: 'High Sierra',
browser: 'Firefox',
browser_version: 'latest'
},

View file

@ -1,7 +1,5 @@
/* eslint-env node */
'use strict'
const path = require('path')
const ip = require('ip')
const { babel } = require('@rollup/plugin-babel')
@ -14,11 +12,10 @@ const {
browsersKeys
} = require('./browsers')
const ENV = process.env
const BROWSERSTACK = Boolean(ENV.BROWSERSTACK)
const DEBUG = Boolean(ENV.DEBUG)
const JQUERY_TEST = Boolean(ENV.JQUERY)
const { env } = process
const browserStack = env.BROWSER === 'true'
const debug = env.DEBUG === 'true'
const jQueryTest = env.JQUERY === 'true'
const frameworks = [
'jasmine'
]
@ -33,16 +30,16 @@ const reporters = ['dots']
const detectBrowsers = {
usePhantomJS: false,
postDetection(availableBrowser) {
if (ENV.CI === true || availableBrowser.includes('Chrome')) {
return DEBUG ? ['Chrome'] : ['ChromeHeadless']
if (env.CI === true || availableBrowser.includes('Chrome')) {
return debug ? ['Chrome'] : ['ChromeHeadless']
}
if (availableBrowser.includes('Chromium')) {
return DEBUG ? ['Chromium'] : ['ChromiumHeadless']
return debug ? ['Chromium'] : ['ChromiumHeadless']
}
if (availableBrowser.includes('Firefox')) {
return DEBUG ? ['Firefox'] : ['FirefoxHeadless']
return debug ? ['Firefox'] : ['FirefoxHeadless']
}
throw new Error('Please install Chrome, Chromium or Firefox')
@ -62,7 +59,7 @@ const conf = {
colors: true,
autoWatch: false,
singleRun: true,
concurrency: Number.POSITIVE_INFINITY,
concurrency: Infinity,
client: {
clearContext: false
},
@ -70,7 +67,7 @@ const conf = {
'node_modules/hammer-simulator/index.js',
{
pattern: 'js/tests/unit/**/!(jquery).spec.js',
watched: !BROWSERSTACK
watched: !browserStack
}
],
preprocessors: {
@ -104,11 +101,11 @@ const conf = {
}
}
if (BROWSERSTACK) {
if (browserStack) {
conf.hostname = ip.address()
conf.browserStack = {
username: ENV.BROWSER_STACK_USERNAME,
accessKey: ENV.BROWSER_STACK_ACCESS_KEY,
username: env.BROWSER_STACK_USERNAME,
accessKey: env.BROWSER_STACK_ACCESS_KEY,
build: `bootstrap-${new Date().toISOString()}`,
project: 'Bootstrap',
retryLimit: 2
@ -117,7 +114,7 @@ if (BROWSERSTACK) {
conf.customLaunchers = browsers
conf.browsers = browsersKeys
reporters.push('BrowserStack', 'kjhtml')
} else if (JQUERY_TEST) {
} else if (jQueryTest) {
frameworks.push('detectBrowsers')
plugins.push(
'karma-chrome-launcher',
@ -158,7 +155,7 @@ if (BROWSERSTACK) {
}
}
if (DEBUG) {
if (debug) {
conf.hostname = ip.address()
plugins.push('karma-jasmine-html-reporter')
reporters.push('kjhtml')
@ -172,6 +169,7 @@ conf.plugins = plugins
conf.reporters = reporters
module.exports = karmaConfig => {
conf.logLevel = karmaConfig.LOG_ERROR
// possible values: karmaConfig.LOG_DISABLE || karmaConfig.LOG_ERROR || karmaConfig.LOG_WARN || karmaConfig.LOG_INFO || karmaConfig.LOG_DEBUG
conf.logLevel = karmaConfig.LOG_ERROR || karmaConfig.LOG_WARN
karmaConfig.set(conf)
}

View file

@ -905,7 +905,7 @@ describe('Carousel', () => {
})
describe('to', () => {
it('should go directly to the provided index', done => {
it('should go directement to the provided index', done => {
fixtureEl.innerHTML = [
'<div id="myCarousel" class="carousel slide">',
' <div class="carousel-inner">',
@ -1136,9 +1136,11 @@ describe('Carousel', () => {
jQueryMock.fn.carousel = Carousel.jQueryInterface
jQueryMock.elements = [div]
expect(() => {
try {
jQueryMock.fn.carousel.call(jQueryMock, action)
}).toThrowError(TypeError, `No method named "${action}"`)
} catch (error) {
expect(error.message).toEqual(`No method named "${action}"`)
}
})
})

View file

@ -374,29 +374,6 @@ describe('Collapse', () => {
})
describe('data-api', () => {
it('should prevent url change if click on nested elements', done => {
fixtureEl.innerHTML = [
'<a role="button" data-bs-toggle="collapse" class="collapsed" href="#collapse">',
' <span id="nested"></span>',
'</a>',
'<div id="collapse" class="collapse"></div>'
].join('')
const triggerEl = fixtureEl.querySelector('a')
const nestedTriggerEl = fixtureEl.querySelector('#nested')
spyOn(Event.prototype, 'preventDefault').and.callThrough()
triggerEl.addEventListener('click', event => {
expect(event.target.isEqualNode(nestedTriggerEl)).toEqual(true)
expect(event.delegateTarget.isEqualNode(triggerEl)).toEqual(true)
expect(Event.prototype.preventDefault).toHaveBeenCalled()
done()
})
nestedTriggerEl.click()
})
it('should show multiple collapsed elements', done => {
fixtureEl.innerHTML = [
'<a role="button" data-bs-toggle="collapse" class="collapsed" href=".multi"></a>',
@ -819,9 +796,11 @@ describe('Collapse', () => {
jQueryMock.fn.collapse = Collapse.jQueryInterface
jQueryMock.elements = [div]
expect(() => {
try {
jQueryMock.fn.collapse.call(jQueryMock, action)
}).toThrowError(TypeError, `No method named "${action}"`)
} catch (error) {
expect(error.message).toEqual(`No method named "${action}"`)
}
})
})

View file

@ -367,58 +367,6 @@ describe('Dropdown', () => {
dropdown.toggle()
})
it('should toggle a dropdown with a valid virtual element reference', done => {
fixtureEl.innerHTML = [
'<div class="dropdown">',
' <button class="btn dropdown-toggle visually-hidden" data-bs-toggle="dropdown" aria-expanded="false">Dropdown</button>',
' <div class="dropdown-menu">',
' <a class="dropdown-item" href="#">Secondary link</a>',
' </div>',
'</div>'
].join('')
const btnDropdown = fixtureEl.querySelector('[data-bs-toggle="dropdown"]')
const virtualElement = {
getBoundingClientRect() {
return {
width: 0,
height: 0,
top: 0,
right: 0,
bottom: 0,
left: 0
}
}
}
expect(() => new Dropdown(btnDropdown, {
reference: {}
})).toThrowError(TypeError, 'DROPDOWN: Option "reference" provided type "object" without a required "getBoundingClientRect" method.')
expect(() => new Dropdown(btnDropdown, {
reference: {
getBoundingClientRect: 'not-a-function'
}
})).toThrowError(TypeError, 'DROPDOWN: Option "reference" provided type "object" without a required "getBoundingClientRect" method.')
// use onFirstUpdate as Poppers internal update is executed async
const dropdown = new Dropdown(btnDropdown, {
reference: virtualElement,
popperConfig: {
onFirstUpdate() {
expect(virtualElement.getBoundingClientRect).toHaveBeenCalled()
expect(btnDropdown.classList.contains('show')).toEqual(true)
expect(btnDropdown.getAttribute('aria-expanded')).toEqual('true')
done()
}
}
})
spyOn(virtualElement, 'getBoundingClientRect').and.callThrough()
dropdown.toggle()
})
it('should not toggle a dropdown if the element is disabled', done => {
fixtureEl.innerHTML = [
'<div class="dropdown">',
@ -1557,9 +1505,11 @@ describe('Dropdown', () => {
jQueryMock.fn.dropdown = Dropdown.jQueryInterface
jQueryMock.elements = [div]
expect(() => {
try {
jQueryMock.fn.dropdown.call(jQueryMock, action)
}).toThrowError(TypeError, `No method named "${action}"`)
} catch (error) {
expect(error.message).toEqual(`No method named "${action}"`)
}
})
})

View file

@ -52,6 +52,6 @@ describe('jQuery', () => {
done()
})
$(fixtureEl).find('button').trigger('click')
$(fixtureEl).find('button').click()
})
})

View file

@ -870,7 +870,7 @@ describe('Modal', () => {
})
describe('data-api', () => {
it('should toggle modal', done => {
it('should open modal', done => {
fixtureEl.innerHTML = [
'<button type="button" data-bs-toggle="modal" data-bs-target="#exampleModal"></button>',
'<div id="exampleModal" class="modal"><div class="modal-dialog"></div></div>'
@ -885,15 +885,6 @@ describe('Modal', () => {
expect(modalEl.getAttribute('aria-hidden')).toEqual(null)
expect(modalEl.style.display).toEqual('block')
expect(document.querySelector('.modal-backdrop')).toBeDefined()
setTimeout(() => trigger.click(), 10)
})
modalEl.addEventListener('hidden.bs.modal', () => {
expect(modalEl.getAttribute('aria-modal')).toEqual(null)
expect(modalEl.getAttribute('role')).toEqual(null)
expect(modalEl.getAttribute('aria-hidden')).toEqual('true')
expect(modalEl.style.display).toEqual('none')
expect(document.querySelector('.modal-backdrop')).toEqual(null)
done()
})
@ -1070,9 +1061,11 @@ describe('Modal', () => {
jQueryMock.fn.modal = Modal.jQueryInterface
jQueryMock.elements = [div]
expect(() => {
try {
jQueryMock.fn.modal.call(jQueryMock, action)
}).toThrowError(TypeError, `No method named "${action}"`)
} catch (error) {
expect(error.message).toEqual(`No method named "${action}"`)
}
})
it('should call show method', () => {

View file

@ -206,9 +206,11 @@ describe('Popover', () => {
jQueryMock.fn.popover = Popover.jQueryInterface
jQueryMock.elements = [popoverEl]
expect(() => {
try {
jQueryMock.fn.popover.call(jQueryMock, action)
}).toThrowError(TypeError, `No method named "${action}"`)
} catch (error) {
expect(error.message).toEqual(`No method named "${action}"`)
}
})
it('should should call show method', () => {

View file

@ -68,7 +68,7 @@ describe('ScrollSpy', () => {
fixtureEl.innerHTML = [
'<nav id="navigation" class="navbar">',
' <ul class="navbar-nav">',
' <li class="nav-item"><a class="nav-link active" id="one-link" href="#">One</a></li>',
' <li class="nav-item active"><a class="nav-link" id="one-link" href="#">One</a></li>',
' <li class="nav-item"><a class="nav-link" id="two-link" href="#two">Two</a></li>',
' <li class="nav-item"><a class="nav-link" id="three-link" href="#three">Three</a></li>',
' </ul>',
@ -177,7 +177,7 @@ describe('ScrollSpy', () => {
'<div id="header" style="height: 500px;"></div>',
'<nav id="navigation" class="navbar">',
' <ul class="navbar-nav">',
' <li class="nav-item"><a class="nav-link active" id="one-link" href="#one">One</a></li>',
' <li class="nav-item active"><a class="nav-link" id="one-link" href="#one">One</a></li>',
' <li class="nav-item"><a class="nav-link" id="two-link" href="#two">Two</a></li>',
' <li class="nav-item"><a class="nav-link" id="three-link" href="#three">Three</a></li>',
' </ul>',
@ -625,9 +625,11 @@ describe('ScrollSpy', () => {
jQueryMock.fn.scrollspy = ScrollSpy.jQueryInterface
jQueryMock.elements = [div]
expect(() => {
try {
jQueryMock.fn.scrollspy.call(jQueryMock, action)
}).toThrowError(TypeError, `No method named "${action}"`)
} catch (error) {
expect(error.message).toEqual(`No method named "${action}"`)
}
})
})

View file

@ -397,9 +397,11 @@ describe('Tab', () => {
jQueryMock.fn.tab = Tab.jQueryInterface
jQueryMock.elements = [div]
expect(() => {
try {
jQueryMock.fn.tab.call(jQueryMock, action)
}).toThrowError(TypeError, `No method named "${action}"`)
} catch (error) {
expect(error.message).toEqual(`No method named "${action}"`)
}
})
})

View file

@ -368,9 +368,11 @@ describe('Toast', () => {
jQueryMock.fn.toast = Toast.jQueryInterface
jQueryMock.elements = [div]
expect(() => {
try {
jQueryMock.fn.toast.call(jQueryMock, action)
}).toThrowError(TypeError, `No method named "${action}"`)
} catch (error) {
expect(error.message).toEqual(`No method named "${action}"`)
}
})
})

View file

@ -286,25 +286,6 @@ describe('Tooltip', () => {
expect(Tooltip.getInstance(tooltipEl)).toEqual(null)
})
it('should destroy a tooltip after it is shown and hidden', done => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl)
tooltipEl.addEventListener('shown.bs.tooltip', () => {
tooltip.hide()
})
tooltipEl.addEventListener('hidden.bs.tooltip', () => {
tooltip.dispose()
expect(tooltip.tip).toEqual(null)
expect(Tooltip.getInstance(tooltipEl)).toEqual(null)
done()
})
tooltip.show()
})
it('should destroy a tooltip and remove it from the dom', done => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
@ -1207,9 +1188,11 @@ describe('Tooltip', () => {
jQueryMock.fn.tooltip = Tooltip.jQueryInterface
jQueryMock.elements = [div]
expect(() => {
try {
jQueryMock.fn.tooltip.call(jQueryMock, action)
}).toThrowError(TypeError, `No method named "${action}"`)
} catch (error) {
expect(error.message).toEqual(`No method named "${action}"`)
}
})
})
})

View file

@ -212,7 +212,7 @@ describe('Util', () => {
expect(() => {
Util.typeCheckConfig(namePlugin, config, defaultType)
}).toThrowError(TypeError, 'COLLAPSE: Option "parent" provided type "number" but expected type "(string|element)".')
}).toThrow(new Error('COLLAPSE: Option "parent" provided type "number" but expected type "(string|element)".'))
})
it('should return null stringified when null is passed', () => {

View file

@ -18,8 +18,8 @@
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link active" href="#" aria-current="page">Home</a>
<li class="nav-item active">
<a class="nav-link" href="#" aria-current="page">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>

View file

@ -18,8 +18,8 @@
<div class="collapse navbar-expand-md" id="navbarResponsive">
<a class="navbar-brand" href="#">This shouldn't jump!</a>
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link active" href="#" aria-current="page">Home</a>
<li class="nav-item active">
<a class="nav-link" href="#" aria-current="page">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>

View file

@ -3,7 +3,7 @@
<metadata>
<id>bootstrap</id>
<!-- pulled from package.json -->
<version>5</version>
<version>4</version>
<title>Bootstrap CSS</title>
<authors>The Bootstrap Authors, Twitter Inc.</authors>
<owners>bootstrap</owners>
@ -14,8 +14,11 @@
<projectUrl>https://getbootstrap.com/</projectUrl>
<icon>bootstrap.png</icon>
<license type="file">LICENSE.txt</license>
<copyright>Copyright 2017-2021</copyright>
<copyright>Copyright 2017-2020</copyright>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<dependencies>
<dependency id="@popperjs/core" version="[2.5.4,3)" />
</dependencies>
<tags>css mobile-first responsive front-end framework web</tags>
<contentFiles>
<files include="**/*" buildAction="Content" />

View file

@ -3,7 +3,7 @@
<metadata>
<id>bootstrap.sass</id>
<!-- pulled from package.json -->
<version>5</version>
<version>4</version>
<title>Bootstrap Sass</title>
<authors>The Bootstrap Authors, Twitter Inc.</authors>
<owners>bootstrap</owners>
@ -14,8 +14,11 @@
<projectUrl>https://getbootstrap.com/</projectUrl>
<icon>bootstrap.png</icon>
<license type="file">LICENSE.txt</license>
<copyright>Copyright 2017-2021</copyright>
<copyright>Copyright 2017-2020</copyright>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<dependencies>
<dependency id="@popperjs/core" version="[2.5.4,3)" />
</dependencies>
<tags>css sass mobile-first responsive front-end framework web</tags>
<contentFiles>
<files include="**/*" buildAction="Content" />

2577
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -2,9 +2,7 @@
"name": "bootstrap",
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
"version": "5.0.0-beta1",
"config": {
"version_short": "5.0"
},
"version_short": "5.0",
"keywords": [
"css",
"sass",
@ -34,7 +32,7 @@
"css-prefix": "npm-run-all --parallel css-prefix-*",
"css-prefix-main": "postcss --config build/postcss.config.js --replace \"dist/css/*.css\" \"!dist/css/*.rtl*.css\" \"!dist/css/*.min.css\"",
"css-prefix-examples": "postcss --config build/postcss.config.js --replace \"site/content/**/*.css\"",
"css-prefix-examples-rtl": "cross-env-shell NODE_ENV=RTL postcss --config build/postcss.config.js --dir \"site/content/docs/$npm_package_config_version_short/examples/\" --ext \".rtl.css\" --base \"site/content/docs/$npm_package_config_version_short/examples/\" \"site/content/docs/$npm_package_config_version_short/examples/{blog,carousel,dashboard,cheatsheet}/*.css\" \"!site/content/docs/$npm_package_config_version_short/examples/{blog,carousel,dashboard,cheatsheet}/*.rtl.css\"",
"css-prefix-examples-rtl": "cross-env-shell NODE_ENV=RTL postcss --config build/postcss.config.js --dir \"site/content/docs/$npm_package_version_short/examples/\" --ext \".rtl.css\" --base \"site/content/docs/$npm_package_version_short/examples/\" \"site/content/docs/$npm_package_version_short/examples/{blog,carousel,dashboard,cheatsheet}/*.css\" \"!site/content/docs/$npm_package_version_short/examples/{blog,carousel,dashboard,cheatsheet}/*.rtl.css\"",
"js": "npm-run-all js-compile js-minify",
"js-compile": "npm-run-all --parallel js-compile-*",
"js-compile-standalone": "rollup --environment BUNDLE:false --config build/rollup.config.js --sourcemap",
@ -43,15 +41,15 @@
"js-compile-plugins": "node build/build-plugins.js",
"js-lint": "eslint --cache --cache-location .cache/.eslintcache --report-unused-disable-directives .",
"js-minify": "npm-run-all --parallel js-minify-*",
"js-minify-standalone": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.js.map,includeSources,url=bootstrap.min.js.map\" --output dist/js/bootstrap.min.js dist/js/bootstrap.js",
"js-minify-standalone-esm": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.esm.js.map,includeSources,url=bootstrap.esm.min.js.map\" --output dist/js/bootstrap.esm.min.js dist/js/bootstrap.esm.js",
"js-minify-bundle": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.bundle.js.map,includeSources,url=bootstrap.bundle.min.js.map\" --output dist/js/bootstrap.bundle.min.js dist/js/bootstrap.bundle.js",
"js-minify-standalone": "terser --compress --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.js.map,includeSources,url=bootstrap.min.js.map\" --output dist/js/bootstrap.min.js dist/js/bootstrap.js",
"js-minify-standalone-esm": "terser --compress --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.esm.js.map,includeSources,url=bootstrap.esm.min.js.map\" --output dist/js/bootstrap.esm.min.js dist/js/bootstrap.esm.js",
"js-minify-bundle": "terser --compress --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.bundle.js.map,includeSources,url=bootstrap.bundle.min.js.map\" --output dist/js/bootstrap.bundle.min.js dist/js/bootstrap.bundle.js",
"js-test": "npm-run-all --parallel js-test-karma js-test-jquery js-test-integration-*",
"js-debug": "cross-env DEBUG=true npm run js-test-karma",
"js-test-karma": "karma start js/tests/karma.conf.js",
"js-test-integration-bundle": "rollup --config js/tests/integration/rollup.bundle.js",
"js-test-integration-modularity": "rollup --config js/tests/integration/rollup.bundle-modularity.js",
"js-test-cloud": "cross-env BROWSERSTACK=true npm run js-test-karma",
"js-test-cloud": "cross-env BROWSER=true npm run js-test-karma",
"js-test-jquery": "cross-env JQUERY=true npm run js-test-karma",
"lint": "npm-run-all --parallel js-lint css-lint lockfile-lint",
"docs": "npm-run-all docs-build docs-lint",
@ -97,32 +95,32 @@
},
"dependencies": {},
"peerDependencies": {
"@popperjs/core": "^2.6.0"
"@popperjs/core": "^2.5.4"
},
"devDependencies": {
"@babel/cli": "^7.12.10",
"@babel/core": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@popperjs/core": "^2.6.0",
"@babel/cli": "^7.12.8",
"@babel/core": "^7.12.9",
"@babel/preset-env": "^7.12.7",
"@popperjs/core": "^2.5.4",
"@rollup/plugin-babel": "^5.2.2",
"@rollup/plugin-commonjs": "^17.0.0",
"@rollup/plugin-node-resolve": "^11.0.1",
"@rollup/plugin-node-resolve": "^11.0.0",
"@rollup/plugin-replace": "^2.3.4",
"autoprefixer": "^10.2.1",
"autoprefixer": "^10.0.4",
"bundlewatch": "^0.3.1",
"clean-css-cli": "^4.3.0",
"cross-env": "^7.0.3",
"eslint": "^7.17.0",
"eslint-config-xo": "^0.34.0",
"eslint": "^7.14.0",
"eslint-config-xo": "^0.33.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-unicorn": "^26.0.1",
"find-unused-sass-variables": "^3.1.0",
"eslint-plugin-unicorn": "^23.0.0",
"find-unused-sass-variables": "^3.0.0",
"glob": "^7.1.6",
"hammer-simulator": "0.0.1",
"hugo-bin": "^0.68.0",
"hugo-bin": "^0.67.0",
"ip": "^1.1.5",
"jquery": "^3.5.1",
"karma": "^6.0.0",
"karma": "^5.2.3",
"karma-browserstack-launcher": "1.4.0",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage-istanbul-reporter": "^3.0.3",
@ -131,16 +129,16 @@
"karma-jasmine": "^4.0.1",
"karma-jasmine-html-reporter": "^1.5.4",
"karma-rollup-preprocessor": "^7.0.5",
"linkinator": "^2.11.2",
"linkinator": "^2.5.1",
"lockfile-lint": "^4.3.7",
"nodemon": "^2.0.7",
"nodemon": "^2.0.6",
"npm-run-all": "^4.1.5",
"postcss": "^8.2.4",
"postcss-cli": "^8.3.1",
"rollup": "^2.36.1",
"rollup-plugin-istanbul": "^3.0.0",
"rtlcss": "^3.0.0",
"sass": "^1.32.4",
"postcss": "^8.1.10",
"postcss-cli": "^8.3.0",
"rollup": "^2.34.0",
"rollup-plugin-istanbul": "^2.0.1",
"rtlcss": "^2.6.2",
"sass": "^1.29.0",
"shelljs": "^0.8.4",
"stylelint": "^13.8.0",
"stylelint-config-twbs-bootstrap": "^2.1.0",
@ -170,7 +168,7 @@
},
"dependencies": {},
"peerDependencies": {
"@popperjs/core": "^2.6.0"
"@popperjs/core": "^2.5.4"
}
}
}

View file

@ -44,14 +44,14 @@
// Generate contextual modifier classes for colorizing the alert.
@each $state, $value in $theme-colors {
$alert-background: shift-color($value, $alert-bg-scale);
$alert-border: shift-color($value, $alert-border-scale);
$alert-color: shift-color($value, $alert-color-scale);
@if (contrast-ratio($alert-background, $alert-color) < $min-contrast-ratio) {
$alert-color: mix($value, color-contrast($alert-background), abs($alert-color-scale));
$background: shift-color($value, $alert-bg-scale);
$border: shift-color($value, $alert-border-scale);
$color: shift-color($value, $alert-color-scale);
@if (contrast-ratio($background, $color) < $min-contrast-ratio) {
$color: mix($value, color-contrast($background), abs($alert-color-scale));
}
.alert-#{$state} {
@include alert-variant($alert-background, $alert-border, $alert-color);
@include alert-variant($background, $border, $color);
}
}
// scss-docs-end alert-modifiers

View file

@ -22,7 +22,7 @@
}
&:focus {
outline: 0;
outline: none;
box-shadow: $btn-close-focus-shadow;
opacity: $btn-close-focus-opacity;
}

View file

@ -35,7 +35,7 @@
// Reset positioning when positioned with Popper
&[style] {
right: auto#{"/* rtl:ignore */"} !important; // stylelint-disable-line declaration-no-important
right: auto !important; // stylelint-disable-line declaration-no-important
}
}

View file

@ -152,12 +152,12 @@
// Organizationally, this must come after the `:hover` states.
@each $state, $value in $theme-colors {
$list-group-background: shift-color($value, $list-group-item-bg-scale);
$list-group-color: shift-color($value, $list-group-item-color-scale);
@if (contrast-ratio($list-group-background, $list-group-color) < $min-contrast-ratio) {
$list-group-color: mix($value, color-contrast($list-group-background), abs($alert-color-scale));
$background: shift-color($value, $list-group-item-bg-scale);
$color: shift-color($value, $list-group-item-color-scale);
@if (contrast-ratio($background, $color) < $min-contrast-ratio) {
$color: mix($value, color-contrast($background), abs($alert-color-scale));
}
@include list-group-item-variant($state, $list-group-background, $list-group-color);
@include list-group-item-variant($state, $background, $color);
}
// scss-docs-end list-group-modifiers

View file

@ -233,3 +233,50 @@
}
}
}
.modal-left,
.modal-right {
.modal-dialog {
width: $modal-sidebar-width;
max-width: $modal-sidebar-max-width;
height: 100%;
margin: 0;
transform: translate(0);
@include transition(transform .2s);
}
.modal-content {
height: inherit;
border: 0;
@include border-radius(0);
}
.modal-body {
overflow-y: auto;
}
&.modal.fade {
.modal-dialog {
transform: translateX(0);
}
}
&.modal.show {
.modal-dialog {
transform: none;
}
}
}
.modal.modal-left {
.modal-dialog {
margin-right: auto;
transform: translateX(-100%);
}
}
.modal.modal-right {
.modal-dialog {
margin-left: auto;
transform: translateX(100%);
}
}

View file

@ -56,9 +56,9 @@
@include pagination-size($pagination-padding-y, $pagination-padding-x, null, $pagination-border-radius);
.pagination-lg {
@include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $pagination-border-radius-lg);
@include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $border-radius-lg);
}
.pagination-sm {
@include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $pagination-border-radius-sm);
@include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $border-radius-sm);
}

View file

@ -411,13 +411,13 @@ button {
border-radius: 0;
}
// Explicitly remove focus outline in Chromium when it shouldn't be
// visible (e.g. as result of mouse click or touch tap). It already
// should be doing this automatically, but seems to currently be
// confused and applies its very visible two-tone outline anyway.
// Work around a Firefox bug where the transparent `button` background
// results in a loss of the default `button` focus styles.
// Credit https://github.com/suitcss/base/
button:focus:not(:focus-visible) {
outline: 0;
button:focus {
outline: dotted 1px;
outline: -webkit-focus-ring-color auto 5px;
}
// 1. Remove the margin in Firefox and Safari

View file

@ -25,8 +25,8 @@
> :not(caption) > * > * {
padding: $table-cell-padding-y $table-cell-padding-x;
background-color: var(--#{$variable-prefix}table-bg);
background-image: linear-gradient(var(--#{$variable-prefix}table-accent-bg), var(--#{$variable-prefix}table-accent-bg));
border-bottom-width: $table-border-width;
box-shadow: inset 0 0 0 9999px var(--#{$variable-prefix}table-accent-bg);
}
> tbody {

View file

@ -47,5 +47,4 @@
.toast-body {
padding: $toast-padding-x; // apply to both vertical and horizontal
word-wrap: break-word;
}

View file

@ -612,15 +612,6 @@ $btn-border-radius-lg: $border-radius-lg !default;
$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;
$btn-hover-bg-shade-amount: 15% !default;
$btn-hover-bg-tint-amount: 15% !default;
$btn-hover-border-shade-amount: 20% !default;
$btn-hover-border-tint-amount: 10% !default;
$btn-active-bg-shade-amount: 20% !default;
$btn-active-bg-tint-amount: 20% !default;
$btn-active-border-shade-amount: 25% !default;
$btn-active-border-tint-amount: 10% !default;
// Forms
@ -744,7 +735,7 @@ $form-select-padding-y: $input-padding-y !default;
$form-select-padding-x: $input-padding-x !default;
$form-select-font-family: $input-font-family !default;
$form-select-font-size: $input-font-size !default;
$form-select-indicator-padding: $form-select-padding-x * 3 !default; // Extra padding for background-image
$form-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator
$form-select-font-weight: $input-font-weight !default;
$form-select-line-height: $input-line-height !default;
$form-select-color: $input-color !default;
@ -757,8 +748,8 @@ $form-select-bg-size: 16px 12px !default; // In pixels because ima
$form-select-indicator-color: $gray-800 !default;
$form-select-indicator: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='#{$form-select-indicator-color}' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/></svg>") !default;
$form-select-feedback-icon-padding-end: $form-select-padding-x * 2.5 + $form-select-indicator-padding !default;
$form-select-feedback-icon-position: center right $form-select-indicator-padding !default;
$form-select-feedback-icon-padding-end: add(1em * .75, (2 * $form-select-padding-y * .75) + $form-select-padding-x + $form-select-indicator-padding) !default;
$form-select-feedback-icon-position: center right ($form-select-padding-x + $form-select-indicator-padding) !default;
$form-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default;
$form-select-border-width: $input-border-width !default;
@ -938,7 +929,7 @@ $dropdown-box-shadow: $box-shadow !default;
$dropdown-link-color: $gray-900 !default;
$dropdown-link-hover-color: shade-color($gray-900, 10%) !default;
$dropdown-link-hover-bg: $gray-200 !default;
$dropdown-link-hover-bg: $gray-100 !default;
$dropdown-link-active-color: $component-active-color !default;
$dropdown-link-active-bg: $component-active-bg !default;
@ -1000,9 +991,6 @@ $pagination-disabled-border-color: $gray-300 !default;
$pagination-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;
$pagination-border-radius-sm: $border-radius-sm !default;
$pagination-border-radius-lg: $border-radius-lg !default;
// Cards
$card-spacer-y: $spacer !default;
@ -1174,6 +1162,9 @@ $modal-md: 500px !default;
$modal-lg: 800px !default;
$modal-xl: 1140px !default;
$modal-sidebar-width: 350px !default;
$modal-sidebar-max-width: 80% !default;
$modal-fade-transform: translate(0, -50px) !default;
$modal-show-transform: none !default;
$modal-transition: transform .3s ease-out !default;

View file

@ -1,7 +1,7 @@
/*!
* Bootstrap Grid v5.0.0-beta1 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Copyright 2011-2020 The Bootstrap Authors
* Copyright 2011-2020 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View file

@ -1,7 +1,7 @@
/*!
* Bootstrap Reboot v5.0.0-beta1 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Copyright 2011-2020 The Bootstrap Authors
* Copyright 2011-2020 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/

View file

@ -1,18 +1,18 @@
/*!
* Bootstrap Utilities v5.0.0-beta1 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Copyright 2011-2020 The Bootstrap Authors
* Copyright 2011-2020 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
// Configuration
@import "functions";
@import "variables";
@import "mixins";
@import "utilities";
// Helpers
@import "helpers";
// Utilities
@import "utilities/api";

4
scss/bootstrap.scss vendored
View file

@ -1,7 +1,7 @@
/*!
* Bootstrap v5.0.0-beta1 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Copyright 2011-2020 The Bootstrap Authors
* Copyright 2011-2020 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View file

@ -12,7 +12,7 @@
appearance: none;
&:focus {
outline: 0;
outline: none;
// Pseudo-elements must be split across multiple rulesets to have an effect.
// No box-shadow() mixin for focus accessibility.

View file

@ -6,7 +6,7 @@
.form-select {
display: block;
width: 100%;
padding: $form-select-padding-y $form-select-indicator-padding $form-select-padding-y $form-select-padding-x;
padding: $form-select-padding-y ($form-select-padding-x + $form-select-indicator-padding) $form-select-padding-y $form-select-padding-x;
font-family: $form-select-font-family;
@include font-size($form-select-font-size);
font-weight: $form-select-font-weight;

View file

@ -7,6 +7,6 @@
// scss-docs-start form-validation-states-loop
@each $state, $data in $form-validation-states {
@include form-validation-state($state, $data...);
@include form-validation-state($state, map-get($data, color), map-get($data, icon));
}
// scss-docs-end form-validation-states-loop

View file

@ -6,7 +6,7 @@
&::before {
display: block;
padding-top: var(--#{$variable-prefix}aspect-ratio);
padding-top: var(--aspect-ratio);
content: "";
}
@ -21,6 +21,6 @@
@each $key, $ratio in $aspect-ratios {
.ratio-#{$key} {
--#{$variable-prefix}aspect-ratio: #{$ratio};
--aspect-ratio: #{$ratio};
}
}

View file

@ -3,6 +3,6 @@
//
.visually-hidden,
.visually-hidden-focusable:not(:focus):not(:focus-within) {
.visually-hidden-focusable:not(:focus) {
@include visually-hidden();
}

View file

@ -7,11 +7,11 @@
$background,
$border,
$color: color-contrast($background),
$hover-background: if($color == $color-contrast-light, shade-color($background, $btn-hover-bg-shade-amount), tint-color($background, $btn-hover-bg-tint-amount)),
$hover-border: if($color == $color-contrast-light, shade-color($border, $btn-hover-border-shade-amount), tint-color($border, $btn-hover-border-tint-amount)),
$hover-background: if($color == $color-contrast-light, shade-color($background, 15%), tint-color($background, 15%)),
$hover-border: if($color == $color-contrast-light, shade-color($border, 20%), tint-color($border, 10%)),
$hover-color: color-contrast($hover-background),
$active-background: if($color == $color-contrast-light, shade-color($background,$btn-active-bg-shade-amount), tint-color($background, $btn-active-bg-tint-amount)),
$active-border: if($color == $color-contrast-light, shade-color($border, $btn-active-border-shade-amount), tint-color($border, $btn-active-border-tint-amount)),
$active-background: if($color == $color-contrast-light, shade-color($background, 20%), tint-color($background, 20%)),
$active-border: if($color == $color-contrast-light, shade-color($border, 25%), tint-color($border, 10%)),
$active-color: color-contrast($active-background),
$disabled-background: $background,
$disabled-border: $border,

View file

@ -13,14 +13,7 @@
}
}
@mixin form-validation-state(
$state,
$color,
$icon,
$tooltip-color: color-contrast($color),
$tooltip-bg-color: rgba($color, $form-feedback-tooltip-opacity),
$focus-box-shadow: 0 0 0 $input-focus-width rgba($color, $input-btn-focus-color-opacity)
) {
@mixin form-validation-state($state, $color, $icon) {
.#{$state}-feedback {
display: none;
width: 100%;
@ -40,8 +33,8 @@
margin-top: .1rem;
@include font-size($form-feedback-tooltip-font-size);
line-height: $form-feedback-tooltip-line-height;
color: $tooltip-color;
background-color: $tooltip-bg-color;
color: color-contrast($color);
background-color: rgba($color, $form-feedback-tooltip-opacity);
@include border-radius($form-feedback-tooltip-border-radius);
}
@ -66,7 +59,7 @@
&:focus {
border-color: $color;
box-shadow: $focus-box-shadow;
box-shadow: 0 0 0 $input-focus-width rgba($color, $input-btn-focus-color-opacity);
}
}
}
@ -94,7 +87,7 @@
&:focus {
border-color: $color;
box-shadow: $focus-box-shadow;
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
}
}
}
@ -108,7 +101,7 @@
}
&:focus {
box-shadow: $focus-box-shadow;
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
}
~ .form-check-label {

View file

@ -17,13 +17,12 @@
border: 0 !important;
}
// Use to only display content when it's focused, or one of its child elements is focused
// (i.e. when focus is within the element/container that the class was applied to)
// Use to only display content when it's focused.
//
// Useful for "Skip to main content" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
@mixin visually-hidden-focusable() {
&:not(:focus):not(:focus-within) {
&:not(:focus) {
@include visually-hidden();
}
}

View file

@ -26,7 +26,7 @@
@each $key, $utility in $utilities {
// The utility can be disabled with `false`, thus check if the utility is a map first
// Only proceed if responsive media queries are enabled or if it's the base media query
@if type-of($utility) == "map" and map-get($utility, rfs) and (map-get($utility, responsive) or $infix == "") {
@if type-of($utility) == "map" and map-get($utility, rfs) {
@include generate-utility($utility, $infix, true);
}
}

View file

@ -35,8 +35,8 @@
"strict": "error",
"unicorn/no-for-loop": "off",
"unicorn/no-null": "off",
"unicorn/prefer-dom-node-append": "off",
"unicorn/prefer-dom-node-dataset": "off",
"unicorn/prefer-dataset": "off",
"unicorn/prefer-node-append": "off",
"unicorn/prefer-query-selector": "off",
"unicorn/prevent-abbreviations": "off"
}

View file

@ -4,8 +4,8 @@
/*!
* JavaScript for Bootstrap's docs (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Copyright 2011-2020 The Bootstrap Authors
* Copyright 2011-2020 Twitter, Inc.
* Licensed under the Creative Commons Attribution 3.0 Unported License.
* For details, see https://creativecommons.org/licenses/by/3.0/.
*/

View file

@ -29,8 +29,7 @@
border: 1px solid;
@include border-radius();
&:hover,
&:focus {
&:hover {
color: $white;
background-color: $primary;
}

View file

@ -187,7 +187,7 @@
width: 16rem;
@include media-breakpoint-up(md) {
--bs-aspect-ratio: 50%; // 2x1
--aspect-ratio: 50%; // 2x1
}
}
}

View file

@ -5,6 +5,11 @@
.navbar-toggler {
padding: 0;
border: 0;
.bi {
width: 2rem;
fill: currentColor;
}
}
.navbar-nav {

View file

@ -49,7 +49,7 @@
padding: .25rem .5rem;
font-weight: 600;
color: rgba($black, .65);
background-color: transparent;
background-color: none;
border: 0;
&:hover,

View file

@ -1,7 +1,20 @@
// stylelint-disable declaration-no-important
.skippy {
background-color: $bd-purple;
a {
color: $white;
}
&:focus-within a {
position: static !important;
width: auto !important;
height: auto !important;
padding: $spacer / 2 !important;
margin: $spacer / 4 !important;
overflow: visible !important;
clip: auto !important;
white-space: normal !important;
}
}

View file

@ -70,6 +70,10 @@
box-shadow: 0 0 0 3px rgba($bd-purple-bright, .25);
}
.bi {
fill: currentColor;
}
.bi-collapse { display: none; }
&:not(.collapsed) {

View file

@ -1,7 +1,7 @@
/*!
* Bootstrap Docs (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Copyright 2011-2020 The Bootstrap Authors
* Copyright 2011-2020 Twitter, Inc.
* Licensed under the Creative Commons Attribution 3.0 Unported License.
* For details, see https://creativecommons.org/licenses/by/3.0/.
*/

View file

@ -75,7 +75,7 @@ Add `.accordion-flush` to remove the default `background-color`, some borders, a
</button>
</h2>
<div id="flush-collapseOne" class="accordion-collapse collapse" aria-labelledby="flush-headingOne" data-bs-parent="#accordionFlushExample">
<div class="accordion-body">Placeholder content for this accordion, which is intended to demonstrate the <code>.accordion-flush</code> class. This is the first item's accordion body.</div>
<div class="accordion-body">Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.</div>
</div>
</div>
<div class="accordion-item">
@ -85,7 +85,7 @@ Add `.accordion-flush` to remove the default `background-color`, some borders, a
</button>
</h2>
<div id="flush-collapseTwo" class="accordion-collapse collapse" aria-labelledby="flush-headingTwo" data-bs-parent="#accordionFlushExample">
<div class="accordion-body">Placeholder content for this accordion, which is intended to demonstrate the <code>.accordion-flush</code> class. This is the second item's accordion body. Let's imagine this being filled with some actual content.</div>
<div class="accordion-body">Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.</div>
</div>
</div>
<div class="accordion-item">
@ -95,7 +95,7 @@ Add `.accordion-flush` to remove the default `background-color`, some borders, a
</button>
</h2>
<div id="flush-collapseThree" class="accordion-collapse collapse" aria-labelledby="flush-headingThree" data-bs-parent="#accordionFlushExample">
<div class="accordion-body">Placeholder content for this accordion, which is intended to demonstrate the <code>.accordion-flush</code> class. This is the third item's accordion body. Nothing more exciting happening here in terms of content, but just filling up the space to make it look, at least at first glance, a bit more representative of how this would look in a real-world application.</div>
<div class="accordion-body">Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.</div>
</div>
</div>
</div>

View file

@ -81,9 +81,9 @@ Create lists of content in a card with a flush list group.
{{< example >}}
<div class="card" style="width: 18rem;">
<ul class="list-group list-group-flush">
<li class="list-group-item">An item</li>
<li class="list-group-item">A second item</li>
<li class="list-group-item">A third item</li>
<li class="list-group-item">Cras justo odio</li>
<li class="list-group-item">Dapibus ac facilisis in</li>
<li class="list-group-item">Vestibulum at eros</li>
</ul>
</div>
{{< /example >}}
@ -94,9 +94,9 @@ Create lists of content in a card with a flush list group.
Featured
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">An item</li>
<li class="list-group-item">A second item</li>
<li class="list-group-item">A third item</li>
<li class="list-group-item">Cras justo odio</li>
<li class="list-group-item">Dapibus ac facilisis in</li>
<li class="list-group-item">Vestibulum at eros</li>
</ul>
</div>
{{< /example >}}
@ -104,9 +104,9 @@ Create lists of content in a card with a flush list group.
{{< example >}}
<div class="card" style="width: 18rem;">
<ul class="list-group list-group-flush">
<li class="list-group-item">An item</li>
<li class="list-group-item">A second item</li>
<li class="list-group-item">A third item</li>
<li class="list-group-item">Cras justo odio</li>
<li class="list-group-item">Dapibus ac facilisis in</li>
<li class="list-group-item">Vestibulum at eros</li>
</ul>
<div class="card-footer">
Card footer
@ -126,9 +126,9 @@ Mix and match multiple content types to create the card you need, or throw every
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">An item</li>
<li class="list-group-item">A second item</li>
<li class="list-group-item">A third item</li>
<li class="list-group-item">Cras justo odio</li>
<li class="list-group-item">Dapibus ac facilisis in</li>
<li class="list-group-item">Vestibulum at eros</li>
</ul>
<div class="card-body">
<a href="#" class="card-link">Card link</a>
@ -174,7 +174,7 @@ Card headers can be styled by adding `.card-header` to `<h*>` elements.
</div>
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>A well-known quote, contained in a blockquote element.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
<footer class="blockquote-footer">Someone famous in <cite title="Source Title">Source Title</cite></footer>
</blockquote>
</div>

View file

@ -121,21 +121,21 @@ Add captions to your slides easily with the `.carousel-caption` element within a
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#555" background="#777" text="First slide" >}}
<div class="carousel-caption d-none d-md-block">
<h5>First slide label</h5>
<p>Some representative placeholder content for the first slide.</p>
<p>Nulla vitae elit libero, a pharetra augue mollis interdum.</p>
</div>
</div>
<div class="carousel-item">
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#444" background="#666" text="Second slide" >}}
<div class="carousel-caption d-none d-md-block">
<h5>Second slide label</h5>
<p>Some representative placeholder content for the second slide.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
<div class="carousel-item">
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#333" background="#555" text="Third slide" >}}
<div class="carousel-caption d-none d-md-block">
<h5>Third slide label</h5>
<p>Some representative placeholder content for the third slide.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur.</p>
</div>
</div>
</div>
@ -206,34 +206,6 @@ Add `data-bs-interval=""` to a `.carousel-item` to change the amount of time to
</div>
{{< /example >}}
### Disable touch swiping
Carousels support swiping left/right on touchscreen devices to move between slides. This can be disabled using the `data-bs-touch` attribute. The example below also does not include the `data-bs-ride` attribute and has `data-bs-interval="false"` so it doesn't autoplay.
{{< example >}}
<div id="carouselExampleControlsNoTouching" class="carousel slide" data-bs-touch="false" data-bs-interval="false">
<div class="carousel-inner">
<div class="carousel-item active">
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#555" background="#777" text="First slide" >}}
</div>
<div class="carousel-item">
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#444" background="#666" text="Second slide" >}}
</div>
<div class="carousel-item">
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#333" background="#555" text="Third slide" >}}
</div>
</div>
<a class="carousel-control-prev" href="#carouselExampleControlsNoTouching" role="button" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleControlsNoTouching" role="button" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</a>
</div>
{{< /example >}}
## Dark variant
Add `.carousel-dark` to the `.carousel` for darker controls, indicators, and captions. Controls have been inverted from their default white fill with the `filter` CSS property. Captions and controls have additional Sass variables that customize the `color` and `background-color`.
@ -250,21 +222,21 @@ Add `.carousel-dark` to the `.carousel` for darker controls, indicators, and cap
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#aaa" background="#f5f5f5" text="First slide" >}}
<div class="carousel-caption d-none d-md-block">
<h5>First slide label</h5>
<p>Some representative placeholder content for the first slide.</p>
<p>Nulla vitae elit libero, a pharetra augue mollis interdum.</p>
</div>
</div>
<div class="carousel-item" data-bs-interval="2000">
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#bbb" background="#eee" text="Second slide" >}}
<div class="carousel-caption d-none d-md-block">
<h5>Second slide label</h5>
<p>Some representative placeholder content for the second slide.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
<div class="carousel-item">
{{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#999" background="#e5e5e5" text="Third slide" >}}
<div class="carousel-caption d-none d-md-block">
<h5>Third slide label</h5>
<p>Some representative placeholder content for the third slide.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur.</p>
</div>
</div>
</div>
@ -314,7 +286,7 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
<td><code>interval</code></td>
<td>number</td>
<td><code>5000</code></td>
<td>The amount of time to delay between automatically cycling an item. If <code>false</code>, carousel will not automatically cycle.</td>
<td>The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle.</td>
</tr>
<tr>
<td><code>keyboard</code></td>
@ -325,15 +297,15 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
<tr>
<td><code>pause</code></td>
<td>string | boolean</td>
<td><code>'hover'</code></td>
<td><p>If set to <code>'hover'</code>, pauses the cycling of the carousel on <code>mouseenter</code> and resumes the cycling of the carousel on <code>mouseleave</code>. If set to <code>false</code>, hovering over the carousel won't pause it.</p>
<p>On touch-enabled devices, when set to <code>'hover'</code>, cycling will pause on <code>touchend</code> (once the user finished interacting with the carousel) for two intervals, before automatically resuming. Note that this is in addition to the above mouse behavior.</p></td>
<td><code>"hover"</code></td>
<td><p>If set to <code>"hover"</code>, pauses the cycling of the carousel on <code>mouseenter</code> and resumes the cycling of the carousel on <code>mouseleave</code>. If set to <code>false</code>, hovering over the carousel won't pause it.</p>
<p>On touch-enabled devices, when set to <code>"hover"</code>, cycling will pause on <code>touchend</code> (once the user finished interacting with the carousel) for two intervals, before automatically resuming. Note that this is in addition to the above mouse behavior.</p></td>
</tr>
<tr>
<td><code>ride</code></td>
<td><code>slide</code></td>
<td>string | boolean</td>
<td><code>false</code></td>
<td>Autoplays the carousel after the user manually cycles the first item. If set to <code>'carousel'</code>, autoplays the carousel on load.</td>
<td>Autoplays the carousel after the user manually cycles the first item. If "carousel", autoplays the carousel on load.</td>
</tr>
<tr>
<td><code>wrap</code></td>

View file

@ -22,7 +22,7 @@ Click the buttons below to show and hide another element via class changes:
- `.collapsing` is applied during transitions
- `.collapse.show` shows content
Generally, we recommend using a button with the `data-bs-target` attribute. While not recommended from a semantic point of view, you can also use a link with the `href` attribute (and a `role="button"`). In both cases, the `data-bs-toggle="collapse"` is required.
You can use a link with the `href` attribute, or a button with the `data-bs-target` attribute. In both cases, the `data-bs-toggle="collapse"` is required.
{{< example >}}
<p>
@ -35,7 +35,7 @@ Generally, we recommend using a button with the `data-bs-target` attribute. Whil
</p>
<div class="collapse" id="collapseExample">
<div class="card card-body">
Some placeholder content for the collapse component. This panel is hidden by default but revealed when the user activates the relevant trigger.
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident.
</div>
</div>
{{< /example >}}
@ -55,14 +55,14 @@ Multiple `<button>` or `<a>` can show and hide an element if they each reference
<div class="col">
<div class="collapse multi-collapse" id="multiCollapseExample1">
<div class="card card-body">
Some placeholder content for the first collapse component of this multi-collapse example. This panel is hidden by default but revealed when the user activates the relevant trigger.
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident.
</div>
</div>
</div>
<div class="col">
<div class="collapse multi-collapse" id="multiCollapseExample2">
<div class="card card-body">
Some placeholder content for the second collapse component of this multi-collapse example. This panel is hidden by default but revealed when the user activates the relevant trigger.
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident.
</div>
</div>
</div>

View file

@ -886,9 +886,9 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
</tr>
<tr>
<td><code>reference</code></td>
<td>string | element | object</td>
<td>string | element</td>
<td><code>'toggle'</code></td>
<td>Reference element of the dropdown menu. Accepts the values of <code>'toggle'</code>, <code>'parent'</code>, an HTMLElement reference or an object providing <code>getBoundingClientRect</code>. For more information refer to Popper's <a href="https://popper.js.org/docs/v2/constructors/#createpopper">constructor docs</a> and <a href="https://popper.js.org/docs/v2/virtual-elements/">virtual element docs</a>.</td>
<td>Reference element of the dropdown menu. Accepts the values of <code>'toggle'</code>, <code>'parent'</code>, or an HTMLElement reference. For more information refer to Popper's <a href="https://popper.js.org/docs/v2/constructors/#createpopper">constructor docs</a>.</td>
</tr>
<tr>
<td><code>display</code></td>
@ -900,7 +900,7 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap
<td><code>popperConfig</code></td>
<td>null | object</td>
<td><code>null</code></td>
<td>To change Bootstrap's default Popper config, see <a href="https://popper.js.org/docs/v2/constructors/#options">Popper's configuration</a></td>
<td>To change Bootstrap's default Popper config, see <a href="https://popper.js.org/docs/v1/#Popper.Defaults">Popper's configuration</a></td>
</tr>
</tbody>
</table>

View file

@ -12,11 +12,11 @@ The most basic list group is an unordered list with list items and the proper cl
{{< example >}}
<ul class="list-group">
<li class="list-group-item">An item</li>
<li class="list-group-item">A second item</li>
<li class="list-group-item">A third item</li>
<li class="list-group-item">A fourth item</li>
<li class="list-group-item">And a fifth one</li>
<li class="list-group-item">Cras justo odio</li>
<li class="list-group-item">Dapibus ac facilisis in</li>
<li class="list-group-item">Morbi leo risus</li>
<li class="list-group-item">Porta ac consectetur ac</li>
<li class="list-group-item">Vestibulum at eros</li>
</ul>
{{< /example >}}
@ -26,11 +26,11 @@ Add `.active` to a `.list-group-item` to indicate the current active selection.
{{< example >}}
<ul class="list-group">
<li class="list-group-item active" aria-current="true">An active item</li>
<li class="list-group-item">A second item</li>
<li class="list-group-item">A third item</li>
<li class="list-group-item">A fourth item</li>
<li class="list-group-item">And a fifth one</li>
<li class="list-group-item active" aria-current="true">Cras justo odio</li>
<li class="list-group-item">Dapibus ac facilisis in</li>
<li class="list-group-item">Morbi leo risus</li>
<li class="list-group-item">Porta ac consectetur ac</li>
<li class="list-group-item">Vestibulum at eros</li>
</ul>
{{< /example >}}
@ -40,11 +40,11 @@ Add `.disabled` to a `.list-group-item` to make it _appear_ disabled. Note that
{{< example >}}
<ul class="list-group">
<li class="list-group-item disabled" aria-disabled="true">A disabled item</li>
<li class="list-group-item">A second item</li>
<li class="list-group-item">A third item</li>
<li class="list-group-item">A fourth item</li>
<li class="list-group-item">And a fifth one</li>
<li class="list-group-item disabled" aria-disabled="true">Cras justo odio</li>
<li class="list-group-item">Dapibus ac facilisis in</li>
<li class="list-group-item">Morbi leo risus</li>
<li class="list-group-item">Porta ac consectetur ac</li>
<li class="list-group-item">Vestibulum at eros</li>
</ul>
{{< /example >}}
@ -57,12 +57,12 @@ Be sure to **not use the standard `.btn` classes here**.
{{< example >}}
<div class="list-group">
<a href="#" class="list-group-item list-group-item-action active" aria-current="true">
The current link item
Cras justo odio
</a>
<a href="#" class="list-group-item list-group-item-action">A second link item</a>
<a href="#" class="list-group-item list-group-item-action">A third link item</a>
<a href="#" class="list-group-item list-group-item-action">A fourth link item</a>
<a href="#" class="list-group-item list-group-item-action disabled" tabindex="-1" aria-disabled="true">A disabled link item</a>
<a href="#" class="list-group-item list-group-item-action">Dapibus ac facilisis in</a>
<a href="#" class="list-group-item list-group-item-action">Morbi leo risus</a>
<a href="#" class="list-group-item list-group-item-action">Porta ac consectetur ac</a>
<a href="#" class="list-group-item list-group-item-action disabled" tabindex="-1" aria-disabled="true">Vestibulum at eros</a>
</div>
{{< /example >}}
@ -71,12 +71,12 @@ With `<button>`s, you can also make use of the `disabled` attribute instead of t
{{< example >}}
<div class="list-group">
<button type="button" class="list-group-item list-group-item-action active" aria-current="true">
The current button
Cras justo odio
</button>
<button type="button" class="list-group-item list-group-item-action">A second item</button>
<button type="button" class="list-group-item list-group-item-action">A third button item</button>
<button type="button" class="list-group-item list-group-item-action">A fourth button item</button>
<button type="button" class="list-group-item list-group-item-action" disabled>A disabled button item</button>
<button type="button" class="list-group-item list-group-item-action">Dapibus ac facilisis in</button>
<button type="button" class="list-group-item list-group-item-action">Morbi leo risus</button>
<button type="button" class="list-group-item list-group-item-action">Porta ac consectetur ac</button>
<button type="button" class="list-group-item list-group-item-action" disabled>Vestibulum at eros</button>
</div>
{{< /example >}}
@ -86,11 +86,11 @@ Add `.list-group-flush` to remove some borders and rounded corners to render lis
{{< example >}}
<ul class="list-group list-group-flush">
<li class="list-group-item">An item</li>
<li class="list-group-item">A second item</li>
<li class="list-group-item">A third item</li>
<li class="list-group-item">A fourth item</li>
<li class="list-group-item">And a fifth one</li>
<li class="list-group-item">Cras justo odio</li>
<li class="list-group-item">Dapibus ac facilisis in</li>
<li class="list-group-item">Morbi leo risus</li>
<li class="list-group-item">Porta ac consectetur ac</li>
<li class="list-group-item">Vestibulum at eros</li>
</ul>
{{< /example >}}
@ -104,9 +104,9 @@ Add `.list-group-horizontal` to change the layout of list group items from verti
{{< list-group.inline >}}
{{- range $.Site.Data.breakpoints }}
<ul class="list-group list-group-horizontal{{ .abbr }}">
<li class="list-group-item">An item</li>
<li class="list-group-item">A second item</li>
<li class="list-group-item">A third item</li>
<li class="list-group-item">Cras justo odio</li>
<li class="list-group-item">Dapibus ac facilisis in</li>
<li class="list-group-item">Morbi leo risus</li>
</ul>
{{- end -}}
{{< /list-group.inline >}}
@ -118,7 +118,7 @@ Use contextual classes to style list items with a stateful background and color.
{{< example >}}
<ul class="list-group">
<li class="list-group-item">A simple default list group item</li>
<li class="list-group-item">Dapibus ac facilisis in</li>
{{< list.inline >}}
{{- range (index $.Site.Data "theme-colors") }}
<li class="list-group-item list-group-item-{{ .name }}">A simple {{ .name }} list group item</li>
@ -131,7 +131,7 @@ Contextual classes also work with `.list-group-item-action`. Note the addition o
{{< example >}}
<div class="list-group">
<a href="#" class="list-group-item list-group-item-action">A simple default list group item</a>
<a href="#" class="list-group-item list-group-item-action">Dapibus ac facilisis in</a>
{{< list.inline >}}
{{- range (index $.Site.Data "theme-colors") }}
<a href="#" class="list-group-item list-group-item-action list-group-item-{{ .name }}">A simple {{ .name }} list group item</a>
@ -151,15 +151,15 @@ Add badges to any list group item to show unread counts, activity, and more with
{{< example >}}
<ul class="list-group">
<li class="list-group-item d-flex justify-content-between align-items-center">
A list item
Cras justo odio
<span class="badge bg-primary rounded-pill">14</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
A second list item
Dapibus ac facilisis in
<span class="badge bg-primary rounded-pill">2</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
A third list item
Morbi leo risus
<span class="badge bg-primary rounded-pill">1</span>
</li>
</ul>
@ -176,24 +176,24 @@ Add nearly any HTML within, even for linked list groups like the one below, with
<h5 class="mb-1">List group item heading</h5>
<small>3 days ago</small>
</div>
<p class="mb-1">Some placeholder content in a paragraph.</p>
<small>And some small print.</small>
<p class="mb-1">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
<small>Donec id elit non mi porta.</small>
</a>
<a href="#" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">List group item heading</h5>
<small class="text-muted">3 days ago</small>
</div>
<p class="mb-1">Some placeholder content in a paragraph.</p>
<small class="text-muted">And some muted small print.</small>
<p class="mb-1">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
<small class="text-muted">Donec id elit non mi porta.</small>
</a>
<a href="#" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">List group item heading</h5>
<small class="text-muted">3 days ago</small>
</div>
<p class="mb-1">Some placeholder content in a paragraph.</p>
<small class="text-muted">And some muted small print.</small>
<p class="mb-1">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
<small class="text-muted">Donec id elit non mi porta.</small>
</a>
</div>
{{< /example >}}
@ -206,23 +206,23 @@ Place Bootstrap's checkboxes and radios within list group items and customize as
<ul class="list-group">
<li class="list-group-item">
<input class="form-check-input me-1" type="checkbox" value="" aria-label="...">
First checkbox
Cras justo odio
</li>
<li class="list-group-item">
<input class="form-check-input me-1" type="checkbox" value="" aria-label="...">
Second checkbox
Dapibus ac facilisis in
</li>
<li class="list-group-item">
<input class="form-check-input me-1" type="checkbox" value="" aria-label="...">
Third checkbox
Morbi leo risus
</li>
<li class="list-group-item">
<input class="form-check-input me-1" type="checkbox" value="" aria-label="...">
Fourth checkbox
Porta ac consectetur ac
</li>
<li class="list-group-item">
<input class="form-check-input me-1" type="checkbox" value="" aria-label="...">
Fifth checkbox
Vestibulum at eros
</li>
</ul>
{{< /example >}}
@ -233,23 +233,23 @@ And if you want `<label>`s as the `.list-group-item` for large hit areas, you ca
<div class="list-group">
<label class="list-group-item">
<input class="form-check-input me-1" type="checkbox" value="">
First checkbox
Cras justo odio
</label>
<label class="list-group-item">
<input class="form-check-input me-1" type="checkbox" value="">
Second checkbox
Dapibus ac facilisis in
</label>
<label class="list-group-item">
<input class="form-check-input me-1" type="checkbox" value="">
Third checkbox
Morbi leo risus
</label>
<label class="list-group-item">
<input class="form-check-input me-1" type="checkbox" value="">
Fourth checkbox
Porta ac consectetur ac
</label>
<label class="list-group-item">
<input class="form-check-input me-1" type="checkbox" value="">
Fifth checkbox
Vestibulum at eros
</label>
</div>
{{< /example >}}
@ -272,16 +272,16 @@ Use the tab JavaScript plugin—include it individually or through the compiled
<div class="col-8">
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade show active" id="list-home" role="tabpanel" aria-labelledby="list-home-list">
<p>Some placeholder content in a paragraph relating to "Home". And some more content, used here just to pad out and fill this tab panel. In production, you would obviously have more real content here. And not just text. It could be anything, really. Text, images, forms.</p>
<p>Velit aute mollit ipsum ad dolor consectetur nulla officia culpa adipisicing exercitation fugiat tempor. Voluptate deserunt sit sunt nisi aliqua fugiat proident ea ut. Mollit voluptate reprehenderit occaecat nisi ad non minim tempor sunt voluptate consectetur exercitation id ut nulla. Ea et fugiat aliquip nostrud sunt incididunt consectetur culpa aliquip eiusmod dolor. Anim ad Lorem aliqua in cupidatat nisi enim eu nostrud do aliquip veniam minim.</p>
</div>
<div class="tab-pane fade" id="list-profile" role="tabpanel" aria-labelledby="list-profile-list">
<p>Some placeholder content in a paragraph relating to "Profile". And some more content, used here just to pad out and fill this tab panel. In production, you would obviously have more real content here. And not just text. It could be anything, really. Text, images, forms.</p>
<p>Cupidatat quis ad sint excepteur laborum in esse qui. Et excepteur consectetur ex nisi eu do cillum ad laborum. Mollit et eu officia dolore sunt Lorem culpa qui commodo velit ex amet id ex. Officia anim incididunt laboris deserunt anim aute dolor incididunt veniam aute dolore do exercitation. Dolor nisi culpa ex ad irure in elit eu dolore. Ad laboris ipsum reprehenderit irure non commodo enim culpa commodo veniam incididunt veniam ad.</p>
</div>
<div class="tab-pane fade" id="list-messages" role="tabpanel" aria-labelledby="list-messages-list">
<p>Some placeholder content in a paragraph relating to "Messages". And some more content, used here just to pad out and fill this tab panel. In production, you would obviously have more real content here. And not just text. It could be anything, really. Text, images, forms.</p>
<p>Ut ut do pariatur aliquip aliqua aliquip exercitation do nostrud commodo reprehenderit aute ipsum voluptate. Irure Lorem et laboris nostrud amet cupidatat cupidatat anim do ut velit mollit consequat enim tempor. Consectetur est minim nostrud nostrud consectetur irure labore voluptate irure. Ipsum id Lorem sit sint voluptate est pariatur eu ad cupidatat et deserunt culpa sit eiusmod deserunt. Consectetur et fugiat anim do eiusmod aliquip nulla laborum elit adipisicing pariatur cillum.</p>
</div>
<div class="tab-pane fade" id="list-settings" role="tabpanel" aria-labelledby="list-settings-list">
<p>Some placeholder content in a paragraph relating to "Settings". And some more content, used here just to pad out and fill this tab panel. In production, you would obviously have more real content here. And not just text. It could be anything, really. Text, images, forms.</p>
<p>Irure enim occaecat labore sit qui aliquip reprehenderit amet velit. Deserunt ullamco ex elit nostrud ut dolore nisi officia magna sit occaecat laboris sunt dolor. Nisi eu minim cillum occaecat aute est cupidatat aliqua labore aute occaecat ea aliquip sunt amet. Aute mollit dolor ut exercitation irure commodo non amet consectetur quis amet culpa. Quis ullamco nisi amet qui aute irure eu. Magna labore dolor quis ex labore id nostrud deserunt dolor eiusmod eu pariatur culpa mollit in irure.</p>
</div>
</div>
</div>

View file

@ -198,14 +198,24 @@ When modals become too long for the user's viewport or device, they scroll indep
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>What follows is just some placeholder text for this modal dialog. Sipping on Rosé, Silver Lake sun, coming up all lazy. Its in the palm of your hand now baby. So we hit the boulevard. So make a wish, I'll make it like your birthday everyday. Do you ever feel already buried deep six feet under? It's time to bring out the big balloons. You could've been the greatest. Passport stamps, she's cosmopolitan. Your kiss is cosmic, every move is magic.</p>
<p>We're living the life. We're doing it right. Open up your heart. I was tryna hit it and quit it. Her love is like a drug. Always leaves a trail of stardust. The girl's a freak, she drive a jeep in Laguna Beach. Fine, fresh, fierce, we got it on lock. All my girls vintage Chanel baby.</p>
<p>Before you met me I was alright but things were kinda heavy. Peach-pink lips, yeah, everybody stares. This is no big deal. Calling out my name. I could have rewrite your addiction. She's got that, je ne sais quoi, you know it. Heavy is the head that wears the crown. 'Cause, baby, you're a firework. Like thunder gonna shake the ground.</p>
<p>Just own the night like the 4th of July! Im gon put her in a coma. What you're waiting for, it's time for you to show it off. Can't replace you with a million rings. You open my eyes and I'm ready to go, lead me into the light. And here you are. Im gon put her in a coma. Come on, let your colours burst. So cover your eyes, I have a surprise. As I march alone to a different beat. Glitter all over the room pink flamingos in the pool.</p>
<p>You just gotta ignite the light and let it shine! Come just as you are to me. Just own the night like the 4th of July. Infect me with your love and fill me with your poison. Come just as you are to me. End of the rainbow looking treasure.</p>
<p>I can't sleep let's run away and don't ever look back, don't ever look back. I can't sleep let's run away and don't ever look back, don't ever look back. Yes, we make angels cry, raining down on earth from up above. I'm walking on air (tonight). Let you put your hands on me in my skin-tight jeans. Stinging like a bee I earned my stripes. I went from zero, to my own hero. Even brighter than the moon, moon, moon. Make 'em go, 'Aah, aah, aah' as you shoot across the sky-y-y! Why don't you let me stop by?</p>
<p>Boom, boom, boom. Never made me blink one time. Yeah, you're lucky if you're on her plane. Talk about our future like we had a clue. Oh my God no exaggeration. You're original, cannot be replaced. The girl's a freak, she drive a jeep in Laguna Beach. It's no big deal, it's no big deal, it's no big deal. In another life I would make you stay. I'm ma get your heart racing in my skin-tight jeans. I wanna walk on your wave length and be there when you vibrate Never made me blink one time.</p>
<p>We'd keep all our promises be us against the world. If you get the chance you better keep her. It's time to bring out the big, big, big, big, big, big balloons. I hope you got a healthy appetite. Don't let the greatness get you down, oh, oh yeah. Yeah, she's footloose and so fancy free. I want the jaw droppin', eye poppin', head turnin', body shockin'. End of the rainbow looking treasure.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
@ -231,14 +241,24 @@ You can also create a scrollable modal that allows scroll the modal body by addi
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>What follows is just some placeholder text for this modal dialog. You just gotta ignite the light and let it shine! Come just as you are to me. Just own the night like the 4th of July. Infect me with your love and fill me with your poison. Come just as you are to me. End of the rainbow looking treasure.</p>
<p>I can't sleep let's run away and don't ever look back, don't ever look back. I can't sleep let's run away and don't ever look back, don't ever look back. Yes, we make angels cry, raining down on earth from up above. I'm walking on air (tonight). Let you put your hands on me in my skin-tight jeans. Stinging like a bee I earned my stripes. I went from zero, to my own hero. Even brighter than the moon, moon, moon. Make 'em go, 'Aah, aah, aah' as you shoot across the sky-y-y! Why don't you let me stop by?</p>
<p>Boom, boom, boom. Never made me blink one time. Yeah, you're lucky if you're on her plane. Talk about our future like we had a clue. Oh my God no exaggeration. You're original, cannot be replaced. The girl's a freak, she drive a jeep in Laguna Beach. It's no big deal, it's no big deal, it's no big deal. In another life I would make you stay. I'm ma get your heart racing in my skin-tight jeans. I wanna walk on your wave length and be there when you vibrate Never made me blink one time.</p>
<p>We'd keep all our promises be us against the world. In another life I would be your girl. We can dance, until we die, you and I, will be young forever. And on my 18th Birthday we got matching tattoos. So open up your heart and just let it begin. 'Cause she's the muse and the artist. She eats your heart out. Like Jeffrey Dahmer (woo). Pop your confetti. (This is how we do) I know one spark will shock the world, yeah yeah. If you only knew what the future holds.</p>
<p>Sipping on Rosé, Silver Lake sun, coming up all lazy. Its in the palm of your hand now baby. So we hit the boulevard. So make a wish, I'll make it like your birthday everyday. Do you ever feel already buried deep six feet under? It's time to bring out the big balloons. You could've been the greatest. Passport stamps, she's cosmopolitan. Your kiss is cosmic, every move is magic.</p>
<p>We're living the life. We're doing it right. Open up your heart. I was tryna hit it and quit it. Her love is like a drug. Always leaves a trail of stardust. The girl's a freak, she drive a jeep in Laguna Beach. Fine, fresh, fierce, we got it on lock. All my girls vintage Chanel baby.</p>
<p>Before you met me I was alright but things were kinda heavy. Peach-pink lips, yeah, everybody stares. This is no big deal. Calling out my name. I could have rewrite your addiction. She's got that, je ne sais quoi, you know it. Heavy is the head that wears the crown. 'Cause, baby, you're a firework. Like thunder gonna shake the ground.</p>
<p>Just own the night like the 4th of July! Im gon put her in a coma. What you're waiting for, it's time for you to show it off. Can't replace you with a million rings. You open my eyes and I'm ready to go, lead me into the light. And here you are. Im gon put her in a coma. Come on, let your colours burst. So cover your eyes, I have a surprise. As I march alone to a different beat. Glitter all over the room pink flamingos in the pool.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
@ -273,7 +293,7 @@ Add `.modal-dialog-centered` to `.modal-dialog` to vertically center the modal.
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Placeholder text for this demonstration of a vertically centered modal dialog.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
@ -291,10 +311,11 @@ Add `.modal-dialog-centered` to `.modal-dialog` to vertically center the modal.
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Placeholder text for this demonstration of a vertically centered modal dialog.</p>
<p>In this case, the dialog has a bit more content, just to show how vertical centering can be added to a scrollable modal.</p>
<p>What follows is just some placeholder text for this modal dialog. Sipping on Rosé, Silver Lake sun, coming up all lazy. Its in the palm of your hand now baby. So we hit the boulevard. So make a wish, I'll make it like your birthday everyday. Do you ever feel already buried deep six feet under? It's time to bring out the big balloons. You could've been the greatest. Passport stamps, she's cosmopolitan. Your kiss is cosmic, every move is magic.</p>
<p>We're living the life. We're doing it right. Open up your heart. I was tryna hit it and quit it. Her love is like a drug. Always leaves a trail of stardust. The girl's a freak, she drive a jeep in Laguna Beach. Fine, fresh, fierce, we got it on lock. All my girls vintage Chanel baby.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
@ -325,6 +346,166 @@ Add `.modal-dialog-centered` to `.modal-dialog` to vertically center the modal.
</div>
```
## Sidebar modals
Convert modals into offcanvas sidebar components with the addition of `.modal-left` or `.modal-right`. These classes override the modal's default position, sizing, and transitions to make them appear as offcanvas drawers for content, shopping carts, navigation, and more.
With these two demos, we've removed our optional `.modal-footer`s, but you can add them back. You can also add any custom content within the modal, or change the default appearance, as you need.
### Left modal
Our first demo is for `.modal-left`, which also has a vertical `.nav-pills` component in it. If you include `.fade` on the `.modal`, the modal and backdrop will slowly fade into view instead of sliding into the viewport from offscreen.
<div class="modal modal-left" id="modalLeft" tabindex="-1" aria-labelledby="modalLeftLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalLeftLabel">Modal left</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<ul class="nav nav-pills flex-column">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Active</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="modal modal-left fade" id="modalLeftFade" tabindex="-1" aria-labelledby="modalLeftFadeLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalLeftFadeLabel">Modal left</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<ul class="nav nav-pills flex-column">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Active</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="bd-example">
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalLeft">
Launch left modal
</button>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalLeftFade">
Launch left modal with fade
</button>
</div>
```html
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalLeft">
Launch left modal
</button>
<div class="modal modal-left" id="modalLeftFade" tabindex="-1" aria-labelledby="modalLeftFadeLabel" aria-hidden="true">
...
</div>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalLeftFadeFade">
Launch left modal with fade
</button>
<div class="modal modal-left fade" id="modalLeftFadeFade" tabindex="-1" aria-labelledby="modalLeftFadeFadeLabel" aria-hidden="true">
...
</div>
```
### Right modal
In this `.modal-right` example, we've removed the default `.modal-body` padding with `.p-0` and added a linked list group within. Just like the left modal, add `.fade` to fade in the modal and backdrop instead of sliding into the viewport from offscreen.
<div class="modal modal-right" id="modalRight" tabindex="-1" aria-labelledby="modalRightLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalRightLabel">Modal right</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-0">
<div class="list-group list-group-flush">
<a href="#" class="list-group-item list-group-item-action active" aria-current="true">Cras justo odio</a>
<a href="#" class="list-group-item list-group-item-action">Dapibus ac facilisis in</a>
<a href="#" class="list-group-item list-group-item-action">Morbi leo risus</a>
<a href="#" class="list-group-item list-group-item-action">Porta ac consectetur ac</a>
<a href="#" class="list-group-item list-group-item-action disabled" tabindex="-1" aria-disabled="true">Vestibulum at eros</a>
</div>
</div>
</div>
</div>
</div>
<div class="modal modal-right fade" id="modalRightFade" tabindex="-1" aria-labelledby="modalRightFadeLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalRightFadeLabel">Modal right</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-0">
<div class="list-group list-group-flush">
<a href="#" class="list-group-item list-group-item-action active" aria-current="true">Cras justo odio</a>
<a href="#" class="list-group-item list-group-item-action">Dapibus ac facilisis in</a>
<a href="#" class="list-group-item list-group-item-action">Morbi leo risus</a>
<a href="#" class="list-group-item list-group-item-action">Porta ac consectetur ac</a>
<a href="#" class="list-group-item list-group-item-action disabled" tabindex="-1" aria-disabled="true">Vestibulum at eros</a>
</div>
</div>
</div>
</div>
</div>
<div class="bd-example">
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalRight">
Launch right modal
</button>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalRightFade">
Launch right modal with fade
</button>
</div>
```html
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalRight">
Launch right modal
</button>
<div class="modal modal-right" id="modalRight" tabindex="-1" aria-labelledby="modalRightLabel" aria-hidden="true">
...
</div>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalRightFade">
Launch right modal with fade
</button>
<div class="modal modal-right fade" id="modalRightFade" tabindex="-1" aria-labelledby="modalRightFadeLabel" aria-hidden="true">
...
</div>
```
## Working with modals
### Tooltips and popovers
[Tooltips]({{< docsref "/components/tooltips" >}}) and [popovers]({{< docsref "/components/popovers" >}}) can be placed within modals as needed. When modals are closed, any tooltips and popovers within are also automatically dismissed.
@ -692,14 +873,24 @@ Another override is the option to pop up a modal that covers the user viewport,
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>What follows is just some placeholder text for this modal dialog. I feel like I'm already there. Im gon put her in a coma. Boom, boom, boom. You're reading me like erotica, boy, you make me feel exotic, yeah. Happy birthday. From Tokyo to Mexico, to Rio. I knew you were.</p>
<p>Last Friday night. Calling out my name. Kiss her, touch her, squeeze her buns. Heavy is the head that wears the crown. So open up your heart and just let it begin. Boy all this time was worth the waiting. You know that I'm the girl that you should call. End of the rainbow looking treasure. You're reading me like erotica, boy, you make me feel exotic, yeah. Do you know that there's still a chance for you 'Cause there's a spark in you? So I sat quietly, agreed politely. From Tokyo to Mexico, to Rio.</p>
<p>Don't be a shy kinda guy I'll bet it's beautiful. You fall asleep during foreplay, 'Cause the pills you take, are more your forte. Open up your heart. You're never gonna be unsatisfied. Know that you are worthy. This one goes out to the ladies at breakfast in last night's dress. You think you've seen her in a magazine. I should've told you what you meant to me 'Cause now I pay the price. Takes you miles high, so high, 'cause shes got that one international smile.</p>
<p>Yo, shout out to all you kids, buying bottle service, with your rent money. So I sat quietly, agreed politely. They say, be afraid you're not like the others, futuristic lover. Boom, boom, boom. Don't need apologies. We can dance, until we die, you and I, will be young forever. If you choose to walk away, dont walk away. You know that I'm the girl that you should call. This Friday night, do it all again.</p>
<p>I'm walking on air. But lil' mama so dope. It's time to bring out the big balloons. Are you ready for, ready for. The boys break their necks try'na to creep a little sneak peek. Summer after high school when we first met. If you want it all. (This is how we do) You open my eyes and I'm ready to go, lead me into the light.</p>
<p>Growing fast into a bolt of lightning. We freak in my jeep, Snoop Doggy Dogg on the stereo. Baby do you dare to do this? Open up your heart and just let it begin. Peach-pink lips, yeah, everybody stares. Be your teenage dream tonight. Are you brave enough to let me see your peacock? You think I'm funny when I tell the punchline wrong. Woo! I knew you were. All this money can't buy me a time machine. I can't sleep let's run away and don't ever look back, don't ever look back.</p>
<p>Make it like your birthday everyday. I'm not sticking around to watch you go down. Uh-huh, I see you. For you I'll risk it all, all. Im gon put her in a coma. She ride me like a roller coaster. You hear my voice, you hear that sound. 'Cause I will love you unconditionally (oh yeah). They say, be afraid you're not like the others, futuristic lover. There is no fear now, let go and just be free, I will love you unconditionally.</p>
<p>We can dance, until we die, you and I, will be young forever. Pop your Pérignon. Last Friday night, yeah I think we broke the law, always say we're gonna stop. Don't need apologies. Give you something good to celebrate. But dont make me your enemy, your enemy, your enemy. Flowers in her hair, she don't care. Tone, tan fit and ready, turn it up cause its gettin' heavy.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
<p>Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>

View file

@ -124,9 +124,9 @@ Adding images to the `.navbar-brand` will likely always require custom styles or
Navbar navigation links build on our `.nav` options with their own modifier class and require the use of [toggler classes](#toggler) for proper responsive styling. **Navigation in navbars will also grow to occupy as much horizontal space as possible** to keep your navbar contents securely aligned.
Add the `.active` class on `.nav-link` to indicate the current page.
Active states—with `.active`—to indicate the current page can be applied directly to `.nav-link`s or their immediate parent `.nav-item`s.
Please note that you should also add the `aria-current` attribute on the active `.nav-link`.
Please note that you should also add the `aria-current` attribute on the `.nav-link` itself.
{{< example >}}
<nav class="navbar navbar-expand-lg navbar-light bg-light">

View file

@ -306,7 +306,7 @@ Add dropdown menus with a little extra HTML and the [dropdowns JavaScript plugin
## JavaScript behavior
Use the tab JavaScript plugin—include it individually or through the compiled `bootstrap.js` file—to extend our navigational tabs and pills to create tabbable panes of local content.
Use the tab JavaScript plugin—include it individually or through the compiled `bootstrap.js` file—to extend our navigational tabs and pills to create tabbable panes of local content, even via dropdown menus.
Dynamic tabbed interfaces, as described in the [<abbr title="Web Accessibility Initiative">WAI</abbr> <abbr title="Accessible Rich Internet Applications">ARIA</abbr> Authoring Practices](https://www.w3.org/TR/wai-aria-practices/#tabpanel), require `role="tablist"`, `role="tab"`, `role="tabpanel"`, and additional `aria-` attributes in order to convey their structure, functionality and current state to users of assistive technologies (such as screen readers).
@ -326,13 +326,13 @@ Note that dynamic tabbed interfaces should <em>not</em> contain dropdown menus,
</ul>
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
<p>Placeholder content for the tab panel. This one relates to the home tab. Takes you miles high, so high, 'cause shes got that one international smile. There's a stranger in my bed, there's a pounding in my head. Oh, no. In another life I would make you stay. Cause I, Im capable of anything. Suiting up for my crowning battle. Used to steal your parents' liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin' heavy. Her love is like a drug. I guess that I forgot I had a choice.</p>
<p>Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.</p>
</div>
<div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">
<p>Placeholder content for the tab panel. This one relates to the profile tab. You got the finest architecture. Passport stamps, she's cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I'd be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she's the one. Greetings loved ones let's take a journey. Just own the night like the 4th of July! But you'd rather get wasted.</p>
<p>Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.</p>
</div>
<div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">
<p>Placeholder content for the tab panel. This one relates to the contact tab. Her love is like a drug. All my girls vintage Chanel baby. Got a motel and built a fort out of sheets. 'Cause she's the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I'm walking, I'm walking on air (tonight). Skip the talk, heard it all, time to walk the walk. Catch her if you can. Stinging like a bee I earned my stripes.</p>
<p>Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.</p>
</div>
</div>
</div>
@ -368,13 +368,13 @@ To help fit your needs, this works with `<ul>`-based markup, as shown above, or
</nav>
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade show active" id="nav-home" role="tabpanel" aria-labelledby="nav-home-tab">
<p>Placeholder content for the tab panel. This one relates to the home tab. Takes you miles high, so high, 'cause shes got that one international smile. There's a stranger in my bed, there's a pounding in my head. Oh, no. In another life I would make you stay. Cause I, Im capable of anything. Suiting up for my crowning battle. Used to steal your parents' liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin' heavy. Her love is like a drug. I guess that I forgot I had a choice.</p>
<p>Et et consectetur ipsum labore excepteur est proident excepteur ad velit occaecat qui minim occaecat veniam. Fugiat veniam incididunt anim aliqua enim pariatur veniam sunt est aute sit dolor anim. Velit non irure adipisicing aliqua ullamco irure incididunt irure non esse consectetur nostrud minim non minim occaecat. Amet duis do nisi duis veniam non est eiusmod tempor incididunt tempor dolor ipsum in qui sit. Exercitation mollit sit culpa nisi culpa non adipisicing reprehenderit do dolore. Duis reprehenderit occaecat anim ullamco ad duis occaecat ex.</p>
</div>
<div class="tab-pane fade" id="nav-profile" role="tabpanel" aria-labelledby="nav-profile-tab">
<p>Placeholder content for the tab panel. This one relates to the profile tab. You got the finest architecture. Passport stamps, she's cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I'd be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she's the one. Greetings loved ones let's take a journey. Just own the night like the 4th of July! But you'd rather get wasted.</p>
<p>Nulla est ullamco ut irure incididunt nulla Lorem Lorem minim irure officia enim reprehenderit. Magna duis labore cillum sint adipisicing exercitation ipsum. Nostrud ut anim non exercitation velit laboris fugiat cupidatat. Commodo esse dolore fugiat sint velit ullamco magna consequat voluptate minim amet aliquip ipsum aute laboris nisi. Labore labore veniam irure irure ipsum pariatur mollit magna in cupidatat dolore magna irure esse tempor ad mollit. Dolore commodo nulla minim amet ipsum officia consectetur amet ullamco voluptate nisi commodo ea sit eu.</p>
</div>
<div class="tab-pane fade" id="nav-contact" role="tabpanel" aria-labelledby="nav-contact-tab">
<p>Placeholder content for the tab panel. This one relates to the contact tab. Her love is like a drug. All my girls vintage Chanel baby. Got a motel and built a fort out of sheets. 'Cause she's the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I'm walking, I'm walking on air (tonight). Skip the talk, heard it all, time to walk the walk. Catch her if you can. Stinging like a bee I earned my stripes.</p>
<p>Sint sit mollit irure quis est nostrud cillum consequat Lorem esse do quis dolor esse fugiat sunt do. Eu ex commodo veniam Lorem aliquip laborum occaecat qui Lorem esse mollit dolore anim cupidatat. Deserunt officia id Lorem nostrud aute id commodo elit eiusmod enim irure amet eiusmod qui reprehenderit nostrud tempor. Fugiat ipsum excepteur in aliqua non et quis aliquip ad irure in labore cillum elit enim. Consequat aliquip incididunt ipsum et minim laborum laborum laborum et cillum labore. Deserunt adipisicing cillum id nulla minim nostrud labore eiusmod et amet. Laboris consequat consequat commodo non ut non aliquip reprehenderit nulla anim occaecat. Sunt sit ullamco reprehenderit irure ea ullamco Lorem aute nostrud magna.</p>
</div>
</div>
</div>
@ -410,13 +410,13 @@ The tabs plugin also works with pills.
</ul>
<div class="tab-content" id="pills-tabContent">
<div class="tab-pane fade show active" id="pills-home" role="tabpanel" aria-labelledby="pills-home-tab">
<p>Placeholder content for the tab panel. This one relates to the home tab. Takes you miles high, so high, 'cause shes got that one international smile. There's a stranger in my bed, there's a pounding in my head. Oh, no. In another life I would make you stay. Cause I, Im capable of anything. Suiting up for my crowning battle. Used to steal your parents' liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin' heavy. Her love is like a drug. I guess that I forgot I had a choice.</p>
<p>Consequat occaecat ullamco amet non eiusmod nostrud dolore irure incididunt est duis anim sunt officia. Fugiat velit proident aliquip nisi incididunt nostrud exercitation proident est nisi. Irure magna elit commodo anim ex veniam culpa eiusmod id nostrud sit cupidatat in veniam ad. Eiusmod consequat eu adipisicing minim anim aliquip cupidatat culpa excepteur quis. Occaecat sit eu exercitation irure Lorem incididunt nostrud.</p>
</div>
<div class="tab-pane fade" id="pills-profile" role="tabpanel" aria-labelledby="pills-profile-tab">
<p>Placeholder content for the tab panel. This one relates to the profile tab. You got the finest architecture. Passport stamps, she's cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I'd be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she's the one. Greetings loved ones let's take a journey. Just own the night like the 4th of July! But you'd rather get wasted.</p>
<p>Ad pariatur nostrud pariatur exercitation ipsum ipsum culpa mollit commodo mollit ex. Aute sunt incididunt amet commodo est sint nisi deserunt pariatur do. Aliquip ex eiusmod voluptate exercitation cillum id incididunt elit sunt. Qui minim sit magna Lorem id et dolore velit Lorem amet exercitation duis deserunt. Anim id labore elit adipisicing ut in id occaecat pariatur ut ullamco ea tempor duis.</p>
</div>
<div class="tab-pane fade" id="pills-contact" role="tabpanel" aria-labelledby="pills-contact-tab">
<p>Placeholder content for the tab panel. This one relates to the contact tab. Her love is like a drug. All my girls vintage Chanel baby. Got a motel and built a fort out of sheets. 'Cause she's the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I'm walking, I'm walking on air (tonight). Skip the talk, heard it all, time to walk the walk. Catch her if you can. Stinging like a bee I earned my stripes.</p>
<p>Est quis nulla laborum officia ad nisi ex nostrud culpa Lorem excepteur aliquip dolor aliqua irure ex. Nulla ut duis ipsum nisi elit fugiat commodo sunt reprehenderit laborum veniam eu veniam. Eiusmod minim exercitation fugiat irure ex labore incididunt do fugiat commodo aliquip sit id deserunt reprehenderit aliquip nostrud. Amet ex cupidatat excepteur aute veniam incididunt mollit cupidatat esse irure officia elit do ipsum ullamco Lorem. Ullamco ut ad minim do mollit labore ipsum laboris ipsum commodo sunt tempor enim incididunt. Commodo quis sunt dolore aliquip aute tempor irure magna enim minim reprehenderit. Ullamco consectetur culpa veniam sint cillum aliqua incididunt velit ullamco sunt ullamco quis quis commodo voluptate. Mollit nulla nostrud adipisicing aliqua cupidatat aliqua pariatur mollit voluptate voluptate consequat non.</p>
</div>
</div>
</div>
@ -452,16 +452,16 @@ And with vertical pills.
</div>
<div class="tab-content" id="v-pills-tabContent">
<div class="tab-pane fade show active" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab">
<p>Placeholder content for the tab panel. This one relates to the home tab. Saw you downtown singing the Blues. Watch you circle the drain. Why don't you let me stop by? Heavy is the head that wears the crown. Yes, we make angels cry, raining down on earth from up above. Wanna see the show in 3D, a movie. Do you ever feel, feel so paper thin. Its a yes or no, no maybe.</p>
<p>Cillum ad ut irure tempor velit nostrud occaecat ullamco aliqua anim Lorem sint. Veniam sint duis incididunt do esse magna mollit excepteur laborum qui. Id id reprehenderit sit est eu aliqua occaecat quis et velit excepteur laborum mollit dolore eiusmod. Ipsum dolor in occaecat commodo et voluptate minim reprehenderit mollit pariatur. Deserunt non laborum enim et cillum eu deserunt excepteur ea incididunt minim occaecat.</p>
</div>
<div class="tab-pane fade" id="v-pills-profile" role="tabpanel" aria-labelledby="v-pills-profile-tab">
<p>Placeholder content for the tab panel. This one relates to the profile tab. Takes you miles high, so high, 'cause shes got that one international smile. There's a stranger in my bed, there's a pounding in my head. Oh, no. In another life I would make you stay. Cause I, Im capable of anything. Suiting up for my crowning battle. Used to steal your parents' liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin' heavy. Her love is like a drug. I guess that I forgot I had a choice.</p>
<p>Culpa dolor voluptate do laboris laboris irure reprehenderit id incididunt duis pariatur mollit aute magna pariatur consectetur. Eu veniam duis non ut dolor deserunt commodo et minim in quis laboris ipsum velit id veniam. Quis ut consectetur adipisicing officia excepteur non sit. Ut et elit aliquip labore Lorem enim eu. Ullamco mollit occaecat dolore ipsum id officia mollit qui esse anim eiusmod do sint minim consectetur qui.</p>
</div>
<div class="tab-pane fade" id="v-pills-messages" role="tabpanel" aria-labelledby="v-pills-messages-tab">
<p>Placeholder content for the tab panel. This one relates to the messages tab. You got the finest architecture. Passport stamps, she's cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I'd be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she's the one. Greetings loved ones let's take a journey. Just own the night like the 4th of July! But you'd rather get wasted.</p>
<p>Fugiat id quis dolor culpa eiusmod anim velit excepteur proident dolor aute qui magna. Ad proident laboris ullamco esse anim Lorem Lorem veniam quis Lorem irure occaecat velit nostrud magna nulla. Velit et et proident Lorem do ea tempor officia dolor. Reprehenderit Lorem aliquip labore est magna commodo est ea veniam consectetur.</p>
</div>
<div class="tab-pane fade" id="v-pills-settings" role="tabpanel" aria-labelledby="v-pills-settings-tab">
<p>Placeholder content for the tab panel. This one relates to the settings tab. Her love is like a drug. All my girls vintage Chanel baby. Got a motel and built a fort out of sheets. 'Cause she's the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I'm walking, I'm walking on air (tonight). Skip the talk, heard it all, time to walk the walk. Catch her if you can. Stinging like a bee I earned my stripes.</p>
<p>Eu dolore ea ullamco dolore Lorem id cupidatat excepteur reprehenderit consectetur elit id dolor proident in cupidatat officia. Voluptate excepteur commodo labore nisi cillum duis aliqua do. Aliqua amet qui mollit consectetur nulla mollit velit aliqua veniam nisi id do Lorem deserunt amet. Culpa ullamco sit adipisicing labore officia magna elit nisi in aute tempor commodo eiusmod.</p>
</div>
</div>
</div>

View file

@ -62,20 +62,40 @@ var popover = new bootstrap.Popover(document.querySelector('.example-popover'),
Four options are available: top, right, bottom, and left aligned. Directions are mirrored when using Bootstrap in RTL.
{{< example >}}
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="top" data-bs-content="Top popover">
<div class="bd-example popover-demo">
<div class="bd-example-popovers">
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="top" data-bs-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Popover on top
</button>
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="right" data-bs-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Popover on right
</button>
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="bottom" data-bs-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Popover on bottom
</button>
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="left" data-bs-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Popover on left
</button>
</div>
</div>
```html
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="top" data-bs-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Popover on top
</button>
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="right" data-bs-content="Right popover">
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="right" data-bs-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Popover on right
</button>
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="bottom" data-bs-content="Bottom popover">
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="bottom" data-bs-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Popover on bottom
</button>
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="left" data-bs-content="Left popover">
<button type="button" class="btn btn-secondary" data-bs-container="body" data-bs-toggle="popover" data-bs-placement="left" data-bs-content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus.">
Popover on left
</button>
{{< /example >}}
```
### Dismiss on next click
@ -99,13 +119,13 @@ var popover = new bootstrap.Popover(document.querySelector('.popover-dismiss'),
### Disabled elements
Elements with the `disabled` attribute aren't interactive, meaning users cannot hover or click them to trigger a popover (or tooltip). As a workaround, you'll want to trigger the popover from a wrapper `<div>` or `<span>`, ideally made keyboard-focusable using `tabindex="0"`.
Elements with the `disabled` attribute aren't interactive, meaning users cannot hover or click them to trigger a popover (or tooltip). As a workaround, you'll want to trigger the popover from a wrapper `<div>` or `<span>` and override the `pointer-events` on the disabled element.
For disabled popover triggers, you may also prefer `data-bs-trigger="hover focus"` so that the popover appears as immediate visual feedback to your users as they may not expect to _click_ on a disabled element.
For disabled popover triggers, you may also prefer `data-bs-trigger="hover"` so that the popover appears as immediate visual feedback to your users as they may not expect to _click_ on a disabled element.
{{< example >}}
<span class="d-inline-block" tabindex="0" data-bs-toggle="popover" data-bs-trigger="hover focus" data-bs-content="Disabled popover">
<button class="btn btn-primary" type="button" disabled>Disabled button</button>
<span class="d-inline-block" data-bs-toggle="popover" data-bs-content="Disabled popover">
<button class="btn btn-primary" style="pointer-events: none;" type="button" disabled>Disabled button</button>
</span>
{{< /example >}}
@ -228,17 +248,23 @@ Note that for security reasons the `sanitize`, `sanitizeFn`, and `allowList` opt
<td>How popover is triggered - click | hover | focus | manual. You may pass multiple triggers; separate them with a space. <code>manual</code> cannot be combined with any other trigger.</td>
</tr>
<tr>
<td><code>fallbackPlacements</code></td>
<td>array</td>
<td><code>['top', 'right', 'bottom', 'left']</code></td>
<td>Define fallback placements by providing a list of placements in array (in order of preference). For more information refer to
Popper's <a href="https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements">behavior docs</a></td>
<td><code>offset</code></td>
<td>number | string</td>
<td><code>0</code></td>
<td>Offset of the popover relative to its target. For more information refer to Popper's <a href="https://popper.js.org/docs/v1/#modifiers..offset.offset">offset docs</a>.</td>
</tr>
<tr>
<td><code>fallbackPlacement</code></td>
<td>string | array</td>
<td><code>'flip'</code></td>
<td>Allow to specify which position Popper will use on fallback. For more information refer to
Popper's <a href="https://popper.js.org/docs/v1/#modifiers..flip.behavior">behavior docs</a></td>
</tr>
<tr>
<td><code>boundary</code></td>
<td>string | element</td>
<td><code>'scrollParent'</code></td>
<td>Overflow constraint boundary of the popover. Accepts the values of <code>'viewport'</code>, <code>'window'</code>, <code>'scrollParent'</code>, or an HTMLElement reference (JavaScript only). For more information refer to Popper's <a href="https://popper.js.org/docs/v2/utils/detect-overflow/#boundary">preventOverflow docs</a>.</td>
<td>Overflow constraint boundary of the popover. Accepts the values of <code>'viewport'</code>, <code>'window'</code>, <code>'scrollParent'</code>, or an HTMLElement reference (JavaScript only). For more information refer to Popper's <a href="https://popper.js.org/docs/v1/#modifiers..preventOverflow.boundariesElement">preventOverflow docs</a>.</td>
</tr>
<tr>
<td><code>customClass</code></td>
@ -271,7 +297,7 @@ Note that for security reasons the `sanitize`, `sanitizeFn`, and `allowList` opt
<td><code>popperConfig</code></td>
<td>null | object</td>
<td><code>null</code></td>
<td>To change Bootstrap's default Popper config, see <a href="https://popper.js.org/docs/v2/constructors/#options">Popper's configuration</a></td>
<td>To change Bootstrap's default Popper config, see <a href="https://popper.js.org/docs/v1/#Popper.Defaults">Popper's configuration</a></td>
</tr>
</tbody>
</table>

View file

@ -49,16 +49,17 @@ Scroll the area below the navbar and watch the active class change. The dropdown
</nav>
<div data-bs-spy="scroll" data-bs-target="#navbar-example2" data-bs-offset="0" class="scrollspy-example" tabindex="0">
<h4 id="fat">@fat</h4>
<p>Placeholder content for the scrollspy example. You got the finest architecture. Passport stamps, she's cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I'd be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she's the one. Greetings loved ones let's take a journey. Just own the night like the 4th of July! But you'd rather get wasted.</p>
<p>Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle rights whatever. Anim keffiyeh carles cardigan. Velit seitan mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean shorts, williamsburg hoodie minim qui you probably haven't heard of them et cardigan trust fund culpa biodiesel wes anderson aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh artisan ullamco consequat.</p>
<h4 id="mdo">@mdo</h4>
<p>Placeholder content for the scrollspy example. 'Cause she's the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I'm walking, I'm walking on air (tonight). Skip the talk, heard it all, time to walk the walk.</p>
<p>Veniam marfa mustache skateboard, adipisicing fugiat velit pitchfork beard. Freegan beard aliqua cupidatat mcsweeney's vero. Cupidatat four loko nisi, ea helvetica nulla carles. Tattooed cosby sweater food truck, mcsweeney's quis non freegan vinyl. Lo-fi wes anderson +1 sartorial. Carles non aesthetic exercitation quis gentrify. Brooklyn adipisicing craft beer vice keytar deserunt.</p>
<h4 id="one">one</h4>
<p>Placeholder content for the scrollspy example. Takes you miles high, so high, 'cause shes got that one international smile. There's a stranger in my bed, there's a pounding in my head. Oh, no. In another life I would make you stay. Cause I, Im capable of anything. Suiting up for my crowning battle. Used to steal your parents' liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin' heavy. Her love is like a drug. I guess that I forgot I had a choice.</p>
<p>Occaecat commodo aliqua delectus. Fap craft beer deserunt skateboard ea. Lomo bicycle rights adipisicing banh mi, velit ea sunt next level locavore single-origin coffee in magna veniam. High life id vinyl, echo park consequat quis aliquip banh mi pitchfork. Vero VHS est adipisicing. Consectetur nisi DIY minim messenger bag. Cred ex in, sustainable delectus consectetur fanny pack iphone.</p>
<h4 id="two">two</h4>
<p>Placeholder content for the scrollspy example. It's time to bring out the big balloons. I'm walking, I'm walking on air (tonight). Yeah, we maxed our credit cards and got kicked out of the bar. Yo, shout out to all you kids, buying bottle service, with your rent money. I'm ma get your heart racing in my skin-tight jeans. If you get the chance you better keep her. Yo, shout out to all you kids, buying bottle service, with your rent money.</p>
<p>In incididunt echo park, officia deserunt mcsweeney's proident master cleanse thundercats sapiente veniam. Excepteur VHS elit, proident shoreditch +1 biodiesel laborum craft beer. Single-origin coffee wayfarers irure four loko, cupidatat terry richardson master cleanse. Assumenda you probably haven't heard of them art party fanny pack, tattooed nulla cardigan tempor ad. Proident wolf nesciunt sartorial keffiyeh eu banh mi sustainable. Elit wolf voluptate, lo-fi ea portland before they sold out four loko. Locavore enim nostrud mlkshk brooklyn nesciunt.</p>
<h4 id="three">three</h4>
<p>Placeholder content for the scrollspy example. If you wanna dance, if you want it all, you know that I'm the girl that you should call. Walk through the storm I would. So let me get you in your birthday suit. The one that got away. Last Friday night, yeah I think we broke the law, always say we're gonna stop. 'Cause she's a little bit of Yoko, And she's a little bit of 'Oh no'. I want the jaw droppin', eye poppin', head turnin', body shockin'. Yeah, we maxed our credit cards and got kicked out of the bar.</p>
<p>And some more placeholder content, for good measure.</p>
<p>Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle rights whatever. Anim keffiyeh carles cardigan. Velit seitan mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean shorts, williamsburg hoodie minim qui you probably haven't heard of them et cardigan trust fund culpa biodiesel wes anderson aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh artisan ullamco consequat.</p>
<p>Keytar twee blog, culpa messenger bag marfa whatever delectus food truck. Sapiente synth id assumenda. Locavore sed helvetica cliche irony, thundercats you probably haven't heard of them consequat hoodie gluten-free lo-fi fap aliquip. Labore elit placeat before they sold out, terry richardson proident brunch nesciunt quis cosby sweater pariatur keffiyeh ut helvetica artisan. Cardigan craft beer seitan readymade velit. VHS chambray laboris tempor veniam. Anim mollit minim commodo ullamco thundercats.
</p>
</div>
</div>
@ -124,19 +125,19 @@ Scrollspy also works with nested `.nav`s. If a nested `.nav` is `.active`, its p
<div class="col-8">
<div data-bs-spy="scroll" data-bs-target="#navbar-example3" data-bs-offset="0" class="scrollspy-example-2" tabindex="0">
<h4 id="item-1">Item 1</h4>
<p>Placeholder content for the scrollspy example. This one relates to item 1. Takes you miles high, so high, 'cause shes got that one international smile. There's a stranger in my bed, there's a pounding in my head. Oh, no. In another life I would make you stay. Cause I, Im capable of anything. Suiting up for my crowning battle. Used to steal your parents' liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin' heavy. Her love is like a drug. I guess that I forgot I had a choice.</p>
<p>Ex consequat commodo adipisicing exercitation aute excepteur occaecat ullamco duis aliqua id magna ullamco eu. Do aute ipsum ipsum ullamco cillum consectetur ut et aute consectetur labore. Fugiat laborum incididunt tempor eu consequat enim dolore proident. Qui laborum do non excepteur nulla magna eiusmod consectetur in. Aliqua et aliqua officia quis et incididunt voluptate non anim reprehenderit adipisicing dolore ut consequat deserunt mollit dolore. Aliquip nulla enim veniam non fugiat id cupidatat nulla elit cupidatat commodo velit ut eiusmod cupidatat elit dolore.</p>
<h5 id="item-1-1">Item 1-1</h5>
<p>Placeholder content for the scrollspy example. This one relates to the item 1-1. You got the finest architecture. Passport stamps, she's cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I'd be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she's the one. Greetings loved ones let's take a journey. Just own the night like the 4th of July! But you'd rather get wasted.</p>
<p>Amet tempor mollit aliquip pariatur excepteur commodo do ea cillum commodo Lorem et occaecat elit qui et. Aliquip labore ex ex esse voluptate occaecat Lorem ullamco deserunt. Aliqua cillum excepteur irure consequat id quis ea. Sit proident ullamco aute magna pariatur nostrud labore. Reprehenderit aliqua commodo eiusmod aliquip est do duis amet proident magna consectetur consequat eu commodo fugiat non quis. Enim aliquip exercitation ullamco adipisicing voluptate excepteur minim exercitation minim minim commodo adipisicing exercitation officia nisi adipisicing. Anim id duis qui consequat labore adipisicing sint dolor elit cillum anim et fugiat.</p>
<h5 id="item-1-2">Item 1-2</h5>
<p>Placeholder content for the scrollspy example. This one relates to the item 1-2. Her love is like a drug. All my girls vintage Chanel baby. Got a motel and built a fort out of sheets. 'Cause she's the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I'm walking, I'm walking on air (tonight). Skip the talk, heard it all, time to walk the walk. Catch her if you can. Stinging like a bee I earned my stripes.</p>
<p>Cillum nisi deserunt magna eiusmod qui eiusmod velit voluptate pariatur laborum sunt enim. Irure laboris mollit consequat incididunt sint et culpa culpa incididunt adipisicing magna magna occaecat. Nulla ipsum cillum eiusmod sint elit excepteur ea labore enim consectetur in labore anim. Proident ullamco ipsum esse elit ut Lorem eiusmod dolor et eiusmod. Anim occaecat nulla in non consequat eiusmod velit incididunt.</p>
<h4 id="item-2">Item 2</h4>
<p>Placeholder content for the scrollspy example. This one relates to item 2. Don't need apologies. There is no fear now, let go and just be free, I will love you unconditionally. Last Friday night. Don't be a shy kinda guy I'll bet it's beautiful. Summer after high school when we first met. 'Cause she's the muse and the artist. What? Wait. No, no, no, no. Thought that I was the exception.</p>
<p>Quis magna Lorem anim amet ipsum do mollit sit cillum voluptate ex nulla tempor. Laborum consequat non elit enim exercitation cillum aliqua consequat id aliqua. Esse ex consectetur mollit voluptate est in duis laboris ad sit ipsum anim Lorem. Incididunt veniam velit elit elit veniam Lorem aliqua quis ullamco deserunt sit enim elit aliqua esse irure. Laborum nisi sit est tempor laborum mollit labore officia laborum excepteur commodo non commodo dolor excepteur commodo. Ipsum fugiat ex est consectetur ipsum commodo tempor sunt in proident.</p>
<h4 id="item-3">Item 3</h4>
<p>Placeholder content for the scrollspy example. This one relates to item 3. Word on the street, you got somethin' to show me, me. All this money can't buy me a time machine. Make it like your birthday everyday. So we hit the boulevard. You make me feel like I'm livin' a teenage dream, the way you turn me on Skip the talk, heard it all, time to walk the walk. Word on the street, you got somethin' to show me, me. It's no big deal, it's no big deal, it's no big deal.</p>
<p>Quis anim sit do amet fugiat dolor velit sit ea ea do reprehenderit culpa duis. Nostrud aliqua ipsum fugiat minim proident occaecat excepteur aliquip culpa aute tempor reprehenderit. Deserunt tempor mollit elit ex pariatur dolore velit fugiat mollit culpa irure ullamco est ex ullamco excepteur.</p>
<h5 id="item-3-1">Item 3-1</h5>
<p>Placeholder content for the scrollspy example. This one relates to item 3-1. Baby do you dare to do this? This is no big deal. Yeah, you're lucky if you're on her plane. Just own the night like the 4th of July! Standing on the frontline when the bombs start to fall. So just be sure before you give it all to me.</p>
<p>Deserunt quis elit Lorem eiusmod amet enim enim amet minim Lorem proident nostrud. Ea id dolore anim exercitation aute fugiat labore voluptate cillum do laboris labore. Ex velit exercitation nisi enim labore reprehenderit labore nostrud ut ut. Esse officia sunt duis aliquip ullamco tempor eiusmod deserunt irure nostrud irure. Ullamco proident veniam laboris ea consectetur magna sunt ex exercitation aliquip minim enim culpa occaecat exercitation. Est tempor excepteur aliquip laborum consequat do deserunt laborum esse eiusmod irure proident ipsum esse qui.</p>
<h5 id="item-3-2">Item 3-2</h5>
<p>Placeholder content for the scrollspy example. This one relates to item 3-2. You're original, cannot be replaced. All night they're playing, your song. California girls we're undeniable. Like a bird without a cage. There is no fear now, let go and just be free, I will love you unconditionally. I can see the writing on the wall. You could travel the world but nothing comes close to the golden coast.</p>
<p>Labore sit culpa commodo elit adipisicing sit aliquip elit proident voluptate minim mollit nostrud aute reprehenderit do. Mollit excepteur eu Lorem ipsum anim commodo sint labore Lorem in exercitation velit incididunt. Occaecat consectetur nisi in occaecat proident minim enim sunt reprehenderit exercitation cupidatat et do officia. Aliquip consequat ad labore labore mollit ut amet. Sit pariatur tempor proident in veniam culpa aliqua excepteur elit magna fugiat eiusmod amet officia.</p>
</div>
</div>
</div>
@ -195,13 +196,13 @@ Scrollspy also works with `.list-group`s. Scroll the area next to the list group
<div class="col-8">
<div data-bs-spy="scroll" data-bs-target="#list-example" data-bs-offset="0" class="scrollspy-example" tabindex="0">
<h4 id="list-item-1">Item 1</h4>
<p>Placeholder content for the scrollspy list-group example. This one relates to item 1. Don't need apologies. There is no fear now, let go and just be free, I will love you unconditionally. Last Friday night. Don't be a shy kinda guy I'll bet it's beautiful. Summer after high school when we first met. 'Cause she's the muse and the artist. What? Wait. Thought that I was the exception.</p>
<p>Ex consequat commodo adipisicing exercitation aute excepteur occaecat ullamco duis aliqua id magna ullamco eu. Do aute ipsum ipsum ullamco cillum consectetur ut et aute consectetur labore. Fugiat laborum incididunt tempor eu consequat enim dolore proident. Qui laborum do non excepteur nulla magna eiusmod consectetur in. Aliqua et aliqua officia quis et incididunt voluptate non anim reprehenderit adipisicing dolore ut consequat deserunt mollit dolore. Aliquip nulla enim veniam non fugiat id cupidatat nulla elit cupidatat commodo velit ut eiusmod cupidatat elit dolore.</p>
<h4 id="list-item-2">Item 2</h4>
<p>Placeholder content for the scrollspy list-group example. This one relates to item 2. Yeah, she dances to her own beat. Oh, no. You could've been the greatest. 'Cause, baby, you're a firework. Maybe a reason why all the doors are closed. Open up your heart and just let it begin. So très chic, yeah, she's a classic.</p>
<p>Quis magna Lorem anim amet ipsum do mollit sit cillum voluptate ex nulla tempor. Laborum consequat non elit enim exercitation cillum aliqua consequat id aliqua. Esse ex consectetur mollit voluptate est in duis laboris ad sit ipsum anim Lorem. Incididunt veniam velit elit elit veniam Lorem aliqua quis ullamco deserunt sit enim elit aliqua esse irure. Laborum nisi sit est tempor laborum mollit labore officia laborum excepteur commodo non commodo dolor excepteur commodo. Ipsum fugiat ex est consectetur ipsum commodo tempor sunt in proident.</p>
<h4 id="list-item-3">Item 3</h4>
<p>Placeholder content for the scrollspy list-group example. This one relates to item 3. We go higher and higher. Never one without the other, we made a pact. I'm walking on air. Someone said you had your tattoo removed. Now Im floating like a butterfly. Tone, tan fit and ready, turn it up cause its gettin' heavy. Cause once youre mine, once youre mine. You just gotta ignite the light and let it shine! So we hit the boulevard. Do you ever feel, feel so paper thin. I see it all, I see it now.</p>
<p>Quis anim sit do amet fugiat dolor velit sit ea ea do reprehenderit culpa duis. Nostrud aliqua ipsum fugiat minim proident occaecat excepteur aliquip culpa aute tempor reprehenderit. Deserunt tempor mollit elit ex pariatur dolore velit fugiat mollit culpa irure ullamco est ex ullamco excepteur.</p>
<h4 id="list-item-4">Item 4</h4>
<p>Placeholder content for the scrollspy list-group example. This one relates to item 4. Summer after high school when we first met. There is no fear now, let go and just be free, I will love you unconditionally. Sun-kissed skin so hot we'll melt your popsicle. This love will make you levitate.</p>
<p>Quis anim sit do amet fugiat dolor velit sit ea ea do reprehenderit culpa duis. Nostrud aliqua ipsum fugiat minim proident occaecat excepteur aliquip culpa aute tempor reprehenderit. Deserunt tempor mollit elit ex pariatur dolore velit fugiat mollit culpa irure ullamco est ex ullamco excepteur.</p>
</div>
</div>
</div>
@ -226,6 +227,7 @@ Scrollspy also works with `.list-group`s. Scroll the area next to the list group
</div>
```
## Usage
### Via data attributes

View file

@ -43,7 +43,7 @@ Toasts are as flexible as you need and have very little required markup. At a mi
### Translucent
Toasts are slightly translucent, too, so they blend over whatever they might appear over.
Toasts are slightly translucent, too, so they blend over whatever they might appear over. For browsers that support the `backdrop-filter` CSS property, we'll also attempt to blur the elements under a toast.
{{< example class="bg-dark" >}}
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true">
@ -120,7 +120,7 @@ Alternatively, you can also add additional controls and components to toasts.
### Color schemes
Building on the above example, you can create different toast color schemes with our [color utilities]({{< docsref "/utilities/colors" >}}). Here we've added `.bg-primary` and `.text-white` to the `.toast`, and then added `.btn-close-white` to our close button. For a crisp edge, we remove the default border with `.border-0`.
Building on the above example, you can create different toast color schemes with our [color utilities]({{< docsref "/utilities/colors" >}}). Here we've added `.bg-primary` and `.text-white` to the `.toast`, and then added `.text-white` to our close button. For a crisp edge, we remove the default border with `.border-0`.
{{< example class="bg-light" >}}
<div class="toast d-flex align-items-center text-white bg-primary border-0" role="alert" aria-live="assertive" aria-atomic="true">
@ -137,7 +137,7 @@ Place toasts with custom CSS as you need them. The top right is often used for n
{{< example >}}
<form>
<div class="mb-3">
<div class="form-group mb-3">
<label for="selectToastPlacement">Toast placement</label>
<select class="form-select mt-2" id="selectToastPlacement">
<option value="" selected>Select a position...</option>

View file

@ -46,7 +46,7 @@ var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
Hover over the links below to see tooltips:
<div class="bd-example tooltip-demo">
<p class="muted">Placeholder text to demonstrate some <a href="#" data-bs-toggle="tooltip" title="Default tooltip">inline links</a> with tooltips. This is now just filler, no killer. Content placed here just to mimic the presence of <a href="#" data-bs-toggle="tooltip" title="Another tooltip">real text</a>. And all that just to give you an idea of how tooltips would look when used in real-world situations. So hopefully you've now seen how <a href="#" data-bs-toggle="tooltip" title="Another one here too">these tooltips on links</a> can work in practice, once you use them on <a href="#" data-bs-toggle="tooltip" title="The last tip!">your own</a> site or project.
<p class="muted">Tight pants next level keffiyeh <a href="#" data-bs-toggle="tooltip" title="Default tooltip">you probably</a> haven't heard of them. Photo booth beard raw denim letterpress vegan messenger bag stumptown. Farm-to-table seitan, mcsweeney's fixie sustainable quinoa 8-bit american apparel <a href="#" data-bs-toggle="tooltip" title="Another tooltip">have a</a> terry richardson vinyl chambray. Beard stumptown, cardigans banh mi lomo thundercats. Tofu biodiesel williamsburg marfa, four loko mcsweeney's cleanse vegan chambray. A really ironic artisan <a href="#" data-bs-toggle="tooltip" title="Another one here too">whatever keytar</a>, scenester farm-to-table banksy Austin <a href="#" data-bs-toggle="tooltip" title="The last tip!">twitter handle</a> freegan cred raw denim single-origin coffee viral.
</p>
</div>
@ -145,12 +145,12 @@ You should only add tooltips to HTML elements that are traditionally keyboard-fo
### Disabled elements
Elements with the `disabled` attribute aren't interactive, meaning users cannot focus, hover, or click them to trigger a tooltip (or popover). As a workaround, you'll want to trigger the tooltip from a wrapper `<div>` or `<span>`, ideally made keyboard-focusable using `tabindex="0"`.
Elements with the `disabled` attribute aren't interactive, meaning users cannot focus, hover, or click them to trigger a tooltip (or popover). As a workaround, you'll want to trigger the tooltip from a wrapper `<div>` or `<span>`, ideally made keyboard-focusable using `tabindex="0"`, and override the `pointer-events` on the disabled element.
<div class="tooltip-demo">
{{< example >}}
<span class="d-inline-block" tabindex="0" data-bs-toggle="tooltip" title="Disabled tooltip">
<button class="btn btn-primary" type="button" disabled>Disabled button</button>
<button class="btn btn-primary" style="pointer-events: none;" type="button" disabled>Disabled button</button>
</span>
{{< /example >}}
</div>
@ -253,10 +253,10 @@ Note that for security reasons the `sanitize`, `sanitizeFn`, and `allowList` opt
</td>
</tr>
<tr>
<td><code>fallbackPlacements</code></td>
<td>array</td>
<td><code>['top', 'right', 'bottom', 'left']</code></td>
<td>Define fallback placements by providing a list of placements in array (in order of preference). For more information refer to
<td><code>fallbackPlacement</code></td>
<td>null | array</td>
<td><code>null</code></td>
<td>Allow to specify which position Popper will use on fallback. For more information refer to
Popper's <a href="https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements">behavior docs</a></td>
</tr>
<tr>
@ -296,7 +296,7 @@ Note that for security reasons the `sanitize`, `sanitizeFn`, and `allowList` opt
<td><code>popperConfig</code></td>
<td>null | object</td>
<td><code>null</code></td>
<td>To change Bootstrap's default Popper config, see <a href="https://popper.js.org/docs/v2/constructors/#options">Popper's configuration</a></td>
<td>To change Bootstrap's default Popper config, see <a href="https://popper.js.org/docs/v1/#Popper.Defaults">Popper's configuration</a></td>
</tr>
</tbody>
</table>

Some files were not shown because too many files have changed in this diff Show more