snehilvj / dash-mantine-components

Plotly Dash components based on Mantine React Components
https://www.dash-mantine-components.com
MIT License
531 stars 53 forks source link

Carousel's don't work in Tabs (except first tab) #299

Closed michaelrussell4 closed 1 week ago

michaelrussell4 commented 2 weeks ago

Carousel slide content doesn't update when pressing right/left if the dmc.Carousel is in a dmc.TabsTab and is not the first dmc.TabsTab of the dmc.TabsList. This is very odd because it works fine if it's the first tab but for any other than the first tab the carousel slide content won't update unless you press F12 and open your dev window—if you do this then the slide content suddenly updates to reflect the slide content corresponding with the indicator slide number.

Here's an example. You'll see that the carousel in the first tab (the "Gallery" tab) works, while the others don't. dash_mantine_components==0.14.4

import dash
from dash import _dash_renderer
import dash_mantine_components as dmc

_dash_renderer._set_react_version("18.2.0")
app = dash.Dash(__name__, external_stylesheets=[dmc.styles.CAROUSEL])

carousel = dmc.Carousel(
    loop=True,
    withIndicators=True,
    children=[
        dmc.CarouselSlide(
            dmc.Center(
                "Slide 1",
                bg="blue",
                c="white",
                p=30,
            )
        ),
        dmc.CarouselSlide(
            dmc.Center(
                "Slide 2",
                bg="green",
                c="white",
                p=30,
            )
        ),
        dmc.CarouselSlide(
            dmc.Center(
                "Slide 3",
                bg="orange",
                c="white",
                p=30,
            )
        ),
    ],
    id="carousel-simple",
)

tabs = dmc.Tabs(
    [
        dmc.TabsList(
            [
                dmc.TabsTab("Gallery", value="gallery"),
                dmc.TabsTab("Messages", value="messages"),
                dmc.TabsTab("Settings", value="settings"),
            ]
        ),
        dmc.TabsPanel(carousel, value="gallery"),
        dmc.TabsPanel(carousel, value="messages"),
        dmc.TabsPanel(carousel, value="settings"),
    ],
    value="gallery",
)

app.layout = dmc.MantineProvider(tabs)

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

https://github.com/user-attachments/assets/d612ac8a-0e0f-4acd-85a3-945088571971

AnnMarieW commented 2 weeks ago

Hi @michaelrussell4

Thanks for reporting. It looks like this is a bug in the upstream Mantine library https://github.com/orgs/mantinedev/discussions/4887

The workaround for now is to update the carousel in a tab using a callback:


import dash
from dash import _dash_renderer, callback, Input, Output, html
import dash_mantine_components as dmc

_dash_renderer._set_react_version("18.2.0")
app = dash.Dash(__name__, external_stylesheets=[dmc.styles.CAROUSEL])

carousel = dmc.Carousel(
    loop=True,
    withIndicators=True,
    children=[
        dmc.CarouselSlide(
            dmc.Center(
                "Slide 1",
                bg="blue",
                c="white",
                p=30,
            )
        ),
        dmc.CarouselSlide(
            dmc.Center(
                "Slide 2",
                bg="green",
                c="white",
                p=30,
            )
        ),
        dmc.CarouselSlide(
            dmc.Center(
                "Slide 3",
                bg="orange",
                c="white",
                p=30,
            )
        ),
    ],
    id="carousel-simple",
)

tabs_callback = html.Div(
    [
        dmc.Tabs(
            [
                dmc.TabsList(
                    [
                        dmc.TabsTab("Tab one", value="1"),
                        dmc.TabsTab("Tab two", value="2"),
                    ]
                ),
            ],
            id="tabs-example",
            value="1",
        ),
        html.Div(id="tabs-content", style={"paddingTop": 10}),
    ]
)

app.layout = dmc.MantineProvider(tabs_callback)

@callback(Output("tabs-content", "children"), Input("tabs-example", "value"))
def render_content(active):
    if active == "1":
        return [dmc.Text("Tab One selected", my=10), carousel]
    else:
        return [dmc.Text("Tab Two selected", my=10), carousel]

if __name__ == "__main__":
    app.run_server(debug=True)
jmanali1996 commented 1 week ago

Thank you so much for sharing the solution. I replaced the dmc.TabsPanel with the callback and the carousel is working smoothly!

AnnMarieW commented 1 week ago

The docs have now been updated to note this limitation. I'll close this for now since it's an issue in the upstream Mantine library.