Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

Allow parent_className and parent_style attributes on dcc.Loading components #840

Merged
merged 11 commits into from
Aug 18, 2020
19 changes: 17 additions & 2 deletions src/components/Loading.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ 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';
import {mergeRight} from 'ramda';

function getSpinner(spinnerType) {
switch (spinnerType) {
Expand Down Expand Up @@ -44,6 +45,7 @@ export default class Loading extends Component {
color,
className,
style,
parent_style,
fullscreen,
debug,
type: spinnerType,
Expand All @@ -53,7 +55,13 @@ export default class Loading extends Component {
const Spinner = isLoading && getSpinner(spinnerType);

return (
<div style={isLoading ? hiddenContainer : {}}>
<div
className={isLoading ? null : className}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the original behavior, modified in #740 which introduced the regression, the className was either applied to

  • the Spinner, if in a loading state
  • the this.props.children div parent, otherwise (at least, if this.props.children wasn't an Object or Function, for some reason. If it was, no className would be applied. See below for these three conditions.)

I'm attempting to mimic this behaviour here. Ideally this would be two different props, in the pattern of style and the new (in this PR) parent_style, but in order to fix the regression and have current apps working without breaking changes I think we need to replicate the old behaviour here.

This was the previous render return value:

if (loading_state && loading_state.is_loading) {
const Spinner = getSpinner(spinnerType);
return (
<div style={{visibility: 'hidden', position: 'relative'}}>
{this.props.children}
<Spinner
className={className}
style={{
visibility: 'visible',
position: 'absolute',
top: '0',
height: '100%',
width: '100%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
...style,
}}
status={loading_state}
color={color}
debug={debug}
fullscreen={fullscreen}
/>
</div>
);
}
if (
type(this.props.children) !== 'Object' ||
type(this.props.children) !== 'Function'
) {
return <div className={className}>{this.props.children}</div>;
}
return this.props.children;

style={mergeRight(
isLoading ? hiddenContainer : {},
parent_style
)}
>
{this.props.children}
<div style={isLoading ? coveringSpinner : {}}>
{isLoading && (
Expand Down Expand Up @@ -113,7 +121,9 @@ Loading.propTypes = {
debug: PropTypes.bool,

/**
* Additional CSS class for the spinner root DOM node
* Additional CSS styling, applied to one of:
* - the spinner root DOM node, if the component's children are currently loading
* - the parent div of the children, once they are loaded
*/
className: PropTypes.string,

Expand All @@ -122,6 +132,11 @@ Loading.propTypes = {
*/
style: PropTypes.object,

/**
* Additional CSS styling for the outermost dcc.Loading parent div DOM node
*/
parent_style: PropTypes.object,

/**
* Primary colour used for the loading spinners
*/
Expand Down