├── .babelrc.js ├── .browserslistrc ├── .bundlewatch.config.json ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .gitattributes ├── .github ├── CODEOWNERS ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── SUPPORT.md └── workflows │ ├── browserstack.yml │ ├── bundlewatch.yml │ ├── codeql.yml │ ├── css.yml │ ├── dart-sass.yml │ ├── docs.yml │ ├── js.yml │ └── lint.yml ├── .gitignore ├── .stylelintignore ├── .stylelintrc ├── CNAME ├── CODE_OF_CONDUCT.md ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── SECURITY.md ├── _config.yml ├── build ├── .eslintrc.json ├── banner.js ├── build-plugins.js ├── change-version.js ├── generate-sri.js ├── postcss.config.js ├── rollup.config.js ├── rtl-docs.js ├── ship.sh ├── svgo.yml ├── vnu-jar.js └── zip-examples.js ├── composer.json ├── dist ├── css │ ├── bootstrap-grid.css │ ├── bootstrap-grid.css.map │ ├── bootstrap-grid.min.css │ ├── bootstrap-grid.min.css.map │ ├── bootstrap-reboot.css │ ├── bootstrap-reboot.css.map │ ├── bootstrap-reboot.min.css │ ├── bootstrap-reboot.min.css.map │ ├── bootstrap.css │ ├── bootstrap.css.map │ ├── bootstrap.min.css │ ├── bootstrap.min.css.map │ └── rtl │ │ ├── bootstrap-grid.css │ │ ├── bootstrap-grid.min.css │ │ ├── bootstrap-grid.min.css.map │ │ ├── bootstrap-reboot.css │ │ ├── bootstrap-reboot.min.css │ │ ├── bootstrap-reboot.min.css.map │ │ ├── bootstrap.css │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map └── js │ ├── bootstrap.bundle.js │ ├── bootstrap.bundle.js.map │ ├── bootstrap.bundle.min.js │ ├── bootstrap.bundle.min.js.map │ ├── bootstrap.js │ ├── bootstrap.js.map │ ├── bootstrap.min.js │ └── bootstrap.min.js.map ├── js ├── dist │ ├── alert.js │ ├── alert.js.map │ ├── button.js │ ├── button.js.map │ ├── carousel.js │ ├── carousel.js.map │ ├── collapse.js │ ├── collapse.js.map │ ├── dropdown.js │ ├── dropdown.js.map │ ├── index.js │ ├── modal.js │ ├── modal.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.js │ └── util.js.map ├── src │ ├── alert.js │ ├── button.js │ ├── carousel.js │ ├── collapse.js │ ├── dropdown.js │ ├── index.js │ ├── modal.js │ ├── popover.js │ ├── scrollspy.js │ ├── tab.js │ ├── toast.js │ ├── tools │ │ └── sanitizer.js │ ├── tooltip.js │ └── util.js └── tests │ ├── README.md │ ├── browsers.js │ ├── index.html │ ├── integration │ ├── bundle.js │ ├── index.html │ └── rollup.bundle.js │ ├── karma.conf.js │ ├── unit │ ├── .eslintrc.json │ ├── alert.js │ ├── button.js │ ├── carousel.js │ ├── collapse.js │ ├── dropdown.js │ ├── modal.js │ ├── popover.js │ ├── scrollspy.js │ ├── tab.js │ ├── toast.js │ ├── tooltip.js │ └── util.js │ └── visual │ ├── alert.html │ ├── button.html │ ├── carousel.html │ ├── collapse.html │ ├── dropdown.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 ├── _alert.scss ├── _badge.scss ├── _breadcrumb.scss ├── _button-group.scss ├── _buttons.scss ├── _card.scss ├── _carousel.scss ├── _close.scss ├── _code.scss ├── _custom-forms.scss ├── _dropdown.scss ├── _forms.scss ├── _functions.scss ├── _grid.scss ├── _images.scss ├── _input-group.scss ├── _jumbotron.scss ├── _list-group.scss ├── _media.scss ├── _mixins.scss ├── _modal.scss ├── _nav.scss ├── _navbar.scss ├── _pagination.scss ├── _popover.scss ├── _print.scss ├── _progress.scss ├── _reboot.scss ├── _root.scss ├── _spinners.scss ├── _tables.scss ├── _toasts.scss ├── _tooltip.scss ├── _transitions.scss ├── _type.scss ├── _utilities.scss ├── _variables.scss ├── bootstrap-grid.scss ├── bootstrap-reboot.scss ├── bootstrap.scss ├── mixins │ ├── _alert.scss │ ├── _background-variant.scss │ ├── _badge.scss │ ├── _border-radius.scss │ ├── _box-shadow.scss │ ├── _breakpoints.scss │ ├── _buttons.scss │ ├── _caret.scss │ ├── _clearfix.scss │ ├── _deprecate.scss │ ├── _float.scss │ ├── _forms.scss │ ├── _gradients.scss │ ├── _grid-framework.scss │ ├── _grid.scss │ ├── _hover.scss │ ├── _image.scss │ ├── _list-group.scss │ ├── _lists.scss │ ├── _nav-divider.scss │ ├── _pagination.scss │ ├── _reset-text.scss │ ├── _resize.scss │ ├── _screen-reader.scss │ ├── _size.scss │ ├── _table-row.scss │ ├── _text-emphasis.scss │ ├── _text-hide.scss │ ├── _text-truncate.scss │ ├── _transition.scss │ └── _visibility.scss ├── utilities │ ├── _align.scss │ ├── _background.scss │ ├── _borders.scss │ ├── _clearfix.scss │ ├── _display.scss │ ├── _embed.scss │ ├── _flex.scss │ ├── _float.scss │ ├── _interactions.scss │ ├── _overflow.scss │ ├── _position.scss │ ├── _screenreaders.scss │ ├── _shadows.scss │ ├── _sizing.scss │ ├── _spacing.scss │ ├── _stretched-link.scss │ ├── _text.scss │ └── _visibility.scss └── vendor │ └── _rfs.scss └── site ├── .eslintrc.json ├── _data ├── breakpoints.yml ├── browser-bugs.yml ├── browser-features.yml ├── colors.yml ├── core-team.yml ├── docs-versions.yml ├── examples.yml ├── grays.yml ├── nav.yml ├── theme-colors.yml └── translations.yml ├── _includes ├── ads.html ├── analytics.html ├── bugify.html ├── callout-danger-async-methods.md ├── callout-info-mediaqueries-breakpoints.md ├── callout-info-prefersreducedmotion.md ├── callout-warning-color-assistive-technologies.md ├── callout.html ├── docs-navbar.html ├── docs-sidebar.html ├── example.html ├── favicons.html ├── footer.html ├── header.html ├── icons │ ├── bootstrap-stack.svg │ ├── bootstrap.svg │ ├── circle-square.svg │ ├── cloud-fill.svg │ ├── code.svg │ ├── droplet-fill.svg │ ├── github.svg │ ├── menu.svg │ ├── opencollective.svg │ ├── placeholder.svg │ ├── slack.svg │ └── twitter.svg ├── scripts.html ├── skippy.html ├── social.html └── stylesheet.html ├── _layouts ├── default.html ├── docs.html ├── examples.html ├── home.html └── simple.html ├── docs ├── 4.4 │ └── assets │ │ └── css │ │ ├── docs.min.css │ │ └── docs.min.css.map ├── 4.5 │ ├── about │ │ ├── brand.md │ │ ├── license.md │ │ ├── overview.md │ │ ├── team.md │ │ └── translations.md │ ├── assets │ │ ├── brand │ │ │ ├── bootstrap-outline.svg │ │ │ ├── bootstrap-punchout.svg │ │ │ ├── bootstrap-social-logo.png │ │ │ ├── bootstrap-social.png │ │ │ └── bootstrap-solid.svg │ │ ├── css │ │ │ ├── docs.min.css │ │ │ └── docs.min.css.map │ │ ├── img │ │ │ ├── bootstrap-icons.png │ │ │ ├── bootstrap-icons@2x.png │ │ │ ├── bootstrap-themes-collage.png │ │ │ ├── bootstrap-themes-collage@2x.png │ │ │ ├── bootstrap-themes.png │ │ │ ├── bootstrap-themes@2x.png │ │ │ ├── examples │ │ │ │ ├── album.png │ │ │ │ ├── album@2x.png │ │ │ │ ├── blog.png │ │ │ │ ├── blog@2x.png │ │ │ │ ├── carousel.png │ │ │ │ ├── carousel@2x.png │ │ │ │ ├── checkout.png │ │ │ │ ├── checkout@2x.png │ │ │ │ ├── cover.png │ │ │ │ ├── cover@2x.png │ │ │ │ ├── dashboard.png │ │ │ │ ├── dashboard@2x.png │ │ │ │ ├── floating-labels.png │ │ │ │ ├── floating-labels@2x.png │ │ │ │ ├── grid.png │ │ │ │ ├── grid@2x.png │ │ │ │ ├── jumbotron.png │ │ │ │ ├── jumbotron@2x.png │ │ │ │ ├── navbar-bottom.png │ │ │ │ ├── navbar-bottom@2x.png │ │ │ │ ├── navbar-fixed.png │ │ │ │ ├── navbar-fixed@2x.png │ │ │ │ ├── navbar-static.png │ │ │ │ ├── navbar-static@2x.png │ │ │ │ ├── navbars.png │ │ │ │ ├── navbars@2x.png │ │ │ │ ├── offcanvas.png │ │ │ │ ├── offcanvas@2x.png │ │ │ │ ├── pricing.png │ │ │ │ ├── pricing@2x.png │ │ │ │ ├── product.png │ │ │ │ ├── product@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 │ │ │ │ ├── browserconfig.xml │ │ │ │ ├── favicon-16x16.png │ │ │ │ ├── favicon-32x32.png │ │ │ │ ├── favicon.ico │ │ │ │ ├── manifest.json │ │ │ │ ├── mstile-144x144.png │ │ │ │ ├── mstile-150x150.png │ │ │ │ ├── mstile-310x150.png │ │ │ │ ├── mstile-310x310.png │ │ │ │ ├── mstile-70x70.png │ │ │ │ └── safari-pinned-tab.svg │ │ ├── js │ │ │ ├── docs.min.js │ │ │ ├── src │ │ │ │ ├── application.js │ │ │ │ ├── ie-emulation-modes-warning.js │ │ │ │ └── search.js │ │ │ └── vendor │ │ │ │ ├── anchor.min.js │ │ │ │ ├── bs-custom-file-input.min.js │ │ │ │ ├── clipboard.min.js │ │ │ │ └── jquery.slim.min.js │ │ └── scss │ │ │ ├── _ads.scss │ │ │ ├── _algolia.scss │ │ │ ├── _anchor.scss │ │ │ ├── _brand.scss │ │ │ ├── _browser-bugs.scss │ │ │ ├── _buttons.scss │ │ │ ├── _callouts.scss │ │ │ ├── _clipboard-js.scss │ │ │ ├── _colors.scss │ │ │ ├── _component-examples.scss │ │ │ ├── _content.scss │ │ │ ├── _footer.scss │ │ │ ├── _masthead.scss │ │ │ ├── _nav.scss │ │ │ ├── _placeholder-img.scss │ │ │ ├── _sidebar.scss │ │ │ ├── _skippy.scss │ │ │ ├── _syntax.scss │ │ │ ├── _variables.scss │ │ │ └── docs.scss │ ├── browser-bugs.md │ ├── components │ │ ├── alerts.md │ │ ├── badge.md │ │ ├── breadcrumb.md │ │ ├── button-group.md │ │ ├── buttons.md │ │ ├── card.md │ │ ├── carousel.md │ │ ├── collapse.md │ │ ├── dropdowns.md │ │ ├── forms.md │ │ ├── input-group.md │ │ ├── jumbotron.md │ │ ├── list-group.md │ │ ├── media-object.md │ │ ├── modal.md │ │ ├── navbar.md │ │ ├── navs.md │ │ ├── pagination.md │ │ ├── popovers.md │ │ ├── progress.md │ │ ├── scrollspy.md │ │ ├── spinners.md │ │ ├── toasts.md │ │ └── tooltips.md │ ├── content │ │ ├── code.md │ │ ├── figures.md │ │ ├── images.md │ │ ├── reboot.md │ │ ├── tables.md │ │ └── typography.md │ ├── examples │ │ ├── .stylelintrc │ │ ├── album │ │ │ ├── album.css │ │ │ ├── album.rtl.css │ │ │ └── index.html │ │ ├── blog │ │ │ ├── blog.css │ │ │ ├── blog.rtl.css │ │ │ └── index.html │ │ ├── carousel │ │ │ ├── carousel.css │ │ │ ├── carousel.rtl.css │ │ │ └── index.html │ │ ├── checkout │ │ │ ├── form-validation.css │ │ │ ├── form-validation.js │ │ │ ├── form-validation.rtl.css │ │ │ └── index.html │ │ ├── cover │ │ │ ├── cover.css │ │ │ ├── cover.rtl.css │ │ │ └── index.html │ │ ├── dashboard │ │ │ ├── dashboard.css │ │ │ ├── dashboard.js │ │ │ ├── dashboard.rtl.css │ │ │ └── index.html │ │ ├── floating-labels │ │ │ ├── floating-labels.css │ │ │ ├── floating-labels.rtl.css │ │ │ └── index.html │ │ ├── grid │ │ │ ├── grid.css │ │ │ ├── grid.rtl.css │ │ │ └── index.html │ │ ├── index.html │ │ ├── jumbotron │ │ │ ├── index.html │ │ │ ├── jumbotron.css │ │ │ └── jumbotron.rtl.css │ │ ├── navbar-bottom │ │ │ └── index.html │ │ ├── navbar-fixed │ │ │ ├── index.html │ │ │ ├── navbar-top-fixed.css │ │ │ └── navbar-top-fixed.rtl.css │ │ ├── navbar-static │ │ │ ├── index.html │ │ │ ├── navbar-top.css │ │ │ └── navbar-top.rtl.css │ │ ├── navbars │ │ │ ├── index.html │ │ │ ├── navbar.css │ │ │ └── navbar.rtl.css │ │ ├── offcanvas │ │ │ ├── index.html │ │ │ ├── offcanvas.css │ │ │ ├── offcanvas.js │ │ │ └── offcanvas.rtl.css │ │ ├── pricing │ │ │ ├── index.html │ │ │ ├── pricing.css │ │ │ └── pricing.rtl.css │ │ ├── product │ │ │ ├── index.html │ │ │ ├── product.css │ │ │ └── product.rtl.css │ │ ├── sign-in │ │ │ ├── index.html │ │ │ ├── signin.css │ │ │ └── signin.rtl.css │ │ ├── starter-template │ │ │ ├── index.html │ │ │ ├── starter-template.css │ │ │ └── starter-template.rtl.css │ │ ├── sticky-footer-navbar │ │ │ ├── index.html │ │ │ ├── sticky-footer-navbar.css │ │ │ └── sticky-footer-navbar.rtl.css │ │ └── sticky-footer │ │ │ ├── index.html │ │ │ ├── sticky-footer.css │ │ │ └── sticky-footer.rtl.css │ ├── extend │ │ ├── approach.md │ │ └── icons.md │ ├── getting-started │ │ ├── accessibility.md │ │ ├── best-practices.md │ │ ├── browsers-devices.md │ │ ├── build-tools.md │ │ ├── contents.md │ │ ├── download.md │ │ ├── introduction.md │ │ ├── javascript.md │ │ ├── theming.md │ │ └── webpack.md │ ├── layout │ │ ├── grid.md │ │ ├── overview.md │ │ └── utilities-for-layout.md │ ├── migration.md │ └── utilities │ │ ├── borders.md │ │ ├── clearfix.md │ │ ├── close-icon.md │ │ ├── colors.md │ │ ├── display.md │ │ ├── embed.md │ │ ├── flex.md │ │ ├── float.md │ │ ├── image-replacement.md │ │ ├── interactions.md │ │ ├── overflow.md │ │ ├── position.md │ │ ├── screen-readers.md │ │ ├── shadows.md │ │ ├── sizing.md │ │ ├── spacing.md │ │ ├── stretched-link.md │ │ ├── text.md │ │ ├── vertical-align.md │ │ └── visibility.md └── versions.html ├── favicon.ico ├── index.html ├── robots.txt └── sw.js /.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 | env: { 13 | test: { 14 | plugins: [ 'istanbul' ] 15 | } 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | # https://github.com/browserslist/browserslist#readme 2 | 3 | >= 1% 4 | last 1 major version 5 | not dead 6 | Chrome >= 45 7 | Firefox >= 38 8 | Edge >= 12 9 | Explorer >= 10 10 | iOS >= 9 11 | Safari >= 9 12 | Android >= 4.4 13 | Opera >= 30 14 | -------------------------------------------------------------------------------- /.bundlewatch.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | { 4 | "path": "./dist/css/bootstrap-grid.css", 5 | "maxSize": "7 kB" 6 | }, 7 | { 8 | "path": "./dist/css/bootstrap-grid.min.css", 9 | "maxSize": "6.25 kB" 10 | }, 11 | { 12 | "path": "./dist/css/bootstrap-reboot.css", 13 | "maxSize": "2 kB" 14 | }, 15 | { 16 | "path": "./dist/css/bootstrap-reboot.min.css", 17 | "maxSize": "2 kB" 18 | }, 19 | { 20 | "path": "./dist/css/bootstrap.css", 21 | "maxSize": "25.5 kB" 22 | }, 23 | { 24 | "path": "./dist/css/bootstrap.min.css", 25 | "maxSize": "23.5 kB" 26 | }, 27 | { 28 | "path": "./dist/js/bootstrap.bundle.js", 29 | "maxSize": "47.5 kB" 30 | }, 31 | { 32 | "path": "./dist/js/bootstrap.bundle.min.js", 33 | "maxSize": "21.5 kB" 34 | }, 35 | { 36 | "path": "./dist/js/bootstrap.js", 37 | "maxSize": "25.5 kB" 38 | }, 39 | { 40 | "path": "./dist/js/bootstrap.min.js", 41 | "maxSize": "14.75 kB" 42 | } 43 | ], 44 | "ci": { 45 | "trackBranches": [ 46 | "main", 47 | "v4-dev" 48 | ] 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /.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 | 13 | [*.md] 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/*.min.js 2 | **/dist/ 3 | **/vendor/ 4 | /_gh_pages/ 5 | /js/coverage/ 6 | /site/sw.js 7 | /package.js 8 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": [ 4 | "plugin:import/errors", 5 | "plugin:import/warnings", 6 | "plugin:unicorn/recommended", 7 | "xo/esnext", 8 | "xo/browser" 9 | ], 10 | "rules": { 11 | "capitalized-comments": "off", 12 | "indent": [ 13 | "error", 14 | 2, 15 | { 16 | "MemberExpression": "off", 17 | "SwitchCase": 1 18 | } 19 | ], 20 | "max-params": [ 21 | "warn", 22 | 5 23 | ], 24 | "new-cap": "off", 25 | "no-console": "error", 26 | "no-mixed-operators": "off", 27 | "no-negated-condition": "off", 28 | "object-curly-spacing": [ 29 | "error", 30 | "always" 31 | ], 32 | "prefer-named-capture-group": "off", 33 | "semi": [ 34 | "error", 35 | "never" 36 | ], 37 | "unicorn/consistent-function-scoping": "off", 38 | "unicorn/explicit-length-check": "off", 39 | "unicorn/import-index": "off", 40 | "unicorn/no-fn-reference-in-iterator": "off", 41 | "unicorn/no-for-loop": "off", 42 | "unicorn/no-null": "off", 43 | "unicorn/no-unused-properties": "error", 44 | "unicorn/no-useless-undefined": "off", 45 | "unicorn/prefer-array-find": "off", 46 | "unicorn/prefer-dataset": "off", 47 | "unicorn/prefer-includes": "off", 48 | "unicorn/prefer-node-append": "off", 49 | "unicorn/prefer-node-remove": "off", 50 | "unicorn/prefer-number-properties": "off", 51 | "unicorn/prefer-optional-catch-binding": "off", 52 | "unicorn/prefer-query-selector": "off", 53 | "unicorn/prefer-reflect-apply": "off", 54 | "unicorn/prefer-set-has": "off", 55 | "unicorn/prevent-abbreviations": "off" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /.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/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Tell us about a bug you may have identified in Bootstrap. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Before opening: 11 | 12 | - [Search for duplicate or closed issues](https://github.com/twbs/bootstrap/issues?utf8=%E2%9C%93&q=is%3Aissue) 13 | - [Validate](https://html5.validator.nu/) any HTML to avoid common problems 14 | - Read the [contributing guidelines](https://github.com/twbs/bootstrap/blob/v4-dev/.github/CONTRIBUTING.md) 15 | 16 | Bug reports must include: 17 | 18 | - Operating system and version (Windows, macOS, Android, iOS) 19 | - Browser and version (Chrome, Firefox, Safari, Internet Explorer, Microsoft Edge, Opera, Android Browser) 20 | - A [reduced test case](https://css-tricks.com/reduced-test-cases/) or suggested fix using [CodePen](https://codepen.io/) or [JS Bin](https://jsbin.com/) 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for a new feature in Bootstrap. 4 | title: '' 5 | labels: feature 6 | assignees: '' 7 | 8 | --- 9 | 10 | Before opening: 11 | 12 | - [Search for duplicate or closed issues](https://github.com/twbs/bootstrap/issues?utf8=%E2%9C%93&q=is%3Aissue) 13 | - Read the [contributing guidelines](https://github.com/twbs/bootstrap/blob/v4-dev/.github/CONTRIBUTING.md) 14 | 15 | Feature requests must include: 16 | 17 | - As much detail as possible for what we should add and why it's important to Bootstrap 18 | - Relevant links to prior art, screenshots, or live demos whenever possible 19 | -------------------------------------------------------------------------------- /.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 | - Join [the official Slack room](https://bootstrap-slack.herokuapp.com/). 10 | - Chat with fellow Bootstrappers in IRC. On the `irc.freenode.net` server, in the `##bootstrap` channel. 11 | - Ask and explore Stack Overflow with the [`bootstrap-4`](https://stackoverflow.com/questions/tagged/bootstrap-4) tag. 12 | -------------------------------------------------------------------------------- /.github/workflows/browserstack.yml: -------------------------------------------------------------------------------- 1 | name: BrowserStack 2 | on: [push] 3 | env: 4 | CI: true 5 | NODE: 12.x 6 | 7 | jobs: 8 | browserstack: 9 | runs-on: ubuntu-latest 10 | if: github.repository == 'twbs/bootstrap' 11 | 12 | steps: 13 | - name: Clone repository 14 | uses: actions/checkout@v2 15 | 16 | - name: Set Node.js version 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: "${{ env.NODE }}" 20 | 21 | - name: Set up npm cache 22 | uses: actions/cache@v2 23 | with: 24 | path: ~/.npm 25 | key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} 26 | restore-keys: | 27 | ${{ runner.OS }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} 28 | ${{ runner.OS }}-node-v${{ env.NODE }}- 29 | 30 | - name: Install npm dependencies 31 | run: npm ci 32 | 33 | - name: Run dist 34 | run: npm run dist 35 | 36 | - name: Run BrowserStack tests 37 | run: npm run js-test-cloud 38 | env: 39 | BROWSER_STACK_ACCESS_KEY: "${{ secrets.BROWSER_STACK_ACCESS_KEY }}" 40 | BROWSER_STACK_USERNAME: "${{ secrets.BROWSER_STACK_USERNAME }}" 41 | -------------------------------------------------------------------------------- /.github/workflows/bundlewatch.yml: -------------------------------------------------------------------------------- 1 | name: Bundlewatch 2 | on: [push, pull_request] 3 | env: 4 | CI: true 5 | NODE: 12.x 6 | 7 | jobs: 8 | bundlewatch: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Clone repository 13 | uses: actions/checkout@v2 14 | 15 | - name: Set Node.js version 16 | uses: actions/setup-node@v1 17 | with: 18 | node-version: "${{ env.NODE }}" 19 | 20 | - name: Set up npm cache 21 | uses: actions/cache@v2 22 | with: 23 | path: ~/.npm 24 | key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} 25 | restore-keys: | 26 | ${{ runner.OS }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} 27 | ${{ runner.OS }}-node-v${{ env.NODE }}- 28 | 29 | - name: Install npm dependencies 30 | run: npm ci 31 | 32 | - name: Run dist 33 | run: npm run dist 34 | 35 | - name: Run bundlewatch 36 | run: npm run bundlewatch 37 | env: 38 | BUNDLEWATCH_GITHUB_TOKEN: "${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }}" 39 | CI_BRANCH_BASE: v4-dev 40 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "Code Scanning - Action" 2 | 3 | on: 4 | push: 5 | schedule: 6 | - cron: "0 0 * * 0" 7 | 8 | jobs: 9 | CodeQL-Build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout repository 14 | uses: actions/checkout@v2 15 | 16 | - name: Initialize CodeQL 17 | uses: github/codeql-action/init@v1 18 | with: 19 | languages: javascript 20 | 21 | - name: Autobuild 22 | uses: github/codeql-action/autobuild@v1 23 | 24 | - name: Perform CodeQL Analysis 25 | uses: github/codeql-action/analyze@v1 26 | -------------------------------------------------------------------------------- /.github/workflows/css.yml: -------------------------------------------------------------------------------- 1 | name: CSS 2 | on: [push, pull_request] 3 | env: 4 | CI: true 5 | NODE: 12.x 6 | 7 | jobs: 8 | css: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Clone repository 13 | uses: actions/checkout@v2 14 | 15 | - name: Set Node.js version 16 | uses: actions/setup-node@v1 17 | with: 18 | node-version: "${{ env.NODE }}" 19 | 20 | - name: Set up npm cache 21 | uses: actions/cache@v2 22 | with: 23 | path: ~/.npm 24 | key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} 25 | restore-keys: | 26 | ${{ runner.OS }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} 27 | ${{ runner.OS }}-node-v${{ env.NODE }}- 28 | 29 | - name: Install npm dependencies 30 | run: npm ci 31 | 32 | - name: Build CSS 33 | run: npm run css 34 | -------------------------------------------------------------------------------- /.github/workflows/dart-sass.yml: -------------------------------------------------------------------------------- 1 | name: CSS (Dart Sass) 2 | on: [push, pull_request] 3 | env: 4 | CI: true 5 | NODE: 12.x 6 | 7 | jobs: 8 | css: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Clone repository 13 | uses: actions/checkout@v2 14 | 15 | - name: Set Node.js version 16 | uses: actions/setup-node@v1 17 | with: 18 | node-version: "${{ env.NODE }}" 19 | 20 | - name: Build CSS with Dart Sass 21 | run: | 22 | npx --package sass@latest sass --version 23 | npx --package sass@latest sass --style expanded --source-map --embed-sources --no-error-css scss/:dist-sass/css/ 24 | ls -Al dist-sass/css 25 | -------------------------------------------------------------------------------- /.github/workflows/js.yml: -------------------------------------------------------------------------------- 1 | name: JS Tests 2 | on: [push, pull_request] 3 | env: 4 | CI: true 5 | 6 | jobs: 7 | run: 8 | name: Node ${{ matrix.node }} 9 | runs-on: ubuntu-latest 10 | 11 | strategy: 12 | fail-fast: false 13 | matrix: 14 | node: [10, 12] 15 | 16 | steps: 17 | - name: Clone repository 18 | uses: actions/checkout@v2 19 | 20 | - name: Set Node.js version 21 | uses: actions/setup-node@v1 22 | with: 23 | node-version: ${{ matrix.node }} 24 | 25 | - name: Set up npm cache 26 | uses: actions/cache@v2 27 | with: 28 | path: ~/.npm 29 | key: ${{ runner.os }}-node-v${{ matrix.node }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}} 30 | restore-keys: | 31 | ${{ runner.OS }}-node-v${{ matrix.node }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} 32 | ${{ runner.OS }}-node-v${{ matrix.node }}- 33 | 34 | - name: Install npm dependencies 35 | run: npm ci 36 | 37 | - name: Run dist 38 | run: npm run js 39 | 40 | - name: Run JS tests 41 | run: npm run js-test 42 | 43 | - name: Run Coveralls 44 | uses: coverallsapp/github-action@master 45 | if: matrix.node == 12 46 | with: 47 | github-token: "${{ secrets.GITHUB_TOKEN }}" 48 | path-to-lcov: "./js/coverage/lcov.info" 49 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | on: [push, pull_request] 3 | env: 4 | CI: true 5 | NODE: 12.x 6 | 7 | jobs: 8 | lint: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Clone repository 13 | uses: actions/checkout@v2 14 | 15 | - name: Set Node.js version 16 | uses: actions/setup-node@v1 17 | with: 18 | node-version: "${{ env.NODE }}" 19 | 20 | - name: Set up npm cache 21 | uses: actions/cache@v2 22 | with: 23 | path: ~/.npm 24 | key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} 25 | restore-keys: | 26 | ${{ runner.OS }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} 27 | ${{ runner.OS }}-node-v${{ env.NODE }}- 28 | 29 | - name: Install npm dependencies 30 | run: npm ci 31 | 32 | - name: Lint 33 | run: npm run lint 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore docs files 2 | /_gh_pages/ 3 | /site/.jekyll-cache 4 | /site/.jekyll-metadata 5 | /site/docs/**/dist/ 6 | # Hugo folders 7 | /resources/ 8 | 9 | # Ignore ruby/bundler files 10 | /.bundle/ 11 | /vendor/ 12 | /.ruby-version 13 | 14 | # Numerous always-ignore extensions 15 | *.diff 16 | *.err 17 | *.log 18 | *.orig 19 | *.rej 20 | *.swo 21 | *.swp 22 | *.vi 23 | *.zip 24 | *~ 25 | 26 | # OS or Editor folders 27 | ._* 28 | .cache 29 | .DS_Store 30 | .idea 31 | .project 32 | .settings 33 | .tmproj 34 | *.esproj 35 | *.sublime-project 36 | *.sublime-workspace 37 | nbproject 38 | Thumbs.db 39 | /.vscode/ 40 | # Local Netlify folder 41 | .netlify 42 | 43 | # Komodo 44 | .komodotools 45 | *.komodoproject 46 | 47 | # Folders to ignore 48 | /js/coverage/ 49 | /node_modules/ 50 | -------------------------------------------------------------------------------- /.stylelintignore: -------------------------------------------------------------------------------- 1 | **/*.min.css 2 | **/dist/ 3 | **/vendor/ 4 | /_gh_pages/ 5 | **/*.rtl.css -------------------------------------------------------------------------------- /.stylelintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "stylelint-config-twbs-bootstrap/scss" 4 | ], 5 | "rules": { 6 | "function-disallowed-list": [ 7 | "calc" 8 | ], 9 | "property-disallowed-list": [ 10 | "border-radius", 11 | "border-top-left-radius", 12 | "border-top-right-radius", 13 | "border-bottom-right-radius", 14 | "border-bottom-left-radius", 15 | "transition" 16 | ] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | bootstrap.rtlcss.com 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | group :development, :test do 4 | gem 'jekyll', '~> 4.1.1' 5 | gem 'jekyll-redirect-from', '~> 0.16.0' 6 | gem 'jekyll-sitemap', '~> 1.4.0' 7 | gem 'jekyll-toc', '~> 0.14.0' 8 | gem 'wdm', '~> 0.1.1', :install_if => Gem.win_platform? 9 | end 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2020 Twitter, Inc. 4 | Copyright (c) 2011-2020 The Bootstrap Authors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /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/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": false, 4 | "node": true 5 | }, 6 | "parserOptions": { 7 | "sourceType": "script" 8 | }, 9 | "extends": "../.eslintrc.json", 10 | "rules": { 11 | "no-console": "off", 12 | "strict": "error" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /build/banner.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const pkg = require('../package.json') 4 | const year = new Date().getFullYear() 5 | 6 | function getBanner(pluginFilename) { 7 | return `/*! 8 | * Bootstrap${pluginFilename ? ` ${pluginFilename}` : ''} v${pkg.version} (${pkg.homepage}) 9 | * Copyright 2011-${year} ${pkg.author} 10 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 11 | */` 12 | } 13 | 14 | module.exports = getBanner 15 | -------------------------------------------------------------------------------- /build/postcss.config.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | module.exports = ctx => ({ 4 | map: ctx.file.dirname.includes('examples') ? false : { 5 | inline: false, 6 | annotation: true, 7 | sourcesContent: true 8 | }, 9 | plugins: { 10 | autoprefixer: { 11 | cascade: false 12 | } 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /build/rollup.config.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('path') 4 | const { babel } = require('@rollup/plugin-babel') 5 | const { nodeResolve } = require('@rollup/plugin-node-resolve') 6 | const banner = require('./banner.js') 7 | 8 | const BUNDLE = process.env.BUNDLE === 'true' 9 | 10 | let fileDest = 'bootstrap.js' 11 | const external = ['jquery', 'popper.js'] 12 | const plugins = [ 13 | babel({ 14 | // Only transpile our source code 15 | exclude: 'node_modules/**', 16 | // Include the helpers in the bundle, at most one copy of each 17 | babelHelpers: 'bundled' 18 | }) 19 | ] 20 | const globals = { 21 | jquery: 'jQuery', // Ensure we use jQuery which is always available even in noConflict mode 22 | 'popper.js': 'Popper' 23 | } 24 | 25 | if (BUNDLE) { 26 | fileDest = 'bootstrap.bundle.js' 27 | // Remove last entry in external array to bundle Popper 28 | external.pop() 29 | delete globals['popper.js'] 30 | plugins.push(nodeResolve()) 31 | } 32 | 33 | module.exports = { 34 | input: path.resolve(__dirname, '../js/src/index.js'), 35 | output: { 36 | banner, 37 | file: path.resolve(__dirname, `../dist/js/${fileDest}`), 38 | format: 'umd', 39 | globals, 40 | name: 'bootstrap' 41 | }, 42 | external, 43 | plugins 44 | } 45 | -------------------------------------------------------------------------------- /build/rtl-docs.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const glob = require('glob') 4 | const pkg = require('../package.json') 5 | const rtlcss = require('rtlcss') 6 | const fs = require('fs') 7 | const v = pkg.version.match(/\d+\.\d+/)[0] 8 | // options is optional 9 | glob(`site/docs/${v}/examples/**/*.css`, { 10 | ignore: `site/docs/${v}/examples/**/*.rtl.css` 11 | }, (er, files) => { 12 | files.forEach((path) => { 13 | fs.writeFileSync(path.replace('.css', '.rtl.css'), rtlcss.process(fs.readFileSync(path))) 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /build/svgo.yml: -------------------------------------------------------------------------------- 1 | # Usage: 2 | # install svgo globally: `npm i -g svgo` 3 | # svgo --config=build/svgo.yml --input=foo.svg 4 | 5 | # https://github.com/svg/svgo/blob/master/docs/how-it-works/en.md 6 | # replace default config 7 | 8 | multipass: true 9 | #full: true 10 | 11 | # https://github.com/svg/svgo/blob/master/lib/svgo/js2svg.js#L6 for more config options 12 | 13 | js2svg: 14 | pretty: true 15 | indent: 2 16 | 17 | plugins: 18 | # remove this with IE 11 is no longer supported 19 | - addAttributesToSVGElement: 20 | attributes: 21 | - focusable: false 22 | - cleanupAttrs: true 23 | - cleanupEnableBackground: true 24 | - cleanupIDs: true 25 | - cleanupListOfValues: true 26 | - cleanupNumericValues: true 27 | - collapseGroups: true 28 | - convertColors: true 29 | - convertPathData: true 30 | - convertShapeToPath: true 31 | - convertStyleToAttrs: true 32 | - convertTransform: true 33 | - inlineStyles: true 34 | - mergePaths: true 35 | - minifyStyles: true 36 | - moveElemsAttrsToGroup: true 37 | - moveGroupAttrsToElems: true 38 | - removeAttrs: 39 | attrs: 40 | - "data-name" 41 | - removeComments: true 42 | - removeDesc: true 43 | - removeDoctype: true 44 | - removeEditorsNSData: true 45 | - removeEmptyAttrs: true 46 | - removeEmptyContainers: true 47 | - removeEmptyText: true 48 | - removeHiddenElems: true 49 | - removeMetadata: true 50 | - removeNonInheritableGroupAttrs: true 51 | - removeTitle: false 52 | - removeUnknownsAndDefaults: 53 | keepRoleAttr: true 54 | - removeUnusedNS: true 55 | - removeUselessDefs: true 56 | - removeUselessStrokeAndFill: true 57 | - removeViewBox: false 58 | - removeXMLNS: false 59 | - removeXMLProcInst: true 60 | - sortAttrs: true 61 | -------------------------------------------------------------------------------- /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 | "extra": { 30 | "branch-alias": { 31 | "dev-master": "3.3.x-dev" 32 | } 33 | }, 34 | "replace": { 35 | "twitter/bootstrap": "self.version" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /js/dist/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v4.5.3): index.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | (function ($) { 8 | if (typeof $ === 'undefined') { 9 | throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.'); 10 | } 11 | 12 | var version = $.fn.jquery.split(' ')[0].split('.'); 13 | var minMajor = 1; 14 | var ltMajor = 2; 15 | var minMinor = 9; 16 | var minPatch = 1; 17 | var maxMajor = 4; 18 | 19 | if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) { 20 | throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0'); 21 | } 22 | })($); 23 | -------------------------------------------------------------------------------- /js/src/index.js: -------------------------------------------------------------------------------- 1 | import Alert from './alert' 2 | import Button from './button' 3 | import Carousel from './carousel' 4 | import Collapse from './collapse' 5 | import Dropdown from './dropdown' 6 | import Modal from './modal' 7 | import Popover from './popover' 8 | import Scrollspy from './scrollspy' 9 | import Tab from './tab' 10 | import Toast from './toast' 11 | import Tooltip from './tooltip' 12 | import Util from './util' 13 | 14 | /** 15 | * -------------------------------------------------------------------------- 16 | * Bootstrap (v4.5.3): index.js 17 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 18 | * -------------------------------------------------------------------------- 19 | */ 20 | 21 | export { 22 | Util, 23 | Alert, 24 | Button, 25 | Carousel, 26 | Collapse, 27 | Dropdown, 28 | Modal, 29 | Popover, 30 | Scrollspy, 31 | Tab, 32 | Toast, 33 | Tooltip 34 | } 35 | -------------------------------------------------------------------------------- /js/tests/browsers.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | /* eslint-disable camelcase */ 3 | 4 | const browsers = { 5 | safariMac: { 6 | base: 'BrowserStack', 7 | os: 'OS X', 8 | os_version: 'High Sierra', 9 | browser: 'Safari', 10 | browser_version: 'latest' 11 | }, 12 | chromeMac: { 13 | base: 'BrowserStack', 14 | os: 'OS X', 15 | os_version: 'High Sierra', 16 | browser: 'Chrome', 17 | browser_version: 'latest' 18 | }, 19 | firefoxMac: { 20 | base: 'BrowserStack', 21 | os: 'OS X', 22 | os_version: 'High Sierra', 23 | browser: 'Firefox', 24 | browser_version: 'latest' 25 | }, 26 | edgeWin10: { 27 | base: 'BrowserStack', 28 | os: 'Windows', 29 | os_version: '10', 30 | browser: 'Edge', 31 | browser_version: '15' 32 | }, 33 | ie11Win10: { 34 | base: 'BrowserStack', 35 | os: 'Windows', 36 | os_version: '10', 37 | browser: 'IE', 38 | browser_version: '11.0' 39 | }, 40 | chromeWin10: { 41 | base: 'BrowserStack', 42 | os: 'Windows', 43 | os_version: '10', 44 | browser: 'Chrome', 45 | browser_version: 'latest' 46 | }, 47 | firefoxWin10: { 48 | base: 'BrowserStack', 49 | os: 'Windows', 50 | os_version: '10', 51 | browser: 'Firefox', 52 | browser_version: 'latest' 53 | }, 54 | ie10Win8: { 55 | base: 'BrowserStack', 56 | os: 'Windows', 57 | os_version: '8', 58 | browser: 'IE', 59 | browser_version: '10.0' 60 | }, 61 | iphoneX: { 62 | base: 'BrowserStack', 63 | os: 'ios', 64 | os_version: '11.0', 65 | device: 'iPhone X', 66 | real_mobile: true 67 | }, 68 | pixel2: { 69 | base: 'BrowserStack', 70 | os: 'android', 71 | os_version: '8.0', 72 | device: 'Google Pixel 2', 73 | real_mobile: true 74 | } 75 | } 76 | 77 | const browsersKeys = Object.keys(browsers) 78 | 79 | module.exports = { 80 | browsers, 81 | browsersKeys 82 | } 83 | -------------------------------------------------------------------------------- /js/tests/integration/bundle.js: -------------------------------------------------------------------------------- 1 | import 'popper.js' 2 | import $ from 'jquery' 3 | import bootstrap from '../../../dist/js/bootstrap' 4 | 5 | $(() => { 6 | $('#resultUID').text(bootstrap.Util.getUID('bs')) 7 | $('[data-toggle="tooltip"]').tooltip() 8 | }) 9 | -------------------------------------------------------------------------------- /js/tests/integration/rollup.bundle.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | 3 | const commonjs = require('@rollup/plugin-commonjs') 4 | const { babel } = require('@rollup/plugin-babel') 5 | const { nodeResolve } = require('@rollup/plugin-node-resolve') 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 | nodeResolve(), 15 | commonjs(), 16 | babel({ 17 | exclude: 'node_modules/**', 18 | babelHelpers: 'bundled' 19 | }) 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /js/tests/unit/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "../../../.eslintrc.json" 4 | ], 5 | "parserOptions": { 6 | "ecmaVersion": 5, 7 | "sourceType": "script" 8 | }, 9 | "env": { 10 | "es6": false, 11 | "jquery": true, 12 | "qunit": true 13 | }, 14 | "globals": { 15 | "bootstrap": false, 16 | "sinon": false, 17 | "Util": false, 18 | "Alert": false, 19 | "Button": false, 20 | "Carousel": false, 21 | "Simulator": false, 22 | "Toast": false 23 | }, 24 | "rules": { 25 | "no-var": "off", 26 | "object-shorthand": "off", 27 | "prefer-arrow-callback": "off", 28 | "prefer-template": "off", 29 | "prefer-rest-params": "off" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /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 | Copy-Item $env:SourcesPath\LICENSE $env:SourcesPath\LICENSE.txt # has to be .txt extension, don't check in 8 | 9 | # parse the version number out of package.json 10 | $bsversionParts = ((Get-Content $env:SourcesPath\package.json) -join "`n" | ConvertFrom-Json).version.split('-', 2) # split the version on the '-' 11 | $bsversion = $bsversionParts[0] 12 | 13 | if ($bsversionParts.Length -gt 1) { 14 | $bsversion += '-' + $bsversionParts[1].replace('.', '').replace('-', '_') # strip out invalid chars from the PreRelease part 15 | } 16 | 17 | # create packages 18 | & $nuget pack "$env:SourcesPath\nuget\bootstrap.nuspec" -Verbosity detailed -NonInteractive -NoPackageAnalysis -BasePath $env:SourcesPath -Version $bsversion 19 | & $nuget pack "$env:SourcesPath\nuget\bootstrap.sass.nuspec" -Verbosity detailed -NonInteractive -NoPackageAnalysis -BasePath $env:SourcesPath -Version $bsversion 20 | -------------------------------------------------------------------------------- /nuget/bootstrap.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bootstrap 5 | 6 | 4 7 | Bootstrap CSS 8 | The Bootstrap Authors, Twitter Inc. 9 | bootstrap 10 | The most popular front-end framework for developing responsive, mobile first projects on the web. 11 | https://blog.getbootstrap.com/ 12 | Bootstrap framework in CSS. Includes JavaScript 13 | en-us 14 | https://getbootstrap.com/ 15 | bootstrap.png 16 | LICENSE.txt 17 | Copyright 2017-2020 18 | false 19 | 20 | 21 | 22 | 23 | css mobile-first responsive front-end framework web 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /nuget/bootstrap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RTLCSS/bootstrap/e3441d8f5989d932a60ffa94a09bbb37b83c4cbe/nuget/bootstrap.png -------------------------------------------------------------------------------- /nuget/bootstrap.sass.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bootstrap.sass 5 | 6 | 4 7 | Bootstrap Sass 8 | The Bootstrap Authors, Twitter Inc. 9 | bootstrap 10 | The most popular front-end framework for developing responsive, mobile first projects on the web. 11 | https://blog.getbootstrap.com/ 12 | Bootstrap framework in Sass. Includes JavaScript 13 | en-us 14 | https://getbootstrap.com/ 15 | bootstrap.png 16 | LICENSE.txt 17 | Copyright 2017-2020 18 | false 19 | 20 | 21 | 22 | 23 | css sass mobile-first responsive front-end framework web 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /package.js: -------------------------------------------------------------------------------- 1 | // package metadata file for Meteor.js 2 | 3 | Package.describe({ 4 | name: 'twbs:bootstrap', // https://atmospherejs.com/twbs/bootstrap 5 | summary: 'The most popular front-end framework for developing responsive, mobile first projects on the web.', 6 | version: '4.5.3', 7 | git: 'https://github.com/twbs/bootstrap.git' 8 | }); 9 | 10 | Package.onUse(function (api) { 11 | api.versionsFrom('METEOR@1.0'); 12 | api.use('jquery', 'client'); 13 | api.addFiles([ 14 | 'dist/css/bootstrap.css', 15 | 'dist/js/bootstrap.js' 16 | ], 'client'); 17 | }); 18 | -------------------------------------------------------------------------------- /scss/_alert.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Base styles 3 | // 4 | 5 | .alert { 6 | position: relative; 7 | padding: $alert-padding-y $alert-padding-x; 8 | margin-bottom: $alert-margin-bottom; 9 | border: $alert-border-width solid transparent; 10 | @include border-radius($alert-border-radius); 11 | } 12 | 13 | // Headings for larger alerts 14 | .alert-heading { 15 | // Specified to prevent conflicts of changing $headings-color 16 | color: inherit; 17 | } 18 | 19 | // Provide class for links that match alerts 20 | .alert-link { 21 | font-weight: $alert-link-font-weight; 22 | } 23 | 24 | 25 | // Dismissible alerts 26 | // 27 | // Expand the right padding and account for the close button's positioning. 28 | 29 | .alert-dismissible { 30 | padding-right: $close-font-size + $alert-padding-x * 2; 31 | 32 | // Adjust close link position 33 | .close { 34 | position: absolute; 35 | top: 0; 36 | right: 0; 37 | z-index: 2; 38 | padding: $alert-padding-y $alert-padding-x; 39 | color: inherit; 40 | } 41 | } 42 | 43 | 44 | // Alternate styles 45 | // 46 | // Generate contextual modifier classes for colorizing the alert. 47 | 48 | @each $color, $value in $theme-colors { 49 | .alert-#{$color} { 50 | @include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /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 | display: inline-block; 8 | padding: $badge-padding-y $badge-padding-x; 9 | @include font-size($badge-font-size); 10 | font-weight: $badge-font-weight; 11 | line-height: 1; 12 | text-align: center; 13 | white-space: nowrap; 14 | vertical-align: baseline; 15 | @include border-radius($badge-border-radius); 16 | @include transition($badge-transition); 17 | 18 | @at-root a#{&} { 19 | @include hover-focus() { 20 | text-decoration: none; 21 | } 22 | } 23 | 24 | // Empty badges collapse automatically 25 | &:empty { 26 | display: none; 27 | } 28 | } 29 | 30 | // Quick fix for badges in buttons 31 | .btn .badge { 32 | position: relative; 33 | top: -1px; 34 | } 35 | 36 | // Pill badges 37 | // 38 | // Make them extra rounded with a modifier to replace v3's badges. 39 | 40 | .badge-pill { 41 | padding-right: $badge-pill-padding-x; 42 | padding-left: $badge-pill-padding-x; 43 | @include border-radius($badge-pill-border-radius); 44 | } 45 | 46 | // Colors 47 | // 48 | // Contextual variations (linked badges get darker on :hover). 49 | 50 | @each $color, $value in $theme-colors { 51 | .badge-#{$color} { 52 | @include badge-variant($value); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /scss/_breadcrumb.scss: -------------------------------------------------------------------------------- 1 | .breadcrumb { 2 | display: flex; 3 | flex-wrap: wrap; 4 | padding: $breadcrumb-padding-y $breadcrumb-padding-x; 5 | margin-bottom: $breadcrumb-margin-bottom; 6 | @include font-size($breadcrumb-font-size); 7 | list-style: none; 8 | background-color: $breadcrumb-bg; 9 | @include border-radius($breadcrumb-border-radius); 10 | } 11 | 12 | .breadcrumb-item { 13 | display: flex; 14 | 15 | // The separator between breadcrumbs (by default, a forward-slash: "/") 16 | + .breadcrumb-item { 17 | padding-left: $breadcrumb-item-padding; 18 | 19 | &::before { 20 | display: inline-block; // Suppress underlining of the separator in modern browsers 21 | padding-right: $breadcrumb-item-padding; 22 | color: $breadcrumb-divider-color; 23 | content: escape-svg($breadcrumb-divider); 24 | } 25 | } 26 | 27 | // IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built 28 | // without `