Disable Accordion component

I have a dmc.Accordion component in my UI, grouped together with a checkbox. I want to enable/disable the accordion if the checkbox is checked or not. The problem is, dmc.accordion doesn’t have a disable property unlike other dcc components which have the option to enable / disable them (i.e dcc checklist).

One workaround is to set css property ‘pointer-events’ to ‘none’ (as show below) , but is there a better way to do this ?

For dmc-accordion , the following callback updates the styles property of component, by setting pointer-events to none for control element of dmc.accordion.

Minimal Working Example:

from dash import Dash, dcc, html, Input, Output, State, callback
from dash.exceptions import PreventUpdate

import dash_mantine_components as dmc

app = Dash(__name__)

app.layout = html.Div(
   children=[
    dmc.Group(spacing='xs',position='left',grow=False,style={'gap':'1px'},
    children=[
        dmc.Checkbox(id='checkbox',size='xs',style={'marginLeft':'5px',},checked=False),      
        dmc.Accordion(id='dmc-accordion',
                    children=[
                        dmc.AccordionItem(
                            [
                                dmc.AccordionControl("Customization",style={'color':'white'}),
                                dmc.AccordionPanel(
                                            dcc.Checklist(inputStyle={'marginRight':'7px'},
                                                options=[
                                                    {'label': 'New York City', 'value': 'New York City'},
                                                    {'label': 'Montreal', 'value': 'Montreal'},
                                                    {'label': 'San Francisco', 'value': 'San Francisco',"disabled":True},
                                                ],
                                                value=['Montreal']
                                            ),
                                ),
                            ],
                            value="customization",
                        ),],
                chevronPosition='right',variant='filled',
                styles={ 'control':{'opacity':'1'},
                    'item':{'backgroundColor':'transparent',
                                "&[data-active]":{'backgroundColor':'transparent'}}}    
                )
                ],
            )
   ],style={'backgroundColor': 'green'}
)


@app.callback(
    Output('dmc-accordion','styles'),
    Input('checkbox', 'checked'),
    State('dmc-accordion', 'styles'),
    prevent_initial_call=True
)
def menu_enable(checked,styles):

    print(f'checkbox: {checked} , styles {styles}')
    if(checked):
        styles['control'] = {'pointer-events':'none','opacity':'0.5'}
    else:
        styles['control']['pointer-events'] = 'auto'
        styles['control']['opacity'] = '1'
        
    
    return styles

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

Running the app:

disable_accordion

As you can see , this doesn’t disable the accordion entirely as I can still select/deselect options from inside.

Is there a better way to do this? Im not familiar with javascript but can we manipulate DOM of dmc accordion to enable/disable it ? Any help would be appreciated , thanks!

hi @ptser
What if you target the disabled key for each checkbox?

Add id='my-checklist', inside the dcc.Checklist. Then,

@app.callback(
    Output('dmc-accordion', 'styles'),
    Output('my-checklist','options'),
    Input('checkbox', 'checked'),
    State('dmc-accordion', 'styles'),
    State('my-checklist', 'options'),
    prevent_initial_call=True
)
def menu_enable(checked, styles, options):
    print(f'checkbox: {checked} , styles {styles}')
    if (checked):
        styles['control'] = {'pointer-events': 'none', 'opacity': '0.5'}
        for x in options:
            x['disabled'] = True
    else:
        styles['control']['pointer-events'] = 'auto'
        styles['control']['opacity'] = '1'
        for x in options:
            x['disabled'] = False

    return styles, options

This solutions does work but since i have multiple of these menu in UI and each menu has a different set of checklists, I need some simple solution, that is, is there a way to disable entire accordion component (including whatever is inside its panel) without iterating over the checklist items as well, in order to disable them?

So, turns out panel of accordion can also be disabled the same way control component of dmc.accordion can be disabled. This is still a ‘hacky’ way of doing this, but anways, code is as follows in case someone needs it.:

@app.callback(
    Output('dmc-accordion', 'styles'),
    Input('checkbox', 'checked'),
    State('dmc-accordion', 'styles'),
    prevent_initial_call=True
)
def menu_enable(checked, styles):
    print(f'checkbox: {checked} , styles {styles}')
    if (checked):
        styles['control'] = {'pointer-events': 'none', 'opacity': '0.5'}
        styles['panel'] = {'pointer-events': 'none', 'opacity': '0.5'}
    else:
        styles['control']['pointer-events'] = 'auto'
        styles['control']['opacity'] = '1'
        styles['panel']['pointer-events'] = 'auto'
        styles['panel']['opacity'] = '1'
       

    return styles
1 Like