Skip to content

[Feature Request] Allow customisation of dcc.Clipboard icon/children #3565

@celia-lm

Description

@celia-lm

Similar to dmc.CopyButton: https://www.dash-mantine-components.com/components/copybutton#

Current functionality:

Screen.Recording.2026-01-09.at.11.20.10.mov
  • The copy icon is always shown.
  • It can be hidden with css properties, but then a workaround with a callback needs to be implemented to trigger the copy functionality.
  • There are python libraries that allow triggering copy-to-clipboard like pyperclip (https://pypi.org/project/pyperclip/) but (1) they still require a callback (2) they don't work on Dash Enterprise because "on Linux, this module makes use of the xclip or xsel commands, which should come with the os" and their installation as apt-packages doesn't work properly.

Desired functionality:

Screen.Recording.2026-01-09.at.11.11.22.mov

This functionality was achieved with the code included in the "Current workarounds" section.

Suggestion for how it would look code-wise: dcc.Clipboard as a wrapper for the component that triggers the copy functionality (similar to html.A). No id or callbacks needed.

app.layout = html.Div([
    html.H3("Click the button to copy the text to the clipboard"),
    ### Relevant code ###
    html.Div([
            dcc.Clipboard(
                children=html.Button(children=symbol), 
                style={"margin-right":"10px", "font-size":20}
                ),
         ], style={"margin":"10px", "display":"inline-flex"}) for symbol in symbols
    ### End of relevant code ###
    ], style={"display":"inline-flex"}),
    html.H3("Try to paste the copied symbol here"),
    dcc.Textarea(id="textarea", style={'width': '100%', 'height': 300})
], style={"margin":"30px"})

Current workarounds

This code is for the app that is run in the "Desired functionality" video.
It uses a hidden dcc.Clipboard and a callback that triggers its n_clicks property when a corresponding html.Button is clicked:

import dash
from dash import dcc, html, callback, Input, Output, State, MATCH

app = dash.Dash(__name__)

symbols = ["√", "π", "∑", "∆", "γ"]

app.layout = html.Div([
    html.H3("Click the button to copy the text to the clipboard"),
    html.Div([
        html.Div([
            html.Button(children=symbol, id={"type":"symbol", "index":str(i)}),
            dcc.Clipboard(
                target_id={"type":"symbol", "index":str(i)},
                id={"type":"copy-symbol", "index":str(i)},
                style={"display":"none"})
         ], style={"margin":"10px"}) for i, symbol in enumerate(symbols)
    ], style={"display":"inline-flex"}),
    html.H3("Try to paste the copied symbol here"),
    dcc.Textarea(id="textarea", style={'width': '100%', 'height': 300})
], style={"margin":"30px"})

@callback(
    Output({"type":"copy-symbol", "index":MATCH}, "n_clicks"),
    Input({"type":"symbol", "index":MATCH}, "n_clicks"),
    prevent_initial_call=True
)
def copy_symbol(n_clicks):
    return n_clicks
    
if __name__ == "__main__":
    app.run(debug=True)

Sample code for current functionality

import dash
from dash import dcc, html, callback, Input, Output, State, MATCH

app = dash.Dash(__name__)

symbols = ["√", "π", "∑", "∆", "γ"]

app.layout = html.Div([
    html.H3("Click the button to copy the text to the clipboard"),
    html.Div([
        html.Div([
            html.Div(
                children=symbol, 
                id={"type":"symbol", "index":str(i)}, 
                style={"margin-right":"10px", "font-size":20}
                ),
            dcc.Clipboard(
                target_id={"type":"symbol", "index":str(i)},
                id={"type":"copy-symbol", "index":str(i)},
                )
         ], style={"margin":"10px", "display":"inline-flex"}) for i, symbol in enumerate(symbols)
    ], style={"display":"inline-flex"}),
    html.H3("Try to paste the copied symbol here"),
    dcc.Textarea(id="textarea", style={'width': '100%', 'height': 300})
], style={"margin":"30px"})
    
if __name__ == "__main__":
    app.run(debug=True)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions