Hi @spriteware,
I actually took a look at dash mantine documentation in the meantime and I also thought that tag inputs could do what I imagined.
But i couldn’t figure out how to use them.
I still ended using Mantine, I just shoved my dcc.dropdown in a mantine Popoverdropdown and it kind of worked out :

I had to stick to what i usually do & used a helper function.
I never had or tried to use my own objects & I don’t think i would try on my own; but if you can get me started with a piece of code, yes please by all means; it’d be a great learning opportunity for me if anything.
Many thanks for your help,
from dash import Dash, html, dcc, callback, Input, Output,State, _dash_renderer, MATCH, ALL
from dash.exceptions import PreventUpdate
import dash_mantine_components as dmc
_dash_renderer._set_react_version("18.2.0")
app = Dash(__name__)
app = Dash(external_stylesheets=dmc.styles.ALL)
server = app.server
def create_dropdown_v3(col_name :'str',options: list) -> html.Div :
# if col_name in df.select_dtypes(include = 'datetime').columns:
# reverse = True
# elif col_name not in df.select_dtypes(include = 'datetime').columns:
# reverse = False
b = html.Button('', id = {'type' : 'button_all_dropdown_filter', 'index' : col_name})
s = dcc.Store(id = {'type' : 'last_search_value_dropdown_filter', 'index' : col_name})
d = dcc.Dropdown(
# options=sorted(list(df[col_name].astype('str').unique()),reverse = reverse),
id = {'type' : 'dropdown_filter', 'index' : col_name},
placeholder = col_name,
multi = True,
options = options,
style = {'height' : '4 px','margin' : 'auto'}
)
res = dmc.Popover(
id = {'type' : 'popover_dropdown_filter', 'index' : col_name},
position="bottom",
width = 500,
withArrow=True,
shadow="md",
children=[
dmc.PopoverTarget(dmc.Button(f"{col_name}")),
dmc.PopoverDropdown(
children = [b,d],
)
],
)
return html.Div(id = {'type' : 'div_dropdown','index' : col_name},children = [res,s],style = {'margin' : '1 px'})
options_list = [
'foo-1',
'foo-2',
'fifoo',
'bar',
'bar2',
'bar3'
]
options_labels = [{'value' : val, 'label': val + val[::-1]} for val in options_list]
dropdown_selection = html.Div(id = 'dropdown_selection')
app.layout = dmc.MantineProvider(
[
html.Div(children=[
html.Div(children = [create_dropdown_v3('dropdown_list',options_list),
create_dropdown_v3('dropdown_labels',options_labels)
],
style = {'display': 'inline-block', 'margin-left': '15px'}),
html.Br(),
dropdown_selection])
]
)
@callback(
Output({'type': 'last_search_value_dropdown_filter', 'index': MATCH}, "data",allow_duplicate=True),
Output({'type': 'button_all_dropdown_filter', 'index': MATCH}, "children",allow_duplicate=True),
Input({'type': 'dropdown_filter', 'index': MATCH}, "search_value"),
prevent_initial_call = True
)
def update_last_search_value(search_value):
if not search_value:
raise PreventUpdate
return search_value, f'add all {search_value}'
@callback(
Output({'type': 'last_search_value_dropdown_filter', 'index': MATCH}, "data",allow_duplicate=True),
Output({'type': 'button_all_dropdown_filter', 'index': MATCH}, "children",allow_duplicate=True),
Input({'type': 'popover_dropdown_filter', 'index': MATCH}, "opened"),
prevent_initial_call = True
)
def reset_search_value(opened):
if not opened:
raise PreventUpdate
return '',''
@callback(
Output({'type': 'dropdown_filter', 'index': MATCH}, 'value', allow_duplicate=True),
Output({'type': 'last_search_value_dropdown_filter', 'index': MATCH}, 'data',allow_duplicate=True),
Output({'type': 'button_all_dropdown_filter', 'index': MATCH}, 'children',allow_duplicate=True),
Input({'type': 'button_all_dropdown_filter', 'index': MATCH}, 'n_clicks'),
State({'type': 'last_search_value_dropdown_filter', 'index': MATCH},'data'),
State({'type': 'dropdown_filter', 'index': MATCH}, 'options'),
State({'type': 'dropdown_filter', 'index': MATCH}, 'value'),
prevent_initial_call=True
)
def add_all_displayed_options_to_selection(n,search_value,options,current_values):
if not search_value:
raise PreventUpdate
if current_values in [None]:
current_values = []
cond1=isinstance(options[0],dict)
if cond1:
temp = [val.get('value') for val in options if str(search_value).lower() in str(val.get('label')).lower()]
else :
temp = [val for val in options if str(search_value).lower() in str(val).lower()]
return current_values+temp, str(), str()
@callback(
Output('dropdown_selection','children'),
Input({'type': 'dropdown_filter', 'index': ALL}, 'value'),
)
def print_current_values(values):
return f'selected values : {values}'
if __name__ == '__main__':
app.run(debug=True)