Create a list in the offcanvas which can connect to the other page

Hi,

How to create something like this in the offcanvas? How to add-in the html.Ul to work together with the dash.register_page?



Sample:

image





Code:

app.py

sidebar = dbc.Nav(
        [
            dbc.NavLink(
                [
                    html.Div([
                               html.I(className=page["icon"]),
                               page["name"]
                           ], className="ms-2"),
                ],
                href=page["path"],
                active="exact",
            )
            for page in dash.page_registry.values()
        ],
        vertical=True,
        pills=True,
        className="bg-light",

)



app.layout = dbc.Container([
        html.Div([
               dbc.Button(html.I(className ="bi bi-list"), #"Menu",
               id="open-offcanvas", n_clicks=0),
              
             dbc.Offcanvas([
                 dcc.Location(id="url"),
                sidebar,
                content
                ],
         
            id="offcanvas",
            title="Welcome to .../",
            is_open=False,
             ),
       ]),


dbc.Row([
    dbc.Col(html.Div("Tes",
                     style={'fontSize':50, 'textAlign':'center'}))
]),

html.Hr(),

dbc.Row([
         dbc.Col([
                dash.page_container
            ], xs=8, sm=8, md=10, lg=10, xl=10, xxl=10)
    ]
)
], fluid=True)




page1.py

dash.register_page(__name__,
               path='/',  # '/' is home page and it represents the url
               name='Home',  # name of page, commonly used as name of link
               title='Main',  # title that appears on browser's tab
               icon="bi bi-house",
)

# page 1 data
layout = dbc.Container([
    dbc.Row([
        dbc.Col([
            html.H1('Welcome to ...', className = 'text-center text-primary, mb-4 '
                    ,style={'font-weight': 'bold'}),
        ]),
    ]),

Hello @beginof,

For this, you can use the accordion of Mantine.

Hi @jinnyzor,

Can you share some sample code that how you work the dmc.Accordion with the dash.register_page?

Sure thing!

Here is the code:

import dash
from dash import Dash, dcc, html, State, Input, Output
import dash_bootstrap_components as dbc
import dash_mantine_components as dmc

app = Dash(__name__, use_pages=True, pages_folder='',
           external_stylesheets=[dbc.icons.BOOTSTRAP, dbc.themes.BOOTSTRAP])

dash.register_page('Home', path='/', layout='You are home', icon="bi bi-house")
dash.register_page('Page 1', path='/page-1', layout='You are at page-1', icon="bi bi-house")
dash.register_page('Page 2', path='/page-2', layout='You are page-2', icon="bi bi-house")

sidebar = dbc.Nav(
    [dmc.Accordion(
        dmc.AccordionItem(
            [
            dbc.NavLink(
                [
                    html.Div([
                        html.I(className=page["icon"]),
                        page["name"]
                    ], className="ms-2"),
                ],
                href=page["path"],
                active="exact",
            )
            for page in dash.page_registry.values()
    
            ], label='Pages')
        )
    ],
    vertical=True,
    pills=True,
    className="bg-light",


)

app.layout = dbc.Container([
    dcc.Location(id="url"),
    dbc.Offcanvas([
        sidebar,
    ],
        id="offcanvas",
        title="Welcome to .../",
        is_open=False,
    ),
    html.Div([
        dbc.Button(html.I(className="bi bi-list"),  # "Menu",
                   id="open-offcanvas", n_clicks=0),
    ]),

    dbc.Row([
        dbc.Col(html.Div("Tes",
                         style={'fontSize': 50, 'textAlign': 'center'}))
    ]),

    html.Hr(),

    dbc.Row([
        dbc.Col([
            dash.page_container
        ], xs=8, sm=8, md=10, lg=10, xl=10, xxl=10)
    ]
    )
], fluid=True)

@app.callback(
    Output('offcanvas', 'is_open'),
    Input('open-offcanvas','n_clicks'),
    State('offcanvas', 'is_open'),
)
def openNav(n1, o):
    if n1:
        return not o

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

Here is the result:

1 Like

Here is an alteration to demonstrate some of the things you can do.

Code alteration:

import dash
from dash import Dash, dcc, html, State, Input, Output
import dash_bootstrap_components as dbc
import dash_mantine_components as dmc

app = Dash(__name__, use_pages=True, pages_folder='',
           external_stylesheets=[dbc.icons.BOOTSTRAP, dbc.themes.BOOTSTRAP])

dash.register_page('Home', path='/', layout='You are home', icon="bi bi-house")
dash.register_page('Page 1', path='/page-1', layout='You are at page-1', icon="bi bi-house")
dash.register_page('Page 2', path='/page-2', layout='You are page-2', icon="bi bi-house")

home = ['Home']

sidebar = dbc.Nav(
    [
        dbc.NavLink(
            [
                html.Div([
                    html.I(className='bi bi-house'),
                    'Home'
                ], className="ms-2"),
            ],
            href='/',
            active="exact",
        ),

        dmc.Accordion(
        dmc.AccordionItem(
            [
            dbc.NavLink(
                [
                    html.Div([
                        html.I(className=page["icon"]),
                        page["name"]
                    ], className="ms-2"),
                ],
                href=page["path"],
                active="exact",
            )
            for page in dash.page_registry.values() if page['name'] not in home

            ], label='Pages')
        )
    ],
    vertical=True,
    pills=True,
    className="bg-light",


)

app.layout = dbc.Container([
    dcc.Location(id="url"),
    dbc.Offcanvas([
        sidebar,
    ],
        id="offcanvas",
        title="Welcome to .../",
        is_open=False,
    ),
    html.Div([
        dbc.Button(html.I(className="bi bi-list"),  # "Menu",
                   id="open-offcanvas", n_clicks=0),
    ]),

    dbc.Row([
        dbc.Col(html.Div("Tes",
                         style={'fontSize': 50, 'textAlign': 'center'}))
    ]),

    html.Hr(),

    dbc.Row([
        dbc.Col([
            dash.page_container
        ], xs=8, sm=8, md=10, lg=10, xl=10, xxl=10)
    ]
    )
], fluid=True)

@app.callback(
    Output('offcanvas', 'is_open'),
    Input('open-offcanvas','n_clicks'),
    State('offcanvas', 'is_open'),
)
def openNav(n1, o):
    if n1:
        return not o

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

Of course, this Mantine library that I am using is not the most up to date, there is the alpha release available.

Thanks @jinnyzor for your quick response and support.:grinning:

1 Like

Hi @jinnyzor,

Can I have the both icon together?

image

I had tried and only one icon can put in the same label.

dmc.Accordion(
    dmc.AccordionItem([
            dbc.NavLink([   
                    html.Div([
                        html.I(className=page["icon"]),
                              page["name"]
                              ], className="ms-2"),
                    ],
                    href=page["path"],
                    active="exact",
                    )
                for page in dash.page_registry.values() if page['name'] not in home
                   
                ], label='Transaction Inquiry',
                    icon=[
                         DashIconify(
                             icon="carbon:search-locate",
                             color=dmc.theme.DEFAULT_COLORS["blue"][6],
                             width=20,
                             )
                         ],
        
                ),
            
            multiple = True,
            # icon=[DashIconify(icon="tabler:arrow-big-down-line")],
            iconPosition = 'right',
            # disableIconRotation=True,
            )

You could with the custom css, pass a right argument with position absolute. But I don’t know if it will be easy, and could cause issues with different screen sizes, etc.

How about if I has more than one page that don’t want to included in the page? Can it work?

1 Like

Yup. Just add it to the list at the top.

Thanks @jinnyzor :grinning:

1 Like