From bae2d7c84f52edb04eb2dc5f73a9c98ca9cb082b Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Tue, 4 Mar 2025 12:18:02 -0800 Subject: [PATCH 01/20] Reorganize scss folder --- scss/_config.scss | 58 ++++++++++++++++ scss/_grid.scss | 39 ----------- scss/_mixins.scss | 6 +- scss/_variables.scss | 80 +++++++++++----------- scss/bootstrap.scss | 11 +-- scss/{mixins => layout}/_breakpoints.scss | 0 scss/{ => layout}/_containers.scss | 14 ++++ scss/layout/_grid.scss | 83 +++++++++++++++++++++++ scss/layout/index.scss | 3 + scss/mixins/_container.scss | 11 --- 10 files changed, 208 insertions(+), 97 deletions(-) create mode 100644 scss/_config.scss delete mode 100644 scss/_grid.scss rename scss/{mixins => layout}/_breakpoints.scss (100%) rename scss/{ => layout}/_containers.scss (72%) create mode 100644 scss/layout/_grid.scss create mode 100644 scss/layout/index.scss delete mode 100644 scss/mixins/_container.scss diff --git a/scss/_config.scss b/scss/_config.scss new file mode 100644 index 000000000000..8116ba1799b3 --- /dev/null +++ b/scss/_config.scss @@ -0,0 +1,58 @@ +// Configuration +// +// Variables and settings not related to theme, components, and more go here. It does include layout. + +$prefix: bs- !default; + +$enable-container-classes: true !default; +// more to come here… + +// Grid breakpoints +// +// Define the minimum dimensions at which your layout will change, +// adapting to different screen sizes, for use in media queries. + +// scss-docs-start grid-breakpoints +$grid-breakpoints: ( + xs: 0, + sm: 576px, + md: 768px, + lg: 992px, + xl: 1200px, + xxl: 1400px +) !default; +// scss-docs-end grid-breakpoints + +// Grid columns +// +// Set the number of columns and specify the width of the gutters. + +$grid-columns: 12 !default; +$grid-gutter-width: 1.5rem !default; +$grid-row-columns: 6 !default; + +// Grid containers +// +// Define the maximum width of `.container` for different screen sizes. + +// scss-docs-start container-max-widths +$container-max-widths: ( + sm: 540px, + md: 720px, + lg: 960px, + xl: 1140px, + xxl: 1320px +) !default; +// scss-docs-end container-max-widths + +$container-padding-x: $grid-gutter-width !default; + + +// Characters which are escaped by the escape-svg function +$escaped-characters: ( + ("<", "%3c"), + (">", "%3e"), + ("#", "%23"), + ("(", "%28"), + (")", "%29"), +) !default; diff --git a/scss/_grid.scss b/scss/_grid.scss deleted file mode 100644 index 048f8009a363..000000000000 --- a/scss/_grid.scss +++ /dev/null @@ -1,39 +0,0 @@ -// Row -// -// Rows contain your columns. - -:root { - @each $name, $value in $grid-breakpoints { - --#{$prefix}breakpoint-#{$name}: #{$value}; - } -} - -@if $enable-grid-classes { - .row { - @include make-row(); - - > * { - @include make-col-ready(); - } - } -} - -@if $enable-cssgrid { - .grid { - display: grid; - grid-template-rows: repeat(var(--#{$prefix}rows, 1), 1fr); - grid-template-columns: repeat(var(--#{$prefix}columns, #{$grid-columns}), 1fr); - gap: var(--#{$prefix}gap, #{$grid-gutter-width}); - - @include make-cssgrid(); - } -} - - -// Columns -// -// Common styles for small and large grid columns - -@if $enable-grid-classes { - @include make-grid-columns(); -} diff --git a/scss/_mixins.scss b/scss/_mixins.scss index 309c0a453349..944d7579958d 100644 --- a/scss/_mixins.scss +++ b/scss/_mixins.scss @@ -9,7 +9,7 @@ @import "mixins/deprecate"; // Helpers -@import "mixins/breakpoints"; +// @import "mixins/breakpoints"; @import "mixins/color-mode"; @import "mixins/color-scheme"; @import "mixins/image"; @@ -37,5 +37,5 @@ @import "mixins/transition"; // Layout -@import "mixins/container"; -@import "mixins/grid"; +// @import "mixins/container"; +// @import "mixins/grid"; diff --git a/scss/_variables.scss b/scss/_variables.scss index 58e0a2c777ed..a78a607e8c49 100644 --- a/scss/_variables.scss +++ b/scss/_variables.scss @@ -389,7 +389,7 @@ $color-mode-type: data !default; // `data` or `media-query` // Prefix for :root CSS variables -$prefix: bs- !default; +// $prefix: bs- !default; // Gradient // @@ -474,54 +474,54 @@ $icon-link-icon-transform: translate3d(.25em, 0, 0) !default; $paragraph-margin-bottom: 1rem !default; -// Grid breakpoints -// -// Define the minimum dimensions at which your layout will change, -// adapting to different screen sizes, for use in media queries. - -// scss-docs-start grid-breakpoints -$grid-breakpoints: ( - xs: 0, - sm: 576px, - md: 768px, - lg: 992px, - xl: 1200px, - xxl: 1400px -) !default; -// scss-docs-end grid-breakpoints +// // Grid breakpoints +// // +// // Define the minimum dimensions at which your layout will change, +// // adapting to different screen sizes, for use in media queries. -@include _assert-ascending($grid-breakpoints, "$grid-breakpoints"); -@include _assert-starts-at-zero($grid-breakpoints, "$grid-breakpoints"); +// // scss-docs-start grid-breakpoints +// $grid-breakpoints: ( +// xs: 0, +// sm: 576px, +// md: 768px, +// lg: 992px, +// xl: 1200px, +// xxl: 1400px +// ) !default; +// // scss-docs-end grid-breakpoints +// @include _assert-ascending($grid-breakpoints, "$grid-breakpoints"); +// @include _assert-starts-at-zero($grid-breakpoints, "$grid-breakpoints"); -// Grid containers -// -// Define the maximum width of `.container` for different screen sizes. - -// scss-docs-start container-max-widths -$container-max-widths: ( - sm: 540px, - md: 720px, - lg: 960px, - xl: 1140px, - xxl: 1320px -) !default; -// scss-docs-end container-max-widths -@include _assert-ascending($container-max-widths, "$container-max-widths"); +// // Grid containers +// // +// // Define the maximum width of `.container` for different screen sizes. +// // scss-docs-start container-max-widths +// $container-max-widths: ( +// sm: 540px, +// md: 720px, +// lg: 960px, +// xl: 1140px, +// xxl: 1320px +// ) !default; +// // scss-docs-end container-max-widths -// Grid columns -// -// Set the number of columns and specify the width of the gutters. +// @include _assert-ascending($container-max-widths, "$container-max-widths"); + + +// // Grid columns +// // +// // Set the number of columns and specify the width of the gutters. -$grid-columns: 12 !default; -$grid-gutter-width: 1.5rem !default; -$grid-row-columns: 6 !default; +// $grid-columns: 12 !default; +// $grid-gutter-width: 1.5rem !default; +// $grid-row-columns: 6 !default; -// Container padding +// // Container padding -$container-padding-x: $grid-gutter-width !default; +// $container-padding-x: $grid-gutter-width !default; // Components diff --git a/scss/bootstrap.scss b/scss/bootstrap.scss index 449d704878fa..244401e02e40 100644 --- a/scss/bootstrap.scss +++ b/scss/bootstrap.scss @@ -1,9 +1,11 @@ -@import "mixins/banner"; -@include bsBanner(""); +// @import "mixins/banner"; +// @include bsBanner(""); // scss-docs-start import-stack // Configuration +@use "config" as *; + @import "functions"; @import "variables"; @import "variables-dark"; @@ -16,8 +18,9 @@ @import "reboot"; @import "type"; @import "images"; -@import "containers"; -@import "grid"; +// @import "containers"; +// @import "grid"; +@import "layout"; @import "tables"; @import "forms"; @import "buttons"; diff --git a/scss/mixins/_breakpoints.scss b/scss/layout/_breakpoints.scss similarity index 100% rename from scss/mixins/_breakpoints.scss rename to scss/layout/_breakpoints.scss diff --git a/scss/_containers.scss b/scss/layout/_containers.scss similarity index 72% rename from scss/_containers.scss rename to scss/layout/_containers.scss index 83b31381bf89..b4f5d6b10f7b 100644 --- a/scss/_containers.scss +++ b/scss/layout/_containers.scss @@ -1,6 +1,20 @@ +@use "../config" as *; +@use "breakpoints" as *; + // Container widths // // Set the container width, and override it for fixed navbars in media queries. +// Container mixins + +@mixin make-container($gutter: $container-padding-x) { + --#{$prefix}gutter-x: #{$gutter}; + --#{$prefix}gutter-y: 0; + width: 100%; + padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list + padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list + margin-right: auto; + margin-left: auto; +} @if $enable-container-classes { // Single container class with breakpoint max-widths diff --git a/scss/layout/_grid.scss b/scss/layout/_grid.scss new file mode 100644 index 000000000000..39b76829ec34 --- /dev/null +++ b/scss/layout/_grid.scss @@ -0,0 +1,83 @@ +@use "sass:map"; +@use "../config" as *; +@use "breakpoints" as *; + +// mdo-do +// - check gap utilities as replacement for gutter classes from v5 + +// Row +// +// Rows contain your columns. + +:root { + @each $name, $value in $grid-breakpoints { + --#{$prefix}breakpoint-#{$name}: #{$value}; + } +} + +.grid { + --#{$prefix}columns: #{$grid-columns}; + --#{$prefix}rows: 1; + --#{$prefix}gap: #{$grid-gutter-width}; + + display: grid; + grid-template-rows: repeat(var(--#{$prefix}rows), 1fr); + grid-template-columns: repeat(var(--#{$prefix}columns), 1fr); + gap: var(--#{$prefix}gap); +} + +@each $breakpoint in map.keys($grid-breakpoints) { + $infix: breakpoint-infix($breakpoint, $grid-breakpoints); + + @include media-breakpoint-up($breakpoint, $grid-breakpoints) { + @if $grid-columns > 0 { + @for $i from 1 through $grid-columns { + .col#{$infix}-#{$i} { + grid-column: auto / span $i; + } + + .end#{$infix}-#{$i} { + grid-column-end: $i; + } + } + + // Start with `1` because `0` is an invalid value. + // Ends with `$columns - 1` because offsetting by the width of an entire row isn't possible. + @for $i from 1 through ($grid-columns - 1) { + .col-start#{$infix}-#{$i} { + grid-column-start: $i; + } + } + } + } +} + +// mdo-do: add to utilities? +.grid-cols-subgrid { + grid-template-columns: subgrid; +} + +.grid-fill { + --#{$prefix}gap: #{$grid-gutter-width}; + + display: grid; + grid-auto-flow: row; + grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); + gap: var(--#{$prefix}gap); +} + +// mdo-do: add to utilities? +.g-col-auto { + grid-column: auto/auto; +} + +// mdo-do: add to utilities? +.grid-cols-3 { + --#{$prefix}columns: 3; +} +.grid-cols-4 { + --#{$prefix}columns: 4; +} +.grid-cols-6 { + --#{$prefix}columns: 6; +} diff --git a/scss/layout/index.scss b/scss/layout/index.scss new file mode 100644 index 000000000000..16303b4ac852 --- /dev/null +++ b/scss/layout/index.scss @@ -0,0 +1,3 @@ +@import "breakpoints"; +@import "containers"; +@import "grid"; \ No newline at end of file diff --git a/scss/mixins/_container.scss b/scss/mixins/_container.scss deleted file mode 100644 index 2a5286536f01..000000000000 --- a/scss/mixins/_container.scss +++ /dev/null @@ -1,11 +0,0 @@ -// Container mixins - -@mixin make-container($gutter: $container-padding-x) { - --#{$prefix}gutter-x: #{$gutter}; - --#{$prefix}gutter-y: 0; - width: 100%; - padding-right: calc(var(--#{$prefix}gutter-x) * .5); - padding-left: calc(var(--#{$prefix}gutter-x) * .5); - margin-right: auto; - margin-left: auto; -} From 15df1896d956b4276352da9bce574a92b7c51072 Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Tue, 18 Feb 2025 09:50:10 -0800 Subject: [PATCH 02/20] Migrate to Sass modules --- package-lock.json | 425 ++++++++++--- package.json | 6 +- scss/_accordion.scss | 9 + scss/_alert.scss | 7 +- scss/_badge.scss | 6 + scss/_banner.scss | 7 + scss/_breadcrumb.scss | 5 + scss/_button-group.scss | 5 + scss/_buttons.scss | 83 +++ scss/_card.scss | 6 + scss/_carousel.scss | 8 + scss/_close.scss | 5 + scss/_colors.scss | 282 +++++++++ scss/_config.scss | 27 +- scss/_dropdown.scss | 13 +- scss/_forms.scss | 9 - scss/_functions.scss | 115 ++-- scss/_list-group.scss | 12 +- scss/_maps.scss | 12 +- scss/_modal.scss | 13 +- scss/_nav.scss | 7 + scss/_navbar.scss | 14 +- scss/_offcanvas.scss | 12 +- scss/_pagination.scss | 17 + scss/_placeholders.scss | 4 + scss/_popover.scss | 7 + scss/_progress.scss | 8 + scss/_root.scss | 14 +- scss/_spinners.scss | 15 + scss/_theme.scss | 153 +++++ scss/_toasts.scss | 5 + scss/_tooltip.scss | 7 + scss/_transitions.scss | 4 + scss/_utilities.scss | 29 +- scss/_variables-dark.scss | 4 +- scss/_variables.scss | 564 ++++++------------ scss/bootstrap-grid.scss | 33 +- scss/bootstrap-reboot.scss | 14 +- scss/bootstrap-utilities.scss | 19 +- scss/bootstrap.scss | 83 ++- scss/{ => content}/_images.scss | 7 + scss/{ => content}/_reboot.scss | 6 + scss/{ => content}/_tables.scss | 36 +- scss/{ => content}/_type.scss | 5 + scss/content/index.scss | 4 + scss/forms/_floating-labels.scss | 5 + scss/forms/_form-check.scss | 9 + scss/forms/_form-control.scss | 10 +- scss/forms/_form-range.scss | 6 + scss/forms/_form-select.scss | 8 + scss/forms/_form-text.scss | 2 + scss/forms/_input-group.scss | 10 +- scss/forms/_labels.scss | 2 + scss/forms/_validation.scss | 171 ++++++ scss/forms/index.scss | 9 + scss/helpers/_color-bg.scss | 4 + scss/helpers/_colored-links.scss | 4 + scss/helpers/_focus-ring.scss | 2 + scss/helpers/_icon-link.scss | 4 + scss/helpers/_position.scss | 7 +- scss/helpers/_stretched-link.scss | 2 + scss/helpers/_text-truncation.scss | 2 +- scss/helpers/_visually-hidden.scss | 2 + scss/helpers/_vr.scss | 2 + scss/helpers/index.scss | 11 + scss/layout/_breakpoints.scss | 14 +- scss/layout/_grid.scss | 2 +- scss/layout/index.scss | 6 +- scss/mixins/_alert.scss | 18 - scss/mixins/_border-radius.scss | 12 +- scss/mixins/_box-shadow.scss | 2 + scss/mixins/_buttons.scss | 70 --- scss/mixins/_caret.scss | 3 + scss/mixins/_color-mode.scss | 2 + scss/mixins/_deprecate.scss | 2 + scss/mixins/_gradients.scss | 3 + scss/mixins/_list-group.scss | 26 - scss/mixins/_pagination.scss | 10 - scss/mixins/_reset-text.scss | 2 + scss/mixins/_table-variants.scss | 24 - scss/mixins/_transition.scss | 11 +- scss/mixins/_utilities.scss | 39 +- scss/mixins/index.scss | 34 ++ .../_auto-import-of-variables-dark.test.scss | 7 - scss/tests/mixins/_color-modes.test.scss | 1 + scss/utilities/_api.scss | 21 +- scss/vendor/_rfs.scss | 89 +-- site/src/content/docs/components/spinners.mdx | 2 +- site/src/scss/_ads.scss | 4 + site/src/scss/_anchor.scss | 3 + site/src/scss/_clipboard-js.scss | 3 + site/src/scss/_colors.scss | 8 +- site/src/scss/_content.scss | 5 + site/src/scss/_masthead.scss | 23 +- site/src/scss/_navbar.scss | 8 + site/src/scss/_placeholder-img.scss | 2 + site/src/scss/_search.scss | 4 + site/src/scss/_sidebar.scss | 4 + site/src/scss/_syntax.scss | 4 + site/src/scss/_toc.scss | 4 + site/src/scss/_variables.scss | 18 +- site/src/scss/docs.scss | 36 +- site/src/scss/docs_search.scss | 9 +- 103 files changed, 1974 insertions(+), 959 deletions(-) create mode 100644 scss/_banner.scss create mode 100644 scss/_colors.scss delete mode 100644 scss/_forms.scss create mode 100644 scss/_theme.scss rename scss/{ => content}/_images.scss (86%) rename scss/{ => content}/_reboot.scss (98%) rename scss/{ => content}/_tables.scss (77%) rename scss/{ => content}/_type.scss (91%) create mode 100644 scss/content/index.scss create mode 100644 scss/forms/index.scss create mode 100644 scss/helpers/index.scss delete mode 100644 scss/mixins/_alert.scss delete mode 100644 scss/mixins/_buttons.scss delete mode 100644 scss/mixins/_list-group.scss delete mode 100644 scss/mixins/_pagination.scss delete mode 100644 scss/mixins/_table-variants.scss create mode 100644 scss/mixins/index.scss delete mode 100644 scss/tests/mixins/_auto-import-of-variables-dark.test.scss diff --git a/package-lock.json b/package-lock.json index a0961c8f81bf..d85215910d15 100644 --- a/package-lock.json +++ b/package-lock.json @@ -83,7 +83,7 @@ "rollup": "^4.46.3", "rollup-plugin-istanbul": "^5.0.0", "rtlcss": "^4.3.0", - "sass": "1.78.0", + "sass": "1.89.2", "sass-true": "^9.0.0", "shelljs": "^0.10.0", "stylelint": "^16.23.1", @@ -3291,6 +3291,316 @@ "dev": true, "license": "MIT" }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -6363,14 +6673,17 @@ } }, "node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, "license": "Apache-2.0", "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, "engines": { - "node": ">=8" + "node": ">=0.10" } }, "node_modules/deterministic-object-hash": { @@ -9060,9 +9373,9 @@ } }, "node_modules/immutable": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", - "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz", + "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", "dev": true, "license": "MIT" }, @@ -13511,6 +13824,14 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -16102,14 +16423,14 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.78.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.78.0.tgz", - "integrity": "sha512-AaIqGSrjo5lA2Yg7RvFZrlXDBCp3nV4XP73GrLGvdRWWwk+8H3l0SDvq/5bA4eF+0RFPLuWUk3E+P1U/YqnpsQ==", + "version": "1.89.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.2.tgz", + "integrity": "sha512-xCmtksBKd/jdJ9Bt9p7nPKiuqrlBMBuuGkQlkhZjjQk3Ty48lv93k5Dq6OPkKt4XwxDJ7tvlfrTa1MPA9bf+QA==", "dev": true, "license": "MIT", "dependencies": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", + "chokidar": "^4.0.0", + "immutable": "^5.0.2", "source-map-js": ">=0.6.2 <2.0.0" }, "bin": { @@ -16117,6 +16438,9 @@ }, "engines": { "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" } }, "node_modules/sass-formatter": { @@ -16156,70 +16480,6 @@ } } }, - "node_modules/sass/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/sass/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/sass/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/sass/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/sax": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", @@ -16356,6 +16616,17 @@ "@img/sharp-win32-x64": "0.33.5" } }, + "node_modules/sharp/node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/sharp/node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", diff --git a/package.json b/package.json index ad90fa6ffbf9..75cfa2eb6496 100644 --- a/package.json +++ b/package.json @@ -42,11 +42,11 @@ "start": "npm-run-all --parallel watch docs-serve", "bundlewatch": "bundlewatch --config .bundlewatch.config.json", "css": "npm-run-all css-compile css-prefix css-rtl css-minify", - "css-compile": "sass --style expanded --source-map --embed-sources --no-error-css scss/:dist/css/", + "css-compile": "sass --style expanded --source-map --embed-sources --no-error-css scss/bootstrap.scss:dist/css/bootstrap.css scss/bootstrap-grid.scss:dist/css/bootstrap-grid.css scss/bootstrap-reboot.scss:dist/css/bootstrap-reboot.css scss/bootstrap-utilities.scss:dist/css/bootstrap-utilities.css", "css-rtl": "cross-env NODE_ENV=RTL postcss --config build/postcss.config.mjs --dir \"dist/css\" --ext \".rtl.css\" \"dist/css/*.css\" \"!dist/css/*.min.css\" \"!dist/css/*.rtl.css\"", "css-lint": "npm-run-all --aggregate-output --continue-on-error --parallel css-lint-*", "css-lint-stylelint": "stylelint \"**/*.{css,scss}\" --cache --cache-location .cache/.stylelintcache", - "css-lint-vars": "fusv scss/ site/src/scss/", + "css-dontlint-vars": "fusv scss/ site/assets/scss/", "css-minify": "npm-run-all --aggregate-output --parallel css-minify-*", "css-minify-main": "cleancss -O1 --format breakWith=lf --with-rebase --source-map --source-map-inline-sources --output dist/css/ --batch --batch-suffix \".min\" \"dist/css/*.css\" \"!dist/css/*.min.css\" \"!dist/css/*rtl*.css\"", "css-minify-rtl": "cleancss -O1 --format breakWith=lf --with-rebase --source-map --source-map-inline-sources --output dist/css/ --batch --batch-suffix \".min\" \"dist/css/*rtl.css\" \"!dist/css/*.min.css\"", @@ -172,7 +172,7 @@ "rollup": "^4.46.3", "rollup-plugin-istanbul": "^5.0.0", "rtlcss": "^4.3.0", - "sass": "1.78.0", + "sass": "1.89.2", "sass-true": "^9.0.0", "shelljs": "^0.10.0", "stylelint": "^16.23.1", diff --git a/scss/_accordion.scss b/scss/_accordion.scss index c2d3b800d124..4ab6a18b1915 100644 --- a/scss/_accordion.scss +++ b/scss/_accordion.scss @@ -1,3 +1,12 @@ +@use "config" as *; +@use "variables" as *; +@use "functions" as *; +@use "vendor/rfs" as *; +@use "mixins/border-radius" as *; +@use "mixins/transition" as *; +@use "mixins/box-shadow" as *; +@use "mixins/color-mode" as *; + // // Base styles // diff --git a/scss/_alert.scss b/scss/_alert.scss index b8cff9b71edf..ef504ca4d920 100644 --- a/scss/_alert.scss +++ b/scss/_alert.scss @@ -1,3 +1,8 @@ +@use "sass:map"; +@use "config" as *; +@use "variables" as *; +@use "mixins/border-radius" as *; + // // Base styles // @@ -57,7 +62,7 @@ // scss-docs-start alert-modifiers // Generate contextual modifier classes for colorizing the alert -@each $state in map-keys($theme-colors) { +@each $state in map.keys($theme-colors) { .alert-#{$state} { --#{$prefix}alert-color: var(--#{$prefix}#{$state}-text-emphasis); --#{$prefix}alert-bg: var(--#{$prefix}#{$state}-bg-subtle); diff --git a/scss/_badge.scss b/scss/_badge.scss index cc3d2695566a..0abaff6523f4 100644 --- a/scss/_badge.scss +++ b/scss/_badge.scss @@ -1,3 +1,9 @@ +@use "config" as *; +@use "variables" as *; +@use "mixins/border-radius" as *; +@use "mixins/gradients" as *; +@use "vendor/rfs" as *; + // Base class // // Requires one of the contextual, color modifier classes for `color` and diff --git a/scss/_banner.scss b/scss/_banner.scss new file mode 100644 index 000000000000..858d062e4f9b --- /dev/null +++ b/scss/_banner.scss @@ -0,0 +1,7 @@ +$file: "" !default; + +/*! + * Bootstrap #{$file} v6.0.0-dev (https://getbootstrap.com/) + * Copyright 2011-2025 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ diff --git a/scss/_breadcrumb.scss b/scss/_breadcrumb.scss index b8252ff2152a..27e19053053e 100644 --- a/scss/_breadcrumb.scss +++ b/scss/_breadcrumb.scss @@ -1,3 +1,8 @@ +@use "config" as *; +@use "variables" as *; +@use "mixins/border-radius" as *; +@use "vendor/rfs" as *; + .breadcrumb { // scss-docs-start breadcrumb-css-vars --#{$prefix}breadcrumb-padding-x: #{$breadcrumb-padding-x}; diff --git a/scss/_button-group.scss b/scss/_button-group.scss index f0e3b8820419..f4e8a4a08c25 100644 --- a/scss/_button-group.scss +++ b/scss/_button-group.scss @@ -1,3 +1,8 @@ +@use "config" as *; +@use "variables" as *; +@use "mixins/border-radius" as *; +@use "mixins/box-shadow" as *; + // Make the div behave like a button .btn-group, .btn-group-vertical { diff --git a/scss/_buttons.scss b/scss/_buttons.scss index caa4518ac8fc..3be8a88e87a7 100644 --- a/scss/_buttons.scss +++ b/scss/_buttons.scss @@ -1,3 +1,86 @@ +@use "sass:color"; +@use "colors" as *; +@use "config" as *; +@use "variables" as *; +@use "functions" as *; +@use "vendor/rfs" as *; +@use "mixins/border-radius" as *; +@use "mixins/box-shadow" as *; +@use "mixins/transition" as *; +@use "mixins/gradients" as *; + +// Button variants +// +// Easily pump out default styles, as well as :hover, :focus, :active, +// and disabled options for all buttons + +// scss-docs-start btn-variant-mixin +@mixin button-variant( + $background, + $border, + $color: color-contrast($background), + $hover-background: if($color == $color-contrast-light, shade-color($background, $btn-hover-bg-shade-amount), tint-color($background, $btn-hover-bg-tint-amount)), + $hover-border: if($color == $color-contrast-light, shade-color($border, $btn-hover-border-shade-amount), tint-color($border, $btn-hover-border-tint-amount)), + $hover-color: color-contrast($hover-background), + $active-background: if($color == $color-contrast-light, shade-color($background, $btn-active-bg-shade-amount), tint-color($background, $btn-active-bg-tint-amount)), + $active-border: if($color == $color-contrast-light, shade-color($border, $btn-active-border-shade-amount), tint-color($border, $btn-active-border-tint-amount)), + $active-color: color-contrast($active-background), + $disabled-background: $background, + $disabled-border: $border, + $disabled-color: color-contrast($disabled-background) +) { + --#{$prefix}btn-color: #{$color}; + --#{$prefix}btn-bg: #{$background}; + --#{$prefix}btn-border-color: #{$border}; + --#{$prefix}btn-hover-color: #{$hover-color}; + --#{$prefix}btn-hover-bg: #{$hover-background}; + --#{$prefix}btn-hover-border-color: #{$hover-border}; + --#{$prefix}btn-focus-shadow-rgb: #{to-rgb(color.mix($color, $border, 15%))}; + --#{$prefix}btn-active-color: #{$active-color}; + --#{$prefix}btn-active-bg: #{$active-background}; + --#{$prefix}btn-active-border-color: #{$active-border}; + --#{$prefix}btn-active-shadow: #{$btn-active-box-shadow}; + --#{$prefix}btn-disabled-color: #{$disabled-color}; + --#{$prefix}btn-disabled-bg: #{$disabled-background}; + --#{$prefix}btn-disabled-border-color: #{$disabled-border}; +} +// scss-docs-end btn-variant-mixin + +// scss-docs-start btn-outline-variant-mixin +@mixin button-outline-variant( + $color, + $color-hover: color-contrast($color), + $active-background: $color, + $active-border: $color, + $active-color: color-contrast($active-background) +) { + --#{$prefix}btn-color: #{$color}; + --#{$prefix}btn-border-color: #{$color}; + --#{$prefix}btn-hover-color: #{$color-hover}; + --#{$prefix}btn-hover-bg: #{$active-background}; + --#{$prefix}btn-hover-border-color: #{$active-border}; + --#{$prefix}btn-focus-shadow-rgb: #{to-rgb($color)}; + --#{$prefix}btn-active-color: #{$active-color}; + --#{$prefix}btn-active-bg: #{$active-background}; + --#{$prefix}btn-active-border-color: #{$active-border}; + --#{$prefix}btn-active-shadow: #{$btn-active-box-shadow}; + --#{$prefix}btn-disabled-color: #{$color}; + --#{$prefix}btn-disabled-bg: transparent; + --#{$prefix}btn-disabled-border-color: #{$color}; + --#{$prefix}gradient: none; +} +// scss-docs-end btn-outline-variant-mixin + +// scss-docs-start btn-size-mixin +@mixin button-size($padding-y, $padding-x, $font-size, $border-radius) { + --#{$prefix}btn-padding-y: #{$padding-y}; + --#{$prefix}btn-padding-x: #{$padding-x}; + @include rfs($font-size, --#{$prefix}btn-font-size); + --#{$prefix}btn-border-radius: #{$border-radius}; +} +// scss-docs-end btn-size-mixin + + // // Base styles // diff --git a/scss/_card.scss b/scss/_card.scss index 5bc84f99cc5d..2c3572c89fbf 100644 --- a/scss/_card.scss +++ b/scss/_card.scss @@ -1,3 +1,9 @@ +@use "config" as *; +@use "variables" as *; +@use "mixins/border-radius" as *; +@use "mixins/box-shadow" as *; +@use "layout/breakpoints" as *; + // // Base styles // diff --git a/scss/_carousel.scss b/scss/_carousel.scss index c99c538e8486..434115872263 100644 --- a/scss/_carousel.scss +++ b/scss/_carousel.scss @@ -1,3 +1,11 @@ +@use "config" as *; +@use "variables" as *; +@use "mixins/transition" as *; +@use "mixins/clearfix" as *; +@use "mixins/gradients" as *; +@use "mixins/color-mode" as *; +@use "vendor/rfs" as *; + // Notes on the classes: // // 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically) diff --git a/scss/_close.scss b/scss/_close.scss index d53c96fbff66..98140fb02df5 100644 --- a/scss/_close.scss +++ b/scss/_close.scss @@ -1,3 +1,8 @@ +@use "config" as *; +@use "variables" as *; +@use "mixins/border-radius" as *; +@use "mixins/color-mode" as *; + // Transparent background and border properties included for button version. // iOS requires the button element instead of an anchor tag. // If you want the anchor version, it requires `href="#"`. diff --git a/scss/_colors.scss b/scss/_colors.scss new file mode 100644 index 000000000000..aca360bbedd0 --- /dev/null +++ b/scss/_colors.scss @@ -0,0 +1,282 @@ +$blue: #0d6efd !default; +$blue-100: #cfe2ff !default; +$blue-200: #9ec5fe !default; +$blue-300: #6ea8fe !default; +$blue-400: #3d8bfd !default; +$blue-500: $blue !default; +$blue-600: #0a58ca !default; +$blue-700: #084298 !default; +$blue-800: #052c65 !default; +$blue-900: #031633 !default; + +$indigo: #6610f2 !default; +$indigo-100: #e0cffc !default; +$indigo-200: #c29ffa !default; +$indigo-300: #a370f7 !default; +$indigo-400: #8540f5 !default; +$indigo-500: $indigo !default; +$indigo-600: #520dc2 !default; +$indigo-700: #3d0a91 !default; +$indigo-800: #290661 !default; +$indigo-900: #140330 !default; + +$purple: #6f42c1 !default; +$purple-100: #e2d9f3 !default; +$purple-200: #c5b3e6 !default; +$purple-300: #a98eda !default; +$purple-400: #8c68cd !default; +$purple-500: $purple !default; +$purple-600: #59359a !default; +$purple-700: #432874 !default; +$purple-800: #2c1a4d !default; +$purple-900: #160d27 !default; + +$pink: #d63384 !default; +$pink-100: #f7d6e6 !default; +$pink-200: #efadce !default; +$pink-300: #e685b5 !default; +$pink-400: #de5c9d !default; +$pink-500: $pink !default; +$pink-600: #ab296a !default; +$pink-700: #801f4f !default; +$pink-800: #561435 !default; +$pink-900: #2b0a1a !default; + +$red: #dc3545 !default; +$red-100: #f8d7da !default; +$red-200: #f1aeb5 !default; +$red-300: #ea868f !default; +$red-400: #e35d6a !default; +$red-500: $red !default; +$red-600: #b02a37 !default; +$red-700: #842029 !default; +$red-800: #58151c !default; +$red-900: #2c0b0e !default; + +$orange: #fd7e14 !default; +$orange-100: #ffe5d0 !default; +$orange-200: #fecba1 !default; +$orange-300: #feb272 !default; +$orange-400: #fd9843 !default; +$orange-500: $orange !default; +$orange-600: #ca6510 !default; +$orange-700: #984c0c !default; +$orange-800: #653208 !default; +$orange-900: #331904 !default; + +$yellow: #ffc107 !default; +$yellow-100: #fff3cd !default; +$yellow-200: #ffe69c !default; +$yellow-300: #ffda6a !default; +$yellow-400: #ffcd39 !default; +$yellow-500: $yellow !default; +$yellow-600: #cc9a06 !default; +$yellow-700: #997404 !default; +$yellow-800: #664d03 !default; +$yellow-900: #332701 !default; + +$green: #198754 !default; +$green-100: #d1e7dd !default; +$green-200: #a3cfbb !default; +$green-300: #75b798 !default; +$green-400: #479f76 !default; +$green-500: $green !default; +$green-600: #146c43 !default; +$green-700: #0f5132 !default; +$green-800: #0a3622 !default; +$green-900: #051b11 !default; + +$teal: #20c997 !default; +$teal-100: #d2f4ea !default; +$teal-200: #a6e9d5 !default; +$teal-300: #79dfc1 !default; +$teal-400: #4dd4ac !default; +$teal-500: $teal !default; +$teal-600: #1aa179 !default; +$teal-700: #13795b !default; +$teal-800: #0d503c !default; +$teal-900: #06281e !default; + +$cyan: #0dcaf0 !default; +$cyan-100: #cff4fc !default; +$cyan-200: #9eeaf9 !default; +$cyan-300: #6edff6 !default; +$cyan-400: #3dd5f3 !default; +$cyan-500: $cyan !default; +$cyan-600: #0aa2c0 !default; +$cyan-700: #087990 !default; +$cyan-800: #055160 !default; +$cyan-900: #032830 !default; + +$gray: #adb5bd !default; +$gray-100: #f8f9fa !default; +$gray-200: #e9ecef !default; +$gray-300: #dee2e6 !default; +$gray-400: #ced4da !default; +$gray-500: $gray !default; +$gray-600: #6c757d !default; +$gray-700: #495057 !default; +$gray-800: #343a40 !default; +$gray-900: #212529 !default; + +$white: #fff !default; +$black: #000 !default; + +$blues: ( + "blue-100": $blue-100, + "blue-200": $blue-200, + "blue-300": $blue-300, + "blue-400": $blue-400, + "blue-500": $blue-500, + "blue-600": $blue-600, + "blue-700": $blue-700, + "blue-800": $blue-800, + "blue-900": $blue-900 +) !default; + +$indigos: ( + "indigo-100": $indigo-100, + "indigo-200": $indigo-200, + "indigo-300": $indigo-300, + "indigo-400": $indigo-400, + "indigo-500": $indigo, + "indigo-600": $indigo-600, + "indigo-700": $indigo-700, + "indigo-800": $indigo-800, + "indigo-900": $indigo-900 +) !default; + +$purples: ( + "purple-100": $purple-100, + "purple-200": $purple-200, + "purple-300": $purple-300, + "purple-400": $purple-400, + "purple-500": $purple, + "purple-600": $purple-600, + "purple-700": $purple-700, + "purple-800": $purple-800, + "purple-900": $purple-900 +) !default; + +$pinks: ( + "pink-100": $pink-100, + "pink-200": $pink-200, + "pink-300": $pink-300, + "pink-400": $pink-400, + "pink-500": $pink-500, + "pink-600": $pink-600, + "pink-700": $pink-700, + "pink-800": $pink-800, + "pink-900": $pink-900 +) !default; + +$reds: ( + "red-100": $red-100, + "red-200": $red-200, + "red-300": $red-300, + "red-400": $red-400, + "red-500": $red-500, + "red-600": $red-600, + "red-700": $red-700, + "red-800": $red-800, + "red-900": $red-900 +) !default; + +$oranges: ( + "orange-100": $orange-100, + "orange-200": $orange-200, + "orange-300": $orange-300, + "orange-400": $orange-400, + "orange-500": $orange-500, + "orange-600": $orange-600, + "orange-700": $orange-700, + "orange-800": $orange-800, + "orange-900": $orange-900 +) !default; + +$yellows: ( + "yellow-100": $yellow-100, + "yellow-200": $yellow-200, + "yellow-300": $yellow-300, + "yellow-400": $yellow-400, + "yellow-500": $yellow-500, + "yellow-600": $yellow-600, + "yellow-700": $yellow-700, + "yellow-800": $yellow-800, + "yellow-900": $yellow-900 +) !default; + +$greens: ( + "green-100": $green-100, + "green-200": $green-200, + "green-300": $green-300, + "green-400": $green-400, + "green-500": $green-500, + "green-600": $green-600, + "green-700": $green-700, + "green-800": $green-800, + "green-900": $green-900 +) !default; + +$teals: ( + "teal-100": $teal-100, + "teal-200": $teal-200, + "teal-300": $teal-300, + "teal-400": $teal-400, + "teal-500": $teal-500, + "teal-600": $teal-600, + "teal-700": $teal-700, + "teal-800": $teal-800, + "teal-900": $teal-900 +) !default; + +$cyans: ( + "cyan-100": $cyan-100, + "cyan-200": $cyan-200, + "cyan-300": $cyan-300, + "cyan-400": $cyan-400, + "cyan-500": $cyan-500, + "cyan-600": $cyan-600, + "cyan-700": $cyan-700, + "cyan-800": $cyan-800, + "cyan-900": $cyan-900 +) !default; + +$grays: ( + "gray-100": $gray-100, + "gray-200": $gray-200, + "gray-300": $gray-300, + "gray-400": $gray-400, + "gray-500": $gray-500, + "gray-600": $gray-600, + "gray-700": $gray-700, + "gray-800": $gray-800, + "gray-900": $gray-900 +) !default; + +$colors: ( + "blue": $blue, + "indigo": $indigo, + "purple": $purple, + "pink": $pink, + "red": $red, + "orange": $orange, + "yellow": $yellow, + "green": $green, + "teal": $teal, + "cyan": $cyan +) !default; + +$all-colors: ( + "grays": $grays, + "blues": $blues, + "indigos": $indigos, + "purples": $purples, + "pinks": $pinks, + "reds": $reds, + "oranges": $oranges, + "yellows": $yellows, + "greens": $greens, + "teals": $teals, + "cyans": $cyans +) !default; diff --git a/scss/_config.scss b/scss/_config.scss index 8116ba1799b3..ad98d20ff153 100644 --- a/scss/_config.scss +++ b/scss/_config.scss @@ -4,9 +4,33 @@ $prefix: bs- !default; -$enable-container-classes: true !default; +$enable-caret: true !default; +$enable-rounded: true !default; +$enable-shadows: false !default; +$enable-gradients: false !default; +$enable-transitions: true !default; +$enable-reduced-motion: true !default; +$enable-smooth-scroll: true !default; +$enable-grid-classes: true !default; +$enable-container-classes: true !default; +$enable-cssgrid: false !default; +$enable-button-pointers: true !default; +$enable-rfs: true !default; +$enable-validation-icons: true !default; +$enable-negative-margins: false !default; +$enable-deprecation-messages: true !default; +$enable-important-utilities: true !default; + +$enable-dark-mode: true !default; +$color-mode-type: data !default; // `data` or `media-query` + // more to come here… +$color-mode-type: "media-query" !default; +$color-contrast-dark: #000 !default; +$color-contrast-light: #fff !default; +$min-contrast-ratio: 4.5 !default; + // Grid breakpoints // // Define the minimum dimensions at which your layout will change, @@ -47,6 +71,7 @@ $container-max-widths: ( $container-padding-x: $grid-gutter-width !default; +$utilities: () !default; // Characters which are escaped by the escape-svg function $escaped-characters: ( diff --git a/scss/_dropdown.scss b/scss/_dropdown.scss index 587ebb487cf4..70780dd7151e 100644 --- a/scss/_dropdown.scss +++ b/scss/_dropdown.scss @@ -1,3 +1,14 @@ +@use "sass:map"; +@use "config" as *; +@use "variables" as *; +@use "mixins/caret" as *; +@use "mixins/border-radius" as *; +@use "mixins/box-shadow" as *; +@use "mixins/gradients" as *; +@use "mixins/caret" as *; +@use "vendor/rfs" as *; +@use "layout/breakpoints" as *; + // The dropdown wrapper (`
`) .dropup, .dropend, @@ -85,7 +96,7 @@ // We deliberately hardcode the `bs-` prefix because we check // this custom property in JS to determine Popper's positioning -@each $breakpoint in map-keys($grid-breakpoints) { +@each $breakpoint in map.keys($grid-breakpoints) { @include media-breakpoint-up($breakpoint) { $infix: breakpoint-infix($breakpoint, $grid-breakpoints); diff --git a/scss/_forms.scss b/scss/_forms.scss deleted file mode 100644 index 7b17d849ac0f..000000000000 --- a/scss/_forms.scss +++ /dev/null @@ -1,9 +0,0 @@ -@import "forms/labels"; -@import "forms/form-text"; -@import "forms/form-control"; -@import "forms/form-select"; -@import "forms/form-check"; -@import "forms/form-range"; -@import "forms/floating-labels"; -@import "forms/input-group"; -@import "forms/validation"; diff --git a/scss/_functions.scss b/scss/_functions.scss index 9ad74ef6d3db..77187e503d6e 100644 --- a/scss/_functions.scss +++ b/scss/_functions.scss @@ -1,3 +1,12 @@ +@use "sass:color"; +@use "sass:list"; +@use "sass:map"; +@use "sass:math"; +@use "sass:meta"; +@use "sass:string"; +// @use "variables" as *; +@use "config" as *; + // Bootstrap functions // // Utility mixins and functions for evaluating source code across our variables, maps, and mixins. @@ -8,7 +17,7 @@ $prev-key: null; $prev-num: null; @each $key, $num in $map { - @if $prev-num == null or unit($num) == "%" or unit($prev-num) == "%" { + @if $prev-num == null or math.unit($num) == "%" or math.unit($prev-num) == "%" { // Do nothing } @else if not comparable($prev-num, $num) { @warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !"; @@ -22,10 +31,10 @@ // Starts at zero // Used to ensure the min-width of the lowest breakpoint starts at 0. -@mixin _assert-starts-at-zero($map, $map-name: "$grid-breakpoints") { - @if length($map) > 0 { - $values: map-values($map); - $first-value: nth($values, 1); +@mixin _assert-starts-at-zero($map, $map-name: "$breakpoints") { + @if list.length($map) > 0 { + $values: map.values($map); + $first-value: list.nth($values, 1); @if $first-value != 0 { @warn "First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}."; } @@ -34,7 +43,7 @@ // Colors @function to-rgb($value) { - @return red($value), green($value), blue($value); + @return color.channel($value, "red"), color.channel($value, "green"), color.channel($value, "blue"); } // stylelint-disable scss/dollar-variable-pattern @@ -55,10 +64,10 @@ // allow to pass the $key and $value of the map as an function argument $_args: (); @each $arg in $args { - $_args: append($_args, if($arg == "$key", $key, if($arg == "$value", $value, $arg))); + $_args: list.append($_args, if($arg == "$key", $key, if($arg == "$value", $value, $arg))); } - $_map: map-merge($_map, ($key: call(get-function($func), $_args...))); + $_map: map.merge($_map, ($key: meta.call(meta.get-function($func), $_args...))); } @return $_map; @@ -68,7 +77,7 @@ @function varify($list) { $result: null; @each $entry in $list { - $result: append($result, var(--#{$prefix}#{$entry}), space); + $result: list.append($result, var(--#{$prefix}#{$entry}), space); } @return $result; } @@ -79,7 +88,7 @@ $result: (); @each $key, $value in $map { @if $key != 0 { - $result: map-merge($result, ("n" + $key: (-$value))); + $result: map.merge($result, ("n" + $key: (-$value))); } } @return $result; @@ -89,8 +98,8 @@ @function map-get-multiple($map, $values) { $result: (); @each $key, $value in $map { - @if (index($values, $key) != null) { - $result: map-merge($result, ($key: $value)); + @if (list.index($values, $key) != null) { + $result: map.merge($result, ($key: $value)); } } @return $result; @@ -101,7 +110,7 @@ $merged-maps: (); @each $map in $maps { - $merged-maps: map-merge($merged-maps, $map); + $merged-maps: map.merge($merged-maps, $map); } @return $merged-maps; } @@ -115,10 +124,10 @@ // @param {String} $replace ('') - New value // @return {String} - Updated string @function str-replace($string, $search, $replace: "") { - $index: str-index($string, $search); + $index: string.index($string, $search); @if $index { - @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); + @return string.slice($string, 1, $index - 1) + $replace + str-replace(string.slice($string, $index + string.length($search)), $search, $replace); } @return $string; @@ -129,11 +138,11 @@ // Requires the use of quotes around data URIs. @function escape-svg($string) { - @if str-index($string, "data:image/svg+xml") { + @if string.index($string, "data:image/svg+xml") { @each $char, $encoded in $escaped-characters { // Do not escape the url brackets - @if str-index($string, "url(") == 1 { - $string: url("#{str-replace(str-slice($string, 6, -3), $char, $encoded)}"); + @if string.index($string, "url(") == 1 { + $string: url("#{str-replace(string.slice($string, 6, -3), $char, $encoded)}"); } @else { $string: str-replace($string, $char, $encoded); } @@ -151,7 +160,7 @@ $_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003 .0033 .0037 .004 .0044 .0048 .0052 .0056 .006 .0065 .007 .0075 .008 .0086 .0091 .0097 .0103 .011 .0116 .0123 .013 .0137 .0144 .0152 .016 .0168 .0176 .0185 .0194 .0203 .0212 .0222 .0232 .0242 .0252 .0262 .0273 .0284 .0296 .0307 .0319 .0331 .0343 .0356 .0369 .0382 .0395 .0409 .0423 .0437 .0452 .0467 .0482 .0497 .0513 .0529 .0545 .0561 .0578 .0595 .0612 .063 .0648 .0666 .0685 .0704 .0723 .0742 .0762 .0782 .0802 .0823 .0844 .0865 .0887 .0908 .0931 .0953 .0976 .0999 .1022 .1046 .107 .1095 .1119 .1144 .117 .1195 .1221 .1248 .1274 .1301 .1329 .1356 .1384 .1413 .1441 .147 .15 .1529 .1559 .159 .162 .1651 .1683 .1714 .1746 .1779 .1812 .1845 .1878 .1912 .1946 .1981 .2016 .2051 .2086 .2122 .2159 .2195 .2232 .227 .2307 .2346 .2384 .2423 .2462 .2502 .2542 .2582 .2623 .2664 .2705 .2747 .2789 .2831 .2874 .2918 .2961 .3005 .305 .3095 .314 .3185 .3231 .3278 .3325 .3372 .3419 .3467 .3515 .3564 .3613 .3663 .3712 .3763 .3813 .3864 .3916 .3968 .402 .4072 .4125 .4179 .4233 .4287 .4342 .4397 .4452 .4508 .4564 .4621 .4678 .4735 .4793 .4851 .491 .4969 .5029 .5089 .5149 .521 .5271 .5333 .5395 .5457 .552 .5583 .5647 .5711 .5776 .5841 .5906 .5972 .6038 .6105 .6172 .624 .6308 .6376 .6445 .6514 .6584 .6654 .6724 .6795 .6867 .6939 .7011 .7084 .7157 .7231 .7305 .7379 .7454 .7529 .7605 .7682 .7758 .7835 .7913 .7991 .807 .8148 .8228 .8308 .8388 .8469 .855 .8632 .8714 .8796 .8879 .8963 .9047 .9131 .9216 .9301 .9387 .9473 .956 .9647 .9734 .9823 .9911 1; @function color-contrast($background, $color-contrast-dark: $color-contrast-dark, $color-contrast-light: $color-contrast-light, $min-contrast-ratio: $min-contrast-ratio) { - $foregrounds: $color-contrast-light, $color-contrast-dark, $white, $black; + $foregrounds: $color-contrast-light, $color-contrast-dark, #fff, #000; $max-ratio: 0; $max-ratio-color: null; @@ -174,7 +183,7 @@ $_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003 $l1: luminance($background); $l2: luminance(opaque($background, $foreground)); - @return if($l1 > $l2, divide($l1 + .05, $l2 + .05), divide($l2 + .05, $l1 + .05)); + @return if($l1 > $l2, math.div($l1 + .05, $l2 + .05), math.div($l2 + .05, $l1 + .05)); } // Return WCAG2.2 relative luminance @@ -182,80 +191,38 @@ $_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003 // See https://www.w3.org/TR/WCAG/#dfn-contrast-ratio @function luminance($color) { $rgb: ( - "r": red($color), - "g": green($color), - "b": blue($color) + "r": color.channel($color, "red"), + "g": color.channel($color, "green"), + "b": color.channel($color, "blue") ); @each $name, $value in $rgb { - $value: if(divide($value, 255) < .04045, divide(divide($value, 255), 12.92), nth($_luminance-list, $value + 1)); - $rgb: map-merge($rgb, ($name: $value)); + $value: if(math.div($value, 255) < .04045, math.div(math.div($value, 255), 12.92), list.nth($_luminance-list, math.round($value + 1))); + $rgb: map.merge($rgb, ($name: $value)); } - @return (map-get($rgb, "r") * .2126) + (map-get($rgb, "g") * .7152) + (map-get($rgb, "b") * .0722); + @return (map.get($rgb, "r") * .2126) + (map.get($rgb, "g") * .7152) + (map.get($rgb, "b") * .0722); } // Return opaque color // opaque(#fff, rgba(0, 0, 0, .5)) => #808080 @function opaque($background, $foreground) { - @return mix(rgba($foreground, 1), $background, opacity($foreground) * 100%); + @return color.mix(rgba($foreground, 1), $background, color.opacity($foreground) * 100%); } // scss-docs-start color-functions -// Tint a color: mix a color with white +// // Tint a color: mix a color with white @function tint-color($color, $weight) { - @return mix(white, $color, $weight); + @return color.mix(white, $color, $weight); } -// Shade a color: mix a color with black +// // Shade a color: mix a color with black @function shade-color($color, $weight) { - @return mix(black, $color, $weight); + @return color.mix(black, $color, $weight); } -// Shade the color if the weight is positive, else tint it +// // Shade the color if the weight is positive, else tint it @function shift-color($color, $weight) { @return if($weight > 0, shade-color($color, $weight), tint-color($color, -$weight)); } // scss-docs-end color-functions - -@function divide($dividend, $divisor, $precision: 10) { - $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1); - $dividend: abs($dividend); - $divisor: abs($divisor); - @if $dividend == 0 { - @return 0; - } - @if $divisor == 0 { - @error "Cannot divide by 0"; - } - $remainder: $dividend; - $result: 0; - $factor: 10; - @while ($remainder > 0 and $precision >= 0) { - $quotient: 0; - @while ($remainder >= $divisor) { - $remainder: $remainder - $divisor; - $quotient: $quotient + 1; - } - $result: $result * 10 + $quotient; - $factor: $factor * .1; - $remainder: $remainder * 10; - $precision: $precision - 1; - @if ($precision < 0 and $remainder >= $divisor * 5) { - $result: $result + 1; - } - } - $result: $result * $factor * $sign; - $dividend-unit: unit($dividend); - $divisor-unit: unit($divisor); - $unit-map: ( - "px": 1px, - "rem": 1rem, - "em": 1em, - "%": 1% - ); - @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) { - $result: $result * map-get($unit-map, $dividend-unit); - } - @return $result; -} diff --git a/scss/_list-group.scss b/scss/_list-group.scss index f7c9ea54c24d..b5bb03d45c34 100644 --- a/scss/_list-group.scss +++ b/scss/_list-group.scss @@ -1,3 +1,11 @@ +@use "sass:map"; +@use "colors" as *; +@use "config" as *; +@use "variables" as *; +@use "mixins/border-radius" as *; +@use "vendor/rfs" as *; +@use "layout/breakpoints" as *; + // Base class // // Easily usable on
    ,
      , or
      . @@ -121,7 +129,7 @@ // // Change the layout of list group items from vertical (default) to horizontal. -@each $breakpoint in map-keys($grid-breakpoints) { +@each $breakpoint in map.keys($grid-breakpoints) { @include media-breakpoint-up($breakpoint) { $infix: breakpoint-infix($breakpoint, $grid-breakpoints); @@ -182,7 +190,7 @@ // Add modifier classes to change text and background color on individual items. // Organizationally, this must come after the `:hover` states. -@each $state in map-keys($theme-colors) { +@each $state in map.keys($theme-colors) { .list-group-item-#{$state} { --#{$prefix}list-group-color: var(--#{$prefix}#{$state}-text-emphasis); --#{$prefix}list-group-bg: var(--#{$prefix}#{$state}-bg-subtle); diff --git a/scss/_maps.scss b/scss/_maps.scss index 68ee421c2b1f..02a7bf7c9004 100644 --- a/scss/_maps.scss +++ b/scss/_maps.scss @@ -1,3 +1,9 @@ +@use "sass:map"; +@use "colors" as *; +@use "functions" as *; +@use "config" as *; +@use "variables" as *; + // Re-assigned maps // // Placed here so that others can override the default Sass maps and see automatic updates to utilities and more. @@ -100,7 +106,7 @@ $utilities-colors: $theme-colors-rgb !default; // scss-docs-end utilities-colors // scss-docs-start utilities-text-colors -$utilities-text: map-merge( +$utilities-text: map.merge( $utilities-colors, ( "black": to-rgb($black), @@ -123,7 +129,7 @@ $utilities-text-emphasis-colors: ( // scss-docs-end utilities-text-colors // scss-docs-start utilities-bg-colors -$utilities-bg: map-merge( +$utilities-bg: map.merge( $utilities-colors, ( "black": to-rgb($black), @@ -146,7 +152,7 @@ $utilities-bg-subtle: ( // scss-docs-end utilities-bg-colors // scss-docs-start utilities-border-colors -$utilities-border: map-merge( +$utilities-border: map.merge( $utilities-colors, ( "black": to-rgb($black), diff --git a/scss/_modal.scss b/scss/_modal.scss index 1e611e3dba31..4b4e25c132ae 100644 --- a/scss/_modal.scss +++ b/scss/_modal.scss @@ -1,3 +1,14 @@ +@use "sass:map"; +@use "config" as *; +@use "variables" as *; +@use "mixins/border-radius" as *; +@use "mixins/box-shadow" as *; +@use "mixins/transition" as *; +@use "mixins/gradients" as *; +@use "mixins/backdrop" as *; +@use "vendor/rfs" as *; +@use "layout/breakpoints" as *; + // .modal-open - body class for killing the scroll // .modal - container to scroll within // .modal-dialog - positioning shell for the actual modal @@ -207,7 +218,7 @@ } // scss-docs-start modal-fullscreen-loop -@each $breakpoint in map-keys($grid-breakpoints) { +@each $breakpoint in map.keys($grid-breakpoints) { $infix: breakpoint-infix($breakpoint, $grid-breakpoints); $postfix: if($infix != "", $infix + "-down", ""); diff --git a/scss/_nav.scss b/scss/_nav.scss index 3c25f0b037f2..767f3baf1544 100644 --- a/scss/_nav.scss +++ b/scss/_nav.scss @@ -1,3 +1,10 @@ +@use "config" as *; +@use "variables" as *; +@use "mixins/border-radius" as *; +@use "mixins/transition" as *; +@use "mixins/gradients" as *; +@use "vendor/rfs" as *; + // Base class // // Kickstart any navigation component with a set of style resets. Works with diff --git a/scss/_navbar.scss b/scss/_navbar.scss index 86aa441eb6e3..643b3678d0b6 100644 --- a/scss/_navbar.scss +++ b/scss/_navbar.scss @@ -1,3 +1,15 @@ +@use "sass:map"; +@use "config" as *; +@use "variables" as *; +@use "mixins/border-radius" as *; +@use "mixins/box-shadow" as *; +@use "mixins/gradients" as *; +@use "mixins/transition" as *; +@use "mixins/color-mode" as *; +@use "mixins/deprecate" as *; +@use "vendor/rfs" as *; +@use "layout/breakpoints" as *; + // Navbar // // Provide a static navbar from which we expand to create full-width, fixed, and @@ -190,7 +202,7 @@ // Generate series of `.navbar-expand-*` responsive classes for configuring // where your navbar collapses. .navbar-expand { - @each $breakpoint in map-keys($grid-breakpoints) { + @each $breakpoint in map.keys($grid-breakpoints) { $next: breakpoint-next($breakpoint, $grid-breakpoints); $infix: breakpoint-infix($next, $grid-breakpoints); diff --git a/scss/_offcanvas.scss b/scss/_offcanvas.scss index 241afb2e4d45..0d442ce2b205 100644 --- a/scss/_offcanvas.scss +++ b/scss/_offcanvas.scss @@ -1,3 +1,11 @@ +@use "sass:map"; +@use "config" as *; +@use "variables" as *; +@use "mixins/box-shadow" as *; +@use "mixins/transition" as *; +@use "mixins/backdrop" as *; +@use "layout/breakpoints" as *; + %offcanvas-css-vars { // scss-docs-start offcanvas-css-vars --#{$prefix}offcanvas-zindex: #{$zindex-offcanvas}; @@ -15,7 +23,7 @@ // scss-docs-end offcanvas-css-vars } -@each $breakpoint in map-keys($grid-breakpoints) { +@each $breakpoint in map.keys($grid-breakpoints) { $next: breakpoint-next($breakpoint, $grid-breakpoints); $infix: breakpoint-infix($next, $grid-breakpoints); @@ -24,7 +32,7 @@ } } -@each $breakpoint in map-keys($grid-breakpoints) { +@each $breakpoint in map.keys($grid-breakpoints) { $next: breakpoint-next($breakpoint, $grid-breakpoints); $infix: breakpoint-infix($next, $grid-breakpoints); diff --git a/scss/_pagination.scss b/scss/_pagination.scss index 9f09694c30ec..a06f1b60c944 100644 --- a/scss/_pagination.scss +++ b/scss/_pagination.scss @@ -1,3 +1,20 @@ +@use "config" as *; +@use "variables" as *; +@use "mixins/lists" as *; +@use "mixins/border-radius" as *; +@use "mixins/transition" as *; +@use "mixins/gradients" as *; +@use "vendor/rfs" as *; + +// scss-docs-start pagination-mixin +@mixin pagination-size($padding-y, $padding-x, $font-size, $border-radius) { + --#{$prefix}pagination-padding-x: #{$padding-x}; + --#{$prefix}pagination-padding-y: #{$padding-y}; + @include rfs($font-size, --#{$prefix}pagination-font-size); + --#{$prefix}pagination-border-radius: #{$border-radius}; +} +// scss-docs-end pagination-mixin + .pagination { // scss-docs-start pagination-css-vars --#{$prefix}pagination-padding-x: #{$pagination-padding-x}; diff --git a/scss/_placeholders.scss b/scss/_placeholders.scss index 6e32e1cdb9b1..47d6ec016272 100644 --- a/scss/_placeholders.scss +++ b/scss/_placeholders.scss @@ -1,3 +1,7 @@ +@use "colors" as *; +@use "config" as *; +@use "variables" as *; + .placeholder { display: inline-block; min-height: 1em; diff --git a/scss/_popover.scss b/scss/_popover.scss index 10833d4de955..8f81dde5e53f 100644 --- a/scss/_popover.scss +++ b/scss/_popover.scss @@ -1,3 +1,10 @@ +@use "config" as *; +@use "variables" as *; +@use "mixins/border-radius" as *; +@use "mixins/box-shadow" as *; +@use "vendor/rfs" as *; +@use "mixins/reset-text" as *; + .popover { // scss-docs-start popover-css-vars --#{$prefix}popover-zindex: #{$zindex-popover}; diff --git a/scss/_progress.scss b/scss/_progress.scss index 732365c52655..386a59613db1 100644 --- a/scss/_progress.scss +++ b/scss/_progress.scss @@ -1,3 +1,11 @@ +@use "config" as *; +@use "variables" as *; +@use "mixins/transition" as *; +@use "mixins/gradients" as *; +@use "mixins/border-radius" as *; +@use "mixins/box-shadow" as *; +@use "vendor/rfs" as *; + // Disable animation if transitions are disabled // scss-docs-start progress-keyframes diff --git a/scss/_root.scss b/scss/_root.scss index cc2fbb6d1e38..e491c4653ce9 100644 --- a/scss/_root.scss +++ b/scss/_root.scss @@ -1,3 +1,11 @@ +@use "sass:meta"; +@use "colors" as *; +@use "config" as *; +@use "variables" as *; +@use "maps" as *; +@use "vendor/rfs" as *; +@use "mixins/color-mode" as *; + :root, [data-bs-theme="light"] { // Note: Custom variable values only support SassScript inside `#{}`. @@ -41,8 +49,8 @@ // Note: Use `inspect` for lists so that quoted items keep the quotes. // See https://github.com/sass/sass/issues/2383#issuecomment-336349172 - --#{$prefix}font-sans-serif: #{inspect($font-family-sans-serif)}; - --#{$prefix}font-monospace: #{inspect($font-family-monospace)}; + --#{$prefix}font-sans-serif: #{meta.inspect($font-family-sans-serif)}; + --#{$prefix}font-monospace: #{meta.inspect($font-family-monospace)}; --#{$prefix}gradient: #{$gradient}; // Root and body @@ -50,7 +58,7 @@ @if $font-size-root != null { --#{$prefix}root-font-size: #{$font-size-root}; } - --#{$prefix}body-font-family: #{inspect($font-family-base)}; + --#{$prefix}body-font-family: #{meta.inspect($font-family-base)}; @include rfs($font-size-base, --#{$prefix}body-font-size); --#{$prefix}body-font-weight: #{$font-weight-base}; --#{$prefix}body-line-height: #{$line-height-base}; diff --git a/scss/_spinners.scss b/scss/_spinners.scss index 9dff289256b4..c95a683526d3 100644 --- a/scss/_spinners.scss +++ b/scss/_spinners.scss @@ -1,3 +1,18 @@ +@use "config" as *; +@use "variables" as *; + +// scss-docs-start spinner-variables +$spinner-width: 2rem !default; +$spinner-height: $spinner-width !default; +$spinner-vertical-align: -.125em !default; +$spinner-border-width: .25em !default; +$spinner-animation-speed: .75s !default; + +$spinner-width-sm: 1rem !default; +$spinner-height-sm: $spinner-width-sm !default; +$spinner-border-width-sm: .2em !default; +// scss-docs-end spinner-variables + // // Rotating border // diff --git a/scss/_theme.scss b/scss/_theme.scss new file mode 100644 index 000000000000..0b7daa273ef2 --- /dev/null +++ b/scss/_theme.scss @@ -0,0 +1,153 @@ +@use "sass:meta"; +@use "sass:map"; +@use "config" as *; +@use "colors" as *; + +@function theme-color-values($key) { + $result: (); + + @each $color-name, $color-map in $new-theme-colors { + @if map.has-key($color-map, $key) { + $result: map.merge($result, ($color-name: map.get($color-map, $key))); + } + } + + @return $result; +} + +// Recursive mixin to handle nested maps +@mixin create-css-vars($map, $parent-key: "") { + @each $key, $value in $map { + $current-key: if($parent-key == "", $key, "#{$parent-key}-#{$key}"); + + @if meta.type-of($value) == "map" { + @include create-css-vars($value, $current-key); + } @else { + --#{$prefix}#{$current-key}: #{$value}; + } + } +} + +// scss-docs-start theme-colors +$new-theme-colors: ( + "primary": ( + "base": var(--#{$prefix}blue-500), + "text": light-dark(var(--#{$prefix}blue-600), var(--#{$prefix}blue-300)), + "bg": light-dark(var(--#{$prefix}blue-500), var(--#{$prefix}blue-500)), + "bg-subtle": light-dark(var(--#{$prefix}blue-100), var(--#{$prefix}blue-900)), + "bg-muted": light-dark(var(--#{$prefix}blue-200), var(--#{$prefix}blue-800)), + // "bg-emphasized": light-dark(color-mix(in oklch, var(--#{$prefix}blue-200), var(--#{$prefix}blue-300)), var(--#{$prefix}blue-700)), + "border": light-dark(var(--#{$prefix}blue-300), var(--#{$prefix}blue-600)), + "focus-ring": color-mix(in oklch, var(--#{$prefix}blue-500) 50%, var(--#{$prefix}bg)), + "contrast": var(--#{$prefix}white) + ), + "accent": ( + "base": var(--#{$prefix}indigo-500), + "text": light-dark(var(--#{$prefix}indigo-600), var(--#{$prefix}indigo-300)), + "bg": light-dark(var(--#{$prefix}indigo-500), var(--#{$prefix}indigo-500)), + "bg-subtle": light-dark(var(--#{$prefix}indigo-100), var(--#{$prefix}indigo-900)), + "bg-muted": light-dark(var(--#{$prefix}indigo-200), var(--#{$prefix}indigo-800)), + // "bg-emphasized": light-dark(color-mix(in oklch, var(--#{$prefix}indigo-200), var(--#{$prefix}indigo-300)), var(--#{$prefix}indigo-700)), + "border": light-dark(var(--#{$prefix}indigo-300), var(--#{$prefix}indigo-600)), + "focus-ring": color-mix(in oklch, var(--#{$prefix}indigo-500) 50%, var(--#{$prefix}bg)), + "contrast": var(--#{$prefix}white) + ), + "danger": ( + "base": var(--#{$prefix}red-500), + "text": light-dark(var(--#{$prefix}red-600), var(--#{$prefix}red-300)), + "bg": light-dark(var(--#{$prefix}red-500), var(--#{$prefix}red-500)), + "bg-subtle": light-dark(var(--#{$prefix}red-100), var(--#{$prefix}red-900)), + "bg-muted": light-dark(var(--#{$prefix}red-200), var(--#{$prefix}red-800)), + // "bg-emphasized": light-dark(color-mix(in oklch, var(--#{$prefix}red-200), var(--#{$prefix}red-300)), var(--#{$prefix}red-700)), + "border": light-dark(var(--#{$prefix}red-300), var(--#{$prefix}red-600)), + "focus-ring": color-mix(in oklch, var(--#{$prefix}red-500) 50%, var(--#{$prefix}bg)), + "contrast": var(--#{$prefix}white) + ), + "warning": ( + "base": var(--#{$prefix}yellow-500), + "text": light-dark(var(--#{$prefix}yellow-700), var(--#{$prefix}yellow-300)), + "bg": light-dark(var(--#{$prefix}yellow-500), var(--#{$prefix}yellow-500)), + "bg-subtle": light-dark(var(--#{$prefix}yellow-100), var(--#{$prefix}yellow-900)), + "bg-muted": light-dark(var(--#{$prefix}yellow-200), var(--#{$prefix}yellow-800)), + // "bg-emphasized": light-dark(color-mix(in oklch, var(--#{$prefix}yellow-200), var(--#{$prefix}yellow-300)), var(--#{$prefix}yellow-700)), + "border": light-dark(var(--#{$prefix}yellow-300), var(--#{$prefix}yellow-600)), + "focus-ring": color-mix(in oklch, var(--#{$prefix}yellow-500) 50%, var(--#{$prefix}bg)), + "contrast": var(--#{$prefix}gray-900) + ), + "success": ( + "base": var(--#{$prefix}green-500), + "text": light-dark(var(--#{$prefix}green-600), var(--#{$prefix}green-300)), + "bg": light-dark(var(--#{$prefix}green-500), var(--#{$prefix}green-500)), + "bg-subtle": light-dark(var(--#{$prefix}green-100), var(--#{$prefix}green-900)), + "bg-muted": light-dark(var(--#{$prefix}green-200), var(--#{$prefix}green-800)), + // "bg-emphasized": light-dark(color-mix(in oklch, var(--#{$prefix}green-200), var(--#{$prefix}green-300)), var(--#{$prefix}green-700)), + "border": light-dark(var(--#{$prefix}green-300), var(--#{$prefix}green-600)), + "focus-ring": color-mix(in oklch, var(--#{$prefix}green-500) 50%, var(--#{$prefix}bg)), + "contrast": var(--#{$prefix}white) + ), + "info": ( + "base": var(--#{$prefix}cyan-500), + "text": light-dark(var(--#{$prefix}cyan-600), var(--#{$prefix}cyan-300)), + "bg": light-dark(var(--#{$prefix}cyan-500), var(--#{$prefix}cyan-500)), + "bg-subtle": light-dark(var(--#{$prefix}cyan-100), var(--#{$prefix}cyan-900)), + "bg-muted": light-dark(var(--#{$prefix}cyan-200), var(--#{$prefix}cyan-800)), + // "bg-emphasized": light-dark(color-mix(in oklch, var(--#{$prefix}cyan-200), var(--#{$prefix}cyan-300)), var(--#{$prefix}cyan-700)), + "border": light-dark(var(--#{$prefix}cyan-300), var(--#{$prefix}cyan-600)), + "focus-ring": color-mix(in oklch, var(--#{$prefix}cyan-500) 50%, var(--#{$prefix}bg)), + "contrast": var(--#{$prefix}gray-900) + ), + "secondary": ( + "base": var(--#{$prefix}gray-300), + "text": light-dark(var(--#{$prefix}gray-600), var(--#{$prefix}gray-400)), + "bg": light-dark(var(--#{$prefix}gray-300), var(--#{$prefix}gray-600)), + "bg-subtle": light-dark(var(--#{$prefix}gray-100), var(--#{$prefix}gray-800)), + "bg-muted": light-dark(var(--#{$prefix}gray-200), var(--#{$prefix}gray-700)), + // "bg-emphasized": light-dark(color-mix(in oklch, var(--#{$prefix}gray-200), var(--#{$prefix}gray-300)), color-mix(in oklch, var(--#{$prefix}gray-600), var(--#{$prefix}gray-700))), + "border": light-dark(var(--#{$prefix}gray-300), var(--#{$prefix}gray-600)), + "focus-ring": color-mix(in oklch, var(--#{$prefix}gray-500) 50%, var(--#{$prefix}bg)), + "contrast": light-dark(var(--#{$prefix}gray-900), var(--#{$prefix}white)) + ) +) !default; +// scss-docs-end theme-colors + +// mdo-do: consider using muted, subtle, ghost or something instead of linear scale? +$theme-bgs: ( + null: light-dark(var(--#{$prefix}white), var(--#{$prefix}gray-900)), + "1": light-dark(var(--#{$prefix}gray-100), color-mix(in srgb, var(--#{$prefix}gray-900), var(--#{$prefix}gray-800))), + "2": light-dark(color-mix(in srgb, var(--#{$prefix}gray-100), var(--#{$prefix}gray-200)), color-mix(in srgb, var(--#{$prefix}gray-800), var(--#{$prefix}gray-700))), + "3": light-dark(color-mix(in srgb, var(--#{$prefix}gray-200), var(--#{$prefix}gray-300)), color-mix(in srgb, var(--#{$prefix}gray-700), var(--#{$prefix}gray-600))), + "white": var(--#{$prefix}white), + "black": var(--#{$prefix}black), + "transparent": transparent, + "inherit": inherit, +) !default; + +$theme-fgs: ( + null: light-dark(var(--#{$prefix}gray-900), var(--#{$prefix}gray-100)), + "1": light-dark(var(--#{$prefix}gray-800), var(--#{$prefix}gray-200)), + "2": light-dark(var(--#{$prefix}gray-700), var(--#{$prefix}gray-300)), + "3": light-dark(var(--#{$prefix}gray-600), var(--#{$prefix}gray-400)), + "white": var(--#{$prefix}white), + "black": var(--#{$prefix}black), + "inherit": inherit, +) !default; + +$theme-borders: ( + null: light-dark(var(--#{$prefix}gray-300), var(--#{$prefix}gray-700)), + "muted": light-dark(var(--#{$prefix}gray-200), var(--#{$prefix}gray-800)), + "subtle": light-dark(var(--#{$prefix}gray-100), color-mix(in srgb, var(--#{$prefix}gray-800), var(--#{$prefix}gray-900))), + "emphasized": light-dark(var(--#{$prefix}gray-400), var(--#{$prefix}gray-600)), +) !default; + +// $util-opacity: ( +// "10": .1, +// "20": .2, +// "30": .3, +// "40": .4, +// "50": .5, +// "60": .6, +// "70": .7, +// "80": .8, +// "90": .9, +// "100": 1 +// ) !default; diff --git a/scss/_toasts.scss b/scss/_toasts.scss index c2a8a61981ca..532d5e8bdf68 100644 --- a/scss/_toasts.scss +++ b/scss/_toasts.scss @@ -1,3 +1,8 @@ +@use "config" as *; +@use "variables" as *; +@use "mixins/border-radius" as *; +@use "vendor/rfs" as *; + .toast { // scss-docs-start toast-css-vars --#{$prefix}toast-zindex: #{$zindex-toast}; diff --git a/scss/_tooltip.scss b/scss/_tooltip.scss index b74e3fcfb8b9..01db6a102640 100644 --- a/scss/_tooltip.scss +++ b/scss/_tooltip.scss @@ -1,3 +1,10 @@ +@use "config" as *; +@use "variables" as *; +@use "mixins/border-radius" as *; +@use "mixins/deprecate" as *; +@use "vendor/rfs" as *; +@use "mixins/reset-text" as *; + // Base class .tooltip { // scss-docs-start tooltip-css-vars diff --git a/scss/_transitions.scss b/scss/_transitions.scss index bfb26aa8ac7e..de779ea6b235 100644 --- a/scss/_transitions.scss +++ b/scss/_transitions.scss @@ -1,3 +1,7 @@ +@use "config" as *; +@use "variables" as *; +@use "mixins/transition" as *; + .fade { @include transition($transition-fade); diff --git a/scss/_utilities.scss b/scss/_utilities.scss index 9fed74fb3727..7bd07f566d57 100644 --- a/scss/_utilities.scss +++ b/scss/_utilities.scss @@ -1,8 +1,15 @@ +@use "sass:map"; +@use "colors" as *; +@use "config" as *; +@use "variables" as *; +@use "functions" as *; +@use "maps" as *; + // Utilities $utilities: () !default; // stylelint-disable-next-line scss/dollar-variable-default -$utilities: map-merge( +$utilities: map.merge( ( // scss-docs-start utils-vertical-align "align": ( @@ -382,43 +389,43 @@ $utilities: map-merge( responsive: true, property: margin, class: m, - values: map-merge($spacers, (auto: auto)) + values: map.merge($spacers, (auto: auto)) ), "margin-x": ( responsive: true, property: margin-right margin-left, class: mx, - values: map-merge($spacers, (auto: auto)) + values: map.merge($spacers, (auto: auto)) ), "margin-y": ( responsive: true, property: margin-top margin-bottom, class: my, - values: map-merge($spacers, (auto: auto)) + values: map.merge($spacers, (auto: auto)) ), "margin-top": ( responsive: true, property: margin-top, class: mt, - values: map-merge($spacers, (auto: auto)) + values: map.merge($spacers, (auto: auto)) ), "margin-end": ( responsive: true, property: margin-right, class: me, - values: map-merge($spacers, (auto: auto)) + values: map.merge($spacers, (auto: auto)) ), "margin-bottom": ( responsive: true, property: margin-bottom, class: mb, - values: map-merge($spacers, (auto: auto)) + values: map.merge($spacers, (auto: auto)) ), "margin-start": ( responsive: true, property: margin-left, class: ms, - values: map-merge($spacers, (auto: auto)) + values: map.merge($spacers, (auto: auto)) ), // Negative margin utilities "negative-margin": ( @@ -608,7 +615,7 @@ $utilities: map-merge( local-vars: ( "text-opacity": 1 ), - values: map-merge( + values: map.merge( $utilities-text-colors, ( "body-secondary": var(--#{$prefix}secondary-color), @@ -663,7 +670,7 @@ $utilities: map-merge( local-vars: ( "link-underline-opacity": 1 ), - values: map-merge( + values: map.merge( $utilities-links-underline, ( null: rgba(var(--#{$prefix}link-color-rgb), var(--#{$prefix}link-underline-opacity, 1)), @@ -691,7 +698,7 @@ $utilities: map-merge( local-vars: ( "bg-opacity": 1 ), - values: map-merge( + values: map.merge( $utilities-bg-colors, ( "transparent": transparent, diff --git a/scss/_variables-dark.scss b/scss/_variables-dark.scss index 590630356af4..be8e662bafa2 100644 --- a/scss/_variables-dark.scss +++ b/scss/_variables-dark.scss @@ -26,7 +26,7 @@ $info-bg-subtle-dark: shade-color($info, 80%) !default; $warning-bg-subtle-dark: shade-color($warning, 80%) !default; $danger-bg-subtle-dark: shade-color($danger, 80%) !default; $light-bg-subtle-dark: $gray-800 !default; -$dark-bg-subtle-dark: mix($gray-800, $black) !default; +$dark-bg-subtle-dark: color.mix($gray-800, $black) !default; // scss-docs-end theme-bg-subtle-dark-variables // scss-docs-start theme-border-subtle-dark-variables @@ -45,7 +45,7 @@ $body-bg-dark: $gray-900 !default; $body-secondary-color-dark: rgba($body-color-dark, .75) !default; $body-secondary-bg-dark: $gray-800 !default; $body-tertiary-color-dark: rgba($body-color-dark, .5) !default; -$body-tertiary-bg-dark: mix($gray-800, $gray-900, 50%) !default; +$body-tertiary-bg-dark: color.mix($gray-800, $gray-900, 50%) !default; $body-emphasis-color-dark: $white !default; $border-color-dark: $gray-700 !default; $border-color-translucent-dark: rgba($white, .15) !default; diff --git a/scss/_variables.scss b/scss/_variables.scss index a78a607e8c49..b2041c6c822f 100644 --- a/scss/_variables.scss +++ b/scss/_variables.scss @@ -1,309 +1,21 @@ +@use "sass:color"; +@use "sass:string"; +@use "colors" as *; +@use "config" as *; +@use "functions" as *; + // Variables // // Variables should follow the `$component-state-property-size` formula for // consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs. -// Color system - -// scss-docs-start gray-color-variables -$white: #fff !default; -$gray-100: #f8f9fa !default; -$gray-200: #e9ecef !default; -$gray-300: #dee2e6 !default; -$gray-400: #ced4da !default; -$gray-500: #adb5bd !default; -$gray-600: #6c757d !default; -$gray-700: #495057 !default; -$gray-800: #343a40 !default; -$gray-900: #212529 !default; -$black: #000 !default; -// scss-docs-end gray-color-variables - -// fusv-disable -// scss-docs-start gray-colors-map -$grays: ( - "100": $gray-100, - "200": $gray-200, - "300": $gray-300, - "400": $gray-400, - "500": $gray-500, - "600": $gray-600, - "700": $gray-700, - "800": $gray-800, - "900": $gray-900 -) !default; -// scss-docs-end gray-colors-map -// fusv-enable - -// scss-docs-start color-variables -$blue: #0d6efd !default; -$indigo: #6610f2 !default; -$purple: #6f42c1 !default; -$pink: #d63384 !default; -$red: #dc3545 !default; -$orange: #fd7e14 !default; -$yellow: #ffc107 !default; -$green: #198754 !default; -$teal: #20c997 !default; -$cyan: #0dcaf0 !default; -// scss-docs-end color-variables - -// scss-docs-start colors-map -$colors: ( - "blue": $blue, - "indigo": $indigo, - "purple": $purple, - "pink": $pink, - "red": $red, - "orange": $orange, - "yellow": $yellow, - "green": $green, - "teal": $teal, - "cyan": $cyan, - "black": $black, - "white": $white, - "gray": $gray-600, - "gray-dark": $gray-800 -) !default; -// scss-docs-end colors-map - -// The contrast ratio to reach against white, to determine if color changes from "light" to "dark". Acceptable values for WCAG 2.2 are 3, 4.5 and 7. -// See https://www.w3.org/TR/WCAG/#contrast-minimum -$min-contrast-ratio: 4.5 !default; - -// Customize the light and dark text colors for use in our color contrast function. -$color-contrast-dark: $black !default; -$color-contrast-light: $white !default; - -// fusv-disable -$blue-100: tint-color($blue, 80%) !default; -$blue-200: tint-color($blue, 60%) !default; -$blue-300: tint-color($blue, 40%) !default; -$blue-400: tint-color($blue, 20%) !default; -$blue-500: $blue !default; -$blue-600: shade-color($blue, 20%) !default; -$blue-700: shade-color($blue, 40%) !default; -$blue-800: shade-color($blue, 60%) !default; -$blue-900: shade-color($blue, 80%) !default; - -$indigo-100: tint-color($indigo, 80%) !default; -$indigo-200: tint-color($indigo, 60%) !default; -$indigo-300: tint-color($indigo, 40%) !default; -$indigo-400: tint-color($indigo, 20%) !default; -$indigo-500: $indigo !default; -$indigo-600: shade-color($indigo, 20%) !default; -$indigo-700: shade-color($indigo, 40%) !default; -$indigo-800: shade-color($indigo, 60%) !default; -$indigo-900: shade-color($indigo, 80%) !default; - -$purple-100: tint-color($purple, 80%) !default; -$purple-200: tint-color($purple, 60%) !default; -$purple-300: tint-color($purple, 40%) !default; -$purple-400: tint-color($purple, 20%) !default; -$purple-500: $purple !default; -$purple-600: shade-color($purple, 20%) !default; -$purple-700: shade-color($purple, 40%) !default; -$purple-800: shade-color($purple, 60%) !default; -$purple-900: shade-color($purple, 80%) !default; - -$pink-100: tint-color($pink, 80%) !default; -$pink-200: tint-color($pink, 60%) !default; -$pink-300: tint-color($pink, 40%) !default; -$pink-400: tint-color($pink, 20%) !default; -$pink-500: $pink !default; -$pink-600: shade-color($pink, 20%) !default; -$pink-700: shade-color($pink, 40%) !default; -$pink-800: shade-color($pink, 60%) !default; -$pink-900: shade-color($pink, 80%) !default; - -$red-100: tint-color($red, 80%) !default; -$red-200: tint-color($red, 60%) !default; -$red-300: tint-color($red, 40%) !default; -$red-400: tint-color($red, 20%) !default; -$red-500: $red !default; -$red-600: shade-color($red, 20%) !default; -$red-700: shade-color($red, 40%) !default; -$red-800: shade-color($red, 60%) !default; -$red-900: shade-color($red, 80%) !default; - -$orange-100: tint-color($orange, 80%) !default; -$orange-200: tint-color($orange, 60%) !default; -$orange-300: tint-color($orange, 40%) !default; -$orange-400: tint-color($orange, 20%) !default; -$orange-500: $orange !default; -$orange-600: shade-color($orange, 20%) !default; -$orange-700: shade-color($orange, 40%) !default; -$orange-800: shade-color($orange, 60%) !default; -$orange-900: shade-color($orange, 80%) !default; - -$yellow-100: tint-color($yellow, 80%) !default; -$yellow-200: tint-color($yellow, 60%) !default; -$yellow-300: tint-color($yellow, 40%) !default; -$yellow-400: tint-color($yellow, 20%) !default; -$yellow-500: $yellow !default; -$yellow-600: shade-color($yellow, 20%) !default; -$yellow-700: shade-color($yellow, 40%) !default; -$yellow-800: shade-color($yellow, 60%) !default; -$yellow-900: shade-color($yellow, 80%) !default; - -$green-100: tint-color($green, 80%) !default; -$green-200: tint-color($green, 60%) !default; -$green-300: tint-color($green, 40%) !default; -$green-400: tint-color($green, 20%) !default; -$green-500: $green !default; -$green-600: shade-color($green, 20%) !default; -$green-700: shade-color($green, 40%) !default; -$green-800: shade-color($green, 60%) !default; -$green-900: shade-color($green, 80%) !default; - -$teal-100: tint-color($teal, 80%) !default; -$teal-200: tint-color($teal, 60%) !default; -$teal-300: tint-color($teal, 40%) !default; -$teal-400: tint-color($teal, 20%) !default; -$teal-500: $teal !default; -$teal-600: shade-color($teal, 20%) !default; -$teal-700: shade-color($teal, 40%) !default; -$teal-800: shade-color($teal, 60%) !default; -$teal-900: shade-color($teal, 80%) !default; - -$cyan-100: tint-color($cyan, 80%) !default; -$cyan-200: tint-color($cyan, 60%) !default; -$cyan-300: tint-color($cyan, 40%) !default; -$cyan-400: tint-color($cyan, 20%) !default; -$cyan-500: $cyan !default; -$cyan-600: shade-color($cyan, 20%) !default; -$cyan-700: shade-color($cyan, 40%) !default; -$cyan-800: shade-color($cyan, 60%) !default; -$cyan-900: shade-color($cyan, 80%) !default; - -$blues: ( - "blue-100": $blue-100, - "blue-200": $blue-200, - "blue-300": $blue-300, - "blue-400": $blue-400, - "blue-500": $blue-500, - "blue-600": $blue-600, - "blue-700": $blue-700, - "blue-800": $blue-800, - "blue-900": $blue-900 -) !default; - -$indigos: ( - "indigo-100": $indigo-100, - "indigo-200": $indigo-200, - "indigo-300": $indigo-300, - "indigo-400": $indigo-400, - "indigo-500": $indigo-500, - "indigo-600": $indigo-600, - "indigo-700": $indigo-700, - "indigo-800": $indigo-800, - "indigo-900": $indigo-900 -) !default; - -$purples: ( - "purple-100": $purple-100, - "purple-200": $purple-200, - "purple-300": $purple-300, - "purple-400": $purple-400, - "purple-500": $purple-500, - "purple-600": $purple-600, - "purple-700": $purple-700, - "purple-800": $purple-800, - "purple-900": $purple-900 -) !default; - -$pinks: ( - "pink-100": $pink-100, - "pink-200": $pink-200, - "pink-300": $pink-300, - "pink-400": $pink-400, - "pink-500": $pink-500, - "pink-600": $pink-600, - "pink-700": $pink-700, - "pink-800": $pink-800, - "pink-900": $pink-900 -) !default; - -$reds: ( - "red-100": $red-100, - "red-200": $red-200, - "red-300": $red-300, - "red-400": $red-400, - "red-500": $red-500, - "red-600": $red-600, - "red-700": $red-700, - "red-800": $red-800, - "red-900": $red-900 -) !default; - -$oranges: ( - "orange-100": $orange-100, - "orange-200": $orange-200, - "orange-300": $orange-300, - "orange-400": $orange-400, - "orange-500": $orange-500, - "orange-600": $orange-600, - "orange-700": $orange-700, - "orange-800": $orange-800, - "orange-900": $orange-900 -) !default; - -$yellows: ( - "yellow-100": $yellow-100, - "yellow-200": $yellow-200, - "yellow-300": $yellow-300, - "yellow-400": $yellow-400, - "yellow-500": $yellow-500, - "yellow-600": $yellow-600, - "yellow-700": $yellow-700, - "yellow-800": $yellow-800, - "yellow-900": $yellow-900 -) !default; - -$greens: ( - "green-100": $green-100, - "green-200": $green-200, - "green-300": $green-300, - "green-400": $green-400, - "green-500": $green-500, - "green-600": $green-600, - "green-700": $green-700, - "green-800": $green-800, - "green-900": $green-900 -) !default; - -$teals: ( - "teal-100": $teal-100, - "teal-200": $teal-200, - "teal-300": $teal-300, - "teal-400": $teal-400, - "teal-500": $teal-500, - "teal-600": $teal-600, - "teal-700": $teal-700, - "teal-800": $teal-800, - "teal-900": $teal-900 -) !default; - -$cyans: ( - "cyan-100": $cyan-100, - "cyan-200": $cyan-200, - "cyan-300": $cyan-300, - "cyan-400": $cyan-400, - "cyan-500": $cyan-500, - "cyan-600": $cyan-600, - "cyan-700": $cyan-700, - "cyan-800": $cyan-800, - "cyan-900": $cyan-900 -) !default; -// fusv-enable - // scss-docs-start theme-color-variables -$primary: $blue !default; +$primary: $purple-500 !default; $secondary: $gray-600 !default; -$success: $green !default; -$info: $cyan !default; -$warning: $yellow !default; -$danger: $red !default; +$success: $green-500 !default; +$info: $cyan-500 !default; +$warning: $yellow-500 !default; +$danger: $red-500 !default; $light: $gray-100 !default; $dark: $gray-900 !default; // scss-docs-end theme-color-variables @@ -339,7 +51,7 @@ $success-bg-subtle: tint-color($success, 80%) !default; $info-bg-subtle: tint-color($info, 80%) !default; $warning-bg-subtle: tint-color($warning, 80%) !default; $danger-bg-subtle: tint-color($danger, 80%) !default; -$light-bg-subtle: mix($gray-100, $white) !default; +$light-bg-subtle: color.mix($gray-100, $white) !default; $dark-bg-subtle: $gray-400 !default; // scss-docs-end theme-bg-subtle-variables @@ -363,34 +75,39 @@ $escaped-characters: ( (")", "%29"), ) !default; -// Options -// -// Quickly modify global styling by enabling or disabling optional features. - -$enable-caret: true !default; -$enable-rounded: true !default; -$enable-shadows: false !default; -$enable-gradients: false !default; -$enable-transitions: true !default; -$enable-reduced-motion: true !default; -$enable-smooth-scroll: true !default; -$enable-grid-classes: true !default; -$enable-container-classes: true !default; -$enable-cssgrid: false !default; -$enable-button-pointers: true !default; -$enable-rfs: true !default; -$enable-validation-icons: true !default; -$enable-negative-margins: false !default; -$enable-deprecation-messages: true !default; -$enable-important-utilities: true !default; - -$enable-dark-mode: true !default; -$color-mode-type: data !default; // `data` or `media-query` - -// Prefix for :root CSS variables - +// // Options +// // +// // Quickly modify global styling by enabling or disabling optional features. + +// $enable-caret: true !default; +// $enable-rounded: true !default; +// $enable-shadows: false !default; +// $enable-gradients: false !default; +// $enable-transitions: true !default; +// $enable-reduced-motion: true !default; +// $enable-smooth-scroll: true !default; +// $enable-grid-classes: true !default; +// $enable-container-classes: true !default; +// $enable-cssgrid: false !default; +// $enable-button-pointers: true !default; +// $enable-rfs: true !default; +// $enable-validation-icons: true !default; +// $enable-negative-margins: false !default; +// $enable-deprecation-messages: true !default; +// $enable-important-utilities: true !default; + +// $enable-dark-mode: true !default; +// $color-mode-type: data !default; // `data` or `media-query` + +// // Prefix for :root CSS variables // $prefix: bs- !default; +// $color-mode-type: "media-query" !default; +// $color-contrast-dark: #000 !default; +// $color-contrast-light: #fff !default; +// $min-contrast-ratio: 4.5 !default; + + // Gradient // // The gradient which is added to components if `$enable-gradients` is `true` @@ -474,54 +191,54 @@ $icon-link-icon-transform: translate3d(.25em, 0, 0) !default; $paragraph-margin-bottom: 1rem !default; -// // Grid breakpoints -// // -// // Define the minimum dimensions at which your layout will change, -// // adapting to different screen sizes, for use in media queries. - -// // scss-docs-start grid-breakpoints -// $grid-breakpoints: ( -// xs: 0, -// sm: 576px, -// md: 768px, -// lg: 992px, -// xl: 1200px, -// xxl: 1400px -// ) !default; -// // scss-docs-end grid-breakpoints +// Grid breakpoints +// +// Define the minimum dimensions at which your layout will change, +// adapting to different screen sizes, for use in media queries. + +// scss-docs-start grid-breakpoints +$grid-breakpoints: ( + xs: 0, + sm: 576px, + md: 768px, + lg: 992px, + xl: 1200px, + xxl: 1400px +) !default; +// scss-docs-end grid-breakpoints // @include _assert-ascending($grid-breakpoints, "$grid-breakpoints"); // @include _assert-starts-at-zero($grid-breakpoints, "$grid-breakpoints"); -// // Grid containers -// // -// // Define the maximum width of `.container` for different screen sizes. - -// // scss-docs-start container-max-widths -// $container-max-widths: ( -// sm: 540px, -// md: 720px, -// lg: 960px, -// xl: 1140px, -// xxl: 1320px -// ) !default; -// // scss-docs-end container-max-widths +// Grid containers +// +// Define the maximum width of `.container` for different screen sizes. + +// scss-docs-start container-max-widths +$container-max-widths: ( + sm: 540px, + md: 720px, + lg: 960px, + xl: 1140px, + xxl: 1320px +) !default; +// scss-docs-end container-max-widths // @include _assert-ascending($container-max-widths, "$container-max-widths"); -// // Grid columns -// // -// // Set the number of columns and specify the width of the gutters. +// Grid columns +// +// Set the number of columns and specify the width of the gutters. -// $grid-columns: 12 !default; -// $grid-gutter-width: 1.5rem !default; -// $grid-row-columns: 6 !default; +$grid-columns: 12 !default; +$grid-gutter-width: 1.5rem !default; +$grid-row-columns: 6 !default; -// // Container padding +// Container padding -// $container-padding-x: $grid-gutter-width !default; +$container-padding-x: $grid-gutter-width !default; // Components @@ -829,7 +546,8 @@ $btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default; $btn-link-color: var(--#{$prefix}link-color) !default; $btn-link-hover-color: var(--#{$prefix}link-hover-color) !default; $btn-link-disabled-color: $gray-600 !default; -$btn-link-focus-shadow-rgb: to-rgb(mix(color-contrast($link-color), $link-color, 15%)) !default; +$btn-link-color-contrast: color-contrast($link-color) !default; +$btn-link-focus-shadow-rgb: to-rgb(color.mix($btn-link-color-contrast, $link-color, 15%)) !default; // Allows for customizing button radius independently from global border radius $btn-border-radius: var(--#{$prefix}border-radius) !default; @@ -1601,7 +1319,7 @@ $breadcrumb-margin-bottom: 1rem !default; $breadcrumb-bg: null !default; $breadcrumb-divider-color: var(--#{$prefix}secondary-color) !default; $breadcrumb-active-color: var(--#{$prefix}secondary-color) !default; -$breadcrumb-divider: quote("/") !default; +$breadcrumb-divider: string.quote("/") !default; $breadcrumb-divider-flipped: $breadcrumb-divider !default; $breadcrumb-border-radius: null !default; // scss-docs-end breadcrumb-variables @@ -1640,21 +1358,6 @@ $carousel-transition: transform $carousel-transition-duration eas // scss-docs-end carousel-variables -// Spinners - -// scss-docs-start spinner-variables -$spinner-width: 2rem !default; -$spinner-height: $spinner-width !default; -$spinner-vertical-align: -.125em !default; -$spinner-border-width: .25em !default; -$spinner-animation-speed: .75s !default; - -$spinner-width-sm: 1rem !default; -$spinner-height-sm: $spinner-width-sm !default; -$spinner-border-width-sm: .2em !default; -// scss-docs-end spinner-variables - - // Close // scss-docs-start close-variables @@ -1704,4 +1407,105 @@ $kbd-bg: var(--#{$prefix}body-color) !default; $pre-color: null !default; -@import "variables-dark"; // TODO: can be removed safely in v6, only here to avoid breaking changes in v5.3 +// Dark color mode variables +// +// Custom variables for the `[data-bs-theme="dark"]` theme. Use this as a starting point for your own custom color modes by creating a new theme-specific file like `_variables-dark.scss` and adding the variables you need. + +// +// Global colors +// + +// scss-docs-start sass-dark-mode-vars +// scss-docs-start theme-text-dark-variables +$primary-text-emphasis-dark: tint-color($primary, 40%) !default; +$secondary-text-emphasis-dark: tint-color($secondary, 40%) !default; +$success-text-emphasis-dark: tint-color($success, 40%) !default; +$info-text-emphasis-dark: tint-color($info, 40%) !default; +$warning-text-emphasis-dark: tint-color($warning, 40%) !default; +$danger-text-emphasis-dark: tint-color($danger, 40%) !default; +$light-text-emphasis-dark: $gray-100 !default; +$dark-text-emphasis-dark: $gray-300 !default; +// scss-docs-end theme-text-dark-variables + +// scss-docs-start theme-bg-subtle-dark-variables +$primary-bg-subtle-dark: shade-color($primary, 80%) !default; +$secondary-bg-subtle-dark: shade-color($secondary, 80%) !default; +$success-bg-subtle-dark: shade-color($success, 80%) !default; +$info-bg-subtle-dark: shade-color($info, 80%) !default; +$warning-bg-subtle-dark: shade-color($warning, 80%) !default; +$danger-bg-subtle-dark: shade-color($danger, 80%) !default; +$light-bg-subtle-dark: $gray-800 !default; +$dark-bg-subtle-dark: color.mix($gray-800, $black) !default; +// scss-docs-end theme-bg-subtle-dark-variables + +// scss-docs-start theme-border-subtle-dark-variables +$primary-border-subtle-dark: shade-color($primary, 40%) !default; +$secondary-border-subtle-dark: shade-color($secondary, 40%) !default; +$success-border-subtle-dark: shade-color($success, 40%) !default; +$info-border-subtle-dark: shade-color($info, 40%) !default; +$warning-border-subtle-dark: shade-color($warning, 40%) !default; +$danger-border-subtle-dark: shade-color($danger, 40%) !default; +$light-border-subtle-dark: $gray-700 !default; +$dark-border-subtle-dark: $gray-800 !default; +// scss-docs-end theme-border-subtle-dark-variables + +$body-color-dark: $gray-300 !default; +$body-bg-dark: $gray-900 !default; +$body-secondary-color-dark: rgba($body-color-dark, .75) !default; +$body-secondary-bg-dark: $gray-800 !default; +$body-tertiary-color-dark: rgba($body-color-dark, .5) !default; +$body-tertiary-bg-dark: color.mix($gray-800, $gray-900, 50%) !default; +$body-emphasis-color-dark: $white !default; +$border-color-dark: $gray-700 !default; +$border-color-translucent-dark: rgba($white, .15) !default; +$headings-color-dark: inherit !default; +$link-color-dark: tint-color($primary, 40%) !default; +$link-hover-color-dark: shift-color($link-color-dark, -$link-shade-percentage) !default; +$code-color-dark: tint-color($code-color, 40%) !default; +$mark-color-dark: $body-color-dark !default; +$mark-bg-dark: $yellow-800 !default; + + +// +// Forms +// + +$form-select-indicator-color-dark: $body-color-dark !default; +$form-select-indicator-dark: url("data:image/svg+xml,") !default; + +$form-switch-color-dark: rgba($white, .25) !default; +$form-switch-bg-image-dark: url("data:image/svg+xml,") !default; + +// scss-docs-start form-validation-colors-dark +$form-valid-color-dark: $green-300 !default; +$form-valid-border-color-dark: $green-300 !default; +$form-invalid-color-dark: $red-300 !default; +$form-invalid-border-color-dark: $red-300 !default; +// scss-docs-end form-validation-colors-dark + + +// +// Accordion +// + +$accordion-icon-color-dark: $primary-text-emphasis-dark !default; +$accordion-icon-active-color-dark: $primary-text-emphasis-dark !default; + +$accordion-button-icon-dark: url("data:image/svg+xml,") !default; +$accordion-button-active-icon-dark: url("data:image/svg+xml,") !default; +// scss-docs-end sass-dark-mode-vars + + +// +// Carousel +// + +$carousel-indicator-active-bg-dark: $carousel-dark-indicator-active-bg !default; +$carousel-caption-color-dark: $carousel-dark-caption-color !default; +$carousel-control-icon-filter-dark: $carousel-dark-control-icon-filter !default; + +// +// Close button +// + +$btn-close-filter-dark: $btn-close-white-filter !default; diff --git a/scss/bootstrap-grid.scss b/scss/bootstrap-grid.scss index 52bd577e3ae5..b41f4fa565ae 100644 --- a/scss/bootstrap-grid.scss +++ b/scss/bootstrap-grid.scss @@ -1,25 +1,20 @@ -@import "mixins/banner"; -@include bsBanner(Grid); - -$include-column-box-sizing: true !default; - -@import "functions"; -@import "variables"; -@import "variables-dark"; -@import "maps"; +@use "banner" with ( + $file: "Grid" +); -@import "mixins/breakpoints"; -@import "mixins/container"; -@import "mixins/grid"; -@import "mixins/utilities"; +@use "sass:map"; +@use "colors" as *; +@use "config" as *; +@use "variables" as *; +@use "functions" as *; +@use "maps" as *; -@import "vendor/rfs"; +@forward "utilities"; // Make utilities available downstream +@use "utilities" as *; // Bring utilities into the current namespace -@import "containers"; -@import "grid"; +@forward "layout/containers"; +@forward "layout/grid"; -@import "utilities"; -// Only use the utilities we need // stylelint-disable-next-line scss/dollar-variable-default $utilities: map-get-multiple( $utilities, @@ -59,4 +54,4 @@ $utilities: map-get-multiple( ) ); -@import "utilities/api"; +@use "utilities/api"; diff --git a/scss/bootstrap-reboot.scss b/scss/bootstrap-reboot.scss index 5b69b9552d66..d8b59518a5be 100644 --- a/scss/bootstrap-reboot.scss +++ b/scss/bootstrap-reboot.scss @@ -1,10 +1,6 @@ -@import "mixins/banner"; -@include bsBanner(Reboot); +@use "banner" with ( + $file: "Reboot" +); -@import "functions"; -@import "variables"; -@import "variables-dark"; -@import "maps"; -@import "mixins"; -@import "root"; -@import "reboot"; +@forward "root"; +@forward "content/reboot"; diff --git a/scss/bootstrap-utilities.scss b/scss/bootstrap-utilities.scss index 99c4a3595ca5..e1c0ed911997 100644 --- a/scss/bootstrap-utilities.scss +++ b/scss/bootstrap-utilities.scss @@ -1,19 +1,16 @@ -@import "mixins/banner"; -@include bsBanner(Utilities); +@use "banner" with ( + $file: "Utilities" +); // Configuration -@import "functions"; -@import "variables"; -@import "variables-dark"; -@import "maps"; -@import "mixins"; -@import "utilities"; +// @forward "variables"; // Layout & components -@import "root"; +@use "root" as *; // Helpers -@import "helpers"; +@forward "helpers"; // Utilities -@import "utilities/api"; +@use "utilities" as *; +@use "utilities/api"; diff --git a/scss/bootstrap.scss b/scss/bootstrap.scss index 244401e02e40..a8b5626319ec 100644 --- a/scss/bootstrap.scss +++ b/scss/bootstrap.scss @@ -1,55 +1,46 @@ -// @import "mixins/banner"; -// @include bsBanner(""); - +@use "banner"; // scss-docs-start import-stack -// Configuration -@use "config" as *; +// Global CSS variables, layer definitions, and configuration +@use "root"; + +// Reboot & Content +@use "content"; + +// Layout +@use "layout"; -@import "functions"; -@import "variables"; -@import "variables-dark"; -@import "maps"; -@import "mixins"; -@import "utilities"; +// Forms +@use "forms"; -// Layout & components -@import "root"; -@import "reboot"; -@import "type"; -@import "images"; -// @import "containers"; -// @import "grid"; -@import "layout"; -@import "tables"; -@import "forms"; -@import "buttons"; -@import "transitions"; -@import "dropdown"; -@import "button-group"; -@import "nav"; -@import "navbar"; -@import "card"; -@import "accordion"; -@import "breadcrumb"; -@import "pagination"; -@import "badge"; -@import "alert"; -@import "progress"; -@import "list-group"; -@import "close"; -@import "toasts"; -@import "modal"; -@import "tooltip"; -@import "popover"; -@import "carousel"; -@import "spinners"; -@import "offcanvas"; -@import "placeholders"; +// Components +@use "accordion"; +@use "alert"; +@use "badge"; +@use "breadcrumb"; +@use "buttons"; +@use "button-group"; +@use "card"; +@use "carousel"; +@use "close"; +@use "dropdown"; +@use "list-group"; +@use "modal"; +@use "nav"; +@use "navbar"; +@use "offcanvas"; +@use "pagination"; +@use "placeholders"; +@use "popover"; +@use "progress"; +@use "spinners"; +@use "toasts"; +@use "tooltip"; +@use "transitions"; // Helpers -@import "helpers"; +@use "helpers"; // Utilities -@import "utilities/api"; +@use "utilities/api"; // scss-docs-end import-stack diff --git a/scss/_images.scss b/scss/content/_images.scss similarity index 86% rename from scss/_images.scss rename to scss/content/_images.scss index 3d6a1014c431..9cff580a50ae 100644 --- a/scss/_images.scss +++ b/scss/content/_images.scss @@ -1,3 +1,10 @@ +@use "../config" as *; +@use "../variables" as *; +@use "../vendor/rfs" as *; +@use "../mixins/image" as *; +@use "../mixins/border-radius" as *; +@use "../mixins/box-shadow" as *; + // Responsive images (ensure images don't scale beyond their parents) // // This is purposefully opt-in via an explicit class rather than being the default for all ``s. diff --git a/scss/_reboot.scss b/scss/content/_reboot.scss similarity index 98% rename from scss/_reboot.scss rename to scss/content/_reboot.scss index cbc369864297..86b4f4f77023 100644 --- a/scss/_reboot.scss +++ b/scss/content/_reboot.scss @@ -1,3 +1,9 @@ +@use "../colors" as *; +@use "../config" as *; +@use "../variables" as *; +@use "../vendor/rfs" as *; +@use "../mixins/border-radius" as *; + // stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix diff --git a/scss/_tables.scss b/scss/content/_tables.scss similarity index 77% rename from scss/_tables.scss rename to scss/content/_tables.scss index fa71cd527122..8ae8f634d67b 100644 --- a/scss/_tables.scss +++ b/scss/content/_tables.scss @@ -1,3 +1,37 @@ +@use "sass:color"; +@use "sass:map"; +@use "sass:math"; +@use "../config" as *; +@use "../colors" as *; +@use "../variables" as *; +@use "../functions" as *; +@use "../layout/breakpoints" as *; + +// scss-docs-start table-variant +@mixin table-variant($state, $background) { + .table-#{$state} { + $color: color-contrast(opaque($body-bg, $background)); + $hover-bg: color.mix($color, $background, math.percentage($table-hover-bg-factor)); + $striped-bg: color.mix($color, $background, math.percentage($table-striped-bg-factor)); + $active-bg: color.mix($color, $background, math.percentage($table-active-bg-factor)); + $table-border-color: color.mix($color, $background, math.percentage($table-border-factor)); + + --#{$prefix}table-color: #{$color}; + --#{$prefix}table-bg: #{$background}; + --#{$prefix}table-border-color: #{$table-border-color}; + --#{$prefix}table-striped-bg: #{$striped-bg}; + --#{$prefix}table-striped-color: #{color-contrast($striped-bg)}; + --#{$prefix}table-active-bg: #{$active-bg}; + --#{$prefix}table-active-color: #{color-contrast($active-bg)}; + --#{$prefix}table-hover-bg: #{$hover-bg}; + --#{$prefix}table-hover-color: #{color-contrast($hover-bg)}; + + color: var(--#{$prefix}table-color); + border-color: var(--#{$prefix}table-border-color); + } +} +// scss-docs-end table-variant + // // Basic Bootstrap table // @@ -159,7 +193,7 @@ // Generate series of `.table-responsive-*` classes for configuring the screen // size of where your table will overflow. -@each $breakpoint in map-keys($grid-breakpoints) { +@each $breakpoint in map.keys($grid-breakpoints) { $infix: breakpoint-infix($breakpoint, $grid-breakpoints); @include media-breakpoint-down($breakpoint) { diff --git a/scss/_type.scss b/scss/content/_type.scss similarity index 91% rename from scss/_type.scss rename to scss/content/_type.scss index 5930e909adf4..187e9444093b 100644 --- a/scss/_type.scss +++ b/scss/content/_type.scss @@ -1,3 +1,8 @@ +@use "../config" as *; +@use "../variables" as *; +@use "../mixins/lists" as *; +@use "../vendor/rfs" as *; + // // Headings // diff --git a/scss/content/index.scss b/scss/content/index.scss new file mode 100644 index 000000000000..e643f1b39381 --- /dev/null +++ b/scss/content/index.scss @@ -0,0 +1,4 @@ +@forward "reboot"; +@forward "type"; +@forward "tables"; +@forward "images"; diff --git a/scss/forms/_floating-labels.scss b/scss/forms/_floating-labels.scss index 38df115561b8..cee16e468c16 100644 --- a/scss/forms/_floating-labels.scss +++ b/scss/forms/_floating-labels.scss @@ -1,3 +1,8 @@ +@use "../config" as *; +@use "../variables" as *; +@use "../mixins/border-radius" as *; +@use "../mixins/transition" as *; + .form-floating { position: relative; diff --git a/scss/forms/_form-check.scss b/scss/forms/_form-check.scss index 8a1b639dfe6f..0496abc3c767 100644 --- a/scss/forms/_form-check.scss +++ b/scss/forms/_form-check.scss @@ -1,3 +1,12 @@ +@use "../config" as *; +@use "../variables" as *; +@use "../functions" as *; +@use "../vendor/rfs" as *; +@use "../mixins/border-radius" as *; +@use "../mixins/box-shadow" as *; +@use "../mixins/transition" as *; +@use "../mixins/color-mode" as *; + // // Check/radio // diff --git a/scss/forms/_form-control.scss b/scss/forms/_form-control.scss index 67ae5f4f9038..07515458f69d 100644 --- a/scss/forms/_form-control.scss +++ b/scss/forms/_form-control.scss @@ -1,3 +1,11 @@ +@use "sass:math"; +@use "../config" as *; +@use "../variables" as *; +@use "../vendor/rfs" as *; +@use "../mixins/border-radius" as *; +@use "../mixins/box-shadow" as *; +@use "../mixins/transition" as *; +@use "../mixins/gradients" as *; // // General form controls (plus a few specific high-level interventions) // @@ -56,7 +64,7 @@ // https://github.com/twbs/bootstrap/issues/23307 // TODO: we can remove this workaround once https://bugs.webkit.org/show_bug.cgi?id=198959 is resolved // Multiply line-height by 1em if it has no unit - height: if(unit($input-line-height) == "", $input-line-height * 1em, $input-line-height); + height: if(math.unit($input-line-height) == "", $input-line-height * 1em, $input-line-height); // Android Chrome type="date" is taller than the other inputs // because of "margin: 1px 24px 1px 4px" inside the shadow DOM diff --git a/scss/forms/_form-range.scss b/scss/forms/_form-range.scss index 4732213e977e..0c29c2c652d9 100644 --- a/scss/forms/_form-range.scss +++ b/scss/forms/_form-range.scss @@ -1,3 +1,9 @@ +@use "../variables" as *; +@use "../mixins/border-radius" as *; +@use "../mixins/box-shadow" as *; +@use "../mixins/transition" as *; +@use "../mixins/gradients" as *; + // Range // // Style range inputs the same across browsers. Vendor-specific rules for pseudo diff --git a/scss/forms/_form-select.scss b/scss/forms/_form-select.scss index 69ace529d76a..41f7103754c5 100644 --- a/scss/forms/_form-select.scss +++ b/scss/forms/_form-select.scss @@ -1,3 +1,11 @@ +@use "../config" as *; +@use "../variables" as *; +@use "../vendor/rfs" as *; +@use "../mixins/border-radius" as *; +@use "../mixins/box-shadow" as *; +@use "../mixins/transition" as *; +@use "../mixins/color-mode" as *; + // Select // // Replaces the browser default select with a custom one, mostly pulled from diff --git a/scss/forms/_form-text.scss b/scss/forms/_form-text.scss index f080d1a23437..00ef046071f1 100644 --- a/scss/forms/_form-text.scss +++ b/scss/forms/_form-text.scss @@ -1,3 +1,5 @@ +@use "../variables" as *; +@use "../vendor/rfs" as *; // // Form text // diff --git a/scss/forms/_input-group.scss b/scss/forms/_input-group.scss index 09a92c510595..4661f43a861d 100644 --- a/scss/forms/_input-group.scss +++ b/scss/forms/_input-group.scss @@ -1,3 +1,9 @@ +@use "sass:map"; +@use "sass:string"; +@use "../variables" as *; +@use "../vendor/rfs" as *; +@use "../mixins/border-radius" as *; + // // Base styles // @@ -116,8 +122,8 @@ } $validation-messages: ""; - @each $state in map-keys($form-validation-states) { - $validation-messages: $validation-messages + ":not(." + unquote($state) + "-tooltip)" + ":not(." + unquote($state) + "-feedback)"; + @each $state in map.keys($form-validation-states) { + $validation-messages: $validation-messages + ":not(." + string.unquote($state) + "-tooltip)" + ":not(." + string.unquote($state) + "-feedback)"; } > :not(:first-child):not(.dropdown-menu)#{$validation-messages} { diff --git a/scss/forms/_labels.scss b/scss/forms/_labels.scss index 39ecafcd2f0d..e01eb5371c6a 100644 --- a/scss/forms/_labels.scss +++ b/scss/forms/_labels.scss @@ -1,3 +1,5 @@ +@use "../variables" as *; +@use "../vendor/rfs" as *; // // Labels // diff --git a/scss/forms/_validation.scss b/scss/forms/_validation.scss index c48123a716c8..b1d8f2e6e618 100644 --- a/scss/forms/_validation.scss +++ b/scss/forms/_validation.scss @@ -1,3 +1,9 @@ +@use "../config" as *; +@use "../variables" as *; +@use "../vendor/rfs" as *; +@use "../mixins/border-radius" as *; +@use "../mixins/box-shadow" as *; + // Form validation // // Provide feedback to users when form field values are valid or invalid. Works @@ -5,6 +11,171 @@ // pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for // server-side validation. +// This mixin uses an `if()` technique to be compatible with Dart Sass +// See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details + +// scss-docs-start form-validation-mixins +@mixin form-validation-state-selector($state) { + @if ($state == "valid" or $state == "invalid") { + .was-validated #{if(&, "&", "")}:#{$state}, + #{if(&, "&", "")}.is-#{$state} { + @content; + } + } @else { + #{if(&, "&", "")}.is-#{$state} { + @content; + } + } +} + +@mixin form-validation-state( + $state, + $color, + $icon, + $tooltip-color: color-contrast($color), + $tooltip-bg-color: rgba($color, $form-feedback-tooltip-opacity), + $focus-box-shadow: 0 0 $input-btn-focus-blur $input-focus-width rgba($color, $input-btn-focus-color-opacity), + $border-color: $color +) { + .#{$state}-feedback { + display: none; + width: 100%; + margin-top: $form-feedback-margin-top; + @include font-size($form-feedback-font-size); + font-style: $form-feedback-font-style; + color: $color; + } + + .#{$state}-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; // Contain to parent when possible + padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x; + margin-top: .1rem; + @include font-size($form-feedback-tooltip-font-size); + line-height: $form-feedback-tooltip-line-height; + color: $tooltip-color; + background-color: $tooltip-bg-color; + @include border-radius($form-feedback-tooltip-border-radius); + } + + @include form-validation-state-selector($state) { + ~ .#{$state}-feedback, + ~ .#{$state}-tooltip { + display: block; + } + } + + .form-control { + @include form-validation-state-selector($state) { + border-color: $border-color; + + @if $enable-validation-icons { + padding-right: $input-height-inner; + background-image: escape-svg($icon); + background-repeat: no-repeat; + background-position: right $input-height-inner-quarter center; + background-size: $input-height-inner-half $input-height-inner-half; + } + + &:focus { + border-color: $border-color; + @if $enable-shadows { + @include box-shadow($input-box-shadow, $focus-box-shadow); + } @else { + // Avoid using mixin so we can pass custom focus shadow properly + box-shadow: $focus-box-shadow; + } + } + } + } + + // stylelint-disable-next-line selector-no-qualifying-type + textarea.form-control { + @include form-validation-state-selector($state) { + @if $enable-validation-icons { + padding-right: $input-height-inner; + background-position: top $input-height-inner-quarter right $input-height-inner-quarter; + } + } + } + + .form-select { + @include form-validation-state-selector($state) { + border-color: $border-color; + + @if $enable-validation-icons { + &:not([multiple]):not([size]), + &:not([multiple])[size="1"] { + --#{$prefix}form-select-bg-icon: #{escape-svg($icon)}; + padding-right: $form-select-feedback-icon-padding-end; + background-position: $form-select-bg-position, $form-select-feedback-icon-position; + background-size: $form-select-bg-size, $form-select-feedback-icon-size; + } + } + + &:focus { + border-color: $border-color; + @if $enable-shadows { + @include box-shadow($form-select-box-shadow, $focus-box-shadow); + } @else { + // Avoid using mixin so we can pass custom focus shadow properly + box-shadow: $focus-box-shadow; + } + } + } + } + + .form-control-color { + @include form-validation-state-selector($state) { + @if $enable-validation-icons { + width: add($form-color-width, $input-height-inner); + } + } + } + + .form-check-input { + @include form-validation-state-selector($state) { + border-color: $border-color; + + &:checked { + background-color: $color; + } + + &:focus { + box-shadow: $focus-box-shadow; + } + + ~ .form-check-label { + color: $color; + } + } + } + .form-check-inline .form-check-input { + ~ .#{$state}-feedback { + margin-left: .5em; + } + } + + .input-group { + > .form-control:not(:focus), + > .form-select:not(:focus), + > .form-floating:not(:focus-within) { + @include form-validation-state-selector($state) { + @if $state == "valid" { + z-index: 3; + } @else if $state == "invalid" { + z-index: 4; + } + } + } + } +} +// scss-docs-end form-validation-mixins + + // scss-docs-start form-validation-states-loop @each $state, $data in $form-validation-states { @include form-validation-state($state, $data...); diff --git a/scss/forms/index.scss b/scss/forms/index.scss new file mode 100644 index 000000000000..57e6cd25ee11 --- /dev/null +++ b/scss/forms/index.scss @@ -0,0 +1,9 @@ +@forward "labels"; +@forward "form-text"; +@forward "form-control"; +@forward "form-select"; +@forward "form-check"; +@forward "form-range"; +@forward "floating-labels"; +@forward "input-group"; +@forward "validation"; diff --git a/scss/helpers/_color-bg.scss b/scss/helpers/_color-bg.scss index 1a3a4cffd656..a1c70c02d4f0 100644 --- a/scss/helpers/_color-bg.scss +++ b/scss/helpers/_color-bg.scss @@ -1,3 +1,7 @@ +@use "../colors" as *; +@use "../config" as *; +@use "../variables" as *; + // All-caps `RGBA()` function used because of this Sass bug: https://github.com/sass/node-sass/issues/2251 @each $color, $value in $theme-colors { .text-bg-#{$color} { diff --git a/scss/helpers/_colored-links.scss b/scss/helpers/_colored-links.scss index 5f86857800d4..472f5bf436f6 100644 --- a/scss/helpers/_colored-links.scss +++ b/scss/helpers/_colored-links.scss @@ -1,3 +1,7 @@ +@use "../colors" as *; +@use "../config" as *; +@use "../variables" as *; + // All-caps `RGBA()` function used because of this Sass bug: https://github.com/sass/node-sass/issues/2251 @each $color, $value in $theme-colors { .link-#{$color} { diff --git a/scss/helpers/_focus-ring.scss b/scss/helpers/_focus-ring.scss index 26508a8d6d67..4162c4655337 100644 --- a/scss/helpers/_focus-ring.scss +++ b/scss/helpers/_focus-ring.scss @@ -1,3 +1,5 @@ +@use "../config" as *; + .focus-ring:focus { outline: 0; // 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 diff --git a/scss/helpers/_icon-link.scss b/scss/helpers/_icon-link.scss index 3f8bcb335c14..a6ee904afd2a 100644 --- a/scss/helpers/_icon-link.scss +++ b/scss/helpers/_icon-link.scss @@ -1,3 +1,7 @@ +@use "../config" as *; +@use "../variables" as *; +@use "../mixins/transition" as *; + .icon-link { display: inline-flex; gap: $icon-link-gap; diff --git a/scss/helpers/_position.scss b/scss/helpers/_position.scss index 59103d943617..7b251de3c1de 100644 --- a/scss/helpers/_position.scss +++ b/scss/helpers/_position.scss @@ -1,3 +1,8 @@ +@use "sass:map"; +@use "../config" as *; +@use "../variables" as *; +@use "../layout/breakpoints" as *; + // Shorthand .fixed-top { @@ -17,7 +22,7 @@ } // Responsive sticky top and bottom -@each $breakpoint in map-keys($grid-breakpoints) { +@each $breakpoint in map.keys($grid-breakpoints) { @include media-breakpoint-up($breakpoint) { $infix: breakpoint-infix($breakpoint, $grid-breakpoints); diff --git a/scss/helpers/_stretched-link.scss b/scss/helpers/_stretched-link.scss index 71a1c755afa6..ec283094d029 100644 --- a/scss/helpers/_stretched-link.scss +++ b/scss/helpers/_stretched-link.scss @@ -1,3 +1,5 @@ +@use "../variables" as *; + // // Stretched link // diff --git a/scss/helpers/_text-truncation.scss b/scss/helpers/_text-truncation.scss index 6421dac9a852..082fa0cdace7 100644 --- a/scss/helpers/_text-truncation.scss +++ b/scss/helpers/_text-truncation.scss @@ -1,4 +1,4 @@ -// +@use "../mixins/text-truncate" as *; // Text truncation // diff --git a/scss/helpers/_visually-hidden.scss b/scss/helpers/_visually-hidden.scss index 4760ff03d19c..ad6bf088452c 100644 --- a/scss/helpers/_visually-hidden.scss +++ b/scss/helpers/_visually-hidden.scss @@ -1,3 +1,5 @@ +@use "../mixins/visually-hidden" as *; + // // Visually hidden // diff --git a/scss/helpers/_vr.scss b/scss/helpers/_vr.scss index b6f9d42cb130..15744ab8f4d1 100644 --- a/scss/helpers/_vr.scss +++ b/scss/helpers/_vr.scss @@ -1,3 +1,5 @@ +@use "../variables" as *; + .vr { display: inline-block; align-self: stretch; diff --git a/scss/helpers/index.scss b/scss/helpers/index.scss new file mode 100644 index 000000000000..d9b033aa99f2 --- /dev/null +++ b/scss/helpers/index.scss @@ -0,0 +1,11 @@ +@forward "clearfix"; +@forward "color-bg"; +@forward "colored-links"; +@forward "focus-ring"; +@forward "icon-link"; +@forward "position"; +@forward "stacks"; +@forward "visually-hidden"; +@forward "stretched-link"; +@forward "text-truncation"; +@forward "vr"; diff --git a/scss/layout/_breakpoints.scss b/scss/layout/_breakpoints.scss index 286be893d7fc..adaecdad2942 100644 --- a/scss/layout/_breakpoints.scss +++ b/scss/layout/_breakpoints.scss @@ -1,3 +1,7 @@ +@use "sass:list"; +@use "sass:map"; +@use "../config" as *; + // Breakpoint viewport sizes and media queries. // // Breakpoints are defined as a map of (name: minimum width), order from small to large: @@ -14,12 +18,12 @@ // md // >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl xxl)) // md -@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) { - $n: index($breakpoint-names, $name); +@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map.keys($breakpoints)) { + $n: list.index($breakpoint-names, $name); @if not $n { @error "breakpoint `#{$name}` not found in `#{$breakpoints}`"; } - @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null); + @return if($n < list.length($breakpoint-names), list.nth($breakpoint-names, $n + 1), null); } // Minimum breakpoint width. Null for the smallest (first) breakpoint. @@ -27,7 +31,7 @@ // >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px)) // 576px @function breakpoint-min($name, $breakpoints: $grid-breakpoints) { - $min: map-get($breakpoints, $name); + $min: map.get($breakpoints, $name); @return if($min != 0, $min, null); } @@ -41,7 +45,7 @@ // >> breakpoint-max(md, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px)) // 767.98px @function breakpoint-max($name, $breakpoints: $grid-breakpoints) { - $max: map-get($breakpoints, $name); + $max: map.get($breakpoints, $name); @return if($max and $max > 0, $max - .02, null); } diff --git a/scss/layout/_grid.scss b/scss/layout/_grid.scss index 39b76829ec34..806fc44f08f5 100644 --- a/scss/layout/_grid.scss +++ b/scss/layout/_grid.scss @@ -61,8 +61,8 @@ --#{$prefix}gap: #{$grid-gutter-width}; display: grid; - grid-auto-flow: row; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); + grid-auto-flow: row; gap: var(--#{$prefix}gap); } diff --git a/scss/layout/index.scss b/scss/layout/index.scss index 16303b4ac852..df0a0f295645 100644 --- a/scss/layout/index.scss +++ b/scss/layout/index.scss @@ -1,3 +1,3 @@ -@import "breakpoints"; -@import "containers"; -@import "grid"; \ No newline at end of file +@forward "breakpoints"; +@forward "containers"; +@forward "grid"; diff --git a/scss/mixins/_alert.scss b/scss/mixins/_alert.scss deleted file mode 100644 index fb524af1c209..000000000000 --- a/scss/mixins/_alert.scss +++ /dev/null @@ -1,18 +0,0 @@ -@include deprecate("`alert-variant()`", "v5.3.0", "v6.0.0"); - -// scss-docs-start alert-variant-mixin -@mixin alert-variant($background, $border, $color) { - --#{$prefix}alert-color: #{$color}; - --#{$prefix}alert-bg: #{$background}; - --#{$prefix}alert-border-color: #{$border}; - --#{$prefix}alert-link-color: #{shade-color($color, 20%)}; - - @if $enable-gradients { - background-image: var(--#{$prefix}gradient); - } - - .alert-link { - color: var(--#{$prefix}alert-link-color); - } -} -// scss-docs-end alert-variant-mixin diff --git a/scss/mixins/_border-radius.scss b/scss/mixins/_border-radius.scss index 616decbce315..dbcfa0550093 100644 --- a/scss/mixins/_border-radius.scss +++ b/scss/mixins/_border-radius.scss @@ -1,3 +1,9 @@ +@use "sass:list"; +@use "sass:math"; +@use "sass:meta"; +@use "../config" as *; +@use "../variables" as *; + // stylelint-disable property-disallowed-list // Single side border-radius @@ -5,10 +11,10 @@ @function valid-radius($radius) { $return: (); @each $value in $radius { - @if type-of($value) == number { - $return: append($return, max($value, 0)); + @if meta.type-of($value) == number { + $return: list.append($return, math.max($value, 0)); } @else { - $return: append($return, $value); + $return: list.append($return, $value); } } @return $return; diff --git a/scss/mixins/_box-shadow.scss b/scss/mixins/_box-shadow.scss index 0bb6bf7e7d87..da4aa50bb8ea 100644 --- a/scss/mixins/_box-shadow.scss +++ b/scss/mixins/_box-shadow.scss @@ -1,3 +1,5 @@ +@use "../config" as *; + @mixin box-shadow($shadow...) { @if $enable-shadows { $result: (); diff --git a/scss/mixins/_buttons.scss b/scss/mixins/_buttons.scss deleted file mode 100644 index cf087fda7809..000000000000 --- a/scss/mixins/_buttons.scss +++ /dev/null @@ -1,70 +0,0 @@ -// Button variants -// -// Easily pump out default styles, as well as :hover, :focus, :active, -// and disabled options for all buttons - -// scss-docs-start btn-variant-mixin -@mixin button-variant( - $background, - $border, - $color: color-contrast($background), - $hover-background: if($color == $color-contrast-light, shade-color($background, $btn-hover-bg-shade-amount), tint-color($background, $btn-hover-bg-tint-amount)), - $hover-border: if($color == $color-contrast-light, shade-color($border, $btn-hover-border-shade-amount), tint-color($border, $btn-hover-border-tint-amount)), - $hover-color: color-contrast($hover-background), - $active-background: if($color == $color-contrast-light, shade-color($background, $btn-active-bg-shade-amount), tint-color($background, $btn-active-bg-tint-amount)), - $active-border: if($color == $color-contrast-light, shade-color($border, $btn-active-border-shade-amount), tint-color($border, $btn-active-border-tint-amount)), - $active-color: color-contrast($active-background), - $disabled-background: $background, - $disabled-border: $border, - $disabled-color: color-contrast($disabled-background) -) { - --#{$prefix}btn-color: #{$color}; - --#{$prefix}btn-bg: #{$background}; - --#{$prefix}btn-border-color: #{$border}; - --#{$prefix}btn-hover-color: #{$hover-color}; - --#{$prefix}btn-hover-bg: #{$hover-background}; - --#{$prefix}btn-hover-border-color: #{$hover-border}; - --#{$prefix}btn-focus-shadow-rgb: #{to-rgb(mix($color, $border, 15%))}; - --#{$prefix}btn-active-color: #{$active-color}; - --#{$prefix}btn-active-bg: #{$active-background}; - --#{$prefix}btn-active-border-color: #{$active-border}; - --#{$prefix}btn-active-shadow: #{$btn-active-box-shadow}; - --#{$prefix}btn-disabled-color: #{$disabled-color}; - --#{$prefix}btn-disabled-bg: #{$disabled-background}; - --#{$prefix}btn-disabled-border-color: #{$disabled-border}; -} -// scss-docs-end btn-variant-mixin - -// scss-docs-start btn-outline-variant-mixin -@mixin button-outline-variant( - $color, - $color-hover: color-contrast($color), - $active-background: $color, - $active-border: $color, - $active-color: color-contrast($active-background) -) { - --#{$prefix}btn-color: #{$color}; - --#{$prefix}btn-border-color: #{$color}; - --#{$prefix}btn-hover-color: #{$color-hover}; - --#{$prefix}btn-hover-bg: #{$active-background}; - --#{$prefix}btn-hover-border-color: #{$active-border}; - --#{$prefix}btn-focus-shadow-rgb: #{to-rgb($color)}; - --#{$prefix}btn-active-color: #{$active-color}; - --#{$prefix}btn-active-bg: #{$active-background}; - --#{$prefix}btn-active-border-color: #{$active-border}; - --#{$prefix}btn-active-shadow: #{$btn-active-box-shadow}; - --#{$prefix}btn-disabled-color: #{$color}; - --#{$prefix}btn-disabled-bg: transparent; - --#{$prefix}btn-disabled-border-color: #{$color}; - --#{$prefix}gradient: none; -} -// scss-docs-end btn-outline-variant-mixin - -// scss-docs-start btn-size-mixin -@mixin button-size($padding-y, $padding-x, $font-size, $border-radius) { - --#{$prefix}btn-padding-y: #{$padding-y}; - --#{$prefix}btn-padding-x: #{$padding-x}; - @include rfs($font-size, --#{$prefix}btn-font-size); - --#{$prefix}btn-border-radius: #{$border-radius}; -} -// scss-docs-end btn-size-mixin diff --git a/scss/mixins/_caret.scss b/scss/mixins/_caret.scss index be731165bd3d..802a95ea8d2d 100644 --- a/scss/mixins/_caret.scss +++ b/scss/mixins/_caret.scss @@ -1,3 +1,6 @@ +@use "../config" as *; +@use "../variables" as *; + // scss-docs-start caret-mixins @mixin caret-down($width: $caret-width) { border-top: $width solid; diff --git a/scss/mixins/_color-mode.scss b/scss/mixins/_color-mode.scss index 03338b025675..518b0b099c3d 100644 --- a/scss/mixins/_color-mode.scss +++ b/scss/mixins/_color-mode.scss @@ -1,3 +1,5 @@ +@use "../config" as *; + // scss-docs-start color-mode-mixin @mixin color-mode($mode: light, $root: false) { @if $color-mode-type == "media-query" { diff --git a/scss/mixins/_deprecate.scss b/scss/mixins/_deprecate.scss index df070bc59634..862823df52e1 100644 --- a/scss/mixins/_deprecate.scss +++ b/scss/mixins/_deprecate.scss @@ -1,3 +1,5 @@ +@use "../config" as *; + // Deprecate mixin // // This mixin can be used to deprecate mixins or functions. diff --git a/scss/mixins/_gradients.scss b/scss/mixins/_gradients.scss index 608e18df2eb9..28e022161134 100644 --- a/scss/mixins/_gradients.scss +++ b/scss/mixins/_gradients.scss @@ -1,3 +1,6 @@ +@use "../colors" as *; +@use "../config" as *; + // Gradients // scss-docs-start gradient-bg-mixin diff --git a/scss/mixins/_list-group.scss b/scss/mixins/_list-group.scss deleted file mode 100644 index 6274f3431954..000000000000 --- a/scss/mixins/_list-group.scss +++ /dev/null @@ -1,26 +0,0 @@ -@include deprecate("`list-group-item-variant()`", "v5.3.0", "v6.0.0"); - -// List Groups - -// scss-docs-start list-group-mixin -@mixin list-group-item-variant($state, $background, $color) { - .list-group-item-#{$state} { - color: $color; - background-color: $background; - - &.list-group-item-action { - &:hover, - &:focus { - color: $color; - background-color: shade-color($background, 10%); - } - - &.active { - color: $white; - background-color: $color; - border-color: $color; - } - } - } -} -// scss-docs-end list-group-mixin diff --git a/scss/mixins/_pagination.scss b/scss/mixins/_pagination.scss deleted file mode 100644 index 0d657964fb55..000000000000 --- a/scss/mixins/_pagination.scss +++ /dev/null @@ -1,10 +0,0 @@ -// Pagination - -// scss-docs-start pagination-mixin -@mixin pagination-size($padding-y, $padding-x, $font-size, $border-radius) { - --#{$prefix}pagination-padding-x: #{$padding-x}; - --#{$prefix}pagination-padding-y: #{$padding-y}; - @include rfs($font-size, --#{$prefix}pagination-font-size); - --#{$prefix}pagination-border-radius: #{$border-radius}; -} -// scss-docs-end pagination-mixin diff --git a/scss/mixins/_reset-text.scss b/scss/mixins/_reset-text.scss index f5bd1afec29a..55c9e344ce04 100644 --- a/scss/mixins/_reset-text.scss +++ b/scss/mixins/_reset-text.scss @@ -1,3 +1,5 @@ +@use "../variables" as *; + @mixin reset-text { font-family: $font-family-base; // We deliberately do NOT reset font-size or overflow-wrap / word-wrap. diff --git a/scss/mixins/_table-variants.scss b/scss/mixins/_table-variants.scss deleted file mode 100644 index 5fe1b9b20da5..000000000000 --- a/scss/mixins/_table-variants.scss +++ /dev/null @@ -1,24 +0,0 @@ -// scss-docs-start table-variant -@mixin table-variant($state, $background) { - .table-#{$state} { - $color: color-contrast(opaque($body-bg, $background)); - $hover-bg: mix($color, $background, percentage($table-hover-bg-factor)); - $striped-bg: mix($color, $background, percentage($table-striped-bg-factor)); - $active-bg: mix($color, $background, percentage($table-active-bg-factor)); - $table-border-color: mix($color, $background, percentage($table-border-factor)); - - --#{$prefix}table-color: #{$color}; - --#{$prefix}table-bg: #{$background}; - --#{$prefix}table-border-color: #{$table-border-color}; - --#{$prefix}table-striped-bg: #{$striped-bg}; - --#{$prefix}table-striped-color: #{color-contrast($striped-bg)}; - --#{$prefix}table-active-bg: #{$active-bg}; - --#{$prefix}table-active-color: #{color-contrast($active-bg)}; - --#{$prefix}table-hover-bg: #{$hover-bg}; - --#{$prefix}table-hover-color: #{color-contrast($hover-bg)}; - - color: var(--#{$prefix}table-color); - border-color: var(--#{$prefix}table-border-color); - } -} -// scss-docs-end table-variant diff --git a/scss/mixins/_transition.scss b/scss/mixins/_transition.scss index d437f6d8f420..c9f2ca413791 100644 --- a/scss/mixins/_transition.scss +++ b/scss/mixins/_transition.scss @@ -1,10 +1,13 @@ +@use "sass:list"; +@use "../config" as *; + // stylelint-disable property-disallowed-list @mixin transition($transition...) { - @if length($transition) == 0 { + @if list.length($transition) == 0 { $transition: $transition-base; } - @if length($transition) > 1 { + @if list.length($transition) > 1 { @each $value in $transition { @if $value == null or $value == none { @warn "The keyword 'none' or 'null' must be used as a single argument."; @@ -13,11 +16,11 @@ } @if $enable-transitions { - @if nth($transition, 1) != null { + @if list.nth($transition, 1) != null { transition: $transition; } - @if $enable-reduced-motion and nth($transition, 1) != null and nth($transition, 1) != none { + @if $enable-reduced-motion and list.nth($transition, 1) != null and list.nth($transition, 1) != none { @media (prefers-reduced-motion: reduce) { transition: none; } diff --git a/scss/mixins/_utilities.scss b/scss/mixins/_utilities.scss index 4795e894001f..7202a8231292 100644 --- a/scss/mixins/_utilities.scss +++ b/scss/mixins/_utilities.scss @@ -1,37 +1,48 @@ +@use "sass:list"; +@use "sass:map"; +@use "sass:meta"; +@use "sass:string"; +@use "../config" as *; + // Utility generator // Used to generate utilities & print utilities @mixin generate-utility($utility, $infix: "", $is-rfs-media-query: false) { - $values: map-get($utility, values); + $values: map.get($utility, values); // If the values are a list or string, convert it into a map - @if type-of($values) == "string" or type-of(nth($values, 1)) != "list" { - $values: zip($values, $values); + @if meta.type-of($values) == "string" or meta.type-of(list.nth($values, 1)) != "list" { + // A single value is converted to a map with a null key. + @if list.length($values) == 1 { + $values: (null: list.nth($values, 1)); + } @else { + $values: list.zip($values, $values); + } } @each $key, $value in $values { - $properties: map-get($utility, property); + $properties: map.get($utility, property); // Multiple properties are possible, for example with vertical or horizontal margins or paddings - @if type-of($properties) == "string" { - $properties: append((), $properties); + @if meta.type-of($properties) == "string" { + $properties: list.append((), $properties); } // Use custom class if present - $property-class: if(map-has-key($utility, class), map-get($utility, class), nth($properties, 1)); + $property-class: if(map.has-key($utility, class), map.get($utility, class), list.nth($properties, 1)); $property-class: if($property-class == null, "", $property-class); // Use custom CSS variable name if present, otherwise default to `class` - $css-variable-name: if(map-has-key($utility, css-variable-name), map-get($utility, css-variable-name), map-get($utility, class)); + $css-variable-name: if(map.has-key($utility, css-variable-name), map.get($utility, css-variable-name), map.get($utility, class)); // State params to generate pseudo-classes - $state: if(map-has-key($utility, state), map-get($utility, state), ()); + $state: if(map.has-key($utility, state), map.get($utility, state), ()); - $infix: if($property-class == "" and str-slice($infix, 1, 1) == "-", str-slice($infix, 2), $infix); + $infix: if($property-class == "" and string.slice($infix, 1, 1) == "-", string.slice($infix, 2), $infix); // Don't prefix if value key is null (e.g. with shadow class) $property-class-modifier: if($key, if($property-class == "" and $infix == "", "", "-") + $key, ""); - @if map-get($utility, rfs) { + @if map.get($utility, rfs) { // Inside the media query @if $is-rfs-media-query { $val: rfs-value($value); @@ -44,9 +55,9 @@ } } - $is-css-var: map-get($utility, css-var); - $is-local-vars: map-get($utility, local-vars); - $is-rtl: map-get($utility, rtl); + $is-css-var: map.get($utility, css-var); + $is-local-vars: map.get($utility, local-vars); + $is-rtl: map.get($utility, rtl); @if $value != null { @if $is-rtl == false { diff --git a/scss/mixins/index.scss b/scss/mixins/index.scss new file mode 100644 index 000000000000..b34adbd63ca3 --- /dev/null +++ b/scss/mixins/index.scss @@ -0,0 +1,34 @@ +// Toggles +// +// Used in conjunction with global variables to enable certain theme features. + +// Vendor +// @forward "vendor/rfs"; + +// Deprecate +@forward "deprecate"; + +// Helpers +@forward "color-mode"; +@forward "color-scheme"; +@forward "image"; +@forward "resize"; +@forward "visually-hidden"; +@forward "reset-text"; +@forward "text-truncate"; + +// Utilities +@forward "utilities"; + +// Components +@forward "backdrop"; +@forward "caret"; + +// Skins +@forward "border-radius"; +@forward "box-shadow"; +@forward "gradients"; +@forward "transition"; + +// Layout +@forward "clearfix"; diff --git a/scss/tests/mixins/_auto-import-of-variables-dark.test.scss b/scss/tests/mixins/_auto-import-of-variables-dark.test.scss deleted file mode 100644 index f08ae5875271..000000000000 --- a/scss/tests/mixins/_auto-import-of-variables-dark.test.scss +++ /dev/null @@ -1,7 +0,0 @@ -// TODO: this file can be removed safely in v6 when `@import "variables-dark"` will be removed at the end of _variables.scss - -@import "../../functions"; -@import "../../variables"; -// Voluntarily not importing _variables-dark.scss -@import "../../maps"; -@import "../../mixins"; diff --git a/scss/tests/mixins/_color-modes.test.scss b/scss/tests/mixins/_color-modes.test.scss index 9ecc628deabe..d42053ad70ee 100644 --- a/scss/tests/mixins/_color-modes.test.scss +++ b/scss/tests/mixins/_color-modes.test.scss @@ -1,5 +1,6 @@ // stylelint-disable selector-attribute-quotes +@import "../../colors"; @import "../../functions"; @import "../../variables"; @import "../../variables-dark"; diff --git a/scss/utilities/_api.scss b/scss/utilities/_api.scss index 62e1d398e352..7043218c5940 100644 --- a/scss/utilities/_api.scss +++ b/scss/utilities/_api.scss @@ -1,5 +1,14 @@ +@use "sass:map"; +@use "sass:meta"; +@use "../variables" as *; +@use "../config" as *; +@use "../vendor/rfs" as *; +@use "../layout/breakpoints" as *; +@use "../mixins/utilities" as *; +@use "../utilities" as *; + // Loop over each breakpoint -@each $breakpoint in map-keys($grid-breakpoints) { +@each $breakpoint in map.keys($grid-breakpoints) { // Generate media query if needed @include media-breakpoint-up($breakpoint) { @@ -9,7 +18,7 @@ @each $key, $utility in $utilities { // The utility can be disabled with `false`, thus check if the utility is a map first // Only proceed if responsive media queries are enabled or if it's the base media query - @if type-of($utility) == "map" and (map-get($utility, responsive) or $infix == "") { + @if meta.type-of($utility) == "map" and (map.get($utility, responsive) or $infix == "") { @include generate-utility($utility, $infix); } } @@ -18,15 +27,15 @@ // RFS rescaling @media (min-width: $rfs-mq-value) { - @each $breakpoint in map-keys($grid-breakpoints) { + @each $breakpoint in map.keys($grid-breakpoints) { $infix: breakpoint-infix($breakpoint, $grid-breakpoints); - @if (map-get($grid-breakpoints, $breakpoint) < $rfs-breakpoint) { + @if (map.get($grid-breakpoints, $breakpoint) < $rfs-breakpoint) { // Loop over each utility property @each $key, $utility in $utilities { // The utility can be disabled with `false`, thus check if the utility is a map first // Only proceed if responsive media queries are enabled or if it's the base media query - @if type-of($utility) == "map" and map-get($utility, rfs) and (map-get($utility, responsive) or $infix == "") { + @if meta.type-of($utility) == "map" and map.get($utility, rfs) and (map.get($utility, responsive) or $infix == "") { @include generate-utility($utility, $infix, true); } } @@ -40,7 +49,7 @@ @each $key, $utility in $utilities { // The utility can be disabled with `false`, thus check if the utility is a map first // Then check if the utility needs print styles - @if type-of($utility) == "map" and map-get($utility, print) == true { + @if meta.type-of($utility) == "map" and map.get($utility, print) == true { @include generate-utility($utility, "-print"); } } diff --git a/scss/vendor/_rfs.scss b/scss/vendor/_rfs.scss index aa1f82b96189..3d7a44eae764 100644 --- a/scss/vendor/_rfs.scss +++ b/scss/vendor/_rfs.scss @@ -1,3 +1,8 @@ +@use "sass:map"; +@use "sass:math"; +@use "sass:meta"; +@use "sass:string"; + // stylelint-disable scss/dimension-no-non-numeric-values // SCSS RFS mixin @@ -30,7 +35,7 @@ $rfs-two-dimensional: false !default; // Factor of decrease $rfs-factor: 10 !default; -@if type-of($rfs-factor) != number or $rfs-factor <= 1 { +@if meta.type-of($rfs-factor) != number or $rfs-factor <= 1 { @error "`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1."; } @@ -50,71 +55,29 @@ $rfs-safari-iframe-resize-bug-fix: false !default; $enable-rfs: true !default; // Cache $rfs-base-value unit -$rfs-base-value-unit: unit($rfs-base-value); - -@function divide($dividend, $divisor, $precision: 10) { - $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1); - $dividend: abs($dividend); - $divisor: abs($divisor); - @if $dividend == 0 { - @return 0; - } - @if $divisor == 0 { - @error "Cannot divide by 0"; - } - $remainder: $dividend; - $result: 0; - $factor: 10; - @while ($remainder > 0 and $precision >= 0) { - $quotient: 0; - @while ($remainder >= $divisor) { - $remainder: $remainder - $divisor; - $quotient: $quotient + 1; - } - $result: $result * 10 + $quotient; - $factor: $factor * .1; - $remainder: $remainder * 10; - $precision: $precision - 1; - @if ($precision < 0 and $remainder >= $divisor * 5) { - $result: $result + 1; - } - } - $result: $result * $factor * $sign; - $dividend-unit: unit($dividend); - $divisor-unit: unit($divisor); - $unit-map: ( - "px": 1px, - "rem": 1rem, - "em": 1em, - "%": 1% - ); - @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) { - $result: $result * map-get($unit-map, $dividend-unit); - } - @return $result; -} +$rfs-base-value-unit: math.unit($rfs-base-value); // Remove px-unit from $rfs-base-value for calculations @if $rfs-base-value-unit == px { - $rfs-base-value: divide($rfs-base-value, $rfs-base-value * 0 + 1); + $rfs-base-value: math.div($rfs-base-value, $rfs-base-value * 0 + 1); } @else if $rfs-base-value-unit == rem { - $rfs-base-value: divide($rfs-base-value, divide($rfs-base-value * 0 + 1, $rfs-rem-value)); + $rfs-base-value: math.div($rfs-base-value, math.div($rfs-base-value * 0 + 1, $rfs-rem-value)); } // Cache $rfs-breakpoint unit to prevent multiple calls -$rfs-breakpoint-unit-cache: unit($rfs-breakpoint); +$rfs-breakpoint-unit-cache: math.unit($rfs-breakpoint); // Remove unit from $rfs-breakpoint for calculations @if $rfs-breakpoint-unit-cache == px { - $rfs-breakpoint: divide($rfs-breakpoint, $rfs-breakpoint * 0 + 1); + $rfs-breakpoint: math.div($rfs-breakpoint, $rfs-breakpoint * 0 + 1); } @else if $rfs-breakpoint-unit-cache == rem or $rfs-breakpoint-unit-cache == "em" { - $rfs-breakpoint: divide($rfs-breakpoint, divide($rfs-breakpoint * 0 + 1, $rfs-rem-value)); + $rfs-breakpoint: math.div($rfs-breakpoint, math.div($rfs-breakpoint * 0 + 1, $rfs-rem-value)); } // Calculate the media query value -$rfs-mq-value: if($rfs-breakpoint-unit == px, #{$rfs-breakpoint}px, #{divide($rfs-breakpoint, $rfs-rem-value)}#{$rfs-breakpoint-unit}); +$rfs-mq-value: if($rfs-breakpoint-unit == px, #{$rfs-breakpoint}px, #{math.div($rfs-breakpoint, $rfs-rem-value)}#{$rfs-breakpoint-unit}); $rfs-mq-property-width: if($rfs-mode == max-media-query, max-width, min-width); $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height); @@ -190,7 +153,7 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height // Helper function to get the formatted non-responsive value @function rfs-value($values) { // Convert to list - $values: if(type-of($values) != list, ($values,), $values); + $values: if(meta.type-of($values) != list, ($values,), $values); $val: ""; @@ -201,15 +164,15 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height } @else { // Cache $value unit - $unit: if(type-of($value) == "number", unit($value), false); + $unit: if(meta.type-of($value) == "number", math.unit($value), false); @if $unit == px { // Convert to rem if needed - $val: $val + " " + if($rfs-unit == rem, #{divide($value, $value * 0 + $rfs-rem-value)}rem, $value); + $val: $val + " " + if($rfs-unit == rem, #{math.div($value, $value * 0 + $rfs-rem-value)}rem, $value); } @else if $unit == rem { // Convert to px if needed - $val: $val + " " + if($rfs-unit == px, #{divide($value, $value * 0 + 1) * $rfs-rem-value}px, $value); + $val: $val + " " + if($rfs-unit == px, #{math.div($value, $value * 0 + 1) * $rfs-rem-value}px, $value); } @else { // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value $val: $val + " " + $value; @@ -218,13 +181,13 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height } // Remove first space - @return unquote(str-slice($val, 2)); + @return string.unquote(string.slice($val, 2)); } // Helper function to get the responsive value calculated by RFS @function rfs-fluid-value($values) { // Convert to list - $values: if(type-of($values) != list, ($values,), $values); + $values: if(meta.type-of($values) != list, ($values,), $values); $val: ""; @@ -234,28 +197,28 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height $val: $val + " 0"; } @else { // Cache $value unit - $unit: if(type-of($value) == "number", unit($value), false); + $unit: if(meta.type-of($value) == "number", math.unit($value), false); // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value @if not $unit or $unit != px and $unit != rem { $val: $val + " " + $value; } @else { // Remove unit from $value for calculations - $value: divide($value, $value * 0 + if($unit == px, 1, divide(1, $rfs-rem-value))); + $value: math.div($value, $value * 0 + if($unit == px, 1, math.div(1, $rfs-rem-value))); // Only add the media query if the value is greater than the minimum value @if abs($value) <= $rfs-base-value or not $enable-rfs { - $val: $val + " " + if($rfs-unit == rem, #{divide($value, $rfs-rem-value)}rem, #{$value}px); + $val: $val + " " + if($rfs-unit == rem, #{math.div($value, $rfs-rem-value)}rem, #{$value}px); } @else { // Calculate the minimum value - $value-min: $rfs-base-value + divide(abs($value) - $rfs-base-value, $rfs-factor); + $value-min: $rfs-base-value + math.div(abs($value) - $rfs-base-value, $rfs-factor); // Calculate difference between $value and the minimum value $value-diff: abs($value) - $value-min; // Base value formatting - $min-width: if($rfs-unit == rem, #{divide($value-min, $rfs-rem-value)}rem, #{$value-min}px); + $min-width: if($rfs-unit == rem, #{math.div($value-min, $rfs-rem-value)}rem, #{$value-min}px); // Use negative value if needed $min-width: if($value < 0, -$min-width, $min-width); @@ -264,7 +227,7 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height $variable-unit: if($rfs-two-dimensional, vmin, vw); // Calculate the variable width between 0 and $rfs-breakpoint - $variable-width: #{divide($value-diff * 100, $rfs-breakpoint)}#{$variable-unit}; + $variable-width: #{math.div($value-diff * 100, $rfs-breakpoint)}#{$variable-unit}; // Return the calculated value $val: $val + " calc(" + $min-width + if($value < 0, " - ", " + ") + $variable-width + ")"; @@ -274,7 +237,7 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height } // Remove first space - @return unquote(str-slice($val, 2)); + @return string.unquote(string.slice($val, 2)); } // RFS mixin diff --git a/site/src/content/docs/components/spinners.mdx b/site/src/content/docs/components/spinners.mdx index 4d54f3c04f93..a562dd649d9e 100644 --- a/site/src/content/docs/components/spinners.mdx +++ b/site/src/content/docs/components/spinners.mdx @@ -155,7 +155,7 @@ For both spinners, small spinner modifier classes are used to update the values ### Sass variables - + ### Keyframes diff --git a/site/src/scss/_ads.scss b/site/src/scss/_ads.scss index 8d006a15681f..87a7a889956b 100644 --- a/site/src/scss/_ads.scss +++ b/site/src/scss/_ads.scss @@ -1,3 +1,7 @@ +@use "../../../scss/layout/breakpoints" as *; +@use "../../../scss/vendor/rfs" as *; +@use "../../../scss/mixins/border-radius" as *; + // stylelint-disable declaration-no-important, selector-max-id // diff --git a/site/src/scss/_anchor.scss b/site/src/scss/_anchor.scss index 5bb39150b14e..e44fc91de102 100644 --- a/site/src/scss/_anchor.scss +++ b/site/src/scss/_anchor.scss @@ -1,3 +1,6 @@ +@use "../../../scss/variables" as *; +@use "../../../scss/mixins/transition" as *; + .anchor-link { padding: 0 .175rem; font-weight: 400; diff --git a/site/src/scss/_clipboard-js.scss b/site/src/scss/_clipboard-js.scss index de709d09ba7f..a4c71c8ccfae 100644 --- a/site/src/scss/_clipboard-js.scss +++ b/site/src/scss/_clipboard-js.scss @@ -1,3 +1,6 @@ +@use "../../../scss/layout/breakpoints" as *; +@use "../../../scss/mixins/border-radius" as *; + // clipboard.js // // JS-based `Copy` buttons for code snippets. diff --git a/site/src/scss/_colors.scss b/site/src/scss/_colors.scss index ed693a068f1e..0b3313f10b3e 100644 --- a/site/src/scss/_colors.scss +++ b/site/src/scss/_colors.scss @@ -1,8 +1,14 @@ +@use "sass:map"; +@use "../../../scss/config" as *; +@use "../../../scss/colors" as *; +@use "../../../scss/layout/breakpoints" as *; +@use "../../../scss/functions" as *; + // // Docs color palette classes // -@each $color, $value in map-merge($colors, ("gray-500": $gray-500)) { +@each $color, $value in map.merge($colors, ("gray-500": $gray-500)) { .swatch-#{$color} { color: color-contrast($value); background-color: #{$value}; diff --git a/site/src/scss/_content.scss b/site/src/scss/_content.scss index 12dbbbda5825..be0f9e85866f 100644 --- a/site/src/scss/_content.scss +++ b/site/src/scss/_content.scss @@ -1,3 +1,8 @@ +@use "../../../scss/colors" as *; +@use "../../../scss/variables" as *; +@use "../../../scss/vendor/rfs" as *; +@use "../../../scss/layout/breakpoints" as *; + // // Bootstrap docs content theming // diff --git a/site/src/scss/_masthead.scss b/site/src/scss/_masthead.scss index 9379b3c0fff8..2856983a2526 100644 --- a/site/src/scss/_masthead.scss +++ b/site/src/scss/_masthead.scss @@ -1,3 +1,12 @@ +@use "../../../scss/config" as *; +@use "../../../scss/colors" as *; +@use "../../../scss/variables" as *; +@use "../../../scss/vendor/rfs" as *; +@use "../../../scss/layout/breakpoints" as *; +@use "../../../scss/mixins/border-radius" as *; +@use "../../../scss/mixins/transition" as *; +@use "../../../scss/mixins/color-mode" as *; + .bd-masthead { --bd-pink-rgb: #{to-rgb($pink)}; padding: 3rem 0; @@ -116,10 +125,10 @@ } } -@if $enable-dark-mode { - [data-bs-theme="dark"] { - .masthead-followup-icon { - mix-blend-mode: lighten; - } - } -} +// @if $enable-dark-mode { +// [data-bs-theme="dark"] { +// .masthead-followup-icon { +// mix-blend-mode: lighten; +// } +// } +// } diff --git a/site/src/scss/_navbar.scss b/site/src/scss/_navbar.scss index 341b5dd135e7..e168e109ca8a 100644 --- a/site/src/scss/_navbar.scss +++ b/site/src/scss/_navbar.scss @@ -1,3 +1,11 @@ +@use "../../../scss/colors" as *; +// @use "../../../scss/variables" as *; +@use "../../../scss/layout/breakpoints" as *; +@use "../../../scss/mixins/border-radius" as *; +@use "../../../scss/mixins/color-mode" as *; +@use "../../../scss/mixins/transition" as *; +@use "../../../scss/vendor/rfs" as *; + .bd-navbar { padding: .75rem 0; background-color: transparent; diff --git a/site/src/scss/_placeholder-img.scss b/site/src/scss/_placeholder-img.scss index 6f5bbe418926..e9489e88ef22 100644 --- a/site/src/scss/_placeholder-img.scss +++ b/site/src/scss/_placeholder-img.scss @@ -1,3 +1,5 @@ +@use "../../../scss/vendor/rfs" as *; + // // Placeholder svg used in the docs. // diff --git a/site/src/scss/_search.scss b/site/src/scss/_search.scss index 592d65f98fda..97abe7ff6d6e 100644 --- a/site/src/scss/_search.scss +++ b/site/src/scss/_search.scss @@ -1,3 +1,7 @@ +@use "../../../scss/layout/breakpoints" as *; +@use "../../../scss/mixins/color-mode" as *; +@use "../../../scss/mixins/border-radius" as *; + // stylelint-disable selector-class-pattern :root { diff --git a/site/src/scss/_sidebar.scss b/site/src/scss/_sidebar.scss index fe445565343e..01e5f61a0b8b 100644 --- a/site/src/scss/_sidebar.scss +++ b/site/src/scss/_sidebar.scss @@ -1,3 +1,7 @@ +@use "../../../scss/variables" as *; +@use "../../../scss/layout/breakpoints" as *; +@use "../../../scss/mixins/border-radius" as *; + .bd-sidebar { @include media-breakpoint-up(lg) { position: sticky; diff --git a/site/src/scss/_syntax.scss b/site/src/scss/_syntax.scss index 57e7b821e4bf..11649d0c7990 100644 --- a/site/src/scss/_syntax.scss +++ b/site/src/scss/_syntax.scss @@ -1,3 +1,7 @@ +@use "../../../scss/colors" as *; +@use "../../../scss/variables" as *; +@use "../../../scss/mixins/color-mode" as *; + :root, [data-bs-theme="light"] { // --base00: #fff; diff --git a/site/src/scss/_toc.scss b/site/src/scss/_toc.scss index f9bb8a3e4015..f3824df91629 100644 --- a/site/src/scss/_toc.scss +++ b/site/src/scss/_toc.scss @@ -1,3 +1,7 @@ +@use "../../../scss/layout/breakpoints" as *; +@use "../../../scss/vendor/rfs" as *; +@use "../../../scss/mixins/border-radius" as *; + // stylelint-disable selector-max-type, selector-no-qualifying-type .bd-toc { diff --git a/site/src/scss/_variables.scss b/site/src/scss/_variables.scss index 81ce120405c7..5b23f48fc925 100644 --- a/site/src/scss/_variables.scss +++ b/site/src/scss/_variables.scss @@ -26,12 +26,12 @@ $bd-callout-variants: info, warning, danger !default; --bd-pre-bg: var(--bs-tertiary-bg); } -@include color-mode(dark, true) { - --bd-violet: #{mix($bd-violet, $white, 75%)}; - --bd-violet-bg: #{$bd-violet}; - --bd-toc-color: var(--#{$prefix}emphasis-color); - --bd-sidebar-link-bg: rgba(#{to-rgb(mix($bd-violet, $black, 75%))}, .5); - --bd-callout-link: #{to-rgb($blue-300)}; - --bd-callout-code-color: #{$pink-300}; - --bd-pre-bg: #{adjust-color($gray-900, $lightness: -2.5%)}; // stylelint-disable-line scss/at-function-named-arguments -} +// @include color-mode(dark, true) { +// --bd-violet: #{mix($bd-violet, $white, 75%)}; +// --bd-violet-bg: #{$bd-violet}; +// --bd-toc-color: var(--#{$prefix}emphasis-color); +// --bd-sidebar-link-bg: rgba(#{to-rgb(mix($bd-violet, $black, 75%))}, .5); +// --bd-callout-link: #{to-rgb($blue-300)}; +// --bd-callout-code-color: #{$pink-300}; +// --bd-pre-bg: #{adjust-color($gray-900, $lightness: -2.5%)}; // stylelint-disable-line scss/at-function-named-arguments +// } diff --git a/site/src/scss/docs.scss b/site/src/scss/docs.scss index 4618e1f9a450..ff98569d1750 100644 --- a/site/src/scss/docs.scss +++ b/site/src/scss/docs.scss @@ -34,24 +34,24 @@ $enable-cssgrid: true; @import "../../../scss/grid"; // Load docs components -@import "variables"; -@import "navbar"; -@import "masthead"; -@import "ads"; -@import "content"; -@import "skippy"; -@import "sidebar"; -@import "layout"; -@import "toc"; -@import "footer"; -@import "component-examples"; -@import "buttons"; -@import "callouts"; -@import "brand"; -@import "colors"; -@import "clipboard-js"; -@import "placeholder-img"; -@import "scrolling"; +// @use "variables"; +@use "navbar"; +@use "masthead"; +@use "ads"; +@use "content"; +@use "skippy"; +@use "sidebar"; +@use "layout"; +@use "toc"; +@use "footer"; +@use "component-examples"; +@use "buttons"; +@use "callouts"; +@use "brand"; +@use "colors"; +@use "clipboard-js"; +@use "placeholder-img"; +@use "scrolling"; // Load docs dependencies @import "syntax"; diff --git a/site/src/scss/docs_search.scss b/site/src/scss/docs_search.scss index 03c6659ea674..f1e7151d6cbc 100644 --- a/site/src/scss/docs_search.scss +++ b/site/src/scss/docs_search.scss @@ -5,10 +5,5 @@ * For details, see https://creativecommons.org/licenses/by/3.0/. */ -@import "../../../scss/functions"; -@import "../../../scss/variables"; -@import "../../../scss/mixins"; -@import "variables"; - -@import "@docsearch/css/dist/style"; -@import "search"; +@use "@docsearch/css/dist/style"; +@use "search"; From 1009af7a0222e5c215293fde7431671e2cab8038 Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Tue, 4 Mar 2025 12:21:00 -0800 Subject: [PATCH 03/20] Migrate docs to Sass modules, comment out docs grid CSS --- site/src/components/DocsSidebar.astro | 2 +- site/src/components/head/Scss.astro | 6 +-- site/src/components/head/ScssProd.astro | 4 +- site/src/scss/_ads.scss | 2 +- site/src/scss/_brand.scss | 5 ++ site/src/scss/_buttons.scss | 7 ++- site/src/scss/_callouts.scss | 4 ++ site/src/scss/_colors.scss | 7 +-- site/src/scss/_component-examples.scss | 60 +++++++++++++----------- site/src/scss/_content.scss | 11 +++-- site/src/scss/_layout.scss | 4 ++ site/src/scss/_masthead.scss | 10 ++-- site/src/scss/_navbar.scss | 19 ++++---- site/src/scss/_search.scss | 2 + site/src/scss/_sidebar.scss | 7 +-- site/src/scss/_skippy.scss | 3 ++ site/src/scss/_syntax.scss | 3 +- site/src/scss/_toc.scss | 4 +- site/src/scss/_variables.scss | 62 ++++++++++++++----------- site/src/scss/docs.scss | 26 ++++++----- site/src/scss/docs_search.scss | 4 +- 21 files changed, 148 insertions(+), 104 deletions(-) diff --git a/site/src/components/DocsSidebar.astro b/site/src/components/DocsSidebar.astro index 1282ed7026e1..fb207fb2e95a 100644 --- a/site/src/components/DocsSidebar.astro +++ b/site/src/components/DocsSidebar.astro @@ -20,7 +20,7 @@ const sidebar = getData('sidebar') {group.icon && ( ` styles: In practice, those variables are then applied in Reboot like so: - + Which allows you to make real-time customizations however you like: diff --git a/site/src/content/docs/content/tables.mdx b/site/src/content/docs/content/tables.mdx index 3c47b930a640..7fe22f011b6e 100644 --- a/site/src/content/docs/content/tables.mdx +++ b/site/src/content/docs/content/tables.mdx @@ -227,7 +227,7 @@ For the accented tables ([striped rows](#striped-rows), [striped columns](#strip Behind the scenes it looks like this: - +{/**/} ## Table borders diff --git a/site/src/content/docs/customize/color.mdx b/site/src/content/docs/customize/color.mdx index 178a74780ede..1d3c72fd5d6e 100644 --- a/site/src/content/docs/customize/color.mdx +++ b/site/src/content/docs/customize/color.mdx @@ -448,7 +448,7 @@ Bootstrap’s source Sass files include three maps to help you quickly and easil Within `scss/_variables.scss`, you’ll find Bootstrap’s color variables and Sass map. Here’s an example of the `$colors` Sass map: - +{/**/} Add, remove, or modify values within the map to update how they’re used in many other components. Unfortunately at this time, not _every_ component utilizes this Sass map. Future updates will strive to improve upon this. Until then, plan on making use of the `${color}` variables and this Sass map. diff --git a/site/src/content/docs/utilities/background.mdx b/site/src/content/docs/utilities/background.mdx index 720132e42213..d51a50fa6c43 100644 --- a/site/src/content/docs/utilities/background.mdx +++ b/site/src/content/docs/utilities/background.mdx @@ -80,7 +80,7 @@ In addition to the following Sass functionality, consider reading about our incl Most `background-color` utilities are generated by our theme colors, reassigned from our generic color palette variables. - +{/**/} @@ -88,7 +88,7 @@ Most `background-color` utilities are generated by our theme colors, reassigned Grayscale colors are also available, but only a subset are used to generate any utilities. - +{/**/} Variables for setting `background-color` in `.bg-*-subtle` utilities in light and dark mode: @@ -104,7 +104,7 @@ Theme colors are then put into a Sass map so we can loop over them to generate o Grayscale colors are also available as a Sass map. **This map is not used to generate any utilities.** - +{/**/} RGB colors are generated from a separate Sass map: diff --git a/site/src/content/docs/utilities/colors.mdx b/site/src/content/docs/utilities/colors.mdx index 69a9fd3308c6..07d3b8ec8edc 100644 --- a/site/src/content/docs/utilities/colors.mdx +++ b/site/src/content/docs/utilities/colors.mdx @@ -72,13 +72,13 @@ In addition to the following Sass functionality, consider reading about our incl Most `color` utilities are generated by our theme colors, reassigned from our generic color palette variables. - +{/**/} Grayscale colors are also available, but only a subset are used to generate any utilities. - +{/**/} @@ -96,7 +96,7 @@ Theme colors are then put into a Sass map so we can loop over them to generate o Grayscale colors are also available as a Sass map. **This map is not used to generate any utilities.** - +{/**/} RGB colors are generated from a separate Sass map: From ea7a19e6d363c0ffbda3362c2ea77c4ec5737ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20D=C3=A9ramond?= Date: Thu, 26 Jun 2025 17:28:46 +0200 Subject: [PATCH 11/20] Temporary Bundlewatch fix --- .bundlewatch.config.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.bundlewatch.config.json b/.bundlewatch.config.json index 69e6ca746f2b..adb8fb9c3ead 100644 --- a/.bundlewatch.config.json +++ b/.bundlewatch.config.json @@ -10,27 +10,27 @@ }, { "path": "./dist/css/bootstrap-reboot.css", - "maxSize": "3.5 kB" + "maxSize": "4.25 kB" }, { "path": "./dist/css/bootstrap-reboot.min.css", - "maxSize": "3.25 kB" + "maxSize": "4.25 kB" }, { "path": "./dist/css/bootstrap-utilities.css", - "maxSize": "11.75 kB" + "maxSize": "12.75 kB" }, { "path": "./dist/css/bootstrap-utilities.min.css", - "maxSize": "11.0 kB" + "maxSize": "12.0 kB" }, { "path": "./dist/css/bootstrap.css", - "maxSize": "32.5 kB" + "maxSize": "33.75 kB" }, { "path": "./dist/css/bootstrap.min.css", - "maxSize": "30.25 kB" + "maxSize": "31.25 kB" }, { "path": "./dist/js/bootstrap.bundle.js", From 5014d2fe83ab566a4c33b62544cfe161737f8b68 Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Sun, 22 Jun 2025 14:14:41 -0700 Subject: [PATCH 12/20] docs fix import to use --- site/src/scss/docs_search.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/src/scss/docs_search.scss b/site/src/scss/docs_search.scss index 4af922030c5e..f1e7151d6cbc 100644 --- a/site/src/scss/docs_search.scss +++ b/site/src/scss/docs_search.scss @@ -5,5 +5,5 @@ * For details, see https://creativecommons.org/licenses/by/3.0/. */ -@import "@docsearch/css/dist/style"; -@import "search"; +@use "@docsearch/css/dist/style"; +@use "search"; From 89cf10b189579722dcd11c4795c54b4e11199ed7 Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Sun, 22 Jun 2025 14:15:00 -0700 Subject: [PATCH 13/20] Restyle docs callouts --- site/src/scss/_callouts.scss | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/site/src/scss/_callouts.scss b/site/src/scss/_callouts.scss index b5a4cfba54dd..b2b843628334 100644 --- a/site/src/scss/_callouts.scss +++ b/site/src/scss/_callouts.scss @@ -1,5 +1,6 @@ @use "../../../scss/config" as *; @use "../../../scss/colors" as *; +@use "../../../scss/mixins/border-radius" as *; @use "variables" as *; // @@ -7,20 +8,28 @@ // .bd-callout { - --#{$prefix}link-color-rgb: var(--bd-callout-link); + --#{$prefix}link-color: var(--bd-callout-color); + --#{$prefix}link-hover-color: var(--bd-callout-color); --#{$prefix}code-color: var(--bd-callout-code-color); padding: 1.25rem; margin-top: 1.25rem; margin-bottom: 1.25rem; - color: var(--bd-callout-color, inherit); + font-size: .875rem; + line-height: 1.5; + // color: var(--bd-callout-color, inherit); background-color: var(--bd-callout-bg, var(--bs-gray-100)); + border: 1px solid var(--bd-callout-border, var(--bs-border-color)); border-left: .25rem solid var(--bd-callout-border, var(--bs-gray-300)); + @include border-radius(var(--bs-border-radius)); + // box-shadow: inset .25rem 0 0 var(--bd-callout-border, var(--bs-gray-300)); h4 { margin-bottom: .25rem; } + a { font-weight: 500; } + > :last-child { margin-bottom: 0; } @@ -37,8 +46,8 @@ // Variations @each $variant in $bd-callout-variants { .bd-callout-#{$variant} { - --bd-callout-color: var(--bs-#{$variant}-text-emphasis); - --bd-callout-bg: var(--bs-#{$variant}-bg-subtle); - --bd-callout-border: var(--bs-#{$variant}-border-subtle); + // --bd-callout-color: var(--bs-#{$variant}-text); + --bd-callout-bg: color-mix(in srgb, var(--bs-#{$variant}-bg-subtle), transparent 50%); + --bd-callout-border: var(--bs-#{$variant}-border); } } From 9f536609cda7b3480b77b62456ae01a5c2d460e1 Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Sun, 22 Jun 2025 14:15:59 -0700 Subject: [PATCH 14/20] Fix docs colors --- site/src/scss/_component-examples.scss | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/site/src/scss/_component-examples.scss b/site/src/scss/_component-examples.scss index f86990dc4ed1..03ac963a40a8 100644 --- a/site/src/scss/_component-examples.scss +++ b/site/src/scss/_component-examples.scss @@ -126,8 +126,8 @@ .bd-example-cssgrid [class*="grid"] > * { padding-top: .75rem; padding-bottom: .75rem; - background-color: rgba(var(--bd-violet-rgb), .15); - border: 1px solid rgba(var(--bd-violet-rgb), .3); + background-color: color-mix(in srgb, var(--bd-violet) 15%, transparent); + border: 1px solid color-mix(in srgb, var(--bd-violet) 30%, transparent); } .bd-example-row .row + .row, @@ -137,12 +137,12 @@ .bd-example-row-flex-cols .row { min-height: 10rem; - background-color: rgba(var(--bd-violet-rgb), .15); + background-color: color-mix(in srgb, var(--bd-violet) 15%, transparent); } .bd-example-flex div:not(.vr) { - background-color: rgba(var(--bd-violet-rgb), .15); - border: 1px solid rgba(var(--bd-violet-rgb), .3); + background-color: color-mix(in srgb, var(--bd-violet) 15%, transparent); + border: 1px solid color-mix(in srgb, var(--bd-violet) 30%, transparent); } // // Grid mixins @@ -247,7 +247,7 @@ .simple-list-example-scrollspy { .active { - background-color: rgba(var(--bd-violet-rgb), .15); + background-color: color-mix(in srgb, var(--bd-violet) 15%, transparent); } } From e44daa264674d034d09576722712bde28123e4b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20D=C3=A9ramond?= Date: Thu, 26 Jun 2025 18:28:31 +0200 Subject: [PATCH 15/20] Revert typo --- site/src/content/docs/utilities/aspect-ratio.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/content/docs/utilities/aspect-ratio.mdx b/site/src/content/docs/utilities/aspect-ratio.mdx index 014a72b4d24b..cec9e5de615e 100644 --- a/site/src/content/docs/utilities/aspect-ratio.mdx +++ b/site/src/content/docs/utilities/aspect-ratio.mdx @@ -7,7 +7,7 @@ toc: true Use the ratio utility to manage the aspect ratios of content like `