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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions