plotly / dash

Data Apps & Dashboards for Python. No JavaScript Required.
https://plotly.com/dash
MIT License
20.95k stars 2.02k forks source link

[BUG] dcc.Tooltip children isn't clickable even with targetable=True #2759

Open celia-lm opened 5 months ago

celia-lm commented 5 months ago

Describe your context

Describe the bug and expected behaviour dcc.Tooltip children isn't clickable even with targetable=True, it's necessary to set style={'pointer-events':'auto'}

After reviewing the code, I believe L74 should look like L42 of the same file, that is, setting pointer-events: ${props.targetable ? 'auto' : 'none'} for .hover-content too, and not only in .dcc-tooltip-bounding-box

Related forum issues:

Screenshots Screen recording: https://github.com/plotly/dash/assets/101562106/f15c893f-5f19-421e-9d2c-e62c14e8cd25

Screenshot 2024-02-13 at 18 42 03

Code to reproduce the issue

from dash import Dash, dcc, html, Input, Output, no_update, callback
from dash import Patch, State, ALL, MATCH, ctx
import plotly.express as px
import dash

fig = px.scatter(x=[1,2,3], y=[1,2,1], text=['A', 'B', 'C'])
fig.update_traces(
    hoverinfo="none",
    hovertemplate=None,
    marker=dict(size=40)
)
fig.update_traces(textfont_color='white')

app = Dash(__name__)

app.layout = html.Div(
    children=[
        html.H3('Change the RadioItems value to see both behaviours'),
        dcc.RadioItems(["default", "{'pointer-events':'auto'}"], 'default', id='control'),
        html.H3('Tooltip button callback output'),
        html.Div('No tooltip button clicked yet', id='out'),
        dcc.Graph(
            id="graph",
            figure=fig,
            clear_on_unhover=True
            ),
        dcc.Tooltip(
            id="tooltip",
            targetable=True,
            children=html.Button(id='hover-click', children='Click me!')
            ),
    ], 
    style={'margin':'20px'}
)

# change the tooltip style to show bug (default) and workaround
@callback(
    Output('tooltip', 'style'),
    Input('control', 'value'),
    prevent_initial_call=True
)
def update_style(val):
    if val == 'default':
        return None
    else :
        return {'pointer-events':'auto'}

# adapted from https://dash.plotly.com/dash-core-components/tooltip#styling-tooltip-with-background-and-border-color
@callback(
    Output("tooltip", "show"),
    Output("tooltip", "bbox"),
    Input("graph", "hoverData"),
    Input('hover-click', 'n_clicks'),
)
def update_tooltip_content(hoverData, clicks):

    # close the tooltip when the button is clicked
    if ctx.triggered_id == 'hover-click':
        return False, no_update

    # keep the tooltip open if we move away from the point, until we hover over another point
    if hoverData is None:
        return no_update

    pt = hoverData["points"][0]
    bbox = pt["bbox"]

    return True, bbox

# tooltip callback to show that is/isn't working
@callback(
    Output('out', 'children'),
    Input('hover-click', 'n_clicks'),
    prevent_initial_call=True
)
def save_changes(clicks):
    return f"Button has been clicked {clicks} times!"

if __name__ == "__main__":
    app.run(debug=True)
Coding-with-Adam commented 5 months ago

Thanks for reporting, @celia-plotly .

@T4rk1n is this something we can quickly fix? If not, @LiamConnors maybe we could at least make note of the workaround in the docs.

T4rk1n commented 5 months ago

@Coding-with-Adam Yes should be an easy fix.

Coding-with-Adam commented 5 months ago

Thanks @T4rk1n . I updated the bug to sev1 so we can prioritize.