From 3b33dc13f5e4860d48cb02c354f7f041b425dbc6 Mon Sep 17 00:00:00 2001 From: Osakpolor Omonbude Date: Sun, 27 Sep 2026 12:19:28 +0100 Subject: [PATCH] Add clip spinner type to dcc.Loading --- .../src/components/Loading.tsx | 2 + .../Loading/spinners/ClipSpinner.tsx | 73 +++++++++++++++++++ components/dash-core-components/src/types.ts | 4 +- .../loading/test_loading_component.py | 25 +++++++ 4 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 components/dash-core-components/src/fragments/Loading/spinners/ClipSpinner.tsx 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 ( +
+ {debugTitle} +
+ +
+ ); +}; + +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() == []