Custom Component: Text area with image/file drop

Hello! Has anyone made/found a custom dash component which is a textfield/text area with the option to drag and drop images/files into the text area? I have a separate upload button, but I would like to be able drag and drop screenshots directly, like other chat apps (e.g. MS Teams).

Hey @faulty13, you could just wrap the input with an upload component and disable the click:

import dash
from dash import dcc, html, Input, Output

app = dash.Dash(__name__)

# --- Text Input ---
txt = html.Div(
    [
        dcc.Input(
            id='text-input',
            type='text',
            placeholder='Type here...',
            style={
                'width': '100%',
                'height': '60px',
                'lineHeight': '60px',
                'borderWidth': '1px',
                'textAlign': 'center', 'margin': '10px 0'
            }
        )
    ]
)


app.layout = html.Div([
    html.H2("Python Dash: Input & Upload Demo"),
    html.Br(),
    # --- File Upload Section ---
    html.Label("Enter some text or drag a file"),
    html.Div(
        [
            dcc.Upload(
                id='upload-data',
                children=txt,        # <--- the dcc.Input() defined above
                disable_click=True,
                multiple=False
            )
        ],
        style={'padding': '10px'}
    ),

    html.Hr(),

    # --- Output Display ---
    html.Div(id='output-display-area', style={'padding': '20px', 'backgroundColor': '#f9f9f9'})
])


# Callback to process both inputs
@app.callback(
    Output('output-display-area', 'children'),
    Input('text-input', 'value'),
    Input('upload-data', 'filename')
)
def update_output(text_value, file_name):
    # This logic runs whenever the text changes or a file is uploaded
    content = []

    if text_value:
        content.append(html.P(f"You typed: {text_value}"))

    if file_name:
        content.append(html.P(f"File uploaded: {file_name}"))

    if not text_value and not file_name:
        return "Waiting for input..."

    return content


if __name__ == '__main__':
    app.run(debug=True)
1 Like