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

Commit

Permalink
Merge pull request #740 from plotly/674-map-uirevision
Browse files Browse the repository at this point in the history
Ensure that components are still in the DOM when they are loading.
  • Loading branch information
alexcjohnson committed Apr 9, 2020
2 parents c0687b3 + 2b41ea0 commit a42d7d2
Show file tree
Hide file tree
Showing 16 changed files with 375 additions and 343 deletions.
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]
### Changed
- [#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.

### Fixed
- [#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

## [1.9.0] - 2020-04-01
### Changed
- [#766](https://github.com/plotly/dash-core-components/pull/766) Update from React 16.8.6 to 16.13.0
Expand Down
5 changes: 5 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[pytest]
testpaths = tests/
addopts = -rsxX -vv
log_format = %(asctime)s | %(levelname)s | %(name)s:%(lineno)d | %(message)s
log_cli_level = ERROR
67 changes: 40 additions & 27 deletions src/components/Loading.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ 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 {type} from 'ramda';

function getSpinner(spinnerType) {
switch (spinnerType) {
Expand All @@ -22,6 +21,19 @@ function getSpinner(spinnerType) {
}
}

const hiddenContainer = {visibility: 'hidden', position: 'relative'};

const coveringSpinner = {
visibility: 'visible',
position: 'absolute',
top: '0',
height: '100%',
width: '100%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
};

/**
* A Loading component that wraps any other component and displays a spinner until the wrapped component has rendered.
*/
Expand All @@ -37,27 +49,26 @@ export default class Loading extends Component {
type: spinnerType,
} = this.props;

if (loading_state && loading_state.is_loading) {
const Spinner = getSpinner(spinnerType);
return (
<Spinner
className={className}
style={style}
status={loading_state}
color={color}
debug={debug}
fullscreen={fullscreen}
/>
);
}

if (
type(this.props.children) !== 'Object' ||
type(this.props.children) !== 'Function'
) {
return <div className={className}>{this.props.children}</div>;
}
return this.props.children;
const isLoading = loading_state && loading_state.is_loading;
const Spinner = isLoading && getSpinner(spinnerType);

return (
<div style={isLoading ? hiddenContainer : {}}>
{this.props.children}
<div style={isLoading ? coveringSpinner : {}}>
{isLoading && (
<Spinner
className={className}
style={style}
status={loading_state}
color={color}
debug={debug}
fullscreen={fullscreen}
/>
)}
</div>
</div>
);
}
}

Expand Down Expand Up @@ -85,27 +96,29 @@ Loading.propTypes = {
]),

/**
* Property that determines which spinner to show - one of 'graph', 'cube', 'circle', 'dot', or 'default'.
* Property that determines which spinner to show
* one of 'graph', 'cube', 'circle', 'dot', or 'default'.
*/
type: PropTypes.oneOf(['graph', 'cube', 'circle', 'dot', 'default']),

/**
* Boolean that determines if the loading spinner will be displayed full-screen or not
* Boolean that makes the spinner display full-screen
*/
fullscreen: PropTypes.bool,

/**
* Boolean that determines if the loading spinner will display the status.prop_name and component_name
* If true, the spinner will display the component_name and prop_name
* while loading
*/
debug: PropTypes.bool,

/**
* Additional CSS class for the root DOM node
* Additional CSS class for the spinner root DOM node
*/
className: PropTypes.string,

/**
* Additional CSS styling for the root DOM node
* Additional CSS styling for the spinner root DOM node
*/
style: PropTypes.object,

Expand Down
2 changes: 1 addition & 1 deletion src/fragments/Loading/spinners/CircleSpinner.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ CircleSpinner.propTypes = {
color: PropTypes.string,
className: PropTypes.string,
fullscreen: PropTypes.bool,
style: PropTypes.bool,
style: PropTypes.object,
debug: PropTypes.bool,
};

Expand Down
2 changes: 1 addition & 1 deletion src/fragments/Loading/spinners/CubeSpinner.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ CubeSpinner.propTypes = {
color: PropTypes.string,
className: PropTypes.string,
fullscreen: PropTypes.bool,
style: PropTypes.bool,
style: PropTypes.object,
debug: PropTypes.bool,
};

Expand Down
2 changes: 1 addition & 1 deletion src/fragments/Loading/spinners/DefaultSpinner.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ DefaultSpinner.propTypes = {
color: PropTypes.string,
className: PropTypes.string,
fullscreen: PropTypes.bool,
style: PropTypes.bool,
style: PropTypes.object,
debug: PropTypes.bool,
};

Expand Down
2 changes: 1 addition & 1 deletion src/fragments/Loading/spinners/DotSpinner.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ DotSpinner.propTypes = {
color: PropTypes.string,
className: PropTypes.string,
fullscreen: PropTypes.bool,
style: PropTypes.bool,
style: PropTypes.object,
debug: PropTypes.bool,
};

Expand Down
2 changes: 1 addition & 1 deletion src/fragments/Loading/spinners/GraphSpinner.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ GraphSpinner.propTypes = {
color: PropTypes.string,
className: PropTypes.string,
fullscreen: PropTypes.bool,
style: PropTypes.bool,
style: PropTypes.object,
debug: PropTypes.bool,
};

Expand Down
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ def dash_dcc(request, dash_thread_server, tmpdir):
download_path=tmpdir.mkdir("download").strpath,
percy_assets_root=request.config.getoption("percy_assets"),
percy_finalize=request.config.getoption("nopercyfinalize"),
pause=request.config.getoption("pause"),
) as dc:
yield dc
4 changes: 2 additions & 2 deletions tests/integration/graph/test_graph_basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,15 @@ def selected_df_figure(selection):


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

@app.callback(Output('page-content', 'children'), [Input('url', 'value')])
@app.callback(Output('page-content', 'children'), [Input('url', 'pathname')])
def render_page(url):
return [
dcc.Dropdown(
Expand Down
Loading

0 comments on commit a42d7d2

Please sign in to comment.