Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to Shiny for Python will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [UNRELEASED]

### Bug fixes

* Fixed `ui.tooltip()`'s `options` parameter to properly pass Bootstrap tooltip options to the underlying web component. The parameter now correctly uses the `bsOptions` attribute expected by the bslib-tooltip component. (#2096)

## [1.5.0] - 2025-09-11

### New features
Expand Down
2 changes: 1 addition & 1 deletion shiny/ui/_tooltip.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def fa_info_circle(title: str):
{
"id": resolve_id_or_none(id),
"placement": placement,
"options": json.dumps(options) if options else None,
"bsOptions": json.dumps(options) if options else None,
},
attrs,
# Use display:none instead of <template> since shiny.js
Expand Down
31 changes: 31 additions & 0 deletions tests/pytest/test_ui.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import textwrap

from htmltools import HTMLDocument, TagList, tags
Expand Down Expand Up @@ -189,3 +190,33 @@ def test__update_options():
assert _update_options(d4, remove_button=True, multiple=True) == d4
assert _update_options(d4, remove_button=True, multiple=False) == d4
assert _update_options(d4, remove_button=False, multiple=False) == d4


def test_tooltip_options():
"""Test that tooltip renders options as bsOptions attribute."""
# Test with options parameter
options_dict = {"offset": [0, 100]}
t = ui.tooltip(
ui.input_action_button("btn", "Test"),
"A message",
id="test_tooltip",
placement="right",
options=options_dict,
)

t_str = str(t)

# Should contain bsOptions attribute with JSON-encoded options
assert "bsoptions" in t_str.lower(), "bsOptions attribute should be present"
assert json.dumps(options_dict) in t_str, "Options should be JSON-encoded"

# Test without options parameter
t2 = ui.tooltip(
ui.input_action_button("btn2", "Test2"),
"Another message",
id="test_tooltip2",
)

t2_str = str(t2)
# Should still render properly
assert "bslib-tooltip" in t2_str, "Tooltip should render without options"