Skip to content

Commit eb96c5d

Browse files
authored
Merge branch 'dev' into support-async-callbacks
2 parents 51c1689 + 76a8e16 commit eb96c5d

File tree

34 files changed

+835
-370
lines changed

34 files changed

+835
-370
lines changed

@plotly/dash-generator-test-component-typescript/dash_prop_typing.py

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React, { useState, useEffect } from "react";
2+
import PropTypes from "prop-types";
3+
4+
const RenderType = (props) => {
5+
const onClick = () => {
6+
props.setProps({n_clicks: (props.n_clicks || 0) + 1})
7+
}
8+
9+
return <div id={props.id}>
10+
<span>{props.dashRenderType}</span>
11+
<button onClick={onClick}>Test Internal</button>
12+
</div>;
13+
};
14+
15+
RenderType.propTypes = {
16+
id: PropTypes.string,
17+
dashRenderType: PropTypes.string,
18+
n_clicks: PropTypes.number,
19+
setProps: PropTypes.func
20+
};
21+
22+
RenderType.dashRenderType = true;
23+
export default RenderType;

@plotly/dash-test-components/src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import MyPersistedComponentNested from './components/MyPersistedComponentNested'
77
import StyledComponent from './components/StyledComponent';
88
import WidthComponent from './components/WidthComponent';
99
import ComponentAsProp from './components/ComponentAsProp';
10+
import RenderType from './components/RenderType';
1011

1112
import DrawCounter from './components/DrawCounter';
1213
import AddPropsComponent from "./components/AddPropsComponent";
@@ -32,4 +33,5 @@ export {
3233
ShapeOrExactKeepOrderComponent,
3334
ArrayOfExactOrShapeWithNodePropAssignNone,
3435
ExternalComponent,
36+
RenderType
3537
};

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,27 @@ This project adheres to [Semantic Versioning](https://semver.org/).
44

55
## [unreleased]
66

7+
## Fixed
8+
- [#3264](https://github.com/plotly/dash/pull/3264) Fixed an issue where moving components inside of children would not update the `setProps` path, leading to hashes being incorrect
9+
- [#3265](https://github.com/plotly/dash/pull/3265) Fixed issue where the resize of graphs was cancelling others
10+
11+
12+
## [3.0.2] - 2025-04-01
13+
714
## Changed
815
- [#3113](https://github.com/plotly/dash/pull/3113) Adjusted background polling requests to strip the data from the request, this allows for context to flow as normal. This addresses issue [#3111](https://github.com/plotly/dash/pull/3111)
16+
- [#3248](https://github.com/plotly/dash/pull/3248) Changes to rendering logic:
17+
- if it is first time rendering, render from the parent props
18+
- listens only to updates for that single component, no children listening to parents
19+
- if parents change a prop with components as props, only the prop changed re-renders, this is then forced on all children regardless of whether or not the props changed
920

21+
## Fixed
22+
- [#3251](https://github.com/plotly/dash/pull/3251). Prevented default styles from overriding `className_*` props in `dcc.Upload` component.
23+
24+
## Added
25+
- [#3248](https://github.com/plotly/dash/pull/3248) added new `dashRenderType` to determine why the component layout was changed (`internal`, `callback`, `parent`, `clientsideApi`):
26+
- this can be utilized to keep from rendering components by the component having `dashRenderType` defined as a prop, and the `dashRenderType = true` must be set on the component, eg (`Div.dashRenderType = true`)
27+
- [#3241](https://github.com/plotly/dash/pull/3241) Added a collapse / expand button to Dash Dev Tools.
1028

1129
## [3.0.1] - 2025-03-24
1230

components/dash-core-components/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/dash-core-components/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dash-core-components",
3-
"version": "3.0.3",
3+
"version": "3.0.4",
44
"description": "Core component suite for Dash",
55
"repository": {
66
"type": "git",

components/dash-core-components/src/fragments/Upload.react.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ export default class Upload extends Component {
6464
style_reject,
6565
style_disabled,
6666
} = this.props;
67+
68+
const activeStyle = className_active ? undefined : style_active;
69+
const disabledStyle = className_disabled ? undefined : style_disabled;
70+
const rejectStyle = className_reject ? undefined : style_reject;
71+
6772
return (
6873
<LoadingElement id={id}>
6974
<Dropzone
@@ -79,9 +84,9 @@ export default class Upload extends Component {
7984
rejectClassName={className_reject}
8085
disabledClassName={className_disabled}
8186
style={style}
82-
activeStyle={style_active}
83-
rejectStyle={style_reject}
84-
disabledStyle={style_disabled}
87+
activeStyle={activeStyle}
88+
rejectStyle={rejectStyle}
89+
disabledStyle={disabledStyle}
8590
>
8691
{children}
8792
</Dropzone>

components/dash-core-components/src/utils/ResizeDetector.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@ import PropTypes from 'prop-types';
44
// Debounce 50 ms
55
const DELAY = 50;
66

7-
let resizeTimeout;
8-
97
const ResizeDetector = props => {
108
const {onResize, children, targets} = props;
119
const ref = createRef();
10+
let resizeTimeout;
1211

1312
const debouncedResizeHandler = useCallback(() => {
1413
if (resizeTimeout) {

components/dash-core-components/tests/integration/graph/test_graph_responsive.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import pytest
22

33
from dash import Dash, Input, Output, State, dcc, html
4+
import plotly.graph_objects as go
45

56
from dash.exceptions import PreventUpdate
67
from dash.testing import wait
@@ -134,3 +135,77 @@ def resize(n_clicks, style):
134135
)
135136

136137
assert dash_dcc.get_logs() == []
138+
139+
140+
def test_grrs002_graph(dash_dcc):
141+
app = Dash(__name__)
142+
143+
app.layout = html.Div(
144+
[
145+
html.Button("Generate Figures", id="generate-btn", n_clicks=0),
146+
html.Button("Get Bounding Box", id="bounding-btn"),
147+
html.Div(
148+
id="graph-container",
149+
children=[
150+
html.Div(id="bounding-output"),
151+
dcc.Graph(
152+
id="prec-climate-daily",
153+
style={"height": "45vh"},
154+
config={"responsive": True},
155+
),
156+
dcc.Graph(
157+
id="temp-climate-daily",
158+
style={"height": "45vh"},
159+
config={"responsive": True},
160+
),
161+
],
162+
style={"display": "none"},
163+
),
164+
]
165+
)
166+
167+
app.clientside_callback(
168+
"""() => {
169+
pcd_container = document.querySelector("#prec-climate-daily")
170+
pcd_container_bbox = pcd_container.getBoundingClientRect()
171+
pcd_graph = pcd_container.querySelector('.main-svg')
172+
pcd_graph_bbox = pcd_graph.getBoundingClientRect()
173+
tcd_container = document.querySelector("#temp-climate-daily")
174+
tcd_container_bbox = tcd_container.getBoundingClientRect()
175+
tcd_graph = tcd_container.querySelector('.main-svg')
176+
tcd_graph_bbox = tcd_graph.getBoundingClientRect()
177+
return JSON.stringify(
178+
pcd_container_bbox.height == pcd_graph_bbox.height &&
179+
pcd_container_bbox.width == pcd_graph_bbox.width &&
180+
tcd_container_bbox.height == tcd_graph_bbox.height &&
181+
tcd_container_bbox.width == tcd_graph_bbox.width
182+
)
183+
}""",
184+
Output("bounding-output", "children"),
185+
Input("bounding-btn", "n_clicks"),
186+
prevent_initial_call=True,
187+
)
188+
189+
@app.callback(
190+
[
191+
Output("prec-climate-daily", "figure"),
192+
Output("temp-climate-daily", "figure"),
193+
Output("graph-container", "style"),
194+
Output("bounding-output", "children", allow_duplicate=True),
195+
],
196+
[Input("generate-btn", "n_clicks")],
197+
prevent_initial_call=True,
198+
)
199+
def update_figures(n_clicks):
200+
fig_acc = go.Figure(data=[go.Scatter(x=[0, 1, 2], y=[0, 1, 0], mode="lines")])
201+
fig_daily = go.Figure(data=[go.Scatter(x=[0, 1, 2], y=[1, 0, 1], mode="lines")])
202+
return fig_acc, fig_daily, {"display": "block"}, "loaded"
203+
204+
dash_dcc.start_server(app)
205+
dash_dcc.wait_for_text_to_equal("#generate-btn", "Generate Figures")
206+
dash_dcc.find_element("#generate-btn").click()
207+
dash_dcc.wait_for_text_to_equal("#bounding-output", "loaded")
208+
dash_dcc.find_element(".dash-graph .js-plotly-plot.dash-graph--pending")
209+
dash_dcc.find_element(".dash-graph .js-plotly-plot:not(.dash-graph--pending)")
210+
dash_dcc.find_element("#bounding-btn").click()
211+
dash_dcc.wait_for_text_to_equal("#bounding-output", "true")

components/dash-core-components/tests/integration/upload/test_children_accept_any_component.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,32 @@ def test_upca001_upload_children_gallery(dash_dcc):
2828
"textAlign": "center",
2929
},
3030
),
31+
dcc.Upload(
32+
"upload",
33+
disabled=True,
34+
className_disabled="upload-disabled",
35+
id="upload",
36+
),
37+
dcc.Upload("upload", disabled=True, id="upload-no-className"),
3138
]
3239
)
3340
dash_dcc.start_server(app)
3441
time.sleep(0.5)
3542
dash_dcc.percy_snapshot("upca001 children gallery")
3643

44+
first_child = dash_dcc.find_element("#upload").find_element_by_css_selector(
45+
":first-child"
46+
)
47+
# Check that there is no default style since className is specified
48+
style = first_child.get_attribute("style")
49+
assert "opacity: 0.5" not in style
50+
51+
first_child = dash_dcc.find_element(
52+
"#upload-no-className"
53+
).find_element_by_css_selector(":first-child")
54+
55+
# Check that there is default style since no className is specified
56+
style = first_child.get_attribute("style")
57+
assert "opacity: 0.5" in style
58+
3759
assert dash_dcc.get_logs() == []

0 commit comments

Comments
 (0)