diff --git a/components/dash-core-components/src/components/Loading.tsx b/components/dash-core-components/src/components/Loading.tsx
index 127b6dfacb..c9c3d31511 100644
--- a/components/dash-core-components/src/components/Loading.tsx
+++ b/components/dash-core-components/src/components/Loading.tsx
@@ -6,6 +6,7 @@ import DefaultSpinner from '../fragments/Loading/spinners/DefaultSpinner';
import CubeSpinner from '../fragments/Loading/spinners/CubeSpinner';
import CircleSpinner from '../fragments/Loading/spinners/CircleSpinner';
import DotSpinner from '../fragments/Loading/spinners/DotSpinner';
+import ClipSpinner from '../fragments/Loading/spinners/ClipSpinner';
import {LoadingProps} from 'src/types';
import {DebugTitleProps} from '../fragments/Loading/types';
import {DashLayoutPath} from '@dash-renderer/types/component';
@@ -15,6 +16,7 @@ const spinnerComponentOptions = {
cube: CubeSpinner,
circle: CircleSpinner,
dot: DotSpinner,
+ clip: ClipSpinner,
default: DefaultSpinner,
} as const;
diff --git a/components/dash-core-components/src/fragments/Loading/spinners/ClipSpinner.tsx b/components/dash-core-components/src/fragments/Loading/spinners/ClipSpinner.tsx
new file mode 100644
index 0000000000..1f615a78d4
--- /dev/null
+++ b/components/dash-core-components/src/fragments/Loading/spinners/ClipSpinner.tsx
@@ -0,0 +1,73 @@
+import React from 'react';
+import DebugTitle from './DebugTitle';
+import {SpinnerProps} from '../types';
+
+/**
+ * Spinner created by David Hu, https://github.com/davidhu2000/react-spinners
+ */
+const ClipSpinner = ({
+ status,
+ color,
+ fullscreen,
+ debug,
+ className,
+ style,
+}: SpinnerProps) => {
+ let debugTitle;
+ if (debug && status) {
+ debugTitle = status.map((s, i) => );
+ }
+ let spinnerClass = fullscreen ? 'dash-spinner-container' : '';
+ if (className) {
+ spinnerClass += ` ${className}`;
+ }
+ return (
+
+ );
+};
+
+export default ClipSpinner;
diff --git a/components/dash-core-components/src/types.ts b/components/dash-core-components/src/types.ts
index da6d6def97..ff0697096b 100644
--- a/components/dash-core-components/src/types.ts
+++ b/components/dash-core-components/src/types.ts
@@ -1077,9 +1077,9 @@ export interface LoadingProps extends BaseDccProps {
/**
* Property that determines which built-in spinner to show
- * one of 'graph', 'cube', 'circle', 'dot', or 'default'.
+ * one of 'graph', 'cube', 'circle', 'dot', 'clip', or 'default'.
*/
- type?: 'graph' | 'cube' | 'circle' | 'dot' | 'default';
+ type?: 'graph' | 'cube' | 'circle' | 'dot' | 'clip' | 'default';
/**
* Boolean that makes the built-in spinner display full-screen
diff --git a/components/dash-core-components/tests/integration/loading/test_loading_component.py b/components/dash-core-components/tests/integration/loading/test_loading_component.py
index dd7946e7e8..6b7c7a097d 100644
--- a/components/dash-core-components/tests/integration/loading/test_loading_component.py
+++ b/components/dash-core-components/tests/integration/loading/test_loading_component.py
@@ -886,3 +886,28 @@ def updateDiv(n_clicks):
dash_dcc.wait_for_text_to_equal(".div-1", "changed")
assert dash_dcc.get_logs() == []
+
+
+def test_ldcp020_loading_component_clip_spinner(dash_dcc):
+ app = Dash(__name__)
+
+ app.layout = html.Div(
+ dcc.Loading(
+ html.Div("content"),
+ type="clip",
+ color="rgb(255, 0, 0)",
+ display="show",
+ className="loading",
+ )
+ )
+
+ dash_dcc.start_server(app)
+
+ spinner = ".loading .dash-spinner.dash-clip-spinner"
+ dash_dcc.wait_for_style_to_equal(spinner, "border-top-color", "rgba(255, 0, 0, 1)")
+ dash_dcc.wait_for_style_to_equal(spinner, "border-bottom-color", "rgba(0, 0, 0, 0)")
+ dash_dcc.wait_for_style_to_equal(
+ spinner, "animation-name", "dash-clip-spinner-rotate"
+ )
+
+ assert dash_dcc.get_logs() == []