Merge branch 'main' into main

This commit is contained in:
Aman Chadha(IVIXMMI) 2025-07-09 15:48:29 +05:30 committed by GitHub
commit f87e201ea6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
117 changed files with 1760 additions and 1567 deletions

View File

@ -47,4 +47,4 @@ jobs:
paths: _site
recurse: true
verbosity: error
skip: "^(?!http://localhost)"
skip: "^http://localhost"

View File

@ -46,12 +46,12 @@ Our default branch is for development of our Bootstrap 5 release. Head to the [`
Several quick start options are available:
- [Download the latest release](https://github.com/twbs/bootstrap/archive/v5.3.6.zip)
- [Download the latest release](https://github.com/twbs/bootstrap/archive/v5.3.7.zip)
- Clone the repo: `git clone https://github.com/twbs/bootstrap.git`
- Install with [npm](https://www.npmjs.com/): `npm install bootstrap@v5.3.6`
- Install with [yarn](https://yarnpkg.com/): `yarn add bootstrap@v5.3.6`
- Install with [Bun](https://bun.sh/): `bun add bootstrap@v5.3.6`
- Install with [Composer](https://getcomposer.org/): `composer require twbs/bootstrap:5.3.6`
- Install with [npm](https://www.npmjs.com/): `npm install bootstrap@v5.3.7`
- Install with [yarn](https://yarnpkg.com/): `yarn add bootstrap@v5.3.7`
- Install with [Bun](https://bun.sh/): `bun add bootstrap@v5.3.7`
- Install with [Composer](https://getcomposer.org/): `composer require twbs/bootstrap:5.3.7`
- Install with [NuGet](https://www.nuget.org/): CSS: `Install-Package bootstrap` Sass: `Install-Package bootstrap.sass`
Read the [Getting started page](https://getbootstrap.com/docs/5.3/getting-started/introduction/) for information on the framework contents, templates, examples, and more.
@ -151,7 +151,7 @@ Documentation search is powered by [Algolia's DocSearch](https://docsearch.algol
1. Run `npm install` to install the Node.js dependencies, including Astro (the site builder).
2. Run `npm run test` (or a specific npm script) to rebuild distributed CSS and JavaScript files, as well as our docs assets.
3. From the root `/bootstrap` directory, run `npm run docs-serve` in the command line.
4. Open `http://localhost:9001/` in your browser, and voilà.
4. Open <http://localhost:9001> in your browser, and voilà.
Learn more about using Astro by reading its [documentation](https://docs.astro.build/en/getting-started/).

View File

@ -18,6 +18,9 @@ fi
# Branch name to create
NEW_BRANCH="gh-pages-${BRANCH_SUFFIX}"
# Get the current docs version from config
DOCS_VERSION=$(node -p "require('js-yaml').load(require('fs').readFileSync('config.yml', 'utf8')).docs_version")
# Function to print colored messages
print_success() {
echo -e "${GREEN}$1${NC}"
@ -89,66 +92,39 @@ fi
print_success "Pulled latest changes from origin/gh-pages"
# Step 4: Create a new branch for the update
print_info "Checking if branch ${NEW_BRANCH} exists and deleting it if it does…"
if git show-ref --verify --quiet refs/heads/${NEW_BRANCH}; then
execute "git branch -D ${NEW_BRANCH}"
else
print_info "Branch ${NEW_BRANCH} does not exist, proceeding with creation…"
fi
print_info "Creating new branch ${NEW_BRANCH}"
execute "git checkout -b ${NEW_BRANCH}"
# Step 5: Move root files
print_info "Moving root files from temporary location…"
ROOT_FILES=("404.html" "CNAME" "apple-touch-icon.png" "favicon.ico" "index.html" "robots.txt" "sitemap-0.xml" "sitemap-index.xml" "sw.js")
for file in "${ROOT_FILES[@]}"; do
if [ -f "/tmp/_site/$file" ]; then
execute "mv /tmp/_site/$file ."
else
print_warning "File /tmp/_site/$file not found. Skipping."
fi
done
# Step 5: Move all root-level files from Astro build
find /tmp/_site -maxdepth 1 -type f -exec mv {} . \;
# Step 6: Move directories with cleanup
print_info "Moving directories from temporary location…"
DIRS=("about" "components" "docsref" "examples" "getting-started" "migration")
for dir in "${DIRS[@]}"; do
if [ -d "/tmp/_site/$dir" ]; then
if [ -d "$dir" ]; then
execute "rm -rf $dir"
# Step 6: Move all top-level directories except 'docs' (which needs special handling)
find /tmp/_site -maxdepth 1 -type d ! -name "_site" ! -name "docs" -exec sh -c 'dir=$(basename "$1"); rm -rf "$dir"; mv "$1" .' _ {} \;
# Step 7: Handle docs directory specially
if [ -d "/tmp/_site/docs" ]; then
# Replace only the current version's docs
if [ -d "docs/$DOCS_VERSION" ]; then
rm -rf "docs/$DOCS_VERSION"
fi
mv "/tmp/_site/docs/$DOCS_VERSION" "docs/"
# Handle docs root files
find /tmp/_site/docs -maxdepth 1 -type f -exec mv {} docs/ \;
# Handle special docs directories (getting-started, versions)
for special_dir in getting-started versions; do
if [ -d "/tmp/_site/docs/$special_dir" ]; then
rm -rf "docs/$special_dir"
mv "/tmp/_site/docs/$special_dir" "docs/"
fi
execute "mv /tmp/_site/$dir ."
else
print_warning "Directory /tmp/_site/$dir not found. Skipping."
fi
done
# Step 7: Handle special doc directories
print_info "Handling special documentation directories…"
SPECIAL_DOCS=("docs/getting-started" "docs/versions")
for dir in "${SPECIAL_DOCS[@]}"; do
if [ -d "/tmp/_site/$dir" ]; then
if [ -d "$dir" ]; then
execute "rm -rf $dir"
fi
# Make sure parent directory exists
parent_dir=$(dirname "$dir")
mkdir -p "$parent_dir"
execute "mv /tmp/_site/$dir $parent_dir/"
else
print_warning "Directory /tmp/_site/$dir not found. Skipping."
fi
done
# Step 8: Move docs index.html
if [ -f "/tmp/_site/docs/index.html" ]; then
execute "mv /tmp/_site/docs/index.html docs/index.html"
else
print_warning "File /tmp/_site/docs/index.html not found. Skipping."
fi
# Step 9: Handle docs/5.3
if [ -d "/tmp/_site/docs/5.3" ]; then
if [ -d "docs/5.3" ]; then
execute "rm -rf docs/5.3"
fi
execute "mv /tmp/_site/docs/5.3 docs/"
else
print_warning "Directory /tmp/_site/docs/5.3 not found. Skipping."
done
fi
# Clean up remaining files in /tmp/_site if any

View File

@ -7,8 +7,8 @@ subtitle: "The most popular HTML, CSS, and JS library in the world
description: "Powerful, extensible, and feature-packed frontend toolkit. Build and customize with Sass, utilize prebuilt grid system and components, and bring projects to life with powerful JavaScript plugins."
authors: "Mark Otto, Jacob Thornton, and Bootstrap contributors"
current_version: "5.3.6"
current_ruby_version: "5.3.6"
current_version: "5.3.7"
current_ruby_version: "5.3.7"
docs_version: "5.3"
rfs_version: "v10.0.0"
github_org: "https://github.com/twbs"
@ -29,20 +29,20 @@ algolia:
index_name: "bootstrap"
download:
source: "https://github.com/twbs/bootstrap/archive/v5.3.6.zip"
dist: "https://github.com/twbs/bootstrap/releases/download/v5.3.6/bootstrap-5.3.6-dist.zip"
dist_examples: "https://github.com/twbs/bootstrap/releases/download/v5.3.6/bootstrap-5.3.6-examples.zip"
source: "https://github.com/twbs/bootstrap/archive/v5.3.7.zip"
dist: "https://github.com/twbs/bootstrap/releases/download/v5.3.7/bootstrap-5.3.7-dist.zip"
dist_examples: "https://github.com/twbs/bootstrap/releases/download/v5.3.7/bootstrap-5.3.7-examples.zip"
cdn:
# See https://www.srihash.org for info on how to generate the hashes
css: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/css/bootstrap.min.css"
css_hash: "sha384-4Q6Gf2aSP4eDXB8Miphtr37CMZZQ5oXLH2yaXMJ2w8e2ZtHTl7GptT4jmndRuHDT"
css_rtl: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/css/bootstrap.rtl.min.css"
css_rtl_hash: "sha384-MdqCcafa5BLgxBDJ3d/4D292geNL64JyRtSGjEszRUQX9rhL1QkcnId+OT7Yw+D+"
js: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/js/bootstrap.min.js"
js_hash: "sha384-RuyvpeZCxMJCqVUGFI0Do1mQrods/hhxYlcVfGPOfQtPJh0JCw12tUAZ/Mv10S7D"
js_bundle: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/js/bootstrap.bundle.min.js"
js_bundle_hash: "sha384-j1CDi7MgGQ12Z7Qab0qlWQ/Qqz24Gc6BM0thvEMVjHnfYGF0rmFCozFSxQBxwHKO"
css: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.7/dist/css/bootstrap.min.css"
css_hash: "sha384-LN+7fdVzj6u52u30Kp6M/trliBMCMKTyK833zpbD+pXdCLuTusPj697FH4R/5mcr"
css_rtl: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.7/dist/css/bootstrap.rtl.min.css"
css_rtl_hash: "sha384-Xbg45MqvDIk1e563NLpGEulpX6AvL404DP+/iCgW9eFa2BqztiwTexswJo2jLMue"
js: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.7/dist/js/bootstrap.min.js"
js_hash: "sha384-7qAoOXltbVP82dhxHAUje59V5r2YsVfBafyUDxEdApLPmcdhBPg1DKg1ERo0BZlK"
js_bundle: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.7/dist/js/bootstrap.bundle.min.js"
js_bundle_hash: "sha384-ndDqU0Gzau9qJ1lfW4pNLlhNTkCfHzAVBReH9diLvGRem5+R9g2FzA8ZGN954O5Q"
popper: "https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"
popper_hash: "sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r"
popper_esm: "https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/esm/popper.min.js"

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap Grid v5.3.6 (https://getbootstrap.com/)
* Bootstrap Grid v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap Grid v5.3.6 (https://getbootstrap.com/)
* Bootstrap Grid v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap Reboot v5.3.6 (https://getbootstrap.com/)
* Bootstrap Reboot v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap Reboot v5.3.6 (https://getbootstrap.com/)
* Bootstrap Reboot v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap Utilities v5.3.6 (https://getbootstrap.com/)
* Bootstrap Utilities v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap Utilities v5.3.6 (https://getbootstrap.com/)
* Bootstrap Utilities v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
@charset "UTF-8";
/*!
* Bootstrap v5.3.6 (https://getbootstrap.com/)
* Bootstrap v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
@charset "UTF-8";
/*!
* Bootstrap v5.3.6 (https://getbootstrap.com/)
* Bootstrap v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap v5.3.6 (https://getbootstrap.com/)
* Bootstrap v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
@ -647,7 +647,7 @@
* Constants
*/
const VERSION = '5.3.6';
const VERSION = '5.3.7';
/**
* Class definition
@ -4805,7 +4805,6 @@
*
* Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38
*/
// eslint-disable-next-line unicorn/better-regex
const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i;
const allowedAttribute = (attribute, allowedAttributeList) => {
const attributeName = attribute.nodeName.toLowerCase();
@ -5349,6 +5348,7 @@
if (trigger === 'click') {
EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => {
const context = this._initializeOnDelegatedTarget(event);
context._activeTrigger[TRIGGER_CLICK] = !(context._isShown() && context._activeTrigger[TRIGGER_CLICK]);
context.toggle();
});
} else if (trigger !== TRIGGER_MANUAL) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap v5.3.6 (https://getbootstrap.com/)
* Bootstrap v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
@ -643,7 +643,7 @@ class Config {
* Constants
*/
const VERSION = '5.3.6';
const VERSION = '5.3.7';
/**
* Class definition
@ -2964,7 +2964,6 @@ const uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longde
*
* Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38
*/
// eslint-disable-next-line unicorn/better-regex
const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i;
const allowedAttribute = (attribute, allowedAttributeList) => {
const attributeName = attribute.nodeName.toLowerCase();
@ -3508,6 +3507,7 @@ class Tooltip extends BaseComponent {
if (trigger === 'click') {
EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => {
const context = this._initializeOnDelegatedTarget(event);
context._activeTrigger[TRIGGER_CLICK] = !(context._isShown() && context._activeTrigger[TRIGGER_CLICK]);
context.toggle();
});
} else if (trigger !== TRIGGER_MANUAL) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap v5.3.6 (https://getbootstrap.com/)
* Bootstrap v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
@ -666,7 +666,7 @@
* Constants
*/
const VERSION = '5.3.6';
const VERSION = '5.3.7';
/**
* Class definition
@ -2987,7 +2987,6 @@
*
* Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38
*/
// eslint-disable-next-line unicorn/better-regex
const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i;
const allowedAttribute = (attribute, allowedAttributeList) => {
const attributeName = attribute.nodeName.toLowerCase();
@ -3531,6 +3530,7 @@
if (trigger === 'click') {
EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => {
const context = this._initializeOnDelegatedTarget(event);
context._activeTrigger[TRIGGER_CLICK] = !(context._isShown() && context._activeTrigger[TRIGGER_CLICK]);
context.toggle();
});
} else if (trigger !== TRIGGER_MANUAL) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
js/dist/alert.js vendored
View File

@ -1,5 +1,5 @@
/*!
* Bootstrap alert.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap alert.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap base-component.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap base-component.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
@ -21,7 +21,7 @@
* Constants
*/
const VERSION = '5.3.6';
const VERSION = '5.3.7';
/**
* Class definition

View File

@ -1 +1 @@
{"version":3,"file":"base-component.js","sources":["../src/base-component.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Data from './dom/data.js'\nimport EventHandler from './dom/event-handler.js'\nimport Config from './util/config.js'\nimport { executeAfterTransition, getElement } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst VERSION = '5.3.6'\n\n/**\n * Class definition\n */\n\nclass BaseComponent extends Config {\n constructor(element, config) {\n super()\n\n element = getElement(element)\n if (!element) {\n return\n }\n\n this._element = element\n this._config = this._getConfig(config)\n\n Data.set(this._element, this.constructor.DATA_KEY, this)\n }\n\n // Public\n dispose() {\n Data.remove(this._element, this.constructor.DATA_KEY)\n EventHandler.off(this._element, this.constructor.EVENT_KEY)\n\n for (const propertyName of Object.getOwnPropertyNames(this)) {\n this[propertyName] = null\n }\n }\n\n // Private\n _queueCallback(callback, element, isAnimated = true) {\n executeAfterTransition(callback, element, isAnimated)\n }\n\n _getConfig(config) {\n config = this._mergeConfigObj(config, this._element)\n config = this._configAfterMerge(config)\n this._typeCheckConfig(config)\n return config\n }\n\n // Static\n static getInstance(element) {\n return Data.get(getElement(element), this.DATA_KEY)\n }\n\n static getOrCreateInstance(element, config = {}) {\n return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)\n }\n\n static get VERSION() {\n return VERSION\n }\n\n static get DATA_KEY() {\n return `bs.${this.NAME}`\n }\n\n static get EVENT_KEY() {\n return `.${this.DATA_KEY}`\n }\n\n static eventName(name) {\n return `${name}${this.EVENT_KEY}`\n }\n}\n\nexport default BaseComponent\n"],"names":["VERSION","BaseComponent","Config","constructor","element","config","getElement","_element","_config","_getConfig","Data","set","DATA_KEY","dispose","remove","EventHandler","off","EVENT_KEY","propertyName","Object","getOwnPropertyNames","_queueCallback","callback","isAnimated","executeAfterTransition","_mergeConfigObj","_configAfterMerge","_typeCheckConfig","getInstance","get","getOrCreateInstance","NAME","eventName","name"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAOA;EACA;EACA;;EAEA,MAAMA,OAAO,GAAG,OAAO;;EAEvB;EACA;EACA;;EAEA,MAAMC,aAAa,SAASC,MAAM,CAAC;EACjCC,EAAAA,WAAWA,CAACC,OAAO,EAAEC,MAAM,EAAE;EAC3B,IAAA,KAAK,EAAE;EAEPD,IAAAA,OAAO,GAAGE,mBAAU,CAACF,OAAO,CAAC;MAC7B,IAAI,CAACA,OAAO,EAAE;EACZ,MAAA;EACF;MAEA,IAAI,CAACG,QAAQ,GAAGH,OAAO;MACvB,IAAI,CAACI,OAAO,GAAG,IAAI,CAACC,UAAU,CAACJ,MAAM,CAAC;EAEtCK,IAAAA,IAAI,CAACC,GAAG,CAAC,IAAI,CAACJ,QAAQ,EAAE,IAAI,CAACJ,WAAW,CAACS,QAAQ,EAAE,IAAI,CAAC;EAC1D;;EAEA;EACAC,EAAAA,OAAOA,GAAG;EACRH,IAAAA,IAAI,CAACI,MAAM,CAAC,IAAI,CAACP,QAAQ,EAAE,IAAI,CAACJ,WAAW,CAACS,QAAQ,CAAC;EACrDG,IAAAA,YAAY,CAACC,GAAG,CAAC,IAAI,CAACT,QAAQ,EAAE,IAAI,CAACJ,WAAW,CAACc,SAAS,CAAC;MAE3D,KAAK,MAAMC,YAAY,IAAIC,MAAM,CAACC,mBAAmB,CAAC,IAAI,CAAC,EAAE;EAC3D,MAAA,IAAI,CAACF,YAAY,CAAC,GAAG,IAAI;EAC3B;EACF;;EAEA;IACAG,cAAcA,CAACC,QAAQ,EAAElB,OAAO,EAAEmB,UAAU,GAAG,IAAI,EAAE;EACnDC,IAAAA,+BAAsB,CAACF,QAAQ,EAAElB,OAAO,EAAEmB,UAAU,CAAC;EACvD;IAEAd,UAAUA,CAACJ,MAAM,EAAE;MACjBA,MAAM,GAAG,IAAI,CAACoB,eAAe,CAACpB,MAAM,EAAE,IAAI,CAACE,QAAQ,CAAC;EACpDF,IAAAA,MAAM,GAAG,IAAI,CAACqB,iBAAiB,CAACrB,MAAM,CAAC;EACvC,IAAA,IAAI,CAACsB,gBAAgB,CAACtB,MAAM,CAAC;EAC7B,IAAA,OAAOA,MAAM;EACf;;EAEA;IACA,OAAOuB,WAAWA,CAACxB,OAAO,EAAE;EAC1B,IAAA,OAAOM,IAAI,CAACmB,GAAG,CAACvB,mBAAU,CAACF,OAAO,CAAC,EAAE,IAAI,CAACQ,QAAQ,CAAC;EACrD;IAEA,OAAOkB,mBAAmBA,CAAC1B,OAAO,EAAEC,MAAM,GAAG,EAAE,EAAE;MAC/C,OAAO,IAAI,CAACuB,WAAW,CAACxB,OAAO,CAAC,IAAI,IAAI,IAAI,CAACA,OAAO,EAAE,OAAOC,MAAM,KAAK,QAAQ,GAAGA,MAAM,GAAG,IAAI,CAAC;EACnG;IAEA,WAAWL,OAAOA,GAAG;EACnB,IAAA,OAAOA,OAAO;EAChB;IAEA,WAAWY,QAAQA,GAAG;EACpB,IAAA,OAAO,CAAM,GAAA,EAAA,IAAI,CAACmB,IAAI,CAAE,CAAA;EAC1B;IAEA,WAAWd,SAASA,GAAG;EACrB,IAAA,OAAO,CAAI,CAAA,EAAA,IAAI,CAACL,QAAQ,CAAE,CAAA;EAC5B;IAEA,OAAOoB,SAASA,CAACC,IAAI,EAAE;EACrB,IAAA,OAAO,GAAGA,IAAI,CAAA,EAAG,IAAI,CAAChB,SAAS,CAAE,CAAA;EACnC;EACF;;;;;;;;"}
{"version":3,"file":"base-component.js","sources":["../src/base-component.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Data from './dom/data.js'\nimport EventHandler from './dom/event-handler.js'\nimport Config from './util/config.js'\nimport { executeAfterTransition, getElement } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst VERSION = '5.3.7'\n\n/**\n * Class definition\n */\n\nclass BaseComponent extends Config {\n constructor(element, config) {\n super()\n\n element = getElement(element)\n if (!element) {\n return\n }\n\n this._element = element\n this._config = this._getConfig(config)\n\n Data.set(this._element, this.constructor.DATA_KEY, this)\n }\n\n // Public\n dispose() {\n Data.remove(this._element, this.constructor.DATA_KEY)\n EventHandler.off(this._element, this.constructor.EVENT_KEY)\n\n for (const propertyName of Object.getOwnPropertyNames(this)) {\n this[propertyName] = null\n }\n }\n\n // Private\n _queueCallback(callback, element, isAnimated = true) {\n executeAfterTransition(callback, element, isAnimated)\n }\n\n _getConfig(config) {\n config = this._mergeConfigObj(config, this._element)\n config = this._configAfterMerge(config)\n this._typeCheckConfig(config)\n return config\n }\n\n // Static\n static getInstance(element) {\n return Data.get(getElement(element), this.DATA_KEY)\n }\n\n static getOrCreateInstance(element, config = {}) {\n return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)\n }\n\n static get VERSION() {\n return VERSION\n }\n\n static get DATA_KEY() {\n return `bs.${this.NAME}`\n }\n\n static get EVENT_KEY() {\n return `.${this.DATA_KEY}`\n }\n\n static eventName(name) {\n return `${name}${this.EVENT_KEY}`\n }\n}\n\nexport default BaseComponent\n"],"names":["VERSION","BaseComponent","Config","constructor","element","config","getElement","_element","_config","_getConfig","Data","set","DATA_KEY","dispose","remove","EventHandler","off","EVENT_KEY","propertyName","Object","getOwnPropertyNames","_queueCallback","callback","isAnimated","executeAfterTransition","_mergeConfigObj","_configAfterMerge","_typeCheckConfig","getInstance","get","getOrCreateInstance","NAME","eventName","name"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAOA;EACA;EACA;;EAEA,MAAMA,OAAO,GAAG,OAAO;;EAEvB;EACA;EACA;;EAEA,MAAMC,aAAa,SAASC,MAAM,CAAC;EACjCC,EAAAA,WAAWA,CAACC,OAAO,EAAEC,MAAM,EAAE;EAC3B,IAAA,KAAK,EAAE;EAEPD,IAAAA,OAAO,GAAGE,mBAAU,CAACF,OAAO,CAAC;MAC7B,IAAI,CAACA,OAAO,EAAE;EACZ,MAAA;EACF;MAEA,IAAI,CAACG,QAAQ,GAAGH,OAAO;MACvB,IAAI,CAACI,OAAO,GAAG,IAAI,CAACC,UAAU,CAACJ,MAAM,CAAC;EAEtCK,IAAAA,IAAI,CAACC,GAAG,CAAC,IAAI,CAACJ,QAAQ,EAAE,IAAI,CAACJ,WAAW,CAACS,QAAQ,EAAE,IAAI,CAAC;EAC1D;;EAEA;EACAC,EAAAA,OAAOA,GAAG;EACRH,IAAAA,IAAI,CAACI,MAAM,CAAC,IAAI,CAACP,QAAQ,EAAE,IAAI,CAACJ,WAAW,CAACS,QAAQ,CAAC;EACrDG,IAAAA,YAAY,CAACC,GAAG,CAAC,IAAI,CAACT,QAAQ,EAAE,IAAI,CAACJ,WAAW,CAACc,SAAS,CAAC;MAE3D,KAAK,MAAMC,YAAY,IAAIC,MAAM,CAACC,mBAAmB,CAAC,IAAI,CAAC,EAAE;EAC3D,MAAA,IAAI,CAACF,YAAY,CAAC,GAAG,IAAI;EAC3B;EACF;;EAEA;IACAG,cAAcA,CAACC,QAAQ,EAAElB,OAAO,EAAEmB,UAAU,GAAG,IAAI,EAAE;EACnDC,IAAAA,+BAAsB,CAACF,QAAQ,EAAElB,OAAO,EAAEmB,UAAU,CAAC;EACvD;IAEAd,UAAUA,CAACJ,MAAM,EAAE;MACjBA,MAAM,GAAG,IAAI,CAACoB,eAAe,CAACpB,MAAM,EAAE,IAAI,CAACE,QAAQ,CAAC;EACpDF,IAAAA,MAAM,GAAG,IAAI,CAACqB,iBAAiB,CAACrB,MAAM,CAAC;EACvC,IAAA,IAAI,CAACsB,gBAAgB,CAACtB,MAAM,CAAC;EAC7B,IAAA,OAAOA,MAAM;EACf;;EAEA;IACA,OAAOuB,WAAWA,CAACxB,OAAO,EAAE;EAC1B,IAAA,OAAOM,IAAI,CAACmB,GAAG,CAACvB,mBAAU,CAACF,OAAO,CAAC,EAAE,IAAI,CAACQ,QAAQ,CAAC;EACrD;IAEA,OAAOkB,mBAAmBA,CAAC1B,OAAO,EAAEC,MAAM,GAAG,EAAE,EAAE;MAC/C,OAAO,IAAI,CAACuB,WAAW,CAACxB,OAAO,CAAC,IAAI,IAAI,IAAI,CAACA,OAAO,EAAE,OAAOC,MAAM,KAAK,QAAQ,GAAGA,MAAM,GAAG,IAAI,CAAC;EACnG;IAEA,WAAWL,OAAOA,GAAG;EACnB,IAAA,OAAOA,OAAO;EAChB;IAEA,WAAWY,QAAQA,GAAG;EACpB,IAAA,OAAO,CAAM,GAAA,EAAA,IAAI,CAACmB,IAAI,CAAE,CAAA;EAC1B;IAEA,WAAWd,SAASA,GAAG;EACrB,IAAA,OAAO,CAAI,CAAA,EAAA,IAAI,CAACL,QAAQ,CAAE,CAAA;EAC5B;IAEA,OAAOoB,SAASA,CAACC,IAAI,EAAE;EACrB,IAAA,OAAO,GAAGA,IAAI,CAAA,EAAG,IAAI,CAAChB,SAAS,CAAE,CAAA;EACnC;EACF;;;;;;;;"}

2
js/dist/button.js vendored
View File

@ -1,5 +1,5 @@
/*!
* Bootstrap button.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap button.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

2
js/dist/carousel.js vendored
View File

@ -1,5 +1,5 @@
/*!
* Bootstrap carousel.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap carousel.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

2
js/dist/collapse.js vendored
View File

@ -1,5 +1,5 @@
/*!
* Bootstrap collapse.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap collapse.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

2
js/dist/dom/data.js vendored
View File

@ -1,5 +1,5 @@
/*!
* Bootstrap data.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap data.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap event-handler.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap event-handler.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap manipulator.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap manipulator.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap selector-engine.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap selector-engine.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

2
js/dist/dropdown.js vendored
View File

@ -1,5 +1,5 @@
/*!
* Bootstrap dropdown.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap dropdown.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

2
js/dist/modal.js vendored
View File

@ -1,5 +1,5 @@
/*!
* Bootstrap modal.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap modal.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap offcanvas.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap offcanvas.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

2
js/dist/popover.js vendored
View File

@ -1,5 +1,5 @@
/*!
* Bootstrap popover.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap popover.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap scrollspy.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap scrollspy.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

2
js/dist/tab.js vendored
View File

@ -1,5 +1,5 @@
/*!
* Bootstrap tab.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap tab.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

2
js/dist/toast.js vendored
View File

@ -1,5 +1,5 @@
/*!
* Bootstrap toast.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap toast.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

3
js/dist/tooltip.js vendored
View File

@ -1,5 +1,5 @@
/*!
* Bootstrap tooltip.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap tooltip.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
@ -395,6 +395,7 @@
if (trigger === 'click') {
EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK), this._config.selector, event => {
const context = this._initializeOnDelegatedTarget(event);
context._activeTrigger[TRIGGER_CLICK] = !(context._isShown() && context._activeTrigger[TRIGGER_CLICK]);
context.toggle();
});
} else if (trigger !== TRIGGER_MANUAL) {

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap backdrop.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap backdrop.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap component-functions.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap component-functions.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap config.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap config.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap focustrap.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap focustrap.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap index.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap index.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap sanitizer.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap sanitizer.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
@ -64,7 +64,6 @@
*
* Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38
*/
// eslint-disable-next-line unicorn/better-regex
const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i;
const allowedAttribute = (attribute, allowedAttributeList) => {
const attributeName = attribute.nodeName.toLowerCase();

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap scrollbar.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap scrollbar.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap swipe.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap swipe.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap template-factory.js v5.3.6 (https://getbootstrap.com/)
* Bootstrap template-factory.js v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View File

@ -14,7 +14,7 @@ import { executeAfterTransition, getElement } from './util/index.js'
* Constants
*/
const VERSION = '5.3.6'
const VERSION = '5.3.7'
/**
* Class definition

View File

@ -448,6 +448,7 @@ class Tooltip extends BaseComponent {
if (trigger === 'click') {
EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK), this._config.selector, event => {
const context = this._initializeOnDelegatedTarget(event)
context._activeTrigger[TRIGGER_CLICK] = !(context._isShown() && context._activeTrigger[TRIGGER_CLICK])
context.toggle()
})
} else if (trigger !== TRIGGER_MANUAL) {

View File

@ -1,6 +1,8 @@
import EventHandler from '../../src/dom/event-handler.js'
import Popover from '../../src/popover.js'
import { clearFixture, getFixture, jQueryMock } from '../helpers/fixture.js'
import {
clearFixture, getFixture, jQueryMock, createEvent
} from '../helpers/fixture.js'
describe('Popover', () => {
let fixtureEl
@ -313,6 +315,28 @@ describe('Popover', () => {
popover.show()
})
})
it('should keep popover open when mouse leaves after click trigger', () => {
return new Promise(resolve => {
fixtureEl.innerHTML = '<a href="#" title="Popover" data-bs-content="https://x.com/getbootstrap" data-bs-trigger="hover click">BS X</a>'
const popoverEl = fixtureEl.querySelector('a')
new Popover(popoverEl) // eslint-disable-line no-new
popoverEl.addEventListener('shown.bs.popover', () => {
popoverEl.dispatchEvent(createEvent('mouseout'))
popoverEl.addEventListener('hide.bs.popover', () => {
throw new Error('Popover should not hide when mouse leaves after click')
})
expect(document.querySelector('.popover')).not.toBeNull()
resolve()
})
popoverEl.click()
})
})
})
describe('hide', () => {

1593
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
Package.describe({
name: 'twbs:bootstrap', // https://atmospherejs.com/twbs/bootstrap
summary: 'The most popular front-end framework for developing responsive, mobile first projects on the web.',
version: '5.3.6',
version: '5.3.7',
git: 'https://github.com/twbs/bootstrap.git'
})

View File

@ -1,7 +1,7 @@
{
"name": "bootstrap",
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
"version": "5.3.6",
"version": "5.3.7",
"config": {
"version_short": "5.3"
},
@ -100,9 +100,9 @@
"watch-css-test": "nodemon --watch scss/ --ext scss,js --exec \"npm run css-test\"",
"watch-js-main": "nodemon --watch js/src/ --ext js --exec \"npm-run-all js-lint js-compile\"",
"watch-js-docs": "nodemon --watch site/src/assets/ --ext js --exec \"npm run js-lint\"",
"astro-dev": "astro dev --root site",
"astro-dev": "astro dev --root site --port 9001",
"astro-build": "astro build --root site && rm -rf _site && cp -r site/dist _site",
"astro-preview": "astro preview --root site"
"astro-preview": "astro preview --root site --port 9001"
},
"peerDependencies": {
"@popperjs/core": "^2.11.8"
@ -112,21 +112,21 @@
"@astrojs/markdown-remark": "^6.3.2",
"@astrojs/mdx": "^4.3.0",
"@astrojs/prism": "^3.3.0",
"@astrojs/sitemap": "^3.4.0",
"@babel/cli": "^7.27.2",
"@babel/core": "^7.27.4",
"@babel/preset-env": "^7.27.2",
"@astrojs/sitemap": "^3.4.1",
"@babel/cli": "^7.28.0",
"@babel/core": "^7.28.0",
"@babel/preset-env": "^7.28.0",
"@docsearch/js": "^3.9.0",
"@popperjs/core": "^2.11.8",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-commonjs": "^28.0.3",
"@rollup/plugin-commonjs": "^28.0.6",
"@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-replace": "^6.0.2",
"@stackblitz/sdk": "^1.11.0",
"@types/js-yaml": "^4.0.9",
"@types/mime": "^4.0.0",
"@types/prismjs": "^1.26.5",
"astro": "^5.8.1",
"astro": "^5.11.0",
"astro-auto-import": "^0.4.4",
"autoprefixer": "^10.4.21",
"bundlewatch": "^0.4.1",
@ -136,7 +136,7 @@
"eslint": "8.57.1",
"eslint-config-xo": "0.45.0",
"eslint-plugin-html": "^8.1.3",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-markdown": "^5.1.0",
"eslint-plugin-unicorn": "56.0.1",
"find-unused-sass-variables": "^6.1.0",
@ -146,7 +146,7 @@
"htmlparser2": "^10.0.0",
"image-size": "^2.0.2",
"ip": "^2.0.1",
"jasmine": "^5.7.1",
"jasmine": "^5.8.0",
"jquery": "^3.7.1",
"js-yaml": "^4.1.0",
"karma": "^6.4.4",
@ -162,25 +162,25 @@
"mime": "^4.0.7",
"nodemon": "^3.1.10",
"npm-run-all2": "^8.0.4",
"postcss": "^8.5.4",
"postcss": "^8.5.6",
"postcss-cli": "^11.0.1",
"prettier": "^3.5.3",
"prettier": "^3.6.2",
"prettier-plugin-astro": "^0.14.1",
"rehype-autolink-headings": "^7.1.0",
"remark": "^15.0.1",
"remark-html": "^16.0.1",
"rollup": "^4.41.1",
"rollup": "^4.44.2",
"rollup-plugin-istanbul": "^5.0.0",
"rtlcss": "^4.3.0",
"sass": "1.78.0",
"sass-true": "^8.1.0",
"sass-true": "^9.0.0",
"shelljs": "^0.10.0",
"stylelint": "^16.20.0",
"stylelint-config-twbs-bootstrap": "^16.0.0",
"terser": "^5.40.0",
"stylelint": "^16.21.1",
"stylelint-config-twbs-bootstrap": "^16.1.0",
"terser": "^5.43.1",
"unist-util-visit": "^5.0.0",
"vnu-jar": "24.10.17",
"zod": "^3.25.42"
"zod": "^3.25.76"
},
"files": [
"dist/{css,js}/*.{css,js,map}",

View File

@ -157,7 +157,7 @@ $_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003
@each $color in $foregrounds {
$contrast-ratio: contrast-ratio($background, $color);
@if $contrast-ratio > $min-contrast-ratio {
@if $contrast-ratio >= $min-contrast-ratio {
@return $color;
} @else if $contrast-ratio > $max-ratio {
$max-ratio: $contrast-ratio;

View File

@ -1,6 +1,6 @@
@mixin bsBanner($file) {
/*!
* Bootstrap #{$file} v5.3.6 (https://getbootstrap.com/)
* Bootstrap #{$file} v5.3.7 (https://getbootstrap.com/)
* Copyright 2011-2025 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/

View File

@ -0,0 +1,139 @@
@import "../../functions";
@import "../../variables";
@import "../../variables-dark";
@import "../../maps";
@import "../../mixins";
@include describe("color-contrast function") {
@include it("should return a color when contrast ratio equals minimum requirement (WCAG 2.1 compliance)") {
// Test case: Background color that produces contrast ratio close to 4.5:1
// This tests the WCAG 2.1 requirement that contrast should be "at least 4.5:1" (>= 4.5)
// rather than "strictly greater than 4.5:1" (> 4.5)
// #777777 produces 4.4776:1 contrast ratio with white text
// Since this is below the 4.5:1 threshold, it should return the highest available contrast color
$test-background: #777;
$result: color-contrast($test-background);
@include assert-equal($result, $black, "Should return black (highest available contrast) for background with 4.4776:1 contrast ratio (below threshold)");
}
@include it("should return a color when contrast ratio is above minimum requirement") {
// Test case: Background color that produces contrast ratio above 4.5:1
// #767676 produces 4.5415:1 contrast ratio with white text
$test-background: #767676;
$result: color-contrast($test-background);
@include assert-equal($result, $white, "Should return white for background with 4.5415:1 contrast ratio (above threshold)");
}
@include it("should return a color when contrast ratio is below minimum requirement") {
// Test case: Background color that produces contrast ratio below 4.5:1
// #787878 produces 4.4155:1 contrast ratio with white text
$test-background: #787878;
$result: color-contrast($test-background);
// Should return the color with the highest available contrast ratio
@include assert-equal($result, $black, "Should return black (highest available contrast) for background with 4.4155:1 contrast ratio (below threshold)");
}
@include it("should handle edge case with very light background") {
// Test case: Very light background that should return dark text
$test-background: #f8f9fa; // Very light gray
$result: color-contrast($test-background);
@include assert-equal($result, $color-contrast-dark, "Should return dark text for very light background");
}
@include it("should handle edge case with very dark background") {
// Test case: Very dark background that should return light text
$test-background: #212529; // Very dark gray
$result: color-contrast($test-background);
@include assert-equal($result, $color-contrast-light, "Should return light text for very dark background");
}
@include it("should work with custom minimum contrast ratio") {
// Test case: Using a custom minimum contrast ratio
$test-background: #666;
$result: color-contrast($test-background, $color-contrast-dark, $color-contrast-light, 3);
@include assert-equal($result, $white, "Should return white when using custom minimum contrast ratio of 3.0");
}
@include it("should test contrast ratio calculation accuracy") {
// Test case: Verify that contrast-ratio function works correctly
$background: #767676;
$foreground: $white;
$ratio: contrast-ratio($background, $foreground);
// Bootstrap's implementation calculates this as ~4.5415, not exactly 4.5, due to its luminance math.
// We use 4.54 as the threshold for this test to match the actual implementation.
@include assert-true($ratio >= 4.54 and $ratio <= 4.55, "Contrast ratio should be approximately 4.54:1 (Bootstrap's math)");
}
@include it("should test luminance calculation") {
// Test case: Verify luminance function works correctly
$white-luminance: luminance($white);
$black-luminance: luminance($black);
@include assert-equal($white-luminance, 1, "White should have luminance of 1");
@include assert-equal($black-luminance, 0, "Black should have luminance of 0");
}
@include it("should handle rgba colors correctly") {
// Test case: Test with rgba colors
$test-background: rgba(118, 118, 118, 1); // Same as #767676
$result: color-contrast($test-background);
@include assert-equal($result, $white, "Should handle rgba colors correctly");
}
@include it("should test the WCAG 2.1 boundary condition with color below threshold") {
// Test case: Background color that produces contrast ratio below 4.5:1
// #787878 produces 4.4155:1 contrast ratio with white
$test-background: #787878; // Produces 4.4155:1 contrast ratio
$contrast-ratio: contrast-ratio($test-background, $white);
// Verify the contrast ratio is below 4.5:1
@include assert-true($contrast-ratio < 4.5, "Contrast ratio should be below 4.5:1 threshold");
// The color-contrast function should return the color with highest available contrast
$result: color-contrast($test-background);
@include assert-equal($result, $black, "color-contrast should return black (highest available contrast) for below-threshold ratio");
}
@include it("should test the WCAG 2.1 boundary condition with color at threshold") {
// Test case: Background color that produces contrast ratio close to 4.5:1
// #777777 produces 4.4776:1 contrast ratio with white
$test-background: #777; // Produces 4.4776:1 contrast ratio
$contrast-ratio: contrast-ratio($test-background, $white);
// Verify the contrast ratio is below 4.5:1 threshold
@include assert-true($contrast-ratio < 4.5, "Contrast ratio is below threshold, function should handle gracefully");
}
@include it("should demonstrate the difference between > and >= operators") {
// Test case: Demonstrates the difference between > and >= operators
// Uses #767676 with a custom minimum contrast ratio that matches its actual ratio (4.5415)
// With > 4.5415: should return black (fallback to highest available)
// With >= 4.5415: should return white (meets threshold)
$test-background: #767676; // Produces 4.5415:1 contrast ratio
$actual-ratio: contrast-ratio($test-background, $white);
// Test with a custom minimum that matches the actual ratio
$result: color-contrast($test-background, $color-contrast-dark, $color-contrast-light, $actual-ratio);
// Should return white when using >= implementation
@include assert-equal($result, $white, "color-contrast should return white when using exact ratio as threshold (>= implementation)");
}
@include it("should test additional working colors above threshold") {
// Test case: Background color that produces contrast ratio well above 4.5:1
// #757575 produces 4.6047:1 contrast ratio with white text
$test-background: #757575; // Produces 4.6047:1 contrast ratio
$result: color-contrast($test-background);
@include assert-equal($result, $white, "Should return white for background with 4.6047:1 contrast ratio (well above threshold)");
}
}

View File

@ -9,7 +9,7 @@ const isDev = process.env.NODE_ENV === 'development'
const site = isDev
? // In development mode, use the local dev server.
'http://localhost:4321'
'http://localhost:9001'
: process.env.DEPLOY_PRIME_URL !== undefined
? // If deploying on Netlify, use the `DEPLOY_PRIME_URL` environment variable.
process.env.DEPLOY_PRIME_URL

View File

@ -48,7 +48,7 @@
- group: v5.x
baseurl: 'https://getbootstrap.com/docs'
description: 'Current major release. Last update was v5.3.6.'
description: 'Current major release. Last update was v5.3.7.'
versions:
- '5.0'
- '5.1'

View File

@ -1418,41 +1418,41 @@ import Placeholder from "@shortcodes/Placeholder.astro"
</div>
<div>
<div class="bd-example">
<nav id="navbar-example2" class="navbar bg-body-tertiary px-3">
<a class="navbar-brand" href="#">شريط التنقل</a>
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link" href="#fat"><bdi lang="en" dir="ltr">@fat</bdi></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#mdo"><bdi lang="en" dir="ltr">@mdo</bdi></a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">قائمة منسدلة</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#one">واحد</a></li>
<li><a class="dropdown-item" href="#two">اثنان</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#three">ثلاثة</a></li>
</ul>
</li>
</ul>
</nav>
<div data-bs-spy="scroll" data-bs-target="#navbar-example2" data-bs-offset="0" class="scrollspy-example position-relative mt-2 overflow-auto">
<h4 id="fat"><bdi lang="en" dir="ltr">@fat</bdi></h4>
<p>محتوى لتوضيح كيف تعمل المخطوطة. ببساطة، المخطوطة عبارة عن منشور طويل يحتوي على عدة أقسام، ولديه شريط تنقل يسهل الوصول إلى هذه الأقسام الفرعية.</p>
<h4 id="mdo"><bdi lang="en" dir="ltr">@mdo</bdi></h4>
<p>بصرف النظر عن تحسيننا جدوى المكيّفات أو عدم تحسينها، فإن الطلب على الطاقة سيزداد. وطبقاً لما جاء في مقالة معهد ماساشوستس للتكنولوجيا، السالف ذكره، ثمَّة أمر يجب عدم إغفاله، وهو كيف أن هذا الطلب سيضغط على نظم توفير الطاقة الحالية. إذ لا بد من إعادة تأهيل كل شبكات الكهرباء، وتوسيعها لتلبية طلب الطاقة في زمن الذروة، خلال موجات الحرارة المتزايدة. فحين يكون الحر شديداً يجنح الناس إلى البقاء في الداخل، وإلى زيادة تشغيل المكيّفات، سعياً إلى جو لطيف وهم يستخدمون أدوات وأجهزة مختلفة أخرى.</p>
<h4 id="one">واحد</h4>
<p>وكل هذه الأمور المتزامنة من تشغيل الأجهزة، يزيد الضغط على شبكات الطاقة، كما أسلفنا. لكن مجرد زيادة سعة الشبكة ليس كافياً. إذ لا بد من تطوير الشبكات الذكية التي تستخدم الجسّاسات، ونظم المراقبة، والبرامج الإلكترونية، لتحديد متى يكون الشاغلون في المبنى، ومتى يكون ثمَّة حاجة إلى الطاقة، ومتى تكون الحرارة منخفضة، وبذلك يخرج الناس، فلا يستخدمون كثيراً من الكهرباء.</p>
<h4 id="two">اثنان</h4>
<p>مع الأسف، كل هذه الحلول المبتكرة مكلِّفة، وهذا ما يجعلها عديمة الجدوى في نظر بعض الشركات الخاصة والمواطن المتقشّف. إن بعض الأفراد الواعين بيئياً يبذلون قصارى جهدهم في تقليص استهلاكهم من الطاقة، ويعون جيداً أهمية أجهزة التكييف المجدية والأرفق بالبيئة. ولكن جهات كثيرة لن تتحرّك لمجرد حافز سلامة المناخ ووقف هدر الطاقة، ما دامت لا تحركها حوافز قانونية. وعلى الحكومات أن تُقدِم عند الاهتمام بالتغيّر المناخي، على وضع التشريعات المناسبة. فبالنظم والحوافز والدعم، يمكن دفع الشركات إلى اعتماد الحلول الأجدى في مكاتبها.</p>
<h4 id="three">ثلاثة</h4>
<p>وكما يتبيّن لنا، من عدد الحلول الملطِّفة للمشكلة، ومن تنوّعها، وهي الحلول التي أسلفنا الحديث عنها، فإن التكنولوجيا التي نحتاج إليها من أجل معالجة هذه التحديات، هي في مدى قدرتنا، لكنها ربما تتطلّب بعض التحسين، ودعماً استثمارياً أكبر!</p>
<p>ولا مانع من إضافة محتوى آخر ليس تحت أي قسم معين.</p>
</div>
<Example showMarkup={false} code={`
<nav id="navbar-example2" class="navbar bg-body-tertiary px-3">
<a class="navbar-brand" href="#">شريط التنقل</a>
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link" href="#fat"><bdi lang="en" dir="ltr">@fat</bdi></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#mdo"><bdi lang="en" dir="ltr">@mdo</bdi></a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">قائمة منسدلة</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#one">واحد</a></li>
<li><a class="dropdown-item" href="#two">اثنان</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#three">ثلاثة</a></li>
</ul>
</li>
</ul>
</nav>
<div data-bs-spy="scroll" data-bs-target="#navbar-example2" data-bs-offset="0" class="scrollspy-example position-relative mt-2 overflow-auto">
<h4 id="fat"><bdi lang="en" dir="ltr">@fat</bdi></h4>
<p>محتوى لتوضيح كيف تعمل المخطوطة. ببساطة، المخطوطة عبارة عن منشور طويل يحتوي على عدة أقسام، ولديه شريط تنقل يسهل الوصول إلى هذه الأقسام الفرعية.</p>
<h4 id="mdo"><bdi lang="en" dir="ltr">@mdo</bdi></h4>
<p>بصرف النظر عن تحسيننا جدوى المكيّفات أو عدم تحسينها، فإن الطلب على الطاقة سيزداد. وطبقاً لما جاء في مقالة معهد ماساشوستس للتكنولوجيا، السالف ذكره، ثمَّة أمر يجب عدم إغفاله، وهو كيف أن هذا الطلب سيضغط على نظم توفير الطاقة الحالية. إذ لا بد من إعادة تأهيل كل شبكات الكهرباء، وتوسيعها لتلبية طلب الطاقة في زمن الذروة، خلال موجات الحرارة المتزايدة. فحين يكون الحر شديداً يجنح الناس إلى البقاء في الداخل، وإلى زيادة تشغيل المكيّفات، سعياً إلى جو لطيف وهم يستخدمون أدوات وأجهزة مختلفة أخرى.</p>
<h4 id="one">واحد</h4>
<p>وكل هذه الأمور المتزامنة من تشغيل الأجهزة، يزيد الضغط على شبكات الطاقة، كما أسلفنا. لكن مجرد زيادة سعة الشبكة ليس كافياً. إذ لا بد من تطوير الشبكات الذكية التي تستخدم الجسّاسات، ونظم المراقبة، والبرامج الإلكترونية، لتحديد متى يكون الشاغلون في المبنى، ومتى يكون ثمَّة حاجة إلى الطاقة، ومتى تكون الحرارة منخفضة، وبذلك يخرج الناس، فلا يستخدمون كثيراً من الكهرباء.</p>
<h4 id="two">اثنان</h4>
<p>مع الأسف، كل هذه الحلول المبتكرة مكلِّفة، وهذا ما يجعلها عديمة الجدوى في نظر بعض الشركات الخاصة والمواطن المتقشّف. إن بعض الأفراد الواعين بيئياً يبذلون قصارى جهدهم في تقليص استهلاكهم من الطاقة، ويعون جيداً أهمية أجهزة التكييف المجدية والأرفق بالبيئة. ولكن جهات كثيرة لن تتحرّك لمجرد حافز سلامة المناخ ووقف هدر الطاقة، ما دامت لا تحركها حوافز قانونية. وعلى الحكومات أن تُقدِم عند الاهتمام بالتغيّر المناخي، على وضع التشريعات المناسبة. فبالنظم والحوافز والدعم، يمكن دفع الشركات إلى اعتماد الحلول الأجدى في مكاتبها.</p>
<h4 id="three">ثلاثة</h4>
<p>وكما يتبيّن لنا، من عدد الحلول الملطِّفة للمشكلة، ومن تنوّعها، وهي الحلول التي أسلفنا الحديث عنها، فإن التكنولوجيا التي نحتاج إليها من أجل معالجة هذه التحديات، هي في مدى قدرتنا، لكنها ربما تتطلّب بعض التحسين، ودعماً استثمارياً أكبر!</p>
<p>ولا مانع من إضافة محتوى آخر ليس تحت أي قسم معين.</p>
</div>
`} />
</div>
</article>
<article class="my-3" id="spinners">

View File

@ -1223,7 +1223,7 @@ export const body_class = 'bg-body-tertiary'
</div>
</div>
</nav>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary mt-5">
<div class="container-fluid">
<a class="navbar-brand" href="#">
@ -1394,40 +1394,40 @@ export const body_class = 'bg-body-tertiary'
</div>
<div>
<div class="bd-example">
<nav id="navbar-example2" class="navbar bg-body-tertiary px-3">
<a class="navbar-brand" href="#">Navbar</a>
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link active" href="#scrollspyHeading1">First</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#scrollspyHeading2">Second</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Dropdown</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#scrollspyHeading3">Third</a></li>
<li><a class="dropdown-item" href="#scrollspyHeading4">Fourth</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#scrollspyHeading5">Fifth</a></li>
</ul>
</li>
</ul>
</nav>
<Example showMarkup={false} code={`
<nav id="navbar-example2" class="navbar bg-body-tertiary px-3">
<a class="navbar-brand" href="#">Navbar</a>
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link active" href="#scrollspyHeading1">First</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#scrollspyHeading2">Second</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Dropdown</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#scrollspyHeading3">Third</a></li>
<li><a class="dropdown-item" href="#scrollspyHeading4">Fourth</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#scrollspyHeading5">Fifth</a></li>
</ul>
</li>
</ul>
</nav>
<div data-bs-spy="scroll" data-bs-target="#navbar-example2" data-bs-offset="0" class="scrollspy-example position-relative mt-2 overflow-auto" tabindex="0">
<h4 id="scrollspyHeading1">First heading</h4>
<p>This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.</p>
<h4 id="scrollspyHeading2">Second heading</h4>
<p>This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.</p>
<h4 id="scrollspyHeading3">Third heading</h4>
<p>This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.</p>
<h4 id="scrollspyHeading4">Fourth heading</h4>
<p>This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.</p>
<h4 id="scrollspyHeading5">Fifth heading</h4>
<p>This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.</p>
</div>
<h4 id="scrollspyHeading1">First heading</h4>
<p>This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.</p>
<h4 id="scrollspyHeading2">Second heading</h4>
<p>This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.</p>
<h4 id="scrollspyHeading3">Third heading</h4>
<p>This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.</p>
<h4 id="scrollspyHeading4">Fourth heading</h4>
<p>This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.</p>
<h4 id="scrollspyHeading5">Fifth heading</h4>
<p>This is some placeholder content for the scrollspy page. Note that as you scroll down the page, the appropriate navigation link is highlighted. It's repeated throughout the component example. We keep adding some more example copy here to emphasize the scrolling and highlighting.</p>
</div>
`} />
</div>
</article>
<article class="my-3" id="spinners">

View File

@ -435,7 +435,7 @@ export const extra_css = ['navbars.css']
</nav>
<div>
<div class="bg-body-tertiaryp-5 rounded">
<div class="bg-body-tertiary p-5 rounded">
<div class="col-sm-8 mx-auto">
<h1>Navbar examples</h1>
<p>This example is a quick exercise to illustrate how the navbar and its contents work. Some navbars extend the width of the viewport, others are confined within a <code>.container</code>. For positioning of navbars, checkout the <a href={getVersionedDocsPath('/examples/navbar-static/')}>top</a> and <a href={getVersionedDocsPath('/examples/navbar-fixed/')}>fixed top</a> examples.</p>

View File

@ -6,7 +6,6 @@ import Stylesheet from '@components/head/Stylesheet.astro'
import Favicons from '@components/head/Favicons.astro'
import Social from '@components/head/Social.astro'
import Analytics from '@components/head/Analytics.astro'
import Scss from '@components/head/Scss.astro'
interface Props {
description: string
@ -25,6 +24,10 @@ const isHome = Astro.url.pathname === '/'
const pageTitle = isHome
? `${getConfig().title} · ${getConfig().subtitle}`
: `${title} · ${getConfig().title} v${getConfig().docs_version}`
// Dynamic imports to avoid build-time processing
const Scss = import.meta.env.PROD ? null : await import('@components/head/Scss.astro')
const ScssProd = import.meta.env.PROD ? await import('@components/head/ScssProd.astro') : null
---
<meta charset="UTF-8" />
@ -47,8 +50,15 @@ const pageTitle = isHome
<script is:inline src={getVersionedDocsPath('assets/js/color-modes.js')}></script>
<Stylesheet direction={direction} layout={layout} />
<Scss />
{import.meta.env.PROD && ScssProd && (
<Stylesheet direction={direction} layout={layout} />
<ScssProd.default />
)}
{!import.meta.env.PROD && Scss && (
<Scss.default />
)}
<Favicons />
<Social description={description} layout={layout} thumbnail={thumbnail} title={title} />
<Analytics />

View File

@ -2,6 +2,7 @@
---
<style is:global lang="scss">
@import '../../../../scss/bootstrap.scss';
@import '../../scss/docs';
@import '../../scss/docs_search';
</style>

View File

@ -0,0 +1,7 @@
---
---
<style is:global lang="scss">
@import '../../scss/docs';
@import '../../scss/docs_search';
</style>

View File

@ -40,7 +40,7 @@ try {
content = matches[1]
// Fix the identation by removing extra spaces at the beginning of each line
// Fix the indentation by removing extra spaces at the beginning of each line
const lines = content.split('\n')
const spaceCounts = lines.filter((line) => line.trim().length > 0).map((line) => line.match(/^ */)[0].length)
const minSpaces = spaceCounts.length ? Math.min(...spaceCounts) : 0

View File

@ -42,7 +42,7 @@ try {
content = matches[1].replaceAll(' !default', '')
// Fix the identation by removing extra spaces at the beginning of each line
// Fix the indentation by removing extra spaces at the beginning of each line
const lines = content.split('\n')
const spaceCounts = lines.filter((line) => line.trim().length > 0).map((line) => line.match(/^ */)[0].length)
const minSpaces = spaceCounts.length ? Math.min(...spaceCounts) : 0

View File

@ -1,5 +1,6 @@
---
import Code from '@shortcodes/Code.astro'
import Example from '@shortcodes/Example.astro'
import * as tableContent from '@shortcodes/TableContent.md'
interface Props {
@ -20,12 +21,12 @@ const { class: className, simplified = true } = Astro.props
const tableCode = `<table${className ? ` class="${className}"` : ''}>
${simplified ? ' ...' : await tableContent.compiledContent()}
</table>`
const exampleCode = `<table${className ? ` class="${className}"` : ''}>
${await tableContent.compiledContent()}
</table>`
---
<div class="bd-example">
<table class={className}>
<tableContent.Content />
</table>
</div>
<Example showMarkup={false} code={exampleCode} />
<Code code={tableCode} lang="html" />

View File

@ -200,9 +200,9 @@ Each `.btn-*` modifier class updates the appropriate CSS variables to minimize a
Heres an example of building a custom `.btn-*` modifier class as we do for the buttons unique to our docs by reassigning Bootstraps CSS variables with a mixture of our own CSS and Sass variables.
<div class="bd-example">
<button type="button" class="btn btn-bd-primary">Custom button</button>
</div>
<Example showMarkup={false} code={`
<button type="button" class="btn btn-bd-primary">Custom button</button>
`} />
<ScssDocs name="btn-css-vars-example" file="site/src/scss/_buttons.scss" />

View File

@ -100,9 +100,9 @@ Toggle a working modal demo by clicking the button below. It will slide down and
</div>
</div>
<div class="bd-example">
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalLive">Launch demo modal</button>
</div>
<Example showMarkup={false} code={`
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalLive">Launch demo modal</button>
`} />
```html
<!-- Button trigger modal -->
@ -152,9 +152,9 @@ When backdrop is set to static, the modal will not close when clicking outside o
</div>
</div>
<div class="bd-example">
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#staticBackdropLive">Launch static backdrop modal</button>
</div>
<Example showMarkup={false} code={`
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#staticBackdropLive">Launch static backdrop modal</button>
`} />
```html
<!-- Button trigger modal -->
@ -204,9 +204,9 @@ When modals become too long for the users viewport or device, they scroll ind
</div>
</div>
<div class="bd-example">
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalLong">Launch demo modal</button>
</div>
<Example showMarkup={false} code={`
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalLong">Launch demo modal</button>
`} />
You can also create a scrollable modal that allows scrolling the modal body by adding `.modal-dialog-scrollable` to `.modal-dialog`.
@ -230,9 +230,9 @@ You can also create a scrollable modal that allows scrolling the modal body by a
</div>
</div>
<div class="bd-example">
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalScrollable">Launch demo modal</button>
</div>
<Example showMarkup={false} code={`
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModalScrollable">Launch demo modal</button>
`} />
```html
<!-- Scrollable modal -->
@ -383,9 +383,9 @@ Utilize the Bootstrap grid system within a modal by nesting `.container-fluid` w
</div>
</div>
<div class="bd-example">
<Example showMarkup={false} code={`
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#gridSystemModal">Launch demo modal</button>
</div>
`} />
```html
<div class="modal-body">

View File

@ -302,94 +302,94 @@ Mix and match with other components and utilities as needed.
Navbar themes are easier than ever thanks to Bootstraps combination of Sass and CSS variables. The default is our “light navbar” for use with light background colors, but you can also apply `data-bs-theme="dark"` to the `.navbar` parent for dark background colors. Then, customize with `.bg-*` and additional utilities.
<div class="bd-example">
<nav class="navbar navbar-expand-lg bg-dark border-bottom border-body" data-bs-theme="dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarColor01" aria-controls="navbarColor01" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarColor01">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Features</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Pricing</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
</ul>
<form class="d-flex" role="search">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search"/>
<button class="btn btn-outline-light" type="submit">Search</button>
</form>
</div>
<Example showMarkup={false} code={`
<nav class="navbar navbar-expand-lg bg-dark border-bottom border-body" data-bs-theme="dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarColor01" aria-controls="navbarColor01" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarColor01">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Features</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Pricing</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
</ul>
<form class="d-flex" role="search">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search"/>
<button class="btn btn-outline-light" type="submit">Search</button>
</form>
</div>
</nav>
</div>
</nav>
<nav class="navbar navbar-expand-lg bg-primary" data-bs-theme="dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarColor02" aria-controls="navbarColor02" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarColor02">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Features</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Pricing</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
</ul>
<form class="d-flex" role="search">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search"/>
<button class="btn btn-outline-light" type="submit">Search</button>
</form>
</div>
<nav class="navbar navbar-expand-lg bg-primary" data-bs-theme="dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarColor02" aria-controls="navbarColor02" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarColor02">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Features</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Pricing</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
</ul>
<form class="d-flex" role="search">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search"/>
<button class="btn btn-outline-light" type="submit">Search</button>
</form>
</div>
</nav>
</div>
</nav>
<nav class="navbar navbar-expand-lg" style="background-color: #e3f2fd;" data-bs-theme="light">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarColor03" aria-controls="navbarColor03" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarColor03">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Features</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Pricing</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
</ul>
<form class="d-flex" role="search">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search"/>
<button class="btn btn-outline-primary" type="submit">Search</button>
</form>
</div>
<nav class="navbar navbar-expand-lg" style="background-color: #e3f2fd;" data-bs-theme="light">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarColor03" aria-controls="navbarColor03" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarColor03">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Features</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Pricing</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
</ul>
<form class="d-flex" role="search">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search"/>
<button class="btn btn-outline-primary" type="submit">Search</button>
</form>
</div>
</nav>
</div>
</div>
</nav>
`} />
```html
<nav class="navbar bg-dark border-bottom border-body" data-bs-theme="dark">

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