Every component in dash_core_components
or dash_html_components
comes equipped with
a loading_state
property. This property contains an is_loading
boolean that tells you
if the component is loading. Additionally, the component_name
and prop_name
attributes
return the name of that component and the name of the property that is loading (i.e. “layout”). Component authors can use this property to determine what to
do if the component is still loading. Dash uses this prop in the Loading
component to display spinners if a component is loading. This means you can use
the Loading
component to wrap other components that you want to display a loading spinner for. Here’s an example of what that looks like:
from dash import Dash, dcc, html, Input, Output, callback
import time
app = Dash()
app.layout = html.Div(
children=[
html.H3("Edit text input to see loading state"),
dcc.Input(id="ls-input-1", value='Input triggers local spinner'),
dcc.Loading(id="ls-loading-1", children=[html.Div(id="ls-loading-output-1")], type="default"),
html.Div(
[
dcc.Input(id="ls-input-2", value='Input triggers nested spinner'),
dcc.Loading(
id="ls-loading-2",
children=[html.Div([html.Div(id="ls-loading-output-2")])],
type="circle",
)
]
),
],
)
@callback(Output("ls-loading-output-1", "children"), Input("ls-input-1", "value"))
def input_triggers_spinner(value):
time.sleep(1)
return value
@callback(Output("ls-loading-output-2", "children"), Input("ls-input-2", "value"))
def input_triggers_nested(value):
time.sleep(1)
return value
if __name__ == "__main__":
app.run(debug=False)
Please also check out the docs for the Loading component for more information on how to use the Loading component.
Aside from using the Loading component, you can check if a certain component
(either from dash_core_components
or dash_html_components
) is loading by checking the
data-dash-is-loading
attribute set on that component’s HTML output. This means that
you can target those components yourself with CSS, and create your own custom loading
for them. Here’s an example of what that could look like:
from dash import Dash, dcc, html, Input, Output, callback
import time
app = Dash()
app.layout = html.Div(
children=[
html.Div(id="cls-output-1", className='output-example-loading'),
dcc.Input(id="cls-input-1", value="Input triggers local spinner"),
html.Div(
[
html.Div(id="cls-output-2", className='output-example-loading'),
dcc.Input(id="cls-input-2", value="Input triggers nested spinner"),
]
),
]
)
@callback(Output("cls-output-1", "children"), Input("cls-input-1", "value"))
def input_triggers_spinner(value):
time.sleep(1)
return value
@callback(Output("cls-output-2", "children"), Input("cls-input-2", "value"))
def input_triggers_nested(value):
time.sleep(1)
return value
if __name__ == "__main__":
app.run(debug=False)
You could target all components in the layout above that are loading using the following CSS:
*[data-dash-is-loading="true"]{
visibility: hidden;
}
*[data-dash-is-loading="true"]::before{
content: "Loading...";
display: inline-block;
color: magenta;
visibility: visible;
}
You can also target any other HTML attributes using CSS.
To target a specific class use the following CSS:
*[class="output-example-loading"][data-dash-is-loading="true"]{
visibility: hidden;
}
*[class="output-example-loading"][data-dash-is-loading="true"]::before{
content: "Loading...";
display: inline-block;
color: magenta;
visibility: visible;
}