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

Commit a42d7d2

Browse files
authored
Merge pull request #740 from plotly/674-map-uirevision
Ensure that components are still in the DOM when they are loading.
2 parents c0687b3 + 2b41ea0 commit a42d7d2

16 files changed

+375
-343
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
All notable changes to this project will be documented in this file.
33
This project adheres to [Semantic Versioning](http://semver.org/).
44

5+
## [Unreleased]
6+
### Changed
7+
- [#740](https://github.com/plotly/dash-core-components/pull/740) Keep components that are loading in the DOM, but not visible, as opposed to removing them entirely. This will ensure that the size of the component's container does not shrink or expand when the component goes into the loading state.
8+
9+
### Fixed
10+
- [#740](https://github.com/plotly/dash-core-components/pull/740) Fixed bug in which mapbox `uirevision` was not behaving when inside a `dcc.Loading` component
11+
512
## [1.9.0] - 2020-04-01
613
### Changed
714
- [#766](https://github.com/plotly/dash-core-components/pull/766) Update from React 16.8.6 to 16.13.0

pytest.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[pytest]
2+
testpaths = tests/
3+
addopts = -rsxX -vv
4+
log_format = %(asctime)s | %(levelname)s | %(name)s:%(lineno)d | %(message)s
5+
log_cli_level = ERROR

src/components/Loading.react.js

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import DefaultSpinner from '../fragments/Loading/spinners/DefaultSpinner.jsx';
55
import CubeSpinner from '../fragments/Loading/spinners/CubeSpinner.jsx';
66
import CircleSpinner from '../fragments/Loading/spinners/CircleSpinner.jsx';
77
import DotSpinner from '../fragments/Loading/spinners/DotSpinner.jsx';
8-
import {type} from 'ramda';
98

109
function getSpinner(spinnerType) {
1110
switch (spinnerType) {
@@ -22,6 +21,19 @@ function getSpinner(spinnerType) {
2221
}
2322
}
2423

24+
const hiddenContainer = {visibility: 'hidden', position: 'relative'};
25+
26+
const coveringSpinner = {
27+
visibility: 'visible',
28+
position: 'absolute',
29+
top: '0',
30+
height: '100%',
31+
width: '100%',
32+
display: 'flex',
33+
justifyContent: 'center',
34+
alignItems: 'center',
35+
};
36+
2537
/**
2638
* A Loading component that wraps any other component and displays a spinner until the wrapped component has rendered.
2739
*/
@@ -37,27 +49,26 @@ export default class Loading extends Component {
3749
type: spinnerType,
3850
} = this.props;
3951

40-
if (loading_state && loading_state.is_loading) {
41-
const Spinner = getSpinner(spinnerType);
42-
return (
43-
<Spinner
44-
className={className}
45-
style={style}
46-
status={loading_state}
47-
color={color}
48-
debug={debug}
49-
fullscreen={fullscreen}
50-
/>
51-
);
52-
}
53-
54-
if (
55-
type(this.props.children) !== 'Object' ||
56-
type(this.props.children) !== 'Function'
57-
) {
58-
return <div className={className}>{this.props.children}</div>;
59-
}
60-
return this.props.children;
52+
const isLoading = loading_state && loading_state.is_loading;
53+
const Spinner = isLoading && getSpinner(spinnerType);
54+
55+
return (
56+
<div style={isLoading ? hiddenContainer : {}}>
57+
{this.props.children}
58+
<div style={isLoading ? coveringSpinner : {}}>
59+
{isLoading && (
60+
<Spinner
61+
className={className}
62+
style={style}
63+
status={loading_state}
64+
color={color}
65+
debug={debug}
66+
fullscreen={fullscreen}
67+
/>
68+
)}
69+
</div>
70+
</div>
71+
);
6172
}
6273
}
6374

@@ -85,27 +96,29 @@ Loading.propTypes = {
8596
]),
8697

8798
/**
88-
* Property that determines which spinner to show - one of 'graph', 'cube', 'circle', 'dot', or 'default'.
99+
* Property that determines which spinner to show
100+
* one of 'graph', 'cube', 'circle', 'dot', or 'default'.
89101
*/
90102
type: PropTypes.oneOf(['graph', 'cube', 'circle', 'dot', 'default']),
91103

92104
/**
93-
* Boolean that determines if the loading spinner will be displayed full-screen or not
105+
* Boolean that makes the spinner display full-screen
94106
*/
95107
fullscreen: PropTypes.bool,
96108

97109
/**
98-
* Boolean that determines if the loading spinner will display the status.prop_name and component_name
110+
* If true, the spinner will display the component_name and prop_name
111+
* while loading
99112
*/
100113
debug: PropTypes.bool,
101114

102115
/**
103-
* Additional CSS class for the root DOM node
116+
* Additional CSS class for the spinner root DOM node
104117
*/
105118
className: PropTypes.string,
106119

107120
/**
108-
* Additional CSS styling for the root DOM node
121+
* Additional CSS styling for the spinner root DOM node
109122
*/
110123
style: PropTypes.object,
111124

src/fragments/Loading/spinners/CircleSpinner.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ CircleSpinner.propTypes = {
191191
color: PropTypes.string,
192192
className: PropTypes.string,
193193
fullscreen: PropTypes.bool,
194-
style: PropTypes.bool,
194+
style: PropTypes.object,
195195
debug: PropTypes.bool,
196196
};
197197

src/fragments/Loading/spinners/CubeSpinner.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ CubeSpinner.propTypes = {
193193
color: PropTypes.string,
194194
className: PropTypes.string,
195195
fullscreen: PropTypes.bool,
196-
style: PropTypes.bool,
196+
style: PropTypes.object,
197197
debug: PropTypes.bool,
198198
};
199199

src/fragments/Loading/spinners/DefaultSpinner.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ DefaultSpinner.propTypes = {
116116
color: PropTypes.string,
117117
className: PropTypes.string,
118118
fullscreen: PropTypes.bool,
119-
style: PropTypes.bool,
119+
style: PropTypes.object,
120120
debug: PropTypes.bool,
121121
};
122122

src/fragments/Loading/spinners/DotSpinner.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ DotSpinner.propTypes = {
9595
color: PropTypes.string,
9696
className: PropTypes.string,
9797
fullscreen: PropTypes.bool,
98-
style: PropTypes.bool,
98+
style: PropTypes.object,
9999
debug: PropTypes.bool,
100100
};
101101

src/fragments/Loading/spinners/GraphSpinner.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ GraphSpinner.propTypes = {
332332
color: PropTypes.string,
333333
className: PropTypes.string,
334334
fullscreen: PropTypes.bool,
335-
style: PropTypes.bool,
335+
style: PropTypes.object,
336336
debug: PropTypes.bool,
337337
};
338338

tests/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@ def dash_dcc(request, dash_thread_server, tmpdir):
3030
download_path=tmpdir.mkdir("download").strpath,
3131
percy_assets_root=request.config.getoption("percy_assets"),
3232
percy_finalize=request.config.getoption("nopercyfinalize"),
33+
pause=request.config.getoption("pause"),
3334
) as dc:
3435
yield dc

tests/integration/graph/test_graph_basics.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,15 @@ def selected_df_figure(selection):
9393

9494

9595
@pytest.mark.DCC672
96-
def test_grbs002_graph_wrapped_in_loading_component_does_not_fail(dash_dcc):
96+
def test_grbs003_graph_wrapped_in_loading_component_does_not_fail(dash_dcc):
9797
app = dash.Dash(__name__, suppress_callback_exceptions=True)
9898
app.layout = html.Div([
9999
html.H1('subplot issue'),
100100
dcc.Location(id='url', refresh=False),
101101
dcc.Loading(id="page-content")
102102
])
103103

104-
@app.callback(Output('page-content', 'children'), [Input('url', 'value')])
104+
@app.callback(Output('page-content', 'children'), [Input('url', 'pathname')])
105105
def render_page(url):
106106
return [
107107
dcc.Dropdown(

0 commit comments

Comments
 (0)