Dash Interval closing tooltip

I’m trying to render some dynamic content that periodically refreshes via the dcc.Interval component. I also want to render a tooltip within this content.

When I hover or the tooltip, it opens as expected, but will then close automatically when the next interval fires. I’ve confirmed that the DOM element isn’t being recreated, and that events like mouseout aren’t firing.

Anyone know how to support this, or if this is just a known limitation?

Demo

demo

Minimal Repro

import dash_bootstrap_components as dbc
from dash import Dash, dcc, html, Input, Output

app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = html.Div(
    [
        html.Div(
            [
                html.Div(id="list"),
                dcc.Interval(id="list-interval", interval=1000),
            ],
        ),
    ]
)


@app.callback(
    Output("list", "children"),
    Input("list-interval", "n_intervals"),
)
def set_output(_trigger):
    return (
        html.Div(
            [
                html.Span("bloop", id="bloop"),
                dbc.Tooltip("bloop", target="bloop"),
            ]
        ),
    )


if __name__ == "__main__":
    app.run_server(debug=True)

IIUC try moving the bloop id to the layout and create a second output

import dash_bootstrap_components as dbc
from dash import Dash, dcc, html, Input, Output
import numpy as np

app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = html.Div(
    [
        html.Div(
            [
                # move the bloop id in the layout
                html.Div(html.Span("bloop", id="bloop"), id="list"),
                dbc.Tooltip("bloop", target="bloop", id='tooltip'),
                dcc.Interval(id="list-interval", interval=1000),
            ],
        ),
    ]
)


@app.callback(Output("tooltip", "children"),
              Output("bloop", "children"),
              Input("list-interval", "n_intervals"),)
def set_tt_bloop(_trigger):
    """
    create a function to set the tooltip and the bloop children
    """
    tt = np.random.choice(['foo', 'bar', 'baz'])
    bloop = np.random.choice(['beep', 'bloop', 'bop'])
    return tt, bloop


if __name__ == "__main__":
    app.run_server(debug=True)

Thanks for the response! I may have made the repro a bit too minimal. In my case, the tooltips themselves are dynamic, here’s another example:

import dash_bootstrap_components as dbc
from dash import Dash, dcc, html, Input, Output

app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = html.Div(
    [
        html.Div(
            [
                html.Div(id="list"),
                dcc.Interval(id="list-interval", interval=1000),
            ],
        ),
    ]
)


@app.callback(
    Output("list", "children"),
    Input("list-interval", "n_intervals"),
)
def set_output(_trigger):
    return (
        html.Ol(
            [
                html.Li([html.Span(element, id=element), dbc.Tooltip(element, target=element)])
                for element in ["bloop", "bleep", "blorp"]
            ]
        ),
    )


if __name__ == "__main__":
    app.run_server(debug=True)

Any thoughts with that added wrinkle?

Is the list of elements the same every time and is the length of the list always the same? Where does ["bloop", "bleep", "blorp"] come from - e.g., is it an input in the set_output function?

They’re not the same every time – the elements are pulled from a database.