Dynamic creating tabs

Hey:

In using the tabs in dash mantine components or dash, is there a way to create the tabs dynamically from callbacks?
The content in each tab will be use pattern-matching components. Wonder if there is any issue with that. Thanks.

Hey @entropy_l, sure you can do so.

I did this here using dash-bootstrap-components.

Hey @entropy_l , here an example using dah-mantine-components.

import dash_mantine_components as dmc
from dash import Dash, html, Input, Output, Patch
import uuid


app = Dash(__name__)

app.layout = html.Div(
    children=[
        dmc.Button(
            children='create tab',
            id='btn'
        ),
        dmc.Button(
            children='change name', 
            id='btn_1'
        ),
        dmc.Tabs(
            id='tabs',
            children=[
                dmc.TabsList(
                    id='tab_list',
                    children=[
                        dmc.Tab(
                            id='your_id',
                            children="Gallery",
                            value="gallery"
                        ),
                        dmc.Tab("Messages", value="messages"),
                        dmc.Tab("Settings", value="settings"),
                    ]
                ),
                dmc.TabsPanel("Gallery tab content", value="gallery"),
                dmc.TabsPanel("Messages tab content", value="messages"),
                dmc.TabsPanel("Settings tab content", value="settings"),
            ],
            color="red",
            orientation="vertical",
        )
    ]
)


@app.callback(
    Output('tabs', 'children'),
    Output('tab_list', 'children'),
    Input('btn', 'n_clicks'),
    prevent_initial_call=True
)
def copy(n_clicks):
    just_an_id = uuid.uuid4().hex

    # add the new tab
    patched_tab_list = Patch()
    patched_tab_list.append(
        dmc.Tab(
            id={'type': 'tab', 'index': n_clicks},
            children=f'tab {n_clicks}',
            value=just_an_id
        )
    )

    # add new tab content
    patched_tabs = Patch()
    patched_tabs.append(
        dmc.TabsPanel(
            id={'type': 'tab_panel', 'index': n_clicks},
            children=f'some dynamic content, button click: {n_clicks}',
            value=just_an_id
        )
    )

    return patched_tabs, patched_tab_list


@app.callback(
    Output('your_id', 'children'),
    Input('btn_1', 'n_clicks'),
    prevent_initial_call=True
)
def change(n_clicks):
    return f'name changed {n_clicks}'


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

I included the answer to your other question in this example too.

Hey guys,

have you tried this with the new tabs system on 0.15?

Thanks in advance.

1 Like

Hey @SpanishHans, I did not try it with 0.15.

I guess you encountered problems trying it :wink: ? Could you give some details?

Hey there, thanks for your help. Will post my solution for anyone looking to 0.15

layout = dmc.Container(
    dmc.Stack(
        children=[
            dmc.Stack([
                dmc.Title('Title'),
            ],gap='0px'),
            
            dmc.Tabs(
                children=[
                    dmc.Group([
                        dmc.TabsList(
                            [
                                dmc.TabsTab(
                                    "Tab 1",
                                    value="Tab 1",
                                ),
                            ],
                            id='tab_list'
                        ),
                        dmc.ActionIcon(
                            get_icon(icon="fa6-solid:plus"),
                            size='34px',
                            id='add_tab'
                        ),
                    ],
                    pb='0.5rem'),
                    dmc.TabsPanel([
                        dmc.Card([
                            'Content tab 1',
                        ],
                        withBorder=True,),
                    ], value="Tab 1"),
                ],
                id='tabs',
                radius='sm',
                variant='pills',
                value="Tab 1",
            )
        ],
        justify='space-between',
        h="100%"
    ),
    size='xl',
    py='1rem',
    h='100%',
)


@callback(
    Output('tabs', 'children'),
    Output('tab_list', 'children'),
    Input('add_tab', 'n_clicks'),
    prevent_initial_call=True
)
def copy(n_clicks):
    just_an_id = uuid.uuid4().hex
    
    # Content
    patched_tabs = Patch()
    patched_tabs.append(
        dmc.TabsPanel(
            id={'type': 'tab_panel', 'index': n_clicks},
            children = dmc.Card([
                f'Content tab {n_clicks+1}',
            ],
            withBorder=True,
            ),
            value=just_an_id
        )
    )

    # List
    patched_tab_list = Patch()
    patched_tab_list.append(
        dmc.TabsTab(
            id={'type': 'tab', 'index': n_clicks},
            children=f'Tab {n_clicks+1}',
            value=just_an_id
        )
    )

    return patched_tabs, patched_tab_list

however, do you happen to know of any way to like right click and rename a tab or double click?

For the right click you would need to use a JS Event handler.

Maybe the forum search is helpful

https://community.plotly.com/search?context=topic&context_id=83410&q=right%20click%20&skip_context=true