diff --git a/components/dash-core-components/package-lock.json b/components/dash-core-components/package-lock.json index 7ead02a9cd..e3626b36ed 100644 --- a/components/dash-core-components/package-lock.json +++ b/components/dash-core-components/package-lock.json @@ -19,7 +19,6 @@ "@radix-ui/react-slider": "^1.3.6", "@radix-ui/react-tooltip": "^1.2.8", "base64-js": "^1.5.1", - "color": "^4.2.3", "d3-format": "^1.4.5", "fast-isnumeric": "^1.1.4", "file-saver": "^2.0.5", @@ -6035,18 +6034,6 @@ "dev": true, "license": "MIT" }, - "node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" - } - }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -6059,33 +6046,19 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "node_modules/color-string": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dev": true, "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, - "node_modules/color/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", @@ -13811,6 +13784,7 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dev": true, "dependencies": { "is-arrayish": "^0.3.1" } @@ -13818,7 +13792,8 @@ "node_modules/simple-swizzle/node_modules/is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true }, "node_modules/sisteransi": { "version": "1.0.5", diff --git a/components/dash-core-components/package.json b/components/dash-core-components/package.json index 8f4bb0763c..e72ceceaec 100644 --- a/components/dash-core-components/package.json +++ b/components/dash-core-components/package.json @@ -46,7 +46,6 @@ "@radix-ui/react-slider": "^1.3.6", "@radix-ui/react-tooltip": "^1.2.8", "base64-js": "^1.5.1", - "color": "^4.2.3", "d3-format": "^1.4.5", "fast-isnumeric": "^1.1.4", "file-saver": "^2.0.5", diff --git a/components/dash-core-components/src/components/Loading.react.js b/components/dash-core-components/src/components/Loading.react.js deleted file mode 100644 index 60f5c2f188..0000000000 --- a/components/dash-core-components/src/components/Loading.react.js +++ /dev/null @@ -1,275 +0,0 @@ -import React, {useState, useRef, useMemo, useEffect} from 'react'; -import {equals, concat, includes, toPairs, any} from 'ramda'; -import PropTypes from 'prop-types'; - -import GraphSpinner from '../fragments/Loading/spinners/GraphSpinner.jsx'; -import DefaultSpinner from '../fragments/Loading/spinners/DefaultSpinner.jsx'; -import CubeSpinner from '../fragments/Loading/spinners/CubeSpinner.jsx'; -import CircleSpinner from '../fragments/Loading/spinners/CircleSpinner.jsx'; -import DotSpinner from '../fragments/Loading/spinners/DotSpinner.jsx'; - -const spinnerComponentOptions = { - graph: GraphSpinner, - cube: CubeSpinner, - circle: CircleSpinner, - dot: DotSpinner, -}; - -const getSpinner = spinnerType => - spinnerComponentOptions[spinnerType] || DefaultSpinner; - -const coveringSpinner = { - visibility: 'visible', - position: 'absolute', - top: '0', - height: '100%', - width: '100%', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', -}; - -const loadingSelector = (componentPath, targetComponents) => state => { - let stringPath = JSON.stringify(componentPath); - // Remove the last ] for easy match and add `,` to make sure only children - // trigger the loading. See issue: https://github.com/plotly/dash/issues/3276 - stringPath = stringPath.substring(0, stringPath.length - 1) + ','; - const loadingChildren = toPairs(state.loading).reduce( - (acc, [path, load]) => { - if (path.startsWith(stringPath) && load.length) { - if ( - targetComponents && - !any(l => { - const target = targetComponents[l.id]; - if (!target) { - return false; - } - if (target === '*') { - return true; - } - if (Array.isArray(target)) { - return includes(l.property, target); - } - return l.property === target; - }, load) - ) { - return acc; - } - return concat(acc, load); - } - return acc; - }, - [] - ); - if (loadingChildren.length) { - return loadingChildren; - } - return null; -}; - -function Loading({ - children, - display = 'auto', - color = '#119DFF', - id, - className, - style, - parent_className, - parent_style, - overlay_style, - fullscreen, - debug, - show_initially = true, - type: spinnerType, - delay_hide = 0, - delay_show = 0, - target_components, - custom_spinner, -}) { - const ctx = window.dash_component_api.useDashContext(); - - const loading = ctx.useSelector( - loadingSelector(ctx.componentPath, target_components), - equals - ); - - const [showSpinner, setShowSpinner] = useState(show_initially); - const dismissTimer = useRef(); - const showTimer = useRef(); - - const containerStyle = useMemo(() => { - if (showSpinner) { - return {visibility: 'hidden', ...overlay_style, ...parent_style}; - } - return parent_style; - }, [showSpinner, parent_style]); - - useEffect(() => { - if (display === 'show' || display === 'hide') { - setShowSpinner(display === 'show'); - return; - } - - if (loading) { - // if component is currently loading and there's a dismiss timer active - // we need to clear it. - if (dismissTimer.current) { - dismissTimer.current = clearTimeout(dismissTimer.current); - } - // if component is currently loading but the spinner is not showing and - // there is no timer set to show, then set a timeout to show - if (!showSpinner && !showTimer.current) { - showTimer.current = setTimeout(() => { - setShowSpinner(true); - showTimer.current = null; - }, delay_show); - } - } else { - // if component is not currently loading and there's a show timer - // active we need to clear it - if (showTimer.current) { - showTimer.current = clearTimeout(showTimer.current); - } - // if component is not currently loading and the spinner is showing and - // there's no timer set to dismiss it, then set a timeout to hide it - if (showSpinner && !dismissTimer.current) { - dismissTimer.current = setTimeout(() => { - setShowSpinner(false); - dismissTimer.current = null; - }, delay_hide); - } - } - }, [delay_hide, delay_show, loading, display, showSpinner]); - - const Spinner = showSpinner && getSpinner(spinnerType); - - return ( -
-
- {children} -
-
- {showSpinner && - (custom_spinner || ( - - ))} -
-
- ); -} - -Loading.propTypes = { - /** - * The ID of this component, used to identify dash components - * in callbacks. The ID needs to be unique across all of the - * components in an app. - */ - id: PropTypes.string, - - /** - * Array that holds components to render - */ - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.node), - PropTypes.node, - ]), - - /** - * Property that determines which built-in spinner to show - * one of 'graph', 'cube', 'circle', 'dot', or 'default'. - */ - type: PropTypes.oneOf(['graph', 'cube', 'circle', 'dot', 'default']), - - /** - * Boolean that makes the built-in spinner display full-screen - */ - fullscreen: PropTypes.bool, - - /** - * If true, the built-in spinner will display the component_name and prop_name - * while loading - */ - debug: PropTypes.bool, - - /** - * Additional CSS class for the built-in spinner root DOM node - */ - className: PropTypes.string, - - /** - * Additional CSS class for the outermost dcc.Loading parent div DOM node - */ - parent_className: PropTypes.string, - - /** - * Additional CSS styling for the built-in spinner root DOM node - */ - style: PropTypes.object, - - /** - * Additional CSS styling for the outermost dcc.Loading parent div DOM node - */ - parent_style: PropTypes.object, - /** - * Additional CSS styling for the spinner overlay. This is applied to the - * dcc.Loading children while the spinner is active. The default is `{'visibility': 'hidden'}` - */ - overlay_style: PropTypes.object, - - /** - * Primary color used for the built-in loading spinners - */ - color: PropTypes.string, - - /** - * Setting display to "show" or "hide" will override the loading state coming from dash-renderer - */ - display: PropTypes.oneOf(['auto', 'show', 'hide']), - - /** - * Add a time delay (in ms) to the spinner being removed to prevent flickering. - */ - delay_hide: PropTypes.number, - - /** - * Add a time delay (in ms) to the spinner being shown after the loading_state - * is set to True. - */ - delay_show: PropTypes.number, - - /** - * Whether the Spinner should show on app start-up before the loading state - * has been determined. Default True. Use when also setting `delay_show`. - */ - show_initially: PropTypes.bool, - - /** - * Specify component and prop to trigger showing the loading spinner - * example: `{"output-container": "children", "grid": ["rowData", "columnDefs]}` - * - */ - target_components: PropTypes.objectOf( - PropTypes.oneOfType([ - PropTypes.string, - PropTypes.arrayOf(PropTypes.string), - ]) - ), - - /** - * Component to use rather than the built-in spinner specified in the `type` prop. - * - */ - custom_spinner: PropTypes.node, -}; - -export default Loading; diff --git a/components/dash-core-components/src/components/Loading.tsx b/components/dash-core-components/src/components/Loading.tsx new file mode 100644 index 0000000000..127b6dfacb --- /dev/null +++ b/components/dash-core-components/src/components/Loading.tsx @@ -0,0 +1,185 @@ +import React, {useState, useRef, useMemo, useEffect} from 'react'; +import {equals, concat, includes, toPairs, any} from 'ramda'; + +import GraphSpinner from '../fragments/Loading/spinners/GraphSpinner'; +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 {LoadingProps} from 'src/types'; +import {DebugTitleProps} from '../fragments/Loading/types'; +import {DashLayoutPath} from '@dash-renderer/types/component'; + +const spinnerComponentOptions = { + graph: GraphSpinner, + cube: CubeSpinner, + circle: CircleSpinner, + dot: DotSpinner, + default: DefaultSpinner, +} as const; + +const getSpinner = (spinnerType: keyof typeof spinnerComponentOptions) => + spinnerComponentOptions[spinnerType]; + +const coveringSpinner: React.CSSProperties = { + visibility: 'visible', + position: 'absolute', + top: '0', + height: '100%', + width: '100%', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', +}; + +type LoadingState = { + loading: Record; +}; + +const loadingSelector = + ( + componentPath: DashLayoutPath, + targetComponents?: Record + ) => + (state: LoadingState): DebugTitleProps[] | null => { + let stringPath = JSON.stringify(componentPath); + // Remove the last ] for easy match and add `,` to make sure only children + // trigger the loading. See issue: https://github.com/plotly/dash/issues/3276 + stringPath = stringPath.substring(0, stringPath.length - 1) + ','; + const loadingChildren = toPairs(state.loading).reduce( + (acc, [path, load]) => { + if (path.startsWith(stringPath) && load.length) { + if ( + targetComponents && + !any((l: DebugTitleProps) => { + const target = targetComponents[l.id]; + if (!target) { + return false; + } + if (target === '*') { + return true; + } + if (Array.isArray(target)) { + return includes(l.property, target); + } + return l.property === target; + }, load) + ) { + return acc; + } + return concat(acc, load); + } + return acc; + }, + [] as DebugTitleProps[] + ); + if (loadingChildren.length) { + return loadingChildren; + } + return null; + }; + +function Loading({ + children, + display = 'auto', + color = 'var(--Dash-Fill-Interactive-Strong)', + id, + className, + style, + parent_className, + parent_style, + overlay_style, + fullscreen, + debug, + show_initially = true, + type: spinnerType = 'default', + delay_hide = 0, + delay_show = 0, + target_components, + custom_spinner, +}: LoadingProps) { + const ctx = window.dash_component_api.useDashContext(); + + const loading = ctx.useSelector( + loadingSelector(ctx.componentPath, target_components), + equals + ); + + const [showSpinner, setShowSpinner] = useState(show_initially); + const dismissTimer = useRef(); + const showTimer = useRef(); + + const containerStyle: React.CSSProperties = useMemo(() => { + if (showSpinner) { + return {visibility: 'hidden', ...overlay_style, ...parent_style}; + } + return parent_style ?? {}; + }, [showSpinner, parent_style]); + + useEffect(() => { + if (display === 'show' || display === 'hide') { + setShowSpinner(display === 'show'); + return; + } + + if (loading) { + // if component is currently loading and there's a dismiss timer active + // we need to clear it. + if (dismissTimer.current) { + dismissTimer.current = window.clearTimeout( + dismissTimer.current + ); + } + // if component is currently loading but the spinner is not showing and + // there is no timer set to show, then set a timeout to show + if (!showSpinner && !showTimer.current) { + showTimer.current = window.setTimeout(() => { + setShowSpinner(true); + showTimer.current = undefined; + }, delay_show); + } + } else { + // if component is not currently loading and there's a show timer + // active we need to clear it + if (showTimer.current) { + showTimer.current = window.clearTimeout(showTimer.current); + } + // if component is not currently loading and the spinner is showing and + // there's no timer set to dismiss it, then set a timeout to hide it + if (showSpinner && !dismissTimer.current) { + dismissTimer.current = window.setTimeout(() => { + setShowSpinner(false); + dismissTimer.current = undefined; + }, delay_hide); + } + } + }, [delay_hide, delay_show, loading, display, showSpinner]); + + const Spinner = getSpinner(spinnerType); + + return ( +
+
+ {children} +
+
+ {showSpinner && + (custom_spinner || ( + + ))} +
+
+ ); +} + +export default Loading; diff --git a/components/dash-core-components/src/fragments/Loading/spinners/CircleSpinner.jsx b/components/dash-core-components/src/fragments/Loading/spinners/CircleSpinner.tsx similarity index 95% rename from components/dash-core-components/src/fragments/Loading/spinners/CircleSpinner.jsx rename to components/dash-core-components/src/fragments/Loading/spinners/CircleSpinner.tsx index 1a486d77f1..36d3320910 100644 --- a/components/dash-core-components/src/fragments/Loading/spinners/CircleSpinner.jsx +++ b/components/dash-core-components/src/fragments/Loading/spinners/CircleSpinner.tsx @@ -1,8 +1,6 @@ import React from 'react'; -import PropTypes from 'prop-types'; - -import DebugTitle from './DebugTitle.jsx'; - +import DebugTitle from './DebugTitle'; +import {SpinnerProps} from '../types'; /** * Spinner created by Tobias Ahlin, https://github.com/tobiasahlin/SpinKit @@ -14,10 +12,10 @@ const CircleSpinner = ({ debug, className, style, -}) => { +}: SpinnerProps) => { let debugTitle; if (debug && status) { - debugTitle = status.map((s) => ); + debugTitle = status.map((s, i) => ); } let spinnerClass = fullscreen ? 'dash-spinner-container' : ''; if (className) { @@ -184,13 +182,4 @@ const CircleSpinner = ({ ); }; -CircleSpinner.propTypes = { - status: PropTypes.array, - color: PropTypes.string, - className: PropTypes.string, - fullscreen: PropTypes.bool, - style: PropTypes.object, - debug: PropTypes.bool, -}; - export default CircleSpinner; diff --git a/components/dash-core-components/src/fragments/Loading/spinners/CubeSpinner.jsx b/components/dash-core-components/src/fragments/Loading/spinners/CubeSpinner.tsx similarity index 89% rename from components/dash-core-components/src/fragments/Loading/spinners/CubeSpinner.jsx rename to components/dash-core-components/src/fragments/Loading/spinners/CubeSpinner.tsx index 936ec5fd8c..319694fdb3 100644 --- a/components/dash-core-components/src/fragments/Loading/spinners/CubeSpinner.jsx +++ b/components/dash-core-components/src/fragments/Loading/spinners/CubeSpinner.tsx @@ -1,14 +1,18 @@ import React from 'react'; -import PropTypes from 'prop-types'; -import changeColor from 'color'; +import DebugTitle from './DebugTitle'; +import {SpinnerProps} from '../types'; -import DebugTitle from './DebugTitle.jsx'; - - -const CubeSpinner = ({status, color, fullscreen, debug, className, style}) => { +const CubeSpinner = ({ + status, + color, + fullscreen, + debug, + className, + style, +}: SpinnerProps) => { let debugTitle; if (debug && status) { - debugTitle = status.map((s) => ); + debugTitle = status.map((s, i) => ); } let spinnerClass = fullscreen ? 'dash-spinner-container' : ''; if (className) { @@ -73,31 +77,31 @@ const CubeSpinner = ({status, color, fullscreen, debug, className, style}) => { transform: rotateY(0deg) translateZ(40px); } .dash-cube-side--back { - background-color: ${changeColor(color).darken(0.2)}; + background-color: color-mix(in srgb, ${color} 80%, black 20%); transform: rotateX(180deg) translateZ(40px); animation: blowout-back 4s infinite; } .dash-cube-side--left { - background-color: ${changeColor(color).darken(0.2)}; + background-color: color-mix(in srgb, ${color} 80%, black 20%); transform: rotateY(-90deg) translateZ(40px); animation: blowout-left 4s infinite; } .dash-cube-side--right { - background-color: ${changeColor(color).darken(0.4)}; + background-color: color-mix(in srgb, ${color} 60%, black 40%); transform: rotateY(90deg) translateZ(40px); animation: blowout-right 4s infinite; } .dash-cube-side--top { - background-color: ${changeColor(color).darken(0.2)}; + background-color: color-mix(in srgb, ${color} 80%, black 20%); transform: rotateX(90deg) translateZ(40px); animation: blowout-top 4s infinite; } .dash-cube-side--bottom { - background-color: ${changeColor(color).darken(0.4)}; + background-color: color-mix(in srgb, ${color} 60%, black 40%); transform: rotateX(-90deg) translateZ(40px); animation: blowout-bottom 4s infinite; } @@ -186,13 +190,4 @@ const CubeSpinner = ({status, color, fullscreen, debug, className, style}) => { ); }; -CubeSpinner.propTypes = { - status: PropTypes.array, - color: PropTypes.string, - className: PropTypes.string, - fullscreen: PropTypes.bool, - style: PropTypes.object, - debug: PropTypes.bool, -}; - export default CubeSpinner; diff --git a/components/dash-core-components/src/fragments/Loading/spinners/DebugTitle.jsx b/components/dash-core-components/src/fragments/Loading/spinners/DebugTitle.jsx deleted file mode 100644 index fa58aaac5a..0000000000 --- a/components/dash-core-components/src/fragments/Loading/spinners/DebugTitle.jsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; - -export default function DebugTitle({id, property}) { - return ( -

- Loading #{id} - 's {property} -

- ) -} diff --git a/components/dash-core-components/src/fragments/Loading/spinners/DebugTitle.tsx b/components/dash-core-components/src/fragments/Loading/spinners/DebugTitle.tsx new file mode 100644 index 0000000000..54daeda407 --- /dev/null +++ b/components/dash-core-components/src/fragments/Loading/spinners/DebugTitle.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import {DebugTitleProps} from '../types'; + +export default function DebugTitle({id, property}: DebugTitleProps) { + return ( +

+ Loading #{id} + 's {property} +

+ ); +} diff --git a/components/dash-core-components/src/fragments/Loading/spinners/DefaultSpinner.jsx b/components/dash-core-components/src/fragments/Loading/spinners/DefaultSpinner.tsx similarity index 91% rename from components/dash-core-components/src/fragments/Loading/spinners/DefaultSpinner.jsx rename to components/dash-core-components/src/fragments/Loading/spinners/DefaultSpinner.tsx index 0d9c7d4924..ba1f578930 100644 --- a/components/dash-core-components/src/fragments/Loading/spinners/DefaultSpinner.jsx +++ b/components/dash-core-components/src/fragments/Loading/spinners/DefaultSpinner.tsx @@ -1,7 +1,6 @@ import React from 'react'; -import PropTypes from 'prop-types'; - -import DebugTitle from './DebugTitle.jsx'; +import DebugTitle from './DebugTitle'; +import {SpinnerProps} from '../types'; /** * Spinner created by Tobias Ahlin, https://github.com/tobiasahlin/SpinKit @@ -13,10 +12,10 @@ const DefaultSpinner = ({ debug, className, style, -}) => { +}: SpinnerProps) => { let debugTitle; if (debug && status) { - debugTitle = status.map((s) => ); + debugTitle = status.map((s, i) => ); } let spinnerClass = fullscreen ? 'dash-spinner-container' : ''; if (className) { @@ -108,13 +107,4 @@ const DefaultSpinner = ({ ); }; -DefaultSpinner.propTypes = { - status: PropTypes.array, - color: PropTypes.string, - className: PropTypes.string, - fullscreen: PropTypes.bool, - style: PropTypes.object, - debug: PropTypes.bool, -}; - export default DefaultSpinner; diff --git a/components/dash-core-components/src/fragments/Loading/spinners/DotSpinner.jsx b/components/dash-core-components/src/fragments/Loading/spinners/DotSpinner.tsx similarity index 85% rename from components/dash-core-components/src/fragments/Loading/spinners/DotSpinner.jsx rename to components/dash-core-components/src/fragments/Loading/spinners/DotSpinner.tsx index c6a0906449..02f8679e57 100644 --- a/components/dash-core-components/src/fragments/Loading/spinners/DotSpinner.jsx +++ b/components/dash-core-components/src/fragments/Loading/spinners/DotSpinner.tsx @@ -1,15 +1,21 @@ import React from 'react'; -import PropTypes from 'prop-types'; - -import DebugTitle from './DebugTitle.jsx'; +import DebugTitle from './DebugTitle'; +import {SpinnerProps} from '../types'; /** * Spinner created by Tobias Ahlin, https://github.com/tobiasahlin/SpinKit */ -const DotSpinner = ({status, color, fullscreen, debug, className, style}) => { +const DotSpinner = ({ + status, + color, + fullscreen, + debug, + className, + style, +}: SpinnerProps) => { let debugTitle; if (debug && status) { - debugTitle = status.map((s) => ); + debugTitle = status.map((s, i) => ); } let spinnerClass = fullscreen ? 'dash-spinner-container' : ''; if (className) { @@ -22,7 +28,7 @@ const DotSpinner = ({status, color, fullscreen, debug, className, style}) => {
- +