├── .babelrc.js ├── .browserslistrc ├── .bundlewatch.config.json ├── .cspell.json ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .gitattributes ├── .github ├── CODEOWNERS ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml ├── PULL_REQUEST_TEMPLATE.md ├── SUPPORT.md ├── codeql │ └── codeql-config.yml ├── dependabot.yml ├── release-drafter.yml └── workflows │ ├── browserstack.yml │ ├── bundlewatch.yml │ ├── calibreapp-image-actions.yml │ ├── codeql.yml │ ├── cspell.yml │ ├── css.yml │ ├── docs.yml │ ├── issue-close-require.yml │ ├── issue-labeled.yml │ ├── js.yml │ ├── lint.yml │ ├── node-sass.yml │ └── release-notes.yml ├── .gitignore ├── .prettierignore ├── .stylelintignore ├── .stylelintrc.json ├── .vscode ├── extensions.json └── settings.json ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SECURITY.md ├── build ├── banner.mjs ├── build-plugins.mjs ├── change-version.mjs ├── docs-prep.sh ├── generate-sri.mjs ├── postcss.config.mjs ├── rollup.config.mjs ├── vnu-jar.mjs └── zip-examples.mjs ├── composer.json ├── config.yml ├── dist ├── css │ ├── bootstrap-grid.css │ ├── 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.rtl.css │ ├── bootstrap.rtl.css.map │ ├── bootstrap.rtl.min.css │ └── bootstrap.rtl.min.css.map └── js │ ├── bootstrap.bundle.js │ ├── bootstrap.bundle.js.map │ ├── bootstrap.bundle.min.js │ ├── bootstrap.bundle.min.js.map │ ├── bootstrap.esm.js │ ├── bootstrap.esm.js.map │ ├── bootstrap.esm.min.js │ ├── bootstrap.esm.min.js.map │ ├── bootstrap.js │ ├── bootstrap.js.map │ ├── bootstrap.min.js │ └── bootstrap.min.js.map ├── js ├── dist │ ├── alert.js │ ├── alert.js.map │ ├── base-component.js │ ├── base-component.js.map │ ├── button.js │ ├── button.js.map │ ├── carousel.js │ ├── carousel.js.map │ ├── collapse.js │ ├── collapse.js.map │ ├── dom │ │ ├── data.js │ │ ├── data.js.map │ │ ├── event-handler.js │ │ ├── event-handler.js.map │ │ ├── manipulator.js │ │ ├── manipulator.js.map │ │ ├── selector-engine.js │ │ └── selector-engine.js.map │ ├── dropdown.js │ ├── dropdown.js.map │ ├── modal.js │ ├── modal.js.map │ ├── offcanvas.js │ ├── offcanvas.js.map │ ├── popover.js │ ├── popover.js.map │ ├── scrollspy.js │ ├── scrollspy.js.map │ ├── tab.js │ ├── tab.js.map │ ├── toast.js │ ├── toast.js.map │ ├── tooltip.js │ ├── tooltip.js.map │ └── util │ │ ├── backdrop.js │ │ ├── backdrop.js.map │ │ ├── component-functions.js │ │ ├── component-functions.js.map │ │ ├── config.js │ │ ├── config.js.map │ │ ├── focustrap.js │ │ ├── focustrap.js.map │ │ ├── index.js │ │ ├── index.js.map │ │ ├── sanitizer.js │ │ ├── sanitizer.js.map │ │ ├── scrollbar.js │ │ ├── scrollbar.js.map │ │ ├── swipe.js │ │ ├── swipe.js.map │ │ ├── template-factory.js │ │ └── template-factory.js.map ├── index.esm.js ├── index.umd.js ├── src │ ├── alert.js │ ├── base-component.js │ ├── button.js │ ├── carousel.js │ ├── collapse.js │ ├── dom │ │ ├── data.js │ │ ├── event-handler.js │ │ ├── manipulator.js │ │ └── selector-engine.js │ ├── dropdown.js │ ├── modal.js │ ├── offcanvas.js │ ├── popover.js │ ├── scrollspy.js │ ├── tab.js │ ├── toast.js │ ├── tooltip.js │ └── util │ │ ├── backdrop.js │ │ ├── component-functions.js │ │ ├── config.js │ │ ├── focustrap.js │ │ ├── index.js │ │ ├── sanitizer.js │ │ ├── scrollbar.js │ │ ├── swipe.js │ │ └── template-factory.js └── tests │ ├── README.md │ ├── browsers.js │ ├── helpers │ └── fixture.js │ ├── integration │ ├── bundle-modularity.js │ ├── bundle.js │ ├── index.html │ ├── rollup.bundle-modularity.js │ └── rollup.bundle.js │ ├── karma.conf.js │ ├── unit │ ├── alert.spec.js │ ├── base-component.spec.js │ ├── button.spec.js │ ├── carousel.spec.js │ ├── collapse.spec.js │ ├── dom │ │ ├── data.spec.js │ │ ├── event-handler.spec.js │ │ ├── manipulator.spec.js │ │ └── selector-engine.spec.js │ ├── dropdown.spec.js │ ├── jquery.spec.js │ ├── modal.spec.js │ ├── offcanvas.spec.js │ ├── popover.spec.js │ ├── scrollspy.spec.js │ ├── tab.spec.js │ ├── toast.spec.js │ ├── tooltip.spec.js │ └── util │ │ ├── backdrop.spec.js │ │ ├── component-functions.spec.js │ │ ├── config.spec.js │ │ ├── focustrap.spec.js │ │ ├── index.spec.js │ │ ├── sanitizer.spec.js │ │ ├── scrollbar.spec.js │ │ ├── swipe.spec.js │ │ └── template-factory.spec.js │ └── visual │ ├── alert.html │ ├── button.html │ ├── carousel.html │ ├── collapse.html │ ├── dropdown.html │ ├── floating-label.html │ ├── input.html │ ├── modal.html │ ├── popover.html │ ├── scrollspy.html │ ├── tab.html │ ├── toast.html │ └── tooltip.html ├── nuget ├── MyGet.ps1 ├── bootstrap.nuspec ├── bootstrap.png └── bootstrap.sass.nuspec ├── package-lock.json ├── package.js ├── package.json ├── scss ├── _accordion.scss ├── _alert.scss ├── _badge.scss ├── _breadcrumb.scss ├── _button-group.scss ├── _buttons.scss ├── _card.scss ├── _carousel.scss ├── _close.scss ├── _containers.scss ├── _dropdown.scss ├── _forms.scss ├── _functions.scss ├── _grid.scss ├── _helpers.scss ├── _images.scss ├── _list-group.scss ├── _maps.scss ├── _mixins.scss ├── _modal.scss ├── _nav.scss ├── _navbar.scss ├── _offcanvas.scss ├── _pagination.scss ├── _placeholders.scss ├── _popover.scss ├── _progress.scss ├── _reboot.scss ├── _root.scss ├── _spinners.scss ├── _tables.scss ├── _toasts.scss ├── _tooltip.scss ├── _transitions.scss ├── _type.scss ├── _utilities.scss ├── _variables-dark.scss ├── _variables.scss ├── bootstrap-grid.scss ├── bootstrap-reboot.scss ├── bootstrap-utilities.scss ├── bootstrap.scss ├── forms │ ├── _floating-labels.scss │ ├── _form-check.scss │ ├── _form-control.scss │ ├── _form-range.scss │ ├── _form-select.scss │ ├── _form-text.scss │ ├── _input-group.scss │ ├── _labels.scss │ └── _validation.scss ├── helpers │ ├── _clearfix.scss │ ├── _color-bg.scss │ ├── _colored-links.scss │ ├── _focus-ring.scss │ ├── _icon-link.scss │ ├── _position.scss │ ├── _ratio.scss │ ├── _stacks.scss │ ├── _stretched-link.scss │ ├── _text-truncation.scss │ ├── _visually-hidden.scss │ └── _vr.scss ├── mixins │ ├── _alert.scss │ ├── _backdrop.scss │ ├── _banner.scss │ ├── _border-radius.scss │ ├── _box-shadow.scss │ ├── _breakpoints.scss │ ├── _buttons.scss │ ├── _caret.scss │ ├── _clearfix.scss │ ├── _color-mode.scss │ ├── _color-scheme.scss │ ├── _container.scss │ ├── _deprecate.scss │ ├── _forms.scss │ ├── _gradients.scss │ ├── _grid.scss │ ├── _image.scss │ ├── _list-group.scss │ ├── _lists.scss │ ├── _pagination.scss │ ├── _reset-text.scss │ ├── _resize.scss │ ├── _table-variants.scss │ ├── _text-truncate.scss │ ├── _transition.scss │ ├── _utilities.scss │ └── _visually-hidden.scss ├── tests │ ├── jasmine.js │ ├── mixins │ │ ├── _auto-import-of-variables-dark.test.scss │ │ ├── _box-shadow.test.scss │ │ ├── _color-modes.test.scss │ │ ├── _media-query-color-mode-full.test.scss │ │ └── _utilities.test.scss │ ├── sass-true │ │ ├── register.js │ │ └── runner.js │ └── utilities │ │ └── _api.test.scss ├── utilities │ └── _api.scss └── vendor │ └── _rfs.scss └── site ├── .prettierrc.json ├── astro.config.ts ├── data ├── breakpoints.yml ├── colors.yml ├── core-team.yml ├── docs-versions.yml ├── examples.yml ├── grays.yml ├── icons.yml ├── plugins.yml ├── sidebar.yml ├── theme-colors.yml └── translations.yml ├── postcss.config.cjs ├── src ├── assets │ ├── application.js │ ├── examples │ │ ├── album-rtl │ │ │ └── index.astro │ │ ├── album │ │ │ └── index.astro │ │ ├── badges │ │ │ ├── badges.css │ │ │ └── index.astro │ │ ├── blog-rtl │ │ │ └── index.astro │ │ ├── blog │ │ │ ├── blog.css │ │ │ ├── blog.rtl.css │ │ │ └── index.astro │ │ ├── breadcrumbs │ │ │ ├── breadcrumbs.css │ │ │ └── index.astro │ │ ├── buttons │ │ │ └── index.astro │ │ ├── carousel-rtl │ │ │ └── index.astro │ │ ├── carousel │ │ │ ├── carousel.css │ │ │ ├── carousel.rtl.css │ │ │ └── index.astro │ │ ├── cheatsheet-rtl │ │ │ └── index.astro │ │ ├── cheatsheet │ │ │ ├── cheatsheet.css │ │ │ ├── cheatsheet.js │ │ │ ├── cheatsheet.rtl.css │ │ │ └── index.astro │ │ ├── checkout-rtl │ │ │ └── index.astro │ │ ├── checkout │ │ │ ├── checkout.css │ │ │ ├── checkout.js │ │ │ └── index.astro │ │ ├── cover │ │ │ ├── cover.css │ │ │ └── index.astro │ │ ├── dashboard-rtl │ │ │ ├── dashboard.js │ │ │ └── index.astro │ │ ├── dashboard │ │ │ ├── dashboard.css │ │ │ ├── dashboard.js │ │ │ ├── dashboard.rtl.css │ │ │ └── index.astro │ │ ├── dropdowns │ │ │ ├── dropdowns.css │ │ │ └── index.astro │ │ ├── features │ │ │ ├── features.css │ │ │ ├── index.astro │ │ │ ├── unsplash-photo-1.jpg │ │ │ ├── unsplash-photo-2.jpg │ │ │ └── unsplash-photo-3.jpg │ │ ├── footers │ │ │ └── index.astro │ │ ├── grid │ │ │ ├── grid.css │ │ │ └── index.astro │ │ ├── headers │ │ │ ├── headers.css │ │ │ └── index.astro │ │ ├── heroes │ │ │ ├── bootstrap-docs.png │ │ │ ├── bootstrap-themes.png │ │ │ ├── heroes.css │ │ │ └── index.astro │ │ ├── jumbotron │ │ │ └── index.astro │ │ ├── jumbotrons │ │ │ ├── index.astro │ │ │ └── jumbotrons.css │ │ ├── list-groups │ │ │ ├── index.astro │ │ │ └── list-groups.css │ │ ├── masonry │ │ │ └── index.astro │ │ ├── modals │ │ │ ├── index.astro │ │ │ └── modals.css │ │ ├── navbar-bottom │ │ │ └── index.astro │ │ ├── navbar-fixed │ │ │ ├── index.astro │ │ │ └── navbar-fixed.css │ │ ├── navbar-static │ │ │ ├── index.astro │ │ │ └── navbar-static.css │ │ ├── navbars-offcanvas │ │ │ ├── index.astro │ │ │ └── navbars-offcanvas.css │ │ ├── navbars │ │ │ ├── index.astro │ │ │ └── navbars.css │ │ ├── offcanvas-navbar │ │ │ ├── index.astro │ │ │ ├── offcanvas-navbar.css │ │ │ └── offcanvas-navbar.js │ │ ├── pricing │ │ │ ├── index.astro │ │ │ └── pricing.css │ │ ├── product │ │ │ ├── index.astro │ │ │ └── product.css │ │ ├── sidebars │ │ │ ├── index.astro │ │ │ ├── sidebars.css │ │ │ └── sidebars.js │ │ ├── sign-in │ │ │ ├── index.astro │ │ │ └── sign-in.css │ │ ├── starter-template │ │ │ └── index.astro │ │ ├── sticky-footer-navbar │ │ │ ├── index.astro │ │ │ └── sticky-footer-navbar.css │ │ └── sticky-footer │ │ │ ├── index.astro │ │ │ └── sticky-footer.css │ ├── partials │ │ ├── sidebar.js │ │ └── snippets.js │ ├── search.js │ ├── snippets.js │ └── stackblitz.js ├── components │ ├── Ads.astro │ ├── DocsScripts.astro │ ├── DocsSidebar.astro │ ├── Scripts.astro │ ├── TableOfContents.astro │ ├── footer │ │ └── Footer.astro │ ├── head │ │ ├── Analytics.astro │ │ ├── Favicons.astro │ │ ├── Head.astro │ │ ├── Scss.astro │ │ ├── Social.astro │ │ └── Stylesheet.astro │ ├── header │ │ ├── Header.astro │ │ ├── LinkItem.astro │ │ ├── Navigation.astro │ │ ├── Skippy.astro │ │ └── Versions.astro │ ├── home │ │ ├── CSSVariables.astro │ │ ├── ComponentUtilities.astro │ │ ├── Customize.astro │ │ ├── GetStarted.astro │ │ ├── Icons.astro │ │ ├── MastHead.astro │ │ ├── Plugins.astro │ │ └── Themes.astro │ ├── icons │ │ ├── BootstrapWhiteFillIcon.astro │ │ ├── CircleSquareIcon.astro │ │ ├── DropletFillIcon.astro │ │ ├── GitHubIcon.astro │ │ ├── HamburgerIcon.astro │ │ ├── OpenCollectiveIcon.astro │ │ ├── Symbols.astro │ │ └── XIcon.astro │ └── shortcodes │ │ ├── AddedIn.astro │ │ ├── BsTable.astro │ │ ├── Callout.astro │ │ ├── CalloutDeprecatedDarkVariants.astro │ │ ├── Code.astro │ │ ├── DeprecatedIn.astro │ │ ├── Example.astro │ │ ├── GuideFooter.mdx │ │ ├── JsDataAttributes.mdx │ │ ├── JsDismiss.astro │ │ ├── JsDocs.astro │ │ ├── Placeholder.astro │ │ ├── ScssDocs.astro │ │ ├── Table.astro │ │ └── TableContent.md ├── content │ ├── callouts │ │ ├── danger-async-methods.md │ │ ├── info-mediaqueries-breakpoints.md │ │ ├── info-npm-starter.md │ │ ├── info-prefersreducedmotion.md │ │ ├── info-sanitizer.md │ │ ├── warning-color-assistive-technologies.md │ │ ├── warning-data-bs-title-vs-title.md │ │ └── warning-input-support.md │ ├── config.ts │ └── docs │ │ ├── about │ │ ├── brand.mdx │ │ ├── license.mdx │ │ ├── overview.mdx │ │ ├── team.mdx │ │ └── translations.mdx │ │ ├── components │ │ ├── accordion.mdx │ │ ├── alerts.mdx │ │ ├── badge.mdx │ │ ├── breadcrumb.mdx │ │ ├── button-group.mdx │ │ ├── buttons.mdx │ │ ├── card.mdx │ │ ├── carousel.mdx │ │ ├── close-button.mdx │ │ ├── collapse.mdx │ │ ├── dropdowns.mdx │ │ ├── list-group.mdx │ │ ├── modal.mdx │ │ ├── navbar.mdx │ │ ├── navs-tabs.mdx │ │ ├── offcanvas.mdx │ │ ├── pagination.mdx │ │ ├── placeholders.mdx │ │ ├── popovers.mdx │ │ ├── progress.mdx │ │ ├── scrollspy.mdx │ │ ├── spinners.mdx │ │ ├── toasts.mdx │ │ └── tooltips.mdx │ │ ├── content │ │ ├── figures.mdx │ │ ├── images.mdx │ │ ├── reboot.mdx │ │ ├── tables.mdx │ │ └── typography.mdx │ │ ├── customize │ │ ├── color-modes.mdx │ │ ├── color.mdx │ │ ├── components.mdx │ │ ├── css-variables.mdx │ │ ├── optimize.mdx │ │ ├── options.mdx │ │ ├── overview.mdx │ │ └── sass.mdx │ │ ├── docsref.mdx │ │ ├── extend │ │ ├── approach.mdx │ │ └── icons.mdx │ │ ├── forms │ │ ├── checks-radios.mdx │ │ ├── floating-labels.mdx │ │ ├── form-control.mdx │ │ ├── input-group.mdx │ │ ├── layout.mdx │ │ ├── overview.mdx │ │ ├── range.mdx │ │ ├── select.mdx │ │ └── validation.mdx │ │ ├── getting-started │ │ ├── accessibility.mdx │ │ ├── best-practices.mdx │ │ ├── browsers-devices.mdx │ │ ├── contents.mdx │ │ ├── contribute.mdx │ │ ├── download.mdx │ │ ├── introduction.mdx │ │ ├── javascript.mdx │ │ ├── parcel.mdx │ │ ├── rfs.mdx │ │ ├── rtl.mdx │ │ ├── vite.mdx │ │ └── webpack.mdx │ │ ├── helpers │ │ ├── clearfix.mdx │ │ ├── color-background.mdx │ │ ├── colored-links.mdx │ │ ├── focus-ring.mdx │ │ ├── icon-link.mdx │ │ ├── position.mdx │ │ ├── ratio.mdx │ │ ├── stacks.mdx │ │ ├── stretched-link.mdx │ │ ├── text-truncation.mdx │ │ ├── vertical-rule.mdx │ │ └── visually-hidden.mdx │ │ ├── layout │ │ ├── breakpoints.mdx │ │ ├── columns.mdx │ │ ├── containers.mdx │ │ ├── css-grid.mdx │ │ ├── grid.mdx │ │ ├── gutters.mdx │ │ ├── utilities.mdx │ │ └── z-index.mdx │ │ ├── migration.mdx │ │ └── utilities │ │ ├── api.mdx │ │ ├── background.mdx │ │ ├── borders.mdx │ │ ├── colors.mdx │ │ ├── display.mdx │ │ ├── flex.mdx │ │ ├── float.mdx │ │ ├── interactions.mdx │ │ ├── link.mdx │ │ ├── object-fit.mdx │ │ ├── opacity.mdx │ │ ├── overflow.mdx │ │ ├── position.mdx │ │ ├── shadows.mdx │ │ ├── sizing.mdx │ │ ├── spacing.mdx │ │ ├── text.mdx │ │ ├── vertical-align.mdx │ │ ├── visibility.mdx │ │ └── z-index.mdx ├── env.d.ts ├── layouts │ ├── BaseLayout.astro │ ├── DocsLayout.astro │ ├── ExamplesLayout.astro │ ├── RedirectLayout.astro │ ├── SingleLayout.astro │ └── partials │ │ ├── BsThemes.astro │ │ ├── ExamplesMain.astro │ │ ├── Icons.astro │ │ ├── ResponsiveImage.astro │ │ └── ThemeToggler.astro ├── libs │ ├── astro.ts │ ├── bootstrap.ts │ ├── config.ts │ ├── content.ts │ ├── data.ts │ ├── examples.ts │ ├── icon.ts │ ├── image.ts │ ├── layout.ts │ ├── path.ts │ ├── placeholder.ts │ ├── prism.ts │ ├── rehype.ts │ ├── remark.ts │ ├── toc.ts │ ├── utils.ts │ └── validation.ts ├── pages │ ├── 404.astro │ ├── [...alias].astro │ ├── docs │ │ ├── [version] │ │ │ ├── [...slug].astro │ │ │ ├── examples │ │ │ │ ├── [...asset].ts │ │ │ │ ├── [...example].astro │ │ │ │ └── index.astro │ │ │ └── index.astro │ │ ├── index.astro │ │ └── versions.astro │ ├── examples.astro │ ├── index.astro │ └── robots.txt.ts ├── plugins │ ├── algolia-plugin.js │ └── stackblitz-plugin.js ├── scss │ ├── _ads.scss │ ├── _anchor.scss │ ├── _brand.scss │ ├── _buttons.scss │ ├── _callouts.scss │ ├── _clipboard-js.scss │ ├── _colors.scss │ ├── _component-examples.scss │ ├── _content.scss │ ├── _footer.scss │ ├── _layout.scss │ ├── _masthead.scss │ ├── _navbar.scss │ ├── _placeholder-img.scss │ ├── _scrolling.scss │ ├── _search.scss │ ├── _sidebar.scss │ ├── _skippy.scss │ ├── _syntax.scss │ ├── _toc.scss │ ├── _variables.scss │ ├── docs.scss │ └── docs_search.scss └── types │ ├── auto-import.d.ts │ └── window.d.ts ├── static ├── CNAME ├── docs │ └── [version] │ │ └── assets │ │ ├── brand │ │ ├── bootstrap-logo-black.svg │ │ ├── bootstrap-logo-shadow.png │ │ ├── bootstrap-logo-shadow@2x.png │ │ ├── bootstrap-logo-white.svg │ │ ├── bootstrap-logo.svg │ │ └── bootstrap-social.png │ │ ├── img │ │ ├── bootstrap-icons.png │ │ ├── bootstrap-icons@2x.png │ │ ├── bootstrap-intellisense-autocomplete.png │ │ ├── bootstrap-themes-collage.png │ │ ├── bootstrap-themes-collage@2x.png │ │ ├── bootstrap-themes.png │ │ ├── bootstrap-themes@2x.png │ │ ├── examples │ │ │ ├── album-rtl.png │ │ │ ├── album-rtl@2x.png │ │ │ ├── album.png │ │ │ ├── album@2x.png │ │ │ ├── badges.png │ │ │ ├── badges@2x.png │ │ │ ├── blog-rtl.png │ │ │ ├── blog-rtl@2x.png │ │ │ ├── blog.png │ │ │ ├── blog@2x.png │ │ │ ├── breadcrumbs.png │ │ │ ├── breadcrumbs@2x.png │ │ │ ├── buttons.png │ │ │ ├── buttons@2x.png │ │ │ ├── carousel-rtl.png │ │ │ ├── carousel-rtl@2x.png │ │ │ ├── carousel.png │ │ │ ├── carousel@2x.png │ │ │ ├── cheatsheet-rtl.png │ │ │ ├── cheatsheet-rtl@2x.png │ │ │ ├── cheatsheet.png │ │ │ ├── cheatsheet@2x.png │ │ │ ├── checkout-rtl.png │ │ │ ├── checkout-rtl@2x.png │ │ │ ├── checkout.png │ │ │ ├── checkout@2x.png │ │ │ ├── cover.png │ │ │ ├── cover@2x.png │ │ │ ├── dashboard-rtl.png │ │ │ ├── dashboard-rtl@2x.png │ │ │ ├── dashboard.png │ │ │ ├── dashboard@2x.png │ │ │ ├── dropdowns.png │ │ │ ├── dropdowns@2x.png │ │ │ ├── features.png │ │ │ ├── features@2x.png │ │ │ ├── footers.png │ │ │ ├── footers@2x.png │ │ │ ├── grid.png │ │ │ ├── grid@2x.png │ │ │ ├── headers.png │ │ │ ├── headers@2x.png │ │ │ ├── heroes.png │ │ │ ├── heroes@2x.png │ │ │ ├── jumbotron.png │ │ │ ├── jumbotron@2x.png │ │ │ ├── jumbotrons.png │ │ │ ├── jumbotrons@2x.png │ │ │ ├── list-groups.png │ │ │ ├── list-groups@2x.png │ │ │ ├── masonry.png │ │ │ ├── masonry@2x.png │ │ │ ├── modals.png │ │ │ ├── modals@2x.png │ │ │ ├── navbar-bottom.png │ │ │ ├── navbar-bottom@2x.png │ │ │ ├── navbar-fixed.png │ │ │ ├── navbar-fixed@2x.png │ │ │ ├── navbar-static.png │ │ │ ├── navbar-static@2x.png │ │ │ ├── navbars-offcanvas.png │ │ │ ├── navbars-offcanvas@2x.png │ │ │ ├── navbars.png │ │ │ ├── navbars@2x.png │ │ │ ├── offcanvas-navbar.png │ │ │ ├── offcanvas-navbar@2x.png │ │ │ ├── pricing.png │ │ │ ├── pricing@2x.png │ │ │ ├── product.png │ │ │ ├── product@2x.png │ │ │ ├── sidebars.png │ │ │ ├── sidebars@2x.png │ │ │ ├── sign-in.png │ │ │ ├── sign-in@2x.png │ │ │ ├── starter-template.png │ │ │ ├── starter-template@2x.png │ │ │ ├── sticky-footer-navbar.png │ │ │ ├── sticky-footer-navbar@2x.png │ │ │ ├── sticky-footer.png │ │ │ └── sticky-footer@2x.png │ │ ├── favicons │ │ │ ├── android-chrome-192x192.png │ │ │ ├── android-chrome-512x512.png │ │ │ ├── apple-touch-icon.png │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── favicon.ico │ │ │ ├── manifest.json │ │ │ └── safari-pinned-tab.svg │ │ ├── guides │ │ │ ├── bootstrap-parcel.png │ │ │ ├── bootstrap-parcel@2x.png │ │ │ ├── bootstrap-vite.png │ │ │ ├── bootstrap-vite@2x.png │ │ │ ├── bootstrap-webpack.png │ │ │ ├── bootstrap-webpack@2x.png │ │ │ ├── parcel-dev-server-bootstrap.png │ │ │ ├── parcel-dev-server.png │ │ │ ├── vite-dev-server-bootstrap.png │ │ │ ├── vite-dev-server.png │ │ │ ├── webpack-dev-server-bootstrap.png │ │ │ └── webpack-dev-server.png │ │ ├── parcel.png │ │ ├── vite.svg │ │ └── webpack.svg │ │ └── js │ │ ├── color-modes.js │ │ └── validate-forms.js └── sw.js └── tsconfig.json /.babelrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@babel/preset-env', 5 | { 6 | loose: true, 7 | bugfixes: true, 8 | modules: false 9 | } 10 | ] 11 | ] 12 | }; 13 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | # https://github.com/browserslist/browserslist#readme 2 | 3 | >= 0.5% 4 | last 2 major versions 5 | not dead 6 | Chrome >= 60 7 | Firefox >= 60 8 | Firefox ESR 9 | iOS >= 12 10 | Safari >= 12 11 | not Explorer <= 11 12 | not kaios <= 2.5 # fix floating label issues in Firefox (see https://github.com/postcss/autoprefixer/issues/1533) 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_size = 2 9 | indent_style = space 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/*.min.js 2 | **/dist/ 3 | **/vendor/ 4 | /_site/ 5 | /site/public/ 6 | /js/coverage/ 7 | /site/static/sw.js 8 | /site/static/docs/**/assets/sw.js 9 | /site/layouts/partials/ 10 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Enforce Unix newlines 2 | * text=auto eol=lf 3 | 4 | # Don't diff or textually merge source maps 5 | *.map binary 6 | 7 | bootstrap.css linguist-vendored=false 8 | bootstrap.js linguist-vendored=false 9 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | *.js @twbs/js-review 2 | *.css @twbs/css-review 3 | *.scss @twbs/css-review 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: Ask the community 3 | url: https://github.com/twbs/bootstrap/discussions/new 4 | about: Ask and discuss questions with other Bootstrap community members. 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest new or updated features to include in Bootstrap. 3 | title: "Suggest a new feature" 4 | labels: [feature] 5 | assignees: [] 6 | body: 7 | - type: checkboxes 8 | attributes: 9 | label: Prerequisites 10 | description: Take a couple minutes to help our maintainers work faster. 11 | options: 12 | - label: I have [searched](https://github.com/twbs/bootstrap/issues?utf8=%E2%9C%93&q=is%3Aissue) for duplicate or closed feature requests 13 | required: true 14 | - label: I have read the [contributing guidelines](https://github.com/twbs/bootstrap/blob/main/.github/CONTRIBUTING.md) 15 | required: true 16 | - type: textarea 17 | id: proposal 18 | attributes: 19 | label: Proposal 20 | description: Provide detailed information for what we should add, including relevant links to prior art, screenshots, or live demos whenever possible. 21 | validations: 22 | required: true 23 | - type: textarea 24 | id: motivation 25 | attributes: 26 | label: Motivation and context 27 | description: Tell us why this change is needed or helpful, and what problems it may help solve. 28 | validations: 29 | required: true 30 | -------------------------------------------------------------------------------- /.github/SUPPORT.md: -------------------------------------------------------------------------------- 1 | ### Bug reports 2 | 3 | See the [contributing guidelines](CONTRIBUTING.md) for sharing bug reports. 4 | 5 | ### How-to 6 | 7 | For general troubleshooting or help getting started: 8 | 9 | - Ask and explore [our GitHub Discussions](https://github.com/twbs/bootstrap/discussions). 10 | - Chat with fellow Bootstrappers in IRC. On the `irc.libera.chat` server, in the `#bootstrap` channel. 11 | - Ask and explore Stack Overflow with the [`bootstrap-5`](https://stackoverflow.com/questions/tagged/bootstrap-5) tag. 12 | -------------------------------------------------------------------------------- /.github/codeql/codeql-config.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL config" 2 | paths-ignore: 3 | - dist 4 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: weekly 7 | day: tuesday 8 | time: "12:00" 9 | timezone: Europe/Athens 10 | - package-ecosystem: npm 11 | directory: "/" 12 | labels: 13 | - dependencies 14 | - v5 15 | schedule: 16 | interval: weekly 17 | day: tuesday 18 | time: "12:00" 19 | timezone: Europe/Athens 20 | versioning-strategy: increase 21 | rebase-strategy: disabled 22 | groups: 23 | production-dependencies: 24 | dependency-type: "production" 25 | development-dependencies: 26 | dependency-type: "development" 27 | -------------------------------------------------------------------------------- /.github/workflows/browserstack.yml: -------------------------------------------------------------------------------- 1 | name: BrowserStack 2 | 3 | on: 4 | push: 5 | branches: 6 | - "**" 7 | - "!dependabot/**" 8 | workflow_dispatch: 9 | 10 | env: 11 | FORCE_COLOR: 2 12 | NODE: 22 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | browserstack: 19 | runs-on: ubuntu-latest 20 | if: github.repository == 'twbs/bootstrap' 21 | timeout-minutes: 30 22 | 23 | steps: 24 | - name: Clone repository 25 | uses: actions/checkout@v4 26 | with: 27 | persist-credentials: false 28 | 29 | - name: Set up Node.js 30 | uses: actions/setup-node@v4 31 | with: 32 | node-version: "${{ env.NODE }}" 33 | cache: npm 34 | 35 | - name: Install npm dependencies 36 | run: npm ci 37 | 38 | - name: Run dist 39 | run: npm run dist 40 | 41 | - name: Run BrowserStack tests 42 | run: npm run js-test-cloud 43 | env: 44 | BROWSER_STACK_ACCESS_KEY: "${{ secrets.BROWSER_STACK_ACCESS_KEY }}" 45 | BROWSER_STACK_USERNAME: "${{ secrets.BROWSER_STACK_USERNAME }}" 46 | GITHUB_SHA: "${{ github.sha }}" 47 | -------------------------------------------------------------------------------- /.github/workflows/bundlewatch.yml: -------------------------------------------------------------------------------- 1 | name: Bundlewatch 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | workflow_dispatch: 9 | 10 | env: 11 | FORCE_COLOR: 2 12 | NODE: 22 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | bundlewatch: 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | - name: Clone repository 23 | uses: actions/checkout@v4 24 | with: 25 | persist-credentials: false 26 | 27 | - name: Set up Node.js 28 | uses: actions/setup-node@v4 29 | with: 30 | node-version: "${{ env.NODE }}" 31 | cache: npm 32 | 33 | - name: Install npm dependencies 34 | run: npm ci 35 | 36 | - name: Run dist 37 | run: npm run dist 38 | 39 | - name: Run bundlewatch 40 | run: npm run bundlewatch 41 | env: 42 | BUNDLEWATCH_GITHUB_TOKEN: "${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }}" 43 | CI_BRANCH_BASE: main 44 | -------------------------------------------------------------------------------- /.github/workflows/calibreapp-image-actions.yml: -------------------------------------------------------------------------------- 1 | name: Compress Images 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - '**.jpg' 7 | - '**.jpeg' 8 | - '**.png' 9 | - '**.webp' 10 | 11 | permissions: 12 | contents: read 13 | 14 | jobs: 15 | build: 16 | # Only run on Pull Requests within the same repository, and not from forks. 17 | if: github.event.pull_request.head.repo.full_name == github.repository 18 | name: calibreapp/image-actions 19 | runs-on: ubuntu-latest 20 | permissions: 21 | # allow calibreapp/image-actions to update PRs 22 | pull-requests: write 23 | steps: 24 | - name: Clone repository 25 | uses: actions/checkout@v4 26 | with: 27 | persist-credentials: false 28 | 29 | - name: Compress Images 30 | uses: calibreapp/image-actions@1.1.0 31 | with: 32 | githubToken: ${{ secrets.GITHUB_TOKEN }} 33 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - v4-dev 8 | - "!dependabot/**" 9 | pull_request: 10 | branches: 11 | - main 12 | - v4-dev 13 | - "!dependabot/**" 14 | schedule: 15 | - cron: "0 2 * * 4" 16 | workflow_dispatch: 17 | 18 | jobs: 19 | analyze: 20 | name: Analyze 21 | runs-on: ubuntu-latest 22 | permissions: 23 | security-events: write 24 | 25 | steps: 26 | - name: Checkout repository 27 | uses: actions/checkout@v4 28 | with: 29 | persist-credentials: false 30 | 31 | - name: Initialize CodeQL 32 | uses: github/codeql-action/init@v3 33 | with: 34 | config-file: ./.github/codeql/codeql-config.yml 35 | languages: "javascript" 36 | queries: +security-and-quality 37 | 38 | - name: Autobuild 39 | uses: github/codeql-action/autobuild@v3 40 | 41 | - name: Perform CodeQL Analysis 42 | uses: github/codeql-action/analyze@v3 43 | with: 44 | category: "/language:javascript" 45 | -------------------------------------------------------------------------------- /.github/workflows/cspell.yml: -------------------------------------------------------------------------------- 1 | name: cspell 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | workflow_dispatch: 9 | 10 | env: 11 | FORCE_COLOR: 2 12 | 13 | permissions: 14 | contents: read 15 | 16 | jobs: 17 | cspell: 18 | permissions: 19 | # allow streetsidesoftware/cspell-action to fetch files for commits and PRs 20 | contents: read 21 | pull-requests: read 22 | runs-on: ubuntu-latest 23 | 24 | steps: 25 | - name: Clone repository 26 | uses: actions/checkout@v4 27 | with: 28 | persist-credentials: false 29 | 30 | - name: Run cspell 31 | uses: streetsidesoftware/cspell-action@v7 32 | with: 33 | config: ".cspell.json" 34 | files: "**/*.{md,mdx}" 35 | inline: error 36 | incremental_files_only: false 37 | -------------------------------------------------------------------------------- /.github/workflows/css.yml: -------------------------------------------------------------------------------- 1 | name: CSS 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | workflow_dispatch: 9 | 10 | env: 11 | FORCE_COLOR: 2 12 | NODE: 22 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | css: 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | - name: Clone repository 23 | uses: actions/checkout@v4 24 | with: 25 | persist-credentials: false 26 | 27 | - name: Set up Node.js 28 | uses: actions/setup-node@v4 29 | with: 30 | node-version: "${{ env.NODE }}" 31 | cache: npm 32 | 33 | - name: Install npm dependencies 34 | run: npm ci 35 | 36 | - name: Build CSS 37 | run: npm run css 38 | 39 | - name: Run CSS tests 40 | run: npm run css-test 41 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Docs 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | workflow_dispatch: 9 | 10 | env: 11 | FORCE_COLOR: 2 12 | NODE: 22 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | docs: 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | - name: Clone repository 23 | uses: actions/checkout@v4 24 | with: 25 | persist-credentials: false 26 | 27 | - name: Set up Node.js 28 | uses: actions/setup-node@v4 29 | with: 30 | node-version: "${{ env.NODE }}" 31 | cache: npm 32 | 33 | - run: java -version 34 | 35 | - name: Install npm dependencies 36 | run: npm ci 37 | 38 | - name: Build docs 39 | run: npm run docs-build 40 | 41 | - name: Validate HTML 42 | run: npm run docs-vnu 43 | 44 | - name: Run linkinator 45 | uses: JustinBeckwith/linkinator-action@v1 46 | with: 47 | paths: _site 48 | recurse: true 49 | verbosity: error 50 | skip: "^(?!http://localhost)" 51 | -------------------------------------------------------------------------------- /.github/workflows/issue-close-require.yml: -------------------------------------------------------------------------------- 1 | name: Close Issue Awaiting Reply 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 * * *" 6 | 7 | permissions: 8 | contents: read 9 | 10 | jobs: 11 | issue-close-require: 12 | permissions: 13 | # allow actions-cool/issues-helper to update issues and PRs 14 | issues: write 15 | pull-requests: write 16 | runs-on: ubuntu-latest 17 | if: github.repository == 'twbs/bootstrap' 18 | steps: 19 | - name: awaiting reply 20 | uses: actions-cool/issues-helper@v3 21 | with: 22 | actions: "close-issues" 23 | labels: "awaiting-reply" 24 | inactive-day: 14 25 | body: | 26 | As the issue was labeled with `awaiting-reply`, but there has been no response in 14 days, this issue will be closed. If you have any questions, you can comment/reply. 27 | -------------------------------------------------------------------------------- /.github/workflows/issue-labeled.yml: -------------------------------------------------------------------------------- 1 | name: Issue Labeled 2 | 3 | on: 4 | issues: 5 | types: [labeled] 6 | 7 | permissions: 8 | contents: read 9 | 10 | jobs: 11 | issue-labeled: 12 | permissions: 13 | # allow actions-cool/issues-helper to update issues and PRs 14 | issues: write 15 | pull-requests: write 16 | if: github.repository == 'twbs/bootstrap' 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: awaiting reply 20 | if: github.event.label.name == 'needs-example' 21 | uses: actions-cool/issues-helper@v3 22 | with: 23 | actions: "create-comment" 24 | token: ${{ secrets.GITHUB_TOKEN }} 25 | body: | 26 | Hello @${{ github.event.issue.user.login }}. Bug reports must include a **live demo** of the issue. Per our [contributing guidelines](https://github.com/twbs/bootstrap/blob/main/.github/CONTRIBUTING.md), please create a reduced test case on [CodePen](https://codepen.io/) or [StackBlitz](https://stackblitz.com/) and report back with your link, Bootstrap version, and specific browser and Operating System details. 27 | -------------------------------------------------------------------------------- /.github/workflows/js.yml: -------------------------------------------------------------------------------- 1 | name: JS Tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | workflow_dispatch: 9 | 10 | env: 11 | FORCE_COLOR: 2 12 | NODE: 22 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | run: 19 | permissions: 20 | # allow coverallsapp/github-action to create new checks issues and fetch code 21 | checks: write 22 | contents: read 23 | name: JS Tests 24 | runs-on: ubuntu-latest 25 | 26 | steps: 27 | - name: Clone repository 28 | uses: actions/checkout@v4 29 | with: 30 | persist-credentials: false 31 | 32 | - name: Set up Node.js 33 | uses: actions/setup-node@v4 34 | with: 35 | node-version: ${{ env.NODE }} 36 | cache: npm 37 | 38 | - name: Install npm dependencies 39 | run: npm ci 40 | 41 | - name: Run dist 42 | run: npm run js 43 | 44 | - name: Run JS tests 45 | run: npm run js-test 46 | 47 | - name: Run Coveralls 48 | uses: coverallsapp/github-action@v2 49 | if: ${{ !github.event.repository.fork }} 50 | with: 51 | github-token: "${{ secrets.GITHUB_TOKEN }}" 52 | path-to-lcov: "./js/coverage/lcov.info" 53 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | workflow_dispatch: 9 | 10 | env: 11 | FORCE_COLOR: 2 12 | NODE: 22 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | lint: 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | - name: Clone repository 23 | uses: actions/checkout@v4 24 | with: 25 | persist-credentials: false 26 | 27 | - name: Set up Node.js 28 | uses: actions/setup-node@v4 29 | with: 30 | node-version: "${{ env.NODE }}" 31 | cache: npm 32 | 33 | - name: Install npm dependencies 34 | run: npm ci 35 | 36 | - name: Lint 37 | run: npm run lint 38 | -------------------------------------------------------------------------------- /.github/workflows/release-notes.yml: -------------------------------------------------------------------------------- 1 | name: Release notes 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | workflow_dispatch: 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | update_release_draft: 14 | permissions: 15 | # allow release-drafter/release-drafter to create GitHub releases and add labels to PRs 16 | contents: write 17 | pull-requests: write 18 | runs-on: ubuntu-latest 19 | if: github.repository == 'twbs/bootstrap' 20 | steps: 21 | - uses: release-drafter/release-drafter@v6 22 | env: 23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore docs files 2 | /_site/ 3 | 4 | # Numerous always-ignore extensions 5 | *.diff 6 | *.err 7 | *.log 8 | *.orig 9 | *.rej 10 | *.swo 11 | *.swp 12 | *.vi 13 | *.zip 14 | *~ 15 | 16 | # OS or Editor folders 17 | ._* 18 | .cache 19 | .DS_Store 20 | .idea 21 | .project 22 | .settings 23 | .tmproj 24 | *.esproj 25 | *.sublime-project 26 | *.sublime-workspace 27 | nbproject 28 | Thumbs.db 29 | # Local Netlify folder 30 | .netlify 31 | 32 | # Komodo 33 | .komodotools 34 | *.komodoproject 35 | 36 | # Folders to ignore 37 | /dist-sass/ 38 | /js/coverage/ 39 | /node_modules/ 40 | 41 | # Site 42 | /site/dist 43 | /site/node_modules 44 | /site/.astro 45 | /site/public 46 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Prettier is only used for the website 2 | 3 | site/.astro 4 | site/dist 5 | site/public 6 | site/src/assets 7 | site/src/scss 8 | site/src/pages/**/*.md 9 | site/src/pages/**/*.mdx 10 | site/src/content/**/*.mdx 11 | site/src/layouts/RedirectLayout.astro 12 | site/static 13 | -------------------------------------------------------------------------------- /.stylelintignore: -------------------------------------------------------------------------------- 1 | **/*.min.css 2 | **/dist/ 3 | **/vendor/ 4 | /_site/ 5 | /site/public/ 6 | /js/coverage/ 7 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "astro-build.astro-vscode", 4 | "dbaeumer.vscode-eslint", 5 | "EditorConfig.EditorConfig", 6 | "hossaini.bootstrap-intellisense", 7 | "streetsidesoftware.code-spell-checker", 8 | "stylelint.vscode-stylelint" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": "explicit", 4 | "source.fixAll.stylelint": "always" 5 | }, 6 | "editor.renderWhitespace": "all", 7 | "scss.validate": false, 8 | "stylelint.enable": true, 9 | "stylelint.validate": ["scss"] 10 | } 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2025 The Bootstrap Authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting Security Issues 2 | 3 | The Bootstrap team and community take security issues in Bootstrap seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions. 4 | 5 | To report a security issue, email [security@getbootstrap.com](mailto:security@getbootstrap.com) and include the word "SECURITY" in the subject line. 6 | 7 | We'll endeavor to respond quickly, and will keep you updated throughout the process. 8 | -------------------------------------------------------------------------------- /build/banner.mjs: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs/promises' 2 | import path from 'node:path' 3 | import { fileURLToPath } from 'node:url' 4 | 5 | const __dirname = path.dirname(fileURLToPath(import.meta.url)) 6 | 7 | const pkgJson = path.join(__dirname, '../package.json') 8 | const pkg = JSON.parse(await fs.readFile(pkgJson, 'utf8')) 9 | 10 | const year = new Date().getFullYear() 11 | 12 | function getBanner(pluginFilename) { 13 | return `/*! 14 | * Bootstrap${pluginFilename ? ` ${pluginFilename}` : ''} v${pkg.version} (${pkg.homepage}) 15 | * Copyright 2011-${year} ${pkg.author} 16 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 17 | */` 18 | } 19 | 20 | export default getBanner 21 | -------------------------------------------------------------------------------- /build/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | const mapConfig = { 2 | inline: false, 3 | annotation: true, 4 | sourcesContent: true 5 | } 6 | 7 | export default context => { 8 | return { 9 | map: context.file.dirname.includes('examples') ? false : mapConfig, 10 | plugins: { 11 | autoprefixer: { 12 | cascade: false 13 | }, 14 | rtlcss: context.env === 'RTL' 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "twbs/bootstrap", 3 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", 4 | "keywords": [ 5 | "css", 6 | "js", 7 | "sass", 8 | "mobile-first", 9 | "responsive", 10 | "front-end", 11 | "framework", 12 | "web" 13 | ], 14 | "homepage": "https://getbootstrap.com/", 15 | "authors": [ 16 | { 17 | "name": "Mark Otto", 18 | "email": "markdotto@gmail.com" 19 | }, 20 | { 21 | "name": "Jacob Thornton", 22 | "email": "jacobthornton@gmail.com" 23 | } 24 | ], 25 | "support": { 26 | "issues": "https://github.com/twbs/bootstrap/issues" 27 | }, 28 | "license": "MIT", 29 | "replace": { 30 | "twitter/bootstrap": "self.version" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /js/index.esm.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap index.esm.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | export { default as Alert } from './src/alert.js' 9 | export { default as Button } from './src/button.js' 10 | export { default as Carousel } from './src/carousel.js' 11 | export { default as Collapse } from './src/collapse.js' 12 | export { default as Dropdown } from './src/dropdown.js' 13 | export { default as Modal } from './src/modal.js' 14 | export { default as Offcanvas } from './src/offcanvas.js' 15 | export { default as Popover } from './src/popover.js' 16 | export { default as ScrollSpy } from './src/scrollspy.js' 17 | export { default as Tab } from './src/tab.js' 18 | export { default as Toast } from './src/toast.js' 19 | export { default as Tooltip } from './src/tooltip.js' 20 | -------------------------------------------------------------------------------- /js/index.umd.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap index.umd.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | import Alert from './src/alert.js' 9 | import Button from './src/button.js' 10 | import Carousel from './src/carousel.js' 11 | import Collapse from './src/collapse.js' 12 | import Dropdown from './src/dropdown.js' 13 | import Modal from './src/modal.js' 14 | import Offcanvas from './src/offcanvas.js' 15 | import Popover from './src/popover.js' 16 | import ScrollSpy from './src/scrollspy.js' 17 | import Tab from './src/tab.js' 18 | import Toast from './src/toast.js' 19 | import Tooltip from './src/tooltip.js' 20 | 21 | export default { 22 | Alert, 23 | Button, 24 | Carousel, 25 | Collapse, 26 | Dropdown, 27 | Modal, 28 | Offcanvas, 29 | Popover, 30 | ScrollSpy, 31 | Tab, 32 | Toast, 33 | Tooltip 34 | } 35 | -------------------------------------------------------------------------------- /js/src/util/component-functions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap util/component-functions.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | import EventHandler from '../dom/event-handler.js' 9 | import SelectorEngine from '../dom/selector-engine.js' 10 | import { isDisabled } from './index.js' 11 | 12 | const enableDismissTrigger = (component, method = 'hide') => { 13 | const clickEvent = `click.dismiss${component.EVENT_KEY}` 14 | const name = component.NAME 15 | 16 | EventHandler.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) { 17 | if (['A', 'AREA'].includes(this.tagName)) { 18 | event.preventDefault() 19 | } 20 | 21 | if (isDisabled(this)) { 22 | return 23 | } 24 | 25 | const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`) 26 | const instance = component.getOrCreateInstance(target) 27 | 28 | // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method 29 | instance[method]() 30 | }) 31 | } 32 | 33 | export { 34 | enableDismissTrigger 35 | } 36 | -------------------------------------------------------------------------------- /js/tests/helpers/fixture.js: -------------------------------------------------------------------------------- 1 | const FIXTURE_ID = 'fixture' 2 | 3 | export const getFixture = () => { 4 | let fixtureElement = document.getElementById(FIXTURE_ID) 5 | 6 | if (!fixtureElement) { 7 | fixtureElement = document.createElement('div') 8 | fixtureElement.setAttribute('id', FIXTURE_ID) 9 | fixtureElement.style.position = 'absolute' 10 | fixtureElement.style.top = '-10000px' 11 | fixtureElement.style.left = '-10000px' 12 | fixtureElement.style.width = '10000px' 13 | fixtureElement.style.height = '10000px' 14 | document.body.append(fixtureElement) 15 | } 16 | 17 | return fixtureElement 18 | } 19 | 20 | export const clearFixture = () => { 21 | const fixtureElement = getFixture() 22 | 23 | fixtureElement.innerHTML = '' 24 | } 25 | 26 | export const createEvent = (eventName, parameters = {}) => { 27 | return new Event(eventName, parameters) 28 | } 29 | 30 | export const jQueryMock = { 31 | elements: undefined, 32 | fn: {}, 33 | each(fn) { 34 | for (const element of this.elements) { 35 | fn.call(element) 36 | } 37 | } 38 | } 39 | 40 | export const clearBodyAndDocument = () => { 41 | const attributes = ['data-bs-padding-right', 'style'] 42 | 43 | for (const attribute of attributes) { 44 | document.documentElement.removeAttribute(attribute) 45 | document.body.removeAttribute(attribute) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /js/tests/integration/bundle-modularity.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/extensions, import/no-unassigned-import */ 2 | 3 | import Tooltip from '../../dist/tooltip' 4 | import '../../dist/carousel' 5 | 6 | window.addEventListener('load', () => { 7 | [].concat(...document.querySelectorAll('[data-bs-toggle="tooltip"]')) 8 | .map(tooltipNode => new Tooltip(tooltipNode)) 9 | }) 10 | -------------------------------------------------------------------------------- /js/tests/integration/bundle.js: -------------------------------------------------------------------------------- 1 | import { Tooltip } from '../../../dist/js/bootstrap.esm.js' 2 | 3 | window.addEventListener('load', () => { 4 | [].concat(...document.querySelectorAll('[data-bs-toggle="tooltip"]')) 5 | .map(tooltipNode => new Tooltip(tooltipNode)) 6 | }) 7 | -------------------------------------------------------------------------------- /js/tests/integration/rollup.bundle-modularity.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const commonjs = require('@rollup/plugin-commonjs') 4 | const configRollup = require('./rollup.bundle.js') 5 | 6 | const config = { 7 | ...configRollup, 8 | input: 'js/tests/integration/bundle-modularity.js', 9 | output: { 10 | file: 'js/coverage/bundle-modularity.js', 11 | format: 'iife' 12 | } 13 | } 14 | 15 | config.plugins.unshift(commonjs()) 16 | 17 | module.exports = config 18 | -------------------------------------------------------------------------------- /js/tests/integration/rollup.bundle.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const { babel } = require('@rollup/plugin-babel') 4 | const { nodeResolve } = require('@rollup/plugin-node-resolve') 5 | const replace = require('@rollup/plugin-replace') 6 | 7 | module.exports = { 8 | input: 'js/tests/integration/bundle.js', 9 | output: { 10 | file: 'js/coverage/bundle.js', 11 | format: 'iife' 12 | }, 13 | plugins: [ 14 | replace({ 15 | 'process.env.NODE_ENV': '"production"', 16 | preventAssignment: true 17 | }), 18 | nodeResolve(), 19 | babel({ 20 | exclude: 'node_modules/**', 21 | babelHelpers: 'bundled' 22 | }) 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /nuget/MyGet.ps1: -------------------------------------------------------------------------------- 1 | # set env vars usually set by MyGet (enable for local testing) 2 | #$env:SourcesPath = '..' 3 | #$env:NuGet = "./nuget.exe" # https://dist.nuget.org/win-x86-commandline/latest/nuget.exe 4 | 5 | $nuget = $env:NuGet 6 | 7 | # parse the version number out of package.json 8 | $bsversionParts = ((Get-Content $env:SourcesPath\package.json) -join "`n" | ConvertFrom-Json).version.split('-', 2) # split the version on the '-' 9 | $bsversion = $bsversionParts[0] 10 | 11 | if ($bsversionParts.Length -gt 1) { 12 | $bsversion += '-' + $bsversionParts[1].replace('.', '').replace('-', '_') # strip out invalid chars from the PreRelease part 13 | } 14 | 15 | # create packages 16 | & $nuget pack "$env:SourcesPath\nuget\bootstrap.nuspec" -Verbosity detailed -NonInteractive -NoPackageAnalysis -BasePath $env:SourcesPath -Version $bsversion 17 | & $nuget pack "$env:SourcesPath\nuget\bootstrap.sass.nuspec" -Verbosity detailed -NonInteractive -NoPackageAnalysis -BasePath $env:SourcesPath -Version $bsversion 18 | -------------------------------------------------------------------------------- /nuget/bootstrap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/nuget/bootstrap.png -------------------------------------------------------------------------------- /package.js: -------------------------------------------------------------------------------- 1 | // package metadata file for Meteor.js 2 | 3 | /* eslint-env meteor */ 4 | 5 | Package.describe({ 6 | name: 'twbs:bootstrap', // https://atmospherejs.com/twbs/bootstrap 7 | summary: 'The most popular front-end framework for developing responsive, mobile first projects on the web.', 8 | version: '5.3.6', 9 | git: 'https://github.com/twbs/bootstrap.git' 10 | }) 11 | 12 | Package.onUse(api => { 13 | api.versionsFrom('METEOR@1.0') 14 | api.addFiles([ 15 | 'dist/css/bootstrap.css', 16 | 'dist/js/bootstrap.js' 17 | ], 'client') 18 | }) 19 | -------------------------------------------------------------------------------- /scss/_badge.scss: -------------------------------------------------------------------------------- 1 | // Base class 2 | // 3 | // Requires one of the contextual, color modifier classes for `color` and 4 | // `background-color`. 5 | 6 | .badge { 7 | // scss-docs-start badge-css-vars 8 | --#{$prefix}badge-padding-x: #{$badge-padding-x}; 9 | --#{$prefix}badge-padding-y: #{$badge-padding-y}; 10 | @include rfs($badge-font-size, --#{$prefix}badge-font-size); 11 | --#{$prefix}badge-font-weight: #{$badge-font-weight}; 12 | --#{$prefix}badge-color: #{$badge-color}; 13 | --#{$prefix}badge-border-radius: #{$badge-border-radius}; 14 | // scss-docs-end badge-css-vars 15 | 16 | display: inline-block; 17 | padding: var(--#{$prefix}badge-padding-y) var(--#{$prefix}badge-padding-x); 18 | @include font-size(var(--#{$prefix}badge-font-size)); 19 | font-weight: var(--#{$prefix}badge-font-weight); 20 | line-height: 1; 21 | color: var(--#{$prefix}badge-color); 22 | text-align: center; 23 | white-space: nowrap; 24 | vertical-align: baseline; 25 | @include border-radius(var(--#{$prefix}badge-border-radius)); 26 | @include gradient-bg(); 27 | 28 | // Empty badges collapse automatically 29 | &:empty { 30 | display: none; 31 | } 32 | } 33 | 34 | // Quick fix for badges in buttons 35 | .btn .badge { 36 | position: relative; 37 | top: -1px; 38 | } 39 | -------------------------------------------------------------------------------- /scss/_containers.scss: -------------------------------------------------------------------------------- 1 | // Container widths 2 | // 3 | // Set the container width, and override it for fixed navbars in media queries. 4 | 5 | @if $enable-container-classes { 6 | // Single container class with breakpoint max-widths 7 | .container, 8 | // 100% wide container at all breakpoints 9 | .container-fluid { 10 | @include make-container(); 11 | } 12 | 13 | // Responsive containers that are 100% wide until a breakpoint 14 | @each $breakpoint, $container-max-width in $container-max-widths { 15 | .container-#{$breakpoint} { 16 | @extend .container-fluid; 17 | } 18 | 19 | @include media-breakpoint-up($breakpoint, $grid-breakpoints) { 20 | %responsive-container-#{$breakpoint} { 21 | max-width: $container-max-width; 22 | } 23 | 24 | // Extend each breakpoint which is smaller or equal to the current breakpoint 25 | $extend-breakpoint: true; 26 | 27 | @each $name, $width in $grid-breakpoints { 28 | @if ($extend-breakpoint) { 29 | .container#{breakpoint-infix($name, $grid-breakpoints)} { 30 | @extend %responsive-container-#{$breakpoint}; 31 | } 32 | 33 | // Once the current breakpoint is reached, stop extending 34 | @if ($breakpoint == $name) { 35 | $extend-breakpoint: false; 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /scss/_forms.scss: -------------------------------------------------------------------------------- 1 | @import "forms/labels"; 2 | @import "forms/form-text"; 3 | @import "forms/form-control"; 4 | @import "forms/form-select"; 5 | @import "forms/form-check"; 6 | @import "forms/form-range"; 7 | @import "forms/floating-labels"; 8 | @import "forms/input-group"; 9 | @import "forms/validation"; 10 | -------------------------------------------------------------------------------- /scss/_grid.scss: -------------------------------------------------------------------------------- 1 | // Row 2 | // 3 | // Rows contain your columns. 4 | 5 | :root { 6 | @each $name, $value in $grid-breakpoints { 7 | --#{$prefix}breakpoint-#{$name}: #{$value}; 8 | } 9 | } 10 | 11 | @if $enable-grid-classes { 12 | .row { 13 | @include make-row(); 14 | 15 | > * { 16 | @include make-col-ready(); 17 | } 18 | } 19 | } 20 | 21 | @if $enable-cssgrid { 22 | .grid { 23 | display: grid; 24 | grid-template-rows: repeat(var(--#{$prefix}rows, 1), 1fr); 25 | grid-template-columns: repeat(var(--#{$prefix}columns, #{$grid-columns}), 1fr); 26 | gap: var(--#{$prefix}gap, #{$grid-gutter-width}); 27 | 28 | @include make-cssgrid(); 29 | } 30 | } 31 | 32 | 33 | // Columns 34 | // 35 | // Common styles for small and large grid columns 36 | 37 | @if $enable-grid-classes { 38 | @include make-grid-columns(); 39 | } 40 | -------------------------------------------------------------------------------- /scss/_helpers.scss: -------------------------------------------------------------------------------- 1 | @import "helpers/clearfix"; 2 | @import "helpers/color-bg"; 3 | @import "helpers/colored-links"; 4 | @import "helpers/focus-ring"; 5 | @import "helpers/icon-link"; 6 | @import "helpers/ratio"; 7 | @import "helpers/position"; 8 | @import "helpers/stacks"; 9 | @import "helpers/visually-hidden"; 10 | @import "helpers/stretched-link"; 11 | @import "helpers/text-truncation"; 12 | @import "helpers/vr"; 13 | -------------------------------------------------------------------------------- /scss/_images.scss: -------------------------------------------------------------------------------- 1 | // Responsive images (ensure images don't scale beyond their parents) 2 | // 3 | // This is purposefully opt-in via an explicit class rather than being the default for all ``s. 4 | // We previously tried the "images are responsive by default" approach in Bootstrap v2, 5 | // and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps) 6 | // which weren't expecting the images within themselves to be involuntarily resized. 7 | // See also https://github.com/twbs/bootstrap/issues/18178 8 | .img-fluid { 9 | @include img-fluid(); 10 | } 11 | 12 | 13 | // Image thumbnails 14 | .img-thumbnail { 15 | padding: $thumbnail-padding; 16 | background-color: $thumbnail-bg; 17 | border: $thumbnail-border-width solid $thumbnail-border-color; 18 | @include border-radius($thumbnail-border-radius); 19 | @include box-shadow($thumbnail-box-shadow); 20 | 21 | // Keep them at most 100% wide 22 | @include img-fluid(); 23 | } 24 | 25 | // 26 | // Figures 27 | // 28 | 29 | .figure { 30 | // Ensures the caption's text aligns with the image. 31 | display: inline-block; 32 | } 33 | 34 | .figure-img { 35 | margin-bottom: $spacer * .5; 36 | line-height: 1; 37 | } 38 | 39 | .figure-caption { 40 | @include font-size($figure-caption-font-size); 41 | color: $figure-caption-color; 42 | } 43 | -------------------------------------------------------------------------------- /scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Toggles 2 | // 3 | // Used in conjunction with global variables to enable certain theme features. 4 | 5 | // Vendor 6 | @import "vendor/rfs"; 7 | 8 | // Deprecate 9 | @import "mixins/deprecate"; 10 | 11 | // Helpers 12 | @import "mixins/breakpoints"; 13 | @import "mixins/color-mode"; 14 | @import "mixins/color-scheme"; 15 | @import "mixins/image"; 16 | @import "mixins/resize"; 17 | @import "mixins/visually-hidden"; 18 | @import "mixins/reset-text"; 19 | @import "mixins/text-truncate"; 20 | 21 | // Utilities 22 | @import "mixins/utilities"; 23 | 24 | // Components 25 | @import "mixins/backdrop"; 26 | @import "mixins/buttons"; 27 | @import "mixins/caret"; 28 | @import "mixins/pagination"; 29 | @import "mixins/lists"; 30 | @import "mixins/forms"; 31 | @import "mixins/table-variants"; 32 | 33 | // Skins 34 | @import "mixins/border-radius"; 35 | @import "mixins/box-shadow"; 36 | @import "mixins/gradients"; 37 | @import "mixins/transition"; 38 | 39 | // Layout 40 | @import "mixins/clearfix"; 41 | @import "mixins/container"; 42 | @import "mixins/grid"; 43 | -------------------------------------------------------------------------------- /scss/_placeholders.scss: -------------------------------------------------------------------------------- 1 | .placeholder { 2 | display: inline-block; 3 | min-height: 1em; 4 | vertical-align: middle; 5 | cursor: wait; 6 | background-color: currentcolor; 7 | opacity: $placeholder-opacity-max; 8 | 9 | &.btn::before { 10 | display: inline-block; 11 | content: ""; 12 | } 13 | } 14 | 15 | // Sizing 16 | .placeholder-xs { 17 | min-height: .6em; 18 | } 19 | 20 | .placeholder-sm { 21 | min-height: .8em; 22 | } 23 | 24 | .placeholder-lg { 25 | min-height: 1.2em; 26 | } 27 | 28 | // Animation 29 | .placeholder-glow { 30 | .placeholder { 31 | animation: placeholder-glow 2s ease-in-out infinite; 32 | } 33 | } 34 | 35 | @keyframes placeholder-glow { 36 | 50% { 37 | opacity: $placeholder-opacity-min; 38 | } 39 | } 40 | 41 | .placeholder-wave { 42 | mask-image: linear-gradient(130deg, $black 55%, rgba(0, 0, 0, (1 - $placeholder-opacity-min)) 75%, $black 95%); 43 | mask-size: 200% 100%; 44 | animation: placeholder-wave 2s linear infinite; 45 | } 46 | 47 | @keyframes placeholder-wave { 48 | 100% { 49 | mask-position: -200% 0%; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /scss/_transitions.scss: -------------------------------------------------------------------------------- 1 | .fade { 2 | @include transition($transition-fade); 3 | 4 | &:not(.show) { 5 | opacity: 0; 6 | } 7 | } 8 | 9 | // scss-docs-start collapse-classes 10 | .collapse { 11 | &:not(.show) { 12 | display: none; 13 | } 14 | } 15 | 16 | .collapsing { 17 | height: 0; 18 | overflow: hidden; 19 | @include transition($transition-collapse); 20 | 21 | &.collapse-horizontal { 22 | width: 0; 23 | height: auto; 24 | @include transition($transition-collapse-width); 25 | } 26 | } 27 | // scss-docs-end collapse-classes 28 | -------------------------------------------------------------------------------- /scss/bootstrap-reboot.scss: -------------------------------------------------------------------------------- 1 | @import "mixins/banner"; 2 | @include bsBanner(Reboot); 3 | 4 | @import "functions"; 5 | @import "variables"; 6 | @import "variables-dark"; 7 | @import "maps"; 8 | @import "mixins"; 9 | @import "root"; 10 | @import "reboot"; 11 | -------------------------------------------------------------------------------- /scss/bootstrap-utilities.scss: -------------------------------------------------------------------------------- 1 | @import "mixins/banner"; 2 | @include bsBanner(Utilities); 3 | 4 | // Configuration 5 | @import "functions"; 6 | @import "variables"; 7 | @import "variables-dark"; 8 | @import "maps"; 9 | @import "mixins"; 10 | @import "utilities"; 11 | 12 | // Layout & components 13 | @import "root"; 14 | 15 | // Helpers 16 | @import "helpers"; 17 | 18 | // Utilities 19 | @import "utilities/api"; 20 | -------------------------------------------------------------------------------- /scss/bootstrap.scss: -------------------------------------------------------------------------------- 1 | @import "mixins/banner"; 2 | @include bsBanner(""); 3 | 4 | 5 | // scss-docs-start import-stack 6 | // Configuration 7 | @import "functions"; 8 | @import "variables"; 9 | @import "variables-dark"; 10 | @import "maps"; 11 | @import "mixins"; 12 | @import "utilities"; 13 | 14 | // Layout & components 15 | @import "root"; 16 | @import "reboot"; 17 | @import "type"; 18 | @import "images"; 19 | @import "containers"; 20 | @import "grid"; 21 | @import "tables"; 22 | @import "forms"; 23 | @import "buttons"; 24 | @import "transitions"; 25 | @import "dropdown"; 26 | @import "button-group"; 27 | @import "nav"; 28 | @import "navbar"; 29 | @import "card"; 30 | @import "accordion"; 31 | @import "breadcrumb"; 32 | @import "pagination"; 33 | @import "badge"; 34 | @import "alert"; 35 | @import "progress"; 36 | @import "list-group"; 37 | @import "close"; 38 | @import "toasts"; 39 | @import "modal"; 40 | @import "tooltip"; 41 | @import "popover"; 42 | @import "carousel"; 43 | @import "spinners"; 44 | @import "offcanvas"; 45 | @import "placeholders"; 46 | 47 | // Helpers 48 | @import "helpers"; 49 | 50 | // Utilities 51 | @import "utilities/api"; 52 | // scss-docs-end import-stack 53 | -------------------------------------------------------------------------------- /scss/forms/_form-text.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Form text 3 | // 4 | 5 | .form-text { 6 | margin-top: $form-text-margin-top; 7 | @include font-size($form-text-font-size); 8 | font-style: $form-text-font-style; 9 | font-weight: $form-text-font-weight; 10 | color: $form-text-color; 11 | } 12 | -------------------------------------------------------------------------------- /scss/forms/_labels.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Labels 3 | // 4 | 5 | .form-label { 6 | margin-bottom: $form-label-margin-bottom; 7 | @include font-size($form-label-font-size); 8 | font-style: $form-label-font-style; 9 | font-weight: $form-label-font-weight; 10 | color: $form-label-color; 11 | } 12 | 13 | // For use with horizontal and inline forms, when you need the label (or legend) 14 | // text to align with the form controls. 15 | .col-form-label { 16 | padding-top: add($input-padding-y, $input-border-width); 17 | padding-bottom: add($input-padding-y, $input-border-width); 18 | margin-bottom: 0; // Override the `` default 19 | @include font-size(inherit); // Override the `` default 20 | font-style: $form-label-font-style; 21 | font-weight: $form-label-font-weight; 22 | line-height: $input-line-height; 23 | color: $form-label-color; 24 | } 25 | 26 | .col-form-label-lg { 27 | padding-top: add($input-padding-y-lg, $input-border-width); 28 | padding-bottom: add($input-padding-y-lg, $input-border-width); 29 | @include font-size($input-font-size-lg); 30 | } 31 | 32 | .col-form-label-sm { 33 | padding-top: add($input-padding-y-sm, $input-border-width); 34 | padding-bottom: add($input-padding-y-sm, $input-border-width); 35 | @include font-size($input-font-size-sm); 36 | } 37 | -------------------------------------------------------------------------------- /scss/forms/_validation.scss: -------------------------------------------------------------------------------- 1 | // Form validation 2 | // 3 | // Provide feedback to users when form field values are valid or invalid. Works 4 | // primarily for client-side validation via scoped `:invalid` and `:valid` 5 | // pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for 6 | // server-side validation. 7 | 8 | // scss-docs-start form-validation-states-loop 9 | @each $state, $data in $form-validation-states { 10 | @include form-validation-state($state, $data...); 11 | } 12 | // scss-docs-end form-validation-states-loop 13 | -------------------------------------------------------------------------------- /scss/helpers/_clearfix.scss: -------------------------------------------------------------------------------- 1 | .clearfix { 2 | @include clearfix(); 3 | } 4 | -------------------------------------------------------------------------------- /scss/helpers/_color-bg.scss: -------------------------------------------------------------------------------- 1 | // All-caps `RGBA()` function used because of this Sass bug: https://github.com/sass/node-sass/issues/2251 2 | @each $color, $value in $theme-colors { 3 | .text-bg-#{$color} { 4 | color: color-contrast($value) if($enable-important-utilities, !important, null); 5 | background-color: RGBA(var(--#{$prefix}#{$color}-rgb), var(--#{$prefix}bg-opacity, 1)) if($enable-important-utilities, !important, null); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /scss/helpers/_focus-ring.scss: -------------------------------------------------------------------------------- 1 | .focus-ring:focus { 2 | outline: 0; 3 | // By default, there is no `--bs-focus-ring-x`, `--bs-focus-ring-y`, or `--bs-focus-ring-blur`, but we provide CSS variables with fallbacks to initial `0` values 4 | box-shadow: var(--#{$prefix}focus-ring-x, 0) var(--#{$prefix}focus-ring-y, 0) var(--#{$prefix}focus-ring-blur, 0) var(--#{$prefix}focus-ring-width) var(--#{$prefix}focus-ring-color); 5 | } 6 | -------------------------------------------------------------------------------- /scss/helpers/_icon-link.scss: -------------------------------------------------------------------------------- 1 | .icon-link { 2 | display: inline-flex; 3 | gap: $icon-link-gap; 4 | align-items: center; 5 | text-decoration-color: rgba(var(--#{$prefix}link-color-rgb), var(--#{$prefix}link-opacity, .5)); 6 | text-underline-offset: $icon-link-underline-offset; 7 | backface-visibility: hidden; 8 | 9 | > .bi { 10 | flex-shrink: 0; 11 | width: $icon-link-icon-size; 12 | height: $icon-link-icon-size; 13 | fill: currentcolor; 14 | @include transition($icon-link-icon-transition); 15 | } 16 | } 17 | 18 | .icon-link-hover { 19 | &:hover, 20 | &:focus-visible { 21 | > .bi { 22 | transform: var(--#{$prefix}icon-link-transform, $icon-link-icon-transform); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /scss/helpers/_position.scss: -------------------------------------------------------------------------------- 1 | // Shorthand 2 | 3 | .fixed-top { 4 | position: fixed; 5 | top: 0; 6 | right: 0; 7 | left: 0; 8 | z-index: $zindex-fixed; 9 | } 10 | 11 | .fixed-bottom { 12 | position: fixed; 13 | right: 0; 14 | bottom: 0; 15 | left: 0; 16 | z-index: $zindex-fixed; 17 | } 18 | 19 | // Responsive sticky top and bottom 20 | @each $breakpoint in map-keys($grid-breakpoints) { 21 | @include media-breakpoint-up($breakpoint) { 22 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 23 | 24 | .sticky#{$infix}-top { 25 | position: sticky; 26 | top: 0; 27 | z-index: $zindex-sticky; 28 | } 29 | 30 | .sticky#{$infix}-bottom { 31 | position: sticky; 32 | bottom: 0; 33 | z-index: $zindex-sticky; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /scss/helpers/_ratio.scss: -------------------------------------------------------------------------------- 1 | // Credit: Nicolas Gallagher and SUIT CSS. 2 | 3 | .ratio { 4 | position: relative; 5 | width: 100%; 6 | 7 | &::before { 8 | display: block; 9 | padding-top: var(--#{$prefix}aspect-ratio); 10 | content: ""; 11 | } 12 | 13 | > * { 14 | position: absolute; 15 | top: 0; 16 | left: 0; 17 | width: 100%; 18 | height: 100%; 19 | } 20 | } 21 | 22 | @each $key, $ratio in $aspect-ratios { 23 | .ratio-#{$key} { 24 | --#{$prefix}aspect-ratio: #{$ratio}; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /scss/helpers/_stacks.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start stacks 2 | .hstack { 3 | display: flex; 4 | flex-direction: row; 5 | align-items: center; 6 | align-self: stretch; 7 | } 8 | 9 | .vstack { 10 | display: flex; 11 | flex: 1 1 auto; 12 | flex-direction: column; 13 | align-self: stretch; 14 | } 15 | // scss-docs-end stacks 16 | -------------------------------------------------------------------------------- /scss/helpers/_stretched-link.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Stretched link 3 | // 4 | 5 | .stretched-link { 6 | &::#{$stretched-link-pseudo-element} { 7 | position: absolute; 8 | top: 0; 9 | right: 0; 10 | bottom: 0; 11 | left: 0; 12 | z-index: $stretched-link-z-index; 13 | content: ""; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /scss/helpers/_text-truncation.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Text truncation 3 | // 4 | 5 | .text-truncate { 6 | @include text-truncate(); 7 | } 8 | -------------------------------------------------------------------------------- /scss/helpers/_visually-hidden.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Visually hidden 3 | // 4 | 5 | .visually-hidden, 6 | .visually-hidden-focusable:not(:focus):not(:focus-within) { 7 | @include visually-hidden(); 8 | } 9 | -------------------------------------------------------------------------------- /scss/helpers/_vr.scss: -------------------------------------------------------------------------------- 1 | .vr { 2 | display: inline-block; 3 | align-self: stretch; 4 | width: $vr-border-width; 5 | min-height: 1em; 6 | background-color: currentcolor; 7 | opacity: $hr-opacity; 8 | } 9 | -------------------------------------------------------------------------------- /scss/mixins/_alert.scss: -------------------------------------------------------------------------------- 1 | @include deprecate("`alert-variant()`", "v5.3.0", "v6.0.0"); 2 | 3 | // scss-docs-start alert-variant-mixin 4 | @mixin alert-variant($background, $border, $color) { 5 | --#{$prefix}alert-color: #{$color}; 6 | --#{$prefix}alert-bg: #{$background}; 7 | --#{$prefix}alert-border-color: #{$border}; 8 | --#{$prefix}alert-link-color: #{shade-color($color, 20%)}; 9 | 10 | @if $enable-gradients { 11 | background-image: var(--#{$prefix}gradient); 12 | } 13 | 14 | .alert-link { 15 | color: var(--#{$prefix}alert-link-color); 16 | } 17 | } 18 | // scss-docs-end alert-variant-mixin 19 | -------------------------------------------------------------------------------- /scss/mixins/_backdrop.scss: -------------------------------------------------------------------------------- 1 | // Shared between modals and offcanvases 2 | @mixin overlay-backdrop($zindex, $backdrop-bg, $backdrop-opacity) { 3 | position: fixed; 4 | top: 0; 5 | left: 0; 6 | z-index: $zindex; 7 | width: 100vw; 8 | height: 100vh; 9 | background-color: $backdrop-bg; 10 | 11 | // Fade for backdrop 12 | &.fade { opacity: 0; } 13 | &.show { opacity: $backdrop-opacity; } 14 | } 15 | -------------------------------------------------------------------------------- /scss/mixins/_banner.scss: -------------------------------------------------------------------------------- 1 | @mixin bsBanner($file) { 2 | /*! 3 | * Bootstrap #{$file} v5.3.6 (https://getbootstrap.com/) 4 | * Copyright 2011-2025 The Bootstrap Authors 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | */ 7 | } 8 | -------------------------------------------------------------------------------- /scss/mixins/_box-shadow.scss: -------------------------------------------------------------------------------- 1 | @mixin box-shadow($shadow...) { 2 | @if $enable-shadows { 3 | $result: (); 4 | $has-single-value: false; 5 | $single-value: null; 6 | 7 | @each $value in $shadow { 8 | @if $value != null { 9 | @if $value == none or $value == initial or $value == inherit or $value == unset { 10 | $has-single-value: true; 11 | $single-value: $value; 12 | } @else { 13 | $result: append($result, $value, "comma"); 14 | } 15 | } 16 | } 17 | 18 | @if $has-single-value { 19 | box-shadow: $single-value; 20 | } @else if (length($result) > 0) { 21 | box-shadow: $result; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /scss/mixins/_clearfix.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start clearfix 2 | @mixin clearfix() { 3 | &::after { 4 | display: block; 5 | clear: both; 6 | content: ""; 7 | } 8 | } 9 | // scss-docs-end clearfix 10 | -------------------------------------------------------------------------------- /scss/mixins/_color-mode.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start color-mode-mixin 2 | @mixin color-mode($mode: light, $root: false) { 3 | @if $color-mode-type == "media-query" { 4 | @if $root == true { 5 | @media (prefers-color-scheme: $mode) { 6 | :root { 7 | @content; 8 | } 9 | } 10 | } @else { 11 | @media (prefers-color-scheme: $mode) { 12 | @content; 13 | } 14 | } 15 | } @else { 16 | [data-bs-theme="#{$mode}"] { 17 | @content; 18 | } 19 | } 20 | } 21 | // scss-docs-end color-mode-mixin 22 | -------------------------------------------------------------------------------- /scss/mixins/_color-scheme.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start mixin-color-scheme 2 | @mixin color-scheme($name) { 3 | @media (prefers-color-scheme: #{$name}) { 4 | @content; 5 | } 6 | } 7 | // scss-docs-end mixin-color-scheme 8 | -------------------------------------------------------------------------------- /scss/mixins/_container.scss: -------------------------------------------------------------------------------- 1 | // Container mixins 2 | 3 | @mixin make-container($gutter: $container-padding-x) { 4 | --#{$prefix}gutter-x: #{$gutter}; 5 | --#{$prefix}gutter-y: 0; 6 | width: 100%; 7 | padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list 8 | padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list 9 | margin-right: auto; 10 | margin-left: auto; 11 | } 12 | -------------------------------------------------------------------------------- /scss/mixins/_deprecate.scss: -------------------------------------------------------------------------------- 1 | // Deprecate mixin 2 | // 3 | // This mixin can be used to deprecate mixins or functions. 4 | // `$enable-deprecation-messages` is a global variable, `$ignore-warning` is a variable that can be passed to 5 | // some deprecated mixins to suppress the warning (for example if the mixin is still be used in the current version of Bootstrap) 6 | @mixin deprecate($name, $deprecate-version, $remove-version, $ignore-warning: false) { 7 | @if ($enable-deprecation-messages != false and $ignore-warning != true) { 8 | @warn "#{$name} has been deprecated as of #{$deprecate-version}. It will be removed entirely in #{$remove-version}."; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /scss/mixins/_image.scss: -------------------------------------------------------------------------------- 1 | // Image Mixins 2 | // - Responsive image 3 | // - Retina image 4 | 5 | 6 | // Responsive image 7 | // 8 | // Keep images from scaling beyond the width of their parents. 9 | 10 | @mixin img-fluid { 11 | // Part 1: Set a maximum relative to the parent 12 | max-width: 100%; 13 | // Part 2: Override the height to auto, otherwise images will be stretched 14 | // when setting a width and height attribute on the img element. 15 | height: auto; 16 | } 17 | -------------------------------------------------------------------------------- /scss/mixins/_list-group.scss: -------------------------------------------------------------------------------- 1 | @include deprecate("`list-group-item-variant()`", "v5.3.0", "v6.0.0"); 2 | 3 | // List Groups 4 | 5 | // scss-docs-start list-group-mixin 6 | @mixin list-group-item-variant($state, $background, $color) { 7 | .list-group-item-#{$state} { 8 | color: $color; 9 | background-color: $background; 10 | 11 | &.list-group-item-action { 12 | &:hover, 13 | &:focus { 14 | color: $color; 15 | background-color: shade-color($background, 10%); 16 | } 17 | 18 | &.active { 19 | color: $white; 20 | background-color: $color; 21 | border-color: $color; 22 | } 23 | } 24 | } 25 | } 26 | // scss-docs-end list-group-mixin 27 | -------------------------------------------------------------------------------- /scss/mixins/_lists.scss: -------------------------------------------------------------------------------- 1 | // Lists 2 | 3 | // Unstyled keeps list items block level, just removes default browser padding and list-style 4 | @mixin list-unstyled { 5 | padding-left: 0; 6 | list-style: none; 7 | } 8 | -------------------------------------------------------------------------------- /scss/mixins/_pagination.scss: -------------------------------------------------------------------------------- 1 | // Pagination 2 | 3 | // scss-docs-start pagination-mixin 4 | @mixin pagination-size($padding-y, $padding-x, $font-size, $border-radius) { 5 | --#{$prefix}pagination-padding-x: #{$padding-x}; 6 | --#{$prefix}pagination-padding-y: #{$padding-y}; 7 | @include rfs($font-size, --#{$prefix}pagination-font-size); 8 | --#{$prefix}pagination-border-radius: #{$border-radius}; 9 | } 10 | // scss-docs-end pagination-mixin 11 | -------------------------------------------------------------------------------- /scss/mixins/_reset-text.scss: -------------------------------------------------------------------------------- 1 | @mixin reset-text { 2 | font-family: $font-family-base; 3 | // We deliberately do NOT reset font-size or overflow-wrap / word-wrap. 4 | font-style: normal; 5 | font-weight: $font-weight-normal; 6 | line-height: $line-height-base; 7 | text-align: left; // Fallback for where `start` is not supported 8 | text-align: start; 9 | text-decoration: none; 10 | text-shadow: none; 11 | text-transform: none; 12 | letter-spacing: normal; 13 | word-break: normal; 14 | white-space: normal; 15 | word-spacing: normal; 16 | line-break: auto; 17 | } 18 | -------------------------------------------------------------------------------- /scss/mixins/_resize.scss: -------------------------------------------------------------------------------- 1 | // Resize anything 2 | 3 | @mixin resizable($direction) { 4 | overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible` 5 | resize: $direction; // Options: horizontal, vertical, both 6 | } 7 | -------------------------------------------------------------------------------- /scss/mixins/_table-variants.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start table-variant 2 | @mixin table-variant($state, $background) { 3 | .table-#{$state} { 4 | $color: color-contrast(opaque($body-bg, $background)); 5 | $hover-bg: mix($color, $background, percentage($table-hover-bg-factor)); 6 | $striped-bg: mix($color, $background, percentage($table-striped-bg-factor)); 7 | $active-bg: mix($color, $background, percentage($table-active-bg-factor)); 8 | $table-border-color: mix($color, $background, percentage($table-border-factor)); 9 | 10 | --#{$prefix}table-color: #{$color}; 11 | --#{$prefix}table-bg: #{$background}; 12 | --#{$prefix}table-border-color: #{$table-border-color}; 13 | --#{$prefix}table-striped-bg: #{$striped-bg}; 14 | --#{$prefix}table-striped-color: #{color-contrast($striped-bg)}; 15 | --#{$prefix}table-active-bg: #{$active-bg}; 16 | --#{$prefix}table-active-color: #{color-contrast($active-bg)}; 17 | --#{$prefix}table-hover-bg: #{$hover-bg}; 18 | --#{$prefix}table-hover-color: #{color-contrast($hover-bg)}; 19 | 20 | color: var(--#{$prefix}table-color); 21 | border-color: var(--#{$prefix}table-border-color); 22 | } 23 | } 24 | // scss-docs-end table-variant 25 | -------------------------------------------------------------------------------- /scss/mixins/_text-truncate.scss: -------------------------------------------------------------------------------- 1 | // Text truncate 2 | // Requires inline-block or block for proper styling 3 | 4 | @mixin text-truncate() { 5 | overflow: hidden; 6 | text-overflow: ellipsis; 7 | white-space: nowrap; 8 | } 9 | -------------------------------------------------------------------------------- /scss/mixins/_transition.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable property-disallowed-list 2 | @mixin transition($transition...) { 3 | @if length($transition) == 0 { 4 | $transition: $transition-base; 5 | } 6 | 7 | @if length($transition) > 1 { 8 | @each $value in $transition { 9 | @if $value == null or $value == none { 10 | @warn "The keyword 'none' or 'null' must be used as a single argument."; 11 | } 12 | } 13 | } 14 | 15 | @if $enable-transitions { 16 | @if nth($transition, 1) != null { 17 | transition: $transition; 18 | } 19 | 20 | @if $enable-reduced-motion and nth($transition, 1) != null and nth($transition, 1) != none { 21 | @media (prefers-reduced-motion: reduce) { 22 | transition: none; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /scss/mixins/_visually-hidden.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // Hide content visually while keeping it accessible to assistive technologies 4 | // 5 | // See: https://www.a11yproject.com/posts/2013-01-11-how-to-hide-content/ 6 | // See: https://kittygiraudel.com/2016/10/13/css-hide-and-seek/ 7 | 8 | @mixin visually-hidden() { 9 | width: 1px !important; 10 | height: 1px !important; 11 | padding: 0 !important; 12 | margin: -1px !important; // Fix for https://github.com/twbs/bootstrap/issues/25686 13 | overflow: hidden !important; 14 | clip: rect(0, 0, 0, 0) !important; 15 | white-space: nowrap !important; 16 | border: 0 !important; 17 | 18 | // Fix for positioned table caption that could become anonymous cells 19 | &:not(caption) { 20 | position: absolute !important; 21 | } 22 | 23 | // Fix to prevent overflowing children to become focusable 24 | * { 25 | overflow: hidden !important; 26 | } 27 | } 28 | 29 | // Use to only display content when it's focused, or one of its child elements is focused 30 | // (i.e. when focus is within the element/container that the class was applied to) 31 | // 32 | // Useful for "Skip to main content" links; see https://www.w3.org/WAI/WCAG22/Techniques/general/G1.html 33 | 34 | @mixin visually-hidden-focusable() { 35 | &:not(:focus):not(:focus-within) { 36 | @include visually-hidden(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /scss/tests/jasmine.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable camelcase */ 2 | 3 | 'use strict' 4 | 5 | const path = require('node:path') 6 | 7 | module.exports = { 8 | spec_dir: 'scss', 9 | // Make Jasmine look for `.test.scss` files 10 | spec_files: ['**/*.{test,spec}.scss'], 11 | // Compile them into JS scripts running `sass-true` 12 | requires: [path.join(__dirname, 'sass-true/register')], 13 | // Ensure we use `require` so that the require.extensions works 14 | // as `import` completely bypasses it 15 | jsLoader: 'require' 16 | } 17 | -------------------------------------------------------------------------------- /scss/tests/mixins/_auto-import-of-variables-dark.test.scss: -------------------------------------------------------------------------------- 1 | // TODO: this file can be removed safely in v6 when `@import "variables-dark"` will be removed at the end of _variables.scss 2 | 3 | @import "../../functions"; 4 | @import "../../variables"; 5 | // Voluntarily not importing _variables-dark.scss 6 | @import "../../maps"; 7 | @import "../../mixins"; 8 | -------------------------------------------------------------------------------- /scss/tests/mixins/_media-query-color-mode-full.test.scss: -------------------------------------------------------------------------------- 1 | $color-mode-type: media-query; 2 | 3 | @import "../../bootstrap"; 4 | 5 | @include describe("global $color-mode-type: media-query") { 6 | @include it("compiles entirely Bootstrap CSS with media-query color mode") { // stylelint-disable-line block-no-empty 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /scss/tests/sass-true/register.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('node:path') 4 | 5 | const runnerPath = path.join(__dirname, 'runner').replace(/\\/g, '/') 6 | 7 | require.extensions['.scss'] = (module, filename) => { 8 | const normalizedFilename = filename.replace(/\\/g, '/') 9 | 10 | return module._compile(` 11 | const runner = require('${runnerPath}') 12 | runner('${normalizedFilename}', { describe, it }) 13 | `, filename) 14 | } 15 | -------------------------------------------------------------------------------- /scss/tests/sass-true/runner.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const fs = require('node:fs') 4 | const path = require('node:path') 5 | const { runSass } = require('sass-true') 6 | 7 | module.exports = (filename, { describe, it }) => { 8 | const data = fs.readFileSync(filename, 'utf8') 9 | const TRUE_SETUP = '$true-terminal-output: false; @import "true";' 10 | const sassString = TRUE_SETUP + data 11 | 12 | runSass( 13 | { describe, it, sourceType: 'string' }, 14 | sassString, 15 | { loadPaths: [path.dirname(filename)] } 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /site/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/prettierrc", 3 | "arrowParens": "always", 4 | "printWidth": 120, 5 | "semi": false, 6 | "singleQuote": true, 7 | "trailingComma": "none" 8 | } 9 | -------------------------------------------------------------------------------- /site/astro.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'astro/config' 2 | 3 | import { bootstrap } from './src/libs/astro' 4 | import { getConfig } from './src/libs/config' 5 | import { algoliaPlugin } from './src/plugins/algolia-plugin' 6 | import { stackblitzPlugin } from './src/plugins/stackblitz-plugin' 7 | 8 | const isDev = process.env.NODE_ENV === 'development' 9 | 10 | const site = isDev 11 | ? // In development mode, use the local dev server. 12 | 'http://localhost:4321' 13 | : process.env.DEPLOY_PRIME_URL !== undefined 14 | ? // If deploying on Netlify, use the `DEPLOY_PRIME_URL` environment variable. 15 | process.env.DEPLOY_PRIME_URL 16 | : // Otherwise, use the `baseURL` value defined in the `config.yml` file. 17 | getConfig().baseURL 18 | 19 | // https://astro.build/config 20 | export default defineConfig({ 21 | build: { 22 | assets: `docs/${getConfig().docs_version}/assets` 23 | }, 24 | integrations: [bootstrap()], 25 | markdown: { 26 | smartypants: false, 27 | syntaxHighlight: 'prism' 28 | }, 29 | site, 30 | vite: { 31 | plugins: [algoliaPlugin(), stackblitzPlugin()] 32 | } 33 | }) 34 | -------------------------------------------------------------------------------- /site/data/breakpoints.yml: -------------------------------------------------------------------------------- 1 | - breakpoint: xs 2 | abbr: '' 3 | name: X-Small 4 | min-width: 0px 5 | container: '' 6 | 7 | - breakpoint: sm 8 | abbr: -sm 9 | name: Small 10 | min-width: 576px 11 | container: 540px 12 | 13 | - breakpoint: md 14 | abbr: -md 15 | name: Medium 16 | min-width: 768px 17 | container: 720px 18 | 19 | - breakpoint: lg 20 | abbr: -lg 21 | name: Large 22 | min-width: 992px 23 | container: 960px 24 | 25 | - breakpoint: xl 26 | abbr: -xl 27 | name: X-Large 28 | min-width: 1200px 29 | container: 1140px 30 | 31 | - breakpoint: xxl 32 | abbr: -xxl 33 | name: XX-Large 34 | min-width: 1400px 35 | container: 1320px 36 | -------------------------------------------------------------------------------- /site/data/colors.yml: -------------------------------------------------------------------------------- 1 | - name: blue 2 | hex: '#0d6efd' 3 | - name: indigo 4 | hex: '#6610f2' 5 | - name: purple 6 | hex: '#6f42c1' 7 | - name: pink 8 | hex: '#d63384' 9 | - name: red 10 | hex: '#dc3545' 11 | - name: orange 12 | hex: '#fd7e14' 13 | - name: yellow 14 | hex: '#ffc107' 15 | - name: green 16 | hex: '#198754' 17 | - name: teal 18 | hex: '#20c997' 19 | - name: cyan 20 | hex: '#0dcaf0' 21 | - name: white 22 | hex: '#fff' 23 | - name: gray 24 | hex: '#6c757d' 25 | - name: gray-dark 26 | hex: '#343a40' 27 | -------------------------------------------------------------------------------- /site/data/core-team.yml: -------------------------------------------------------------------------------- 1 | - name: Mark Otto 2 | user: mdo 3 | 4 | - name: Jacob Thornton 5 | user: fat 6 | 7 | - name: XhmikosR 8 | user: xhmikosr 9 | 10 | - name: GeoSot 11 | user: geosot 12 | 13 | - name: Patrick H. Lauke 14 | user: patrickhlauke 15 | 16 | - name: Julien Déramond 17 | user: julien-deramond 18 | 19 | - name: Gaël Poupard 20 | user: ffoodd 21 | 22 | - name: Rohit Sharma 23 | user: rohit2sharma95 24 | 25 | - name: alpadev 26 | user: alpadev 27 | 28 | - name: Martijn Cuppens 29 | user: martijncuppens 30 | 31 | - name: Johann-S 32 | user: johann-s 33 | 34 | - name: Gleb Mazovetskiy 35 | user: glebm 36 | -------------------------------------------------------------------------------- /site/data/docs-versions.yml: -------------------------------------------------------------------------------- 1 | - group: v1.x 2 | baseurl: 'https://getbootstrap.com' 3 | description: 'Every minor and patch release from v1 is listed below.' 4 | versions: 5 | - '1.0.0' 6 | - '1.1.0' 7 | - '1.1.1' 8 | - '1.2.0' 9 | - '1.3.0' 10 | - '1.4.0' 11 | 12 | - group: v2.x 13 | baseurl: 'https://getbootstrap.com' 14 | description: 'Every minor and patch release from v2 is listed below.' 15 | versions: 16 | - '2.0.0' 17 | - '2.0.1' 18 | - '2.0.2' 19 | - '2.0.3' 20 | - '2.0.4' 21 | - '2.1.0' 22 | - '2.1.1' 23 | - '2.2.0' 24 | - '2.2.1' 25 | - '2.2.2' 26 | - '2.3.0' 27 | - '2.3.1' 28 | - '2.3.2' 29 | 30 | - group: v3.x 31 | baseurl: 'https://getbootstrap.com/docs' 32 | description: 'Every minor release from v3 is listed below. Last update was v3.4.1.' 33 | versions: 34 | - '3.3' 35 | - '3.4' 36 | 37 | - group: v4.x 38 | baseurl: 'https://getbootstrap.com/docs' 39 | description: 'Our previous major release with its minor releases. Last update was v4.6.2.' 40 | versions: 41 | - '4.0' 42 | - '4.1' 43 | - '4.2' 44 | - '4.3' 45 | - '4.4' 46 | - '4.5' 47 | - '4.6' 48 | 49 | - group: v5.x 50 | baseurl: 'https://getbootstrap.com/docs' 51 | description: 'Current major release. Last update was v5.3.6.' 52 | versions: 53 | - '5.0' 54 | - '5.1' 55 | - '5.2' 56 | - '5.3' 57 | -------------------------------------------------------------------------------- /site/data/grays.yml: -------------------------------------------------------------------------------- 1 | - name: 100 2 | hex: '#f8f9fa' 3 | - name: 200 4 | hex: '#e9ecef' 5 | - name: 300 6 | hex: '#dee2e6' 7 | - name: 400 8 | hex: '#ced4da' 9 | - name: 500 10 | hex: '#adb5bd' 11 | - name: 600 12 | hex: '#868e96' 13 | - name: 700 14 | hex: '#495057' 15 | - name: 800 16 | hex: '#343a40' 17 | - name: 900 18 | hex: '#212529' 19 | -------------------------------------------------------------------------------- /site/data/icons.yml: -------------------------------------------------------------------------------- 1 | preferred: 2 | - name: Font Awesome 3 | website: https://fontawesome.com/ 4 | - name: Feather 5 | website: https://feathericons.com/ 6 | - name: Octicons 7 | website: https://primer.style/foundations/icons 8 | 9 | more: 10 | - name: Bytesize 11 | website: https://github.com/danklammer/bytesize-icons 12 | - name: CoreUI Icons 13 | website: https://coreui.io/icons/ 14 | - name: Google Material icons 15 | website: https://fonts.google.com/icons 16 | - name: Ionicons 17 | website: https://ionic.io/ionicons 18 | - name: Dripicons 19 | website: http://demo.amitjakhu.com/dripicons/ 20 | - name: Ikons 21 | website: https://ikons.piotrkwiatkowski.co.uk/ 22 | - name: Icons8 23 | website: https://icons8.com/ 24 | - name: icofont 25 | website: https://icofont.com/ 26 | - name: Tabler Icons 27 | website: https://tabler.io/icons 28 | -------------------------------------------------------------------------------- /site/data/theme-colors.yml: -------------------------------------------------------------------------------- 1 | - name: primary 2 | hex: '#0d6efd' 3 | - name: secondary 4 | hex: '#6c757d' 5 | - name: success 6 | hex: '#28a745' 7 | - name: danger 8 | hex: '#dc3545' 9 | - name: warning 10 | hex: '#ffc107' 11 | contrast_color: dark 12 | - name: info 13 | hex: '#17a2b8' 14 | contrast_color: dark 15 | - name: light 16 | hex: '#f8f9fa' 17 | contrast_color: dark 18 | - name: dark 19 | hex: '#343a40' 20 | contrast_color: white 21 | -------------------------------------------------------------------------------- /site/data/translations.yml: -------------------------------------------------------------------------------- 1 | - name: 中文(繁體) 2 | code: zh-tw 3 | description: Bootstrap 5 繁體中文手冊 4 | url: https://bootstrap5.hexschool.com/ 5 | 6 | - name: Simplified Chinese 7 | code: zh-CN 8 | description: Bootstrap 5 中文文档 9 | url: https://v5.bootcss.com/ 10 | 11 | - name: Japanese 12 | code: ja 13 | description: Bootstrap 5 日本語リファレンス 14 | url: https://getbootstrap.jp/ 15 | 16 | - name: Russian 17 | code: ru 18 | description: Bootstrap 5 на русском 19 | url: https://getbootstrap.su/ 20 | 21 | - name: Korean 22 | code: ko 23 | description: Bootstrap 5 한국어 문서 24 | url: https://getbootstrap.kr/ 25 | -------------------------------------------------------------------------------- /site/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [require('autoprefixer')] 3 | } 4 | -------------------------------------------------------------------------------- /site/src/assets/application.js: -------------------------------------------------------------------------------- 1 | // NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT 2 | // IT'S ALL JUST JUNK FOR OUR DOCS! 3 | // ++++++++++++++++++++++++++++++++++++++++++ 4 | 5 | /*! 6 | * JavaScript for Bootstrap's docs (https://getbootstrap.com/) 7 | * Copyright 2011-2025 The Bootstrap Authors 8 | * Licensed under the Creative Commons Attribution 3.0 Unported License. 9 | * For details, see https://creativecommons.org/licenses/by/3.0/. 10 | */ 11 | 12 | import sidebarScroll from './partials/sidebar.js' 13 | import snippets from './partials/snippets.js' 14 | 15 | sidebarScroll() 16 | snippets() 17 | -------------------------------------------------------------------------------- /site/src/assets/examples/badges/badges.css: -------------------------------------------------------------------------------- 1 | .badge > a { 2 | color: inherit; 3 | } 4 | -------------------------------------------------------------------------------- /site/src/assets/examples/blog/blog.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable @stylistic/selector-list-comma-newline-after */ 2 | 3 | .blog-header-logo { 4 | font-family: "Playfair Display", Georgia, "Times New Roman", serif/*rtl:Amiri, Georgia, "Times New Roman", serif*/; 5 | font-size: 2.25rem; 6 | } 7 | 8 | .blog-header-logo:hover { 9 | text-decoration: none; 10 | } 11 | 12 | h1, h2, h3, h4, h5, h6 { 13 | font-family: "Playfair Display", Georgia, "Times New Roman", serif/*rtl:Amiri, Georgia, "Times New Roman", serif*/; 14 | } 15 | 16 | .flex-auto { 17 | flex: 0 0 auto; 18 | } 19 | 20 | .h-250 { height: 250px; } 21 | @media (min-width: 768px) { 22 | .h-md-250 { height: 250px; } 23 | } 24 | 25 | /* Pagination */ 26 | .blog-pagination { 27 | margin-bottom: 4rem; 28 | } 29 | 30 | /* 31 | * Blog posts 32 | */ 33 | .blog-post { 34 | margin-bottom: 4rem; 35 | } 36 | .blog-post-meta { 37 | margin-bottom: 1.25rem; 38 | color: #727272; 39 | } 40 | -------------------------------------------------------------------------------- /site/src/assets/examples/blog/blog.rtl.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable @stylistic/selector-list-comma-newline-after */ 2 | 3 | .blog-header-logo { 4 | font-family: Amiri, Georgia, "Times New Roman", serif; 5 | font-size: 2.25rem; 6 | } 7 | 8 | .blog-header-logo:hover { 9 | text-decoration: none; 10 | } 11 | 12 | h1, h2, h3, h4, h5, h6 { 13 | font-family: Amiri, Georgia, "Times New Roman", serif; 14 | } 15 | 16 | .flex-auto { 17 | flex: 0 0 auto; 18 | } 19 | 20 | .h-250 { height: 250px; } 21 | @media (min-width: 768px) { 22 | .h-md-250 { height: 250px; } 23 | } 24 | 25 | /* Pagination */ 26 | .blog-pagination { 27 | margin-bottom: 4rem; 28 | } 29 | 30 | /* 31 | * Blog posts 32 | */ 33 | .blog-post { 34 | margin-bottom: 4rem; 35 | } 36 | .blog-post-meta { 37 | margin-bottom: 1.25rem; 38 | color: #727272; 39 | } 40 | -------------------------------------------------------------------------------- /site/src/assets/examples/checkout/checkout.css: -------------------------------------------------------------------------------- 1 | .container { 2 | max-width: 960px; 3 | } 4 | -------------------------------------------------------------------------------- /site/src/assets/examples/checkout/checkout.js: -------------------------------------------------------------------------------- 1 | // Example starter JavaScript for disabling form submissions if there are invalid fields 2 | (() => { 3 | 'use strict' 4 | 5 | // Fetch all the forms we want to apply custom Bootstrap validation styles to 6 | const forms = document.querySelectorAll('.needs-validation') 7 | 8 | // Loop over them and prevent submission 9 | Array.from(forms).forEach(form => { 10 | form.addEventListener('submit', event => { 11 | if (!form.checkValidity()) { 12 | event.preventDefault() 13 | event.stopPropagation() 14 | } 15 | 16 | form.classList.add('was-validated') 17 | }, false) 18 | }) 19 | })() 20 | -------------------------------------------------------------------------------- /site/src/assets/examples/cover/cover.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Globals 3 | */ 4 | 5 | 6 | /* Custom default button */ 7 | .btn-light, 8 | .btn-light:hover, 9 | .btn-light:focus { 10 | color: #333; 11 | text-shadow: none; /* Prevent inheritance from `body` */ 12 | } 13 | 14 | 15 | /* 16 | * Base structure 17 | */ 18 | 19 | body { 20 | text-shadow: 0 .05rem .1rem rgba(0, 0, 0, .5); 21 | box-shadow: inset 0 0 5rem rgba(0, 0, 0, .5); 22 | } 23 | 24 | .cover-container { 25 | max-width: 42em; 26 | } 27 | 28 | 29 | /* 30 | * Header 31 | */ 32 | 33 | .nav-masthead .nav-link { 34 | color: rgba(255, 255, 255, .5); 35 | border-bottom: .25rem solid transparent; 36 | } 37 | 38 | .nav-masthead .nav-link:hover, 39 | .nav-masthead .nav-link:focus { 40 | border-bottom-color: rgba(255, 255, 255, .25); 41 | } 42 | 43 | .nav-masthead .nav-link + .nav-link { 44 | margin-left: 1rem; 45 | } 46 | 47 | .nav-masthead .active { 48 | color: #fff; 49 | border-bottom-color: #fff; 50 | } 51 | -------------------------------------------------------------------------------- /site/src/assets/examples/dashboard-rtl/dashboard.js: -------------------------------------------------------------------------------- 1 | /* globals Chart:false */ 2 | 3 | (() => { 4 | 'use strict' 5 | 6 | // Graphs 7 | const ctx = document.getElementById('myChart') 8 | new Chart(ctx, { 9 | type: 'line', 10 | data: { 11 | labels: [ 12 | 'الأحد', 13 | 'الإثنين', 14 | 'الثلاثاء', 15 | 'الأربعاء', 16 | 'الخميس', 17 | 'الجمعة', 18 | 'السبت' 19 | ], 20 | datasets: [{ 21 | data: [ 22 | 15339, 23 | 21345, 24 | 18483, 25 | 24003, 26 | 23489, 27 | 24092, 28 | 12034 29 | ], 30 | lineTension: 0, 31 | backgroundColor: 'transparent', 32 | borderColor: '#007bff', 33 | borderWidth: 4, 34 | pointBackgroundColor: '#007bff' 35 | }] 36 | }, 37 | options: { 38 | plugins: { 39 | legend: { 40 | display: false 41 | }, 42 | tooltip: { 43 | boxPadding: 3 44 | } 45 | } 46 | } 47 | }) 48 | })() 49 | -------------------------------------------------------------------------------- /site/src/assets/examples/dashboard/dashboard.css: -------------------------------------------------------------------------------- 1 | .bi { 2 | display: inline-block; 3 | width: 1rem; 4 | height: 1rem; 5 | } 6 | 7 | /* 8 | * Sidebar 9 | */ 10 | 11 | @media (min-width: 768px) { 12 | .sidebar .offcanvas-lg { 13 | position: -webkit-sticky; 14 | position: sticky; 15 | top: 48px; 16 | } 17 | .navbar-search { 18 | display: block; 19 | } 20 | } 21 | 22 | .sidebar .nav-link { 23 | font-size: .875rem; 24 | font-weight: 500; 25 | } 26 | 27 | .sidebar .nav-link.active { 28 | color: #2470dc; 29 | } 30 | 31 | .sidebar-heading { 32 | font-size: .75rem; 33 | } 34 | 35 | /* 36 | * Navbar 37 | */ 38 | 39 | .navbar-brand { 40 | padding-top: .75rem; 41 | padding-bottom: .75rem; 42 | background-color: rgba(0, 0, 0, .25); 43 | box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25); 44 | } 45 | 46 | .navbar .form-control { 47 | padding: .75rem 1rem; 48 | } 49 | -------------------------------------------------------------------------------- /site/src/assets/examples/dashboard/dashboard.js: -------------------------------------------------------------------------------- 1 | /* globals Chart:false */ 2 | 3 | (() => { 4 | 'use strict' 5 | 6 | // Graphs 7 | const ctx = document.getElementById('myChart') 8 | new Chart(ctx, { 9 | type: 'line', 10 | data: { 11 | labels: [ 12 | 'Sunday', 13 | 'Monday', 14 | 'Tuesday', 15 | 'Wednesday', 16 | 'Thursday', 17 | 'Friday', 18 | 'Saturday' 19 | ], 20 | datasets: [{ 21 | data: [ 22 | 15339, 23 | 21345, 24 | 18483, 25 | 24003, 26 | 23489, 27 | 24092, 28 | 12034 29 | ], 30 | lineTension: 0, 31 | backgroundColor: 'transparent', 32 | borderColor: '#007bff', 33 | borderWidth: 4, 34 | pointBackgroundColor: '#007bff' 35 | }] 36 | }, 37 | options: { 38 | plugins: { 39 | legend: { 40 | display: false 41 | }, 42 | tooltip: { 43 | boxPadding: 3 44 | } 45 | } 46 | } 47 | }) 48 | })() 49 | -------------------------------------------------------------------------------- /site/src/assets/examples/dashboard/dashboard.rtl.css: -------------------------------------------------------------------------------- 1 | .bi { 2 | display: inline-block; 3 | width: 1rem; 4 | height: 1rem; 5 | } 6 | 7 | /* 8 | * Sidebar 9 | */ 10 | 11 | @media (min-width: 768px) { 12 | .sidebar .offcanvas-lg { 13 | position: -webkit-sticky; 14 | position: sticky; 15 | top: 48px; 16 | } 17 | .navbar-search { 18 | display: block; 19 | } 20 | } 21 | 22 | .sidebar .nav-link { 23 | font-size: .875rem; 24 | font-weight: 500; 25 | } 26 | 27 | .sidebar .nav-link.active { 28 | color: #2470dc; 29 | } 30 | 31 | .sidebar-heading { 32 | font-size: .75rem; 33 | } 34 | 35 | /* 36 | * Navbar 37 | */ 38 | 39 | .navbar-brand { 40 | padding-top: .75rem; 41 | padding-bottom: .75rem; 42 | background-color: rgba(0, 0, 0, .25); 43 | box-shadow: inset 1px 0 0 rgba(0, 0, 0, .25); 44 | } 45 | 46 | .navbar .form-control { 47 | padding: .75rem 1rem; 48 | } 49 | -------------------------------------------------------------------------------- /site/src/assets/examples/features/features.css: -------------------------------------------------------------------------------- 1 | .feature-icon { 2 | width: 4rem; 3 | height: 4rem; 4 | border-radius: .75rem; 5 | } 6 | 7 | .icon-square { 8 | width: 3rem; 9 | height: 3rem; 10 | border-radius: .75rem; 11 | } 12 | 13 | .text-shadow-1 { text-shadow: 0 .125rem .25rem rgba(0, 0, 0, .25); } 14 | .text-shadow-2 { text-shadow: 0 .25rem .5rem rgba(0, 0, 0, .25); } 15 | .text-shadow-3 { text-shadow: 0 .5rem 1.5rem rgba(0, 0, 0, .25); } 16 | 17 | .card-cover { 18 | background-repeat: no-repeat; 19 | background-position: center center; 20 | background-size: cover; 21 | } 22 | 23 | .feature-icon-small { 24 | width: 3rem; 25 | height: 3rem; 26 | } 27 | -------------------------------------------------------------------------------- /site/src/assets/examples/features/unsplash-photo-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/src/assets/examples/features/unsplash-photo-1.jpg -------------------------------------------------------------------------------- /site/src/assets/examples/features/unsplash-photo-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/src/assets/examples/features/unsplash-photo-2.jpg -------------------------------------------------------------------------------- /site/src/assets/examples/features/unsplash-photo-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/src/assets/examples/features/unsplash-photo-3.jpg -------------------------------------------------------------------------------- /site/src/assets/examples/grid/grid.css: -------------------------------------------------------------------------------- 1 | .themed-grid-col { 2 | padding-top: .75rem; 3 | padding-bottom: .75rem; 4 | background-color: rgba(112.520718, 44.062154, 249.437846, .15); 5 | border: 1px solid rgba(112.520718, 44.062154, 249.437846, .3); 6 | } 7 | 8 | .themed-container { 9 | padding: .75rem; 10 | margin-bottom: 1.5rem; 11 | background-color: rgba(112.520718, 44.062154, 249.437846, .15); 12 | border: 1px solid rgba(112.520718, 44.062154, 249.437846, .3); 13 | } 14 | -------------------------------------------------------------------------------- /site/src/assets/examples/headers/headers.css: -------------------------------------------------------------------------------- 1 | .form-control-dark { 2 | border-color: var(--bs-gray); 3 | } 4 | .form-control-dark:focus { 5 | border-color: #fff; 6 | box-shadow: 0 0 0 .25rem rgba(255, 255, 255, .25); 7 | } 8 | 9 | .text-small { 10 | font-size: 85%; 11 | } 12 | 13 | .dropdown-toggle:not(:focus) { 14 | outline: 0; 15 | } 16 | -------------------------------------------------------------------------------- /site/src/assets/examples/heroes/bootstrap-docs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/src/assets/examples/heroes/bootstrap-docs.png -------------------------------------------------------------------------------- /site/src/assets/examples/heroes/bootstrap-themes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/src/assets/examples/heroes/bootstrap-themes.png -------------------------------------------------------------------------------- /site/src/assets/examples/heroes/heroes.css: -------------------------------------------------------------------------------- 1 | @media (min-width: 992px) { 2 | .rounded-lg-3 { border-radius: .3rem; } 3 | } 4 | -------------------------------------------------------------------------------- /site/src/assets/examples/jumbotrons/jumbotrons.css: -------------------------------------------------------------------------------- 1 | .border-dashed { --bs-border-style: dashed; } 2 | -------------------------------------------------------------------------------- /site/src/assets/examples/modals/modals.css: -------------------------------------------------------------------------------- 1 | .modal-sheet .modal-dialog { 2 | width: 380px; 3 | transition: bottom .75s ease-in-out; 4 | } 5 | .modal-sheet .modal-footer { 6 | padding-bottom: 2rem; 7 | } 8 | -------------------------------------------------------------------------------- /site/src/assets/examples/navbar-fixed/navbar-fixed.css: -------------------------------------------------------------------------------- 1 | /* Show it is fixed to the top */ 2 | body { 3 | min-height: 75rem; 4 | padding-top: 4.5rem; 5 | } 6 | -------------------------------------------------------------------------------- /site/src/assets/examples/navbar-static/navbar-static.css: -------------------------------------------------------------------------------- 1 | /* Show it's not fixed to the top */ 2 | body { 3 | min-height: 75rem; 4 | } 5 | -------------------------------------------------------------------------------- /site/src/assets/examples/navbars-offcanvas/navbars-offcanvas.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-bottom: 20px; 3 | } 4 | 5 | .navbar { 6 | margin-bottom: 20px; 7 | } 8 | -------------------------------------------------------------------------------- /site/src/assets/examples/navbars/navbars.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-bottom: 20px; 3 | } 4 | 5 | .navbar { 6 | margin-bottom: 20px; 7 | } 8 | -------------------------------------------------------------------------------- /site/src/assets/examples/offcanvas-navbar/offcanvas-navbar.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | overflow-x: hidden; /* Prevent scroll on narrow devices */ 4 | } 5 | 6 | body { 7 | padding-top: 56px; 8 | } 9 | 10 | @media (max-width: 991.98px) { 11 | .offcanvas-collapse { 12 | position: fixed; 13 | top: 56px; /* Height of navbar */ 14 | bottom: 0; 15 | left: 100%; 16 | width: 100%; 17 | padding-right: 1rem; 18 | padding-left: 1rem; 19 | overflow-y: auto; 20 | visibility: hidden; 21 | background-color: #343a40; 22 | transition: transform .3s ease-in-out, visibility .3s ease-in-out; 23 | } 24 | .offcanvas-collapse.open { 25 | visibility: visible; 26 | transform: translateX(-100%); 27 | } 28 | } 29 | 30 | .nav-scroller .nav { 31 | color: rgba(255, 255, 255, .75); 32 | } 33 | 34 | .nav-scroller .nav-link { 35 | padding-top: .75rem; 36 | padding-bottom: .75rem; 37 | font-size: .875rem; 38 | color: #6c757d; 39 | } 40 | 41 | .nav-scroller .nav-link:hover { 42 | color: #007bff; 43 | } 44 | 45 | .nav-scroller .active { 46 | font-weight: 500; 47 | color: #343a40; 48 | } 49 | 50 | .bg-purple { 51 | background-color: #6f42c1; 52 | } 53 | -------------------------------------------------------------------------------- /site/src/assets/examples/offcanvas-navbar/offcanvas-navbar.js: -------------------------------------------------------------------------------- 1 | (() => { 2 | 'use strict' 3 | 4 | document.querySelector('#navbarSideCollapse').addEventListener('click', () => { 5 | document.querySelector('.offcanvas-collapse').classList.toggle('open') 6 | }) 7 | })() 8 | -------------------------------------------------------------------------------- /site/src/assets/examples/pricing/pricing.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-image: linear-gradient(180deg, var(--bs-secondary-bg), var(--bs-body-bg) 100px, var(--bs-body-bg)); 3 | } 4 | 5 | .container { 6 | max-width: 960px; 7 | } 8 | 9 | .pricing-header { 10 | max-width: 700px; 11 | } 12 | -------------------------------------------------------------------------------- /site/src/assets/examples/sidebars/sidebars.js: -------------------------------------------------------------------------------- 1 | /* global bootstrap: false */ 2 | (() => { 3 | 'use strict' 4 | const tooltipTriggerList = Array.from(document.querySelectorAll('[data-bs-toggle="tooltip"]')) 5 | tooltipTriggerList.forEach(tooltipTriggerEl => { 6 | new bootstrap.Tooltip(tooltipTriggerEl) 7 | }) 8 | })() 9 | -------------------------------------------------------------------------------- /site/src/assets/examples/sign-in/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getVersionedDocsPath } from '@libs/path' 3 | 4 | export const title = 'Signin Template' 5 | export const extra_css = ['sign-in.css'] 6 | export const body_class = 'd-flex align-items-center py-4 bg-body-tertiary' 7 | --- 8 | 9 |
10 |
11 | 12 |

Please sign in

13 | 14 |
15 | 16 | 17 |
18 |
19 | 20 | 21 |
22 | 23 |
24 | 25 | 28 |
29 | 30 |

© 2017–{new Date().getFullYear()}

31 |
32 |
33 | -------------------------------------------------------------------------------- /site/src/assets/examples/sign-in/sign-in.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | height: 100%; 4 | } 5 | 6 | .form-signin { 7 | max-width: 330px; 8 | padding: 1rem; 9 | } 10 | 11 | .form-signin .form-floating:focus-within { 12 | z-index: 2; 13 | } 14 | 15 | .form-signin input[type="email"] { 16 | margin-bottom: -1px; 17 | border-bottom-right-radius: 0; 18 | border-bottom-left-radius: 0; 19 | } 20 | 21 | .form-signin input[type="password"] { 22 | margin-bottom: 10px; 23 | border-top-left-radius: 0; 24 | border-top-right-radius: 0; 25 | } 26 | -------------------------------------------------------------------------------- /site/src/assets/examples/sticky-footer-navbar/sticky-footer-navbar.css: -------------------------------------------------------------------------------- 1 | /* Custom page CSS 2 | -------------------------------------------------- */ 3 | /* Not required for template or sticky footer method. */ 4 | 5 | main > .container { 6 | padding: 60px 15px 0; 7 | } 8 | -------------------------------------------------------------------------------- /site/src/assets/examples/sticky-footer/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getVersionedDocsPath } from '@libs/path' 3 | 4 | export const title = 'Sticky Footer Template' 5 | export const extra_css = ['sticky-footer.css'] 6 | export const html_class = 'h-100' 7 | export const body_class = 'd-flex flex-column h-100' 8 | --- 9 | 10 | 11 |
12 |
13 |

Sticky footer

14 |

Pin a footer to the bottom of the viewport in desktop browsers with this custom HTML and CSS.

15 |

Use the sticky footer with a fixed navbar if need be, too.

16 |
17 |
18 | 19 |
20 |
21 | Place sticky footer content here. 22 |
23 |
24 | -------------------------------------------------------------------------------- /site/src/assets/examples/sticky-footer/sticky-footer.css: -------------------------------------------------------------------------------- 1 | /* Custom page CSS 2 | -------------------------------------------------- */ 3 | /* Not required for template or sticky footer method. */ 4 | 5 | .container { 6 | width: auto; 7 | max-width: 680px; 8 | padding: 0 15px; 9 | } 10 | -------------------------------------------------------------------------------- /site/src/assets/partials/sidebar.js: -------------------------------------------------------------------------------- 1 | // NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT 2 | // IT'S ALL JUST JUNK FOR OUR DOCS! 3 | // ++++++++++++++++++++++++++++++++++++++++++ 4 | 5 | /* 6 | * JavaScript for Bootstrap's docs (https://getbootstrap.com/) 7 | * Copyright 2011-2025 The Bootstrap Authors 8 | * Licensed under the Creative Commons Attribution 3.0 Unported License. 9 | * For details, see https://creativecommons.org/licenses/by/3.0/. 10 | */ 11 | 12 | export default () => { 13 | // Scroll the active sidebar link into view 14 | const sidenav = document.querySelector('.bd-sidebar') 15 | const sidenavActiveLink = document.querySelector('.bd-links-nav .active') 16 | 17 | if (!sidenav || !sidenavActiveLink) { 18 | return 19 | } 20 | 21 | const sidenavHeight = sidenav.clientHeight 22 | const sidenavActiveLinkTop = sidenavActiveLink.offsetTop 23 | const sidenavActiveLinkHeight = sidenavActiveLink.clientHeight 24 | const viewportTop = sidenavActiveLinkTop 25 | const viewportBottom = viewportTop - sidenavHeight + sidenavActiveLinkHeight 26 | 27 | if (sidenav.scrollTop > viewportTop || sidenav.scrollTop < viewportBottom) { 28 | sidenav.scrollTop = viewportTop - (sidenavHeight / 2) + (sidenavActiveLinkHeight / 2) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /site/src/assets/snippets.js: -------------------------------------------------------------------------------- 1 | /* 2 | * JavaScript for Bootstrap's docs (https://getbootstrap.com/) 3 | * Copyright 2011-2025 The Bootstrap Authors 4 | * Licensed under the Creative Commons Attribution 3.0 Unported License. 5 | * For details, see https://creativecommons.org/licenses/by/3.0/. 6 | */ 7 | 8 | // Note that this file is not published; we only include it in scripts.html 9 | // for StackBlitz to work 10 | 11 | /* eslint-disable import/no-unresolved */ 12 | import snippets from 'js/partials/snippets.js' 13 | /* eslint-enable import/no-unresolved */ 14 | 15 | snippets() 16 | -------------------------------------------------------------------------------- /site/src/components/Ads.astro: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | 10 | -------------------------------------------------------------------------------- /site/src/components/DocsScripts.astro: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | 5 | -------------------------------------------------------------------------------- /site/src/components/Scripts.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getVersionedBsJsProps } from '@libs/bootstrap' 3 | import type { Layout } from '@libs/layout' 4 | import DocsScripts from './DocsScripts.astro' 5 | 6 | interface Props { 7 | layout: Layout 8 | } 9 | 10 | const { layout } = Astro.props 11 | --- 12 | 13 | 14 | 15 | 16 | 17 | 18 | {layout === 'docs' && } 19 | -------------------------------------------------------------------------------- /site/src/components/TableOfContents.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { MarkdownHeading } from 'astro' 3 | import { generateToc, type TocEntry } from '@libs/toc' 4 | 5 | interface Props { 6 | headings?: MarkdownHeading[] 7 | entries?: TocEntry[] 8 | } 9 | 10 | const { entries, headings } = Astro.props 11 | 12 | const toc = entries ? entries : generateToc(headings ?? []) 13 | --- 14 | 15 |
    16 | { 17 | toc.map(({ children, slug, text }) => { 18 | return ( 19 |
  • 20 | {text} 21 | {children.length > 0 && } 22 |
  • 23 | ) 24 | }) 25 | } 26 |
27 | -------------------------------------------------------------------------------- /site/src/components/head/Analytics.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getConfig } from '@libs/config' 3 | --- 4 | 5 | 7 | -------------------------------------------------------------------------------- /site/src/components/head/Favicons.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getVersionedDocsPath } from '@libs/path' 3 | --- 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /site/src/components/head/Scss.astro: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | 8 | -------------------------------------------------------------------------------- /site/src/components/head/Social.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getConfig } from '@libs/config' 3 | import { getVersionedDocsPath } from '@libs/path' 4 | import { getStaticImageSize } from '@libs/image' 5 | import type { Layout } from '@libs/layout' 6 | 7 | interface Props { 8 | description: string 9 | layout: Layout 10 | thumbnail: string 11 | title: string 12 | } 13 | 14 | const { description, layout, thumbnail, title } = Astro.props 15 | 16 | const socialImageUrl = new URL(getVersionedDocsPath(`assets/${thumbnail}`), Astro.site) 17 | const socialImageSize = await getStaticImageSize(`/docs/[version]/assets/${thumbnail}`) 18 | --- 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /site/src/components/head/Stylesheet.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getVersionedBsCssProps } from '@libs/bootstrap' 3 | import type { Layout } from '@libs/layout' 4 | 5 | interface Props { 6 | direction?: 'rtl' 7 | layout: Layout 8 | } 9 | 10 | const { direction } = Astro.props 11 | --- 12 | 13 | 14 | -------------------------------------------------------------------------------- /site/src/components/header/Header.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { CollectionEntry } from 'astro:content' 3 | import type { Layout } from '@libs/layout' 4 | import Skippy from '@components/header/Skippy.astro' 5 | import Symbols from '@components/icons/Symbols.astro' 6 | import Navigation from '@components/header/Navigation.astro' 7 | 8 | interface Props { 9 | addedIn?: CollectionEntry<'docs'>['data']['added'] 10 | layout: Layout 11 | title: string 12 | } 13 | 14 | const { addedIn, layout, title } = Astro.props 15 | --- 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /site/src/components/header/LinkItem.astro: -------------------------------------------------------------------------------- 1 | --- 2 | interface Props { 3 | active?: boolean 4 | class?: string 5 | href: string 6 | rel?: HTMLAnchorElement['rel'] 7 | target?: HTMLAnchorElement['target'] 8 | track?: boolean 9 | } 10 | 11 | const { active, class: className, track, ...props } = Astro.props 12 | 13 | const content = await Astro.slots.render('default') 14 | --- 15 | 16 | 25 | -------------------------------------------------------------------------------- /site/src/components/header/Skippy.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { Layout } from '@libs/layout' 3 | 4 | interface Props { 5 | layout: Layout 6 | } 7 | 8 | const { layout } = Astro.props 9 | --- 10 | 11 |
12 |
13 | Skip to main content 14 | { 15 | layout === 'docs' && ( 16 | 17 | Skip to docs navigation 18 | 19 | ) 20 | } 21 |
22 |
23 | -------------------------------------------------------------------------------- /site/src/components/icons/BootstrapWhiteFillIcon.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { SvgIconProps } from '@libs/icon' 3 | 4 | type Props = SvgIconProps 5 | 6 | const { class: className, height, width } = Astro.props 7 | --- 8 | 9 | 10 | Bootstrap 11 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /site/src/components/icons/CircleSquareIcon.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { SvgIconProps } from '@libs/icon' 3 | 4 | type Props = SvgIconProps 5 | 6 | const { class: className, height, width } = Astro.props 7 | --- 8 | 9 | 24 | -------------------------------------------------------------------------------- /site/src/components/icons/DropletFillIcon.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { SvgIconProps } from '@libs/icon' 3 | 4 | type Props = SvgIconProps 5 | 6 | const { class: className, height, width } = Astro.props 7 | --- 8 | 9 | 25 | -------------------------------------------------------------------------------- /site/src/components/icons/GitHubIcon.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { SvgIconProps } from '@libs/icon' 3 | 4 | type Props = SvgIconProps 5 | 6 | const { class: className, height, width } = Astro.props 7 | --- 8 | 9 | 17 | GitHub 18 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /site/src/components/icons/HamburgerIcon.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { SvgIconProps } from '@libs/icon' 3 | 4 | type Props = SvgIconProps 5 | 6 | const { class: className, height, width } = Astro.props 7 | --- 8 | 9 | 24 | -------------------------------------------------------------------------------- /site/src/components/icons/OpenCollectiveIcon.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { SvgIconProps } from '@libs/icon' 3 | 4 | type Props = SvgIconProps 5 | 6 | const { class: className, height, width } = Astro.props 7 | --- 8 | 9 | 19 | Open Collective 20 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /site/src/components/icons/XIcon.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { SvgIconProps } from '@libs/icon' 3 | 4 | type Props = SvgIconProps 5 | 6 | const { class: className, height, width } = Astro.props 7 | --- 8 | 9 | 17 | X 18 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /site/src/components/shortcodes/AddedIn.astro: -------------------------------------------------------------------------------- 1 | --- 2 | /* 3 | * Outputs badge to identify the first version something was added 4 | */ 5 | 6 | interface Props { 7 | version: string 8 | } 9 | 10 | const { version } = Astro.props 11 | --- 12 | 13 | Added in v{version} 17 | -------------------------------------------------------------------------------- /site/src/components/shortcodes/BsTable.astro: -------------------------------------------------------------------------------- 1 | --- 2 | interface Props { 3 | /** 4 | * The CSS class to apply to the table. 5 | * Note that the prop is not used in this component, but in a rehype plugin applying the classes to the table element 6 | * directly on the HTML AST (HAST) generated by Astro. 7 | * @default "table" 8 | * @see src/libs/rehype.ts 9 | */ 10 | class?: string 11 | } 12 | --- 13 | 14 |
15 | 16 |
17 | -------------------------------------------------------------------------------- /site/src/components/shortcodes/Callout.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getCalloutByName } from '@libs/content' 3 | import type { MarkdownInstance } from 'astro' 4 | 5 | interface Props { 6 | /** 7 | * The name of an existing callout to display located in `src/content/callouts`. 8 | * This will override any content passed in via the default slot. 9 | */ 10 | name?: 11 | | 'danger-async-methods' 12 | | 'info-mediaqueries-breakpoints' 13 | | 'info-npm-starter' 14 | | 'info-prefersreducedmotion' 15 | | 'info-sanitizer' 16 | | 'warning-color-assistive-technologies' 17 | | 'warning-data-bs-title-vs-title' 18 | | 'warning-input-support' 19 | /** 20 | * The type of callout to display. One of `info`, `danger`, or `warning`. 21 | * @default 'info' 22 | */ 23 | type?: 'danger' | 'info' | 'warning' 24 | } 25 | 26 | const { name, type = 'info' } = Astro.props 27 | 28 | let Content: MarkdownInstance<{}>['Content'] | undefined 29 | 30 | if (name) { 31 | const callout = await getCalloutByName(name) 32 | 33 | if (!callout) { 34 | throw new Error(`Could not find callout with name '${name}'.`) 35 | } 36 | 37 | const namedCallout = await callout.render() 38 | Content = namedCallout.Content 39 | } 40 | --- 41 | 42 |
43 | {Content ? : } 44 |
45 | -------------------------------------------------------------------------------- /site/src/components/shortcodes/CalloutDeprecatedDarkVariants.astro: -------------------------------------------------------------------------------- 1 | --- 2 | /* 3 | * Outputs message about dark mode component variants being deprecated in v5.3. 4 | */ 5 | 6 | interface Props { 7 | component: string 8 | } 9 | 10 | const { component } = Astro.props 11 | --- 12 | 13 |
14 |

15 | Heads up! Dark variants for components were deprecated in v5.3.0 with the introduction of color modes. 16 | Instead of adding .{component}-dark, set data-bs-theme="dark" on the root element, a parent 17 | wrapper, or the component itself. 18 |

19 |
20 | -------------------------------------------------------------------------------- /site/src/components/shortcodes/DeprecatedIn.astro: -------------------------------------------------------------------------------- 1 | --- 2 | /* 3 | * Outputs badge to identify the version something was deprecated 4 | */ 5 | 6 | interface Props { 7 | version: string 8 | } 9 | 10 | const { version } = Astro.props 11 | --- 12 | 13 | 16 | Deprecated in v{version} 17 | 18 | -------------------------------------------------------------------------------- /site/src/components/shortcodes/GuideFooter.mdx: -------------------------------------------------------------------------------- 1 |
2 | 3 | _See something wrong or out of date here? Please [open an issue on GitHub]([[config:repo]]/issues/new/choose). Need help troubleshooting? [Search or start a discussion]([[config:repo]]/discussions) on GitHub._ 4 | -------------------------------------------------------------------------------- /site/src/components/shortcodes/JsDataAttributes.mdx: -------------------------------------------------------------------------------- 1 | As options can be passed via data attributes or JavaScript, you can append an option name to `data-bs-`, as in `data-bs-animation="{value}"`. Make sure to change the case type of the option name from “_camelCase_” to “_kebab-case_” when passing the options via data attributes. For example, use `data-bs-custom-class="beautifier"` instead of `data-bs-customClass="beautifier"`. 2 | 3 | As of Bootstrap 5.2.0, all components support an **experimental** reserved data attribute `data-bs-config` that can house simple component configuration as a JSON string. When an element has `data-bs-config='{"delay":0, "title":123}'` and `data-bs-title="456"` attributes, the final `title` value will be `456` and the separate data attributes will override values given on `data-bs-config`. In addition, existing data attributes are able to house JSON values like `data-bs-delay='{"show":0,"hide":150}'`. 4 | 5 | The final configuration object is the merged result of `data-bs-config`, `data-bs-`, and `js object` where the latest given key-value overrides the others. 6 | -------------------------------------------------------------------------------- /site/src/components/shortcodes/JsDismiss.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Code from '@shortcodes/Code.astro' 3 | 4 | interface Props { 5 | name: string 6 | } 7 | 8 | const { name } = Astro.props 9 | --- 10 | 11 |

12 | Dismissal can be achieved with the data-bs-dismiss attribute on a button within the {name} as demonstrated below: 15 |

16 | 17 | `} 19 | lang="html" 20 | /> 21 | 22 |

23 | or on a button outside the {name} using the additional data-bs-target as demonstrated below: 24 |

25 | 26 | `} 28 | lang="html" 29 | /> 30 | -------------------------------------------------------------------------------- /site/src/components/shortcodes/Placeholder.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getPlaceholder, type PlaceholderOptions } from '@libs/placeholder' 3 | 4 | type Props = Partial 5 | 6 | const { 7 | options: { background, color, showText, showTitle, text, title }, 8 | props, 9 | type 10 | } = getPlaceholder(Astro.props) 11 | --- 12 | 13 | { 14 | type === 'img' ? ( 15 | 16 | ) : ( 17 | 18 | {showTitle && {title}} 19 | 20 | {showText && ( 21 | 22 | {text} 23 | 24 | )} 25 | 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /site/src/components/shortcodes/Table.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Code from '@shortcodes/Code.astro' 3 | import * as tableContent from '@shortcodes/TableContent.md' 4 | 5 | interface Props { 6 | /** 7 | * Any class(es) to be added to the `` element (both in the example and code snippet). 8 | */ 9 | class?: string 10 | /** 11 | * Show a simplified version in the example code snippet by replacing the table content inside `
` & `
` 12 | * with `...`. 13 | * @default true 14 | */ 15 | simplified?: boolean 16 | } 17 | 18 | const { class: className, simplified = true } = Astro.props 19 | 20 | const tableCode = ` 21 | ${simplified ? ' ...' : await tableContent.compiledContent()} 22 | ` 23 | --- 24 | 25 |
26 | 27 | 28 |
29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /site/src/components/shortcodes/TableContent.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 4 | First 5 | Last 6 | Handle 7 | 8 | 9 | 10 | 11 | 1 12 | Mark 13 | Otto 14 | @mdo 15 | 16 | 17 | 2 18 | Jacob 19 | Thornton 20 | @fat 21 | 22 | 23 | 3 24 | John 25 | Doe 26 | @social 27 | 28 | 29 | -------------------------------------------------------------------------------- /site/src/content/callouts/danger-async-methods.md: -------------------------------------------------------------------------------- 1 | **All API methods are asynchronous and start a transition.** They return to the caller as soon as the transition is started, but before it ends. In addition, a method call on a transitioning component will be ignored. [Learn more in our JavaScript docs.](/docs/[[config:docs_version]]/getting-started/javascript/#asynchronous-functions-and-transitions) 2 | -------------------------------------------------------------------------------- /site/src/content/callouts/info-mediaqueries-breakpoints.md: -------------------------------------------------------------------------------- 1 | **Why subtract .02px?** Browsers don’t currently support [range context queries](https://www.w3.org/TR/mediaqueries-4/#range-context), so we work around the limitations of [`min-` and `max-` prefixes](https://www.w3.org/TR/mediaqueries-4/#mq-min-max) and viewports with fractional widths (which can occur under certain conditions on high-dpi devices, for instance) by using values with higher precision. 2 | -------------------------------------------------------------------------------- /site/src/content/callouts/info-npm-starter.md: -------------------------------------------------------------------------------- 1 | **Get started with Bootstrap via npm with our starter project!** Head to the [Sass & JS example](https://github.com/twbs/examples/tree/main/sass-js) template repository to see how to build and customize Bootstrap in your own npm project. Includes Sass compiler, Autoprefixer, Stylelint, PurgeCSS, and Bootstrap Icons. 2 | -------------------------------------------------------------------------------- /site/src/content/callouts/info-prefersreducedmotion.md: -------------------------------------------------------------------------------- 1 | The animation effect of this component is dependent on the `prefers-reduced-motion` media query. See the [reduced motion section of our accessibility documentation](/docs/[[config:docs_version]]/getting-started/accessibility/#reduced-motion). 2 | -------------------------------------------------------------------------------- /site/src/content/callouts/info-sanitizer.md: -------------------------------------------------------------------------------- 1 | By default, this component uses the built-in content sanitizer, which strips out any HTML elements that are not explicitly allowed. See the [sanitizer section in our JavaScript documentation](/docs/[[config:docs_version]]/getting-started/javascript/#sanitizer) for more details. 2 | -------------------------------------------------------------------------------- /site/src/content/callouts/warning-color-assistive-technologies.md: -------------------------------------------------------------------------------- 1 | **Accessibility tip:** Using color to add meaning only provides a visual indication, which will not be conveyed to users of assistive technologies like screen readers. Please ensure the meaning is obvious from the content itself (e.g., the visible text with a [_sufficient_ color contrast](/docs/[[config:docs_version]]/getting-started/accessibility/#color-contrast)) or is included through alternative means, such as additional text hidden with the `.visually-hidden` class. 2 | -------------------------------------------------------------------------------- /site/src/content/callouts/warning-data-bs-title-vs-title.md: -------------------------------------------------------------------------------- 1 | Feel free to use either `title` or `data-bs-title` in your HTML. When `title` is used, Popper will replace it automatically with `data-bs-title` when the element is rendered. 2 | -------------------------------------------------------------------------------- /site/src/content/callouts/warning-input-support.md: -------------------------------------------------------------------------------- 1 | Some date inputs types are [not fully supported](https://caniuse.com/input-datetime) by the latest versions of Safari and Firefox. 2 | -------------------------------------------------------------------------------- /site/src/content/config.ts: -------------------------------------------------------------------------------- 1 | import { z, defineCollection } from 'astro:content' 2 | 3 | const docsSchema = z.object({ 4 | added: z 5 | .object({ 6 | show_badge: z.boolean().optional(), 7 | version: z.string() 8 | }) 9 | .optional(), 10 | aliases: z.string().or(z.string().array()).optional(), 11 | description: z.string(), 12 | direction: z.literal('rtl').optional(), 13 | extra_js: z 14 | .object({ 15 | async: z.boolean().optional(), 16 | src: z.string() 17 | }) 18 | .array() 19 | .optional(), 20 | sections: z 21 | .object({ 22 | description: z.string(), 23 | title: z.string() 24 | }) 25 | .array() 26 | .optional(), 27 | thumbnail: z.string().optional(), 28 | title: z.string(), 29 | toc: z.boolean().optional() 30 | }) 31 | 32 | const docsCollection = defineCollection({ 33 | schema: docsSchema 34 | }) 35 | 36 | const calloutsSchema = z.object({}) 37 | 38 | const calloutsCollection = defineCollection({ 39 | schema: calloutsSchema 40 | }) 41 | 42 | export const collections = { 43 | docs: docsCollection, 44 | callouts: calloutsCollection 45 | } 46 | -------------------------------------------------------------------------------- /site/src/content/docs/about/team.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Team 3 | description: An overview of the founding team and core contributors to Bootstrap. 4 | --- 5 | 6 | import { getData } from '@libs/data' 7 | 8 | Bootstrap is maintained by the founding team and a small group of invaluable core contributors, with the massive support and involvement of our community. 9 | 10 |
11 | {getData('core-team').map((member) => { 12 | return ( 13 | 14 | {`@${member.user}`} 15 | 16 | {member.name} @{member.user} 17 | 18 | 19 | ) 20 | })} 21 |
22 | 23 | Get involved with Bootstrap development by [opening an issue]([[config:repo]]/issues/new/choose) or submitting a pull request. Read our [contributing guidelines]([[config:repo]]/blob/v[[config:current_version]]/.github/CONTRIBUTING.md) for information on how we develop. 24 | -------------------------------------------------------------------------------- /site/src/content/docs/about/translations.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Translations 3 | description: Links to community-translated Bootstrap documentation sites. 4 | --- 5 | 6 | import { getData } from '@libs/data' 7 | 8 | Community members have translated Bootstrap’s documentation into various languages. None are officially supported and they may not always be up-to-date. 9 | 10 | 17 | 18 | **We don’t help organize or host translations, we just link to them.** 19 | 20 | Finished a new or better translation? Open a pull request to add it to our list. 21 | -------------------------------------------------------------------------------- /site/src/content/docs/content/figures.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Figures 3 | description: Documentation and examples for displaying related images and text with the figure component in Bootstrap. 4 | toc: true 5 | --- 6 | 7 | Anytime you need to display a piece of content—like an image with an optional caption, consider using a `
`. 8 | 9 | Use the included `.figure`, `.figure-img` and `.figure-caption` classes to provide some baseline styles for the HTML5 `
` and `
` elements. Images in figures have no explicit size, so be sure to add the `.img-fluid` class to your `` to make it responsive. 10 | 11 | 12 | 13 |
A caption for the above image.
14 |
`} /> 15 | 16 | Aligning the figure’s caption is easy with our [text utilities]([[docsref:/utilities/text#text-alignment]]). 17 | 18 | 19 | 20 |
A caption for the above image.
21 |
`} /> 22 | 23 | ## CSS 24 | 25 | ### Sass variables 26 | 27 | 28 | -------------------------------------------------------------------------------- /site/src/content/docs/docsref.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Docs reference 3 | description: Examples of Bootstrap’s documentation-specific components and styles. 4 | aliases: "/docsref/" 5 | toc: true 6 | robots: noindex,follow 7 | --- 8 | 9 | ## Buttons 10 | 11 | 12 | 13 | 14 | 15 | ## Callouts 16 | 17 | 18 | Default callout 19 | 20 | 21 | 22 | Warning callout 23 | 24 | 25 | 26 | Danger callout 27 | 28 | 29 | ## Code example 30 | 31 | ```scss 32 | .test { 33 | --color: blue; 34 | } 35 | ``` 36 | 37 |
38 | The HTML abbreviation element. 39 |
40 | 41 | This is a test.`} /> 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /site/src/content/docs/getting-started/best-practices.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Best practices 3 | description: Learn about some of the best practices we’ve gathered from years of working on and using Bootstrap. 4 | --- 5 | 6 | We’ve designed and developed Bootstrap to work in a number of environments. Here are some of the best practices we’ve gathered from years of working on and using it ourselves. 7 | 8 | 9 | **Heads up!** This copy is a work in progress. 10 | 11 | 12 | ### General outline 13 | 14 | - Working with CSS 15 | - Working with Sass files 16 | - Building new CSS components 17 | - Working with flexbox 18 | - Ask in [our GitHub Discussions](https://github.com/twbs/bootstrap/discussions) 19 | -------------------------------------------------------------------------------- /site/src/content/docs/helpers/clearfix.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Clearfix 3 | description: Quickly and easily clear floated content within a container by adding a clearfix utility. 4 | aliases: "/docs/[[config:docs_version]]/helpers/" 5 | --- 6 | 7 | Easily clear `float`s by adding `.clearfix` **to the parent element**. Can also be used as a mixin. 8 | 9 | Use in HTML: 10 | 11 | ```html 12 |
...
13 | ``` 14 | 15 | The mixin source code: 16 | 17 | 18 | 19 | Use the mixin in SCSS: 20 | 21 | ```scss 22 | .element { 23 | @include clearfix; 24 | } 25 | ``` 26 | 27 | The following example shows how the clearfix can be used. Without the clearfix the wrapping div would not span around the buttons which would cause a broken layout. 28 | 29 | 30 | 31 | 32 | `} /> 33 | -------------------------------------------------------------------------------- /site/src/content/docs/helpers/text-truncation.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Text truncation 3 | description: Truncate long strings of text with an ellipsis. 4 | toc: false 5 | --- 6 | 7 | For longer content, you can add a `.text-truncate` class to truncate the text with an ellipsis. **Requires `display: inline-block` or `display: block`.** 8 | 9 | 10 |
11 |
12 | This text is quite long, and will be truncated once displayed. 13 |
14 |
15 | 16 | 17 | 18 | This text is quite long, and will be truncated once displayed. 19 | `} /> 20 | -------------------------------------------------------------------------------- /site/src/content/docs/helpers/vertical-rule.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Vertical rule 3 | description: Use the custom vertical rule helper to create vertical dividers like the `
` element. 4 | toc: true 5 | added: 6 | version: "5.1" 7 | --- 8 | 9 | ## How it works 10 | 11 | Vertical rules are inspired by the `
` element, allowing you to create vertical dividers in common layouts. They’re styled just like `
` elements: 12 | 13 | - They’re `1px` wide 14 | - They have `min-height` of `1em` 15 | - Their color is set via `currentColor` and `opacity` 16 | 17 | Customize them with additional styles as needed. 18 | 19 | ## Example 20 | 21 | `} /> 22 | 23 | Vertical rules scale their height in flex layouts: 24 | 25 | 26 |
27 | `} /> 28 | 29 | ## With stacks 30 | 31 | They can also be used in [stacks]([[docsref:/helpers/stacks]]): 32 | 33 | 34 |
First item
35 |
Second item
36 |
37 |
Third item
38 | `} /> 39 | 40 | ## CSS 41 | 42 | ### Sass variables 43 | 44 | Customize the vertical rule Sass variable to change its width. 45 | 46 | 47 | -------------------------------------------------------------------------------- /site/src/content/docs/helpers/visually-hidden.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Visually hidden 3 | description: Use these helpers to visually hide elements but keep them accessible to assistive technologies. 4 | aliases: "/docs/[[config:docs_version]]/helpers/screen-readers/" 5 | --- 6 | 7 | Visually hide an element while still allowing it to be exposed to assistive technologies (such as screen readers) with `.visually-hidden`. Use `.visually-hidden-focusable` to visually hide an element by default, but to display it when it’s focused (e.g. by a keyboard-only user). `.visually-hidden-focusable` can also be applied to a container–thanks to `:focus-within`, the container will be displayed when any child element of the container receives focus. 8 | 9 | Title for screen readers 10 | Skip to main content 11 |
A container with a focusable element.
`} /> 12 | 13 | Both `visually-hidden` and `visually-hidden-focusable` can also be used as mixins. 14 | 15 | ```scss 16 | // Usage as a mixin 17 | 18 | .visually-hidden-title { 19 | @include visually-hidden; 20 | } 21 | 22 | .skip-navigation { 23 | @include visually-hidden-focusable; 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /site/src/content/docs/layout/z-index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Z-index 3 | description: While not a part of Bootstrap’s grid system, z-indexes play an important part in how our components overlay and interact with one another. 4 | --- 5 | 6 | Several Bootstrap components utilize `z-index`, the CSS property that helps control layout by providing a third axis to arrange content. We utilize a default z-index scale in Bootstrap that’s been designed to properly layer navigation, tooltips and popovers, modals, and more. 7 | 8 | These higher values start at an arbitrary number, high and specific enough to ideally avoid conflicts. We need a standard set of these across our layered components—tooltips, popovers, navbars, dropdowns, modals—so we can be reasonably consistent in the behaviors. There’s no reason we couldn’t have used `100`+ or `500`+. 9 | 10 | We don’t encourage customization of these individual values; should you change one, you likely need to change them all. 11 | 12 | 13 | 14 | To handle overlapping borders within components (e.g., buttons and inputs in input groups), we use low single digit `z-index` values of `1`, `2`, and `3` for default, hover, and active states. On hover/focus/active, we bring a particular element to the forefront with a higher `z-index` value to show their border over the sibling elements. 15 | -------------------------------------------------------------------------------- /site/src/content/docs/utilities/shadows.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Shadows 3 | description: Add or remove shadows to elements with box-shadow utilities. 4 | toc: true 5 | --- 6 | 7 | ## Examples 8 | 9 | While shadows on components are disabled by default in Bootstrap and can be enabled via `$enable-shadows`, you can also quickly add or remove a shadow with our `box-shadow` utility classes. Includes support for `.shadow-none` and three default sizes (which have associated variables to match). 10 | 11 | No shadow 12 |
Small shadow
13 |
Regular shadow
14 |
Larger shadow
`} /> 15 | 16 | ## CSS 17 | 18 | ### Sass variables 19 | 20 | 21 | 22 | ### Sass utilities API 23 | 24 | Shadow utilities are declared in our utilities API in `scss/_utilities.scss`. [Learn how to use the utilities API.]([[docsref:/utilities/api#using-the-api]]) 25 | 26 | 27 | -------------------------------------------------------------------------------- /site/src/content/docs/utilities/visibility.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Visibility 3 | description: Control the visibility of elements, without modifying their display, with visibility utilities. 4 | --- 5 | 6 | Set the `visibility` of elements with our visibility utilities. These utility classes do not modify the `display` value at all and do not affect layout – `.invisible` elements still take up space in the page. 7 | 8 | 9 | Elements with the `.invisible` class will be hidden *both* visually and for assistive technology/screen reader users. 10 | 11 | 12 | Apply `.visible` or `.invisible` as needed. 13 | 14 | ```html 15 |
...
16 | 17 | ``` 18 | 19 | ```scss 20 | // Class 21 | .visible { 22 | visibility: visible !important; 23 | } 24 | .invisible { 25 | visibility: hidden !important; 26 | } 27 | ``` 28 | 29 | ## CSS 30 | 31 | ### Sass utilities API 32 | 33 | Visibility utilities are declared in our utilities API in `scss/_utilities.scss`. [Learn how to use the utilities API.]([[docsref:/utilities/api#using-the-api]]) 34 | 35 | 36 | -------------------------------------------------------------------------------- /site/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | interface ImportMetaEnv { 5 | readonly NETLIFY?: string 6 | } 7 | 8 | interface ImportMeta { 9 | readonly env: ImportMetaEnv 10 | } 11 | -------------------------------------------------------------------------------- /site/src/layouts/RedirectLayout.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getConfig } from '@libs/config' 3 | 4 | interface Props { 5 | path: string 6 | } 7 | 8 | const { path } = Astro.props 9 | 10 | const url = new URL(path, Astro.site) 11 | --- 12 | 13 | 14 | 15 | 16 | 17 | 18 | {getConfig().title} 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /site/src/layouts/SingleLayout.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Ads from '@components/Ads.astro' 3 | import BaseLayout from '@layouts/BaseLayout.astro' 4 | 5 | interface Props { 6 | description: string 7 | title: string 8 | } 9 | 10 | const { description, title } = Astro.props 11 | --- 12 | 13 | 14 | 15 |
16 |
17 |
18 |
19 |

{title}

20 |

{description}

21 | 22 |
23 |
24 | 25 |
26 |
27 |
28 |
29 | 30 |
31 |
32 | 33 | 34 |
35 |
36 |
37 |
38 | -------------------------------------------------------------------------------- /site/src/layouts/partials/BsThemes.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getConfig } from '@libs/config' 3 | import { getVersionedDocsPath } from '@libs/path' 4 | import DropletFillIcon from '@components/icons/DropletFillIcon.astro' 5 | import ResponsiveImage from '@layouts/partials/ResponsiveImage.astro' 6 | --- 7 | 8 |
9 |
10 |
11 |
12 | 13 |
14 |

Go further with Bootstrap Themes

15 |

16 | Need something more than these examples? Take Bootstrap to the next level with premium themes from the official Bootstrap Themes marketplace. They’re built as their own extended frameworks, rich with new components and plugins, documentation, and 19 | powerful build tools. 20 |

21 | Browse themes 22 |
23 | 30 |
31 | -------------------------------------------------------------------------------- /site/src/layouts/partials/ResponsiveImage.astro: -------------------------------------------------------------------------------- 1 | --- 2 | // TODO: This Astro component could be improved to implement the equivalent of Hugo's `imageConfig` 3 | // and calculate the width and height of the image automatically 4 | 5 | import { getVersionedDocsPath } from '@libs/path' 6 | 7 | interface Props { 8 | imgPath: string 9 | alt: string 10 | classes?: string 11 | lazyload?: boolean 12 | width?: number 13 | height?: number 14 | } 15 | 16 | const { imgPath, alt, classes = '', lazyload = true, width, height } = Astro.props 17 | 18 | const classNames = ['img-fluid', 'mx-auto', classes].filter(Boolean).join(' ') 19 | 20 | const basePath = getVersionedDocsPath(imgPath.split('/').slice(0, -1).join('/')) 21 | const basename = imgPath.split('/').pop()?.split('.')[0] || '' 22 | const ext = imgPath.includes('.') ? `.${imgPath.split('.').pop()}` : '' 23 | 24 | const imgPath1x = `${basePath}/${basename}${ext}` 25 | const imgPath2x = `${basePath}/${basename}@2x${ext}` 26 | --- 27 | 28 | {alt} 37 | -------------------------------------------------------------------------------- /site/src/libs/bootstrap.ts: -------------------------------------------------------------------------------- 1 | import type { HTMLAttributes } from 'astro/types' 2 | import { getConfig } from '@libs/config' 3 | import { getVersionedDocsPath } from '@libs/path' 4 | 5 | export function getVersionedBsCssProps(direction: 'rtl' | undefined) { 6 | let bsCssLinkHref = '/dist/css/bootstrap' 7 | 8 | if (direction === 'rtl') { 9 | bsCssLinkHref = `${bsCssLinkHref}.rtl` 10 | } 11 | 12 | if (import.meta.env.PROD) { 13 | bsCssLinkHref = `${bsCssLinkHref}.min` 14 | } 15 | 16 | bsCssLinkHref = `${bsCssLinkHref}.css` 17 | 18 | const bsCssLinkProps: HTMLAttributes<'link'> = { 19 | href: getVersionedDocsPath(bsCssLinkHref), 20 | rel: 'stylesheet' 21 | } 22 | 23 | if (import.meta.env.PROD) { 24 | bsCssLinkProps.integrity = direction === 'rtl' ? getConfig().cdn.css_rtl_hash : getConfig().cdn.css_hash 25 | } 26 | 27 | return bsCssLinkProps 28 | } 29 | 30 | export function getVersionedBsJsProps() { 31 | let bsJsScriptSrc = '/dist/js/bootstrap.bundle' 32 | 33 | if (import.meta.env.PROD) { 34 | bsJsScriptSrc = `${bsJsScriptSrc}.min` 35 | } 36 | 37 | bsJsScriptSrc = `${bsJsScriptSrc}.js` 38 | 39 | const bsJsLinkProps: HTMLAttributes<'script'> = { 40 | src: getVersionedDocsPath(bsJsScriptSrc) 41 | } 42 | 43 | if (import.meta.env.PROD) { 44 | bsJsLinkProps.integrity = getConfig().cdn.js_bundle_hash 45 | } 46 | 47 | return bsJsLinkProps 48 | } 49 | -------------------------------------------------------------------------------- /site/src/libs/content.ts: -------------------------------------------------------------------------------- 1 | import { getCollection, getEntryBySlug } from 'astro:content' 2 | 3 | export const docsPages = await getCollection('docs') 4 | export const callouts = await getCollection('callouts') 5 | 6 | export const aliasedDocsPages = await getCollection('docs', ({ data }) => { 7 | return data.aliases !== undefined 8 | }) 9 | 10 | export function getCalloutByName(name: string) { 11 | return getEntryBySlug('callouts', name) 12 | } 13 | -------------------------------------------------------------------------------- /site/src/libs/icon.ts: -------------------------------------------------------------------------------- 1 | export interface SvgIconProps { 2 | class?: string 3 | height: number 4 | width: number 5 | } 6 | -------------------------------------------------------------------------------- /site/src/libs/image.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path' 2 | import { promises as fs } from 'node:fs' 3 | import sizeOf from 'image-size' 4 | import { getDocsStaticFsPath } from './path' 5 | 6 | export async function getStaticImageSize(imagePath: string) { 7 | const fullPath = path.join(getDocsStaticFsPath(), imagePath) 8 | const buffer = await fs.readFile(fullPath) 9 | const size = await sizeOf(buffer) 10 | 11 | if (!size?.height || !size?.width) { 12 | throw new Error(`Failed to get size of static image at '${imagePath}'.`) 13 | } 14 | 15 | return { height: size.height, width: size.width } 16 | } 17 | -------------------------------------------------------------------------------- /site/src/libs/layout.ts: -------------------------------------------------------------------------------- 1 | import type { HTMLAttributes, HTMLTag } from 'astro/types' 2 | 3 | export type Layout = 'docs' | 'examples' | 'single' | undefined 4 | 5 | export type LayoutOverridesHTMLAttributes = HTMLAttributes & { 6 | [key in `data-${string}`]: string 7 | } 8 | -------------------------------------------------------------------------------- /site/src/libs/rehype.ts: -------------------------------------------------------------------------------- 1 | import type { Root } from 'hast' 2 | import type { Plugin } from 'unified' 3 | import { SKIP, visit } from 'unist-util-visit' 4 | 5 | // A rehype plugin to apply CSS classes to tables rendered in markdown (or MDX) files when wrapped in a `` 6 | // component. 7 | export const rehypeBsTable: Plugin<[], Root> = function () { 8 | return function rehypeBsTablePlugin(ast) { 9 | visit(ast, 'element', (node, _index, parent) => { 10 | if (node.tagName !== 'table' || parent?.type !== 'mdxJsxFlowElement' || parent.name !== 'BsTable') { 11 | return SKIP 12 | } 13 | 14 | const classAttribute = parent.attributes.find( 15 | (attribute) => attribute.type === 'mdxJsxAttribute' && attribute.name === 'class' 16 | ) 17 | 18 | if (classAttribute && typeof classAttribute.value !== 'string') { 19 | return SKIP 20 | } 21 | 22 | const tableClass = typeof classAttribute?.value === 'string' ? classAttribute.value : 'table' 23 | 24 | if (!node.properties) { 25 | node.properties = {} 26 | } 27 | 28 | node.properties = { 29 | ...node.properties, 30 | class: tableClass 31 | } 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /site/src/libs/toc.ts: -------------------------------------------------------------------------------- 1 | import type { MarkdownHeading } from 'astro' 2 | import { getConfig } from './config' 3 | 4 | // Generate a tree like structure from a list of headings. 5 | export function generateToc(allHeadings: MarkdownHeading[]) { 6 | const headings = allHeadings.filter( 7 | (heading) => heading.depth >= getConfig().toc.min && heading.depth <= getConfig().toc.max 8 | ) 9 | 10 | const toc: TocEntry[] = [] 11 | 12 | for (const heading of headings) { 13 | if (toc.length === 0) { 14 | toc.push({ ...heading, children: [] }) 15 | continue 16 | } 17 | 18 | const previousEntry = toc[toc.length - 1] 19 | 20 | if (heading.depth === previousEntry.depth) { 21 | toc.push({ ...heading, children: [] }) 22 | continue 23 | } 24 | 25 | const children = getEntryChildrenAtDepth(previousEntry, heading.depth - previousEntry.depth) 26 | children.push({ ...heading, children: [] }) 27 | } 28 | 29 | return toc 30 | } 31 | 32 | function getEntryChildrenAtDepth(entry: TocEntry, depth: number): TocEntry['children'] { 33 | if (!entry) { 34 | return [] 35 | } 36 | 37 | return depth === 1 ? entry.children : getEntryChildrenAtDepth(entry.children[entry.children.length - 1], depth - 1) 38 | } 39 | 40 | export interface TocEntry extends MarkdownHeading { 41 | children: TocEntry[] 42 | } 43 | -------------------------------------------------------------------------------- /site/src/libs/validation.ts: -------------------------------------------------------------------------------- 1 | import { z } from 'zod' 2 | 3 | export const zVersionMajorMinor = z.string().regex(/^\d+\.\d+$/) 4 | 5 | // https://ihateregex.io/expr/semver/ 6 | const unboundSemverRegex = 7 | /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?/ 8 | 9 | export const zVersionSemver = z.string().regex(new RegExp(`^${unboundSemverRegex.source}$`)) 10 | export const zPrefixedVersionSemver = z.string().regex(new RegExp(`^v${unboundSemverRegex.source}$`)) 11 | 12 | export const zHexColor = z.string().regex(/^#(?:[0-9a-fA-F]{3}){1,2}$/) 13 | 14 | export const zNamedHexColors = (count: number) => { 15 | return z 16 | .object({ 17 | name: z.union([z.string(), z.number()]), 18 | hex: zHexColor 19 | }) 20 | .array() 21 | .length(count) 22 | } 23 | 24 | export const zPxSizeOrEmpty = z.string().regex(/^(?:\d+px)?$/) 25 | 26 | export const zLanguageCode = z.string().regex(/^[a-z]{2}(?:-[a-zA-Z]{2})?$/) 27 | -------------------------------------------------------------------------------- /site/src/pages/404.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import BaseLayout from '@layouts/BaseLayout.astro' 3 | --- 4 | 5 | 13 |
14 |

404

15 |

File not found

16 |
17 |
18 | -------------------------------------------------------------------------------- /site/src/pages/docs/[version]/[...slug].astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { InferGetStaticPropsType } from 'astro' 3 | import DocsLayout from '@layouts/DocsLayout.astro' 4 | import { getConfig } from '@libs/config' 5 | import { docsPages } from '@libs/content' 6 | import Code from '@shortcodes/Code.astro' 7 | 8 | export async function getStaticPaths() { 9 | return docsPages.map((docsPage) => { 10 | return { 11 | params: { slug: docsPage.slug, version: getConfig().docs_version }, 12 | props: docsPage 13 | } 14 | }) 15 | } 16 | 17 | type Props = InferGetStaticPropsType 18 | 19 | const { id, data, render } = Astro.props 20 | const { Content, headings, remarkPluginFrontmatter } = await render() 21 | --- 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /site/src/pages/docs/[version]/examples/[...asset].ts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs' 2 | import path from 'node:path' 3 | import type { APIRoute } from 'astro' 4 | import mime from 'mime' 5 | import { getConfig } from '@libs/config' 6 | import { getExamplesAssets } from '@libs/examples' 7 | import { getDocsFsPath } from '@libs/path' 8 | 9 | export function getStaticPaths() { 10 | const examplesAssets = getExamplesAssets() 11 | 12 | return examplesAssets.map((examplesAsset) => { 13 | return { 14 | params: { asset: examplesAsset, version: getConfig().docs_version } 15 | } 16 | }) 17 | } 18 | 19 | export const GET: APIRoute = ({ params }) => { 20 | const asset = params.asset 21 | 22 | if (!asset) { 23 | throw new Error('Missing asset parameter while generating an example asset.') 24 | } 25 | 26 | const assetPath = path.join(getDocsFsPath(), 'src/assets/examples', asset) 27 | const buffer = fs.readFileSync(assetPath) 28 | const mimetype = mime.getType(assetPath) 29 | const headers: ResponseInit['headers'] = typeof mimetype === 'string' ? { 'Content-Type': mimetype } : {} 30 | 31 | return new Response(buffer, { headers }) 32 | } 33 | -------------------------------------------------------------------------------- /site/src/pages/docs/[version]/examples/[...example].astro: -------------------------------------------------------------------------------- 1 | --- 2 | import ExamplesLayout from '@layouts/ExamplesLayout.astro' 3 | import { getConfig } from '@libs/config' 4 | import { exampleFrontmatterSchema, getExampleNameFromPagePath, type ExampleFrontmatter } from '@libs/examples' 5 | 6 | export async function getStaticPaths() { 7 | const examplesPageModules = import.meta.glob('../../../../assets/examples/**/*.astro', { eager: true }) 8 | const examplesPages = Object.entries(examplesPageModules).map(([file, module]) => { 9 | return { 10 | file, 11 | ...module 12 | } 13 | }) 14 | 15 | return examplesPages.map((examplesPage) => { 16 | const { default: Content, file, url, ...props } = examplesPage 17 | const example = getExampleNameFromPagePath(examplesPage.file) 18 | let frontmatter: ExampleFrontmatter 19 | 20 | try { 21 | frontmatter = exampleFrontmatterSchema.parse(props) 22 | } catch (error) { 23 | throw new Error(`Invalid frontmatter for the '${example}' example.`, { cause: error }) 24 | } 25 | 26 | return { 27 | params: { example, version: getConfig().docs_version }, 28 | props: { ...frontmatter, Content } 29 | } 30 | }) 31 | } 32 | 33 | type Props = ExampleFrontmatter 34 | 35 | const { Content, ...props } = Astro.props 36 | --- 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /site/src/pages/docs/[version]/examples/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import SingleLayout from '@layouts/SingleLayout.astro' 3 | import { getConfig } from '@libs/config' 4 | import BsThemes from '@layouts/partials/BsThemes.astro' 5 | import ExamplesMain from '@layouts/partials/ExamplesMain.astro' 6 | export function getStaticPaths() { 7 | return [ 8 | { 9 | params: { version: getConfig().docs_version } 10 | } 11 | ] 12 | } 13 | --- 14 | 15 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /site/src/pages/docs/[version]/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import RedirectLayout from '@layouts/RedirectLayout.astro' 3 | import { getConfig } from '@libs/config' 4 | import { getVersionedDocsPath } from '@libs/path' 5 | 6 | export function getStaticPaths() { 7 | return [ 8 | { 9 | params: { version: getConfig().docs_version } 10 | } 11 | ] 12 | } 13 | --- 14 | 15 | 16 | -------------------------------------------------------------------------------- /site/src/pages/docs/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import RedirectLayout from '@layouts/RedirectLayout.astro' 3 | import { getVersionedDocsPath } from '@libs/path' 4 | --- 5 | 6 | 7 | -------------------------------------------------------------------------------- /site/src/pages/examples.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import RedirectLayout from '@layouts/RedirectLayout.astro' 3 | import { getVersionedDocsPath } from '@libs/path' 4 | --- 5 | 6 | 7 | -------------------------------------------------------------------------------- /site/src/pages/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import BaseLayout from '@layouts/BaseLayout.astro' 3 | import GetStarted from '@components/home/GetStarted.astro' 4 | import Customize from '@components/home/Customize.astro' 5 | import CSSVariables from '@components/home/CSSVariables.astro' 6 | import ComponentUtilities from '@components/home/ComponentUtilities.astro' 7 | import MastHead from '@components/home/MastHead.astro' 8 | import Plugins from '@components/home/Plugins.astro' 9 | import Icons from '@components/home/Icons.astro' 10 | import Themes from '@components/home/Themes.astro' 11 | --- 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |
25 | -------------------------------------------------------------------------------- /site/src/pages/robots.txt.ts: -------------------------------------------------------------------------------- 1 | import type { APIRoute } from 'astro' 2 | 3 | export const GET: APIRoute = function GET({ site }) { 4 | const isProduction = import.meta.env.PROD 5 | const isNetlify = import.meta.env.NETLIFY === 'true' 6 | 7 | const allowCrawling = !isNetlify && isProduction 8 | 9 | const robotsTxt = `# www.robotstxt.org${allowCrawling ? '\n# Allow crawling of all content' : ''} 10 | User-agent: * 11 | Disallow: ${allowCrawling ? '' : '/'} 12 | Sitemap: ${new URL('sitemap-index.xml', site)} 13 | ` 14 | 15 | return new Response(robotsTxt, { 16 | headers: { 17 | 'Content-Type': 'text/plain' 18 | } 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /site/src/plugins/algolia-plugin.js: -------------------------------------------------------------------------------- 1 | import { getConfig } from '../libs/config.ts' 2 | 3 | /** 4 | * Vite plugin to replace placeholder values in search.js with actual configuration values 5 | */ 6 | export function algoliaPlugin() { 7 | const config = getConfig() 8 | 9 | return { 10 | name: 'algolia-config-replacer', 11 | transform(code, id) { 12 | if (id.includes('search.js')) { 13 | return code 14 | .replace(/__API_KEY__/g, config.algolia.api_key) 15 | .replace(/__INDEX_NAME__/g, config.algolia.index_name) 16 | .replace(/__APP_ID__/g, config.algolia.app_id) 17 | } 18 | 19 | return code 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /site/src/plugins/stackblitz-plugin.js: -------------------------------------------------------------------------------- 1 | import { getConfig } from '../libs/config.ts' 2 | 3 | /** 4 | * Vite plugin to replace placeholder values in stackblitz.js with actual configuration values 5 | */ 6 | export function stackblitzPlugin() { 7 | const config = getConfig() 8 | 9 | return { 10 | name: 'stackblitz-config-replacer', 11 | transform(code, id) { 12 | if (id.includes('stackblitz.js')) { 13 | return code 14 | .replace(/__CSS_CDN__/g, config.cdn.css) 15 | .replace(/__JS_BUNDLE_CDN__/g, config.cdn.js_bundle) 16 | .replace(/__DOCS_VERSION__/g, config.docs_version) 17 | } 18 | 19 | return code 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /site/src/scss/_ads.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important, selector-max-id 2 | 3 | // 4 | // Carbon ads 5 | // 6 | 7 | #carbonads { 8 | position: static; 9 | max-width: 400px; 10 | padding: 15px 15px 15px 160px; 11 | margin: 1rem 0; 12 | overflow: hidden; 13 | @include font-size(.8125rem); 14 | line-height: 1.4; 15 | text-align: left; 16 | background-color: var(--bs-tertiary-bg); 17 | 18 | a { 19 | color: var(--bs-body-color); 20 | text-decoration: none; 21 | } 22 | 23 | @include media-breakpoint-up(sm) { 24 | @include border-radius(.5rem); 25 | } 26 | } 27 | 28 | .carbon-img { 29 | float: left; 30 | margin-left: -145px; 31 | } 32 | 33 | @container (max-width: 240px) { 34 | #carbonads { 35 | padding-left: 15px; 36 | } 37 | 38 | .carbon-img { 39 | display: block; 40 | float: none; 41 | margin-left: 0; 42 | } 43 | 44 | .carbon-wrap { 45 | display: flex; 46 | flex-direction: column; 47 | gap: .5rem; 48 | } 49 | 50 | .carbon-img > img { 51 | width: 100%; 52 | max-width: 100% !important; 53 | height: auto; 54 | @include border-radius(var(--bs-border-radius-sm)); 55 | } 56 | } 57 | 58 | .carbon-poweredby { 59 | display: block; 60 | margin-top: .75rem; 61 | color: var(--bs-fg-3) !important; 62 | } 63 | -------------------------------------------------------------------------------- /site/src/scss/_anchor.scss: -------------------------------------------------------------------------------- 1 | .anchor-link { 2 | padding: 0 .175rem; 3 | font-weight: 400; 4 | color: rgba($link-color, .5); 5 | text-decoration: none; 6 | opacity: 0; 7 | @include transition(color .15s ease-in-out, opacity .15s ease-in-out); 8 | 9 | &::after { 10 | content: "#"; 11 | } 12 | 13 | &:focus, 14 | &:hover, 15 | :hover > &, 16 | :target > & { 17 | color: $link-color; 18 | text-decoration: none; 19 | opacity: 1; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /site/src/scss/_brand.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Brand guidelines 3 | // 4 | 5 | // Logo series wrapper 6 | .bd-brand-logos { 7 | color: $bd-violet; 8 | 9 | .inverse { 10 | color: $white; 11 | background-color: $bd-violet; 12 | } 13 | } 14 | 15 | // Individual items 16 | .bd-brand-item { 17 | + .bd-brand-item { 18 | border-top: 1px solid var(--bs-border-color); 19 | } 20 | 21 | @include media-breakpoint-up(md) { 22 | + .bd-brand-item { 23 | border-top: 0; 24 | border-left: 1px solid var(--bs-border-color); 25 | } 26 | } 27 | } 28 | 29 | 30 | // 31 | // Color swatches 32 | // 33 | 34 | .color-swatches { 35 | margin: 0 -5px; 36 | 37 | // Docs colors 38 | .bd-purple { 39 | background-color: $bd-purple; 40 | } 41 | .bd-purple-light { 42 | background-color: $bd-purple-light; 43 | } 44 | .bd-purple-lighter { 45 | background-color: #e5e1ea; 46 | } 47 | .bd-gray { 48 | background-color: #f9f9f9; 49 | } 50 | } 51 | 52 | .color-swatch { 53 | width: 4rem; 54 | height: 4rem; 55 | 56 | @include media-breakpoint-up(md) { 57 | width: 6rem; 58 | height: 6rem; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /site/src/scss/_callouts.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Callouts 3 | // 4 | 5 | .bd-callout { 6 | --#{$prefix}link-color-rgb: var(--bd-callout-link); 7 | --#{$prefix}code-color: var(--bd-callout-code-color); 8 | 9 | padding: 1.25rem; 10 | margin-top: 1.25rem; 11 | margin-bottom: 1.25rem; 12 | color: var(--bd-callout-color, inherit); 13 | background-color: var(--bd-callout-bg, var(--bs-gray-100)); 14 | border-left: .25rem solid var(--bd-callout-border, var(--bs-gray-300)); 15 | 16 | h4 { 17 | margin-bottom: .25rem; 18 | } 19 | 20 | > :last-child { 21 | margin-bottom: 0; 22 | } 23 | 24 | + .bd-callout { 25 | margin-top: -.25rem; 26 | } 27 | 28 | .highlight { 29 | background-color: rgba($black, .05); 30 | } 31 | } 32 | 33 | // Variations 34 | @each $variant in $bd-callout-variants { 35 | .bd-callout-#{$variant} { 36 | --bd-callout-color: var(--bs-#{$variant}-text-emphasis); 37 | --bd-callout-bg: var(--bs-#{$variant}-bg-subtle); 38 | --bd-callout-border: var(--bs-#{$variant}-border-subtle); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /site/src/scss/_clipboard-js.scss: -------------------------------------------------------------------------------- 1 | // clipboard.js 2 | // 3 | // JS-based `Copy` buttons for code snippets. 4 | 5 | .bd-clipboard, 6 | .bd-edit { 7 | position: relative; 8 | display: none; 9 | float: right; 10 | 11 | + .highlight { 12 | margin-top: 0; 13 | } 14 | 15 | @include media-breakpoint-up(md) { 16 | display: block; 17 | } 18 | } 19 | 20 | .btn-clipboard, 21 | .btn-edit { 22 | display: block; 23 | padding: .5em; 24 | line-height: 1; 25 | color: var(--bs-body-color); 26 | background-color: var(--bd-pre-bg); 27 | border: 0; 28 | @include border-radius(.25rem); 29 | 30 | &:hover { 31 | color: var(--bs-link-hover-color); 32 | } 33 | 34 | &:focus { 35 | z-index: 3; 36 | } 37 | } 38 | 39 | .btn-clipboard { 40 | position: relative; 41 | z-index: 2; 42 | margin-top: 1.25rem; 43 | margin-right: .75rem; 44 | } 45 | -------------------------------------------------------------------------------- /site/src/scss/_footer.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Footer 3 | // 4 | 5 | .bd-footer { 6 | a { 7 | color: var(--bs-body-color); 8 | text-decoration: none; 9 | 10 | &:hover, 11 | &:focus { 12 | color: var(--bs-link-hover-color); 13 | text-decoration: underline; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /site/src/scss/_layout.scss: -------------------------------------------------------------------------------- 1 | .bd-gutter { 2 | --bs-gutter-x: #{$bd-gutter-x}; 3 | } 4 | 5 | .bd-layout { 6 | 7 | @include media-breakpoint-up(lg) { 8 | display: grid; 9 | grid-template-areas: "sidebar main"; 10 | grid-template-columns: 1fr 5fr; 11 | gap: $grid-gutter-width; 12 | } 13 | } 14 | 15 | .bd-sidebar { 16 | grid-area: sidebar; 17 | } 18 | 19 | .bd-main { 20 | grid-area: main; 21 | 22 | @include media-breakpoint-down(lg) { 23 | max-width: 760px; 24 | margin-inline: auto; 25 | } 26 | 27 | @include media-breakpoint-up(md) { 28 | display: grid; 29 | grid-template-areas: 30 | "intro" 31 | "toc" 32 | "content"; 33 | grid-template-rows: auto auto 1fr; 34 | gap: inherit; 35 | } 36 | 37 | @include media-breakpoint-up(lg) { 38 | grid-template-areas: 39 | "intro toc" 40 | "content toc"; 41 | grid-template-rows: auto 1fr; 42 | grid-template-columns: 4fr 1fr; 43 | } 44 | } 45 | 46 | .bd-intro { 47 | grid-area: intro; 48 | } 49 | 50 | .bd-toc { 51 | grid-area: toc; 52 | } 53 | 54 | .bd-content { 55 | grid-area: content; 56 | min-width: 1px; // Fix width when bd-content contains a `
` https://github.com/twbs/bootstrap/issues/25410
57 | }
58 | 


--------------------------------------------------------------------------------
/site/src/scss/_placeholder-img.scss:
--------------------------------------------------------------------------------
 1 | //
 2 | // Placeholder svg used in the docs.
 3 | //
 4 | 
 5 | // Remember to update `site/_layouts/examples.html` too if this changes!
 6 | 
 7 | .bd-placeholder-img {
 8 |   @include font-size(1.125rem);
 9 |   user-select: none;
10 |   text-anchor: middle;
11 | }
12 | 
13 | .bd-placeholder-img-lg {
14 |   @include font-size(3.5rem);
15 | }
16 | 


--------------------------------------------------------------------------------
/site/src/scss/_scrolling.scss:
--------------------------------------------------------------------------------
 1 | // When navigating with the keyboard, prevent focus from landing behind the sticky header
 2 | 
 3 | main {
 4 |   a,
 5 |   button,
 6 |   input,
 7 |   select,
 8 |   textarea,
 9 |   h2,
10 |   h3,
11 |   h4,
12 |   [tabindex="0"] {
13 |     scroll-margin-top: 80px;
14 |     scroll-margin-bottom: 100px;
15 |   }
16 | }
17 | 


--------------------------------------------------------------------------------
/site/src/scss/_skippy.scss:
--------------------------------------------------------------------------------
1 | .skippy {
2 |   background-color: $bd-purple;
3 | 
4 |   a {
5 |     color: $white;
6 |   }
7 | }
8 | 


--------------------------------------------------------------------------------
/site/src/scss/docs_search.scss:
--------------------------------------------------------------------------------
 1 | /*!
 2 |  * Bootstrap Docs (https://getbootstrap.com/)
 3 |  * Copyright 2024-2025 The Bootstrap Authors
 4 |  * Licensed under the Creative Commons Attribution 3.0 Unported License.
 5 |  * For details, see https://creativecommons.org/licenses/by/3.0/.
 6 |  */
 7 | 
 8 | @import "../../../scss/functions";
 9 | @import "../../../scss/variables";
10 | @import "../../../scss/mixins";
11 | @import "variables";
12 | 
13 | @import "@docsearch/css/dist/style";
14 | @import "search";
15 | 


--------------------------------------------------------------------------------
/site/src/types/auto-import.d.ts:
--------------------------------------------------------------------------------
 1 | /**
 2 |  * DO NOT EDIT THIS FILE MANUALLY.
 3 |  *
 4 |  * This file is automatically generated by the Boostrap Astro Integration.
 5 |  * It contains the type definitions for the components that are auto imported in all pages.
 6 |  * @see site/src/libs/astro.ts
 7 |  */
 8 | export declare global {
 9 |   export const AddedIn: typeof import('@shortcodes/AddedIn.astro').default
10 |   export const BsTable: typeof import('@shortcodes/BsTable.astro').default
11 |   export const Callout: typeof import('@shortcodes/Callout.astro').default
12 |   export const CalloutDeprecatedDarkVariants: typeof import('@shortcodes/CalloutDeprecatedDarkVariants.astro').default
13 |   export const Code: typeof import('@shortcodes/Code.astro').default
14 |   export const DeprecatedIn: typeof import('@shortcodes/DeprecatedIn.astro').default
15 |   export const Example: typeof import('@shortcodes/Example.astro').default
16 |   export const JsDismiss: typeof import('@shortcodes/JsDismiss.astro').default
17 |   export const JsDocs: typeof import('@shortcodes/JsDocs.astro').default
18 |   export const Placeholder: typeof import('@shortcodes/Placeholder.astro').default
19 |   export const ScssDocs: typeof import('@shortcodes/ScssDocs.astro').default
20 |   export const Table: typeof import('@shortcodes/Table.astro').default
21 | }
22 | 


--------------------------------------------------------------------------------
/site/src/types/window.d.ts:
--------------------------------------------------------------------------------
 1 | export declare global {
 2 |   export const StackBlitzSDK: typeof import('@stackblitz/sdk').default
 3 | 
 4 |   /**
 5 |    * The `bootstrap` object is exposed to the global scope and also to the `window` object in the browser.
 6 |    * We rely on the DefinitelyTyped community types for this object to get proper type checking for part of the
 7 |    * documentation using the Bootstrap API and avoid any misuse of the API.
 8 |    * To temporarily or permanently disable this feature (e.g. when modifying the Bootstrap API used in the
 9 |    * documentation), the 2 lines containing `typeof import('bootstrap')` can be commented and replaced by the commented
10 |    * lines containing `any`.
11 |    *
12 |    * The documentation is currently using the following APIs from Bootstrap:
13 |    *
14 |    *  - `bootstrap.Tooltip.getOrCreateInstance`
15 |    *  - `bootstrap.Tooltip.getInstance`
16 |    *
17 |    */
18 |   export const bootstrap: typeof import('bootstrap')
19 |   // export const bootstrap: any
20 | 
21 |   interface Window {
22 |     bootstrap: typeof import('bootstrap')
23 |     // bootstrap: any
24 |   }
25 | }
26 | 


--------------------------------------------------------------------------------
/site/static/CNAME:
--------------------------------------------------------------------------------
1 | getbootstrap.com
2 | 


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/brand/bootstrap-logo-black.svg:
--------------------------------------------------------------------------------
1 | 


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/brand/bootstrap-logo-shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/brand/bootstrap-logo-shadow.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/brand/bootstrap-logo-shadow@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/brand/bootstrap-logo-shadow@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/brand/bootstrap-logo-white.svg:
--------------------------------------------------------------------------------
1 | 


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/brand/bootstrap-social.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/brand/bootstrap-social.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/bootstrap-icons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/bootstrap-icons.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/bootstrap-icons@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/bootstrap-icons@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/bootstrap-intellisense-autocomplete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/bootstrap-intellisense-autocomplete.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/bootstrap-themes-collage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/bootstrap-themes-collage.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/bootstrap-themes-collage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/bootstrap-themes-collage@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/bootstrap-themes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/bootstrap-themes.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/bootstrap-themes@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/bootstrap-themes@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/album-rtl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/album-rtl.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/album-rtl@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/album-rtl@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/album.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/album.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/album@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/album@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/badges.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/badges.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/badges@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/badges@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/blog-rtl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/blog-rtl.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/blog-rtl@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/blog-rtl@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/blog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/blog.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/blog@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/blog@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/breadcrumbs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/breadcrumbs.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/breadcrumbs@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/breadcrumbs@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/buttons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/buttons.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/buttons@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/buttons@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/carousel-rtl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/carousel-rtl.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/carousel-rtl@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/carousel-rtl@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/carousel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/carousel.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/carousel@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/carousel@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/cheatsheet-rtl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/cheatsheet-rtl.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/cheatsheet-rtl@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/cheatsheet-rtl@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/cheatsheet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/cheatsheet.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/cheatsheet@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/cheatsheet@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/checkout-rtl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/checkout-rtl.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/checkout-rtl@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/checkout-rtl@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/checkout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/checkout.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/checkout@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/checkout@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/cover.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/cover@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/cover@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/dashboard-rtl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/dashboard-rtl.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/dashboard-rtl@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/dashboard-rtl@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/dashboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/dashboard.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/dashboard@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/dashboard@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/dropdowns.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/dropdowns.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/dropdowns@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/dropdowns@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/features.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/features.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/features@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/features@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/footers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/footers.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/footers@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/footers@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/grid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/grid.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/grid@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/grid@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/headers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/headers.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/headers@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/headers@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/heroes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/heroes.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/heroes@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/heroes@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/jumbotron.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/jumbotron.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/jumbotron@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/jumbotron@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/jumbotrons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/jumbotrons.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/jumbotrons@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/jumbotrons@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/list-groups.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/list-groups.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/list-groups@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/list-groups@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/masonry.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/masonry.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/masonry@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/masonry@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/modals.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/modals.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/modals@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/modals@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/navbar-bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/navbar-bottom.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/navbar-bottom@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/navbar-bottom@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/navbar-fixed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/navbar-fixed.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/navbar-fixed@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/navbar-fixed@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/navbar-static.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/navbar-static.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/navbar-static@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/navbar-static@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/navbars-offcanvas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/navbars-offcanvas.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/navbars-offcanvas@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/navbars-offcanvas@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/navbars.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/navbars.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/navbars@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/navbars@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/offcanvas-navbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/offcanvas-navbar.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/offcanvas-navbar@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/offcanvas-navbar@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/pricing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/pricing.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/pricing@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/pricing@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/product.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/product.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/product@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/product@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/sidebars.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/sidebars.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/sidebars@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/sidebars@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/sign-in.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/sign-in.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/sign-in@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/sign-in@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/starter-template.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/starter-template.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/starter-template@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/starter-template@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/sticky-footer-navbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/sticky-footer-navbar.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/sticky-footer-navbar@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/sticky-footer-navbar@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/sticky-footer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/sticky-footer.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/examples/sticky-footer@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/examples/sticky-footer@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/favicons/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/favicons/android-chrome-192x192.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/favicons/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/favicons/android-chrome-512x512.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/favicons/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/favicons/apple-touch-icon.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/favicons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/favicons/favicon-16x16.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/favicons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/favicons/favicon-32x32.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/favicons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/favicons/favicon.ico


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/favicons/manifest.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "name": "Bootstrap",
 3 |   "short_name": "Bootstrap",
 4 |   "icons": [
 5 |     {
 6 |       "src": "android-chrome-192x192.png",
 7 |       "sizes": "192x192",
 8 |       "type": "image/png"
 9 |     },
10 |     {
11 |       "src": "android-chrome-512x512.png",
12 |       "sizes": "512x512",
13 |       "type": "image/png"
14 |     }
15 |   ],
16 |   "start_url": "/?utm_source=a2hs",
17 |   "theme_color": "#7952b3",
18 |   "background_color": "#7952b3",
19 |   "display": "standalone"
20 | }
21 | 


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/favicons/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 | 


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/guides/bootstrap-parcel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/guides/bootstrap-parcel.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/guides/bootstrap-parcel@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/guides/bootstrap-parcel@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/guides/bootstrap-vite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/guides/bootstrap-vite.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/guides/bootstrap-vite@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/guides/bootstrap-vite@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/guides/bootstrap-webpack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/guides/bootstrap-webpack.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/guides/bootstrap-webpack@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/guides/bootstrap-webpack@2x.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/guides/parcel-dev-server-bootstrap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/guides/parcel-dev-server-bootstrap.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/guides/parcel-dev-server.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/guides/parcel-dev-server.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/guides/vite-dev-server-bootstrap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/guides/vite-dev-server-bootstrap.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/guides/vite-dev-server.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/guides/vite-dev-server.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/guides/webpack-dev-server-bootstrap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/guides/webpack-dev-server-bootstrap.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/guides/webpack-dev-server.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/guides/webpack-dev-server.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/parcel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/twbs/bootstrap/fb5409b65f6004a0db2eb27c4057f39520fbae38/site/static/docs/[version]/assets/img/parcel.png


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/vite.svg:
--------------------------------------------------------------------------------
1 | 
2 | 


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/img/webpack.svg:
--------------------------------------------------------------------------------
1 | 
2 | 


--------------------------------------------------------------------------------
/site/static/docs/[version]/assets/js/validate-forms.js:
--------------------------------------------------------------------------------
 1 | // Example starter JavaScript for disabling form submissions if there are invalid fields
 2 | (() => {
 3 |   'use strict'
 4 | 
 5 |   // Fetch all the forms we want to apply custom Bootstrap validation styles to
 6 |   const forms = document.querySelectorAll('.needs-validation')
 7 | 
 8 |   // Loop over them and prevent submission
 9 |   Array.from(forms).forEach(form => {
10 |     form.addEventListener('submit', event => {
11 |       if (!form.checkValidity()) {
12 |         event.preventDefault()
13 |         event.stopPropagation()
14 |       }
15 | 
16 |       form.classList.add('was-validated')
17 |     }, false)
18 |   })
19 | })()
20 | 


--------------------------------------------------------------------------------
/site/static/sw.js:
--------------------------------------------------------------------------------
 1 | // NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT
 2 | // IT'S ALL JUST JUNK FOR OUR DOCS!
 3 | // ++++++++++++++++++++++++++++++++++++++++++
 4 | 
 5 | (function () {
 6 |   'use strict'
 7 | 
 8 |   if ('serviceWorker' in navigator) {
 9 |     window.addEventListener('load', function () {
10 |       navigator.serviceWorker.getRegistrations().then(function (registrations) {
11 |         for (var registration of registrations) {
12 |           registration.unregister()
13 |             .then(function () {
14 |               return self.clients.matchAll()
15 |             })
16 |             .then(function (clients) {
17 |               clients.forEach(function (client) {
18 |                 if (client.url && 'navigate' in client) {
19 |                   client.navigate(client.url)
20 |                 }
21 |               })
22 |             })
23 |         }
24 |       })
25 |     })
26 |   }
27 | })()
28 | 


--------------------------------------------------------------------------------
/site/tsconfig.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "extends": "astro/tsconfigs/strict",
 3 |   "compilerOptions": {
 4 |     "baseUrl": ".",
 5 |     "paths": {
 6 |       "@assets/*": ["src/assets/*"],
 7 |       "@components/*": ["src/components/*"],
 8 |       "@layouts/*": ["src/layouts/*"],
 9 |       "@libs/*": ["src/libs/*"],
10 |       "@shortcodes/*": ["src/components/shortcodes/*"]
11 |     }
12 |   }
13 | }
14 | 


--------------------------------------------------------------------------------