Compare commits

..

8 Commits

Author SHA1 Message Date
XhmikosR ac6069641e bundle-modularity.js: add file extensions 2024-03-13 22:10:48 +02:00
XhmikosR cb0ab4e05e Rename variable 2024-03-11 16:40:04 +02:00
XhmikosR 5fc4efb910 ESLint: fix sourceType for docs md files 2024-03-11 16:37:25 +02:00
XhmikosR 7df3fb5970 ESLint: properly disable no-negated-condition 2024-03-11 16:37:24 +02:00
XhmikosR 76bbd3fdee unicorn/prefer-top-level-await 2024-03-11 16:34:07 +02:00
XhmikosR 9c1b83a23c unicorn/prefer-node-protocol 2024-03-11 16:34:07 +02:00
XhmikosR 958cdec31b Switch to using for...of 2024-03-11 16:34:07 +02:00
XhmikosR 8590295993 Enable unicorn/prefer-spread rule 2024-03-11 16:34:04 +02:00
153 changed files with 11079 additions and 3647 deletions
+1 -1
View File
@@ -38,7 +38,7 @@
},
{
"path": "./dist/js/bootstrap.bundle.min.js",
"maxSize": "23.5 kB"
"maxSize": "23.25 kB"
},
{
"path": "./dist/js/bootstrap.esm.js",
+6 -29
View File
@@ -67,7 +67,6 @@
}
],
"no-console": "error",
"no-negated-condition": "off",
"object-curly-spacing": [
"error",
"always"
@@ -85,9 +84,9 @@
"strict": "error",
"unicorn/explicit-length-check": "off",
"unicorn/filename-case": "off",
"unicorn/no-anonymous-default-export": "off",
"unicorn/no-array-callback-reference": "off",
"unicorn/no-array-method-this-argument": "off",
"unicorn/no-negated-condition": "off",
"unicorn/no-null": "off",
"unicorn/no-typeof-undefined": "off",
"unicorn/no-unused-properties": "error",
@@ -97,10 +96,7 @@
"unicorn/prefer-dom-node-dataset": "off",
"unicorn/prefer-module": "off",
"unicorn/prefer-query-selector": "off",
"unicorn/prefer-spread": "off",
"unicorn/prefer-string-raw": "off",
"unicorn/prefer-string-replace-all": "off",
"unicorn/prefer-structured-clone": "off",
"unicorn/prevent-abbreviations": "off"
},
"overrides": [
@@ -116,8 +112,7 @@
"sourceType": "module"
},
"rules": {
"no-console": "off",
"unicorn/prefer-top-level-await": "off"
"no-console": "off"
}
},
{
@@ -168,8 +163,7 @@
},
"rules": {
"no-console": "off",
"no-new": "off",
"unicorn/no-array-for-each": "off"
"no-new": "off"
}
},
{
@@ -196,17 +190,7 @@
"ecmaVersion": 2019
},
"rules": {
"no-new": "off",
"unicorn/no-array-for-each": "off"
}
},
{
"files": [
"site/assets/js/**"
],
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 2020
"no-new": "off"
}
},
{
@@ -220,16 +204,9 @@
},
{
"files": [
"**/*.md/*.js",
"**/*.md/*.mjs"
"**/*.md/*.js"
],
"extends": "plugin:markdown/recommended-legacy",
"parserOptions": {
"sourceType": "module"
},
"rules": {
"unicorn/prefer-node-protocol": "off"
}
"extends": "plugin:markdown/recommended"
}
]
}
+1
View File
@@ -0,0 +1 @@
lockfile-version=2
+1 -1
View File
@@ -177,7 +177,7 @@ Get updates on Bootstrap's development and chat with the project maintainers and
- Follow [@getbootstrap on Twitter](https://twitter.com/getbootstrap).
- Read and subscribe to [The Official Bootstrap Blog](https://blog.getbootstrap.com/).
- Ask questions and explore [our GitHub Discussions](https://github.com/twbs/bootstrap/discussions).
- Discuss, ask questions, and more on [the community Discord](https://discord.gg/bZUvakRU3M) or [Bootstrap subreddit](https://www.reddit.com/r/bootstrap/).
- Discuss, ask questions, and more on [the community Discord](https://discord.gg/bZUvakRU3M) or [Bootstrap subreddit](https://reddit.com/r/bootstrap).
- Chat with fellow Bootstrappers in IRC. On the `irc.libera.chat` server, in the `#bootstrap` channel.
- Implementation help may be found at Stack Overflow (tagged [`bootstrap-5`](https://stackoverflow.com/questions/tagged/bootstrap-5)).
- Developers should use the keyword `bootstrap` on packages which modify or add to the functionality of Bootstrap when distributing through [npm](https://www.npmjs.com/browse/keyword/bootstrap) or similar delivery mechanisms for maximum discoverability.
+8 -18
View File
@@ -9,7 +9,7 @@
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { babel } from '@rollup/plugin-babel'
import { globby } from 'globby'
import globby from 'globby'
import { rollup } from 'rollup'
import banner from './banner.mjs'
@@ -17,7 +17,7 @@ const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const sourcePath = path.resolve(__dirname, '../js/src/').replace(/\\/g, '/')
const jsFiles = await globby(`${sourcePath}/**/*.js`)
const jsFiles = globby.sync(`${sourcePath}/**/*.js`)
// Array which holds the resolved plugins
const resolvedPlugins = []
@@ -37,9 +37,6 @@ for (const file of jsFiles) {
}
const build = async plugin => {
/**
* @type {import('rollup').GlobalsOption}
*/
const globals = {}
const bundle = await rollup({
@@ -90,19 +87,12 @@ const build = async plugin => {
console.log(`Built ${plugin.className}`)
}
(async () => {
try {
const basename = path.basename(__filename)
const timeLabel = `[${basename}] finished`
const basename = path.basename(__filename)
const timeLabel = `[${basename}] finished`
console.log('Building individual plugins...')
console.time(timeLabel)
console.log('Building individual plugins...')
console.time(timeLabel)
await Promise.all(Object.values(resolvedPlugins).map(plugin => build(plugin)))
await Promise.all(Object.values(resolvedPlugins).map(plugin => build(plugin)))
console.timeEnd(timeLabel)
} catch (error) {
console.error(error)
process.exit(1)
}
})()
console.timeEnd(timeLabel)
+19 -27
View File
@@ -81,33 +81,25 @@ function showUsage(args) {
process.exit(1)
}
async function main(args) {
let [oldVersion, newVersion] = args
const args = process.argv.slice(2)
let [oldVersion, newVersion] = args
if (!oldVersion || !newVersion) {
showUsage(args)
}
// Strip any leading `v` from arguments because
// otherwise we will end up with duplicate `v`s
[oldVersion, newVersion] = [oldVersion, newVersion].map(arg => {
return arg.startsWith('v') ? arg.slice(1) : arg
})
if (oldVersion === newVersion) {
showUsage(args)
}
bumpNpmVersion(newVersion)
try {
await Promise.all(
FILES.map(file => replaceRecursively(file, oldVersion, newVersion))
)
} catch (error) {
console.error(error)
process.exit(1)
}
if (!oldVersion || !newVersion) {
showUsage(args)
}
main(process.argv.slice(2))
// Strip any leading `v` from arguments because
// otherwise we will end up with duplicate `v`s
[oldVersion, newVersion] = [oldVersion, newVersion].map(arg => {
return arg.startsWith('v') ? arg.slice(1) : arg
})
if (oldVersion === newVersion) {
showUsage(args)
}
bumpNpmVersion(newVersion)
await Promise.all(
FILES.map(file => replaceRecursively(file, oldVersion, newVersion))
)
+2 -13
View File
@@ -8,6 +8,8 @@ security:
getenv:
- ^HUGO_
- NETLIFY
gotemplates:
allowActionJSTmpl: true
markup:
goldmark:
@@ -19,9 +21,6 @@ markup:
startLevel: 2
endLevel: 6
build:
noJSConfigInAssets: true
buildDrafts: true
buildFuture: true
@@ -45,8 +44,6 @@ module:
target: layouts
- source: site/static
target: static
- source: node_modules/@docsearch/css
target: assets/scss/@docsearch/css
- source: site/static/docs/5.3/assets/img/favicons/apple-touch-icon.png
target: static/apple-touch-icon.png
- source: site/static/docs/5.3/assets/img/favicons/favicon.ico
@@ -70,14 +67,6 @@ params:
icons: "https://icons.getbootstrap.com/"
swag: "https://cottonbureau.com/people/bootstrap"
analytics:
fathom_site: "ITUSEYJG"
algolia:
appId: "AK7KMZKZHQ"
apiKey: "3151f502c7b9e9dafd5e6372b691a24e"
indexName: "bootstrap"
download:
source: "https://github.com/twbs/bootstrap/archive/v5.3.3.zip"
dist: "https://github.com/twbs/bootstrap/releases/download/v5.3.3/bootstrap-5.3.3-dist.zip"
+1 -1
View File
@@ -23,7 +23,7 @@ export default {
// can be removed later when multiple key/instances are fine to be used
if (!instanceMap.has(key) && instanceMap.size !== 0) {
// eslint-disable-next-line no-console
console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`)
console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${[...instanceMap.keys()][0]}.`)
return
}
+2 -2
View File
@@ -34,7 +34,7 @@ const getSelector = element => {
const SelectorEngine = {
find(selector, element = document.documentElement) {
return [].concat(...Element.prototype.querySelectorAll.call(element, selector))
return [...Element.prototype.querySelectorAll.call(element, selector)]
},
findOne(selector, element = document.documentElement) {
@@ -42,7 +42,7 @@ const SelectorEngine = {
},
children(element, selector) {
return [].concat(...element.children).filter(child => child.matches(selector))
return [...element.children].filter(child => child.matches(selector))
},
parents(element, selector) {
+5 -3
View File
@@ -143,7 +143,8 @@ class Dropdown extends BaseComponent {
// only needed because of broken event delegation on iOS
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {
for (const element of [].concat(...document.body.children)) {
const children = [...document.body.children]
for (const element of children) {
EventHandler.on(element, 'mouseover', noop)
}
}
@@ -193,7 +194,8 @@ class Dropdown extends BaseComponent {
// If this is a touch-enabled device we remove the extra
// empty mouseover listeners we added for iOS support
if ('ontouchstart' in document.documentElement) {
for (const element of [].concat(...document.body.children)) {
const children = [...document.body.children]
for (const element of children) {
EventHandler.off(element, 'mouseover', noop)
}
}
@@ -320,7 +322,7 @@ class Dropdown extends BaseComponent {
return {
...defaultBsPopperConfig,
...execute(this._config.popperConfig, [undefined, defaultBsPopperConfig])
...execute(this._config.popperConfig, [defaultBsPopperConfig])
}
}
+6 -4
View File
@@ -222,7 +222,8 @@ class Tooltip extends BaseComponent {
// only needed because of broken event delegation on iOS
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
if ('ontouchstart' in document.documentElement) {
for (const element of [].concat(...document.body.children)) {
const children = [...document.body.children]
for (const element of children) {
EventHandler.on(element, 'mouseover', noop)
}
}
@@ -256,7 +257,8 @@ class Tooltip extends BaseComponent {
// If this is a touch-enabled device we remove the extra
// empty mouseover listeners we added for iOS support
if ('ontouchstart' in document.documentElement) {
for (const element of [].concat(...document.body.children)) {
const children = [...document.body.children]
for (const element of children) {
EventHandler.off(element, 'mouseover', noop)
}
}
@@ -392,7 +394,7 @@ class Tooltip extends BaseComponent {
}
_resolvePossibleFunction(arg) {
return execute(arg, [this._element, this._element])
return execute(arg, [this._element])
}
_getPopperConfig(attachment) {
@@ -438,7 +440,7 @@ class Tooltip extends BaseComponent {
return {
...defaultBsPopperConfig,
...execute(this._config.popperConfig, [undefined, defaultBsPopperConfig])
...execute(this._config.popperConfig, [defaultBsPopperConfig])
}
}
+2 -2
View File
@@ -170,7 +170,7 @@ const noop = () => {}
* @param {HTMLElement} element
* @return void
*
* @see https://www.harrytheo.com/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
* @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
*/
const reflow = element => {
element.offsetHeight // eslint-disable-line no-unused-expressions
@@ -223,7 +223,7 @@ const defineJQueryPlugin = plugin => {
}
const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {
return typeof possibleCallback === 'function' ? possibleCallback.call(...args) : defaultValue
return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue
}
const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
+3 -3
View File
@@ -93,7 +93,7 @@ export function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {
const domParser = new window.DOMParser()
const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')
const elements = [].concat(...createdDocument.body.querySelectorAll('*'))
const elements = [...createdDocument.body.querySelectorAll('*')]
for (const element of elements) {
const elementName = element.nodeName.toLowerCase()
@@ -103,8 +103,8 @@ export function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {
continue
}
const attributeList = [].concat(...element.attributes)
const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || [])
const attributeList = [...element.attributes]
const allowedAttributes = [...allowList['*'] || [], ...allowList[elementName] || []]
for (const attribute of attributeList) {
if (!allowedAttribute(attribute, allowedAttributes)) {
+1 -1
View File
@@ -143,7 +143,7 @@ class TemplateFactory extends Config {
}
_resolvePossibleFunction(arg) {
return execute(arg, [undefined, this])
return execute(arg, [this])
}
_putElementInTemplate(element, templateElement) {
+3 -3
View File
@@ -1,7 +1,7 @@
/* eslint-disable import/extensions, import/no-unassigned-import */
/* eslint-disable import/no-unassigned-import */
import Tooltip from '../../dist/tooltip'
import '../../dist/carousel'
import Tooltip from '../../dist/tooltip.js'
import '../../dist/carousel.js'
window.addEventListener('load', () => {
[].concat(...document.querySelectorAll('[data-bs-toggle="tooltip"]'))
+1 -1
View File
@@ -1,6 +1,6 @@
import { Tooltip } from '../../../dist/js/bootstrap.esm.js'
window.addEventListener('load', () => {
[].concat(...document.querySelectorAll('[data-bs-toggle="tooltip"]'))
[...document.querySelectorAll('[data-bs-toggle="tooltip"]')]
.map(tooltipNode => new Tooltip(tooltipNode))
})
+1 -1
View File
@@ -153,7 +153,7 @@ describe('Collapse', () => {
const collapseEl1 = fixtureEl.querySelector('#collapse1')
const collapseEl2 = fixtureEl.querySelector('#collapse2')
const collapseList = [].concat(...fixtureEl.querySelectorAll('.collapse'))
const collapseList = [...fixtureEl.querySelectorAll('.collapse')]
.map(el => new Collapse(el, {
parent,
toggle: false
+5 -5
View File
@@ -68,7 +68,7 @@ describe('SelectorEngine', () => {
].join('')
const list = fixtureEl.querySelector('ul')
const liList = [].concat(...fixtureEl.querySelectorAll('li'))
const liList = [...fixtureEl.querySelectorAll('li')]
const result = SelectorEngine.children(list, 'li')
expect(result).toEqual(liList)
@@ -356,7 +356,7 @@ describe('SelectorEngine', () => {
const testEl = fixtureEl.querySelector('#test')
expect(SelectorEngine.getMultipleElementsFromSelector(testEl)).toEqual(Array.from(fixtureEl.querySelectorAll('.target')))
expect(SelectorEngine.getMultipleElementsFromSelector(testEl)).toEqual([...fixtureEl.querySelectorAll('.target')])
})
it('should get elements if several ids are given', () => {
@@ -368,7 +368,7 @@ describe('SelectorEngine', () => {
const testEl = fixtureEl.querySelector('#test')
expect(SelectorEngine.getMultipleElementsFromSelector(testEl)).toEqual(Array.from(fixtureEl.querySelectorAll('.target')))
expect(SelectorEngine.getMultipleElementsFromSelector(testEl)).toEqual([...fixtureEl.querySelectorAll('.target')])
})
it('should get elements if several ids with special chars are given', () => {
@@ -380,7 +380,7 @@ describe('SelectorEngine', () => {
const testEl = fixtureEl.querySelector('#test')
expect(SelectorEngine.getMultipleElementsFromSelector(testEl)).toEqual(Array.from(fixtureEl.querySelectorAll('.target')))
expect(SelectorEngine.getMultipleElementsFromSelector(testEl)).toEqual([...fixtureEl.querySelectorAll('.target')])
})
it('should get elements in array, from href if no data-bs-target set', () => {
@@ -392,7 +392,7 @@ describe('SelectorEngine', () => {
const testEl = fixtureEl.querySelector('#test')
expect(SelectorEngine.getMultipleElementsFromSelector(testEl)).toEqual(Array.from(fixtureEl.querySelectorAll('.target')))
expect(SelectorEngine.getMultipleElementsFromSelector(testEl)).toEqual([...fixtureEl.querySelectorAll('.target')])
})
it('should return empty array if elements not found', () => {
+1 -4
View File
@@ -172,10 +172,7 @@ describe('Dropdown', () => {
const popperConfig = dropdown._getPopperConfig()
// Ensure that the function was called with the default config.
expect(getPopperConfig).toHaveBeenCalledWith(jasmine.objectContaining({
placement: jasmine.any(String)
}))
expect(getPopperConfig).toHaveBeenCalled()
expect(popperConfig.placement).toEqual('left')
})
})
-54
View File
@@ -95,60 +95,6 @@ describe('Popover', () => {
})
})
it('should call content and title functions with trigger element', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" data-foo="bar">BS twitter</a>'
const popoverEl = fixtureEl.querySelector('a')
const popover = new Popover(popoverEl, {
title(el) {
return el.dataset.foo
},
content(el) {
return el.dataset.foo
}
})
popoverEl.addEventListener('shown.bs.popover', () => {
const popoverDisplayed = document.querySelector('.popover')
expect(popoverDisplayed).not.toBeNull()
expect(popoverDisplayed.querySelector('.popover-header').textContent).toEqual('bar')
expect(popoverDisplayed.querySelector('.popover-body').textContent).toEqual('bar')
resolve()
})
popover.show()
})
})
it('should call content and title functions with correct this value', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" data-foo="bar">BS twitter</a>'
const popoverEl = fixtureEl.querySelector('a')
const popover = new Popover(popoverEl, {
title() {
return this.dataset.foo
},
content() {
return this.dataset.foo
}
})
popoverEl.addEventListener('shown.bs.popover', () => {
const popoverDisplayed = document.querySelector('.popover')
expect(popoverDisplayed).not.toBeNull()
expect(popoverDisplayed.querySelector('.popover-header').textContent).toEqual('bar')
expect(popoverDisplayed.querySelector('.popover-body').textContent).toEqual('bar')
resolve()
})
popover.show()
})
})
it('should show a popover with just content without having header', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#">Nice link</a>'
+4 -36
View File
@@ -177,10 +177,7 @@ describe('Tooltip', () => {
const popperConfig = tooltip._getPopperConfig('top')
// Ensure that the function was called with the default config.
expect(getPopperConfig).toHaveBeenCalledWith(jasmine.objectContaining({
placement: jasmine.any(String)
}))
expect(getPopperConfig).toHaveBeenCalled()
expect(popperConfig.placement).toEqual('left')
})
@@ -922,12 +919,10 @@ describe('Tooltip', () => {
it('should show a tooltip with custom class provided as a function in config', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip" data-class-a="custom-class-a" data-class-b="custom-class-b"></a>'
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
const spy = jasmine.createSpy('customClass').and.returnValue('custom-class')
const tooltipEl = fixtureEl.querySelector('a')
const spy = jasmine.createSpy('customClass').and.callFake(function (el) {
return `${el.dataset.classA} ${this.dataset.classB}`
})
const tooltip = new Tooltip(tooltipEl, {
customClass: spy
})
@@ -936,8 +931,7 @@ describe('Tooltip', () => {
const tip = document.querySelector('.tooltip')
expect(tip).not.toBeNull()
expect(spy).toHaveBeenCalled()
expect(tip).toHaveClass('custom-class-a')
expect(tip).toHaveClass('custom-class-b')
expect(tip).toHaveClass('custom-class')
resolve()
})
@@ -1343,32 +1337,6 @@ describe('Tooltip', () => {
expect(tooltip._getTitle()).toEqual('test')
})
it('should call title function with trigger element', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" data-foo="bar"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl, {
title(el) {
return el.dataset.foo
}
})
expect(tooltip._getTitle()).toEqual('bar')
})
it('should call title function with correct this value', () => {
fixtureEl.innerHTML = '<a href="#" rel="tooltip" data-foo="bar"></a>'
const tooltipEl = fixtureEl.querySelector('a')
const tooltip = new Tooltip(tooltipEl, {
title() {
return this.dataset.foo
}
})
expect(tooltip._getTitle()).toEqual('bar')
})
})
describe('getInstance', () => {
+2 -2
View File
@@ -521,10 +521,10 @@ describe('Util', () => {
it('should execute if arg is function & return the result', () => {
const functionFoo = (num1, num2 = 10) => num1 + num2
const resultFoo = Util.execute(functionFoo, [undefined, 4, 5])
const resultFoo = Util.execute(functionFoo, [4, 5])
expect(resultFoo).toBe(9)
const resultFoo1 = Util.execute(functionFoo, [undefined, 4])
const resultFoo1 = Util.execute(functionFoo, [4])
expect(resultFoo1).toBe(14)
const functionBar = () => 'foo'
-337
View File
@@ -1,337 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="../../../dist/css/bootstrap.min.css" rel="stylesheet">
<title>Form</title>
<style></style>
</head>
<body>
<div class="container py-5 d-flex flex-column gap-3">
<div class="form-floating">
<input type="email" class="form-control" id="floatingInput" placeholder="name@example.com">
<label for="floatingInput">Email address</label>
</div>
<div class="form-floating">
<input type="email" class="form-control" id="floatingInput1" placeholder="name@example.com">
<label for="floatingInput1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<form class="form-floating">
<input type="email" class="form-control" id="floatingInputValue" placeholder="name@example.com" value="test@example.com">
<label for="floatingInputValue">Input with value</label>
</form>
<form class="form-floating">
<input type="email" class="form-control" id="floatingInputValue1" placeholder="name@example.com" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.">
<label for="floatingInputValue1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</form>
<form class="form-floating">
<input type="email" class="form-control is-invalid" id="floatingInputInvalid" placeholder="name@example.com" value="test@example.com">
<label for="floatingInputInvalid">Invalid input</label>
</form>
<form class="form-floating">
<input type="email" class="form-control is-invalid" id="floatingInputInvalid1" placeholder="name@example.com" value="test@example.com">
<label for="floatingInputInvalid1">Invalid input</label>
</form>
<form class="form-floating">
<input type="email" class="form-control is-invalid" id="floatingInputInvalid2" placeholder="name@example.com">
<label for="floatingInputInvalid2">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</form>
<form class="form-floating">
<input type="email" class="form-control is-invalid" id="floatingInputInvalid3" placeholder="name@example.com" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.">
<label for="floatingInputInvalid3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</form>
<div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea"></textarea>
<label for="floatingTextarea">Comments</label>
</div>
<div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea1"></textarea>
<label for="floatingTextarea1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea2" style="height: 50px"></textarea>
<label for="floatingTextarea2">Comments</label>
</div>
<div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea3" style="height: 50px"></textarea>
<label for="floatingTextarea3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea4" style="height: 50px">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</textarea>
<label for="floatingTextarea4">Comments</label>
</div>
<div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea5" style="height: 50px">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</textarea>
<label for="floatingTextarea5">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating">
<textarea class="form-control is-invalid" placeholder="Leave a comment here" id="floatingTextarea6" style="height: 50px">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</textarea>
<label for="floatingTextarea6">Comments</label>
</div>
<div class="form-floating">
<textarea class="form-control is-invalid" placeholder="Leave a comment here" id="floatingTextarea7" style="height: 50px">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</textarea>
<label for="floatingTextarea7">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating">
<select class="form-select" id="floatingSelect" aria-label="Floating label select example">
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<label for="floatingSelect">Works with selects</label>
</div>
<div class="form-floating">
<select class="form-select is-invalid" id="floatingSelect1" aria-label="Floating label select example">
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<label for="floatingSelect1">Works with selects</label>
</div>
<div class="form-floating">
<select class="form-select" id="floatingSelect2" aria-label="Floating label select example">
<option selected>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="2">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
</select>
<label for="floatingSelect2">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating">
<select class="form-select is-invalid" id="floatingSelect3" aria-label="Floating label select example">
<option selected>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="2">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
</select>
<label for="floatingSelect3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating mb-3">
<input type="email" class="form-control" id="floatingInputDisabled" placeholder="name@example.com" disabled>
<label for="floatingInputDisabled">Email address</label>
</div>
<div class="form-floating mb-3">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextareaDisabled" disabled></textarea>
<label for="floatingTextareaDisabled">Comments</label>
</div>
<div class="form-floating mb-3">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextareaDisabled1" style="height: 50px" disabled>Disabled textarea with some text inside</textarea>
<label for="floatingTextareaDisabled1">Comments</label>
</div>
<div class="form-floating">
<select class="form-select" id="floatingSelectDisabled" aria-label="Floating label disabled select example" disabled>
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<label for="floatingSelectDisabled">Works with selects</label>
</div>
<div class="form-floating mb-3">
<input type="email" class="form-control" id="floatingInputDisabled1" placeholder="name@example.com" disabled>
<label for="floatingInputDisabled1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating mb-3">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextareaDisabled2" disabled></textarea>
<label for="floatingTextareaDisabled2">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating mb-3">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextareaDisabled3" style="height: 50px" disabled>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</textarea>
<label for="floatingTextareaDisabled3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating">
<select class="form-select" id="floatingSelectDisabled1" aria-label="Floating label disabled select example" disabled>
<option selected>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="2">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
</select>
<label for="floatingSelectDisabled1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating mb-3">
<input type="email" readonly class="form-control-plaintext" id="floatingEmptyPlaintextInput" placeholder="name@example.com">
<label for="floatingEmptyPlaintextInput">Empty input</label>
</div>
<div class="form-floating mb-3">
<input type="email" readonly class="form-control-plaintext" id="floatingPlaintextInput" placeholder="name@example.com" value="name@example.com">
<label for="floatingPlaintextInput">Input with value</label>
</div>
<div class="form-floating mb-3">
<input type="email" readonly class="form-control-plaintext" id="floatingEmptyPlaintextInput1" placeholder="name@example.com">
<label for="floatingEmptyPlaintextInput1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating mb-3">
<input type="email" readonly class="form-control-plaintext" id="floatingPlaintextInput1" placeholder="name@example.com" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.">
<label for="floatingPlaintextInput1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
</div>
<div class="container-fluid bg-body" data-bs-theme="dark">
<div class="container py-5 d-flex flex-column gap-3">
<div class="form-floating">
<input type="email" class="form-control" id="floatingInput2" placeholder="name@example.com">
<label for="floatingInput2">Email address</label>
</div>
<div class="form-floating">
<input type="email" class="form-control" id="floatingInput3" placeholder="name@example.com">
<label for="floatingInput3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<form class="form-floating">
<input type="email" class="form-control" id="floatingInputValue2" placeholder="name@example.com" value="test@example.com">
<label for="floatingInputValue2">Input with value</label>
</form>
<form class="form-floating">
<input type="email" class="form-control" id="floatingInputValue3" placeholder="name@example.com" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.">
<label for="floatingInputValue3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</form>
<form class="form-floating">
<input type="email" class="form-control is-invalid" id="floatingInputInvalid4" placeholder="name@example.com" value="test@example.com">
<label for="floatingInputInvalid4">Invalid input</label>
</form>
<form class="form-floating">
<input type="email" class="form-control is-invalid" id="floatingInputInvalid5" placeholder="name@example.com" value="test@example.com">
<label for="floatingInputInvalid5">Invalid input</label>
</form>
<form class="form-floating">
<input type="email" class="form-control is-invalid" id="floatingInputInvalid6" placeholder="name@example.com">
<label for="floatingInputInvalid6">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</form>
<form class="form-floating">
<input type="email" class="form-control is-invalid" id="floatingInputInvalid7" placeholder="name@example.com" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.">
<label for="floatingInputInvalid7">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</form>
<div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea8"></textarea>
<label for="floatingTextarea8">Comments</label>
</div>
<div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea9"></textarea>
<label for="floatingTextarea9">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea10" style="height: 50px"></textarea>
<label for="floatingTextarea10">Comments</label>
</div>
<div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea11" style="height: 50px"></textarea>
<label for="floatingTextarea11">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea12" style="height: 50px">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</textarea>
<label for="floatingTextarea12">Comments</label>
</div>
<div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea13" style="height: 50px">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</textarea>
<label for="floatingTextarea13">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating">
<textarea class="form-control is-invalid" placeholder="Leave a comment here" id="floatingTextarea14" style="height: 50px">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</textarea>
<label for="floatingTextarea14">Comments</label>
</div>
<div class="form-floating">
<textarea class="form-control is-invalid" placeholder="Leave a comment here" id="floatingTextarea15" style="height: 50px">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</textarea>
<label for="floatingTextarea15">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating">
<select class="form-select" id="floatingSelect4" aria-label="Floating label select example">
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<label for="floatingSelect4">Works with selects</label>
</div>
<div class="form-floating">
<select class="form-select is-invalid" id="floatingSelect5" aria-label="Floating label select example">
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<label for="floatingSelect5">Works with selects</label>
</div>
<div class="form-floating">
<select class="form-select" id="floatingSelect6" aria-label="Floating label select example">
<option selected>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="2">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
</select>
<label for="floatingSelect6">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating">
<select class="form-select is-invalid" id="floatingSelect7" aria-label="Floating label select example">
<option selected>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="2">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
</select>
<label for="floatingSelect7">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating mb-3">
<input type="email" class="form-control" id="floatingInputDisabled2" placeholder="name@example.com" disabled>
<label for="floatingInputDisabled2">Email address</label>
</div>
<div class="form-floating mb-3">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextareaDisabled4" disabled></textarea>
<label for="floatingTextareaDisabled4">Comments</label>
</div>
<div class="form-floating mb-3">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextareaDisabled5" style="height: 50px" disabled>Disabled textarea with some text inside</textarea>
<label for="floatingTextareaDisabled5">Comments</label>
</div>
<div class="form-floating">
<select class="form-select" id="floatingSelectDisabled2" aria-label="Floating label disabled select example" disabled>
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<label for="floatingSelectDisabled2">Works with selects</label>
</div>
<div class="form-floating mb-3">
<input type="email" class="form-control" id="floatingInputDisabled3" placeholder="name@example.com" disabled>
<label for="floatingInputDisabled3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating mb-3">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextareaDisabled6" disabled></textarea>
<label for="floatingTextareaDisabled6">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating mb-3">
<textarea class="form-control" placeholder="Leave a comment here" id="floatingTextareaDisabled7" style="height: 50px" disabled>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</textarea>
<label for="floatingTextareaDisabled7">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating">
<select class="form-select" id="floatingSelectDisabled3" aria-label="Floating label disabled select example" disabled>
<option selected>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="2">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
<option value="3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</option>
</select>
<label for="floatingSelectDisabled3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating mb-3">
<input type="email" readonly class="form-control-plaintext" id="floatingEmptyPlaintextInput2" placeholder="name@example.com">
<label for="floatingEmptyPlaintextInput2">Empty input</label>
</div>
<div class="form-floating mb-3">
<input type="email" readonly class="form-control-plaintext" id="floatingPlaintextInput2" placeholder="name@example.com" value="name@example.com">
<label for="floatingPlaintextInput2">Input with value</label>
</div>
<div class="form-floating mb-3">
<input type="email" readonly class="form-control-plaintext" id="floatingEmptyPlaintextInput3" placeholder="name@example.com">
<label for="floatingEmptyPlaintextInput3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
<div class="form-floating mb-3">
<input type="email" readonly class="form-control-plaintext" id="floatingPlaintextInput3" placeholder="name@example.com" value="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.">
<label for="floatingPlaintextInput3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum mattis mi at lobortis rutrum. Phasellus varius a risus non lobortis. Ut id congue enim. Quisque facilisis elit ac elit dapibus aliquet nec sit amet arcu. Morbi vitae ultricies eros. Proin varius augue in tristique pretium. Morbi at ullamcorper elit, at ullamcorper massa. Vivamus suscipit quam quis viverra eleifend.</label>
</div>
</div>
</div>
<script src="../../../dist/js/bootstrap.bundle.js"></script>
</body>
</html>
+6 -2
View File
@@ -217,9 +217,13 @@
}
}
document.querySelectorAll('[data-bs-toggle="popover"]').forEach(popoverEl => new bootstrap.Popover(popoverEl))
for (const popoverEl of document.querySelectorAll('[data-bs-toggle="popover"]')) {
new bootstrap.Popover(popoverEl)
}
document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(tooltipEl => new bootstrap.Tooltip(tooltipEl))
for (const tooltipEl of document.querySelectorAll('[data-bs-toggle="tooltip"]')) {
new bootstrap.Tooltip(tooltipEl)
}
const tall = document.getElementById('tall')
document.getElementById('tall-toggle').addEventListener('click', () => {
+3 -1
View File
@@ -35,7 +35,9 @@
<script>
/* global bootstrap: false */
document.querySelectorAll('[data-bs-toggle="popover"]').forEach(popoverEl => new bootstrap.Popover(popoverEl))
for (const popoverEl of document.querySelectorAll('[data-bs-toggle="popover"]')) {
new bootstrap.Popover(popoverEl)
}
</script>
</body>
</html>
+9 -3
View File
@@ -55,14 +55,20 @@
/* global bootstrap: false */
window.addEventListener('load', () => {
document.querySelectorAll('.toast').forEach(toastEl => new bootstrap.Toast(toastEl))
for (const toastEl of document.querySelectorAll('.toast')) {
new bootstrap.Toast(toastEl)
}
document.getElementById('btnShowToast').addEventListener('click', () => {
document.querySelectorAll('.toast').forEach(toastEl => bootstrap.Toast.getInstance(toastEl).show())
for (const toastEl of document.querySelectorAll('.toast')) {
bootstrap.Toast.getInstance(toastEl).show()
}
})
document.getElementById('btnHideToast').addEventListener('click', () => {
document.querySelectorAll('.toast').forEach(toastEl => bootstrap.Toast.getInstance(toastEl).hide())
for (const toastEl of document.querySelectorAll('.toast')) {
bootstrap.Toast.getInstance(toastEl).hide()
}
})
})
</script>
+3 -1
View File
@@ -113,7 +113,9 @@
})
targetTooltip.show()
document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(tooltipEl => new bootstrap.Tooltip(tooltipEl))
for (const tooltipEl of document.querySelectorAll('[data-bs-toggle="tooltip"]')) {
new bootstrap.Tooltip(tooltipEl)
}
</script>
<script>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

+10305 -2222
View File
File diff suppressed because it is too large Load Diff
+24 -27
View File
@@ -82,7 +82,7 @@
"docs-serve": "hugo server --port 9001 --disableFastRender --noHTTPCache --renderToMemory --printPathWarnings --printUnusedTemplates",
"docs-serve-only": "npx sirv-cli _site --port 9001",
"lockfile-lint": "lockfile-lint --allowed-hosts npm --allowed-schemes https: --empty-hostname false --type npm --path package-lock.json",
"update-deps": "ncu -u -x eslint,karma-browserstack-launcher,karma-rollup-preprocessor",
"update-deps": "ncu -u -x globby,jasmine,karma-browserstack-launcher,karma-rollup-preprocessor && echo Manually update site/assets/js/vendor",
"release": "npm-run-all dist release-sri docs-build release-zip*",
"release-sri": "node build/generate-sri.mjs",
"release-version": "node build/change-version.mjs",
@@ -103,33 +103,30 @@
"@popperjs/core": "^2.11.8"
},
"devDependencies": {
"@babel/cli": "^7.24.8",
"@babel/core": "^7.24.9",
"@babel/preset-env": "^7.24.8",
"@docsearch/js": "^3.6.1",
"@babel/cli": "^7.23.9",
"@babel/core": "^7.24.0",
"@babel/preset-env": "^7.24.0",
"@popperjs/core": "^2.11.8",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-commonjs": "^26.0.1",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^5.0.7",
"@stackblitz/sdk": "^1.11.0",
"autoprefixer": "^10.4.19",
"@rollup/plugin-replace": "^5.0.5",
"autoprefixer": "^10.4.18",
"bundlewatch": "^0.3.3",
"clean-css-cli": "^5.6.3",
"clipboard": "^2.0.11",
"cross-env": "^7.0.3",
"eslint": "^8.57.0",
"eslint-config-xo": "^0.45.0",
"eslint-plugin-html": "^8.1.1",
"eslint-config-xo": "^0.44.0",
"eslint-plugin-html": "^8.0.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-markdown": "^5.1.0",
"eslint-plugin-unicorn": "^54.0.0",
"find-unused-sass-variables": "^6.0.0",
"globby": "^14.0.2",
"eslint-plugin-markdown": "^3.0.1",
"eslint-plugin-unicorn": "^51.0.1",
"find-unused-sass-variables": "^5.0.0",
"globby": "^11.1.0",
"hammer-simulator": "0.0.1",
"hugo-bin": "^0.126.0",
"hugo-bin": "^0.120.7",
"ip": "^2.0.1",
"jasmine": "^5.2.0",
"jasmine": "^5.1.0",
"jquery": "^3.7.1",
"karma": "^6.4.3",
"karma-browserstack-launcher": "1.4.0",
@@ -140,20 +137,20 @@
"karma-jasmine": "^5.1.0",
"karma-jasmine-html-reporter": "^2.1.0",
"karma-rollup-preprocessor": "7.0.7",
"lockfile-lint": "^4.14.0",
"nodemon": "^3.1.4",
"npm-run-all2": "^6.2.2",
"postcss": "^8.4.39",
"lockfile-lint": "^4.13.2",
"nodemon": "^3.1.0",
"npm-run-all2": "^6.1.2",
"postcss": "^8.4.35",
"postcss-cli": "^11.0.0",
"rollup": "^4.19.0",
"rollup": "^4.12.0",
"rollup-plugin-istanbul": "^5.0.0",
"rtlcss": "^4.1.1",
"sass": "^1.77.8",
"sass": "^1.71.1",
"sass-true": "^8.0.0",
"shelljs": "^0.8.5",
"stylelint": "^16.7.0",
"stylelint-config-twbs-bootstrap": "^14.2.0",
"terser": "^5.31.3",
"stylelint": "^16.2.1",
"stylelint-config-twbs-bootstrap": "^14.0.0",
"terser": "^5.27.2",
"vnu-jar": "23.4.11"
},
"files": [
+1 -6
View File
@@ -135,12 +135,7 @@
@include border-bottom-radius(0);
}
// The top radius should be 0 if the button is:
// - the "third or more" child
// - the second child and the previous element isn't `.btn-check` (making it the first child visually)
// - part of a btn-group which isn't the first child
> .btn:nth-child(n + 3),
> :not(.btn-check) + .btn,
> .btn ~ .btn,
> .btn-group:not(:first-child) > .btn {
@include border-top-radius(0);
}
+1 -1
View File
@@ -59,8 +59,8 @@
// When fading in the modal, animate it to slide down
.modal.fade & {
transform: $modal-fade-transform;
@include transition($modal-transition);
transform: $modal-fade-transform;
}
.modal.show & {
transform: $modal-show-transform;
+1 -1
View File
@@ -499,9 +499,9 @@ legend {
width: 100%;
padding: 0;
margin-bottom: $legend-margin-bottom;
@include font-size($legend-font-size);
font-weight: $legend-font-weight;
line-height: inherit;
@include font-size($legend-font-size);
+ * {
clear: left; // 2
+1 -1
View File
@@ -34,11 +34,11 @@
// Type display classes
@each $display, $font-size in $display-font-sizes {
.display-#{$display} {
@include font-size($font-size);
font-family: $display-font-family;
font-style: $display-font-style;
font-weight: $display-font-weight;
line-height: $display-line-height;
@include font-size($font-size);
}
}
+2 -2
View File
@@ -82,6 +82,6 @@ $form-invalid-border-color-dark: $red-300 !default;
$accordion-icon-color-dark: $primary-text-emphasis-dark !default;
$accordion-icon-active-color-dark: $primary-text-emphasis-dark !default;
$accordion-button-icon-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-color-dark}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/></svg>") !default;
$accordion-button-active-icon-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-active-color-dark}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/></svg>") !default;
$accordion-button-icon-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-color-dark}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>") !default;
$accordion-button-active-icon-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-active-color-dark}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>") !default;
// scss-docs-end sass-dark-mode-vars
+6 -6
View File
@@ -1091,7 +1091,7 @@ $form-feedback-valid-color: $success !default;
$form-feedback-invalid-color: $danger !default;
$form-feedback-icon-valid-color: $form-feedback-valid-color !default;
$form-feedback-icon-valid: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1'/></svg>") !default;
$form-feedback-icon-valid: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><path fill='#{$form-feedback-icon-valid-color}' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>") !default;
$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;
$form-feedback-icon-invalid: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='#{$form-feedback-icon-invalid-color}'><circle cx='6' cy='6' r='4.5'/><path stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/><circle cx='6' cy='8.2' r='.6' fill='#{$form-feedback-icon-invalid-color}' stroke='none'/></svg>") !default;
// scss-docs-end form-feedback-variables
@@ -1394,8 +1394,8 @@ $accordion-icon-active-color: $primary-text-emphasis !default;
$accordion-icon-transition: transform .2s ease-in-out !default;
$accordion-icon-transform: rotate(-180deg) !default;
$accordion-button-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='#{$accordion-icon-color}' stroke-linecap='round' stroke-linejoin='round'><path d='m2 5 6 6 6-6'/></svg>") !default;
$accordion-button-active-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='#{$accordion-icon-active-color}' stroke-linecap='round' stroke-linejoin='round'><path d='m2 5 6 6 6-6'/></svg>") !default;
$accordion-button-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='#{$accordion-icon-color}' stroke-linecap='round' stroke-linejoin='round'><path d='M2 5L8 11L14 5'/></svg>") !default;
$accordion-button-active-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='#{$accordion-icon-active-color}' stroke-linecap='round' stroke-linejoin='round'><path d='M2 5L8 11L14 5'/></svg>") !default;
// scss-docs-end accordion-variables
// Tooltips
@@ -1669,8 +1669,8 @@ $carousel-caption-spacer: 1.25rem !default;
$carousel-control-icon-width: 2rem !default;
$carousel-control-prev-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$carousel-control-color}'><path d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0'/></svg>") !default;
$carousel-control-next-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$carousel-control-color}'><path d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708'/></svg>") !default;
$carousel-control-prev-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$carousel-control-color}'><path d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/></svg>") !default;
$carousel-control-next-icon-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$carousel-control-color}'><path d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/></svg>") !default;
$carousel-transition-duration: .6s !default;
$carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)
@@ -1706,7 +1706,7 @@ $btn-close-height: $btn-close-width !default;
$btn-close-padding-x: .25em !default;
$btn-close-padding-y: $btn-close-padding-x !default;
$btn-close-color: $black !default;
$btn-close-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$btn-close-color}'><path d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414'/></svg>") !default;
$btn-close-bg: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$btn-close-color}'><path d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/></svg>") !default;
$btn-close-focus-shadow: $focus-ring-box-shadow !default;
$btn-close-opacity: .5 !default;
$btn-close-hover-opacity: .75 !default;
+16 -17
View File
@@ -14,11 +14,9 @@
top: 0;
left: 0;
z-index: 2;
max-width: 100%;
height: 100%; // allow textareas
padding: $form-floating-padding-y $form-floating-padding-x;
overflow: hidden;
color: rgba(var(--#{$prefix}body-color-rgb), #{$form-floating-label-opacity});
text-align: start;
text-overflow: ellipsis;
white-space: nowrap;
@@ -58,30 +56,27 @@
> .form-control-plaintext,
> .form-select {
~ label {
color: rgba(var(--#{$prefix}body-color-rgb), #{$form-floating-label-opacity});
transform: $form-floating-label-transform;
&::after {
position: absolute;
inset: $form-floating-padding-y ($form-floating-padding-x * .5);
z-index: -1;
height: $form-floating-label-height;
content: "";
background-color: $input-bg;
@include border-radius($input-border-radius);
}
}
}
// Duplicated because `:-webkit-autofill` invalidates other selectors when grouped
> .form-control:-webkit-autofill {
~ label {
color: rgba(var(--#{$prefix}body-color-rgb), #{$form-floating-label-opacity});
transform: $form-floating-label-transform;
}
}
> textarea:focus,
> textarea:not(:placeholder-shown) {
~ label::after {
position: absolute;
inset: $form-floating-padding-y ($form-floating-padding-x * .5);
z-index: -1;
height: $form-floating-label-height;
content: "";
background-color: $input-bg;
@include border-radius($input-border-radius);
}
}
> textarea:disabled ~ label::after {
background-color: $input-disabled-bg;
}
> .form-control-plaintext {
~ label {
@@ -92,5 +87,9 @@
> :disabled ~ label,
> .form-control:disabled ~ label { // Required for `.form-control`s because of specificity
color: $form-floating-label-disabled-color;
&::after {
background-color: $input-disabled-bg;
}
}
}
+18 -8
View File
@@ -9,12 +9,22 @@
* For details, see https://creativecommons.org/licenses/by/3.0/.
*/
/* eslint-disable import/no-unresolved */
import sidebarScroll from 'js/partials/sidebar.js'
import codeExamples from 'js/partials/code-examples.js'
import snippets from 'js/partials/snippets.js'
/* eslint-enable import/no-unresolved */
(() => {
'use strict'
sidebarScroll()
codeExamples()
snippets()
// Scroll the active sidebar link into view
const sidenav = document.querySelector('.bd-sidebar')
const sidenavActiveLink = document.querySelector('.bd-links-nav .active')
if (sidenav && sidenavActiveLink) {
const sidenavHeight = sidenav.clientHeight
const sidenavActiveLinkTop = sidenavActiveLink.offsetTop
const sidenavActiveLinkHeight = sidenavActiveLink.clientHeight
const viewportTop = sidenavActiveLinkTop
const viewportBottom = viewportTop - sidenavHeight + sidenavActiveLinkHeight
if (sidenav.scrollTop > viewportTop || sidenav.scrollTop < viewportBottom) {
sidenav.scrollTop = viewportTop - (sidenavHeight / 2) + (sidenavActiveLinkHeight / 2)
}
}
})()
@@ -2,45 +2,40 @@
// IT'S ALL JUST JUNK FOR OUR DOCS!
// ++++++++++++++++++++++++++++++++++++++++++
/*
/*!
* JavaScript for Bootstrap's docs (https://getbootstrap.com/)
* Copyright 2011-2024 The Bootstrap Authors
* Licensed under the Creative Commons Attribution 3.0 Unported License.
* For details, see https://creativecommons.org/licenses/by/3.0/.
*/
/* global bootstrap: false */
/* global ClipboardJS: false, bootstrap: false */
import ClipboardJS from 'clipboard'
(() => {
'use strict'
export default () => {
// Insert copy to clipboard button before .highlight
const btnTitle = 'Copy to clipboard'
const btnEdit = 'Edit on StackBlitz'
const btnHtml = [
'<div class="bd-code-snippet">',
' <div class="d-flex align-items-center highlight-toolbar ps-3 pe-2 py-1">',
' <small class="font-monospace text-body-secondary text-uppercase">html</small>',
' <div class="d-flex ms-auto">',
' <button type="button" class="btn-clipboard mt-0 me-0">',
' <svg class="bi" aria-hidden="true"><use xlink:href="#clipboard"></use></svg>',
' </button>',
' </div>',
' <div class="bd-clipboard">',
' <button type="button" class="btn-clipboard">',
' <svg class="bi" role="img" aria-label="Copy"><use xlink:href="#clipboard"/></svg>',
' </button>',
' </div>',
'</div>'
].join('')
// Wrap programmatically code blocks and add copy btn.
document.querySelectorAll('.highlight')
.forEach(element => {
// Ignore examples made by shortcode
if (!element.closest('.bd-example-snippet')) {
element.insertAdjacentHTML('beforebegin', btnHtml)
element.previousElementSibling.append(element)
element.previousElementSibling.querySelector('small').textContent = element.querySelector('pre > code').getAttribute('data-lang')
}
})
for (const element of document.querySelectorAll('.highlight')) {
// Ignore examples made by shortcode
if (!element.closest('.bd-example-snippet')) {
element.insertAdjacentHTML('beforebegin', btnHtml)
element.previousElementSibling.append(element)
}
}
/**
*
@@ -48,9 +43,9 @@ export default () => {
* @param {string} title
*/
function snippetButtonTooltip(selector, title) {
document.querySelectorAll(selector).forEach(btn => {
for (const btn of document.querySelectorAll(selector)) {
bootstrap.Tooltip.getOrCreateInstance(btn, { title })
})
}
}
snippetButtonTooltip('.btn-clipboard', btnTitle)
@@ -91,4 +86,4 @@ export default () => {
tooltipBtn.setContent({ '.tooltip-inner': btnTitle })
}, { once: true })
})
}
})()
-30
View File
@@ -1,30 +0,0 @@
// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT
// IT'S ALL JUST JUNK FOR OUR DOCS!
// ++++++++++++++++++++++++++++++++++++++++++
/*
* JavaScript for Bootstrap's docs (https://getbootstrap.com/)
* Copyright 2011-2024 The Bootstrap Authors
* Licensed under the Creative Commons Attribution 3.0 Unported License.
* For details, see https://creativecommons.org/licenses/by/3.0/.
*/
export default () => {
// Scroll the active sidebar link into view
const sidenav = document.querySelector('.bd-sidebar')
const sidenavActiveLink = document.querySelector('.bd-links-nav .active')
if (!sidenav || !sidenavActiveLink) {
return
}
const sidenavHeight = sidenav.clientHeight
const sidenavActiveLinkTop = sidenavActiveLink.offsetTop
const sidenavActiveLinkHeight = sidenavActiveLink.clientHeight
const viewportTop = sidenavActiveLinkTop
const viewportBottom = viewportTop - sidenavHeight + sidenavActiveLinkHeight
if (sidenav.scrollTop > viewportTop || sidenav.scrollTop < viewportBottom) {
sidenav.scrollTop = viewportTop - (sidenavHeight / 2) + (sidenavActiveLinkHeight / 2)
}
}
-168
View File
@@ -1,168 +0,0 @@
// NOTICE!!! Initially embedded in our docs this JavaScript
// file contains elements that can help you create reproducible
// use cases in StackBlitz for instance.
// In a real project please adapt this content to your needs.
// ++++++++++++++++++++++++++++++++++++++++++
/*
* JavaScript for Bootstrap's docs (https://getbootstrap.com/)
* Copyright 2011-2024 The Bootstrap Authors
* Licensed under the Creative Commons Attribution 3.0 Unported License.
* For details, see https://creativecommons.org/licenses/by/3.0/.
*/
/* global bootstrap: false */
export default () => {
// --------
// Tooltips
// --------
// Instantiate all tooltips in a docs or StackBlitz
document.querySelectorAll('[data-bs-toggle="tooltip"]')
.forEach(tooltip => {
new bootstrap.Tooltip(tooltip)
})
// --------
// Popovers
// --------
// Instantiate all popovers in docs or StackBlitz
document.querySelectorAll('[data-bs-toggle="popover"]')
.forEach(popover => {
new bootstrap.Popover(popover)
})
// -------------------------------
// Toasts
// -------------------------------
// Used by 'Placement' example in docs or StackBlitz
const toastPlacement = document.getElementById('toastPlacement')
if (toastPlacement) {
document.getElementById('selectToastPlacement').addEventListener('change', function () {
if (!toastPlacement.dataset.originalClass) {
toastPlacement.dataset.originalClass = toastPlacement.className
}
toastPlacement.className = `${toastPlacement.dataset.originalClass} ${this.value}`
})
}
// Instantiate all toasts in docs pages only
document.querySelectorAll('.bd-example .toast')
.forEach(toastNode => {
const toast = new bootstrap.Toast(toastNode, {
autohide: false
})
toast.show()
})
// Instantiate all toasts in docs pages only
// js-docs-start live-toast
const toastTrigger = document.getElementById('liveToastBtn')
const toastLiveExample = document.getElementById('liveToast')
if (toastTrigger) {
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample)
toastTrigger.addEventListener('click', () => {
toastBootstrap.show()
})
}
// js-docs-end live-toast
// -------------------------------
// Alerts
// -------------------------------
// Used in 'Show live alert' example in docs or StackBlitz
// js-docs-start live-alert
const alertPlaceholder = document.getElementById('liveAlertPlaceholder')
const appendAlert = (message, type) => {
const wrapper = document.createElement('div')
wrapper.innerHTML = [
`<div class="alert alert-${type} alert-dismissible" role="alert">`,
` <div>${message}</div>`,
' <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>',
'</div>'
].join('')
alertPlaceholder.append(wrapper)
}
const alertTrigger = document.getElementById('liveAlertBtn')
if (alertTrigger) {
alertTrigger.addEventListener('click', () => {
appendAlert('Nice, you triggered this alert message!', 'success')
})
}
// js-docs-end live-alert
// --------
// Carousels
// --------
// Instantiate all non-autoplaying carousels in docs or StackBlitz
document.querySelectorAll('.carousel:not([data-bs-ride="carousel"])')
.forEach(carousel => {
bootstrap.Carousel.getOrCreateInstance(carousel)
})
// -------------------------------
// Checks & Radios
// -------------------------------
// Indeterminate checkbox example in docs and StackBlitz
document.querySelectorAll('.bd-example-indeterminate [type="checkbox"]')
.forEach(checkbox => {
if (checkbox.id.includes('Indeterminate')) {
checkbox.indeterminate = true
}
})
// -------------------------------
// Links
// -------------------------------
// Disable empty links in docs examples only
document.querySelectorAll('.bd-content [href="#"]')
.forEach(link => {
link.addEventListener('click', event => {
event.preventDefault()
})
})
// -------------------------------
// Modal
// -------------------------------
// Modal 'Varying modal content' example in docs and StackBlitz
// js-docs-start varying-modal-content
const exampleModal = document.getElementById('exampleModal')
if (exampleModal) {
exampleModal.addEventListener('show.bs.modal', event => {
// Button that triggered the modal
const button = event.relatedTarget
// Extract info from data-bs-* attributes
const recipient = button.getAttribute('data-bs-whatever')
// If necessary, you could initiate an Ajax request here
// and then do the updating in a callback.
// Update the modal's content.
const modalTitle = exampleModal.querySelector('.modal-title')
const modalBodyInput = exampleModal.querySelector('.modal-body input')
modalTitle.textContent = `New message to ${recipient}`
modalBodyInput.value = recipient
})
}
// js-docs-end varying-modal-content
// -------------------------------
// Offcanvas
// -------------------------------
// 'Offcanvas components' example in docs only
const myOffcanvas = document.querySelectorAll('.bd-example-offcanvas .offcanvas')
if (myOffcanvas) {
myOffcanvas.forEach(offcanvas => {
offcanvas.addEventListener('show.bs.offcanvas', event => {
event.preventDefault()
}, false)
})
}
}
+7 -17
View File
@@ -2,31 +2,21 @@
// IT'S ALL JUST JUNK FOR OUR DOCS!
// ++++++++++++++++++++++++++++++++++++++++++
/*!
* JavaScript for Bootstrap's docs (https://getbootstrap.com/)
* Copyright 2024 The Bootstrap Authors
* Licensed under the Creative Commons Attribution 3.0 Unported License.
* For details, see https://creativecommons.org/licenses/by/3.0/.
*/
import docsearch from '@docsearch/js'
// https://gohugo.io/hugo-pipes/js/#options
// eslint-disable-next-line import/no-unresolved
import { appId, apiKey, indexName } from '@params';
(() => {
'use strict'
const searchElement = document.getElementById('docsearch')
if (!searchElement) {
if (!window.docsearch || !searchElement) {
return
}
const siteDocsVersion = searchElement.getAttribute('data-bd-docs-version')
docsearch({
apiKey,
indexName,
appId,
window.docsearch({
apiKey: '3151f502c7b9e9dafd5e6372b691a24e',
indexName: 'bootstrap',
appId: 'AK7KMZKZHQ',
container: searchElement,
searchParameters: {
facetFilters: [`version:${siteDocsVersion}`]
+156 -7
View File
@@ -1,15 +1,164 @@
/*
// NOTICE!!! Initially embedded in our docs this JavaScript
// file contains elements that can help you create reproducible
// use cases in StackBlitz for instance.
// In a real project please adapt this content to your needs.
// ++++++++++++++++++++++++++++++++++++++++++
/*!
* JavaScript for Bootstrap's docs (https://getbootstrap.com/)
* Copyright 2011-2024 The Bootstrap Authors
* Licensed under the Creative Commons Attribution 3.0 Unported License.
* For details, see https://creativecommons.org/licenses/by/3.0/.
*/
// Note that this file is not published; we only include it in scripts.html
// for StackBlitz to work
/* global bootstrap: false */
/* eslint-disable import/no-unresolved */
import snippets from 'js/partials/snippets.js'
/* eslint-enable import/no-unresolved */
(() => {
'use strict'
snippets()
// --------
// Tooltips
// --------
// Instantiate all tooltips in a docs or StackBlitz
for (const tooltip of document.querySelectorAll('[data-bs-toggle="tooltip"]')) {
new bootstrap.Tooltip(tooltip)
}
// --------
// Popovers
// --------
// Instantiate all popovers in docs or StackBlitz
for (const popover of document.querySelectorAll('[data-bs-toggle="popover"]')) {
new bootstrap.Popover(popover)
}
// -------------------------------
// Toasts
// -------------------------------
// Used by 'Placement' example in docs or StackBlitz
const toastPlacement = document.getElementById('toastPlacement')
if (toastPlacement) {
document.getElementById('selectToastPlacement').addEventListener('change', function () {
if (!toastPlacement.dataset.originalClass) {
toastPlacement.dataset.originalClass = toastPlacement.className
}
toastPlacement.className = `${toastPlacement.dataset.originalClass} ${this.value}`
})
}
// Instantiate all toasts in docs pages only
for (const toastEl of document.querySelectorAll('.bd-example .toast')) {
const toast = new bootstrap.Toast(toastEl, {
autohide: false
})
toast.show()
}
// Instantiate all toasts in docs pages only
// js-docs-start live-toast
const toastTrigger = document.getElementById('liveToastBtn')
const toastLiveExample = document.getElementById('liveToast')
if (toastTrigger) {
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample)
toastTrigger.addEventListener('click', () => {
toastBootstrap.show()
})
}
// js-docs-end live-toast
// -------------------------------
// Alerts
// -------------------------------
// Used in 'Show live alert' example in docs or StackBlitz
// js-docs-start live-alert
const alertPlaceholder = document.getElementById('liveAlertPlaceholder')
const appendAlert = (message, type) => {
const wrapper = document.createElement('div')
wrapper.innerHTML = [
`<div class="alert alert-${type} alert-dismissible" role="alert">`,
` <div>${message}</div>`,
' <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>',
'</div>'
].join('')
alertPlaceholder.append(wrapper)
}
const alertTrigger = document.getElementById('liveAlertBtn')
if (alertTrigger) {
alertTrigger.addEventListener('click', () => {
appendAlert('Nice, you triggered this alert message!', 'success')
})
}
// js-docs-end live-alert
// --------
// Carousels
// --------
// Instantiate all non-autoplaying carousels in docs or StackBlitz
for (const carousel of document.querySelectorAll('.carousel:not([data-bs-ride="carousel"])')) {
bootstrap.Carousel.getOrCreateInstance(carousel)
}
// -------------------------------
// Checks & Radios
// -------------------------------
// Indeterminate checkbox example in docs and StackBlitz
for (const checkbox of document.querySelectorAll('.bd-example-indeterminate [type="checkbox"]')) {
if (checkbox.id.includes('Indeterminate')) {
checkbox.indeterminate = true
}
}
// -------------------------------
// Links
// -------------------------------
// Disable empty links in docs examples only
for (const link of document.querySelectorAll('.bd-content [href="#"]')) {
link.addEventListener('click', event => {
event.preventDefault()
})
}
// -------------------------------
// Modal
// -------------------------------
// Modal 'Varying modal content' example in docs and StackBlitz
// js-docs-start varying-modal-content
const exampleModal = document.getElementById('exampleModal')
if (exampleModal) {
exampleModal.addEventListener('show.bs.modal', event => {
// Button that triggered the modal
const button = event.relatedTarget
// Extract info from data-bs-* attributes
const recipient = button.getAttribute('data-bs-whatever')
// If necessary, you could initiate an Ajax request here
// and then do the updating in a callback.
// Update the modal's content.
const modalTitle = exampleModal.querySelector('.modal-title')
const modalBodyInput = exampleModal.querySelector('.modal-body input')
modalTitle.textContent = `New message to ${recipient}`
modalBodyInput.value = recipient
})
}
// js-docs-end varying-modal-content
// -------------------------------
// Offcanvas
// -------------------------------
// 'Offcanvas components' example in docs only
const myOffcanvas = document.querySelectorAll('.bd-example-offcanvas .offcanvas')
if (myOffcanvas) {
for (const offcanvas of myOffcanvas) {
offcanvas.addEventListener('show.bs.offcanvas', event => {
event.preventDefault()
}, false)
}
}
})()
-66
View File
@@ -1,66 +0,0 @@
// NOTICE!!! Initially embedded in our docs this JavaScript
// file contains elements that can help you create reproducible
// use cases in StackBlitz for instance.
// In a real project please adapt this content to your needs.
// ++++++++++++++++++++++++++++++++++++++++++
/*!
* JavaScript for Bootstrap's docs (https://getbootstrap.com/)
* Copyright 2024 The Bootstrap Authors
* Licensed under the Creative Commons Attribution 3.0 Unported License.
* For details, see https://creativecommons.org/licenses/by/3.0/.
*/
import sdk from '@stackblitz/sdk'
// https://gohugo.io/hugo-pipes/js/#options
import {
cssCdn, docsVersion, jsBundleCdn, jsSnippetFile
} from '@params' // eslint-disable-line import/no-unresolved
// Open in StackBlitz logic
document.querySelectorAll('.btn-edit').forEach(btn => {
btn.addEventListener('click', event => {
const codeSnippet = event.target.closest('.bd-code-snippet')
const exampleEl = codeSnippet.querySelector('.bd-example')
const htmlSnippet = exampleEl.innerHTML
const jsSnippet = codeSnippet.querySelector('.btn-edit').getAttribute('data-sb-js-snippet')
// Get extra classes for this example
const classes = Array.from(exampleEl.classList).join(' ')
openBootstrapSnippet(htmlSnippet, jsSnippet, classes)
})
})
const openBootstrapSnippet = (htmlSnippet, jsSnippet, classes) => {
const indexHtml = `<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="${cssCdn}" rel="stylesheet">
<link href="https://getbootstrap.com/docs/${docsVersion}/assets/css/docs.css" rel="stylesheet">
<title>Bootstrap Example</title>
<${'script'} defer src="${jsBundleCdn}"></${'script'}>
</head>
<body class="p-3 m-0 border-0 ${classes}">
<!-- Example Code Start-->
${htmlSnippet.trimStart().replace(/^/gm, ' ').replace(/^ {4}$/gm, '').trimEnd()}
<!-- Example Code End -->
</body>
</html>
`
const project = {
files: {
'index.html': indexHtml,
...(jsSnippet && { 'index.js': jsSnippetFile })
},
title: 'Bootstrap Example',
description: `Official example from ${window.location.href}`,
template: jsSnippet ? 'javascript' : 'html',
tags: ['bootstrap']
}
sdk.openProject(project, { openFile: 'index.html' })
}
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -23,7 +23,7 @@
padding: .5em;
line-height: 1;
color: var(--bs-body-color);
background-color: transparent;
background-color: var(--bd-pre-bg);
border: 0;
@include border-radius(.25rem);
+14 -16
View File
@@ -12,18 +12,6 @@
margin-left: 0;
border-width: 1px;
@include border-radius(var(--bs-border-radius));
> :first-child {
@include border-top-radius(calc(var(--bs-border-radius) - 1px));
}
> :last-child {
@include border-bottom-radius(calc(var(--bs-border-radius) - 1px));
}
}
> :not(:first-child) {
border-top: 1px solid var(--bs-border-color);
}
}
@@ -43,10 +31,7 @@
margin-right: 0;
margin-left: 0;
border-width: 1px;
&:not(:first-child) {
@include border-radius(var(--bs-border-radius));
}
@include border-radius(var(--bs-border-radius));
}
+ p {
@@ -368,6 +353,7 @@
@include media-breakpoint-up(md) {
padding: .75rem 1.25rem;
@include border-radius(calc(var(--bs-border-radius) - 1px));
}
@include media-breakpoint-up(lg) {
@@ -399,6 +385,18 @@
.highlight-toolbar {
background-color: var(--bd-pre-bg);
+ .highlight {
@include border-top-radius(0);
}
}
.bd-file-ref {
.highlight-toolbar {
@include media-breakpoint-up(md) {
@include border-top-radius(calc(var(--bs-border-radius) - 1px));
}
}
}
.bd-content .bd-code-snippet {
+2 -1
View File
@@ -73,8 +73,9 @@
}
// Prevent breaking of code
// stylelint-disable-next-line selector-max-compound-selectors
th,
td:first-child > code { // stylelint-disable-line selector-max-compound-selectors
td:first-child > code {
white-space: nowrap;
}
}
+3 -22
View File
@@ -21,37 +21,19 @@
}
.bd-code-snippet {
--bs-border-radius: .5rem;
position: relative;
margin: 0;
border-color: var(--bs-border-color-translucent);
border-width: 1px;
@include border-radius(.5rem);
}
.highlight-toolbar {
padding: 0 !important; // stylelint-disable-line declaration-no-important
> :first-child {
display: none;
}
.btn-clipboard {
position: absolute;
top: 50%;
right: .75rem;
z-index: 1;
transform: translateY(-50%);
}
}
.highlight-toolbar + .highlight {
.highlight {
width: 100%;
padding: .5rem 1rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
background-color: rgba(var(--bs-body-color-rgb), .075);
border: 0;
@include border-radius(calc(.5rem - 1px));
@include media-breakpoint-up(lg) {
@@ -64,7 +46,6 @@
overflow: hidden;
}
}
.btn-clipboard {
position: absolute;
top: -.625rem;
+1
View File
@@ -36,6 +36,7 @@ $enable-cssgrid: true;
// Load docs components
@import "variables";
@import "navbar";
@import "search";
@import "masthead";
@import "ads";
@import "content";
-14
View File
@@ -1,14 +0,0 @@
/*!
* Bootstrap Docs (https://getbootstrap.com/)
* Copyright 2024 The Bootstrap Authors
* Licensed under the Creative Commons Attribution 3.0 Unported License.
* For details, see https://creativecommons.org/licenses/by/3.0/.
*/
@import "../../../scss/functions";
@import "../../../scss/variables";
@import "../../../scss/mixins";
@import "variables";
@import "@docsearch/css/dist/style";
@import "search";
+1 -2
View File
@@ -4,8 +4,7 @@ layout: 404
description: ""
url: /404.html
robots: noindex,follow
sitemap:
disable: true
sitemap_exclude: true
---
<div class="text-center py-5">
+1 -2
View File
@@ -1,6 +1,5 @@
---
layout: redirect
sitemap:
disable: true
sitemap_exclude: true
redirect: "/docs/5.3/getting-started/introduction/"
---
+4 -4
View File
@@ -38,7 +38,7 @@ Click the button below to show an alert (hidden with inline styles to start), th
We use the following JavaScript to trigger our live alert demo:
{{< js-docs name="live-alert" file="site/assets/js/partials/snippets.js" >}}
{{< js-docs name="live-alert" file="site/assets/js/snippets.js" >}}
### Link color
@@ -72,7 +72,7 @@ Similarly, you can use [flexbox utilities]({{< docsref "/utilities/flex" >}}) an
{{< example >}}
<div class="alert alert-primary d-flex align-items-center" role="alert">
<svg xmlns="http://www.w3.org/2000/svg" class="bi flex-shrink-0 me-2" viewBox="0 0 16 16" role="img" aria-label="Warning:">
<svg xmlns="http://www.w3.org/2000/svg" class="bi bi-exclamation-triangle-fill flex-shrink-0 me-2" viewBox="0 0 16 16" role="img" aria-label="Warning:">
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
</svg>
<div>
@@ -215,8 +215,8 @@ This makes an alert listen for click events on descendant elements which have th
Basic usage:
```js
const alert = bootstrap.Alert.getOrCreateInstance('#myAlert')
alert.close()
const myAlert = bootstrap.Alert.getOrCreateInstance('#myAlert')
myAlert.close()
```
### Events
@@ -195,6 +195,8 @@ Make a set of buttons appear vertically stacked rather than horizontally. **Spli
{{< example >}}
<div class="btn-group-vertical" role="group" aria-label="Vertical button group">
<button type="button" class="btn btn-primary">Button</button>
<button type="button" class="btn btn-primary">Button</button>
<div class="btn-group" role="group">
<button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
@@ -204,8 +206,6 @@ Make a set of buttons appear vertically stacked rather than horizontally. **Spli
<li><a class="dropdown-item" href="#">Dropdown link</a></li>
</ul>
</div>
<button type="button" class="btn btn-primary">Button</button>
<button type="button" class="btn btn-primary">Button</button>
<div class="btn-group dropstart" role="group">
<button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
+2 -2
View File
@@ -223,10 +223,10 @@ const bsButton = new bootstrap.Button('#myButton')
For example, to toggle all buttons
```js
document.querySelectorAll('.btn').forEach(buttonElement => {
for (const buttonElement of document.querySelectorAll('.btn')) {
const button = bootstrap.Button.getOrCreateInstance(buttonElement)
button.toggle()
})
}
```
## CSS
@@ -413,14 +413,14 @@ Enable tabbable list item via JavaScript (each list item needs to be activated i
```js
const triggerTabList = document.querySelectorAll('#myTab a')
triggerTabList.forEach(triggerEl => {
for (const triggerEl of triggerTabList) {
const tabTrigger = new bootstrap.Tab(triggerEl)
triggerEl.addEventListener('click', event => {
event.preventDefault()
tabTrigger.show()
})
})
}
```
You can activate individual list item in several ways:
@@ -491,10 +491,10 @@ If no tab was already active, then the `hide.bs.tab` and `hidden.bs.tab` events
```js
const tabElms = document.querySelectorAll('a[data-bs-toggle="list"]')
tabElms.forEach(tabElm => {
for (const tabElm of tabElms) {
tabElm.addEventListener('shown.bs.tab', event => {
event.target // newly activated tab
event.relatedTarget // previous active tab
})
})
}
```
+1 -1
View File
@@ -481,7 +481,7 @@ Below is a live demo followed by example HTML and JavaScript. For more informati
</div>
{{< /example >}}
{{< js-docs name="varying-modal-content" file="site/assets/js/partials/snippets.js" >}}
{{< js-docs name="varying-modal-content" file="site/assets/js/snippets.js" >}}
### Toggle between modals
+1 -1
View File
@@ -428,7 +428,7 @@ Navbar themes are easier than ever thanks to Bootstrap's combination of Sass and
<!-- Navbar content -->
</nav>
<nav class="navbar" style="background-color: #e3f2fd;" data-bs-theme="light">
<nav class="navbar" style="background-color: #e3f2fd;">
<!-- Navbar content -->
</nav>
```
@@ -613,14 +613,14 @@ Enable tabbable tabs via JavaScript (each tab needs to be activated individually
```js
const triggerTabList = document.querySelectorAll('#myTab button')
triggerTabList.forEach(triggerEl => {
for (const triggerEl of triggerTabList) {
const tabTrigger = new bootstrap.Tab(triggerEl)
triggerEl.addEventListener('click', event => {
event.preventDefault()
tabTrigger.show()
})
})
}
```
You can activate individual tabs in several ways:
+4 -4
View File
@@ -192,15 +192,15 @@ Note that for security reasons the `sanitize`, `sanitizeFn`, and `allowList` opt
| `delay` | number, object | `0` | Delay showing and hiding the popover (ms)—doesn't apply to manual trigger type. If a number is supplied, delay is applied to both hide/show. Object structure is: `delay: { "show": 500, "hide": 100 }`. |
| `fallbackPlacements` | string, array | `['top', 'right', 'bottom', 'left']` | Define fallback placements by providing a list of placements in array (in order of preference). For more information refer to Popper's [behavior docs](https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements). |
| `html` | boolean | `false` | Allow HTML in the popover. If true, HTML tags in the popover's `title` will be rendered in the popover. If false, `innerText` property will be used to insert content into the DOM. Use text if you're worried about XSS attacks. |
| `offset` | number, string, function | `[0, 8]` | Offset of the popover relative to its target. You can pass a string in data attributes with comma separated values like: `data-bs-offset="10,20"`. When a function is used to determine the offset, it is called with an object containing the popper placement, the reference, and popper rects as its first argument. The triggering element DOM node is passed as the second argument. The function must return an array with two numbers: [skidding](https://popper.js.org/docs/v2/modifiers/offset/#skidding-1), [distance](https://popper.js.org/docs/v2/modifiers/offset/#distance-1). For more information refer to Popper's [offset docs](https://popper.js.org/docs/v2/modifiers/offset/#options). |
| `placement` | string, function | `'right'` | How to position the popover: auto, top, bottom, left, right. When `auto` is specified, it will dynamically reorient the popover. When a function is used to determine the placement, it is called with the popover DOM node as its first argument and the triggering element DOM node as its second. The `this` context is set to the popover instance. |
| `offset` | number, string, function | `[0, 0]` | Offset of the popover relative to its target. You can pass a string in data attributes with comma separated values like: `data-bs-offset="10,20"`. When a function is used to determine the offset, it is called with an object containing the popper placement, the reference, and popper rects as its first argument. The triggering element DOM node is passed as the second argument. The function must return an array with two numbers: [skidding](https://popper.js.org/docs/v2/modifiers/offset/#skidding-1), [distance](https://popper.js.org/docs/v2/modifiers/offset/#distance-1). For more information refer to Popper's [offset docs](https://popper.js.org/docs/v2/modifiers/offset/#options). |
| `placement` | string, function | `'top'` | How to position the popover: auto, top, bottom, left, right. When `auto` is specified, it will dynamically reorient the popover. When a function is used to determine the placement, it is called with the popover DOM node as its first argument and the triggering element DOM node as its second. The `this` context is set to the popover instance. |
| `popperConfig` | null, object, function | `null` | To change Bootstrap's default Popper config, see [Popper's configuration](https://popper.js.org/docs/v2/constructors/#options). When a function is used to create the Popper configuration, it's called with an object that contains the Bootstrap's default Popper configuration. It helps you use and merge the default with your own configuration. The function must return a configuration object for Popper. |
| `sanitize` | boolean | `true` | Enable or disable the sanitization. If activated `'template'`, `'content'` and `'title'` options will be sanitized. |
| `sanitizeFn` | null, function | `null` | Here you can supply your own sanitize function. This can be useful if you prefer to use a dedicated library to perform sanitization. |
| `selector` | string, false | `false` | If a selector is provided, popover objects will be delegated to the specified targets. In practice, this is used to also apply popovers to dynamically added DOM elements (`jQuery.on` support). See [this issue]({{< param repo >}}/issues/4215) and [an informative example](https://codepen.io/Johann-S/pen/djJYPb). **Note**: `title` attribute must not be used as a selector. |
| `template` | string | `'<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'` | Base HTML to use when creating the popover. The popover's `title` will be injected into the `.popover-header`. The popover's `content` will be injected into the `.popover-body`. `.popover-arrow` will become the popover's arrow. The outermost wrapper element should have the `.popover` class and `role="tooltip"`. |
| `template` | string | `'<div class="popover" role="tooltip"><div class="popover-arrow"></div><div class="popover-inner"></div></div>'` | Base HTML to use when creating the popover. The popover's `title` will be injected into the `.popover-inner`. `.popover-arrow` will become the popover's arrow. The outermost wrapper element should have the `.popover` class and `role="tooltip"`. |
| `title` | string, element, function | `''` | The popover title. If a function is given, it will be called with its `this` reference set to the element that the popover is attached to. |
| `trigger` | string | `'click'` | How popover is triggered: click, hover, focus, manual. You may pass multiple triggers; separate them with a space. `'manual'` indicates that the popover will be triggered programmatically via the `.popover('show')`, `.popover('hide')` and `.popover('toggle')` methods; this value cannot be combined with any other trigger. `'hover'` on its own will result in popovers that cannot be triggered via the keyboard, and should only be used if alternative methods for conveying the same information for keyboard users is present. |
| `trigger` | string | `'hover focus'` | How popover is triggered: click, hover, focus, manual. You may pass multiple triggers; separate them with a space. `'manual'` indicates that the popover will be triggered programmatically via the `.popover('show')`, `.popover('hide')` and `.popover('toggle')` methods; this value cannot be combined with any other trigger. `'hover'` on its own will result in popovers that cannot be triggered via the keyboard, and should only be used if alternative methods for conveying the same information for keyboard users is present. |
{{< /bs-table >}}
{{< callout info >}}
@@ -333,13 +333,13 @@ Scrollspy is not limited to nav components and list groups, so it will work on a
Target elements that arent visible will be ignored and their corresponding nav items won't receive an `.active` class. Scrollspy instances initialized in a non-visible wrapper will ignore all target elements. Use the `refresh` method to check for observable elements once the wrapper becomes visible.
```js
document.querySelectorAll('#nav-tab>[data-bs-toggle="tab"]').forEach(el => {
for (const el of document.querySelectorAll('#nav-tab > [data-bs-toggle="tab"]')) {
el.addEventListener('shown.bs.tab', () => {
const target = el.getAttribute('data-bs-target')
const scrollElem = document.querySelector(`${target} [data-bs-spy="scroll"]`)
bootstrap.ScrollSpy.getOrCreateInstance(scrollElem).refresh()
})
})
}
```
## Usage
@@ -406,9 +406,9 @@ Here's an example using the refresh method:
```js
const dataSpyList = document.querySelectorAll('[data-bs-spy="scroll"]')
dataSpyList.forEach(dataSpyEl => {
for (const dataSpyEl of dataSpyList) {
bootstrap.ScrollSpy.getInstance(dataSpyEl).refresh()
})
}
```
### Events
+1 -1
View File
@@ -87,7 +87,7 @@ Click the button below to show a toast (positioned with our utilities in the low
We use the following JavaScript to trigger our live toast demo:
{{< js-docs name="live-toast" file="site/assets/js/partials/snippets.js" >}}
{{< js-docs name="live-toast" file="site/assets/js/snippets.js" >}}
### Translucent
+1 -1
View File
@@ -205,7 +205,7 @@ Note that for security reasons the `sanitize`, `sanitizeFn`, and `allowList` opt
| `delay` | number, object | `0` | Delay showing and hiding the tooltip (ms)—doesn't apply to manual trigger type. If a number is supplied, delay is applied to both hide/show. Object structure is: `delay: { "show": 500, "hide": 100 }`. |
| `fallbackPlacements` | array | `['top', 'right', 'bottom', 'left']` | Define fallback placements by providing a list of placements in array (in order of preference). For more information refer to Popper's [behavior docs](https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements). |
| `html` | boolean | `false` | Allow HTML in the tooltip. If true, HTML tags in the tooltip's `title` will be rendered in the tooltip. If false, `innerText` property will be used to insert content into the DOM. Use text if you're worried about XSS attacks. |
| `offset` | array, string, function | `[0, 6]` | Offset of the tooltip relative to its target. You can pass a string in data attributes with comma separated values like: `data-bs-offset="10,20"`. When a function is used to determine the offset, it is called with an object containing the popper placement, the reference, and popper rects as its first argument. The triggering element DOM node is passed as the second argument. The function must return an array with two numbers: [skidding](https://popper.js.org/docs/v2/modifiers/offset/#skidding-1), [distance](https://popper.js.org/docs/v2/modifiers/offset/#distance-1). For more information refer to Popper's [offset docs](https://popper.js.org/docs/v2/modifiers/offset/#options). |
| `offset` | array, string, function | `[0, 0]` | Offset of the tooltip relative to its target. You can pass a string in data attributes with comma separated values like: `data-bs-offset="10,20"`. When a function is used to determine the offset, it is called with an object containing the popper placement, the reference, and popper rects as its first argument. The triggering element DOM node is passed as the second argument. The function must return an array with two numbers: [skidding](https://popper.js.org/docs/v2/modifiers/offset/#skidding-1), [distance](https://popper.js.org/docs/v2/modifiers/offset/#distance-1). For more information refer to Popper's [offset docs](https://popper.js.org/docs/v2/modifiers/offset/#options). |
| `placement` | string, function | `'top'` | How to position the tooltip: auto, top, bottom, left, right. When `auto` is specified, it will dynamically reorient the tooltip. When a function is used to determine the placement, it is called with the tooltip DOM node as its first argument and the triggering element DOM node as its second. The `this` context is set to the tooltip instance. |
| `popperConfig` | null, object, function | `null` | To change Bootstrap's default Popper config, see [Popper's configuration](https://popper.js.org/docs/v2/constructors/#options). When a function is used to create the Popper configuration, it's called with an object that contains the Bootstrap's default Popper configuration. It helps you use and merge the default with your own configuration. The function must return a configuration object for Popper. |
| `sanitize` | boolean | `true` | Enable or disable the sanitization. If activated `'template'`, `'content'` and `'title'` options will be sanitized. |
+5 -26
View File
@@ -5,8 +5,7 @@ description: Examples of Bootstrap's documentation-specific components and style
aliases: "/docsref/"
toc: true
robots: noindex,follow
sitemap:
disable: true
sitemap_exclude: true
---
## Buttons
@@ -31,40 +30,20 @@ sitemap:
## Code example
<div class="bd-example">
<div class="test">This is a test using <code>.bd-example</code> directly.</div>
</div>
```scss
.test {
--color: blue;
}
```
```html
<div class="test">This is a triple backtick markup only test.</div>
```
{{< highlight html >}}
<div class="test">This is a highlight tag markup only test.</div>
{{< /highlight >}}
{{< example show_preview=false >}}
<div class="test">This is a markup only test.</div>
{{< /example >}}
{{< example show_markup=false >}}
<div class="test">This is a preview only test.</div>
{{< /example >}}
<div class="bd-example">
The <abbr title="HyperText Markup Language">HTML</abbr> abbreviation element.
</div>
{{< example >}}
<div class="test">This is a test.</div>
{{< /example >}}
{{< example class=bg-body-secondary >}}
<div class="test">This is a test with a custom background color.</div>
{{< /example >}}
{{< scss-docs name="variable-gradient" file="scss/_variables.scss" >}}
{{< js-docs name="live-toast" file="site/assets/js/partials/snippets.js" >}}
{{< js-docs name="live-toast" file="site/assets/js/snippets.js" >}}
+60
View File
@@ -4,3 +4,63 @@ title: Examples
description: Quickly get a project started with any of our examples ranging from using parts of the framework to custom components and layouts.
aliases: "/examples/"
---
{{< list-examples.inline >}}
{{ range $entry := $.Site.Data.examples -}}
<div class="bd-content">
<h2 id="{{ $entry.category | urlize }}">{{ $entry.category }}</h2>
<p>{{ $entry.description }}</p>
{{ if eq $entry.category "RTL" -}}
<div class="bd-callout bd-callout-warning small">
<p>
<strong>RTL is still experimental</strong> and will evolve with feedback. Spotted something or have an improvement to suggest?
</p>
<p><a href="{{ $.Site.Params.repo }}/issues/new/choose">Please open an issue.</a></p>
</div>
{{ end -}}
{{ range $i, $example := $entry.examples -}}
{{- $len := len $entry.examples -}}
{{ if (eq $i 0) }}<div class="row">{{ end }}
{{ if $entry.external }}
<div class="col-md-6 col-lg-4 mb-3 d-flex gap-3">
<svg class="bi fs-5 flex-shrink-0 mt-1"><use xlink:href="#box-seam"></use></svg>
<div>
<h3 class="h5 mb-1">
<a class="d-block link-offset-1" href="{{ $.Site.Params.github_org }}{{ $example.url }}/" target="_blank" rel="noopener">
{{ $example.name }}
</a>
</h3>
<p class="text-body-secondary">{{ $example.description }}</p>
<p>
{{- $indexPath := "index.html" -}}
{{- if $example.indexPath -}}
{{- $indexPath = $example.indexPath -}}
{{- end }}
<a class="icon-link small link-secondary link-offset-1" href="https://stackblitz.com/github/twbs{{ $example.url }}?file={{ $indexPath | urlquery }}" target="_blank" rel="noopener">
<svg class="bi flex-shrink-0"><use xlink:href="#lightning-charge-fill"></use></svg>
Edit in StackBlitz
</a>
</p>
</div>
</div>
{{ else }}
<div class="col-sm-6 col-md-3 mb-3">
<a class="d-block link-offset-1" href="/docs/{{ $.Site.Params.docs_version }}/examples/{{ $example.name | urlize }}/"{{ if in $example.name "RTL" }} hreflang="ar"{{ end }}>
<img class="img-thumbnail mb-3" srcset="/docs/{{ $.Site.Params.docs_version }}/assets/img/examples/{{ $example.name | urlize }}.png,
/docs/{{ $.Site.Params.docs_version }}/assets/img/examples/{{ $example.name | urlize }}@2x.png 2x"
src="/docs/{{ $.Site.Params.docs_version }}/assets/img/examples/{{ $example.name | urlize }}.png"
alt=""
width="480" height="300"
loading="lazy">
<h3 class="h5 mb-1">
{{ $example.name }}
</h3>
</a>
<p class="text-body-secondary">{{ $example.description }}</p>
</div>
{{ end }}
{{ if (eq (add $i 1) $len) }}</div>{{ end }}
{{ end -}}
</div>
{{ end -}}
{{< /list-examples.inline >}}
@@ -5,7 +5,6 @@ extra_css:
- "../cheatsheet/cheatsheet.rtl.css"
extra_js:
- src: "../cheatsheet/cheatsheet.js"
defer: true
body_class: "bg-body-tertiary"
direction: rtl
---
@@ -71,7 +70,7 @@ direction: rtl
</ul>
</nav>
</aside>
<main class="bd-cheatsheet container-fluid bg-body">
<div class="bd-cheatsheet container-fluid bg-body">
<section id="content">
<h2 class="sticky-xl-top fw-bold pt-3 pt-xl-5 pb-2 pb-xl-3">المحتوى</h2>
@@ -1538,7 +1537,7 @@ direction: rtl
</div>
</article>
</section>
</main>
</div>
<div class="modal fade" id="exampleModalDefault" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
@@ -4,34 +4,30 @@
'use strict'
// Tooltip and popover demos
document.querySelectorAll('.tooltip-demo')
.forEach(tooltip => {
new bootstrap.Tooltip(tooltip, {
selector: '[data-bs-toggle="tooltip"]'
})
for (const tooltip of document.querySelectorAll('.tooltip-demo')) {
new bootstrap.Tooltip(tooltip, {
selector: '[data-bs-toggle="tooltip"]'
})
}
for (const popover of document.querySelectorAll('[data-bs-toggle="popover"]')) {
new bootstrap.Popover(popover)
}
for (const toastEl of document.querySelectorAll('.toast')) {
const toast = new bootstrap.Toast(toastEl, {
autohide: false
})
document.querySelectorAll('[data-bs-toggle="popover"]')
.forEach(popover => {
new bootstrap.Popover(popover)
})
document.querySelectorAll('.toast')
.forEach(toastNode => {
const toast = new bootstrap.Toast(toastNode, {
autohide: false
})
toast.show()
})
toast.show()
}
// Disable empty links and submit buttons
document.querySelectorAll('[href="#"], [type="submit"]')
.forEach(link => {
link.addEventListener('click', event => {
event.preventDefault()
})
for (const link of document.querySelectorAll('[href="#"], [type="submit"]')) {
link.addEventListener('click', event => {
event.preventDefault()
})
}
function setActiveItem() {
const { hash } = window.location
@@ -5,7 +5,6 @@ extra_css:
- "cheatsheet.css"
extra_js:
- src: "cheatsheet.js"
defer: true
body_class: "bg-body-tertiary"
---
@@ -70,7 +69,7 @@ body_class: "bg-body-tertiary"
</ul>
</nav>
</aside>
<main class="bd-cheatsheet container-fluid bg-body">
<div class="bd-cheatsheet container-fluid bg-body">
<section id="content">
<h2 class="sticky-xl-top fw-bold pt-3 pt-xl-5 pb-2 pb-xl-3">Contents</h2>
@@ -1534,7 +1533,7 @@ body_class: "bg-body-tertiary"
</div>
</article>
</section>
</main>
</div>
<div class="modal fade" id="exampleModalDefault" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
@@ -6,7 +6,6 @@ extra_css:
- "../checkout/checkout.css"
extra_js:
- src: "../checkout/checkout.js"
defer: true
body_class: "bg-body-tertiary"
---
@@ -14,7 +13,7 @@ body_class: "bg-body-tertiary"
<main>
<div class="py-5 text-center">
<img class="d-block mx-auto mb-4" src="/docs/{{< param docs_version >}}/assets/brand/bootstrap-logo.svg" alt="" width="72" height="57">
<h1 class="h2">نموذج إتمام الشراء</h1>
<h2>نموذج إتمام الشراء</h2>
<p class="lead">فيما يلي مثال على نموذج تم إنشاؤه بالكامل باستخدام عناصر تحكم النموذج في Bootstrap. لكل مجموعة نماذج مطلوبة حالة تحقق يمكن تشغيلها بمحاولة إرسال النموذج دون استكماله.</p>
</div>
@@ -6,7 +6,7 @@
const forms = document.querySelectorAll('.needs-validation')
// Loop over them and prevent submission
Array.from(forms).forEach(form => {
for (const form of forms) {
form.addEventListener('submit', event => {
if (!form.checkValidity()) {
event.preventDefault()
@@ -15,5 +15,5 @@
form.classList.add('was-validated')
}, false)
})
}
})()
@@ -5,7 +5,6 @@ extra_css:
- "checkout.css"
extra_js:
- src: "checkout.js"
defer: true
body_class: "bg-body-tertiary"
---
@@ -13,7 +12,7 @@ body_class: "bg-body-tertiary"
<main>
<div class="py-5 text-center">
<img class="d-block mx-auto mb-4" src="/docs/{{< param docs_version >}}/assets/brand/bootstrap-logo.svg" alt="" width="72" height="57">
<h1 class="h2">Checkout form</h1>
<h2>Checkout form</h2>
<p class="lead">Below is an example form built entirely with Bootstraps form controls. Each required form group has a validation state that can be triggered by attempting to submit the form without completing it.</p>
</div>
@@ -7,9 +7,7 @@ extra_css:
extra_js:
- src: "https://cdn.jsdelivr.net/npm/chart.js@4.3.2/dist/chart.umd.js"
integrity: "sha384-eI7PSr3L1XLISH8JdDII5YN/njoSsxfbrkCTnJrzXt+ENP5MOVBxD+l6sEG4zoLp"
defer: true
- src: "dashboard.js"
defer: true
---
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
@@ -6,9 +6,7 @@ extra_css:
extra_js:
- src: "https://cdn.jsdelivr.net/npm/chart.js@4.3.2/dist/chart.umd.js"
integrity: "sha384-eI7PSr3L1XLISH8JdDII5YN/njoSsxfbrkCTnJrzXt+ENP5MOVBxD+l6sEG4zoLp"
defer: true
- src: "dashboard.js"
defer: true
---
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
@@ -208,7 +208,7 @@ body_class: ""
<div class="d-grid gap-1">
<div class="cal">
<div class="cal-month">
<button class="btn cal-btn" type="button" aria-label="previous month">
<button class="btn cal-btn" type="button">
<svg class="bi" width="16" height="16"><use xlink:href="#arrow-left-short"/></svg>
</button>
<strong class="cal-month-name">June</strong>
@@ -226,7 +226,7 @@ body_class: ""
<option value="November">November</option>
<option value="December">December</option>
</select>
<button class="btn cal-btn" type="button" aria-label="next month">
<button class="btn cal-btn" type="button">
<svg class="bi" width="16" height="16"><use xlink:href="#arrow-right-short"/></svg>
</button>
</div>
@@ -287,7 +287,7 @@ body_class: ""
<div class="d-grid gap-1">
<div class="cal">
<div class="cal-month">
<button class="btn cal-btn" type="button" aria-label="previous month">
<button class="btn cal-btn" type="button">
<svg class="bi" width="16" height="16"><use xlink:href="#arrow-left-short"/></svg>
</button>
<strong class="cal-month-name">June</strong>
@@ -305,7 +305,7 @@ body_class: ""
<option value="November">November</option>
<option value="December">December</option>
</select>
<button class="btn cal-btn" type="button" aria-label="next month">
<button class="btn cal-btn" type="button">
<svg class="bi" width="16" height="16"><use xlink:href="#arrow-right-short"/></svg>
</button>
</div>
@@ -167,7 +167,7 @@ body_class: ""
<p>Monthly digest of what's new and exciting from us.</p>
<div class="d-flex flex-column flex-sm-row w-100 gap-2">
<label for="newsletter1" class="visually-hidden">Email address</label>
<input id="newsletter1" type="email" class="form-control" placeholder="Email address">
<input id="newsletter1" type="text" class="form-control" placeholder="Email address">
<button class="btn btn-primary" type="button">Subscribe</button>
</div>
</form>
@@ -34,7 +34,7 @@ body_class: ""
</svg>
<div class="modal modal-sheet position-static d-block bg-body-secondary p-4 py-md-5" tabindex="-1" role="dialog" id="modalSheet">
<div class="modal-dialog">
<div class="modal-dialog" role="document">
<div class="modal-content rounded-4 shadow">
<div class="modal-header border-bottom-0">
<h1 class="modal-title fs-5">Modal title</h1>
@@ -54,7 +54,7 @@ body_class: ""
<div class="b-example-divider"></div>
<div class="modal modal-sheet position-static d-block bg-body-secondary p-4 py-md-5" tabindex="-1" role="dialog" id="modalChoice">
<div class="modal-dialog">
<div class="modal-dialog" role="document">
<div class="modal-content rounded-3 shadow">
<div class="modal-body p-4 text-center">
<h5 class="mb-0">Enable this setting?</h5>
@@ -71,7 +71,7 @@ body_class: ""
<div class="b-example-divider"></div>
<div class="modal modal-sheet position-static d-block bg-body-secondary p-4 py-md-5" tabindex="-1" role="dialog" id="modalTour">
<div class="modal-dialog">
<div class="modal-dialog" role="document">
<div class="modal-content rounded-4 shadow">
<div class="modal-body p-5">
<h2 class="fw-bold mb-0">What's new</h2>
@@ -108,7 +108,7 @@ body_class: ""
<div class="b-example-divider"></div>
<div class="modal modal-sheet position-static d-block bg-body-secondary p-4 py-md-5" tabindex="-1" role="dialog" id="modalSignin">
<div class="modal-dialog">
<div class="modal-dialog" role="document">
<div class="modal-content rounded-4 shadow">
<div class="modal-header p-5 pb-4 border-bottom-0">
<h1 class="fw-bold mb-0 fs-2">Sign up for free</h1>
@@ -5,7 +5,6 @@ extra_css:
- "offcanvas-navbar.css"
extra_js:
- src: "offcanvas-navbar.js"
defer: true
body_class: "bg-body-tertiary"
aliases: "/docs/5.3/examples/offcanvas/"
---
@@ -5,7 +5,6 @@ extra_css:
- "sidebars.css"
extra_js:
- src: "sidebars.js"
defer: true
body_class: ""
---
@@ -1,8 +1,8 @@
/* global bootstrap: false */
(() => {
'use strict'
const tooltipTriggerList = Array.from(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
tooltipTriggerList.forEach(tooltipTriggerEl => {
const tooltipTriggerList = [...document.querySelectorAll('[data-bs-toggle="tooltip"]')]
for (const tooltipTriggerEl of tooltipTriggerList) {
new bootstrap.Tooltip(tooltipTriggerEl)
})
}
})()
@@ -32,7 +32,7 @@ Get started by including Bootstrap's production-ready CSS and JavaScript via CDN
</html>
```
2. **Include Bootstrap's CSS and JS.** Place the `<link>` tag in the `<head>` for our CSS, and the `<script>` tag for our JavaScript bundle (including Popper for positioning dropdowns, popovers, and tooltips) before the closing `</body>`. Learn more about our [CDN links](#cdn-links).
2. **Include Bootstrap's CSS and JS.** Place the `<link>` tag in the `<head>` for our CSS, and the `<script>` tag for our JavaScript bundle (including Popper for positioning dropdowns, poppers, and tooltips) before the closing `</body>`. Learn more about our [CDN links](#cdn-links).
```html
<!doctype html>
@@ -83,7 +83,6 @@ You can also use the CDN to fetch any of our [additional builds listed in the Co
Curious which components explicitly require our JavaScript and Popper? If you're at all unsure about the general page structure, keep reading for an example page template.
- Accordions for extending our Collapse plugin
- Alerts for dismissing
- Buttons for toggling states and checkbox/radio functionality
- Carousel for all slide behaviors, controls, and indicators
@@ -39,8 +39,9 @@ We provide a version of Bootstrap built as `ESM` (`bootstrap.esm.js` and `bootst
<script type="module">
import { Toast } from 'bootstrap.esm.min.js'
Array.from(document.querySelectorAll('.toast'))
.forEach(toastNode => new Toast(toastNode))
for (const toastEl of document.querySelectorAll('.toast')) {
new Toast(toastEl))
}
</script>
```
@@ -159,7 +160,7 @@ In addition to the `getInstance` and `getOrCreateInstance` methods, all plugin c
const modal = new bootstrap.Modal('#myModal')
const dropdown = new bootstrap.Dropdown('[data-bs-toggle="dropdown"]')
const offcanvas = bootstrap.Offcanvas.getInstance('#myOffcanvas')
const alert = bootstrap.Alert.getOrCreateInstance('#myAlert')
const myAlert = bootstrap.Alert.getOrCreateInstance('#myAlert')
```
### Asynchronous functions and transitions
@@ -7,7 +7,7 @@ toc: true
thumbnail: guides/bootstrap-parcel@2x.png
---
<img class="d-block mx-auto mb-4 img-fluid rounded-3" srcset="/docs/{{< param docs_version >}}/assets/img/guides/bootstrap-parcel.png, /docs/{{< param docs_version >}}/assets/img/guides/bootstrap-parcel@2x.png 2x" src="/docs/{{< param docs_version >}}/assets/img/guides/bootstrap-parcel.png" width="800" height="400" alt="">
<img class="mb-4 img-fluid rounded-3" srcset="/docs/{{< param docs_version >}}/assets/img/guides/bootstrap-parcel.png, /docs/{{< param docs_version >}}/assets/img/guides/bootstrap-parcel@2x.png 2x" src="/docs/{{< param docs_version >}}/assets/img/guides/bootstrap-parcel.png" width="2000" height="1000" alt="">
{{< callout >}}
**Want to skip to the end?** Download the source code and working demo for this guide from the [twbs/examples repository](https://github.com/twbs/examples/tree/main/parcel). You can also [open the example in StackBlitz](https://stackblitz.com/github/twbs/examples/tree/main/parcel?file=index.html) but not run it because Parcel isn't currently supported there.
@@ -111,7 +111,7 @@ With dependencies installed and our project folder ready for us to start coding,
npm start
```
![Parcel dev server running](/assets/img/guides/parcel-dev-server.png)
<img class="img-fluid" src="/docs/{{< param docs_version >}}/assets/img/guides/parcel-dev-server.png" alt="Parcel dev server running">
In the next and final section to this guide, we'll import all of Bootstrap's CSS and JavaScript.
@@ -150,7 +150,7 @@ Importing Bootstrap into Parcel requires two imports, one into our `styles.scss`
3. **And you're done! 🎉** With Bootstrap's source Sass and JS fully loaded, your local development server should now look like this:
![Parcel dev server running with Bootstrap](/assets/img/guides/parcel-dev-server-bootstrap.png)
<img class="img-fluid" src="/docs/{{< param docs_version >}}/assets/img/guides/parcel-dev-server-bootstrap.png" alt="Parcel dev server running with Bootstrap">
Now you can start adding any Bootstrap components you want to use. Be sure to [check out the complete Parcel example project](https://github.com/twbs/examples/tree/main/parcel) for how to include additional custom Sass and optimize your build by importing only the parts of Bootstrap's CSS and JS that you need.
@@ -168,16 +168,6 @@ After running Sass then RTLCSS, each selector in your CSS files will be prepende
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 >}}
Do you want to automate this process and address several edge cases involving both directions within a single stylesheet? Then, consider using [PostCSS RTLCSS](https://github.com/elchininet/postcss-rtlcss) as a [PostCSS](https://github.com/postcss/postcss) plugin to process your source files. PostCSS RTLCSS uses [RTLCSS](https://rtlcss.com) behind the scenes to manage the direction flipping process, but it separates the flipped declarations into rules with a different prefix for LTR and RTL, something that allows you to have both directions within the same stylesheet file. By doing this, you can switch between LTR and RTL orientations by simply changing the `dir` of the page (or even by modifying a specific class if you configure the plugin accordingly).
{{< callout warning >}}
**Important things to take into account** when using PostCSS RTLCSS to build a combined LTR and RTL implementation:
1. It is recommended that you add the `dir` attribute to the `html` element. This way, the entire page will be affected when you change the direction. Also, make sure you add the `lang` attribute accordingly.
2. Having a single bundle with both directions will increase the size of the final stylesheet (on average, by 20%-30%): consider some [optimization]({{< docsref "/customize/optimize" >}}).
3. Take into account that PostCSS RTLCSS is not compatible with `/* rtl:remove */` directives because it doesn't remove any CSS rule. You should replace your `/* rtl:remove */`, `/* rtl:begin:remove */` and `/* rtl:end:remove */` directives with `/* rtl:ignore */`, `/* rtl:begin:ignore */` and `/* rtl:end:ignore */` directives respectively. These directives will ignore the rule and will not create an RTL counterpart (same result as the `remove` ones in RTLCSS).
{{< /callout >}}
## The breadcrumb case
The [breadcrumb separator]({{< docsref "/components/breadcrumb#dividers" >}}) is the only case requiring its own brand-new variable— namely `$breadcrumb-divider-flipped` —defaulting to `$breadcrumb-divider`.
@@ -10,7 +10,7 @@ added:
version: "5.2"
---
<img class="d-block mx-auto mb-4 img-fluid rounded-3" srcset="/docs/{{< param docs_version >}}/assets/img/guides/bootstrap-vite.png, /docs/{{< param docs_version >}}/assets/img/guides/bootstrap-vite@2x.png 2x" src="/docs/{{< param docs_version >}}/assets/img/guides/bootstrap-vite.png" width="800" height="400" alt="">
<img class="mb-4 img-fluid rounded-3" srcset="/docs/{{< param docs_version >}}/assets/img/guides/bootstrap-vite.png, /docs/{{< param docs_version >}}/assets/img/guides/bootstrap-vite@2x.png 2x" src="/docs/{{< param docs_version >}}/assets/img/guides/bootstrap-vite.png" width="2000" height="1000" alt="">
{{< callout >}}
**Want to skip to the end?** Download the source code and working demo for this guide from the [twbs/examples repository](https://github.com/twbs/examples/tree/main/vite). You can also [open the example in StackBlitz](https://stackblitz.com/github/twbs/examples/tree/main/vite?file=index.html) for live editing.
@@ -135,7 +135,7 @@ With dependencies installed and our project folder ready for us to start coding,
npm start
```
![Vite dev server running](/assets/img/guides/vite-dev-server.png)
<img class="img-fluid" src="/docs/{{< param docs_version >}}/assets/img/guides/vite-dev-server.png" alt="Vite dev server running">
In the next and final section to this guide, well import all of Bootstraps CSS and JavaScript.
@@ -175,7 +175,7 @@ In the next and final section to this guide, well import all of Bootstraps
3. **And you're done! 🎉** With Bootstrap's source Sass and JS fully loaded, your local development server should now look like this:
![Vite dev server running with Bootstrap](/assets/img/guides/vite-dev-server-bootstrap.png)
<img class="img-fluid" src="/docs/{{< param docs_version >}}/assets/img/guides/vite-dev-server-bootstrap.png" alt="Vite dev server running with Bootstrap">
Now you can start adding any Bootstrap components you want to use. Be sure to [check out the complete Vite example project](https://github.com/twbs/examples/tree/main/vite) for how to include additional custom Sass and optimize your build by importing only the parts of Bootstrap's CSS and JS that you need.
@@ -7,7 +7,7 @@ toc: true
thumbnail: guides/bootstrap-webpack@2x.png
---
<img class="d-block mx-auto mb-4 img-fluid rounded-3" srcset="/docs/{{< param docs_version >}}/assets/img/guides/bootstrap-webpack.png, /docs/{{< param docs_version >}}/assets/img/guides/bootstrap-webpack@2x.png 2x" src="/docs/{{< param docs_version >}}/assets/img/guides/bootstrap-webpack.png" width="800" height="400" alt="">
<img class="mb-4 img-fluid rounded-3" srcset="/docs/{{< param docs_version >}}/assets/img/guides/bootstrap-webpack.png, /docs/{{< param docs_version >}}/assets/img/guides/bootstrap-webpack@2x.png 2x" src="/docs/{{< param docs_version >}}/assets/img/guides/bootstrap-webpack.png" width="2000" height="1000" alt="">
{{< callout >}}
**Want to skip to the end?** Download the source code and working demo for this guide from the [twbs/examples repository](https://github.com/twbs/examples/tree/main/webpack). You can also [open the example in StackBlitz](https://stackblitz.com/github/twbs/examples/tree/main/webpack?file=index.html) for live editing.
@@ -79,7 +79,7 @@ With dependencies installed and our project folder ready for us to start coding,
```js
'use strict'
const path = require('path')
const path = require('node:path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
@@ -141,7 +141,7 @@ With dependencies installed and our project folder ready for us to start coding,
npm start
```
![Webpack dev server running](/assets/img/guides/webpack-dev-server.png)
<img class="img-fluid" src="/docs/{{< param docs_version >}}/assets/img/guides/webpack-dev-server.png" alt="Webpack dev server running">
In the next and final section to this guide, we'll set up the Webpack loaders and import all of Bootstrap's CSS and JavaScript.
@@ -154,7 +154,7 @@ Importing Bootstrap into Webpack requires the loaders we installed in the first
```js
'use strict'
const path = require('path')
const path = require('node:path')
const autoprefixer = require('autoprefixer')
const HtmlWebpackPlugin = require('html-webpack-plugin')
@@ -244,7 +244,7 @@ Importing Bootstrap into Webpack requires the loaders we installed in the first
4. **And you're done! 🎉** With Bootstrap's source Sass and JS fully loaded, your local development server should now look like this:
![Webpack dev server running with Bootstrap](/assets/img/guides/webpack-dev-server-bootstrap.png)
<img class="img-fluid" src="/docs/{{< param docs_version >}}/assets/img/guides/webpack-dev-server-bootstrap.png" alt="Webpack dev server running with Bootstrap">
Now you can start adding any Bootstrap components you want to use. Be sure to [check out the complete Webpack example project](https://github.com/twbs/examples/tree/main/webpack) for how to include additional custom Sass and optimize your build by importing only the parts of Bootstrap's CSS and JS that you need.
+1 -1
View File
@@ -58,7 +58,7 @@ Note that [breaking words isn't possible in Arabic](https://rtlstyling.com/posts
## Text transform
Transform text in components with our text capitalization classes: `text-lowercase`, `text-uppercase` or `text-capitalize`.
Transform text in components with text capitalization classes.
{{< example >}}
<p class="text-lowercase">Lowercased text.</p>
+1 -2
View File
@@ -1,6 +1,5 @@
---
layout: redirect
sitemap:
disable: true
sitemap_exclude: true
redirect: "/docs/5.3/getting-started/introduction/"
---
+1 -1
View File
@@ -13,7 +13,7 @@ description: An appendix of hosted documentation for nearly every release of Boo
{{- range $i, $version := $versions }}
{{- $len := len $versions -}}
{{ if (eq $i 0) }}<div class="list-group">{{ end }}
<a class="list-group-item list-group-item-action py-2 text-primary{{ if (eq $version $.Site.Params.docs_version) }} d-flex justify-content-between align-items-center{{ end }}" href="{{ urls.JoinPath $release.baseurl $version "/" }}">
<a class="list-group-item list-group-item-action py-2 text-primary{{ if (eq $version $.Site.Params.docs_version) }} d-flex justify-content-between align-items-center{{ end }}" href="{{ $release.baseurl }}/{{ $version }}/">
{{ $version }}
{{ if (eq $version $.Site.Params.docs_version) -}}
<span class="badge text-bg-primary">Latest</span>
+1 -1
View File
@@ -18,7 +18,7 @@ more:
- name: Dripicons
website: http://demo.amitjakhu.com/dripicons/
- name: Ikons
website: https://ikons.piotrkwiatkowski.co.uk/
website: http://ikons.piotrkwiatkowski.co.uk/
- name: Icons8
website: https://icons8.com/
- name: icofont
@@ -1,8 +0,0 @@
{{- $originalSrc := .Destination | safeURL -}}
{{- $localImgPath := path.Join "/site/static/docs" site.Params.docs_version $originalSrc -}}
{{- /* This shouldn't be needed but we have a weird folder structure with version included... */ -}}
{{- $src := urls.JoinPath "/docs" site.Params.docs_version $originalSrc -}}
{{- $config := imageConfig $localImgPath -}}
{{- $classes := "d-block img-fluid" -}}
<img src="{{ $src }}" class="{{ $classes }}" alt="{{ .Text }}" width="{{ $config.Width }}" height="{{ $config.Height }}" loading="lazy">
+1 -1
View File
@@ -67,7 +67,7 @@
{{ end }}
{{ define "footer" }}
{{ range .Page.Params.extra_js -}}
<script{{ with .async }} async{{ end }}{{ with .defer }} defer{{ end }} src="{{ .src }}"></script>
<script{{ with .async }} async{{ end }} src="{{ .src }}"></script>
{{- end -}}
<div class="position-fixed" aria-hidden="true"><input type="text" tabindex="-1"></div>
{{ end }}
+51 -11
View File
@@ -94,38 +94,78 @@
z-index: 1500;
}
.bd-mode-toggle .bi {
width: 1em;
height: 1em;
}
.bd-mode-toggle .dropdown-menu .active .bi {
display: block !important;
}
</style>
{{ range .Page.Params.extra_css -}}
{{ range .Page.Params.extra_css }}
{{ "<!-- Custom styles for this template -->" | safeHTML }}
<link href="{{ . }}" rel="stylesheet">
{{- end }}
</head>
<body{{ with .Page.Params.body_class }} class="{{ . }}"{{ end }}>
{{ partial "examples/icons" . }}
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
<symbol id="check2" viewBox="0 0 16 16">
<path d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0z"/>
</symbol>
<symbol id="circle-half" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 0 8 1v14zm0 1A8 8 0 1 1 8 0a8 8 0 0 1 0 16z"/>
</symbol>
<symbol id="moon-stars-fill" viewBox="0 0 16 16">
<path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z"/>
<path d="M10.794 3.148a.217.217 0 0 1 .412 0l.387 1.162c.173.518.579.924 1.097 1.097l1.162.387a.217.217 0 0 1 0 .412l-1.162.387a1.734 1.734 0 0 0-1.097 1.097l-.387 1.162a.217.217 0 0 1-.412 0l-.387-1.162A1.734 1.734 0 0 0 9.31 6.593l-1.162-.387a.217.217 0 0 1 0-.412l1.162-.387a1.734 1.734 0 0 0 1.097-1.097l.387-1.162zM13.863.099a.145.145 0 0 1 .274 0l.258.774c.115.346.386.617.732.732l.774.258a.145.145 0 0 1 0 .274l-.774.258a1.156 1.156 0 0 0-.732.732l-.258.774a.145.145 0 0 1-.274 0l-.258-.774a1.156 1.156 0 0 0-.732-.732l-.774-.258a.145.145 0 0 1 0-.274l.774-.258c.346-.115.617-.386.732-.732L13.863.1z"/>
</symbol>
<symbol id="sun-fill" viewBox="0 0 16 16">
<path d="M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z"/>
</symbol>
</svg>
<div class="dropdown position-fixed bottom-0 end-0 mb-3 me-3 bd-mode-toggle">
{{ partial "theme-toggler" . }}
<button class="btn btn-bd-primary py-2 dropdown-toggle d-flex align-items-center"
id="bd-theme"
type="button"
aria-expanded="false"
data-bs-toggle="dropdown"
aria-label="Toggle theme (auto)">
<svg class="bi my-1 theme-icon-active" width="1em" height="1em"><use href="#circle-half"></use></svg>
<span class="visually-hidden" id="bd-theme-text">Toggle theme</span>
</button>
<ul class="dropdown-menu dropdown-menu-end shadow" aria-labelledby="bd-theme-text">
<li>
<button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="light" aria-pressed="false">
<svg class="bi me-2 opacity-50" width="1em" height="1em"><use href="#sun-fill"></use></svg>
Light
<svg class="bi ms-auto d-none" width="1em" height="1em"><use href="#check2"></use></svg>
</button>
</li>
<li>
<button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="dark" aria-pressed="false">
<svg class="bi me-2 opacity-50" width="1em" height="1em"><use href="#moon-stars-fill"></use></svg>
Dark
<svg class="bi ms-auto d-none" width="1em" height="1em"><use href="#check2"></use></svg>
</button>
</li>
<li>
<button type="button" class="dropdown-item d-flex align-items-center active" data-bs-theme-value="auto" aria-pressed="true">
<svg class="bi me-2 opacity-50" width="1em" height="1em"><use href="#circle-half"></use></svg>
Auto
<svg class="bi ms-auto d-none" width="1em" height="1em"><use href="#check2"></use></svg>
</button>
</li>
</ul>
</div>
{{ .Content }}
{{- if hugo.IsProduction -}}
<script defer src="/docs/{{ .Site.Params.docs_version }}/dist/js/bootstrap.bundle.min.js" {{ printf "integrity=%q" .Site.Params.cdn.js_bundle_hash | safeHTMLAttr }}></script>
<script src="/docs/{{ .Site.Params.docs_version }}/dist/js/bootstrap.bundle.min.js" {{ printf "integrity=%q" .Site.Params.cdn.js_bundle_hash | safeHTMLAttr }}></script>
{{- else -}}
<script defer src="/docs/{{ .Site.Params.docs_version }}/dist/js/bootstrap.bundle.js"></script>
<script src="/docs/{{ .Site.Params.docs_version }}/dist/js/bootstrap.bundle.js"></script>
{{- end }}
{{ range .Page.Params.extra_js -}}
<script{{ with .async }} async{{ end }}{{ with .defer }} defer{{ end }} src="{{ .src }}"{{ with .integrity }} {{ printf "integrity=%q" . | safeHTMLAttr }} crossorigin="anonymous"{{ end }}></script>
<script{{ with .async }} async{{ end }} src="{{ .src }}"{{ with .integrity }} {{ printf "integrity=%q" . | safeHTMLAttr }} crossorigin="anonymous"{{ end }}></script>
{{- end -}}
</body>
</html>
+23 -4
View File
@@ -28,10 +28,29 @@
<div class="container-xxl bd-gutter">
{{ .Content }}
{{ if eq .Title "Examples" -}}
{{ partial "examples/main" . }}
{{ partial "examples/bs-themes" . }}
{{- end }}
{{ if eq .Title "Examples" }}
<hr class="my-5">
<div class="container">
<div class="text-center">
<div class="masthead-followup-icon d-inline-block mb-2 text-bg-danger">
{{ partial "icons/droplet-fill.svg" (dict "width" "32" "height" "32") }}
</div>
<h2 class="display-6 fw-normal">Go further with Bootstrap Themes</h2>
<p class="col-md-10 col-lg-8 mx-auto lead">
Need something more than these examples? Take Bootstrap to the next level with premium themes from the <a href="{{ .Site.Params.themes }}">official Bootstrap Themes marketplace</a>. Theyre built as their own extended frameworks, rich with new components and plugins, documentation, and powerful build tools.
</p>
<a href="{{ .Site.Params.themes }}" class="btn btn-lg btn-outline-primary mb-3">Browse themes</a>
</div>
<img class="d-block img-fluid mt-3 mx-auto"
srcset="/docs/{{ .Site.Params.docs_version }}/assets/img/bootstrap-themes-collage.png,
/docs/{{ .Site.Params.docs_version }}/assets/img/bootstrap-themes-collage@2x.png 2x"
src="/docs/{{ .Site.Params.docs_version }}/assets/img/bootstrap-themes-collage.png"
alt="Bootstrap Themes"
width="1150"
height="320"
loading="lazy">
</div>
{{ end }}
</div>
</main>
{{ end }}
+1 -1
View File
@@ -1 +1 @@
<script defer src="https://cdn.usefathom.com/script.js" data-site="{{ .Site.Params.analytics.fathom_site }}"></script>
<script defer src="https://cdn.usefathom.com/script.js" data-site="ITUSEYJG"></script>
+33 -1
View File
@@ -83,7 +83,39 @@
</li>
<li class="nav-item dropdown">
{{ partial "theme-toggler" . }}
<button class="btn btn-link nav-link py-2 px-0 px-lg-2 dropdown-toggle d-flex align-items-center"
id="bd-theme"
type="button"
aria-expanded="false"
data-bs-toggle="dropdown"
data-bs-display="static"
aria-label="Toggle theme (auto)">
<svg class="bi my-1 theme-icon-active"><use href="#circle-half"></use></svg>
<span class="d-lg-none ms-2" id="bd-theme-text">Toggle theme</span>
</button>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="bd-theme-text">
<li>
<button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="light" aria-pressed="false">
<svg class="bi me-2 opacity-50"><use href="#sun-fill"></use></svg>
Light
<svg class="bi ms-auto d-none"><use href="#check2"></use></svg>
</button>
</li>
<li>
<button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="dark" aria-pressed="false">
<svg class="bi me-2 opacity-50"><use href="#moon-stars-fill"></use></svg>
Dark
<svg class="bi ms-auto d-none"><use href="#check2"></use></svg>
</button>
</li>
<li>
<button type="button" class="dropdown-item d-flex align-items-center active" data-bs-theme-value="auto" aria-pressed="true">
<svg class="bi me-2 opacity-50"><use href="#circle-half"></use></svg>
Auto
<svg class="bi ms-auto d-none"><use href="#check2"></use></svg>
</button>
</li>
</ul>
</li>
</ul>
</div>
+1 -2
View File
@@ -36,8 +36,7 @@
{{- else }}
<li class="bd-links-span-all mt-1 mb-3 mx-4 border-top"></li>
<li class="bd-links-span-all">
{{- $href := urls.JoinPath "/docs" $.Site.Params.docs_version $group_slug "/" }}
<a href="{{ $href }}" class="bd-links-link d-inline-block rounded small{{ if $is_active_group }} active{{ end }}"{{ if $is_active_group }} aria-current="page"{{ end }}>
<a href="/docs/{{ $.Site.Params.docs_version }}/{{ $group_slug }}/" class="bd-links-link d-inline-block rounded small {{ if $is_active_group }} active{{ end }}"{{ if $is_active_group }} aria-current="page"{{ end }}>
{{ $group.title }}
</a>
</li>
@@ -1,17 +0,0 @@
<hr class="my-5">
<div class="container">
<div class="text-center">
<div class="masthead-followup-icon d-inline-block mb-2 text-bg-danger">
{{ partial "icons/droplet-fill.svg" (dict "width" "32" "height" "32") }}
</div>
<h2 class="display-6 fw-normal">Go further with Bootstrap Themes</h2>
<p class="col-md-10 col-lg-8 mx-auto lead">
Need something more than these examples? Take Bootstrap to the next level with premium themes from the <a href="{{ .Site.Params.themes }}">official Bootstrap Themes marketplace</a>. Theyre built as their own extended frameworks, rich with new components and plugins, documentation, and powerful build tools.
</p>
<a href="{{ .Site.Params.themes }}" class="btn btn-lg btn-outline-primary mb-3">Browse themes</a>
</div>
{{ partial "responsive-img" (dict "context" .
"imgPath" "/assets/img/bootstrap-themes-collage.png"
"alt" "Bootstrap Themes"
"classes" "d-block mt-3") }}
</div>
-15
View File
@@ -1,15 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
<symbol id="check2" viewBox="0 0 16 16">
<path d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0z"/>
</symbol>
<symbol id="circle-half" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 0 8 1v14zm0 1A8 8 0 1 1 8 0a8 8 0 0 1 0 16z"/>
</symbol>
<symbol id="moon-stars-fill" viewBox="0 0 16 16">
<path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278z"/>
<path d="M10.794 3.148a.217.217 0 0 1 .412 0l.387 1.162c.173.518.579.924 1.097 1.097l1.162.387a.217.217 0 0 1 0 .412l-1.162.387a1.734 1.734 0 0 0-1.097 1.097l-.387 1.162a.217.217 0 0 1-.412 0l-.387-1.162A1.734 1.734 0 0 0 9.31 6.593l-1.162-.387a.217.217 0 0 1 0-.412l1.162-.387a1.734 1.734 0 0 0 1.097-1.097l.387-1.162zM13.863.099a.145.145 0 0 1 .274 0l.258.774c.115.346.386.617.732.732l.774.258a.145.145 0 0 1 0 .274l-.774.258a1.156 1.156 0 0 0-.732.732l-.258.774a.145.145 0 0 1-.274 0l-.258-.774a1.156 1.156 0 0 0-.732-.732l-.774-.258a.145.145 0 0 1 0-.274l.774-.258c.346-.115.617-.386.732-.732L13.863.1z"/>
</symbol>
<symbol id="sun-fill" viewBox="0 0 16 16">
<path d="M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z"/>
</symbol>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

-63
View File
@@ -1,63 +0,0 @@
{{ range $entry := $.Site.Data.examples -}}
<div class="bd-content">
<h2 id="{{ $entry.category | urlize }}">{{ $entry.category }}</h2>
<p>{{ $entry.description }}</p>
{{ if eq $entry.category "RTL" -}}
<div class="bd-callout bd-callout-warning small">
<p>
<strong>RTL is still experimental</strong> and will evolve with feedback. Spotted something or have an improvement to suggest?
</p>
<p><a href="{{ urls.JoinPath $.Site.Params.repo "issues/new/choose" }}">Please open an issue.</a></p>
</div>
{{ end -}}
{{ range $i, $example := $entry.examples -}}
{{- $len := len $entry.examples -}}
{{ if (eq $i 0) }}<div class="row">{{ end }}
{{ if $entry.external -}}
<div class="col-md-6 col-lg-4 mb-3 d-flex gap-3">
<svg class="bi fs-5 flex-shrink-0 mt-1"><use xlink:href="#box-seam"></use></svg>
<div>
<h3 class="h5 mb-1">
<a class="d-block link-offset-1" href="{{ urls.JoinPath $.Site.Params.github_org $example.url }}" target="_blank" rel="noopener">
{{ $example.name }}
</a>
</h3>
<p class="text-body-secondary">{{ $example.description }}</p>
<p>
{{- $indexPath := default "index.html" $example.indexPath -}}
{{- $stackBlitzUrl := printf "%s%s%s" (urls.JoinPath "https://stackblitz.com/github/twbs" $example.url) "?file=" ($indexPath | urlquery) }}
<a class="icon-link small link-secondary link-offset-1" href="{{ $stackBlitzUrl }}" target="_blank" rel="noopener">
<svg class="bi flex-shrink-0"><use xlink:href="#lightning-charge-fill"></use></svg>
Edit in StackBlitz
</a>
</p>
</div>
</div>
{{ else -}}
<div class="col-sm-6 col-md-3 mb-3">
{{- $exampleNameUrlized := $example.name | urlize -}}
{{- $exampleUrl := urls.JoinPath "/docs" $.Site.Params.docs_version "/examples" $exampleNameUrlized "/" }}
<a class="d-block link-offset-1" href="{{ $exampleUrl }}"{{ if in $example.name "RTL" }} hreflang="ar"{{ end }}>
{{ $imageBasePath := urls.JoinPath "/docs" $.Site.Params.docs_version "assets/img/examples" -}}
{{- $imgPath := urls.JoinPath $imageBasePath (printf "%s.png" $exampleNameUrlized) -}}
{{- $imgPath2x := urls.JoinPath $imageBasePath (printf "%s@2x.png" $exampleNameUrlized) -}}
{{- with (imageConfig (path.Join "/site/static" $imgPath)) -}}
<img class="img-thumbnail mb-3"
srcset="{{ $imgPath }}, {{ $imgPath2x }} 2x"
src="{{ $imgPath }}"
alt=""
width="{{ .Width }}"
height="{{ .Height }}"
loading="lazy">
{{- end }}
<h3 class="h5 mb-1">
{{ $example.name }}
</h3>
</a>
<p class="text-body-secondary">{{ $example.description }}</p>
</div>
{{- end }}
{{ if (eq (add $i 1) $len) }}</div>{{ end -}}
{{ end -}}
</div>
{{ end -}}

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