Merge branch 'main' into main-xmr-js-isRTL
This commit is contained in:
commit
ea0eaa0b8b
39 changed files with 261 additions and 180 deletions
5
.github/workflows/browserstack.yml
vendored
5
.github/workflows/browserstack.yml
vendored
|
|
@ -4,7 +4,6 @@ on:
|
|||
push:
|
||||
|
||||
env:
|
||||
CI: true
|
||||
FORCE_COLOR: 2
|
||||
NODE: 14.x
|
||||
|
||||
|
|
@ -29,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
|
||||
|
|
|
|||
5
.github/workflows/bundlewatch.yml
vendored
5
.github/workflows/bundlewatch.yml
vendored
|
|
@ -7,7 +7,6 @@ on:
|
|||
pull_request:
|
||||
|
||||
env:
|
||||
CI: true
|
||||
FORCE_COLOR: 2
|
||||
NODE: 14.x
|
||||
|
||||
|
|
@ -30,8 +29,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
|
||||
|
|
|
|||
5
.github/workflows/css.yml
vendored
5
.github/workflows/css.yml
vendored
|
|
@ -7,7 +7,6 @@ on:
|
|||
pull_request:
|
||||
|
||||
env:
|
||||
CI: true
|
||||
FORCE_COLOR: 2
|
||||
NODE: 14.x
|
||||
|
||||
|
|
@ -30,8 +29,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
|
||||
|
|
|
|||
5
.github/workflows/docs.yml
vendored
5
.github/workflows/docs.yml
vendored
|
|
@ -7,7 +7,6 @@ on:
|
|||
pull_request:
|
||||
|
||||
env:
|
||||
CI: true
|
||||
FORCE_COLOR: 2
|
||||
NODE: 14.x
|
||||
|
||||
|
|
@ -32,8 +31,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
|
||||
|
|
|
|||
5
.github/workflows/js.yml
vendored
5
.github/workflows/js.yml
vendored
|
|
@ -7,7 +7,6 @@ on:
|
|||
pull_request:
|
||||
|
||||
env:
|
||||
CI: true
|
||||
FORCE_COLOR: 2
|
||||
|
||||
jobs:
|
||||
|
|
@ -35,8 +34,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
|
||||
|
|
|
|||
5
.github/workflows/lint.yml
vendored
5
.github/workflows/lint.yml
vendored
|
|
@ -7,7 +7,6 @@ on:
|
|||
pull_request:
|
||||
|
||||
env:
|
||||
CI: true
|
||||
FORCE_COLOR: 2
|
||||
NODE: 14.x
|
||||
|
||||
|
|
@ -30,8 +29,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
|
||||
|
|
|
|||
1
.github/workflows/node-sass.yml
vendored
1
.github/workflows/node-sass.yml
vendored
|
|
@ -7,7 +7,6 @@ on:
|
|||
pull_request:
|
||||
|
||||
env:
|
||||
CI: true
|
||||
FORCE_COLOR: 2
|
||||
NODE: 14.x
|
||||
|
||||
|
|
|
|||
11
.gitignore
vendored
11
.gitignore
vendored
|
|
@ -1,19 +1,8 @@
|
|||
# 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
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@
|
|||
"stylelint-config-twbs-bootstrap/scss"
|
||||
],
|
||||
"rules": {
|
||||
"declaration-property-value-disallowed-list": {
|
||||
"border": "none",
|
||||
"outline": "none"
|
||||
},
|
||||
"function-disallowed-list": [
|
||||
"calc",
|
||||
"lighten",
|
||||
|
|
|
|||
|
|
@ -12,36 +12,67 @@
|
|||
const path = require('path')
|
||||
const sh = require('shelljs')
|
||||
|
||||
const { version, version_short: versionShort } = require('../package.json')
|
||||
const pkg = require('../package.json')
|
||||
|
||||
const folderName = `bootstrap-${version}-examples`
|
||||
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'
|
||||
]
|
||||
|
||||
sh.config.fatal = true
|
||||
|
||||
if (!sh.test('-d', '_gh_pages')) {
|
||||
throw new Error('The "_gh_pages" folder does not exist, did you forget building the docs?')
|
||||
if (!sh.test('-d', rootDocsDir)) {
|
||||
throw new Error(`The "${rootDocsDir}" 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 with the same name
|
||||
sh.rm('-rf', folderName)
|
||||
// create any folders so that `cp` works
|
||||
sh.mkdir('-p', folderName)
|
||||
sh.mkdir('-p', `${folderName}/assets/brand/`)
|
||||
sh.rm('-rf', distFolder)
|
||||
|
||||
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`)
|
||||
// create any folders so that `cp` works
|
||||
sh.mkdir('-p', [
|
||||
distFolder,
|
||||
`${distFolder}/assets/brand/`,
|
||||
`${distFolder}/assets/dist/css/`,
|
||||
`${distFolder}/assets/dist/js/`
|
||||
])
|
||||
|
||||
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`)
|
||||
|
||||
// get all examples' HTML files
|
||||
sh.find(`${folderName}/**/*.html`).forEach(file => {
|
||||
sh.find(`${distFolder}/**/*.html`).forEach(file => {
|
||||
const fileContents = sh.cat(file)
|
||||
.toString()
|
||||
.replace(new RegExp(`"/docs/${versionShort}/`, 'g'), '"../')
|
||||
|
|
@ -53,7 +84,7 @@ sh.find(`${folderName}/**/*.html`).forEach(file => {
|
|||
})
|
||||
|
||||
// create the zip file
|
||||
sh.exec(`zip -r9 "${folderName}.zip" "${folderName}"`, { fatal: true })
|
||||
sh.exec(`zip -r9 "${distFolder}.zip" "${distFolder}"`)
|
||||
|
||||
// remove the folder we created
|
||||
sh.rm('-rf', folderName)
|
||||
sh.rm('-rf', distFolder)
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ class Dropdown extends BaseComponent {
|
|||
typeof config.reference.getBoundingClientRect !== 'function'
|
||||
) {
|
||||
// Popper virtual elements require a getBoundingClientRect method
|
||||
throw new Error(`${NAME}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`)
|
||||
throw new TypeError(`${NAME.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`)
|
||||
}
|
||||
|
||||
return config
|
||||
|
|
|
|||
|
|
@ -589,7 +589,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
|
|||
data = new Modal(target, config)
|
||||
}
|
||||
|
||||
data.show(this)
|
||||
data.toggle(this)
|
||||
})
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -111,15 +111,14 @@ 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 Error(
|
||||
throw new TypeError(
|
||||
`${componentName.toUpperCase()}: ` +
|
||||
`Option "${property}" provided type "${valueType}" ` +
|
||||
`but expected type "${expectedTypes}".`)
|
||||
`but expected type "${expectedTypes}".`
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
/* eslint-env node */
|
||||
|
||||
'use strict'
|
||||
|
||||
const path = require('path')
|
||||
const ip = require('ip')
|
||||
const { babel } = require('@rollup/plugin-babel')
|
||||
|
|
@ -12,10 +14,11 @@ const {
|
|||
browsersKeys
|
||||
} = require('./browsers')
|
||||
|
||||
const { env } = process
|
||||
const browserStack = env.BROWSER === 'true'
|
||||
const debug = env.DEBUG === 'true'
|
||||
const jQueryTest = env.JQUERY === 'true'
|
||||
const ENV = process.env
|
||||
const BROWSERSTACK = Boolean(ENV.BROWSERSTACK)
|
||||
const DEBUG = Boolean(ENV.DEBUG)
|
||||
const JQUERY_TEST = Boolean(ENV.JQUERY)
|
||||
|
||||
const frameworks = [
|
||||
'jasmine'
|
||||
]
|
||||
|
|
@ -30,16 +33,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')
|
||||
|
|
@ -67,7 +70,7 @@ const conf = {
|
|||
'node_modules/hammer-simulator/index.js',
|
||||
{
|
||||
pattern: 'js/tests/unit/**/!(jquery).spec.js',
|
||||
watched: !browserStack
|
||||
watched: !BROWSERSTACK
|
||||
}
|
||||
],
|
||||
preprocessors: {
|
||||
|
|
@ -101,11 +104,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
|
||||
|
|
@ -114,7 +117,7 @@ if (browserStack) {
|
|||
conf.customLaunchers = browsers
|
||||
conf.browsers = browsersKeys
|
||||
reporters.push('BrowserStack', 'kjhtml')
|
||||
} else if (jQueryTest) {
|
||||
} else if (JQUERY_TEST) {
|
||||
frameworks.push('detectBrowsers')
|
||||
plugins.push(
|
||||
'karma-chrome-launcher',
|
||||
|
|
@ -155,7 +158,7 @@ if (browserStack) {
|
|||
}
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
if (DEBUG) {
|
||||
conf.hostname = ip.address()
|
||||
plugins.push('karma-jasmine-html-reporter')
|
||||
reporters.push('kjhtml')
|
||||
|
|
@ -169,7 +172,6 @@ conf.plugins = plugins
|
|||
conf.reporters = reporters
|
||||
|
||||
module.exports = karmaConfig => {
|
||||
// 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
|
||||
conf.logLevel = karmaConfig.LOG_ERROR
|
||||
karmaConfig.set(conf)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1136,11 +1136,9 @@ describe('Carousel', () => {
|
|||
jQueryMock.fn.carousel = Carousel.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
try {
|
||||
expect(() => {
|
||||
jQueryMock.fn.carousel.call(jQueryMock, action)
|
||||
} catch (error) {
|
||||
expect(error.message).toEqual(`No method named "${action}"`)
|
||||
}
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -819,11 +819,9 @@ describe('Collapse', () => {
|
|||
jQueryMock.fn.collapse = Collapse.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
try {
|
||||
expect(() => {
|
||||
jQueryMock.fn.collapse.call(jQueryMock, action)
|
||||
} catch (error) {
|
||||
expect(error.message).toEqual(`No method named "${action}"`)
|
||||
}
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -393,13 +393,13 @@ describe('Dropdown', () => {
|
|||
|
||||
expect(() => new Dropdown(btnDropdown, {
|
||||
reference: {}
|
||||
})).toThrow()
|
||||
})).toThrowError(TypeError, 'DROPDOWN: Option "reference" provided type "object" without a required "getBoundingClientRect" method.')
|
||||
|
||||
expect(() => new Dropdown(btnDropdown, {
|
||||
reference: {
|
||||
getBoundingClientRect: 'not-a-function'
|
||||
}
|
||||
})).toThrow()
|
||||
})).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, {
|
||||
|
|
@ -1557,11 +1557,9 @@ describe('Dropdown', () => {
|
|||
jQueryMock.fn.dropdown = Dropdown.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
try {
|
||||
expect(() => {
|
||||
jQueryMock.fn.dropdown.call(jQueryMock, action)
|
||||
} catch (error) {
|
||||
expect(error.message).toEqual(`No method named "${action}"`)
|
||||
}
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -870,7 +870,7 @@ describe('Modal', () => {
|
|||
})
|
||||
|
||||
describe('data-api', () => {
|
||||
it('should open modal', done => {
|
||||
it('should toggle 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,6 +885,15 @@ 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()
|
||||
})
|
||||
|
||||
|
|
@ -1061,11 +1070,9 @@ describe('Modal', () => {
|
|||
jQueryMock.fn.modal = Modal.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
try {
|
||||
expect(() => {
|
||||
jQueryMock.fn.modal.call(jQueryMock, action)
|
||||
} catch (error) {
|
||||
expect(error.message).toEqual(`No method named "${action}"`)
|
||||
}
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
|
||||
it('should call show method', () => {
|
||||
|
|
|
|||
|
|
@ -206,11 +206,9 @@ describe('Popover', () => {
|
|||
jQueryMock.fn.popover = Popover.jQueryInterface
|
||||
jQueryMock.elements = [popoverEl]
|
||||
|
||||
try {
|
||||
expect(() => {
|
||||
jQueryMock.fn.popover.call(jQueryMock, action)
|
||||
} catch (error) {
|
||||
expect(error.message).toEqual(`No method named "${action}"`)
|
||||
}
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
|
||||
it('should should call show method', () => {
|
||||
|
|
|
|||
|
|
@ -625,11 +625,9 @@ describe('ScrollSpy', () => {
|
|||
jQueryMock.fn.scrollspy = ScrollSpy.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
try {
|
||||
expect(() => {
|
||||
jQueryMock.fn.scrollspy.call(jQueryMock, action)
|
||||
} catch (error) {
|
||||
expect(error.message).toEqual(`No method named "${action}"`)
|
||||
}
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -397,11 +397,9 @@ describe('Tab', () => {
|
|||
jQueryMock.fn.tab = Tab.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
try {
|
||||
expect(() => {
|
||||
jQueryMock.fn.tab.call(jQueryMock, action)
|
||||
} catch (error) {
|
||||
expect(error.message).toEqual(`No method named "${action}"`)
|
||||
}
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -368,11 +368,9 @@ describe('Toast', () => {
|
|||
jQueryMock.fn.toast = Toast.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
try {
|
||||
expect(() => {
|
||||
jQueryMock.fn.toast.call(jQueryMock, action)
|
||||
} catch (error) {
|
||||
expect(error.message).toEqual(`No method named "${action}"`)
|
||||
}
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -1207,11 +1207,9 @@ describe('Tooltip', () => {
|
|||
jQueryMock.fn.tooltip = Tooltip.jQueryInterface
|
||||
jQueryMock.elements = [div]
|
||||
|
||||
try {
|
||||
expect(() => {
|
||||
jQueryMock.fn.tooltip.call(jQueryMock, action)
|
||||
} catch (error) {
|
||||
expect(error.message).toEqual(`No method named "${action}"`)
|
||||
}
|
||||
}).toThrowError(TypeError, `No method named "${action}"`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ describe('Util', () => {
|
|||
|
||||
expect(() => {
|
||||
Util.typeCheckConfig(namePlugin, config, defaultType)
|
||||
}).toThrow(new Error('COLLAPSE: Option "parent" provided type "number" but expected type "(string|element)".'))
|
||||
}).toThrowError(TypeError, 'COLLAPSE: Option "parent" provided type "number" but expected type "(string|element)".')
|
||||
})
|
||||
|
||||
it('should return null stringified when null is passed', () => {
|
||||
|
|
|
|||
100
package-lock.json
generated
100
package-lock.json
generated
|
|
@ -1612,9 +1612,9 @@
|
|||
"optional": true
|
||||
},
|
||||
"autoprefixer": {
|
||||
"version": "10.2.0",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.2.0.tgz",
|
||||
"integrity": "sha512-5SdPoK2Q3rxVh4xC8GKdy772KbEESdl2SyJADCw5FMUrd5eNtpOTLo7oCFMEKvK86zQdvsIVTYk93E8dAfRy6g==",
|
||||
"version": "10.2.1",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.2.1.tgz",
|
||||
"integrity": "sha512-dwP0UjyYvROUvtU+boBx8ff5pPWami1NGTrJs9YUsS/oZVbRAcdNHOOuXSA1fc46tgKqe072cVaKD69rvCc3QQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"browserslist": "^4.16.1",
|
||||
|
|
@ -1623,21 +1623,6 @@
|
|||
"fraction.js": "^4.0.13",
|
||||
"normalize-range": "^0.1.2",
|
||||
"postcss-value-parser": "^4.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"browserslist": {
|
||||
"version": "4.16.1",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.1.tgz",
|
||||
"integrity": "sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"caniuse-lite": "^1.0.30001173",
|
||||
"colorette": "^1.2.1",
|
||||
"electron-to-chromium": "^1.3.634",
|
||||
"escalade": "^3.1.1",
|
||||
"node-releases": "^1.1.69"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"axios": {
|
||||
|
|
@ -2068,16 +2053,16 @@
|
|||
}
|
||||
},
|
||||
"browserslist": {
|
||||
"version": "4.16.0",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.0.tgz",
|
||||
"integrity": "sha512-/j6k8R0p3nxOC6kx5JGAxsnhc9ixaWJfYc+TNTzxg6+ARaESAvQGV7h0uNOB4t+pLQJZWzcrMxXOxjgsCj3dqQ==",
|
||||
"version": "4.16.1",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.1.tgz",
|
||||
"integrity": "sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"caniuse-lite": "^1.0.30001165",
|
||||
"caniuse-lite": "^1.0.30001173",
|
||||
"colorette": "^1.2.1",
|
||||
"electron-to-chromium": "^1.3.621",
|
||||
"electron-to-chromium": "^1.3.634",
|
||||
"escalade": "^3.1.1",
|
||||
"node-releases": "^1.1.67"
|
||||
"node-releases": "^1.1.69"
|
||||
}
|
||||
},
|
||||
"browserstack": {
|
||||
|
|
@ -2284,13 +2269,13 @@
|
|||
}
|
||||
},
|
||||
"call-bind": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz",
|
||||
"integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==",
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.1.tgz",
|
||||
"integrity": "sha512-tvAvUwNcRikl3RVF20X9lsYmmepsovzTWeJiXjO0PkJp15uy/6xKFZOQtuiSULwYW+6ToZBprphCgWXC2dSgcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1",
|
||||
"get-intrinsic": "^1.0.0"
|
||||
"get-intrinsic": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"callsites": {
|
||||
|
|
@ -2401,14 +2386,14 @@
|
|||
}
|
||||
},
|
||||
"chokidar": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz",
|
||||
"integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==",
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.0.tgz",
|
||||
"integrity": "sha512-JgQM9JS92ZbFR4P90EvmzNpSGhpPBGBSj10PILeDyYFwp4h2/D9OM03wsJ4zW1fEp4ka2DGrnUeD7FuvQ2aZ2Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"anymatch": "~3.1.1",
|
||||
"braces": "~3.0.2",
|
||||
"fsevents": "~2.1.2",
|
||||
"fsevents": "~2.3.1",
|
||||
"glob-parent": "~5.1.0",
|
||||
"is-binary-path": "~2.1.0",
|
||||
"is-glob": "~4.0.1",
|
||||
|
|
@ -3336,9 +3321,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.3.634",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.634.tgz",
|
||||
"integrity": "sha512-QPrWNYeE/A0xRvl/QP3E0nkaEvYUvH3gM04ZWYtIa6QlSpEetRlRI1xvQ7hiMIySHHEV+mwDSX8Kj4YZY6ZQAw==",
|
||||
"version": "1.3.635",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.635.tgz",
|
||||
"integrity": "sha512-RRriZOLs9CpW6KTLmgBqyUdnY0QNqqWs0HOtuQGGEMizOTNNn1P7sGRBxARnUeLejOsgwjDyRqT3E/CSst02ZQ==",
|
||||
"dev": true
|
||||
},
|
||||
"emoji-regex": {
|
||||
|
|
@ -4640,9 +4625,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
|
||||
"integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.1.tgz",
|
||||
"integrity": "sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
|
|
@ -4879,9 +4864,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"globby": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz",
|
||||
"integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==",
|
||||
"version": "11.0.2",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz",
|
||||
"integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"array-union": "^2.1.0",
|
||||
|
|
@ -6594,9 +6579,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"meow": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/meow/-/meow-8.1.0.tgz",
|
||||
"integrity": "sha512-fNWkgM1UVMey2kf24yLiccxLihc5W+6zVus3/N0b+VfnJgxV99E9u04X6NAiKdg6ED7DAQBX5sy36NM0QJZkWA==",
|
||||
"version": "8.1.2",
|
||||
"resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz",
|
||||
"integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/minimist": "^1.2.0",
|
||||
|
|
@ -7849,9 +7834,9 @@
|
|||
"optional": true
|
||||
},
|
||||
"postcss": {
|
||||
"version": "8.2.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.2.tgz",
|
||||
"integrity": "sha512-HM1NDNWLgglJPQQMNwvLxgH2KcrKZklKLi/xXYIOaqQB57p/pDWEJNS83PVICYsn1Dg/9C26TiejNr422/ePaQ==",
|
||||
"version": "8.2.4",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.4.tgz",
|
||||
"integrity": "sha512-kRFftRoExRVXZlwUuay9iC824qmXPcQQVzAjbCCgjpXnkdMCJYBu2gTwAaFBzv8ewND6O8xFb3aELmEkh9zTzg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"colorette": "^1.2.1",
|
||||
|
|
@ -8854,6 +8839,15 @@
|
|||
"dev": true,
|
||||
"requires": {
|
||||
"fsevents": "~2.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"fsevents": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
|
||||
"integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"rollup-plugin-istanbul": {
|
||||
|
|
@ -9020,9 +9014,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"sass": {
|
||||
"version": "1.32.2",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.32.2.tgz",
|
||||
"integrity": "sha512-u1pUuzqwz3SAgvHSWp1k0mRhX82b2DdlVnP6UIetQPZtYbuJUDaPQhZE12jyjB7vYeOScfz9WPsZJB6Rpk7heA==",
|
||||
"version": "1.32.4",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.32.4.tgz",
|
||||
"integrity": "sha512-N0BT0PI/t3+gD8jKa83zJJUb7ssfQnRRfqN+GIErokW6U4guBpfYl8qYB+OFLEho+QvnV5ZH1R9qhUC/Z2Ch9w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chokidar": ">=2.0.0 <4.0.0"
|
||||
|
|
@ -9478,9 +9472,9 @@
|
|||
}
|
||||
},
|
||||
"socket.io": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.4.0.tgz",
|
||||
"integrity": "sha512-9UPJ1UTvKayuQfVv2IQ3k7tCQC/fboDyIK62i99dAQIyHKaBsNdTpwHLgKJ6guRWxRtC9H+138UwpaGuQO9uWQ==",
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.4.1.tgz",
|
||||
"integrity": "sha512-Si18v0mMXGAqLqCVpTxBa8MGqriHGQh8ccEOhmsmNS3thNCGBwO8WGrwMibANsWtQQ5NStdZwHqZR3naJVFc3w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "~4.1.0",
|
||||
|
|
|
|||
14
package.json
14
package.json
|
|
@ -2,7 +2,9 @@
|
|||
"name": "bootstrap",
|
||||
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
|
||||
"version": "5.0.0-beta1",
|
||||
"version_short": "5.0",
|
||||
"config": {
|
||||
"version_short": "5.0"
|
||||
},
|
||||
"keywords": [
|
||||
"css",
|
||||
"sass",
|
||||
|
|
@ -32,7 +34,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_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\"",
|
||||
"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\"",
|
||||
"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",
|
||||
|
|
@ -49,7 +51,7 @@
|
|||
"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 BROWSER=true npm run js-test-karma",
|
||||
"js-test-cloud": "cross-env BROWSERSTACK=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",
|
||||
|
|
@ -106,7 +108,7 @@
|
|||
"@rollup/plugin-commonjs": "^17.0.0",
|
||||
"@rollup/plugin-node-resolve": "^11.0.1",
|
||||
"@rollup/plugin-replace": "^2.3.4",
|
||||
"autoprefixer": "^10.2.0",
|
||||
"autoprefixer": "^10.2.1",
|
||||
"bundlewatch": "^0.3.1",
|
||||
"clean-css-cli": "^4.3.0",
|
||||
"cross-env": "^7.0.3",
|
||||
|
|
@ -133,12 +135,12 @@
|
|||
"lockfile-lint": "^4.3.7",
|
||||
"nodemon": "^2.0.7",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.2.2",
|
||||
"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.2",
|
||||
"sass": "^1.32.4",
|
||||
"shelljs": "^0.8.4",
|
||||
"stylelint": "^13.8.0",
|
||||
"stylelint-config-twbs-bootstrap": "^2.1.0",
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
outline: 0;
|
||||
box-shadow: $btn-close-focus-shadow;
|
||||
opacity: $btn-close-focus-opacity;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -411,6 +411,15 @@ 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.
|
||||
|
||||
button:focus:not(:focus-visible) {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
// 1. Remove the margin in Firefox and Safari
|
||||
|
||||
input,
|
||||
|
|
|
|||
|
|
@ -47,4 +47,5 @@
|
|||
|
||||
.toast-body {
|
||||
padding: $toast-padding-x; // apply to both vertical and horizontal
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -938,7 +938,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-100 !default;
|
||||
$dropdown-link-hover-bg: $gray-200 !default;
|
||||
|
||||
$dropdown-link-active-color: $component-active-color !default;
|
||||
$dropdown-link-active-bg: $component-active-bg !default;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
appearance: none;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
outline: 0;
|
||||
|
||||
// Pseudo-elements must be split across multiple rulesets to have an effect.
|
||||
// No box-shadow() mixin for focus accessibility.
|
||||
|
|
|
|||
|
|
@ -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. For browsers that support the `backdrop-filter` CSS property, we'll also attempt to blur the elements under a toast.
|
||||
Toasts are slightly translucent, too, so they blend over whatever they might appear over.
|
||||
|
||||
{{< 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 `.text-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 `.btn-close-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">
|
||||
|
|
|
|||
|
|
@ -76,3 +76,11 @@ Specifically regarding custom CSS, utilities can help combat increasing file siz
|
|||
## Flexible HTML
|
||||
|
||||
While not always possible, we strive to avoid being overly dogmatic in our HTML requirements for components. Thus, we focus on single classes in our CSS selectors and try to avoid immediate children selectors (`>`). This gives you more flexibility in your implementation and helps keep our CSS simpler and less specific.
|
||||
|
||||
## Code conventions
|
||||
|
||||
[Code Guide](https://codeguide.co/) (from Bootstrap co-creator, @mdo) documents how we write our HTML and CSS across Bootstrap. It specifices guidelines for general formatting, common sense defaults, property and attribute orders, and more.
|
||||
|
||||
We use [Stylelint](https://stylelint.io/) to enforce these standards and more in our Sass/CSS. [Our custom Stylelint config](https://github.com/twbs/stylelint-config-twbs-bootstrap) is open source and available for others to use and extend.
|
||||
|
||||
We use [vnu-jar](https://www.npmjs.com/package/vnu-jar) to enforce standard and semantic HTML, as well as detecting common errors.
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ To set a custom height on your `<textarea>`, do not use the `rows` attribute. In
|
|||
|
||||
## Selects
|
||||
|
||||
Other than `.form-control`, floating labels are only available on `.form-select`s. They work in the same way, but unlike `<input>`s, they'll always show the `<label>` in its floated state.
|
||||
Other than `.form-control`, floating labels are only available on `.form-select`s. They work in the same way, but unlike `<input>`s, they'll always show the `<label>` in its floated state. **Selects with `size` and `multiple` are not supported.**
|
||||
|
||||
{{< example >}}
|
||||
<div class="form-floating">
|
||||
|
|
|
|||
|
|
@ -136,6 +136,42 @@ $font-family-sans-serif:
|
|||
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default;
|
||||
```
|
||||
|
||||
### LTR and RTL at the same time
|
||||
|
||||
Need both LTR and RTL on the same page? Thanks to [RTLCSS String Maps](https://rtlcss.com/learn/usage-guide/string-map/), this is pretty straightforward. Wrap your `@import`s with a class, and set a custom rename rule for RTLCSS:
|
||||
|
||||
```scss
|
||||
/* rtl:begin:options: {
|
||||
"autoRename": true,
|
||||
"stringMap":[
|
||||
"name": "ltr-rtl",
|
||||
"priority": 100,
|
||||
"search": ["ltr"],
|
||||
"replace": ["rtl"],
|
||||
"options": {
|
||||
"scope": "*",
|
||||
"ignoreCase": false
|
||||
}
|
||||
]
|
||||
} */
|
||||
.ltr {
|
||||
@import "../node_modules/bootstrap/scss/bootstrap";
|
||||
}
|
||||
/*rtl:end:options*/
|
||||
```
|
||||
|
||||
After running Sass then RTLCSS, each selector in your CSS files will be prepended by `.ltr`, and `.rtl` for RTL files. Now you're able to use both files on the same page, and simply use `.ltr` or `.rtl` on your components wrappers to use one or the other direction.
|
||||
|
||||
{{< callout warning >}}
|
||||
#### Edge cases and known limitations
|
||||
|
||||
While this approach is understandable, please pay attention to the following:
|
||||
|
||||
1. When switching `.ltr` and `.rtl`, make sure you add `dir` and `lang` attributes accordingly.
|
||||
2. Loading both files can be a real performance bottleneck: consider some [optimization]({{< docsref "/customize/optimize" >}}), and maybe try to [load one of those files asynchronously](https://www.filamentgroup.com/lab/load-css-simpler/).
|
||||
3. Nesting styles this way will prevent our `form-validation-state()` mixin from working as intended, thus require you tweak it a bit by yourself. [See #31223](https://github.com/twbs/bootstrap/issues/31223).
|
||||
{{< /callout >}}
|
||||
|
||||
## The breadcrumb case
|
||||
|
||||
The [breadcrumb separator]({{< docsref "/components/breadcrumb" >}}/#changing-the-separator) is the only case requiring its own brand new variable— namely `$breadcrumb-divider-flipped` —defaulting to `$breadcrumb-divider`.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ description: Make any HTML element or Bootstrap component clickable by "stretchi
|
|||
group: helpers
|
||||
---
|
||||
|
||||
Add `.stretched-link` to a link to make its [containing block](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block) clickable via a `::after` pseudo element. In most cases, this means that an element with `position: relative;` that contains a link with the `.stretched-link` class is clickable.
|
||||
Add `.stretched-link` to a link to make its [containing block](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block) clickable via a `::after` pseudo element. In most cases, this means that an element with `position: relative;` that contains a link with the `.stretched-link` class is clickable. Please note given [how CSS `position` works](https://www.w3.org/TR/CSS21/visuren.html#propdef-position), `.stretched-link` cannot be mixed with most table elements.
|
||||
|
||||
Cards have `position: relative` by default in Bootstrap, so in this case you can safely add the `.stretched-link` class to a link in the card without any other HTML changes.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
layout: docs
|
||||
title: Breakpoints
|
||||
description: Breakpoints are the triggers in Bootstrap for how your layout responsive changes across device or viewport sizes.
|
||||
description: Breakpoints are customizable widths that determine how your responsive layout behaves across device or viewport sizes in Bootstrap.
|
||||
group: layout
|
||||
aliases: "/docs/5.0/layout/"
|
||||
toc: true
|
||||
|
|
|
|||
|
|
@ -50,7 +50,9 @@ Horizontal direction sensitive variables, utilities and mixins are renamed with
|
|||
- Renamed `.pl-*` and `.pr-*` to `.ps-*` and `.pe-*`.
|
||||
- Renamed `.text-left` and `.text-right` to `.text-start` and `.text-end`.
|
||||
|
||||
Breakpoints specific variants are consequently renamed too (eg. `.text-md-start` replaces `.text-md-left`).
|
||||
Breakpoints specific variants are consequently renamed too (e.g. `.text-md-start` replaces `.text-md-left`).
|
||||
|
||||
**Note**: if you used v4 to make RTL pages, ensure to reverse changes mentioned above: e.g. use `.*-start` were you used `.*-right`.
|
||||
|
||||
##### Mixins
|
||||
|
||||
|
|
@ -127,6 +129,7 @@ Breakpoints specific variants are consequently renamed too (eg. `.text-md-start`
|
|||
- Renamed `.font-style-*` utilities as `.fst-*` for brevity and consistency.
|
||||
- Added `.d-grid` to display utilities
|
||||
- Added new `gap` utilities (`.gap`) for CSS Grid layouts
|
||||
- Removed `.rounded-sm` and `rounded-lg`, and introduced `.rounded-0` to `.rounded-3`. [See #31687](https://github.com/twbs/bootstrap/pull/31687).
|
||||
|
||||
## v5.0.0-alpha2
|
||||
|
||||
|
|
|
|||
|
|
@ -289,6 +289,25 @@ $utilities: map-merge(
|
|||
);
|
||||
```
|
||||
|
||||
#### Rename utilities
|
||||
|
||||
Missing v4 utilities, or used to another naming convention? The utilities API can be used to override the resulting `class` of a given utility—for example, to rename `.ms-*` utilities to oldish `.ml-*`:
|
||||
|
||||
```scss
|
||||
@import "bootstrap/scss/functions";
|
||||
@import "bootstrap/scss/variables";
|
||||
@import "bootstrap/scss/utilities";
|
||||
|
||||
$utilities: map-merge(
|
||||
$utilities, (
|
||||
"margin-start": map-merge(
|
||||
map-get($utilities, "margin-start"),
|
||||
( class: ml ),
|
||||
),
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
### Remove utilities
|
||||
|
||||
Remove any of the default utilities by setting the group key to `null`. For example, to remove all our `width` utilities, create a `$utilities` `map-merge` and add `"width": null` within.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue