plotly / dash

Data Apps & Dashboards for Python. No JavaScript Required.
https://plotly.com/dash
MIT License
20.84k stars 2.01k forks source link

[BUG] `id` passed through `dcc.Loading` not visible in DOM #2878

Closed huong-li-nguyen closed 1 week ago

huong-li-nguyen commented 3 weeks ago

Describe your context Hello guys 👋

I am currently trying to pass an id to the dcc.Loading component or its parent container and I would like the id to be visible in the DOM such that I can target the CSS of the components inside the dcc.Loading via ID.

Please provide us your environment, so we can easily reproduce the issue.

Describe the bug Let's take the example app below - what I would have expected is that there would be an html div visible with a className="loading" and an id="loading-id". However, if I provide the className="loading" I see a div but it does not have the className="loading" in the DOM nor does it have the id="loading-id" in the DOM.

When I switch this to parent_className="loading", now I see a div with the className="loading", but I cannot attach an id to this parent container.

I am not a react expert, but from the source I can see that the id doesn't seem to be passed on in the return of the react component and is therefore not visible in the DOM? Is there any reason for that?

https://github.com/plotly/dash/blob/09252f8d2f690480cc468b2e015f9e2417dc90ad/components/dash-core-components/src/components/Loading.react.js#L128-L133

from dash import Dash, html, dcc, callback, Output, Input
import plotly.express as px
import pandas as pd

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder_unfiltered.csv')

app = Dash()

app.layout = [
    html.H1(children='Title of Dash App', style={'textAlign':'center'}),
    dcc.Dropdown(df.country.unique(), 'Canada', id='dropdown-selection'),
    dcc.Loading(dcc.Graph(id='graph-content'), color='grey', id="loading-id", parent_className="loading")
]

@callback(
    Output('graph-content', 'figure'),
    Input('dropdown-selection', 'value')
)
def update_graph(value):
    dff = df[df.country==value]
    return px.line(dff, x='year', y='pop')

if __name__ == "__main__":
    app.run(debug=True)

Expected behavior

I would expect the id being passed on to the react component and visible in the DOM, so having a <div class="loading" id="loading-id"

visible in the DOM.

Screenshots Screenshot 2024-06-07 at 12 29 36

T4rk1n commented 3 weeks ago

I don't think there's a particular reason for it to be missing, it should be added.

huong-li-nguyen commented 3 weeks ago

I can try to fix it :) Seems like it's just a one-line change?

T4rk1n commented 3 weeks ago

Seems like it's just a one-line change?

Yes, maybe two lines, adding the id prop in the function arguments then on the div.

T4rk1n commented 1 week ago

Fixed by #2888