-
Notifications
You must be signed in to change notification settings - Fork 63
Add tooltip()
API
#662
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Merged
Add tooltip()
API
#662
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
2c856b7
First pass on tooltip()
cpsievert afc7fba
`yarn build` (GitHub Actions)
cpsievert dc34842
chore(srcts): Separate _utils and web component helpers
gadenbuie 08c3d16
chore: Update yarn.lock
gadenbuie d24448a
Merge branch 'main' into tooltips
cpsievert 444d821
`devtools::document()` (GitHub Actions)
cpsievert 311c33b
`yarn build` (GitHub Actions)
cpsievert 1bc957f
Fix bug introduced by merge conflict error
cpsievert 52f6b9b
`devtools::document()` (GitHub Actions)
cpsievert 6f83755
Code review; fix tooltips inside a card
cpsievert a6a901d
`devtools::document()` (GitHub Actions)
cpsievert a8d442d
`yarn build` (GitHub Actions)
cpsievert e6ea4fe
Resave distributed files (GitHub Action)
cpsievert 9db9d14
Make sure value_box()'s dependency doesn't create an empty card-body …
cpsievert 149e9a6
Add input_switch() (#483)
cpsievert 44b0ed3
fix(bs_theme_preview): Don't include dashboard tab for BS < 5 (#670)
gadenbuie 5111433
feat(bs_theme_preview): Add more DT features and more tables (#671)
gadenbuie 13e69e4
feat(bs_theme_preview): Add more DT features and more tables (#671)
gadenbuie 17cddeb
feat(card): Use an attribute to signal card is in full screen (#669)
gadenbuie 9683c4f
Constrain width of showcase icons in value boxes (#653)
gadenbuie b254430
Better tooltip_toggle() and tooltip_update() behavior; small improvem…
cpsievert 2d587ec
Merge branch 'main' into tooltips
cpsievert 2786ad0
`devtools::document()` (GitHub Actions)
cpsievert c447bef
`yarn build` (GitHub Actions)
cpsievert dd9fd21
Resave distributed files (GitHub Action)
cpsievert 5d0d951
Embrace update/toggle as a prefix; doc improvements
cpsievert fe14af6
Update/use utility for collection/separating ... args
cpsievert f9fe0e2
Don't show if trigger isn't visible; hide when trigger loses visibili…
cpsievert 22664b8
`devtools::document()` (GitHub Actions)
cpsievert 941f45f
`yarn build` (GitHub Actions)
cpsievert 7cd8ba7
Resave data (GitHub Action)
cpsievert 634e30b
simplify
cpsievert dac46d8
`yarn build` (GitHub Actions)
cpsievert File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
#' Add a tooltip to a UI element | ||
#' | ||
#' Display additional information when focusing (or hovering over) a UI element. | ||
#' | ||
#' @param trigger A UI element (i.e., [htmltools tag][htmltools::tags]) to serve | ||
#' as the tooltips trigger. It's good practice for this element to be a | ||
#' keyboard-focusable and interactive element (e.g., `actionButton()`, | ||
#' `actionLink()`, etc) so that the tooltip is accessible to keyboard and | ||
#' assistive technology users. | ||
#' @param ... UI elements for the tooltip. Character strings are [automatically | ||
#' escaped][htmlEscape()] unless marked as [HTML()]. | ||
#' @param id A character string. Required to re-actively respond to the | ||
#' visibility of the tooltip (via the `input[[id]]` value) and/or update the | ||
#' visibility/contents of the tooltip. | ||
#' @param placement The placement of the tooltip relative to its trigger. | ||
#' @param options A list of additional [Bootstrap | ||
#' options](https://getbootstrap.com/docs/5.3/components/tooltips/#options). | ||
#' | ||
#' @details If `trigger` yields multiple HTML elements (e.g., a `tagList()` or | ||
#' complex `{htmlwidgets}` object), the last HTML element is used as the | ||
#' trigger. If the `trigger` should contain all of those elements, wrap the | ||
#' object in a [div()] or [span()]. | ||
#' | ||
#' @describeIn tooltip Add a tooltip to a UI element | ||
#' @references <https://getbootstrap.com/docs/5.3/components/tooltips/> | ||
#' @export | ||
#' @examplesIf interactive() | ||
#' | ||
#' tooltip( | ||
#' shiny::actionButton("btn", "A button"), | ||
#' "A message" | ||
#' ) | ||
#' | ||
#' card( | ||
#' card_header( | ||
#' tooltip( | ||
#' span("Card title ", bsicons::bs_icon("question-circle-fill")), | ||
#' "Additional info", | ||
#' placement = "right" | ||
#' ) | ||
#' ), | ||
#' "Card body content..." | ||
#' ) | ||
tooltip <- function( | ||
trigger, | ||
..., | ||
id = NULL, | ||
placement = c("auto", "top", "right", "bottom", "left"), | ||
options = list() | ||
) { | ||
|
||
args <- separate_arguments(...) | ||
children <- args$children | ||
attribs <- args$attribs | ||
|
||
if (length(children) == 0) { | ||
abort("At least one value must be provided to `...`.") | ||
} | ||
|
||
res <- web_component( | ||
"bslib-tooltip", | ||
id = id, | ||
placement = rlang::arg_match(placement), | ||
options = jsonlite::toJSON(options, auto_unbox = TRUE), | ||
!!!attribs, | ||
# Use display:none instead of <template> since shiny.js | ||
# doesn't bind to the contents of the latter | ||
div(!!!children, style = "display:none;"), | ||
trigger | ||
) | ||
|
||
res <- tag_require(res, version = 5, caller = "tooltip()") | ||
as_fragment(res) | ||
} | ||
|
||
#' @describeIn tooltip Programmatically show/hide a tooltip. | ||
#' | ||
#' @param id a character string that matches an existing tooltip id. | ||
#' @param show Whether to show (`TRUE`) or hide (`FALSE`) the tooltip. The | ||
#' default (`NULL`) will show if currently hidden and hide if currently shown. | ||
#' Note that a tooltip will not be shown if the trigger is not visible (e.g., | ||
#' it's hidden behind a tab). | ||
#' @param session A Shiny session object (the default should almost always be | ||
#' used). | ||
#' | ||
#' @export | ||
toggle_tooltip <- function(id, show = NULL, session = get_current_session()) { | ||
show <- normalize_show_value(show) | ||
|
||
msg <- list(method = "toggle", value = show) | ||
force(id) | ||
callback <- function() { | ||
session$sendInputMessage(id, msg) | ||
} | ||
session$onFlush(callback, once = TRUE) | ||
} | ||
|
||
|
||
#' @describeIn tooltip Update the contents of a tooltip. | ||
#' @export | ||
update_tooltip <- function(id, ..., session = get_current_session()) { | ||
|
||
title <- tagList(...) | ||
|
||
msg <- dropNulls(list( | ||
method = "update", | ||
title = if (length(title) > 0) processDeps(title, session) | ||
)) | ||
|
||
force(id) | ||
callback <- function() { | ||
session$sendInputMessage(id, msg) | ||
} | ||
session$onFlush(callback, once = TRUE) | ||
} | ||
|
||
normalize_show_value <- function(show) { | ||
if (is.null(show)) return("toggle") | ||
|
||
if (length(show) != 1 || !is.logical(show)) { | ||
abort("`show` must be `TRUE`, `FALSE`, or `NULL`.") | ||
} | ||
|
||
if (show) "show" else "hide" | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.