I really like that in R shiny bs4dash cards have a button to minimize them so I made it for python dash. I thought I’d share to see if others had a better approach or just wanted to use it as-is.
There are 3 things that make this work (really two to make it function), the last is just external style.
- These two functions:
def myCard_collapse(title, children, headsize=None, classcard=None, classbody=None):
headsize=4 if headsize is None else headsize
sameid=str(uuid.uuid4())
if not isinstance(children, list):
children=[children]
newchildren=[
html.Button(className="btn btn-tool btn-sm",
children=html.I(className="fa fa-minus", id={'type':'collapseicon','id':sameid}),
style={'position':'absolute','top':'0','right':'0'},
id={'type':'collapsebutt','id':sameid}),
dbc.Collapse(children, is_open=True, id={"type":'collapsewin','id':sameid})
]
if title is None:
cardbody=newchildren
else:
cardbody=[dynH(title, headsize, className="card-title")] + newchildren
return dbc.Card(dbc.CardBody(cardbody, className=classbody), className=classcard)
def dynH(children, headsize, className=None):
if headsize==1:
return html.H1(children, className=className)
elif headsize==2:
return html.H2(children, className=className)
elif headsize==3:
return html.H3(children, className=className)
elif headsize==4:
return html.H4(children, className=className)
elif headsize==5:
return html.H5(children, className=className)
elif headsize==6:
return html.H6(children, className=className)
else:
raise ValueError("headsize must be 1-6")
of course, you don’t really need the second if you change the first function to not use it but up to the user.
- These two clientside callbacks (could probably be just one but I made it two)
app.clientside_callback("""
function(clicks, is_open) {
if (clicks>0) {
return !is_open;
} else {
throw window.dash_clientside.PreventUpdate;
}
}""",
Output({"type":'collapsewin','id':MATCH},'is_open'),
Input({'type':'collapsebutt','id':MATCH}, 'n_clicks'),
State({"type":'collapsewin','id':MATCH},'is_open'))
app.clientside_callback("""
function(is_open) {
if (is_open==true) {
return "fa fa-minus";
} else {
return "fa fa-plus";
}
}""",
Output({'type':'collapseicon','id':MATCH}, 'className'),
Input({"type":'collapsewin','id':MATCH},'is_open')
)
- adding font-awesome style sheet to external_stylesheets
external_stylesheets=[
dbc.themes.BOOTSTRAP, dbc.icons.BOOTSTRAP,
"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css",
]
If you want to use default buttons then you can skip this but I like the - + icons.
Obviously, I’m a terrible for not having docstrings or using camel case.