From 71582eabff54b6ff98aa471350258da70a14c802 Mon Sep 17 00:00:00 2001
From: Mark Otto <markd.otto@gmail.com>
Date: Thu, 17 Mar 2022 13:49:57 -0700
Subject: [PATCH] Convert spinners to CSS variables (#35960)

* Convert spinners to CSS variables

* bundlewatch
---
 .bundlewatch.config.json                     |  4 +-
 scss/_spinners.scss                          | 58 +++++++++++++-------
 site/content/docs/5.1/components/spinners.md | 20 ++++++-
 3 files changed, 58 insertions(+), 24 deletions(-)

diff --git a/.bundlewatch.config.json b/.bundlewatch.config.json
index eff437cee5..c040d32389 100644
--- a/.bundlewatch.config.json
+++ b/.bundlewatch.config.json
@@ -26,11 +26,11 @@
     },
     {
       "path": "./dist/css/bootstrap.css",
-      "maxSize": "26.6 kB"
+      "maxSize": "26.65 kB"
     },
     {
       "path": "./dist/css/bootstrap.min.css",
-      "maxSize": "24.65 kB"
+      "maxSize": "24.75 kB"
     },
     {
       "path": "./dist/js/bootstrap.bundle.js",
diff --git a/scss/_spinners.scss b/scss/_spinners.scss
index a4a2c77cf6..2ea94ca4ce 100644
--- a/scss/_spinners.scss
+++ b/scss/_spinners.scss
@@ -2,6 +2,17 @@
 // Rotating border
 //
 
+.spinner-grow,
+.spinner-border {
+  display: inline-block;
+  width: var(--#{$prefix}spinner-width);
+  height: var(--#{$prefix}spinner-height);
+  vertical-align: var(--#{$prefix}spinner-vertical-align);
+  // stylelint-disable-next-line property-disallowed-list
+  border-radius: 50%;
+  animation: var(--#{$prefix}spinner-animation-speed) linear infinite var(--#{$prefix}spinner-animation-name);
+}
+
 // scss-docs-start spinner-border-keyframes
 @keyframes spinner-border {
   to { transform: rotate(360deg) #{"/* rtl:ignore */"}; }
@@ -9,21 +20,25 @@
 // scss-docs-end spinner-border-keyframes
 
 .spinner-border {
-  display: inline-block;
-  width: $spinner-width;
-  height: $spinner-height;
-  vertical-align: $spinner-vertical-align;
-  border: $spinner-border-width solid currentColor;
+  // scss-docs-start spinner-border-css-vars
+  --#{$prefix}spinner-width: #{$spinner-width};
+  --#{$prefix}spinner-height: #{$spinner-height};
+  --#{$prefix}spinner-vertical-align: #{$spinner-vertical-align};
+  --#{$prefix}spinner-border-width: #{$spinner-border-width};
+  --#{$prefix}spinner-animation-speed: #{$spinner-animation-speed};
+  --#{$prefix}spinner-animation-name: spinner-border;
+  // scss-docs-end spinner-border-css-vars
+
+  border: var(--#{$prefix}spinner-border-width) solid currentColor;
   border-right-color: transparent;
-  // stylelint-disable-next-line property-disallowed-list
-  border-radius: 50%;
-  animation: $spinner-animation-speed linear infinite spinner-border;
 }
 
 .spinner-border-sm {
-  width: $spinner-width-sm;
-  height: $spinner-height-sm;
-  border-width: $spinner-border-width-sm;
+  // scss-docs-start spinner-border-sm-css-vars
+  --#{$prefix}spinner-width: #{$spinner-width-sm};
+  --#{$prefix}spinner-height: #{$spinner-height-sm};
+  --#{$prefix}spinner-border-width: #{$spinner-border-width-sm};
+  // scss-docs-end spinner-border-sm-css-vars
 }
 
 //
@@ -43,27 +58,28 @@
 // scss-docs-end spinner-grow-keyframes
 
 .spinner-grow {
-  display: inline-block;
-  width: $spinner-width;
-  height: $spinner-height;
-  vertical-align: $spinner-vertical-align;
+  // scss-docs-start spinner-grow-css-vars
+  --#{$prefix}spinner-width: #{$spinner-width};
+  --#{$prefix}spinner-height: #{$spinner-height};
+  --#{$prefix}spinner-vertical-align: #{$spinner-vertical-align};
+  --#{$prefix}spinner-animation-speed: #{$spinner-animation-speed};
+  --#{$prefix}spinner-animation-name: spinner-grow;
+  // scss-docs-end spinner-grow-css-vars
+
   background-color: currentColor;
-  // stylelint-disable-next-line property-disallowed-list
-  border-radius: 50%;
   opacity: 0;
-  animation: $spinner-animation-speed linear infinite spinner-grow;
 }
 
 .spinner-grow-sm {
-  width: $spinner-width-sm;
-  height: $spinner-height-sm;
+  --#{$prefix}spinner-width: #{$spinner-width-sm};
+  --#{$prefix}spinner-height: #{$spinner-height-sm};
 }
 
 @if $enable-reduced-motion {
   @media (prefers-reduced-motion: reduce) {
     .spinner-border,
     .spinner-grow {
-      animation-duration: $spinner-animation-speed * 2;
+      --#{$prefix}spinner-animation-speed: #{$spinner-animation-speed * 2};
     }
   }
 }
diff --git a/site/content/docs/5.1/components/spinners.md b/site/content/docs/5.1/components/spinners.md
index ef7efaf58c..bc1b1e64f8 100644
--- a/site/content/docs/5.1/components/spinners.md
+++ b/site/content/docs/5.1/components/spinners.md
@@ -171,10 +171,28 @@ Use spinners within buttons to indicate an action is currently processing or tak
 </button>
 {{< /example >}}
 
-## Sass
+## CSS
 
 ### Variables
 
+{{< added-in "5.2.0" >}}
+
+As part of Bootstrap's evolving CSS variables approach, spinners now use local CSS variables on `.spinner-border` and `.spinner-grow` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
+
+Border spinner variables:
+
+{{< scss-docs name="spinner-border-css-vars" file="scss/_spinners.scss" >}}
+
+Growing spinner variables:
+
+{{< scss-docs name="spinner-grow-css-vars" file="scss/_spinners.scss" >}}
+
+For both spinners, small spinner modifier classes are used to update the values of these CSS variables as needed. For example, the `.spinner-border-sm` class does the following:
+
+{{< scss-docs name="spinner-border-sm-css-vars" file="scss/_spinners.scss" >}}
+
+### Sass variables
+
 {{< scss-docs name="spinner-variables" file="scss/_variables.scss" >}}
 
 ### Keyframes