Hey @davidharris
I think this is similar to the issue described here:
Try triggering a dummy resize via callback as shown here.
If I’m not mistaken, this could be a workaround for the issue. Note that you’ll need dash 2.17 for the example below due to the missing Output()
for the clientside callback.
from dash import Dash, html, Input, Output, ClientsideFunction
from dash.exceptions import PreventUpdate
import dash_mantine_components as dmc
from dash_iconify import DashIconify
import dash_leaflet as dl
app = Dash(__name__)
def cre_main_accordion():
items_list = [
{
"id": "map-item",
"image": DashIconify(icon="noto-v1:world-map", width=50),
"label": "Map",
"description": "Goes wrong if viewport is resized while accordion item is closed",
"content": dmc.Text("Processing...", size="sm"),
},
{
"id": "selection-item",
"image": DashIconify(icon="noto:globe-showing-asia-australia", width=50),
"label": "Select countries",
"description": "",
"content": dmc.Text("To be completed...", size="sm")
},
]
result = dmc.Accordion(
children=[
dmc.AccordionItem(
[
create_accordion_label(
item["label"], item["image"], item["description"]
),
dmc.AccordionPanel(item["content"], id=f"{item['id']}-content"),
],
value=item["id"],
)
for item in items_list
],
id="accord",
)
return result
def create_accordion_label(label, image, description):
return dmc.AccordionControl(
dmc.Group(
[
dmc.Avatar(src=image, radius="xl", size="lg") if type(image) == str else image,
html.Div(
[
dmc.Text(label),
dmc.Text(description, size="sm", fw=400, c="dimmed"),
]
),
]
)
)
def create_map():
return dl.Map(
children=dl.TileLayer(),
center=[56, 10], zoom=6,
style={'width': '100%', 'height': '50vh'}
)
app.layout = dmc.MantineProvider(children=[cre_main_accordion()])
@app.callback(
Output("map-item-content", "children"),
Input("accord", "value")
)
def refresh_map(val):
if val == "map-item":
return create_map()
else:
raise PreventUpdate
app.clientside_callback(
ClientsideFunction(namespace="clientside", function_name="resize"),
Input("map-item-content", "children")
)
if __name__ == "__main__":
app.run(debug=True)
custom.js
in assets
folder:
if (!window.dash_clientside) {
window.dash_clientside = {};
}
window.dash_clientside.clientside = {
resize: function(value) {
console.log("resizing..."); // for testing
setTimeout(function() {
window.dispatchEvent(new Event("resize"));
console.log("fired resize");
}, 500);
return null;
},
};