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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]
### Added
- [#840](https://github.com/plotly/dash-table/pull/840) Add styling properties to `dcc.Loading` component
+ `parent_className`: Add CSS class for the outermost `dcc.Loading` parent div DOM node
+ `parent_style`: Add CSS style property for the outermost `dcc.Loading` parent div DOM node
+ provides a workaround for the previous behaviour the of `className` property, which changed in [#740](https://github.com/plotly/dash-core-components/pull/740). `parent_className` (or inline styles in `parent_style`) now allow CSS rules to be applied to the outermost `dcc.Loading` div, which is no longer covered by `className` on loading completion as of Dash Core Components `>= 1.9.1` (Dash `>= 1.11.0`).

## [1.10.2] - 2020-07-27
- [#835](https://github.com/plotly/dash-core-components/pull/835)
- Upgraded Plotly.js to [1.54.7](https://github.com/plotly/plotly.js/releases/tag/v1.54.7)
Expand Down
22 changes: 21 additions & 1 deletion 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,8 @@ export default class Loading extends Component {
color,
className,
style,
parent_className,
parent_style,
fullscreen,
debug,
type: spinnerType,
Expand All @@ -53,7 +56,14 @@ export default class Loading extends Component {
const Spinner = isLoading && getSpinner(spinnerType);

return (
<div style={isLoading ? hiddenContainer : {}}>
<div
className={parent_className}
style={
isLoading
? mergeRight(hiddenContainer, parent_style)
: parent_style
}
>
{this.props.children}
<div style={isLoading ? coveringSpinner : {}}>
{isLoading && (
Expand Down Expand Up @@ -117,11 +127,21 @@ Loading.propTypes = {
*/
className: PropTypes.string,

/**
* Additional CSS class for the outermost dcc.Loading parent div DOM node
*/
parent_className: PropTypes.string,

/**
* Additional CSS styling for the spinner root DOM node
*/
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
85 changes: 85 additions & 0 deletions tests/integration/loading/test_loading_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,88 @@ def get_graph_visibility():
assert len(dash_dcc.find_elements(".js-plotly-plot .bars path")) == 4
assert dash_dcc.driver.execute_script(test_identity)
assert get_graph_visibility() == "visible"


def test_ldcp007_class_and_style_props(dash_dcc):
lock = Lock()

app = dash.Dash(__name__)

app.layout = html.Div(
[
html.Button("click", id="btn"),
dcc.Loading(
id="loading",
className="spinner-class",
parent_className="parent-class",
style={"background-color": "rgb(255,192,203)"},
# rgb(240, 248, 255) = aliceblue
parent_style={"border": "3px solid rgb(240, 248, 255)"},
children=html.Div(id="loading-child"),
),
]
)

@app.callback(Output("loading-child", "children"), [Input("btn", "n_clicks")])
def updateDiv(n_clicks):
if n_clicks is None:
return

with lock:
return "sample text content"

dash_dcc.start_server(app)

dash_dcc.wait_for_style_to_equal(
".parent-class", "border-color", "rgb(240, 248, 255)"
)

with lock:
button = dash_dcc.find_element("#btn")
button.click()
dash_dcc.wait_for_style_to_equal(
".spinner-class", "background-color", "rgba(255, 192, 203, 1)"
)

assert not dash_dcc.get_logs()


def test_ldcp008_graph_in_loading_fits_container_height(dash_dcc):
lock = Lock()

app = dash.Dash(__name__)

app.layout = html.Div(
className="outer-container",
children=[
html.Div(
dcc.Loading(
parent_style={"height": "100%"},
children=dcc.Graph(
style={"height": "100%"},
figure={
"data": [
{
"x": [1, 2, 3, 4],
"y": [4, 1, 6, 9],
"line": {"shape": "spline"},
}
]
},
),
),
)
],
style={"display": "flex", "height": "300px"},
)

dash_dcc.start_server(app)

with lock:
dash_dcc.wait_for_style_to_equal(".js-plotly-plot", "height", "300px")

assert dash_dcc.wait_for_element(".js-plotly-plot").size.get(
"height"
) == dash_dcc.wait_for_element(".outer-container").size.get("height")

assert not dash_dcc.get_logs()
Loading