Compare commits
74 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f5c8756283 | |||
| 95c97cd3bd | |||
| 97ce2abd4f | |||
| e20a43bbb5 | |||
| fa3e4fe949 | |||
| c49c641e01 | |||
| 4aeb37d2b9 | |||
| 91563e26d8 | |||
| 8a4945db28 | |||
| 5c3aa0e9f4 | |||
| 49478f2a59 | |||
| 5cea91b303 | |||
| e929e0cdcf | |||
| da5c4316ed | |||
| f0c333e3f2 | |||
| 058a270338 | |||
| 6359cb7d0f | |||
| d809eef178 | |||
| 1391f89052 | |||
| ad3bffc613 | |||
| 0cd00d3703 | |||
| 08508c5024 | |||
| 4a3272d2d8 | |||
| 57a81db0cf | |||
| 4634b58cd8 | |||
| 808e15d387 | |||
| 31eb33577b | |||
| 15e61ae916 | |||
| 015f19a0a3 | |||
| 18f90fbd3b | |||
| 7f9c85d5bb | |||
| a9822ac21c | |||
| 509332ee40 | |||
| f3f3ef99e4 | |||
| d30d9bfd96 | |||
| f9c74a0974 | |||
| 13a3d3e744 | |||
| e6d82194ac | |||
| 396f2bc4db | |||
| 24f2269928 | |||
| 142a16fe55 | |||
| 684673f314 | |||
| bcb50912cd | |||
| 785c31f79b | |||
| e09539933c | |||
| cc31550def | |||
| 88fbaa9073 | |||
| e311985f1e | |||
| 12fb082b3b | |||
| 9f8967d470 | |||
| 02c1e34645 | |||
| 6e9f89d81d | |||
| 0e25f4f25f | |||
| 4dc3e62ec2 | |||
| d1fe9fedba | |||
| 125651adbd | |||
| eb3622e4ce | |||
| 3f88e39de9 | |||
| 37d579548a | |||
| 78b6a5a0ad | |||
| 958b029988 | |||
| 80c4f78ffb | |||
| c1e8462c4b | |||
| 0f5fba9c63 | |||
| 06df112bc1 | |||
| 21a94cae37 | |||
| c4fefeba36 | |||
| 6f48778940 | |||
| 769d539f22 | |||
| 3ce5bfcfb2 | |||
| 8692a00565 | |||
| ede41f571b | |||
| 7d8b2f0ded | |||
| 726d4fa16c |
@@ -1,5 +1,6 @@
|
||||
# https://github.com/browserslist/browserslist#readme
|
||||
|
||||
>= 0.5%
|
||||
last 2 major versions
|
||||
not dead
|
||||
Chrome >= 120
|
||||
@@ -7,4 +8,5 @@ Firefox >= 121
|
||||
iOS >= 15.6
|
||||
Safari >= 15.6
|
||||
not Explorer <= 11
|
||||
Samsung >= 23
|
||||
not kaios <= 2.5 # fix floating label issues in Firefox (see https://github.com/postcss/autoprefixer/issues/1533)
|
||||
|
||||
@@ -1,60 +1,36 @@
|
||||
{
|
||||
"files": [
|
||||
{
|
||||
"path": "./dist/css/bootstrap-grid.css",
|
||||
"maxSize": "9.5 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/bootstrap-grid.min.css",
|
||||
"maxSize": "8.5 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/bootstrap-reboot.css",
|
||||
"maxSize": "5.25 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/bootstrap-reboot.min.css",
|
||||
"maxSize": "4.25 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/bootstrap-utilities.css",
|
||||
"maxSize": "14.5 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/bootstrap-utilities.min.css",
|
||||
"maxSize": "12.75 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/bootstrap.css",
|
||||
"maxSize": "36.0 kB"
|
||||
"maxSize": "34 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/css/bootstrap.min.css",
|
||||
"maxSize": "32.5 kB"
|
||||
"maxSize": "32 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/js/bootstrap.bundle.js",
|
||||
"maxSize": "49.75 kB"
|
||||
"maxSize": "43.0 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/js/bootstrap.bundle.min.js",
|
||||
"maxSize": "26.0 kB"
|
||||
"maxSize": "23.5 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/js/bootstrap.esm.js",
|
||||
"maxSize": "36.0 kB"
|
||||
"maxSize": "28.0 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/js/bootstrap.esm.min.js",
|
||||
"maxSize": "22.25 kB"
|
||||
"maxSize": "18.25 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/js/bootstrap.js",
|
||||
"maxSize": "36.5 kB"
|
||||
"maxSize": "28.75 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/js/bootstrap.min.js",
|
||||
"maxSize": "19.75 kB"
|
||||
"maxSize": "16.25 kB"
|
||||
}
|
||||
],
|
||||
"ci": {
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
"callout",
|
||||
"callouts",
|
||||
"camelCase",
|
||||
"checkgroup",
|
||||
"clearfix",
|
||||
"Codesniffer",
|
||||
"combinator",
|
||||
@@ -48,7 +47,6 @@
|
||||
"favicons",
|
||||
"fieldsets",
|
||||
"flexbox",
|
||||
"frontmatter",
|
||||
"fullscreen",
|
||||
"getbootstrap",
|
||||
"Grayscale",
|
||||
|
||||
@@ -27,6 +27,9 @@ restrictions:
|
||||
Use [GitHub's "reactions" feature](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/)
|
||||
instead. We reserve the right to delete comments which violate this rule.
|
||||
|
||||
- Please **do not** open issues regarding the official themes offered on <https://themes.getbootstrap.com/>.
|
||||
Instead, please email any questions or feedback regarding those themes to `themes AT getbootstrap DOT com`.
|
||||
|
||||
|
||||
## Issues assignment
|
||||
|
||||
|
||||
@@ -7,10 +7,6 @@ updates:
|
||||
day: tuesday
|
||||
time: "12:00"
|
||||
timezone: Europe/Athens
|
||||
groups:
|
||||
github-actions:
|
||||
patterns:
|
||||
- "*"
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
labels:
|
||||
|
||||
@@ -22,12 +22,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
|
||||
@@ -4,7 +4,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- v6-dev
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -21,12 +20,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
|
||||
@@ -18,16 +18,15 @@ jobs:
|
||||
name: calibreapp/image-actions
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# allow calibreapp/image-actions to update PRs and commit compressed images
|
||||
contents: write
|
||||
# allow calibreapp/image-actions to update PRs
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Compress Images
|
||||
uses: calibreapp/image-actions@f32575787d333b0579f0b7d506ff03be63a669d1 # v1.4.1
|
||||
uses: calibreapp/image-actions@1.1.0
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
githubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -5,13 +5,11 @@ on:
|
||||
branches:
|
||||
- main
|
||||
- v4-dev
|
||||
- v6-dev
|
||||
- "!dependabot/**"
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- v4-dev
|
||||
- v6-dev
|
||||
- "!dependabot/**"
|
||||
schedule:
|
||||
- cron: "0 2 * * 4"
|
||||
@@ -26,21 +24,21 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
languages: "javascript"
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:javascript"
|
||||
|
||||
@@ -4,7 +4,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- v6-dev
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -24,12 +23,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Run cspell
|
||||
uses: streetsidesoftware/cspell-action@3294df585d3d639e30f3bc019cb11940b9866e95 # v8.0.0
|
||||
uses: streetsidesoftware/cspell-action@v7
|
||||
with:
|
||||
config: ".cspell.json"
|
||||
files: "**/*.{md,mdx}"
|
||||
|
||||
@@ -4,7 +4,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- v6-dev
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -21,12 +20,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
|
||||
@@ -4,7 +4,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- v6-dev
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -21,16 +20,18 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
|
||||
- run: java -version
|
||||
|
||||
- name: Install npm dependencies
|
||||
run: npm ci
|
||||
|
||||
@@ -38,12 +39,12 @@ jobs:
|
||||
run: npm run docs-build
|
||||
|
||||
- name: Validate HTML
|
||||
run: npm run docs-html-validate
|
||||
run: npm run docs-vnu
|
||||
|
||||
- name: Run linkinator
|
||||
uses: JustinBeckwith/linkinator-action@af984b9f30f63e796ae2ea5be5e07cb587f1bbd9 # v2.3
|
||||
uses: JustinBeckwith/linkinator-action@v1
|
||||
with:
|
||||
paths: _site
|
||||
recurse: true
|
||||
verbosity: error
|
||||
skip: "^http://localhost"
|
||||
skip: "^(?!http://localhost)"
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
if: github.repository == 'twbs/bootstrap'
|
||||
steps:
|
||||
- name: awaiting reply
|
||||
uses: actions-cool/issues-helper@9861779a695cf1898bd984c727f685f351cfc372 # v3.7.2
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: "close-issues"
|
||||
labels: "awaiting-reply"
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
steps:
|
||||
- name: awaiting reply
|
||||
if: github.event.label.name == 'needs-example'
|
||||
uses: actions-cool/issues-helper@9861779a695cf1898bd984c727f685f351cfc372 # v3.7.2
|
||||
uses: actions-cool/issues-helper@v3
|
||||
with:
|
||||
actions: "create-comment"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -4,7 +4,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- v6-dev
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -26,12 +25,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ env.NODE }}
|
||||
cache: npm
|
||||
@@ -46,7 +45,7 @@ jobs:
|
||||
run: npm run js-test
|
||||
|
||||
- name: Run Coveralls
|
||||
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2.3.6
|
||||
uses: coverallsapp/github-action@v2
|
||||
if: ${{ !github.event.repository.fork }}
|
||||
with:
|
||||
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
@@ -4,7 +4,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- v6-dev
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -21,12 +20,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "${{ env.NODE }}"
|
||||
cache: npm
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
name: Publish NuGet Packages
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
package-nuget:
|
||||
runs-on: windows-latest
|
||||
if: ${{ github.repository == 'twbs/bootstrap' && startsWith(github.event.release.tag_name, 'v') }}
|
||||
env:
|
||||
GITHUB_REF_NAME: ${{ github.ref_name }}
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up NuGet
|
||||
uses: nuget/setup-nuget@323ab0502cd38fdc493335025a96c8fdb0edc71f # v2.0.1
|
||||
with:
|
||||
nuget-api-key: ${{ secrets.NuGetAPIKey }}
|
||||
nuget-version: '5.x'
|
||||
|
||||
- name: Pack NuGet packages
|
||||
shell: pwsh
|
||||
run: |
|
||||
$bsversion = $env:GITHUB_REF_NAME.Substring(1)
|
||||
nuget pack "nuget\bootstrap.nuspec" -Verbosity detailed -NonInteractive -BasePath . -Version $bsversion
|
||||
nuget pack "nuget\bootstrap.sass.nuspec" -Verbosity detailed -NonInteractive -BasePath . -Version $bsversion
|
||||
nuget push "bootstrap.$bsversion.nupkg" -Verbosity detailed -NonInteractive -Source "https://api.nuget.org/v3/index.json"
|
||||
nuget push "bootstrap.sass.$bsversion.nupkg" -Verbosity detailed -NonInteractive -Source "https://api.nuget.org/v3/index.json"
|
||||
@@ -4,7 +4,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- v6-dev
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
@@ -19,6 +18,6 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'twbs/bootstrap'
|
||||
steps:
|
||||
- uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6.1.0
|
||||
- uses: release-drafter/release-drafter@v6
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
# This workflow uses actions that are not certified by GitHub. They are provided
|
||||
# by a third-party and are governed by separate terms of service, privacy
|
||||
# policy, and support documentation.
|
||||
|
||||
name: Scorecard supply-chain security
|
||||
on:
|
||||
# For Branch-Protection check. Only the default branch is supported. See
|
||||
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
|
||||
branch_protection_rule:
|
||||
# To guarantee Maintained check is occasionally updated. See
|
||||
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
|
||||
schedule:
|
||||
- cron: '27 12 * * 2'
|
||||
push:
|
||||
branches: [ "main", "v6-dev" ]
|
||||
|
||||
# Declare default permissions as read only.
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
analysis:
|
||||
name: Scorecard analysis
|
||||
runs-on: ubuntu-latest
|
||||
# `publish_results: true` only works when run from the default branch. conditional can be removed if disabled.
|
||||
if: github.event.repository.default_branch == github.ref_name || github.event_name == 'pull_request'
|
||||
permissions:
|
||||
# Needed to upload the results to code-scanning dashboard.
|
||||
security-events: write
|
||||
# Needed to publish results and get a badge (see publish_results below).
|
||||
id-token: write
|
||||
# Uncomment the permissions below if installing in a private repository.
|
||||
# contents: read
|
||||
# actions: read
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
# (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
|
||||
# - you want to enable the Branch-Protection check on a *public* repository, or
|
||||
# - you are installing Scorecard on a *private* repository
|
||||
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action?tab=readme-ov-file#authentication-with-fine-grained-pat-optional.
|
||||
# repo_token: ${{ secrets.SCORECARD_TOKEN }}
|
||||
|
||||
# Public repositories:
|
||||
# - Publish results to OpenSSF REST API for easy access by consumers
|
||||
# - Allows the repository to include the Scorecard badge.
|
||||
# - See https://github.com/ossf/scorecard-action#publishing-results.
|
||||
# For private repositories:
|
||||
# - `publish_results` will always be set to `false`, regardless
|
||||
# of the value entered here.
|
||||
publish_results: true
|
||||
|
||||
# (Optional) Uncomment file_mode if you have a .gitattributes with files marked export-ignore
|
||||
# file_mode: git
|
||||
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
retention-days: 5
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard (optional).
|
||||
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
@@ -18,7 +18,6 @@
|
||||
.cache
|
||||
.DS_Store
|
||||
.idea
|
||||
.nvmrc
|
||||
.project
|
||||
.settings
|
||||
.tmproj
|
||||
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"default": true,
|
||||
"MD004": { "style": "dash" },
|
||||
"MD011": false,
|
||||
"MD013": false,
|
||||
"MD024": false,
|
||||
"MD025": false,
|
||||
@@ -15,4 +14,4 @@
|
||||
"MD046": false,
|
||||
"line-length": false,
|
||||
"no-inline-html": false
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
·
|
||||
<a href="https://github.com/twbs/bootstrap/issues/new?assignees=&labels=feature&template=feature_request.yml">Request feature</a>
|
||||
·
|
||||
<a href="https://themes.getbootstrap.com/">Themes</a>
|
||||
·
|
||||
<a href="https://blog.getbootstrap.com/">Blog</a>
|
||||
</p>
|
||||
|
||||
@@ -44,15 +46,15 @@ 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.8.zip)
|
||||
- [Download the latest release](https://github.com/twbs/bootstrap/archive/v5.3.6.zip)
|
||||
- Clone the repo: `git clone https://github.com/twbs/bootstrap.git`
|
||||
- Install with [npm](https://www.npmjs.com/): `npm install bootstrap@v5.3.8`
|
||||
- Install with [yarn](https://yarnpkg.com/): `yarn add bootstrap@v5.3.8`
|
||||
- Install with [Bun](https://bun.sh/): `bun add bootstrap@v5.3.8`
|
||||
- Install with [Composer](https://getcomposer.org/): `composer require twbs/bootstrap:5.3.8`
|
||||
- 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 [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/) for information on the framework contents, templates, examples, and more.
|
||||
Read the [Getting started page](https://getbootstrap.com/docs/5.3/getting-started/introduction/) for information on the framework contents, templates, examples, and more.
|
||||
|
||||
|
||||
## Status
|
||||
@@ -68,7 +70,6 @@ Read the [Getting started page](https://getbootstrap.com/docs/5.3/getting-starte
|
||||
[](https://github.com/twbs/bootstrap/blob/main/dist/css/bootstrap.min.css)
|
||||
[](https://github.com/twbs/bootstrap/blob/main/dist/js/bootstrap.min.js)
|
||||
[](https://github.com/twbs/bootstrap/blob/main/dist/js/bootstrap.min.js)
|
||||

|
||||
[](#backers)
|
||||
[](#sponsors)
|
||||
|
||||
@@ -87,18 +88,34 @@ Within the download you’ll find the following directories and files, logically
|
||||
│ ├── bootstrap-grid.css.map
|
||||
│ ├── bootstrap-grid.min.css
|
||||
│ ├── bootstrap-grid.min.css.map
|
||||
│ ├── bootstrap-grid.rtl.css
|
||||
│ ├── bootstrap-grid.rtl.css.map
|
||||
│ ├── bootstrap-grid.rtl.min.css
|
||||
│ ├── bootstrap-grid.rtl.min.css.map
|
||||
│ ├── bootstrap-reboot.css
|
||||
│ ├── bootstrap-reboot.css.map
|
||||
│ ├── bootstrap-reboot.min.css
|
||||
│ ├── bootstrap-reboot.min.css.map
|
||||
│ ├── bootstrap-reboot.rtl.css
|
||||
│ ├── bootstrap-reboot.rtl.css.map
|
||||
│ ├── bootstrap-reboot.rtl.min.css
|
||||
│ ├── bootstrap-reboot.rtl.min.css.map
|
||||
│ ├── bootstrap-utilities.css
|
||||
│ ├── bootstrap-utilities.css.map
|
||||
│ ├── bootstrap-utilities.min.css
|
||||
│ ├── bootstrap-utilities.min.css.map
|
||||
│ ├── bootstrap-utilities.rtl.css
|
||||
│ ├── bootstrap-utilities.rtl.css.map
|
||||
│ ├── bootstrap-utilities.rtl.min.css
|
||||
│ ├── bootstrap-utilities.rtl.min.css.map
|
||||
│ ├── bootstrap.css
|
||||
│ ├── bootstrap.css.map
|
||||
│ ├── bootstrap.min.css
|
||||
│ └── bootstrap.min.css.map
|
||||
│ ├── bootstrap.min.css.map
|
||||
│ ├── bootstrap.rtl.css
|
||||
│ ├── bootstrap.rtl.css.map
|
||||
│ ├── bootstrap.rtl.min.css
|
||||
│ └── bootstrap.rtl.min.css.map
|
||||
└── js/
|
||||
├── bootstrap.bundle.js
|
||||
├── bootstrap.bundle.js.map
|
||||
@@ -115,7 +132,7 @@ Within the download you’ll find the following directories and files, logically
|
||||
```
|
||||
</details>
|
||||
|
||||
We provide compiled CSS and JS (`bootstrap.*`), as well as compiled and minified CSS and JS (`bootstrap.min.*`). [Source maps](https://web.dev/articles/source-maps) (`bootstrap.*.map`) are available for use with certain browsers' developer tools. Bundled JS files (`bootstrap.bundle.js` and minified `bootstrap.bundle.min.js`) include [Popper](https://popper.js.org/docs/v2/). All CSS files work for both LTR and RTL layouts thanks to logical properties—simply set `dir="rtl"` on your HTML element.
|
||||
We provide compiled CSS and JS (`bootstrap.*`), as well as compiled and minified CSS and JS (`bootstrap.min.*`). [Source maps](https://web.dev/articles/source-maps) (`bootstrap.*.map`) are available for use with certain browsers’ developer tools. Bundled JS files (`bootstrap.bundle.js` and minified `bootstrap.bundle.min.js`) include [Popper](https://popper.js.org/docs/v2/).
|
||||
|
||||
|
||||
## Bugs and feature requests
|
||||
@@ -134,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/).
|
||||
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { execSync } from 'node:child_process'
|
||||
|
||||
// Run bundlewatch and capture output
|
||||
let stdout
|
||||
let exitCode = 0
|
||||
|
||||
try {
|
||||
stdout = execSync('npx bundlewatch --config .bundlewatch.config.json', {
|
||||
encoding: 'utf8',
|
||||
stdio: ['pipe', 'pipe', 'pipe']
|
||||
})
|
||||
} catch (error) {
|
||||
stdout = error.stdout || ''
|
||||
exitCode = error.status || 1
|
||||
}
|
||||
|
||||
// Parse lines that contain PASS or FAIL
|
||||
const lines = stdout.split('\n').filter(l => l.startsWith('PASS') || l.startsWith('FAIL'))
|
||||
|
||||
if (lines.length === 0) {
|
||||
console.log(stdout)
|
||||
process.exit(exitCode)
|
||||
}
|
||||
|
||||
// Parse size string to number (KB)
|
||||
const parseSize = str => Number.parseFloat(str.replace('KB', ''))
|
||||
|
||||
// Calculate column widths and headroom
|
||||
const rows = lines.map(line => {
|
||||
const match = line.match(/(PASS|FAIL)\s+(.+?):\s+([\d.]+KB)\s+([<>])\s+([\d.]+KB)/)
|
||||
if (match) {
|
||||
const sizeNum = parseSize(match[3])
|
||||
const maxNum = parseSize(match[5])
|
||||
const headroomNum = maxNum - sizeNum
|
||||
const headroom = `${headroomNum.toFixed(2)}KB`
|
||||
return {
|
||||
status: match[1],
|
||||
file: match[2],
|
||||
size: match[3],
|
||||
max: match[5],
|
||||
headroomNum,
|
||||
headroom: match[1] === 'PASS' ? `+${headroom}` : `-${Math.abs(headroomNum).toFixed(2)}KB`
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}).filter(Boolean)
|
||||
|
||||
const maxFileLen = Math.max(...rows.map(r => r.file.length), 4)
|
||||
const maxSizeLen = Math.max(...rows.map(r => r.size.length), 4)
|
||||
const maxMaxLen = Math.max(...rows.map(r => r.max.length), 3)
|
||||
const maxHeadroomLen = Math.max(...rows.map(r => r.headroom.length), 8)
|
||||
|
||||
// Build table
|
||||
const hr = `+-${'-'.repeat(maxFileLen)}-+-${'-'.repeat(maxSizeLen)}-+-${'-'.repeat(maxMaxLen)}-+-${'-'.repeat(maxHeadroomLen)}-+`
|
||||
|
||||
console.log('')
|
||||
console.log('bundlewatch results')
|
||||
console.log(hr)
|
||||
console.log(`| ${'File'.padEnd(maxFileLen)} | ${'Size'.padStart(maxSizeLen)} | ${'Max'.padStart(maxMaxLen)} | ${'Headroom'.padStart(maxHeadroomLen)} |`)
|
||||
console.log(hr)
|
||||
|
||||
const green = '\u001B[32m'
|
||||
const red = '\u001B[31m'
|
||||
const reset = '\u001B[0m'
|
||||
|
||||
for (const row of rows) {
|
||||
const sizeColor = row.status === 'PASS' ? green : red
|
||||
const coloredSize = `${sizeColor}${row.size.padStart(maxSizeLen)}${reset}`
|
||||
const headroomColor = row.headroomNum > 0.25 ? red : ''
|
||||
const headroomReset = row.headroomNum > 0.25 ? reset : ''
|
||||
const coloredHeadroom = `${headroomColor}${row.headroom.padStart(maxHeadroomLen)}${headroomReset}`
|
||||
console.log(`| ${row.file.padEnd(maxFileLen)} | ${coloredSize} | ${row.max.padStart(maxMaxLen)} | ${coloredHeadroom} |`)
|
||||
}
|
||||
|
||||
console.log(hr)
|
||||
|
||||
// Summary
|
||||
const passed = rows.filter(r => r.status === 'PASS').length
|
||||
const failed = rows.filter(r => r.status === 'FAIL').length
|
||||
|
||||
console.log('')
|
||||
if (failed > 0) {
|
||||
console.log(`\u001B[31mbundlewatch FAIL\u001B[0m - ${passed} passed, ${failed} failed`)
|
||||
} else {
|
||||
console.log(`\u001B[32mbundlewatch PASS\u001B[0m - ${passed}/${rows.length} files within limits`)
|
||||
}
|
||||
|
||||
console.log('')
|
||||
|
||||
process.exit(exitCode)
|
||||
+54
-30
@@ -18,9 +18,6 @@ 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}"
|
||||
@@ -92,39 +89,66 @@ 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 all root-level files from Astro build
|
||||
find /tmp/_site -maxdepth 1 -type f -exec mv {} . \;
|
||||
|
||||
# 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"
|
||||
# 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
|
||||
mv "/tmp/_site/docs/$DOCS_VERSION" "docs/"
|
||||
done
|
||||
|
||||
# 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/"
|
||||
# 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"
|
||||
fi
|
||||
done
|
||||
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."
|
||||
fi
|
||||
|
||||
# Clean up remaining files in /tmp/_site if any
|
||||
|
||||
@@ -29,6 +29,10 @@ const files = [
|
||||
file: 'dist/css/bootstrap.min.css',
|
||||
configPropertyName: 'css_hash'
|
||||
},
|
||||
{
|
||||
file: 'dist/css/bootstrap.rtl.min.css',
|
||||
configPropertyName: 'css_rtl_hash'
|
||||
},
|
||||
{
|
||||
file: 'dist/js/bootstrap.min.js',
|
||||
configPropertyName: 'js_hash'
|
||||
@@ -38,8 +42,8 @@ const files = [
|
||||
configPropertyName: 'js_bundle_hash'
|
||||
},
|
||||
{
|
||||
file: 'node_modules/@floating-ui/dom/dist/floating-ui.dom.umd.min.js',
|
||||
configPropertyName: 'floating_ui_hash'
|
||||
file: 'node_modules/@popperjs/core/dist/umd/popper.min.js',
|
||||
configPropertyName: 'popper_hash'
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Generate utilities metadata JSON from Sass
|
||||
* This script compiles a special Sass file that outputs utility information as CSS comments,
|
||||
* then extracts and saves it as JSON for documentation use.
|
||||
*/
|
||||
|
||||
import { readFileSync, writeFileSync, unlinkSync } from 'node:fs'
|
||||
import { execSync } from 'node:child_process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import path from 'node:path'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
const rootDir = path.join(__dirname, '..')
|
||||
|
||||
// Compile the metadata generator SCSS file
|
||||
console.log('Compiling utilities metadata...')
|
||||
|
||||
try {
|
||||
execSync(
|
||||
'sass --style expanded --no-source-map build/generate-utilities-metadata.scss:dist/css/utilities-metadata.tmp.css',
|
||||
{ cwd: rootDir, stdio: 'inherit' }
|
||||
)
|
||||
} catch {
|
||||
console.error('Failed to compile metadata SCSS')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Read the compiled CSS
|
||||
const cssPath = path.join(rootDir, 'dist/css/utilities-metadata.tmp.css')
|
||||
const cssContent = readFileSync(cssPath, 'utf8')
|
||||
|
||||
// Extract JSON from the CSS comment
|
||||
const startMarker = 'BOOTSTRAP-UTILITIES-METADATA-START'
|
||||
const endMarker = 'BOOTSTRAP-UTILITIES-METADATA-END'
|
||||
|
||||
const startIndex = cssContent.indexOf(startMarker)
|
||||
const endIndex = cssContent.indexOf(endMarker)
|
||||
|
||||
if (startIndex === -1 || endIndex === -1) {
|
||||
console.error('Could not find metadata markers in compiled CSS')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Extract JSON content between markers
|
||||
const jsonContent = cssContent
|
||||
.slice(startIndex + startMarker.length, endIndex)
|
||||
.trim()
|
||||
|
||||
// Validate JSON
|
||||
try {
|
||||
const parsed = JSON.parse(jsonContent)
|
||||
console.log(`✓ Extracted metadata for ${Object.keys(parsed.utilities).length} utilities`)
|
||||
|
||||
// Write to JSON file
|
||||
const outputPath = path.join(rootDir, 'dist/css/bootstrap-utilities.metadata.json')
|
||||
writeFileSync(outputPath, JSON.stringify(parsed, null, 2))
|
||||
console.log(`✓ Wrote metadata to ${outputPath}`)
|
||||
|
||||
// Clean up temporary CSS files
|
||||
try {
|
||||
unlinkSync(cssPath)
|
||||
} catch {
|
||||
// File may not exist
|
||||
}
|
||||
|
||||
// Also clean up any other temporary variants that may have been created
|
||||
const tempFiles = [
|
||||
'dist/css/utilities-metadata.tmp.min.css',
|
||||
'dist/css/utilities-metadata.tmp.min.css.map'
|
||||
]
|
||||
|
||||
for (const file of tempFiles) {
|
||||
try {
|
||||
unlinkSync(path.join(rootDir, file))
|
||||
} catch {
|
||||
// File may not exist, ignore
|
||||
}
|
||||
}
|
||||
|
||||
console.log('✓ Cleaned up temporary files')
|
||||
} catch (error) {
|
||||
console.error('Failed to parse extracted JSON:', error.message)
|
||||
console.error('Extracted content:', jsonContent.slice(0, 500))
|
||||
process.exit(1)
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
// Generate utilities metadata JSON for documentation
|
||||
// This file is compiled to extract utility information without generating CSS
|
||||
|
||||
@use "sass:map";
|
||||
@use "sass:list";
|
||||
@use "sass:string";
|
||||
@use "sass:meta";
|
||||
@use "../scss/config" as *;
|
||||
@use "../scss/colors" as *;
|
||||
@use "../scss/variables" as *;
|
||||
@use "../scss/functions" as *;
|
||||
@use "../scss/theme" as *;
|
||||
@use "../scss/utilities" as *;
|
||||
|
||||
// Access the utilities map
|
||||
$utilities-map: $utilities !default;
|
||||
|
||||
// Start JSON output
|
||||
$json: '{"utilities":{' !default;
|
||||
|
||||
$utility-count: 0 !default;
|
||||
$total-utilities: list.length(map.keys($utilities-map)) !default;
|
||||
|
||||
@each $key, $utility in $utilities-map {
|
||||
$utility-count: $utility-count + 1;
|
||||
|
||||
// Skip if utility is null or false (disabled)
|
||||
@if $utility {
|
||||
// Extract class prefix
|
||||
$class: $key;
|
||||
@if map.has-key($utility, "class") {
|
||||
$class: map.get($utility, "class");
|
||||
}
|
||||
|
||||
// Extract property
|
||||
$property: null;
|
||||
@if map.has-key($utility, "property") {
|
||||
$property: map.get($utility, "property");
|
||||
}
|
||||
|
||||
// Extract values
|
||||
$values: null;
|
||||
@if map.has-key($utility, "values") {
|
||||
$values: map.get($utility, "values");
|
||||
}
|
||||
|
||||
// Generate class list
|
||||
$classes: "";
|
||||
@if $values {
|
||||
@if meta.type-of($values) == "map" {
|
||||
$value-keys: map.keys($values);
|
||||
$first: true;
|
||||
@each $value-key in $value-keys {
|
||||
@if not $first {
|
||||
$classes: $classes + ", ";
|
||||
}
|
||||
$class-name: "#{$class}-#{$value-key}";
|
||||
@if $value-key == "null" or $value-key == null {
|
||||
$class-name: $class;
|
||||
}
|
||||
$classes: $classes + '"' + $class-name + '"';
|
||||
$first: false;
|
||||
}
|
||||
} @else if meta.type-of($values) == "list" {
|
||||
$first: true;
|
||||
@each $value in $values {
|
||||
@if not $first {
|
||||
$classes: $classes + ", ";
|
||||
}
|
||||
$class-name: "#{$class}-#{$value}";
|
||||
$classes: $classes + '"' + $class-name + '"';
|
||||
$first: false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build JSON entry
|
||||
$json: $json + '"' + $key + '":{"class":"' + $class + '"';
|
||||
|
||||
@if $property {
|
||||
@if meta.type-of($property) == "string" {
|
||||
$json: $json + ',"property":"' + $property + '"';
|
||||
} @else if meta.type-of($property) == "list" {
|
||||
$property-str: "";
|
||||
$first: true;
|
||||
@each $prop in $property {
|
||||
@if not $first {
|
||||
$property-str: $property-str + " ";
|
||||
}
|
||||
$property-str: $property-str + $prop;
|
||||
$first: false;
|
||||
}
|
||||
$json: $json + ',"property":"' + $property-str + '"';
|
||||
}
|
||||
// Skip map properties as they're complex and don't translate to JSON well
|
||||
}
|
||||
|
||||
@if $classes != "" {
|
||||
$json: $json + ',"classes":[' + $classes + "]";
|
||||
} @else {
|
||||
$json: $json + ',"classes":[]';
|
||||
}
|
||||
|
||||
$json: $json + "}";
|
||||
|
||||
@if $utility-count < $total-utilities {
|
||||
$json: $json + ",";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// stylelint-disable-next-line scss/dollar-variable-default
|
||||
$json: $json + "}}";
|
||||
|
||||
// Output as CSS comment so it appears in compiled file
|
||||
|
||||
/*! BOOTSTRAP-UTILITIES-METADATA-START
|
||||
#{$json}
|
||||
BOOTSTRAP-UTILITIES-METADATA-END */
|
||||
|
||||
// Prevent any actual CSS output
|
||||
.bootstrap-utilities-metadata-generator {
|
||||
content: "This file should not generate CSS, only metadata comments";
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/*!
|
||||
* Script to run html-validate for HTML validation.
|
||||
*
|
||||
* This replaces the Java-based vnu-jar validator with a faster, Node.js-only solution.
|
||||
* Benefits:
|
||||
* - No Java dependency required
|
||||
* - Faster execution (no JVM startup time)
|
||||
* - Easy to configure with rule-based system
|
||||
* - Better integration with Node.js build tools
|
||||
*
|
||||
* Copyright 2017-2025 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
||||
import { HtmlValidate } from 'html-validate'
|
||||
import { globby } from 'globby'
|
||||
|
||||
const htmlValidate = new HtmlValidate({
|
||||
rules: {
|
||||
// Allow autocomplete on buttons (Bootstrap specific)
|
||||
'attribute-allowed-values': 'off',
|
||||
// Allow aria-disabled on links (Bootstrap specific)
|
||||
'aria-label-misuse': 'off',
|
||||
// Allow modern CSS syntax
|
||||
'valid-id': 'off',
|
||||
// Allow void elements with trailing slashes (Astro)
|
||||
'void-style': 'off',
|
||||
// Allow custom attributes
|
||||
'no-unknown-elements': 'off',
|
||||
'attribute-boolean-style': 'off',
|
||||
'no-inline-style': 'off',
|
||||
// KEEP duplicate ID checking enabled (this is important for HTML validity)
|
||||
'no-dup-id': 'error'
|
||||
},
|
||||
elements: [
|
||||
'html5',
|
||||
{
|
||||
// Allow custom attributes for Astro/framework compatibility
|
||||
'*': {
|
||||
attributes: {
|
||||
'is:raw': { boolean: true },
|
||||
switch: { boolean: true },
|
||||
autocomplete: { enum: ['on', 'off', 'new-password', 'current-password'] }
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
async function validateHTML() {
|
||||
try {
|
||||
console.log('Running html-validate validation...')
|
||||
|
||||
// Find all HTML files
|
||||
const files = await globby([
|
||||
'_site/**/*.html',
|
||||
'js/tests/**/*.html'
|
||||
], {
|
||||
ignore: ['**/node_modules/**']
|
||||
})
|
||||
|
||||
console.log(`Validating ${files.length} HTML files...`)
|
||||
|
||||
let hasErrors = false
|
||||
|
||||
// Validate all files in parallel to avoid await-in-loop
|
||||
const validationPromises = files.map(file =>
|
||||
htmlValidate.validateFile(file).then(report => ({ file, report }))
|
||||
)
|
||||
|
||||
const validationResults = await Promise.all(validationPromises)
|
||||
|
||||
// Process results and check for errors
|
||||
for (const { file, report } of validationResults) {
|
||||
if (!report.valid) {
|
||||
hasErrors = true
|
||||
console.error(`\nErrors in ${file}:`)
|
||||
|
||||
// Extract error messages with reduced nesting
|
||||
const errorMessages = report.results.flatMap(result =>
|
||||
result.messages.filter(message => message.severity === 2)
|
||||
)
|
||||
|
||||
for (const message of errorMessages) {
|
||||
console.error(` Line ${message.line}:${message.column} - ${message.message} (${message.ruleId})`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasErrors) {
|
||||
console.error('\nHTML validation failed!')
|
||||
process.exit(1)
|
||||
} else {
|
||||
console.log('✓ All HTML files are valid!')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('HTML validation error:', error)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
validateHTML()
|
||||
@@ -1,6 +1,3 @@
|
||||
import postcssPrefixCustomProperties from 'postcss-prefix-custom-properties'
|
||||
import autoprefixer from 'autoprefixer'
|
||||
|
||||
const mapConfig = {
|
||||
inline: false,
|
||||
annotation: true,
|
||||
@@ -10,12 +7,11 @@ const mapConfig = {
|
||||
export default context => {
|
||||
return {
|
||||
map: context.file.dirname.includes('examples') ? false : mapConfig,
|
||||
plugins: [
|
||||
postcssPrefixCustomProperties({
|
||||
prefix: 'bs-',
|
||||
ignore: [/^--bs-/, /^--bd-/]
|
||||
}),
|
||||
autoprefixer({ cascade: false })
|
||||
]
|
||||
plugins: {
|
||||
autoprefixer: {
|
||||
cascade: false
|
||||
},
|
||||
rtlcss: context.env === 'RTL'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ const BUNDLE = process.env.BUNDLE === 'true'
|
||||
const ESM = process.env.ESM === 'true'
|
||||
|
||||
let destinationFile = `bootstrap${ESM ? '.esm' : ''}`
|
||||
const external = ['@floating-ui/dom']
|
||||
const external = ['@popperjs/core']
|
||||
const plugins = [
|
||||
babel({
|
||||
// Only transpile our source code
|
||||
@@ -22,14 +22,14 @@ const plugins = [
|
||||
})
|
||||
]
|
||||
const globals = {
|
||||
'@floating-ui/dom': 'FloatingUIDOM'
|
||||
'@popperjs/core': 'Popper'
|
||||
}
|
||||
|
||||
if (BUNDLE) {
|
||||
destinationFile += '.bundle'
|
||||
// Remove last entry in external array to bundle Floating UI
|
||||
// Remove last entry in external array to bundle Popper
|
||||
external.pop()
|
||||
delete globals['@floating-ui/dom']
|
||||
delete globals['@popperjs/core']
|
||||
plugins.push(
|
||||
replace({
|
||||
'process.env.NODE_ENV': '"production"',
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/*!
|
||||
* Script to run vnu-jar if Java is available.
|
||||
* Copyright 2017-2025 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
||||
import { execFile, spawn } from 'node:child_process'
|
||||
import vnu from 'vnu-jar'
|
||||
|
||||
execFile('java', ['-version'], (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.error('Skipping vnu-jar test; Java is probably missing.')
|
||||
console.error(error)
|
||||
return
|
||||
}
|
||||
|
||||
console.log('Running vnu-jar validation...')
|
||||
|
||||
const is32bitJava = !/64-Bit/.test(stderr)
|
||||
|
||||
// vnu-jar accepts multiple ignores joined with a `|`.
|
||||
// Also note that the ignores are string regular expressions.
|
||||
const ignores = [
|
||||
// "autocomplete" is included in <button> and checkboxes and radio <input>s due to
|
||||
// Firefox's non-standard autocomplete behavior - see https://bugzilla.mozilla.org/show_bug.cgi?id=654072
|
||||
'Attribute “autocomplete” is only allowed when the input type is.*',
|
||||
'Attribute “autocomplete” not allowed on element “button” at this point.',
|
||||
// Per https://www.w3.org/TR/html-aria/#docconformance having "aria-disabled" on a link is
|
||||
// NOT RECOMMENDED, but it's still valid - we explain in the docs that it's not ideal,
|
||||
// and offer more robust alternatives, but also need to show a less-than-ideal example
|
||||
'An “aria-disabled” attribute whose value is “true” should not be specified on an “a” element that has an “href” attribute.',
|
||||
// A `code` element with the `is:raw` attribute coming from remark-prismjs (Astro upstream possible bug)
|
||||
'Attribute “is:raw” is not serializable as XML 1.0.',
|
||||
'Attribute “is:raw” not allowed on element “code” at this point.',
|
||||
// Astro's expecting trailing slashes on HTML tags such as <br />
|
||||
'Trailing slash on void elements has no effect and interacts badly with unquoted attribute values.',
|
||||
// Allow `switch` attribute.
|
||||
'Attribute “switch” not allowed on element “input” at this point.'
|
||||
].join('|')
|
||||
|
||||
const args = [
|
||||
'-jar',
|
||||
`"${vnu}"`,
|
||||
'--asciiquotes',
|
||||
'--skip-non-html',
|
||||
'--Werror',
|
||||
`--filterpattern "${ignores}"`,
|
||||
'_site/',
|
||||
'js/tests/'
|
||||
]
|
||||
|
||||
// For the 32-bit Java we need to pass `-Xss512k`
|
||||
if (is32bitJava) {
|
||||
args.splice(0, 0, '-Xss512k')
|
||||
}
|
||||
|
||||
console.log(`command used: java ${args.join(' ')}`)
|
||||
|
||||
return spawn('java', args, {
|
||||
shell: true,
|
||||
stdio: 'inherit'
|
||||
})
|
||||
.on('exit', process.exit)
|
||||
})
|
||||
+6
-23
@@ -11,7 +11,6 @@ import fs from 'node:fs/promises'
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import sh from 'shelljs'
|
||||
import { format } from 'prettier'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
@@ -26,7 +25,9 @@ const docsDir = `${rootDocsDir}/docs/${versionShort}/`
|
||||
// these are the files we need in the examples
|
||||
const cssFiles = [
|
||||
'bootstrap.min.css',
|
||||
'bootstrap.min.css.map'
|
||||
'bootstrap.min.css.map',
|
||||
'bootstrap.rtl.min.css',
|
||||
'bootstrap.rtl.min.css.map'
|
||||
]
|
||||
const jsFiles = [
|
||||
'bootstrap.bundle.min.js',
|
||||
@@ -82,9 +83,7 @@ for (const file of staticJsFiles) {
|
||||
sh.rm(`${distFolder}/index.html`)
|
||||
|
||||
// get all examples' HTML files
|
||||
const htmlFiles = sh.find(`${distFolder}/**/*.html`)
|
||||
|
||||
const formatPromises = htmlFiles.map(async file => {
|
||||
for (const file of sh.find(`${distFolder}/**/*.html`)) {
|
||||
const fileContents = sh.cat(file)
|
||||
.toString()
|
||||
.replace(new RegExp(`"/docs/${versionShort}/`, 'g'), '"../')
|
||||
@@ -92,24 +91,8 @@ const formatPromises = htmlFiles.map(async file => {
|
||||
.replace(/(<link href="\.\.\/[^"]*"[^>]*) integrity="[^"]*"/g, '$1')
|
||||
.replace(/<link[^>]*href="\.\.\/assets\/img\/favicons\/[^"]*"[^>]*>/g, '')
|
||||
.replace(/(<script src="\.\.\/[^"]*"[^>]*) integrity="[^"]*"/g, '$1')
|
||||
|
||||
let formattedHTML
|
||||
try {
|
||||
formattedHTML = await format(fileContents, {
|
||||
parser: 'html',
|
||||
filepath: file
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(`\nError formatting ${file}:`)
|
||||
console.error(`Message: ${error.message}`)
|
||||
console.error('\nSkipping formatting for this file...\n')
|
||||
formattedHTML = fileContents
|
||||
}
|
||||
|
||||
new sh.ShellString(formattedHTML).to(file)
|
||||
})
|
||||
|
||||
await Promise.all(formatPromises)
|
||||
new sh.ShellString(fileContents).to(file)
|
||||
}
|
||||
|
||||
// create the zip file
|
||||
sh.exec(`zip -qr9 "${distFolder}.zip" "${distFolder}"`)
|
||||
|
||||
+17
-14
@@ -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.8"
|
||||
current_ruby_version: "5.3.8"
|
||||
current_version: "5.3.6"
|
||||
current_ruby_version: "5.3.6"
|
||||
docs_version: "5.3"
|
||||
rfs_version: "v10.0.0"
|
||||
github_org: "https://github.com/twbs"
|
||||
@@ -16,6 +16,7 @@ repo: "https://github.com/twbs/bootstrap"
|
||||
x: "getbootstrap"
|
||||
opencollective: "https://opencollective.com/bootstrap"
|
||||
blog: "https://blog.getbootstrap.com/"
|
||||
themes: "https://themes.getbootstrap.com/"
|
||||
icons: "https://icons.getbootstrap.com/"
|
||||
swag: "https://cottonbureau.com/people/bootstrap"
|
||||
|
||||
@@ -28,21 +29,23 @@ algolia:
|
||||
index_name: "bootstrap"
|
||||
|
||||
download:
|
||||
source: "https://github.com/twbs/bootstrap/archive/v5.3.8.zip"
|
||||
dist: "https://github.com/twbs/bootstrap/releases/download/v5.3.8/bootstrap-5.3.8-dist.zip"
|
||||
dist_examples: "https://github.com/twbs/bootstrap/releases/download/v5.3.8/bootstrap-5.3.8-examples.zip"
|
||||
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"
|
||||
|
||||
cdn:
|
||||
# See https://www.srihash.org for info on how to generate the hashes
|
||||
css: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
|
||||
css_hash: "sha384-TDmpFhAO5TwSQwPF95I/odgwpTUuv0aaVm9/0fL7b+kKe7hFBp/+9cBCMkydgGOi"
|
||||
js: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.min.js"
|
||||
js_hash: "sha384-Php492snRLTR5p+hMyxpV6gYwp1avWXn4AaX31MgANrvsjr9Dpodl3Nw60L7Pewl"
|
||||
js_bundle: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"
|
||||
js_bundle_hash: "sha384-I2J4jlw924JZXHU9un9Mcuixq/rKhd5A8/B1NQ6ifPAiBFacZjwNcec8d6L38jQv"
|
||||
floating_ui: "https://cdn.jsdelivr.net/npm/@floating-ui/dom@1.7.0/dist/floating-ui.dom.umd.min.js"
|
||||
floating_ui_hash: "sha384-R7p1RqabZNhI+RdPNIzTouzd/LBVorZ0Tn3ApcogSOk+HF3o+P0HIenrUw/n0MOj"
|
||||
floating_ui_esm: "https://cdn.jsdelivr.net/npm/@floating-ui/dom@1.7.0/dist/floating-ui.dom.esm.min.js"
|
||||
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"
|
||||
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"
|
||||
|
||||
anchors:
|
||||
min: 2
|
||||
|
||||
Vendored
+3807
-4357
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+4
-4
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+4084
File diff suppressed because it is too large
Load Diff
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+6
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
Vendored
+562
-809
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+4
-4
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+594
@@ -0,0 +1,594 @@
|
||||
/*!
|
||||
* Bootstrap Reboot v5.3.6 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
:root,
|
||||
[data-bs-theme=light] {
|
||||
--bs-blue: #0d6efd;
|
||||
--bs-indigo: #6610f2;
|
||||
--bs-purple: #6f42c1;
|
||||
--bs-pink: #d63384;
|
||||
--bs-red: #dc3545;
|
||||
--bs-orange: #fd7e14;
|
||||
--bs-yellow: #ffc107;
|
||||
--bs-green: #198754;
|
||||
--bs-teal: #20c997;
|
||||
--bs-cyan: #0dcaf0;
|
||||
--bs-black: #000;
|
||||
--bs-white: #fff;
|
||||
--bs-gray: #6c757d;
|
||||
--bs-gray-dark: #343a40;
|
||||
--bs-gray-100: #f8f9fa;
|
||||
--bs-gray-200: #e9ecef;
|
||||
--bs-gray-300: #dee2e6;
|
||||
--bs-gray-400: #ced4da;
|
||||
--bs-gray-500: #adb5bd;
|
||||
--bs-gray-600: #6c757d;
|
||||
--bs-gray-700: #495057;
|
||||
--bs-gray-800: #343a40;
|
||||
--bs-gray-900: #212529;
|
||||
--bs-primary: #0d6efd;
|
||||
--bs-secondary: #6c757d;
|
||||
--bs-success: #198754;
|
||||
--bs-info: #0dcaf0;
|
||||
--bs-warning: #ffc107;
|
||||
--bs-danger: #dc3545;
|
||||
--bs-light: #f8f9fa;
|
||||
--bs-dark: #212529;
|
||||
--bs-primary-rgb: 13, 110, 253;
|
||||
--bs-secondary-rgb: 108, 117, 125;
|
||||
--bs-success-rgb: 25, 135, 84;
|
||||
--bs-info-rgb: 13, 202, 240;
|
||||
--bs-warning-rgb: 255, 193, 7;
|
||||
--bs-danger-rgb: 220, 53, 69;
|
||||
--bs-light-rgb: 248, 249, 250;
|
||||
--bs-dark-rgb: 33, 37, 41;
|
||||
--bs-primary-text-emphasis: #052c65;
|
||||
--bs-secondary-text-emphasis: #2b2f32;
|
||||
--bs-success-text-emphasis: #0a3622;
|
||||
--bs-info-text-emphasis: #055160;
|
||||
--bs-warning-text-emphasis: #664d03;
|
||||
--bs-danger-text-emphasis: #58151c;
|
||||
--bs-light-text-emphasis: #495057;
|
||||
--bs-dark-text-emphasis: #495057;
|
||||
--bs-primary-bg-subtle: #cfe2ff;
|
||||
--bs-secondary-bg-subtle: #e2e3e5;
|
||||
--bs-success-bg-subtle: #d1e7dd;
|
||||
--bs-info-bg-subtle: #cff4fc;
|
||||
--bs-warning-bg-subtle: #fff3cd;
|
||||
--bs-danger-bg-subtle: #f8d7da;
|
||||
--bs-light-bg-subtle: #fcfcfd;
|
||||
--bs-dark-bg-subtle: #ced4da;
|
||||
--bs-primary-border-subtle: #9ec5fe;
|
||||
--bs-secondary-border-subtle: #c4c8cb;
|
||||
--bs-success-border-subtle: #a3cfbb;
|
||||
--bs-info-border-subtle: #9eeaf9;
|
||||
--bs-warning-border-subtle: #ffe69c;
|
||||
--bs-danger-border-subtle: #f1aeb5;
|
||||
--bs-light-border-subtle: #e9ecef;
|
||||
--bs-dark-border-subtle: #adb5bd;
|
||||
--bs-white-rgb: 255, 255, 255;
|
||||
--bs-black-rgb: 0, 0, 0;
|
||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||
--bs-body-font-family: var(--bs-font-sans-serif);
|
||||
--bs-body-font-size: 1rem;
|
||||
--bs-body-font-weight: 400;
|
||||
--bs-body-line-height: 1.5;
|
||||
--bs-body-color: #212529;
|
||||
--bs-body-color-rgb: 33, 37, 41;
|
||||
--bs-body-bg: #fff;
|
||||
--bs-body-bg-rgb: 255, 255, 255;
|
||||
--bs-emphasis-color: #000;
|
||||
--bs-emphasis-color-rgb: 0, 0, 0;
|
||||
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
||||
--bs-secondary-color-rgb: 33, 37, 41;
|
||||
--bs-secondary-bg: #e9ecef;
|
||||
--bs-secondary-bg-rgb: 233, 236, 239;
|
||||
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
||||
--bs-tertiary-color-rgb: 33, 37, 41;
|
||||
--bs-tertiary-bg: #f8f9fa;
|
||||
--bs-tertiary-bg-rgb: 248, 249, 250;
|
||||
--bs-heading-color: inherit;
|
||||
--bs-link-color: #0d6efd;
|
||||
--bs-link-color-rgb: 13, 110, 253;
|
||||
--bs-link-decoration: underline;
|
||||
--bs-link-hover-color: #0a58ca;
|
||||
--bs-link-hover-color-rgb: 10, 88, 202;
|
||||
--bs-code-color: #d63384;
|
||||
--bs-highlight-color: #212529;
|
||||
--bs-highlight-bg: #fff3cd;
|
||||
--bs-border-width: 1px;
|
||||
--bs-border-style: solid;
|
||||
--bs-border-color: #dee2e6;
|
||||
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
||||
--bs-border-radius: 0.375rem;
|
||||
--bs-border-radius-sm: 0.25rem;
|
||||
--bs-border-radius-lg: 0.5rem;
|
||||
--bs-border-radius-xl: 1rem;
|
||||
--bs-border-radius-xxl: 2rem;
|
||||
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
||||
--bs-border-radius-pill: 50rem;
|
||||
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
||||
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
||||
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
||||
--bs-focus-ring-width: 0.25rem;
|
||||
--bs-focus-ring-opacity: 0.25;
|
||||
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
||||
--bs-form-valid-color: #198754;
|
||||
--bs-form-valid-border-color: #198754;
|
||||
--bs-form-invalid-color: #dc3545;
|
||||
--bs-form-invalid-border-color: #dc3545;
|
||||
}
|
||||
|
||||
[data-bs-theme=dark] {
|
||||
color-scheme: dark;
|
||||
--bs-body-color: #dee2e6;
|
||||
--bs-body-color-rgb: 222, 226, 230;
|
||||
--bs-body-bg: #212529;
|
||||
--bs-body-bg-rgb: 33, 37, 41;
|
||||
--bs-emphasis-color: #fff;
|
||||
--bs-emphasis-color-rgb: 255, 255, 255;
|
||||
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
||||
--bs-secondary-color-rgb: 222, 226, 230;
|
||||
--bs-secondary-bg: #343a40;
|
||||
--bs-secondary-bg-rgb: 52, 58, 64;
|
||||
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
||||
--bs-tertiary-color-rgb: 222, 226, 230;
|
||||
--bs-tertiary-bg: #2b3035;
|
||||
--bs-tertiary-bg-rgb: 43, 48, 53;
|
||||
--bs-primary-text-emphasis: #6ea8fe;
|
||||
--bs-secondary-text-emphasis: #a7acb1;
|
||||
--bs-success-text-emphasis: #75b798;
|
||||
--bs-info-text-emphasis: #6edff6;
|
||||
--bs-warning-text-emphasis: #ffda6a;
|
||||
--bs-danger-text-emphasis: #ea868f;
|
||||
--bs-light-text-emphasis: #f8f9fa;
|
||||
--bs-dark-text-emphasis: #dee2e6;
|
||||
--bs-primary-bg-subtle: #031633;
|
||||
--bs-secondary-bg-subtle: #161719;
|
||||
--bs-success-bg-subtle: #051b11;
|
||||
--bs-info-bg-subtle: #032830;
|
||||
--bs-warning-bg-subtle: #332701;
|
||||
--bs-danger-bg-subtle: #2c0b0e;
|
||||
--bs-light-bg-subtle: #343a40;
|
||||
--bs-dark-bg-subtle: #1a1d20;
|
||||
--bs-primary-border-subtle: #084298;
|
||||
--bs-secondary-border-subtle: #41464b;
|
||||
--bs-success-border-subtle: #0f5132;
|
||||
--bs-info-border-subtle: #087990;
|
||||
--bs-warning-border-subtle: #997404;
|
||||
--bs-danger-border-subtle: #842029;
|
||||
--bs-light-border-subtle: #495057;
|
||||
--bs-dark-border-subtle: #343a40;
|
||||
--bs-heading-color: inherit;
|
||||
--bs-link-color: #6ea8fe;
|
||||
--bs-link-hover-color: #8bb9fe;
|
||||
--bs-link-color-rgb: 110, 168, 254;
|
||||
--bs-link-hover-color-rgb: 139, 185, 254;
|
||||
--bs-code-color: #e685b5;
|
||||
--bs-highlight-color: #dee2e6;
|
||||
--bs-highlight-bg: #664d03;
|
||||
--bs-border-color: #495057;
|
||||
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
||||
--bs-form-valid-color: #75b798;
|
||||
--bs-form-valid-border-color: #75b798;
|
||||
--bs-form-invalid-color: #ea868f;
|
||||
--bs-form-invalid-border-color: #ea868f;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
:root {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: var(--bs-body-font-family);
|
||||
font-size: var(--bs-body-font-size);
|
||||
font-weight: var(--bs-body-font-weight);
|
||||
line-height: var(--bs-body-line-height);
|
||||
color: var(--bs-body-color);
|
||||
text-align: var(--bs-body-text-align);
|
||||
background-color: var(--bs-body-bg);
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 1rem 0;
|
||||
color: inherit;
|
||||
border: 0;
|
||||
border-top: var(--bs-border-width) solid;
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
h6, h5, h4, h3, h2, h1 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
color: var(--bs-heading-color);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: calc(1.375rem + 1.5vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: calc(1.325rem + 0.9vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h2 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: calc(1.3rem + 0.6vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h3 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
h4 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
abbr[title] {
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
cursor: help;
|
||||
-webkit-text-decoration-skip-ink: none;
|
||||
text-decoration-skip-ink: none;
|
||||
}
|
||||
|
||||
address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: 0.5rem;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
mark {
|
||||
padding: 0.1875em;
|
||||
color: var(--bs-highlight-color);
|
||||
background-color: var(--bs-highlight-bg);
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 0.75em;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
||||
text-decoration: underline;
|
||||
}
|
||||
a:hover {
|
||||
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
||||
}
|
||||
|
||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: var(--bs-font-monospace);
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
pre {
|
||||
display: block;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
pre code {
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.875em;
|
||||
color: var(--bs-code-color);
|
||||
word-wrap: break-word;
|
||||
}
|
||||
a > code {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
kbd {
|
||||
padding: 0.1875rem 0.375rem;
|
||||
font-size: 0.875em;
|
||||
color: var(--bs-body-bg);
|
||||
background-color: var(--bs-body-color);
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
kbd kbd {
|
||||
padding: 0;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img,
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
table {
|
||||
caption-side: bottom;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
color: var(--bs-secondary-color);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: inherit;
|
||||
text-align: -webkit-match-parent;
|
||||
}
|
||||
|
||||
thead,
|
||||
tbody,
|
||||
tfoot,
|
||||
tr,
|
||||
td,
|
||||
th {
|
||||
border-color: inherit;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:focus:not(:focus-visible) {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea {
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
[role=button] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
select {
|
||||
word-wrap: normal;
|
||||
}
|
||||
select:disabled {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
button,
|
||||
[type=button],
|
||||
[type=reset],
|
||||
[type=submit] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
button:not(:disabled),
|
||||
[type=button]:not(:disabled),
|
||||
[type=reset]:not(:disabled),
|
||||
[type=submit]:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
float: right;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
line-height: inherit;
|
||||
font-size: calc(1.275rem + 0.3vw);
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
legend {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
legend + * {
|
||||
clear: right;
|
||||
}
|
||||
|
||||
::-webkit-datetime-edit-fields-wrapper,
|
||||
::-webkit-datetime-edit-text,
|
||||
::-webkit-datetime-edit-minute,
|
||||
::-webkit-datetime-edit-hour-field,
|
||||
::-webkit-datetime-edit-day-field,
|
||||
::-webkit-datetime-edit-month-field,
|
||||
::-webkit-datetime-edit-year-field {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-inner-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type=search] {
|
||||
-webkit-appearance: textfield;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
[type="tel"],
|
||||
[type="url"],
|
||||
[type="email"],
|
||||
[type="number"] {
|
||||
direction: ltr;
|
||||
}
|
||||
::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
::file-selector-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */
|
||||
+1
File diff suppressed because one or more lines are too long
+6
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
Vendored
+5370
-5580
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
File diff suppressed because one or more lines are too long
-1224
File diff suppressed because it is too large
Load Diff
Vendored
+4
-4
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+5397
File diff suppressed because it is too large
Load Diff
+1
File diff suppressed because one or more lines are too long
+6
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+11666
-11655
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+4
-4
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+12016
File diff suppressed because it is too large
Load Diff
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+6
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+2894
-3649
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1163
-2141
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+1185
-2147
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+25
-5
@@ -1,13 +1,13 @@
|
||||
/*!
|
||||
* Bootstrap alert.js v5.3.8 (https://getbootstrap.com/)
|
||||
* Bootstrap alert.js v5.3.6 (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)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./util/component-functions.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './util/component-functions'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Alert = factory(global.BaseComponent, global.EventHandler, global.ComponentFunctions));
|
||||
})(this, (function (BaseComponent, EventHandler, componentFunctions_js) { 'use strict';
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./util/component-functions.js'), require('./util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './util/component-functions', './util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Alert = factory(global.BaseComponent, global.EventHandler, global.ComponentFunctions, global.Index));
|
||||
})(this, (function (BaseComponent, EventHandler, componentFunctions_js, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
@@ -56,6 +56,20 @@
|
||||
EventHandler.trigger(this._element, EVENT_CLOSED);
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Alert.getOrCreateInstance(this);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config](this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,6 +78,12 @@
|
||||
|
||||
componentFunctions_js.enableDismissTrigger(Alert, 'close');
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Alert);
|
||||
|
||||
return Alert;
|
||||
|
||||
}));
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"alert.js","sources":["../src/alert.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport { enableDismissTrigger } from './util/component-functions.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'alert'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * Class definition\n */\n\nclass Alert extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME\n }\n\n // Public\n close() {\n const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE)\n\n if (closeEvent.defaultPrevented) {\n return\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n\n const isAnimated = this._element.classList.contains(CLASS_NAME_FADE)\n this._queueCallback(() => this._destroyElement(), this._element, isAnimated)\n }\n\n // Private\n _destroyElement() {\n this._element.remove()\n EventHandler.trigger(this._element, EVENT_CLOSED)\n this.dispose()\n }\n}\n\n/**\n * Data API implementation\n */\n\nenableDismissTrigger(Alert, 'close')\n\nexport default Alert\n"],"names":["NAME","DATA_KEY","EVENT_KEY","EVENT_CLOSE","EVENT_CLOSED","CLASS_NAME_FADE","CLASS_NAME_SHOW","Alert","BaseComponent","close","closeEvent","EventHandler","trigger","_element","defaultPrevented","classList","remove","isAnimated","contains","_queueCallback","_destroyElement","dispose","enableDismissTrigger"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAMA;EACA;EACA;;EAEA,MAAMA,IAAI,GAAG,OAAO;EACpB,MAAMC,QAAQ,GAAG,UAAU;EAC3B,MAAMC,SAAS,GAAG,CAAA,CAAA,EAAID,QAAQ,CAAA,CAAE;EAEhC,MAAME,WAAW,GAAG,CAAA,KAAA,EAAQD,SAAS,CAAA,CAAE;EACvC,MAAME,YAAY,GAAG,CAAA,MAAA,EAASF,SAAS,CAAA,CAAE;EACzC,MAAMG,eAAe,GAAG,MAAM;EAC9B,MAAMC,eAAe,GAAG,MAAM;;EAE9B;EACA;EACA;;EAEA,MAAMC,KAAK,SAASC,aAAa,CAAC;EAChC;IACA,WAAWR,IAAIA,GAAG;EAChB,IAAA,OAAOA,IAAI;EACb,EAAA;;EAEA;EACAS,EAAAA,KAAKA,GAAG;MACN,MAAMC,UAAU,GAAGC,YAAY,CAACC,OAAO,CAAC,IAAI,CAACC,QAAQ,EAAEV,WAAW,CAAC;MAEnE,IAAIO,UAAU,CAACI,gBAAgB,EAAE;EAC/B,MAAA;EACF,IAAA;MAEA,IAAI,CAACD,QAAQ,CAACE,SAAS,CAACC,MAAM,CAACV,eAAe,CAAC;MAE/C,MAAMW,UAAU,GAAG,IAAI,CAACJ,QAAQ,CAACE,SAAS,CAACG,QAAQ,CAACb,eAAe,CAAC;EACpE,IAAA,IAAI,CAACc,cAAc,CAAC,MAAM,IAAI,CAACC,eAAe,EAAE,EAAE,IAAI,CAACP,QAAQ,EAAEI,UAAU,CAAC;EAC9E,EAAA;;EAEA;EACAG,EAAAA,eAAeA,GAAG;EAChB,IAAA,IAAI,CAACP,QAAQ,CAACG,MAAM,EAAE;MACtBL,YAAY,CAACC,OAAO,CAAC,IAAI,CAACC,QAAQ,EAAET,YAAY,CAAC;MACjD,IAAI,CAACiB,OAAO,EAAE;EAChB,EAAA;EACF;;EAEA;EACA;EACA;;AAEAC,4CAAoB,CAACf,KAAK,EAAE,OAAO,CAAC;;;;;;;;"}
|
||||
{"version":3,"file":"alert.js","sources":["../src/alert.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport { enableDismissTrigger } from './util/component-functions.js'\nimport { defineJQueryPlugin } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'alert'\nconst DATA_KEY = 'bs.alert'\nconst EVENT_KEY = `.${DATA_KEY}`\n\nconst EVENT_CLOSE = `close${EVENT_KEY}`\nconst EVENT_CLOSED = `closed${EVENT_KEY}`\nconst CLASS_NAME_FADE = 'fade'\nconst CLASS_NAME_SHOW = 'show'\n\n/**\n * Class definition\n */\n\nclass Alert extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME\n }\n\n // Public\n close() {\n const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE)\n\n if (closeEvent.defaultPrevented) {\n return\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW)\n\n const isAnimated = this._element.classList.contains(CLASS_NAME_FADE)\n this._queueCallback(() => this._destroyElement(), this._element, isAnimated)\n }\n\n // Private\n _destroyElement() {\n this._element.remove()\n EventHandler.trigger(this._element, EVENT_CLOSED)\n this.dispose()\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Alert.getOrCreateInstance(this)\n\n if (typeof config !== 'string') {\n return\n }\n\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`)\n }\n\n data[config](this)\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nenableDismissTrigger(Alert, 'close')\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Alert)\n\nexport default Alert\n"],"names":["NAME","DATA_KEY","EVENT_KEY","EVENT_CLOSE","EVENT_CLOSED","CLASS_NAME_FADE","CLASS_NAME_SHOW","Alert","BaseComponent","close","closeEvent","EventHandler","trigger","_element","defaultPrevented","classList","remove","isAnimated","contains","_queueCallback","_destroyElement","dispose","jQueryInterface","config","each","data","getOrCreateInstance","undefined","startsWith","TypeError","enableDismissTrigger","defineJQueryPlugin"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAOA;EACA;EACA;;EAEA,MAAMA,IAAI,GAAG,OAAO;EACpB,MAAMC,QAAQ,GAAG,UAAU;EAC3B,MAAMC,SAAS,GAAG,CAAID,CAAAA,EAAAA,QAAQ,CAAE,CAAA;EAEhC,MAAME,WAAW,GAAG,CAAQD,KAAAA,EAAAA,SAAS,CAAE,CAAA;EACvC,MAAME,YAAY,GAAG,CAASF,MAAAA,EAAAA,SAAS,CAAE,CAAA;EACzC,MAAMG,eAAe,GAAG,MAAM;EAC9B,MAAMC,eAAe,GAAG,MAAM;;EAE9B;EACA;EACA;;EAEA,MAAMC,KAAK,SAASC,aAAa,CAAC;EAChC;IACA,WAAWR,IAAIA,GAAG;EAChB,IAAA,OAAOA,IAAI;EACb;;EAEA;EACAS,EAAAA,KAAKA,GAAG;MACN,MAAMC,UAAU,GAAGC,YAAY,CAACC,OAAO,CAAC,IAAI,CAACC,QAAQ,EAAEV,WAAW,CAAC;MAEnE,IAAIO,UAAU,CAACI,gBAAgB,EAAE;EAC/B,MAAA;EACF;MAEA,IAAI,CAACD,QAAQ,CAACE,SAAS,CAACC,MAAM,CAACV,eAAe,CAAC;MAE/C,MAAMW,UAAU,GAAG,IAAI,CAACJ,QAAQ,CAACE,SAAS,CAACG,QAAQ,CAACb,eAAe,CAAC;EACpE,IAAA,IAAI,CAACc,cAAc,CAAC,MAAM,IAAI,CAACC,eAAe,EAAE,EAAE,IAAI,CAACP,QAAQ,EAAEI,UAAU,CAAC;EAC9E;;EAEA;EACAG,EAAAA,eAAeA,GAAG;EAChB,IAAA,IAAI,CAACP,QAAQ,CAACG,MAAM,EAAE;MACtBL,YAAY,CAACC,OAAO,CAAC,IAAI,CAACC,QAAQ,EAAET,YAAY,CAAC;MACjD,IAAI,CAACiB,OAAO,EAAE;EAChB;;EAEA;IACA,OAAOC,eAAeA,CAACC,MAAM,EAAE;EAC7B,IAAA,OAAO,IAAI,CAACC,IAAI,CAAC,YAAY;EAC3B,MAAA,MAAMC,IAAI,GAAGlB,KAAK,CAACmB,mBAAmB,CAAC,IAAI,CAAC;EAE5C,MAAA,IAAI,OAAOH,MAAM,KAAK,QAAQ,EAAE;EAC9B,QAAA;EACF;EAEA,MAAA,IAAIE,IAAI,CAACF,MAAM,CAAC,KAAKI,SAAS,IAAIJ,MAAM,CAACK,UAAU,CAAC,GAAG,CAAC,IAAIL,MAAM,KAAK,aAAa,EAAE;EACpF,QAAA,MAAM,IAAIM,SAAS,CAAC,CAAoBN,iBAAAA,EAAAA,MAAM,GAAG,CAAC;EACpD;EAEAE,MAAAA,IAAI,CAACF,MAAM,CAAC,CAAC,IAAI,CAAC;EACpB,KAAC,CAAC;EACJ;EACF;;EAEA;EACA;EACA;;AAEAO,4CAAoB,CAACvB,KAAK,EAAE,OAAO,CAAC;;EAEpC;EACA;EACA;;AAEAwB,6BAAkB,CAACxB,KAAK,CAAC;;;;;;;;"}
|
||||
Vendored
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Bootstrap base-component.js v5.3.8 (https://getbootstrap.com/)
|
||||
* Bootstrap base-component.js v5.3.6 (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.8';
|
||||
const VERSION = '5.3.6';
|
||||
|
||||
/**
|
||||
* Class definition
|
||||
|
||||
Vendored
+1
-1
@@ -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.8'\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,IAAA;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,EAAA;;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,IAAA;EACF,EAAA;;EAEA;IACAG,cAAcA,CAACC,QAAQ,EAAElB,OAAO,EAAEmB,UAAU,GAAG,IAAI,EAAE;EACnDC,IAAAA,+BAAsB,CAACF,QAAQ,EAAElB,OAAO,EAAEmB,UAAU,CAAC;EACvD,EAAA;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,EAAA;;EAEA;IACA,OAAOuB,WAAWA,CAACxB,OAAO,EAAE;EAC1B,IAAA,OAAOM,IAAI,CAACmB,GAAG,CAACvB,mBAAU,CAACF,OAAO,CAAC,EAAE,IAAI,CAACQ,QAAQ,CAAC;EACrD,EAAA;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,EAAA;IAEA,WAAWL,OAAOA,GAAG;EACnB,IAAA,OAAOA,OAAO;EAChB,EAAA;IAEA,WAAWY,QAAQA,GAAG;EACpB,IAAA,OAAO,CAAA,GAAA,EAAM,IAAI,CAACmB,IAAI,CAAA,CAAE;EAC1B,EAAA;IAEA,WAAWd,SAASA,GAAG;EACrB,IAAA,OAAO,CAAA,CAAA,EAAI,IAAI,CAACL,QAAQ,CAAA,CAAE;EAC5B,EAAA;IAEA,OAAOoB,SAASA,CAACC,IAAI,EAAE;EACrB,IAAA,OAAO,GAAGA,IAAI,CAAA,EAAG,IAAI,CAAChB,SAAS,CAAA,CAAE;EACnC,EAAA;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.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;;;;;;;;"}
|
||||
Vendored
+21
-5
@@ -1,13 +1,13 @@
|
||||
/*!
|
||||
* Bootstrap button.js v5.3.8 (https://getbootstrap.com/)
|
||||
* Bootstrap button.js v5.3.6 (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)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Button = factory(global.BaseComponent, global.EventHandler));
|
||||
})(this, (function (BaseComponent, EventHandler) { 'use strict';
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Button = factory(global.BaseComponent, global.EventHandler, global.Index));
|
||||
})(this, (function (BaseComponent, EventHandler, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
@@ -44,6 +44,16 @@
|
||||
// Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method
|
||||
this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE));
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Button.getOrCreateInstance(this);
|
||||
if (config === 'toggle') {
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,6 +67,12 @@
|
||||
data.toggle();
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Button);
|
||||
|
||||
return Button;
|
||||
|
||||
}));
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"button.js","sources":["../src/button.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'button'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"button\"]'\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * Class definition\n */\n\nclass Button extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle() {\n // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE))\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => {\n event.preventDefault()\n\n const button = event.target.closest(SELECTOR_DATA_TOGGLE)\n const data = Button.getOrCreateInstance(button)\n\n data.toggle()\n})\n\nexport default Button\n"],"names":["NAME","DATA_KEY","EVENT_KEY","DATA_API_KEY","CLASS_NAME_ACTIVE","SELECTOR_DATA_TOGGLE","EVENT_CLICK_DATA_API","Button","BaseComponent","toggle","_element","setAttribute","classList","EventHandler","on","document","event","preventDefault","button","target","closest","data","getOrCreateInstance"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAKA;EACA;EACA;;EAEA,MAAMA,IAAI,GAAG,QAAQ;EACrB,MAAMC,QAAQ,GAAG,WAAW;EAC5B,MAAMC,SAAS,GAAG,CAAA,CAAA,EAAID,QAAQ,CAAA,CAAE;EAChC,MAAME,YAAY,GAAG,WAAW;EAEhC,MAAMC,iBAAiB,GAAG,QAAQ;EAClC,MAAMC,oBAAoB,GAAG,2BAA2B;EACxD,MAAMC,oBAAoB,GAAG,CAAA,KAAA,EAAQJ,SAAS,CAAA,EAAGC,YAAY,CAAA,CAAE;;EAE/D;EACA;EACA;;EAEA,MAAMI,MAAM,SAASC,aAAa,CAAC;EACjC;IACA,WAAWR,IAAIA,GAAG;EAChB,IAAA,OAAOA,IAAI;EACb,EAAA;;EAEA;EACAS,EAAAA,MAAMA,GAAG;EACP;EACA,IAAA,IAAI,CAACC,QAAQ,CAACC,YAAY,CAAC,cAAc,EAAE,IAAI,CAACD,QAAQ,CAACE,SAAS,CAACH,MAAM,CAACL,iBAAiB,CAAC,CAAC;EAC/F,EAAA;EACF;;EAEA;EACA;EACA;;EAEAS,YAAY,CAACC,EAAE,CAACC,QAAQ,EAAET,oBAAoB,EAAED,oBAAoB,EAAEW,KAAK,IAAI;IAC7EA,KAAK,CAACC,cAAc,EAAE;IAEtB,MAAMC,MAAM,GAAGF,KAAK,CAACG,MAAM,CAACC,OAAO,CAACf,oBAAoB,CAAC;EACzD,EAAA,MAAMgB,IAAI,GAAGd,MAAM,CAACe,mBAAmB,CAACJ,MAAM,CAAC;IAE/CG,IAAI,CAACZ,MAAM,EAAE;EACf,CAAC,CAAC;;;;;;;;"}
|
||||
{"version":3,"file":"button.js","sources":["../src/button.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport BaseComponent from './base-component.js'\nimport EventHandler from './dom/event-handler.js'\nimport { defineJQueryPlugin } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst NAME = 'button'\nconst DATA_KEY = 'bs.button'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst DATA_API_KEY = '.data-api'\n\nconst CLASS_NAME_ACTIVE = 'active'\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"button\"]'\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`\n\n/**\n * Class definition\n */\n\nclass Button extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME\n }\n\n // Public\n toggle() {\n // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE))\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Button.getOrCreateInstance(this)\n\n if (config === 'toggle') {\n data[config]()\n }\n })\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => {\n event.preventDefault()\n\n const button = event.target.closest(SELECTOR_DATA_TOGGLE)\n const data = Button.getOrCreateInstance(button)\n\n data.toggle()\n})\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Button)\n\nexport default Button\n"],"names":["NAME","DATA_KEY","EVENT_KEY","DATA_API_KEY","CLASS_NAME_ACTIVE","SELECTOR_DATA_TOGGLE","EVENT_CLICK_DATA_API","Button","BaseComponent","toggle","_element","setAttribute","classList","jQueryInterface","config","each","data","getOrCreateInstance","EventHandler","on","document","event","preventDefault","button","target","closest","defineJQueryPlugin"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAMA;EACA;EACA;;EAEA,MAAMA,IAAI,GAAG,QAAQ;EACrB,MAAMC,QAAQ,GAAG,WAAW;EAC5B,MAAMC,SAAS,GAAG,CAAID,CAAAA,EAAAA,QAAQ,CAAE,CAAA;EAChC,MAAME,YAAY,GAAG,WAAW;EAEhC,MAAMC,iBAAiB,GAAG,QAAQ;EAClC,MAAMC,oBAAoB,GAAG,2BAA2B;EACxD,MAAMC,oBAAoB,GAAG,CAAA,KAAA,EAAQJ,SAAS,CAAA,EAAGC,YAAY,CAAE,CAAA;;EAE/D;EACA;EACA;;EAEA,MAAMI,MAAM,SAASC,aAAa,CAAC;EACjC;IACA,WAAWR,IAAIA,GAAG;EAChB,IAAA,OAAOA,IAAI;EACb;;EAEA;EACAS,EAAAA,MAAMA,GAAG;EACP;EACA,IAAA,IAAI,CAACC,QAAQ,CAACC,YAAY,CAAC,cAAc,EAAE,IAAI,CAACD,QAAQ,CAACE,SAAS,CAACH,MAAM,CAACL,iBAAiB,CAAC,CAAC;EAC/F;;EAEA;IACA,OAAOS,eAAeA,CAACC,MAAM,EAAE;EAC7B,IAAA,OAAO,IAAI,CAACC,IAAI,CAAC,YAAY;EAC3B,MAAA,MAAMC,IAAI,GAAGT,MAAM,CAACU,mBAAmB,CAAC,IAAI,CAAC;QAE7C,IAAIH,MAAM,KAAK,QAAQ,EAAE;EACvBE,QAAAA,IAAI,CAACF,MAAM,CAAC,EAAE;EAChB;EACF,KAAC,CAAC;EACJ;EACF;;EAEA;EACA;EACA;;EAEAI,YAAY,CAACC,EAAE,CAACC,QAAQ,EAAEd,oBAAoB,EAAED,oBAAoB,EAAEgB,KAAK,IAAI;IAC7EA,KAAK,CAACC,cAAc,EAAE;IAEtB,MAAMC,MAAM,GAAGF,KAAK,CAACG,MAAM,CAACC,OAAO,CAACpB,oBAAoB,CAAC;EACzD,EAAA,MAAMW,IAAI,GAAGT,MAAM,CAACU,mBAAmB,CAACM,MAAM,CAAC;IAE/CP,IAAI,CAACP,MAAM,EAAE;EACf,CAAC,CAAC;;EAEF;EACA;EACA;;AAEAiB,6BAAkB,CAACnB,MAAM,CAAC;;;;;;;;"}
|
||||
Vendored
+24
-1
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Bootstrap carousel.js v5.3.8 (https://getbootstrap.com/)
|
||||
* Bootstrap carousel.js v5.3.6 (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)
|
||||
*/
|
||||
@@ -325,6 +325,23 @@
|
||||
}
|
||||
return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Carousel.getOrCreateInstance(this, config);
|
||||
if (typeof config === 'number') {
|
||||
data.to(config);
|
||||
return;
|
||||
}
|
||||
if (typeof config === 'string') {
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -359,6 +376,12 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Carousel);
|
||||
|
||||
return Carousel;
|
||||
|
||||
}));
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+24
-1
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Bootstrap collapse.js v5.3.8 (https://getbootstrap.com/)
|
||||
* Bootstrap collapse.js v5.3.6 (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)
|
||||
*/
|
||||
@@ -202,6 +202,23 @@
|
||||
element.setAttribute('aria-expanded', isOpen);
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
const _config = {};
|
||||
if (typeof config === 'string' && /show|hide/.test(config)) {
|
||||
_config.toggle = false;
|
||||
}
|
||||
return this.each(function () {
|
||||
const data = Collapse.getOrCreateInstance(this, _config);
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,6 +237,12 @@
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Collapse);
|
||||
|
||||
return Collapse;
|
||||
|
||||
}));
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
-242
@@ -1,242 +0,0 @@
|
||||
/*!
|
||||
* Bootstrap dialog.js v5.3.8 (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)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./dom/manipulator.js'), require('./dom/selector-engine.js'), require('./util/component-functions.js'), require('./util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './dom/manipulator', './dom/selector-engine', './util/component-functions', './util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Dialog = factory(global.BaseComponent, global.EventHandler, global.Manipulator, global.SelectorEngine, global.ComponentFunctions, global.Index));
|
||||
})(this, (function (BaseComponent, EventHandler, Manipulator, SelectorEngine, componentFunctions_js, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap dialog.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
const NAME = 'dialog';
|
||||
const DATA_KEY = 'bs.dialog';
|
||||
const EVENT_KEY = `.${DATA_KEY}`;
|
||||
const DATA_API_KEY = '.data-api';
|
||||
const EVENT_SHOW = `show${EVENT_KEY}`;
|
||||
const EVENT_SHOWN = `shown${EVENT_KEY}`;
|
||||
const EVENT_HIDE = `hide${EVENT_KEY}`;
|
||||
const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
|
||||
const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`;
|
||||
const EVENT_CANCEL = `cancel${EVENT_KEY}`;
|
||||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
|
||||
const CLASS_NAME_STATIC = 'dialog-static';
|
||||
const CLASS_NAME_OPEN = 'dialog-open';
|
||||
const CLASS_NAME_NONMODAL = 'dialog-nonmodal';
|
||||
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="dialog"]';
|
||||
const SELECTOR_OPEN_MODAL_DIALOG = 'dialog.dialog[open]:not(.dialog-nonmodal)';
|
||||
const Default = {
|
||||
backdrop: true,
|
||||
// true (click dismisses) or 'static' (click does nothing) - only applies to modal dialogs
|
||||
keyboard: true,
|
||||
modal: true // true uses showModal(), false uses show() for non-modal dialogs
|
||||
};
|
||||
const DefaultType = {
|
||||
backdrop: '(boolean|string)',
|
||||
keyboard: 'boolean',
|
||||
modal: 'boolean'
|
||||
};
|
||||
|
||||
/**
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class Dialog extends BaseComponent {
|
||||
constructor(element, config) {
|
||||
super(element, config);
|
||||
this._isTransitioning = false;
|
||||
this._addEventListeners();
|
||||
}
|
||||
|
||||
// Getters
|
||||
static get Default() {
|
||||
return Default;
|
||||
}
|
||||
static get DefaultType() {
|
||||
return DefaultType;
|
||||
}
|
||||
static get NAME() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
// Public
|
||||
toggle(relatedTarget) {
|
||||
return this._element.open ? this.hide() : this.show(relatedTarget);
|
||||
}
|
||||
show(relatedTarget) {
|
||||
if (this._element.open || this._isTransitioning) {
|
||||
return;
|
||||
}
|
||||
const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
|
||||
relatedTarget
|
||||
});
|
||||
if (showEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
this._isTransitioning = true;
|
||||
if (this._config.modal) {
|
||||
// Modal dialog: use showModal() for focus trapping, backdrop, and top layer
|
||||
this._element.showModal();
|
||||
// Prevent body scroll for modal dialogs
|
||||
document.body.classList.add(CLASS_NAME_OPEN);
|
||||
} else {
|
||||
// Non-modal dialog: use show() - no backdrop, no focus trap, no top layer
|
||||
this._element.classList.add(CLASS_NAME_NONMODAL);
|
||||
this._element.show();
|
||||
}
|
||||
this._queueCallback(() => {
|
||||
this._isTransitioning = false;
|
||||
EventHandler.trigger(this._element, EVENT_SHOWN, {
|
||||
relatedTarget
|
||||
});
|
||||
}, this._element, this._isAnimated());
|
||||
}
|
||||
hide() {
|
||||
if (!this._element.open || this._isTransitioning) {
|
||||
return;
|
||||
}
|
||||
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE);
|
||||
if (hideEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
this._isTransitioning = true;
|
||||
this._queueCallback(() => this._hideDialog(), this._element, this._isAnimated());
|
||||
}
|
||||
dispose() {
|
||||
EventHandler.off(this._element, EVENT_KEY);
|
||||
super.dispose();
|
||||
}
|
||||
handleUpdate() {
|
||||
// Provided for API consistency with Modal.
|
||||
// Native dialogs handle their own positioning.
|
||||
}
|
||||
|
||||
// Private
|
||||
_hideDialog() {
|
||||
this._element.close();
|
||||
this._element.classList.remove(CLASS_NAME_NONMODAL);
|
||||
this._isTransitioning = false;
|
||||
|
||||
// Only restore body scroll if no other modal dialogs are open
|
||||
if (!document.querySelector(SELECTOR_OPEN_MODAL_DIALOG)) {
|
||||
document.body.classList.remove(CLASS_NAME_OPEN);
|
||||
}
|
||||
EventHandler.trigger(this._element, EVENT_HIDDEN);
|
||||
}
|
||||
_isAnimated() {
|
||||
return this._element.classList.contains('fade');
|
||||
}
|
||||
_triggerBackdropTransition() {
|
||||
const hidePreventedEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
|
||||
if (hidePreventedEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
this._element.classList.add(CLASS_NAME_STATIC);
|
||||
this._queueCallback(() => {
|
||||
this._element.classList.remove(CLASS_NAME_STATIC);
|
||||
}, this._element);
|
||||
}
|
||||
_addEventListeners() {
|
||||
// Handle native cancel event (Escape key) - only fires for modal dialogs
|
||||
EventHandler.on(this._element, 'cancel', event => {
|
||||
// Prevent native close behavior - we'll handle it
|
||||
event.preventDefault();
|
||||
if (!this._config.keyboard) {
|
||||
this._triggerBackdropTransition();
|
||||
return;
|
||||
}
|
||||
EventHandler.trigger(this._element, EVENT_CANCEL);
|
||||
this.hide();
|
||||
});
|
||||
|
||||
// Handle Escape key for non-modal dialogs (native cancel doesn't fire for show())
|
||||
EventHandler.on(this._element, 'keydown', event => {
|
||||
if (event.key !== 'Escape' || this._config.modal) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
if (!this._config.keyboard) {
|
||||
return;
|
||||
}
|
||||
EventHandler.trigger(this._element, EVENT_CANCEL);
|
||||
this.hide();
|
||||
});
|
||||
|
||||
// Handle backdrop clicks (only applies to modal dialogs)
|
||||
// Native <dialog> fires click on the dialog element when backdrop is clicked
|
||||
EventHandler.on(this._element, 'click', event => {
|
||||
// Only handle clicks directly on the dialog (backdrop area)
|
||||
// Non-modal dialogs don't have a backdrop
|
||||
if (event.target !== this._element || !this._config.modal) {
|
||||
return;
|
||||
}
|
||||
if (this._config.backdrop === 'static') {
|
||||
this._triggerBackdropTransition();
|
||||
return;
|
||||
}
|
||||
|
||||
// Default: click backdrop to dismiss
|
||||
this.hide();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data API implementation
|
||||
*/
|
||||
|
||||
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
||||
const target = SelectorEngine.getElementFromSelector(this);
|
||||
if (['A', 'AREA'].includes(this.tagName)) {
|
||||
event.preventDefault();
|
||||
}
|
||||
EventHandler.one(target, EVENT_SHOW, showEvent => {
|
||||
if (showEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
EventHandler.one(target, EVENT_HIDDEN, () => {
|
||||
if (index_js.isVisible(this)) {
|
||||
this.focus();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Get config from trigger's data attributes
|
||||
const config = Manipulator.getDataAttributes(this);
|
||||
|
||||
// Check if trigger is inside an open dialog
|
||||
const currentDialog = this.closest('dialog[open]');
|
||||
const shouldSwap = currentDialog && currentDialog !== target;
|
||||
if (shouldSwap) {
|
||||
// Open new dialog first (its backdrop appears over current)
|
||||
const newDialog = Dialog.getOrCreateInstance(target, config);
|
||||
newDialog.show(this);
|
||||
|
||||
// Close the current dialog (no backdrop flash since new one is already open)
|
||||
const currentInstance = Dialog.getInstance(currentDialog);
|
||||
if (currentInstance) {
|
||||
currentInstance.hide();
|
||||
}
|
||||
return;
|
||||
}
|
||||
const data = Dialog.getOrCreateInstance(target, config);
|
||||
data.toggle(this);
|
||||
});
|
||||
componentFunctions_js.enableDismissTrigger(Dialog);
|
||||
|
||||
return Dialog;
|
||||
|
||||
}));
|
||||
//# sourceMappingURL=dialog.js.map
|
||||
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Bootstrap data.js v5.3.8 (https://getbootstrap.com/)
|
||||
* Bootstrap data.js v5.3.6 (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)
|
||||
*/
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"data.js","sources":["../../src/dom/data.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * Constants\n */\n\nconst elementMap = new Map()\n\nexport default {\n set(element, key, instance) {\n if (!elementMap.has(element)) {\n elementMap.set(element, new Map())\n }\n\n const instanceMap = elementMap.get(element)\n\n // make it clear we only want one instance per element\n // can be removed later when multiple key/instances are fine to be used\n if (!instanceMap.has(key) && instanceMap.size !== 0) {\n // eslint-disable-next-line no-console\n console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`)\n return\n }\n\n instanceMap.set(key, instance)\n },\n\n get(element, key) {\n if (elementMap.has(element)) {\n return elementMap.get(element).get(key) || null\n }\n\n return null\n },\n\n remove(element, key) {\n if (!elementMap.has(element)) {\n return\n }\n\n const instanceMap = elementMap.get(element)\n\n instanceMap.delete(key)\n\n // free up element references if there are no instances left for an element\n if (instanceMap.size === 0) {\n elementMap.delete(element)\n }\n }\n}\n"],"names":["elementMap","Map","set","element","key","instance","has","instanceMap","get","size","console","error","Array","from","keys","remove","delete"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;;EAEA,MAAMA,UAAU,GAAG,IAAIC,GAAG,EAAE;AAE5B,eAAe;EACbC,EAAAA,GAAGA,CAACC,OAAO,EAAEC,GAAG,EAAEC,QAAQ,EAAE;EAC1B,IAAA,IAAI,CAACL,UAAU,CAACM,GAAG,CAACH,OAAO,CAAC,EAAE;QAC5BH,UAAU,CAACE,GAAG,CAACC,OAAO,EAAE,IAAIF,GAAG,EAAE,CAAC;EACpC,IAAA;EAEA,IAAA,MAAMM,WAAW,GAAGP,UAAU,CAACQ,GAAG,CAACL,OAAO,CAAC;;EAE3C;EACA;EACA,IAAA,IAAI,CAACI,WAAW,CAACD,GAAG,CAACF,GAAG,CAAC,IAAIG,WAAW,CAACE,IAAI,KAAK,CAAC,EAAE;EACnD;EACAC,MAAAA,OAAO,CAACC,KAAK,CAAC,+EAA+EC,KAAK,CAACC,IAAI,CAACN,WAAW,CAACO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;EAClI,MAAA;EACF,IAAA;EAEAP,IAAAA,WAAW,CAACL,GAAG,CAACE,GAAG,EAAEC,QAAQ,CAAC;IAChC,CAAC;EAEDG,EAAAA,GAAGA,CAACL,OAAO,EAAEC,GAAG,EAAE;EAChB,IAAA,IAAIJ,UAAU,CAACM,GAAG,CAACH,OAAO,CAAC,EAAE;EAC3B,MAAA,OAAOH,UAAU,CAACQ,GAAG,CAACL,OAAO,CAAC,CAACK,GAAG,CAACJ,GAAG,CAAC,IAAI,IAAI;EACjD,IAAA;EAEA,IAAA,OAAO,IAAI;IACb,CAAC;EAEDW,EAAAA,MAAMA,CAACZ,OAAO,EAAEC,GAAG,EAAE;EACnB,IAAA,IAAI,CAACJ,UAAU,CAACM,GAAG,CAACH,OAAO,CAAC,EAAE;EAC5B,MAAA;EACF,IAAA;EAEA,IAAA,MAAMI,WAAW,GAAGP,UAAU,CAACQ,GAAG,CAACL,OAAO,CAAC;EAE3CI,IAAAA,WAAW,CAACS,MAAM,CAACZ,GAAG,CAAC;;EAEvB;EACA,IAAA,IAAIG,WAAW,CAACE,IAAI,KAAK,CAAC,EAAE;EAC1BT,MAAAA,UAAU,CAACgB,MAAM,CAACb,OAAO,CAAC;EAC5B,IAAA;EACF,EAAA;EACF,CAAC;;;;;;;;"}
|
||||
{"version":3,"file":"data.js","sources":["../../src/dom/data.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * Constants\n */\n\nconst elementMap = new Map()\n\nexport default {\n set(element, key, instance) {\n if (!elementMap.has(element)) {\n elementMap.set(element, new Map())\n }\n\n const instanceMap = elementMap.get(element)\n\n // make it clear we only want one instance per element\n // can be removed later when multiple key/instances are fine to be used\n if (!instanceMap.has(key) && instanceMap.size !== 0) {\n // eslint-disable-next-line no-console\n console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`)\n return\n }\n\n instanceMap.set(key, instance)\n },\n\n get(element, key) {\n if (elementMap.has(element)) {\n return elementMap.get(element).get(key) || null\n }\n\n return null\n },\n\n remove(element, key) {\n if (!elementMap.has(element)) {\n return\n }\n\n const instanceMap = elementMap.get(element)\n\n instanceMap.delete(key)\n\n // free up element references if there are no instances left for an element\n if (instanceMap.size === 0) {\n elementMap.delete(element)\n }\n }\n}\n"],"names":["elementMap","Map","set","element","key","instance","has","instanceMap","get","size","console","error","Array","from","keys","remove","delete"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;;EAEA,MAAMA,UAAU,GAAG,IAAIC,GAAG,EAAE;AAE5B,eAAe;EACbC,EAAAA,GAAGA,CAACC,OAAO,EAAEC,GAAG,EAAEC,QAAQ,EAAE;EAC1B,IAAA,IAAI,CAACL,UAAU,CAACM,GAAG,CAACH,OAAO,CAAC,EAAE;QAC5BH,UAAU,CAACE,GAAG,CAACC,OAAO,EAAE,IAAIF,GAAG,EAAE,CAAC;EACpC;EAEA,IAAA,MAAMM,WAAW,GAAGP,UAAU,CAACQ,GAAG,CAACL,OAAO,CAAC;;EAE3C;EACA;EACA,IAAA,IAAI,CAACI,WAAW,CAACD,GAAG,CAACF,GAAG,CAAC,IAAIG,WAAW,CAACE,IAAI,KAAK,CAAC,EAAE;EACnD;EACAC,MAAAA,OAAO,CAACC,KAAK,CAAC,+EAA+EC,KAAK,CAACC,IAAI,CAACN,WAAW,CAACO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;EAClI,MAAA;EACF;EAEAP,IAAAA,WAAW,CAACL,GAAG,CAACE,GAAG,EAAEC,QAAQ,CAAC;KAC/B;EAEDG,EAAAA,GAAGA,CAACL,OAAO,EAAEC,GAAG,EAAE;EAChB,IAAA,IAAIJ,UAAU,CAACM,GAAG,CAACH,OAAO,CAAC,EAAE;EAC3B,MAAA,OAAOH,UAAU,CAACQ,GAAG,CAACL,OAAO,CAAC,CAACK,GAAG,CAACJ,GAAG,CAAC,IAAI,IAAI;EACjD;EAEA,IAAA,OAAO,IAAI;KACZ;EAEDW,EAAAA,MAAMA,CAACZ,OAAO,EAAEC,GAAG,EAAE;EACnB,IAAA,IAAI,CAACJ,UAAU,CAACM,GAAG,CAACH,OAAO,CAAC,EAAE;EAC5B,MAAA;EACF;EAEA,IAAA,MAAMI,WAAW,GAAGP,UAAU,CAACQ,GAAG,CAACL,OAAO,CAAC;EAE3CI,IAAAA,WAAW,CAACS,MAAM,CAACZ,GAAG,CAAC;;EAEvB;EACA,IAAA,IAAIG,WAAW,CAACE,IAAI,KAAK,CAAC,EAAE;EAC1BT,MAAAA,UAAU,CAACgB,MAAM,CAACb,OAAO,CAAC;EAC5B;EACF;EACF,CAAC;;;;;;;;"}
|
||||
Vendored
+31
-8
@@ -1,13 +1,13 @@
|
||||
/*!
|
||||
* Bootstrap event-handler.js v5.3.8 (https://getbootstrap.com/)
|
||||
* Bootstrap event-handler.js v5.3.6 (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)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.EventHandler = factory());
|
||||
})(this, (function () { 'use strict';
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('../util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['../util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.EventHandler = factory(global.Index));
|
||||
})(this, (function (index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
@@ -16,6 +16,7 @@
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
@@ -184,11 +185,33 @@
|
||||
if (typeof event !== 'string' || !element) {
|
||||
return null;
|
||||
}
|
||||
const $ = index_js.getjQuery();
|
||||
const typeEvent = getTypeEvent(event);
|
||||
const inNamespace = event !== typeEvent;
|
||||
let jQueryEvent = null;
|
||||
let bubbles = true;
|
||||
let nativeDispatch = true;
|
||||
let defaultPrevented = false;
|
||||
if (inNamespace && $) {
|
||||
jQueryEvent = $.Event(event, args);
|
||||
$(element).trigger(jQueryEvent);
|
||||
bubbles = !jQueryEvent.isPropagationStopped();
|
||||
nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();
|
||||
defaultPrevented = jQueryEvent.isDefaultPrevented();
|
||||
}
|
||||
const evt = hydrateObj(new Event(event, {
|
||||
bubbles: true,
|
||||
bubbles,
|
||||
cancelable: true
|
||||
}), args);
|
||||
element.dispatchEvent(evt);
|
||||
if (defaultPrevented) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
if (nativeDispatch) {
|
||||
element.dispatchEvent(evt);
|
||||
}
|
||||
if (evt.defaultPrevented && jQueryEvent) {
|
||||
jQueryEvent.preventDefault();
|
||||
}
|
||||
return evt;
|
||||
}
|
||||
};
|
||||
@@ -196,7 +219,7 @@
|
||||
for (const [key, value] of Object.entries(meta)) {
|
||||
try {
|
||||
obj[key] = value;
|
||||
} catch {
|
||||
} catch (_unused) {
|
||||
Object.defineProperty(obj, key, {
|
||||
configurable: true,
|
||||
get() {
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Bootstrap manipulator.js v5.3.8 (https://getbootstrap.com/)
|
||||
* Bootstrap manipulator.js v5.3.6 (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)
|
||||
*/
|
||||
@@ -34,7 +34,7 @@
|
||||
}
|
||||
try {
|
||||
return JSON.parse(decodeURIComponent(value));
|
||||
} catch {
|
||||
} catch (_unused) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"manipulator.js","sources":["../../src/dom/manipulator.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/manipulator.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nfunction normalizeData(value) {\n if (value === 'true') {\n return true\n }\n\n if (value === 'false') {\n return false\n }\n\n if (value === Number(value).toString()) {\n return Number(value)\n }\n\n if (value === '' || value === 'null') {\n return null\n }\n\n if (typeof value !== 'string') {\n return value\n }\n\n try {\n return JSON.parse(decodeURIComponent(value))\n } catch {\n return value\n }\n}\n\nfunction normalizeDataKey(key) {\n return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`)\n}\n\nconst Manipulator = {\n setDataAttribute(element, key, value) {\n element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value)\n },\n\n removeDataAttribute(element, key) {\n element.removeAttribute(`data-bs-${normalizeDataKey(key)}`)\n },\n\n getDataAttributes(element) {\n if (!element) {\n return {}\n }\n\n const attributes = {}\n const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'))\n\n for (const key of bsKeys) {\n let pureKey = key.replace(/^bs/, '')\n pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1)\n attributes[pureKey] = normalizeData(element.dataset[key])\n }\n\n return attributes\n },\n\n getDataAttribute(element, key) {\n return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`))\n }\n}\n\nexport default Manipulator\n"],"names":["normalizeData","value","Number","toString","JSON","parse","decodeURIComponent","normalizeDataKey","key","replace","chr","toLowerCase","Manipulator","setDataAttribute","element","setAttribute","removeDataAttribute","removeAttribute","getDataAttributes","attributes","bsKeys","Object","keys","dataset","filter","startsWith","pureKey","charAt","slice","getDataAttribute","getAttribute"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;EAEA,SAASA,aAAaA,CAACC,KAAK,EAAE;IAC5B,IAAIA,KAAK,KAAK,MAAM,EAAE;EACpB,IAAA,OAAO,IAAI;EACb,EAAA;IAEA,IAAIA,KAAK,KAAK,OAAO,EAAE;EACrB,IAAA,OAAO,KAAK;EACd,EAAA;IAEA,IAAIA,KAAK,KAAKC,MAAM,CAACD,KAAK,CAAC,CAACE,QAAQ,EAAE,EAAE;MACtC,OAAOD,MAAM,CAACD,KAAK,CAAC;EACtB,EAAA;EAEA,EAAA,IAAIA,KAAK,KAAK,EAAE,IAAIA,KAAK,KAAK,MAAM,EAAE;EACpC,IAAA,OAAO,IAAI;EACb,EAAA;EAEA,EAAA,IAAI,OAAOA,KAAK,KAAK,QAAQ,EAAE;EAC7B,IAAA,OAAOA,KAAK;EACd,EAAA;IAEA,IAAI;MACF,OAAOG,IAAI,CAACC,KAAK,CAACC,kBAAkB,CAACL,KAAK,CAAC,CAAC;EAC9C,EAAA,CAAC,CAAC,MAAM;EACN,IAAA,OAAOA,KAAK;EACd,EAAA;EACF;EAEA,SAASM,gBAAgBA,CAACC,GAAG,EAAE;EAC7B,EAAA,OAAOA,GAAG,CAACC,OAAO,CAAC,QAAQ,EAAEC,GAAG,IAAI,CAAA,CAAA,EAAIA,GAAG,CAACC,WAAW,EAAE,EAAE,CAAC;EAC9D;AAEA,QAAMC,WAAW,GAAG;EAClBC,EAAAA,gBAAgBA,CAACC,OAAO,EAAEN,GAAG,EAAEP,KAAK,EAAE;MACpCa,OAAO,CAACC,YAAY,CAAC,CAAA,QAAA,EAAWR,gBAAgB,CAACC,GAAG,CAAC,CAAA,CAAE,EAAEP,KAAK,CAAC;IACjE,CAAC;EAEDe,EAAAA,mBAAmBA,CAACF,OAAO,EAAEN,GAAG,EAAE;MAChCM,OAAO,CAACG,eAAe,CAAC,CAAA,QAAA,EAAWV,gBAAgB,CAACC,GAAG,CAAC,CAAA,CAAE,CAAC;IAC7D,CAAC;IAEDU,iBAAiBA,CAACJ,OAAO,EAAE;MACzB,IAAI,CAACA,OAAO,EAAE;EACZ,MAAA,OAAO,EAAE;EACX,IAAA;MAEA,MAAMK,UAAU,GAAG,EAAE;EACrB,IAAA,MAAMC,MAAM,GAAGC,MAAM,CAACC,IAAI,CAACR,OAAO,CAACS,OAAO,CAAC,CAACC,MAAM,CAAChB,GAAG,IAAIA,GAAG,CAACiB,UAAU,CAAC,IAAI,CAAC,IAAI,CAACjB,GAAG,CAACiB,UAAU,CAAC,UAAU,CAAC,CAAC;EAE9G,IAAA,KAAK,MAAMjB,GAAG,IAAIY,MAAM,EAAE;QACxB,IAAIM,OAAO,GAAGlB,GAAG,CAACC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;EACpCiB,MAAAA,OAAO,GAAGA,OAAO,CAACC,MAAM,CAAC,CAAC,CAAC,CAAChB,WAAW,EAAE,GAAGe,OAAO,CAACE,KAAK,CAAC,CAAC,CAAC;EAC5DT,MAAAA,UAAU,CAACO,OAAO,CAAC,GAAG1B,aAAa,CAACc,OAAO,CAACS,OAAO,CAACf,GAAG,CAAC,CAAC;EAC3D,IAAA;EAEA,IAAA,OAAOW,UAAU;IACnB,CAAC;EAEDU,EAAAA,gBAAgBA,CAACf,OAAO,EAAEN,GAAG,EAAE;EAC7B,IAAA,OAAOR,aAAa,CAACc,OAAO,CAACgB,YAAY,CAAC,CAAA,QAAA,EAAWvB,gBAAgB,CAACC,GAAG,CAAC,CAAA,CAAE,CAAC,CAAC;EAChF,EAAA;EACF;;;;;;;;"}
|
||||
{"version":3,"file":"manipulator.js","sources":["../../src/dom/manipulator.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/manipulator.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nfunction normalizeData(value) {\n if (value === 'true') {\n return true\n }\n\n if (value === 'false') {\n return false\n }\n\n if (value === Number(value).toString()) {\n return Number(value)\n }\n\n if (value === '' || value === 'null') {\n return null\n }\n\n if (typeof value !== 'string') {\n return value\n }\n\n try {\n return JSON.parse(decodeURIComponent(value))\n } catch {\n return value\n }\n}\n\nfunction normalizeDataKey(key) {\n return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`)\n}\n\nconst Manipulator = {\n setDataAttribute(element, key, value) {\n element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value)\n },\n\n removeDataAttribute(element, key) {\n element.removeAttribute(`data-bs-${normalizeDataKey(key)}`)\n },\n\n getDataAttributes(element) {\n if (!element) {\n return {}\n }\n\n const attributes = {}\n const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'))\n\n for (const key of bsKeys) {\n let pureKey = key.replace(/^bs/, '')\n pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1)\n attributes[pureKey] = normalizeData(element.dataset[key])\n }\n\n return attributes\n },\n\n getDataAttribute(element, key) {\n return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`))\n }\n}\n\nexport default Manipulator\n"],"names":["normalizeData","value","Number","toString","JSON","parse","decodeURIComponent","_unused","normalizeDataKey","key","replace","chr","toLowerCase","Manipulator","setDataAttribute","element","setAttribute","removeDataAttribute","removeAttribute","getDataAttributes","attributes","bsKeys","Object","keys","dataset","filter","startsWith","pureKey","charAt","slice","getDataAttribute","getAttribute"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;EAEA,SAASA,aAAaA,CAACC,KAAK,EAAE;IAC5B,IAAIA,KAAK,KAAK,MAAM,EAAE;EACpB,IAAA,OAAO,IAAI;EACb;IAEA,IAAIA,KAAK,KAAK,OAAO,EAAE;EACrB,IAAA,OAAO,KAAK;EACd;IAEA,IAAIA,KAAK,KAAKC,MAAM,CAACD,KAAK,CAAC,CAACE,QAAQ,EAAE,EAAE;MACtC,OAAOD,MAAM,CAACD,KAAK,CAAC;EACtB;EAEA,EAAA,IAAIA,KAAK,KAAK,EAAE,IAAIA,KAAK,KAAK,MAAM,EAAE;EACpC,IAAA,OAAO,IAAI;EACb;EAEA,EAAA,IAAI,OAAOA,KAAK,KAAK,QAAQ,EAAE;EAC7B,IAAA,OAAOA,KAAK;EACd;IAEA,IAAI;MACF,OAAOG,IAAI,CAACC,KAAK,CAACC,kBAAkB,CAACL,KAAK,CAAC,CAAC;KAC7C,CAAC,OAAAM,OAAA,EAAM;EACN,IAAA,OAAON,KAAK;EACd;EACF;EAEA,SAASO,gBAAgBA,CAACC,GAAG,EAAE;EAC7B,EAAA,OAAOA,GAAG,CAACC,OAAO,CAAC,QAAQ,EAAEC,GAAG,IAAI,CAAA,CAAA,EAAIA,GAAG,CAACC,WAAW,EAAE,EAAE,CAAC;EAC9D;AAEA,QAAMC,WAAW,GAAG;EAClBC,EAAAA,gBAAgBA,CAACC,OAAO,EAAEN,GAAG,EAAER,KAAK,EAAE;MACpCc,OAAO,CAACC,YAAY,CAAC,CAAWR,QAAAA,EAAAA,gBAAgB,CAACC,GAAG,CAAC,CAAA,CAAE,EAAER,KAAK,CAAC;KAChE;EAEDgB,EAAAA,mBAAmBA,CAACF,OAAO,EAAEN,GAAG,EAAE;MAChCM,OAAO,CAACG,eAAe,CAAC,CAAA,QAAA,EAAWV,gBAAgB,CAACC,GAAG,CAAC,CAAA,CAAE,CAAC;KAC5D;IAEDU,iBAAiBA,CAACJ,OAAO,EAAE;MACzB,IAAI,CAACA,OAAO,EAAE;EACZ,MAAA,OAAO,EAAE;EACX;MAEA,MAAMK,UAAU,GAAG,EAAE;EACrB,IAAA,MAAMC,MAAM,GAAGC,MAAM,CAACC,IAAI,CAACR,OAAO,CAACS,OAAO,CAAC,CAACC,MAAM,CAAChB,GAAG,IAAIA,GAAG,CAACiB,UAAU,CAAC,IAAI,CAAC,IAAI,CAACjB,GAAG,CAACiB,UAAU,CAAC,UAAU,CAAC,CAAC;EAE9G,IAAA,KAAK,MAAMjB,GAAG,IAAIY,MAAM,EAAE;QACxB,IAAIM,OAAO,GAAGlB,GAAG,CAACC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;EACpCiB,MAAAA,OAAO,GAAGA,OAAO,CAACC,MAAM,CAAC,CAAC,CAAC,CAAChB,WAAW,EAAE,GAAGe,OAAO,CAACE,KAAK,CAAC,CAAC,CAAC;EAC5DT,MAAAA,UAAU,CAACO,OAAO,CAAC,GAAG3B,aAAa,CAACe,OAAO,CAACS,OAAO,CAACf,GAAG,CAAC,CAAC;EAC3D;EAEA,IAAA,OAAOW,UAAU;KAClB;EAEDU,EAAAA,gBAAgBA,CAACf,OAAO,EAAEN,GAAG,EAAE;EAC7B,IAAA,OAAOT,aAAa,CAACe,OAAO,CAACgB,YAAY,CAAC,CAAWvB,QAAAA,EAAAA,gBAAgB,CAACC,GAAG,CAAC,CAAA,CAAE,CAAC,CAAC;EAChF;EACF;;;;;;;;"}
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Bootstrap selector-engine.js v5.3.8 (https://getbootstrap.com/)
|
||||
* Bootstrap selector-engine.js v5.3.6 (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)
|
||||
*/
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+143
-603
@@ -1,13 +1,32 @@
|
||||
/*!
|
||||
* Bootstrap dropdown.js v5.3.8 (https://getbootstrap.com/)
|
||||
* Bootstrap dropdown.js v5.3.6 (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)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@floating-ui/dom'), require('./base-component.js'), require('./dom/event-handler.js'), require('./dom/manipulator.js'), require('./dom/selector-engine.js'), require('./util/index.js'), require('./util/floating-ui.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['@floating-ui/dom', './base-component', './dom/event-handler', './dom/manipulator', './dom/selector-engine', './util/index', './util/floating-ui'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Dropdown = factory(global["@floating-ui/dom"], global.BaseComponent, global.EventHandler, global.Manipulator, global.SelectorEngine, global.Index, global.FloatingUi));
|
||||
})(this, (function (dom, BaseComponent, EventHandler, Manipulator, SelectorEngine, index_js, floatingUi_js) { 'use strict';
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@popperjs/core'), require('./base-component.js'), require('./dom/event-handler.js'), require('./dom/manipulator.js'), require('./dom/selector-engine.js'), require('./util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['@popperjs/core', './base-component', './dom/event-handler', './dom/manipulator', './dom/selector-engine', './util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Dropdown = factory(global["@popperjs/core"], global.BaseComponent, global.EventHandler, global.Manipulator, global.SelectorEngine, global.Index));
|
||||
})(this, (function (Popper, BaseComponent, EventHandler, Manipulator, SelectorEngine, index_js) { 'use strict';
|
||||
|
||||
function _interopNamespaceDefault(e) {
|
||||
const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
|
||||
if (e) {
|
||||
for (const k in e) {
|
||||
if (k !== 'default') {
|
||||
const d = Object.getOwnPropertyDescriptor(e, k);
|
||||
Object.defineProperty(n, k, d.get ? d : {
|
||||
enumerable: true,
|
||||
get: () => e[k]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
n.default = e;
|
||||
return Object.freeze(n);
|
||||
}
|
||||
|
||||
const Popper__namespace = /*#__PURE__*/_interopNamespaceDefault(Popper);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
@@ -29,16 +48,8 @@
|
||||
const TAB_KEY = 'Tab';
|
||||
const ARROW_UP_KEY = 'ArrowUp';
|
||||
const ARROW_DOWN_KEY = 'ArrowDown';
|
||||
const ARROW_LEFT_KEY = 'ArrowLeft';
|
||||
const ARROW_RIGHT_KEY = 'ArrowRight';
|
||||
const HOME_KEY = 'Home';
|
||||
const END_KEY = 'End';
|
||||
const ENTER_KEY = 'Enter';
|
||||
const SPACE_KEY = ' ';
|
||||
const RIGHT_MOUSE_BUTTON = 2;
|
||||
const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button
|
||||
|
||||
// Hover intent delay (ms) - grace period before closing submenu
|
||||
const SUBMENU_CLOSE_DELAY = 100;
|
||||
const EVENT_HIDE = `hide${EVENT_KEY}`;
|
||||
const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
|
||||
const EVENT_SHOW = `show${EVENT_KEY}`;
|
||||
@@ -47,54 +58,40 @@
|
||||
const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`;
|
||||
const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`;
|
||||
const CLASS_NAME_SHOW = 'show';
|
||||
const CLASS_NAME_DROPUP = 'dropup';
|
||||
const CLASS_NAME_DROPEND = 'dropend';
|
||||
const CLASS_NAME_DROPSTART = 'dropstart';
|
||||
const CLASS_NAME_DROPUP_CENTER = 'dropup-center';
|
||||
const CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center';
|
||||
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)';
|
||||
const SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE}.${CLASS_NAME_SHOW}`;
|
||||
const SELECTOR_MENU = '.dropdown-menu';
|
||||
const SELECTOR_SUBMENU = '.dropdown-submenu';
|
||||
const SELECTOR_SUBMENU_TOGGLE = '.dropdown-submenu > .dropdown-item';
|
||||
const SELECTOR_NAVBAR = '.navbar';
|
||||
const SELECTOR_NAVBAR_NAV = '.navbar-nav';
|
||||
const SELECTOR_VISIBLE_ITEMS = '.dropdown-item:not(.disabled):not(:disabled)';
|
||||
|
||||
// Default logical placement (uses start/end which get resolved to left/right based on RTL)
|
||||
const DEFAULT_PLACEMENT = 'bottom-start';
|
||||
const SUBMENU_PLACEMENT = 'end-start';
|
||||
|
||||
// Resolve logical placement (start/end) to physical (left/right) based on RTL
|
||||
const resolveLogicalPlacement = placement => {
|
||||
if (index_js.isRTL()) {
|
||||
// RTL: start → right, end → left
|
||||
return placement.replace(/^start(?=-|$)/, 'right').replace(/^end(?=-|$)/, 'left');
|
||||
}
|
||||
|
||||
// LTR: start → left, end → right
|
||||
return placement.replace(/^start(?=-|$)/, 'left').replace(/^end(?=-|$)/, 'right');
|
||||
};
|
||||
|
||||
// Helper for barycentric coordinate calculation (point in triangle check)
|
||||
const triangleSign = (p1, p2, p3) => (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);
|
||||
const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';
|
||||
const PLACEMENT_TOP = index_js.isRTL() ? 'top-end' : 'top-start';
|
||||
const PLACEMENT_TOPEND = index_js.isRTL() ? 'top-start' : 'top-end';
|
||||
const PLACEMENT_BOTTOM = index_js.isRTL() ? 'bottom-end' : 'bottom-start';
|
||||
const PLACEMENT_BOTTOMEND = index_js.isRTL() ? 'bottom-start' : 'bottom-end';
|
||||
const PLACEMENT_RIGHT = index_js.isRTL() ? 'left-start' : 'right-start';
|
||||
const PLACEMENT_LEFT = index_js.isRTL() ? 'right-start' : 'left-start';
|
||||
const PLACEMENT_TOPCENTER = 'top';
|
||||
const PLACEMENT_BOTTOMCENTER = 'bottom';
|
||||
const Default = {
|
||||
autoClose: true,
|
||||
boundary: 'clippingParents',
|
||||
display: 'dynamic',
|
||||
offset: [0, 2],
|
||||
floatingConfig: null,
|
||||
placement: DEFAULT_PLACEMENT,
|
||||
reference: 'toggle',
|
||||
// Submenu options
|
||||
submenuTrigger: 'both',
|
||||
// 'click', 'hover', or 'both'
|
||||
submenuDelay: SUBMENU_CLOSE_DELAY
|
||||
popperConfig: null,
|
||||
reference: 'toggle'
|
||||
};
|
||||
const DefaultType = {
|
||||
autoClose: '(boolean|string)',
|
||||
boundary: '(string|element)',
|
||||
display: 'string',
|
||||
offset: '(array|string|function)',
|
||||
floatingConfig: '(null|object|function)',
|
||||
placement: 'string',
|
||||
reference: '(string|element|object)',
|
||||
submenuTrigger: 'string',
|
||||
submenuDelay: 'number'
|
||||
popperConfig: '(null|object|function)',
|
||||
reference: '(string|element|object)'
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -103,27 +100,12 @@
|
||||
|
||||
class Dropdown extends BaseComponent {
|
||||
constructor(element, config) {
|
||||
if (typeof dom.computePosition === 'undefined') {
|
||||
throw new TypeError('Bootstrap\'s dropdowns require Floating UI (https://floating-ui.com)');
|
||||
}
|
||||
super(element, config);
|
||||
this._floatingCleanup = null;
|
||||
this._mediaQueryListeners = [];
|
||||
this._responsivePlacements = null;
|
||||
this._popper = null;
|
||||
this._parent = this._element.parentNode; // dropdown wrapper
|
||||
this._isSubmenu = this._parent.classList.contains('dropdown-submenu');
|
||||
this._openSubmenus = new Map(); // Map of submenu element -> cleanup function
|
||||
this._submenuCloseTimeouts = new Map(); // Map of submenu element -> timeout ID
|
||||
this._hoverIntentData = null; // For safe triangle calculation
|
||||
|
||||
// TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/
|
||||
this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent);
|
||||
|
||||
// Parse responsive placements on init
|
||||
this._parseResponsivePlacements();
|
||||
|
||||
// Set up submenu event listeners
|
||||
this._setupSubmenuListeners();
|
||||
this._inNavbar = this._detectNavbar();
|
||||
}
|
||||
|
||||
// Getters
|
||||
@@ -152,7 +134,7 @@
|
||||
if (showEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
this._createFloating();
|
||||
this._createPopper();
|
||||
|
||||
// If this is a touch-enabled device we add extra
|
||||
// empty mouseover listeners to the body's immediate children;
|
||||
@@ -164,10 +146,9 @@
|
||||
}
|
||||
}
|
||||
this._element.focus();
|
||||
this._element.setAttribute('aria-expanded', 'true');
|
||||
this._element.setAttribute('aria-expanded', true);
|
||||
this._menu.classList.add(CLASS_NAME_SHOW);
|
||||
this._element.classList.add(CLASS_NAME_SHOW);
|
||||
this._parent.classList.add(CLASS_NAME_SHOW);
|
||||
EventHandler.trigger(this._element, EVENT_SHOWN, relatedTarget);
|
||||
}
|
||||
hide() {
|
||||
@@ -180,15 +161,15 @@
|
||||
this._completeHide(relatedTarget);
|
||||
}
|
||||
dispose() {
|
||||
this._disposeFloating();
|
||||
this._disposeMediaQueryListeners();
|
||||
this._closeAllSubmenus();
|
||||
this._clearAllSubmenuTimeouts();
|
||||
if (this._popper) {
|
||||
this._popper.destroy();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
update() {
|
||||
if (this._floatingCleanup) {
|
||||
this._updateFloatingPosition();
|
||||
this._inNavbar = this._detectNavbar();
|
||||
if (this._popper) {
|
||||
this._popper.update();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,9 +180,6 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// Close all open submenus first
|
||||
this._closeAllSubmenus();
|
||||
|
||||
// If this is a touch-enabled device we remove the extra
|
||||
// empty mouseover listeners we added for iOS support
|
||||
if ('ontouchstart' in document.documentElement) {
|
||||
@@ -209,27 +187,29 @@
|
||||
EventHandler.off(element, 'mouseover', index_js.noop);
|
||||
}
|
||||
}
|
||||
this._disposeFloating();
|
||||
if (this._popper) {
|
||||
this._popper.destroy();
|
||||
}
|
||||
this._menu.classList.remove(CLASS_NAME_SHOW);
|
||||
this._element.classList.remove(CLASS_NAME_SHOW);
|
||||
this._parent.classList.remove(CLASS_NAME_SHOW);
|
||||
this._element.setAttribute('aria-expanded', 'false');
|
||||
Manipulator.removeDataAttribute(this._menu, 'placement');
|
||||
Manipulator.removeDataAttribute(this._menu, 'display');
|
||||
Manipulator.removeDataAttribute(this._menu, 'popper');
|
||||
EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget);
|
||||
|
||||
// Explicitly return focus to the trigger element
|
||||
this._element.focus();
|
||||
}
|
||||
_getConfig(config) {
|
||||
config = super._getConfig(config);
|
||||
if (typeof config.reference === 'object' && !index_js.isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {
|
||||
// Floating UI virtual elements require a getBoundingClientRect method
|
||||
// Popper virtual elements require a getBoundingClientRect method
|
||||
throw new TypeError(`${NAME.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
_createFloating() {
|
||||
if (this._config.display === 'static') {
|
||||
Manipulator.setDataAttribute(this._menu, 'display', 'static');
|
||||
return;
|
||||
_createPopper() {
|
||||
if (typeof Popper__namespace === 'undefined') {
|
||||
throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org/docs/v2/)');
|
||||
}
|
||||
let referenceElement = this._element;
|
||||
if (this._config.reference === 'parent') {
|
||||
@@ -239,430 +219,83 @@
|
||||
} else if (typeof this._config.reference === 'object') {
|
||||
referenceElement = this._config.reference;
|
||||
}
|
||||
|
||||
// Initial position update
|
||||
this._updateFloatingPosition(referenceElement);
|
||||
|
||||
// Set up auto-update for scroll/resize
|
||||
this._floatingCleanup = dom.autoUpdate(referenceElement, this._menu, () => this._updateFloatingPosition(referenceElement));
|
||||
}
|
||||
async _updateFloatingPosition(referenceElement = null) {
|
||||
if (!this._menu) {
|
||||
return;
|
||||
}
|
||||
if (!referenceElement) {
|
||||
if (this._config.reference === 'parent') {
|
||||
referenceElement = this._parent;
|
||||
} else if (index_js.isElement(this._config.reference)) {
|
||||
referenceElement = index_js.getElement(this._config.reference);
|
||||
} else if (typeof this._config.reference === 'object') {
|
||||
referenceElement = this._config.reference;
|
||||
} else {
|
||||
referenceElement = this._element;
|
||||
}
|
||||
}
|
||||
const placement = this._getPlacement();
|
||||
const middleware = this._getFloatingMiddleware();
|
||||
const floatingConfig = this._getFloatingConfig(placement, middleware);
|
||||
await this._applyFloatingPosition(referenceElement, this._menu, floatingConfig.placement, floatingConfig.middleware);
|
||||
const popperConfig = this._getPopperConfig();
|
||||
this._popper = Popper__namespace.createPopper(referenceElement, this._menu, popperConfig);
|
||||
}
|
||||
_isShown() {
|
||||
return this._menu.classList.contains(CLASS_NAME_SHOW);
|
||||
}
|
||||
_getPlacement() {
|
||||
// If we have responsive placements, find the appropriate one for current viewport
|
||||
const placement = this._responsivePlacements ? floatingUi_js.getResponsivePlacement(this._responsivePlacements, DEFAULT_PLACEMENT) : this._config.placement;
|
||||
|
||||
// Resolve logical placements (start/end) to physical (left/right) based on RTL
|
||||
return resolveLogicalPlacement(placement);
|
||||
}
|
||||
_parseResponsivePlacements() {
|
||||
this._responsivePlacements = floatingUi_js.parseResponsivePlacement(this._config.placement, DEFAULT_PLACEMENT);
|
||||
if (this._responsivePlacements) {
|
||||
this._setupMediaQueryListeners();
|
||||
const parentDropdown = this._parent;
|
||||
if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {
|
||||
return PLACEMENT_RIGHT;
|
||||
}
|
||||
if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {
|
||||
return PLACEMENT_LEFT;
|
||||
}
|
||||
if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {
|
||||
return PLACEMENT_TOPCENTER;
|
||||
}
|
||||
if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {
|
||||
return PLACEMENT_BOTTOMCENTER;
|
||||
}
|
||||
|
||||
// We need to trim the value because custom properties can also include spaces
|
||||
const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end';
|
||||
if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {
|
||||
return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP;
|
||||
}
|
||||
return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM;
|
||||
}
|
||||
_setupMediaQueryListeners() {
|
||||
this._disposeMediaQueryListeners();
|
||||
this._mediaQueryListeners = floatingUi_js.createBreakpointListeners(() => {
|
||||
if (this._isShown()) {
|
||||
this._updateFloatingPosition();
|
||||
}
|
||||
});
|
||||
}
|
||||
_disposeMediaQueryListeners() {
|
||||
floatingUi_js.disposeBreakpointListeners(this._mediaQueryListeners);
|
||||
this._mediaQueryListeners = [];
|
||||
_detectNavbar() {
|
||||
return this._element.closest(SELECTOR_NAVBAR) !== null;
|
||||
}
|
||||
_getOffset() {
|
||||
const {
|
||||
offset: offsetConfig
|
||||
offset
|
||||
} = this._config;
|
||||
if (typeof offsetConfig === 'string') {
|
||||
return offsetConfig.split(',').map(value => Number.parseInt(value, 10));
|
||||
if (typeof offset === 'string') {
|
||||
return offset.split(',').map(value => Number.parseInt(value, 10));
|
||||
}
|
||||
if (typeof offsetConfig === 'function') {
|
||||
// Floating UI passes different args, adapt the interface for offset function callbacks
|
||||
return ({
|
||||
placement,
|
||||
rects
|
||||
}) => {
|
||||
const result = offsetConfig({
|
||||
placement,
|
||||
reference: rects.reference,
|
||||
floating: rects.floating
|
||||
}, this._element);
|
||||
return result;
|
||||
};
|
||||
if (typeof offset === 'function') {
|
||||
return popperData => offset(popperData, this._element);
|
||||
}
|
||||
return offsetConfig;
|
||||
return offset;
|
||||
}
|
||||
_getFloatingMiddleware() {
|
||||
const offsetValue = this._getOffset();
|
||||
const middleware = [
|
||||
// Offset middleware - handles distance from reference
|
||||
dom.offset(typeof offsetValue === 'function' ? offsetValue : {
|
||||
mainAxis: offsetValue[1] || 0,
|
||||
crossAxis: offsetValue[0] || 0
|
||||
}),
|
||||
// Flip middleware - handles fallback placements
|
||||
dom.flip({
|
||||
fallbackPlacements: this._getFallbackPlacements()
|
||||
}),
|
||||
// Shift middleware - prevents overflow
|
||||
dom.shift({
|
||||
boundary: this._config.boundary === 'clippingParents' ? 'clippingAncestors' : this._config.boundary
|
||||
})];
|
||||
return middleware;
|
||||
}
|
||||
_getFallbackPlacements() {
|
||||
// Get appropriate fallback placements based on current placement
|
||||
// Fallbacks should preserve alignment (start/end) when possible
|
||||
const placement = this._getPlacement();
|
||||
_getPopperConfig() {
|
||||
const defaultBsPopperConfig = {
|
||||
placement: this._getPlacement(),
|
||||
modifiers: [{
|
||||
name: 'preventOverflow',
|
||||
options: {
|
||||
boundary: this._config.boundary
|
||||
}
|
||||
}, {
|
||||
name: 'offset',
|
||||
options: {
|
||||
offset: this._getOffset()
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
// Handle all possible Floating UI placements
|
||||
const fallbackMap = {
|
||||
bottom: ['top', 'bottom-start', 'bottom-end', 'top-start', 'top-end'],
|
||||
'bottom-start': ['top-start', 'bottom-end', 'top-end'],
|
||||
'bottom-end': ['top-end', 'bottom-start', 'top-start'],
|
||||
top: ['bottom', 'top-start', 'top-end', 'bottom-start', 'bottom-end'],
|
||||
'top-start': ['bottom-start', 'top-end', 'bottom-end'],
|
||||
'top-end': ['bottom-end', 'top-start', 'bottom-start'],
|
||||
right: ['left', 'right-start', 'right-end', 'left-start', 'left-end'],
|
||||
'right-start': ['left-start', 'right-end', 'left-end', 'top-start', 'bottom-start'],
|
||||
'right-end': ['left-end', 'right-start', 'left-start', 'top-end', 'bottom-end'],
|
||||
left: ['right', 'left-start', 'left-end', 'right-start', 'right-end'],
|
||||
'left-start': ['right-start', 'left-end', 'right-end', 'top-start', 'bottom-start'],
|
||||
'left-end': ['right-end', 'left-start', 'right-start', 'top-end', 'bottom-end']
|
||||
};
|
||||
return fallbackMap[placement] || ['top', 'bottom', 'right', 'left'];
|
||||
}
|
||||
_getFloatingConfig(placement, middleware) {
|
||||
const defaultConfig = {
|
||||
placement,
|
||||
middleware
|
||||
};
|
||||
// Disable Popper if we have a static display or Dropdown is in Navbar
|
||||
if (this._inNavbar || this._config.display === 'static') {
|
||||
Manipulator.setDataAttribute(this._menu, 'popper', 'static'); // TODO: v6 remove
|
||||
defaultBsPopperConfig.modifiers = [{
|
||||
name: 'applyStyles',
|
||||
enabled: false
|
||||
}];
|
||||
}
|
||||
return {
|
||||
...defaultConfig,
|
||||
...index_js.execute(this._config.floatingConfig, [undefined, defaultConfig])
|
||||
...defaultBsPopperConfig,
|
||||
...index_js.execute(this._config.popperConfig, [undefined, defaultBsPopperConfig])
|
||||
};
|
||||
}
|
||||
_disposeFloating() {
|
||||
if (this._floatingCleanup) {
|
||||
this._floatingCleanup();
|
||||
this._floatingCleanup = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Shared helper for positioning any floating element
|
||||
async _applyFloatingPosition(reference, floating, placement, middleware) {
|
||||
if (!floating.isConnected) {
|
||||
return null;
|
||||
}
|
||||
const {
|
||||
x,
|
||||
y,
|
||||
placement: finalPlacement
|
||||
} = await dom.computePosition(reference, floating, {
|
||||
placement,
|
||||
middleware
|
||||
});
|
||||
if (!floating.isConnected) {
|
||||
return null;
|
||||
}
|
||||
Object.assign(floating.style, {
|
||||
position: 'absolute',
|
||||
left: `${x}px`,
|
||||
top: `${y}px`,
|
||||
margin: '0'
|
||||
});
|
||||
Manipulator.setDataAttribute(floating, 'placement', finalPlacement);
|
||||
return finalPlacement;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Submenu handling
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
_setupSubmenuListeners() {
|
||||
// Set up hover listeners for submenu triggers
|
||||
if (this._config.submenuTrigger === 'hover' || this._config.submenuTrigger === 'both') {
|
||||
EventHandler.on(this._menu, 'mouseenter', SELECTOR_SUBMENU_TOGGLE, event => {
|
||||
this._onSubmenuTriggerEnter(event);
|
||||
});
|
||||
EventHandler.on(this._menu, 'mouseleave', SELECTOR_SUBMENU, event => {
|
||||
this._onSubmenuLeave(event);
|
||||
});
|
||||
|
||||
// Track mouse movement for safe triangle calculation
|
||||
EventHandler.on(this._menu, 'mousemove', event => {
|
||||
this._trackMousePosition(event);
|
||||
});
|
||||
}
|
||||
|
||||
// Set up click listener for submenu triggers
|
||||
if (this._config.submenuTrigger === 'click' || this._config.submenuTrigger === 'both') {
|
||||
EventHandler.on(this._menu, 'click', SELECTOR_SUBMENU_TOGGLE, event => {
|
||||
this._onSubmenuTriggerClick(event);
|
||||
});
|
||||
}
|
||||
}
|
||||
_onSubmenuTriggerEnter(event) {
|
||||
const trigger = event.target.closest(SELECTOR_SUBMENU_TOGGLE);
|
||||
if (!trigger) {
|
||||
return;
|
||||
}
|
||||
const submenuWrapper = trigger.closest(SELECTOR_SUBMENU);
|
||||
const submenu = SelectorEngine.findOne(SELECTOR_MENU, submenuWrapper);
|
||||
if (!submenu) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Cancel any pending close timeout for this submenu
|
||||
this._cancelSubmenuCloseTimeout(submenu);
|
||||
|
||||
// Close other open submenus at the same level
|
||||
this._closeSiblingSubmenus(submenuWrapper);
|
||||
|
||||
// Open this submenu
|
||||
this._openSubmenu(trigger, submenu, submenuWrapper);
|
||||
}
|
||||
_onSubmenuLeave(event) {
|
||||
const submenuWrapper = event.target.closest(SELECTOR_SUBMENU);
|
||||
const submenu = SelectorEngine.findOne(SELECTOR_MENU, submenuWrapper);
|
||||
if (!submenu || !this._openSubmenus.has(submenu)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we're moving toward the submenu (safe triangle)
|
||||
if (this._isMovingTowardSubmenu(event, submenu)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Schedule submenu close with delay
|
||||
this._scheduleSubmenuClose(submenu, submenuWrapper);
|
||||
}
|
||||
_onSubmenuTriggerClick(event) {
|
||||
const trigger = event.target.closest(SELECTOR_SUBMENU_TOGGLE);
|
||||
if (!trigger) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
const submenuWrapper = trigger.closest(SELECTOR_SUBMENU);
|
||||
const submenu = SelectorEngine.findOne(SELECTOR_MENU, submenuWrapper);
|
||||
if (!submenu) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Toggle submenu
|
||||
if (this._openSubmenus.has(submenu)) {
|
||||
this._closeSubmenu(submenu, submenuWrapper);
|
||||
} else {
|
||||
this._closeSiblingSubmenus(submenuWrapper);
|
||||
this._openSubmenu(trigger, submenu, submenuWrapper);
|
||||
}
|
||||
}
|
||||
_openSubmenu(trigger, submenu, submenuWrapper) {
|
||||
if (this._openSubmenus.has(submenu)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set ARIA attributes
|
||||
trigger.setAttribute('aria-expanded', 'true');
|
||||
trigger.setAttribute('aria-haspopup', 'true');
|
||||
|
||||
// Position and show submenu
|
||||
submenu.classList.add(CLASS_NAME_SHOW);
|
||||
submenuWrapper.classList.add(CLASS_NAME_SHOW);
|
||||
|
||||
// Set up Floating UI positioning for submenu
|
||||
const cleanup = this._createSubmenuFloating(trigger, submenu, submenuWrapper);
|
||||
this._openSubmenus.set(submenu, cleanup);
|
||||
|
||||
// Set up mouseenter on submenu to cancel close timeout
|
||||
EventHandler.on(submenu, 'mouseenter', () => {
|
||||
this._cancelSubmenuCloseTimeout(submenu);
|
||||
});
|
||||
}
|
||||
_closeSubmenu(submenu, submenuWrapper) {
|
||||
if (!this._openSubmenus.has(submenu)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Close any nested submenus first
|
||||
const nestedSubmenus = SelectorEngine.find(`${SELECTOR_SUBMENU} ${SELECTOR_MENU}.${CLASS_NAME_SHOW}`, submenu);
|
||||
for (const nested of nestedSubmenus) {
|
||||
const nestedWrapper = nested.closest(SELECTOR_SUBMENU);
|
||||
this._closeSubmenu(nested, nestedWrapper);
|
||||
}
|
||||
|
||||
// Get the trigger
|
||||
const trigger = SelectorEngine.findOne(SELECTOR_SUBMENU_TOGGLE, submenuWrapper);
|
||||
|
||||
// Clean up Floating UI
|
||||
const cleanup = this._openSubmenus.get(submenu);
|
||||
if (cleanup) {
|
||||
cleanup();
|
||||
}
|
||||
this._openSubmenus.delete(submenu);
|
||||
|
||||
// Remove event listeners
|
||||
EventHandler.off(submenu, 'mouseenter');
|
||||
|
||||
// Update ARIA and visibility
|
||||
if (trigger) {
|
||||
trigger.setAttribute('aria-expanded', 'false');
|
||||
}
|
||||
submenu.classList.remove(CLASS_NAME_SHOW);
|
||||
submenuWrapper.classList.remove(CLASS_NAME_SHOW);
|
||||
|
||||
// Clear inline styles
|
||||
submenu.style.position = '';
|
||||
submenu.style.left = '';
|
||||
submenu.style.top = '';
|
||||
submenu.style.margin = '';
|
||||
}
|
||||
_closeAllSubmenus() {
|
||||
for (const [submenu] of this._openSubmenus) {
|
||||
const submenuWrapper = submenu.closest(SELECTOR_SUBMENU);
|
||||
this._closeSubmenu(submenu, submenuWrapper);
|
||||
}
|
||||
}
|
||||
_closeSiblingSubmenus(currentSubmenuWrapper) {
|
||||
// Find all sibling submenu wrappers and close their menus
|
||||
const parent = currentSubmenuWrapper.parentNode;
|
||||
const siblingSubmenus = SelectorEngine.find(`${SELECTOR_SUBMENU} > ${SELECTOR_MENU}.${CLASS_NAME_SHOW}`, parent);
|
||||
for (const siblingMenu of siblingSubmenus) {
|
||||
const siblingWrapper = siblingMenu.closest(SELECTOR_SUBMENU);
|
||||
if (siblingWrapper !== currentSubmenuWrapper) {
|
||||
this._closeSubmenu(siblingMenu, siblingWrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
_createSubmenuFloating(trigger, submenu, submenuWrapper) {
|
||||
const referenceElement = submenuWrapper;
|
||||
const placement = resolveLogicalPlacement(SUBMENU_PLACEMENT);
|
||||
const middleware = [dom.offset({
|
||||
mainAxis: 0,
|
||||
crossAxis: -4
|
||||
}), dom.flip({
|
||||
fallbackPlacements: [resolveLogicalPlacement('start-start'), resolveLogicalPlacement('end-end'), resolveLogicalPlacement('start-end')]
|
||||
}), dom.shift({
|
||||
padding: 8
|
||||
})];
|
||||
const updatePosition = () => this._applyFloatingPosition(referenceElement, submenu, placement, middleware);
|
||||
updatePosition();
|
||||
return dom.autoUpdate(referenceElement, submenu, updatePosition);
|
||||
}
|
||||
_scheduleSubmenuClose(submenu, submenuWrapper) {
|
||||
this._cancelSubmenuCloseTimeout(submenu);
|
||||
const timeoutId = setTimeout(() => {
|
||||
this._closeSubmenu(submenu, submenuWrapper);
|
||||
this._submenuCloseTimeouts.delete(submenu);
|
||||
}, this._config.submenuDelay);
|
||||
this._submenuCloseTimeouts.set(submenu, timeoutId);
|
||||
}
|
||||
_cancelSubmenuCloseTimeout(submenu) {
|
||||
const timeoutId = this._submenuCloseTimeouts.get(submenu);
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
this._submenuCloseTimeouts.delete(submenu);
|
||||
}
|
||||
}
|
||||
_clearAllSubmenuTimeouts() {
|
||||
for (const timeoutId of this._submenuCloseTimeouts.values()) {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
this._submenuCloseTimeouts.clear();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Hover intent / Safe triangle
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
_trackMousePosition(event) {
|
||||
this._hoverIntentData = {
|
||||
x: event.clientX,
|
||||
y: event.clientY,
|
||||
timestamp: Date.now()
|
||||
};
|
||||
}
|
||||
_isMovingTowardSubmenu(event, submenu) {
|
||||
if (!this._hoverIntentData) {
|
||||
return false;
|
||||
}
|
||||
const submenuRect = submenu.getBoundingClientRect();
|
||||
const currentPos = {
|
||||
x: event.clientX,
|
||||
y: event.clientY
|
||||
};
|
||||
const lastPos = {
|
||||
x: this._hoverIntentData.x,
|
||||
y: this._hoverIntentData.y
|
||||
};
|
||||
|
||||
// Create a triangle from current position to submenu edges
|
||||
// The triangle represents the "safe zone" for diagonal movement
|
||||
const isRtl = index_js.isRTL();
|
||||
|
||||
// Determine which edge of the submenu to target based on direction
|
||||
const targetX = isRtl ? submenuRect.right : submenuRect.left;
|
||||
const topCorner = {
|
||||
x: targetX,
|
||||
y: submenuRect.top
|
||||
};
|
||||
const bottomCorner = {
|
||||
x: targetX,
|
||||
y: submenuRect.bottom
|
||||
};
|
||||
|
||||
// Check if cursor is moving toward the submenu
|
||||
// by checking if the current position is within the safe triangle
|
||||
return this._pointInTriangle(currentPos, lastPos, topCorner, bottomCorner);
|
||||
}
|
||||
_pointInTriangle(point, v1, v2, v3) {
|
||||
// Barycentric coordinate method to check if point is inside triangle
|
||||
const d1 = triangleSign(point, v1, v2);
|
||||
const d2 = triangleSign(point, v2, v3);
|
||||
const d3 = triangleSign(point, v3, v1);
|
||||
const hasNeg = d1 < 0 || d2 < 0 || d3 < 0;
|
||||
const hasPos = d1 > 0 || d2 > 0 || d3 > 0;
|
||||
return !(hasNeg && hasPos);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Keyboard navigation
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
_selectMenuItem({
|
||||
key,
|
||||
target
|
||||
}) {
|
||||
// Get items only from the current menu level (not nested submenus)
|
||||
// If target is inside a menu, use that menu; otherwise use the main menu
|
||||
const currentMenu = target.closest(SELECTOR_MENU) || this._menu;
|
||||
const items = SelectorEngine.find(`:scope > li > ${SELECTOR_VISIBLE_ITEMS}, :scope > ${SELECTOR_VISIBLE_ITEMS}`, currentMenu).filter(element => index_js.isVisible(element));
|
||||
const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => index_js.isVisible(element));
|
||||
if (!items.length) {
|
||||
return;
|
||||
}
|
||||
@@ -671,88 +304,19 @@
|
||||
// allow cycling to get the last item in case key equals ARROW_UP_KEY
|
||||
index_js.getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus();
|
||||
}
|
||||
_handleSubmenuKeydown(event) {
|
||||
const {
|
||||
key,
|
||||
target
|
||||
} = event;
|
||||
const isRtl = index_js.isRTL();
|
||||
|
||||
// Determine the "enter submenu" and "exit submenu" keys based on RTL
|
||||
const enterKey = isRtl ? ARROW_LEFT_KEY : ARROW_RIGHT_KEY;
|
||||
const exitKey = isRtl ? ARROW_RIGHT_KEY : ARROW_LEFT_KEY;
|
||||
|
||||
// Check if target is a submenu trigger
|
||||
const submenuWrapper = target.closest(SELECTOR_SUBMENU);
|
||||
const isSubmenuTrigger = submenuWrapper && target.matches(SELECTOR_SUBMENU_TOGGLE);
|
||||
|
||||
// Handle Enter/Space on submenu trigger
|
||||
if ((key === ENTER_KEY || key === SPACE_KEY) && isSubmenuTrigger) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
const submenu = SelectorEngine.findOne(SELECTOR_MENU, submenuWrapper);
|
||||
if (submenu) {
|
||||
this._closeSiblingSubmenus(submenuWrapper);
|
||||
this._openSubmenu(target, submenu, submenuWrapper);
|
||||
// Focus first item in submenu
|
||||
requestAnimationFrame(() => {
|
||||
const firstItem = SelectorEngine.findOne(SELECTOR_VISIBLE_ITEMS, submenu);
|
||||
if (firstItem) {
|
||||
firstItem.focus();
|
||||
}
|
||||
});
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Dropdown.getOrCreateInstance(this, config);
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle Right arrow (or Left in RTL) - enter submenu
|
||||
if (key === enterKey && isSubmenuTrigger) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
const submenu = SelectorEngine.findOne(SELECTOR_MENU, submenuWrapper);
|
||||
if (submenu) {
|
||||
this._closeSiblingSubmenus(submenuWrapper);
|
||||
this._openSubmenu(target, submenu, submenuWrapper);
|
||||
// Focus first item in submenu
|
||||
requestAnimationFrame(() => {
|
||||
const firstItem = SelectorEngine.findOne(SELECTOR_VISIBLE_ITEMS, submenu);
|
||||
if (firstItem) {
|
||||
firstItem.focus();
|
||||
}
|
||||
});
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle Left arrow (or Right in RTL) - exit submenu
|
||||
if (key === exitKey) {
|
||||
const currentMenu = target.closest(SELECTOR_MENU);
|
||||
const parentSubmenuWrapper = currentMenu?.closest(SELECTOR_SUBMENU);
|
||||
if (parentSubmenuWrapper) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
const parentTrigger = SelectorEngine.findOne(SELECTOR_SUBMENU_TOGGLE, parentSubmenuWrapper);
|
||||
this._closeSubmenu(currentMenu, parentSubmenuWrapper);
|
||||
if (parentTrigger) {
|
||||
parentTrigger.focus();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Home/End keys
|
||||
if (key === HOME_KEY || key === END_KEY) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
const currentMenu = target.closest(SELECTOR_MENU);
|
||||
const items = SelectorEngine.find(`:scope > li > ${SELECTOR_VISIBLE_ITEMS}, :scope > ${SELECTOR_VISIBLE_ITEMS}`, currentMenu).filter(element => index_js.isVisible(element));
|
||||
if (items.length) {
|
||||
const targetItem = key === HOME_KEY ? items[0] : items[items.length - 1];
|
||||
targetItem.focus();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
static clearMenus(event) {
|
||||
if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY) {
|
||||
@@ -784,62 +348,32 @@
|
||||
}
|
||||
}
|
||||
static dataApiKeydownHandler(event) {
|
||||
// If not a relevant key => not a dropdown command
|
||||
// If not an UP | DOWN | ESCAPE key => not a dropdown command
|
||||
// If input/textarea && if key is other than ESCAPE => not a dropdown command
|
||||
|
||||
const isInput = /input|textarea/i.test(event.target.tagName);
|
||||
const isEscapeEvent = event.key === ESCAPE_KEY;
|
||||
const isUpOrDownEvent = [ARROW_UP_KEY, ARROW_DOWN_KEY].includes(event.key);
|
||||
const isLeftOrRightEvent = [ARROW_LEFT_KEY, ARROW_RIGHT_KEY].includes(event.key);
|
||||
const isHomeOrEndEvent = [HOME_KEY, END_KEY].includes(event.key);
|
||||
const isEnterOrSpaceEvent = [ENTER_KEY, SPACE_KEY].includes(event.key);
|
||||
|
||||
// Allow Enter/Space only on submenu triggers
|
||||
const isSubmenuTrigger = event.target.matches(SELECTOR_SUBMENU_TOGGLE);
|
||||
if (!isUpOrDownEvent && !isEscapeEvent && !isLeftOrRightEvent && !isHomeOrEndEvent && !(isEnterOrSpaceEvent && isSubmenuTrigger)) {
|
||||
if (!isUpOrDownEvent && !isEscapeEvent) {
|
||||
return;
|
||||
}
|
||||
if (isInput && !isEscapeEvent) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
|
||||
// TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/
|
||||
const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0] || SelectorEngine.next(this, SELECTOR_DATA_TOGGLE)[0] || SelectorEngine.findOne(SELECTOR_DATA_TOGGLE, event.delegateTarget.parentNode);
|
||||
if (!getToggleButton) {
|
||||
return;
|
||||
}
|
||||
const instance = Dropdown.getOrCreateInstance(getToggleButton);
|
||||
|
||||
// Handle submenu navigation first
|
||||
if ((isLeftOrRightEvent || isHomeOrEndEvent || isEnterOrSpaceEvent && isSubmenuTrigger) && instance._handleSubmenuKeydown(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle Up/Down navigation
|
||||
if (isUpOrDownEvent) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
instance.show();
|
||||
instance._selectMenuItem(event);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle Escape
|
||||
if (isEscapeEvent && instance._isShown()) {
|
||||
event.preventDefault();
|
||||
if (instance._isShown()) {
|
||||
// else is escape and we check if it is shown
|
||||
event.stopPropagation();
|
||||
|
||||
// If in a submenu, close just that submenu
|
||||
const currentMenu = event.target.closest(SELECTOR_MENU);
|
||||
const parentSubmenuWrapper = currentMenu?.closest(SELECTOR_SUBMENU);
|
||||
if (parentSubmenuWrapper && instance._openSubmenus.size > 0) {
|
||||
const parentTrigger = SelectorEngine.findOne(SELECTOR_SUBMENU_TOGGLE, parentSubmenuWrapper);
|
||||
instance._closeSubmenu(currentMenu, parentSubmenuWrapper);
|
||||
if (parentTrigger) {
|
||||
parentTrigger.focus();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise close the whole dropdown
|
||||
instance.hide();
|
||||
getToggleButton.focus();
|
||||
}
|
||||
@@ -859,6 +393,12 @@
|
||||
Dropdown.getOrCreateInstance(this).toggle();
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Dropdown);
|
||||
|
||||
return Dropdown;
|
||||
|
||||
}));
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user