diff --git a/README.md b/README.md index 70b6347..d04783f 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ If a Shinylive app cannot be exported, the build fails. Move it to the server ru ## Input Help and Tooltips -Use input tooltips conservatively. Add them only when a control represents a non-obvious statistical or mathematical concept, uses a confusing scale, changes the result conceptually, or needs context that does not fit naturally in its label. +Use input tooltips conservatively across all apps, including drafts. Add them only when a control represents a non-obvious statistical or mathematical concept, uses a confusing scale, changes the result conceptually, or needs context that does not fit naturally in its label. - Treat two to four tooltips per app as an upper limit, not a target. - Do not add help to obvious controls such as the number of observations unless there is an important non-obvious consequence. @@ -94,38 +94,32 @@ Use input tooltips conservatively. Add them only when a control represents a non - Do not repeat the general explanation already available in `readme.md`. - Preserve existing label wrappers such as `tags$small()` and the current sidebar spacing. - Use namespace-qualified calls instead of adding `library(bsicons)`. -- Give icon-only triggers a short accessible `title`. +- Do not set `title` on the icon trigger; browser-native title tooltips duplicate the `bslib` tooltip. +- For an icon-only trigger, wrap the icon in an accessible span with `role = "button"` and an `aria-label`. - Add a small spacing utility such as `class = "ms-1"` so the icon remains visually separate from the label. - Support hover, keyboard focus, and click/touch with `options = list(trigger = "hover focus click")`. -- Use a light tooltip theme with a white background, dark text, and a subtle border or shadow. +- Use the repository tooltip background `#495057`; keep the rest of the appearance on Bootstrap defaults. - Test the icon at normal and narrow widths and verify the interaction directly in the running app. -Configure the light tooltip appearance once in the app theme: +Configure the tooltip appearance once in each app that uses tooltips: ```r -apptheme <- bs_theme( - "tooltip-bg" = "$white", - "tooltip-color" = "$body-color", - "tooltip-opacity" = 1 -) |> - bs_add_rules( - ".tooltip-inner { - border: 1px solid $border-color; - box-shadow: $box-shadow-sm; - }" - ) +apptheme <- bs_theme("tooltip-bg" = "#495057") ``` +If the app already customizes `bs_theme()`, keep those settings and add `"tooltip-bg" = "#495057"` to the same call. + Use this pattern, adapting the outer wrapper to the existing label: ```r label = tags$small(tagList( "Parameter name", bslib::tooltip( - bsicons::bs_icon( - "info-circle", + tags$span( + bsicons::bs_icon("info-circle"), class = "ms-1", - title = "About parameter name" + role = "button", + `aria-label` = "About parameter name" ), "Short explanation.", placement = "right", diff --git a/app-template/app.R b/app-template/app.R index 43d2cbc..6b61d44 100644 --- a/app-template/app.R +++ b/app-template/app.R @@ -3,7 +3,7 @@ library(shiny) library(bslib) # theme ------------------------------------------------------------------- -apptheme <- bs_theme() +apptheme <- bs_theme("tooltip-bg" = "#495057") sidebar <- purrr::partial(bslib::sidebar, width = 300) @@ -39,4 +39,4 @@ server <- function(input, output, session) { # Add server logic here. } -shinyApp(ui, server) \ No newline at end of file +shinyApp(ui, server) diff --git a/decision-tree/app.R b/decision-tree/app.R index fb4beb0..297230d 100644 --- a/decision-tree/app.R +++ b/decision-tree/app.R @@ -12,7 +12,7 @@ library(risk3r) # remotes::install_github("jbkunst/risk3r", force = TRUE) library(klassets) # remotes::install_github("jbkunst/klassets", force = TRUE) # theme options ----------------------------------------------------------- -apptheme <- bs_theme() +apptheme <- bs_theme("tooltip-bg" = "#495057") sidebar <- purrr::partial(bslib::sidebar, width = 300) @@ -48,7 +48,20 @@ ui <- page_fillable( ), sliderInput( "percent_noise", - tags$small("Percent noise"), + tags$small(tagList( + "Percent noise", + bslib::tooltip( + tags$span( + bsicons::bs_icon("info-circle"), + class = "ms-1", + role = "button", + `aria-label` = "About percent noise" + ), + "Randomly flips this percentage of class labels, making the underlying relationship harder to learn.", + placement = "right", + options = list(trigger = "hover focus click") + ) + )), min = 0, max = 50, step = 5, @@ -253,4 +266,4 @@ server <- function(input, output, session) { } -shinyApp(ui, server) \ No newline at end of file +shinyApp(ui, server) diff --git a/lorenz-attractor/app.R b/lorenz-attractor/app.R index 16159f1..27a6278 100644 --- a/lorenz-attractor/app.R +++ b/lorenz-attractor/app.R @@ -8,17 +8,7 @@ library(markdown) library(shinyWidgets) # theme options ----------------------------------------------------------- -apptheme <- bs_theme( - "tooltip-bg" = "$white", - "tooltip-color" = "$body-color", - "tooltip-opacity" = 1 -) |> - bs_add_rules( - ".tooltip-inner { - border: 1px solid $border-color; - box-shadow: $box-shadow-sm; - }" - ) +apptheme <- bs_theme("tooltip-bg" = "#495057") sidebar <- purrr::partial(bslib::sidebar, width = 300) @@ -63,7 +53,12 @@ ui <- page_fillable( tagList( "\\( \\sigma \\) (sigma):", bslib::tooltip( - bsicons::bs_icon("info-circle", class = "ms-1", title = "About sigma"), + tags$span( + bsicons::bs_icon("info-circle"), + class = "ms-1", + role = "button", + `aria-label` = "About sigma" + ), "Controls how quickly x follows y.", placement = "right", options = list(trigger = "hover focus click") @@ -79,7 +74,12 @@ ui <- page_fillable( tagList( "\\( \\rho \\) (rho):", bslib::tooltip( - bsicons::bs_icon("info-circle", class = "ms-1", title = "About rho"), + tags$span( + bsicons::bs_icon("info-circle"), + class = "ms-1", + role = "button", + `aria-label` = "About rho" + ), "Controls the system's driving strength and whether chaotic behavior emerges.", placement = "right", options = list(trigger = "hover focus click") @@ -95,7 +95,12 @@ ui <- page_fillable( tagList( "\\( \\beta \\) (beta):", bslib::tooltip( - bsicons::bs_icon("info-circle", class = "ms-1", title = "About beta"), + tags$span( + bsicons::bs_icon("info-circle"), + class = "ms-1", + role = "button", + `aria-label` = "About beta" + ), "Controls damping in the z direction.", placement = "right", options = list(trigger = "hover focus click") @@ -119,7 +124,12 @@ ui <- page_fillable( tagList( "Time step (dt):", bslib::tooltip( - bsicons::bs_icon("info-circle", class = "ms-1", title = "About time step"), + tags$span( + bsicons::bs_icon("info-circle"), + class = "ms-1", + role = "button", + `aria-label` = "About time step" + ), "Larger steps cover more time per point but reduce numerical accuracy.", placement = "right", options = list(trigger = "hover focus click") diff --git a/pokemon-dimensionality-reduction/app.R b/pokemon-dimensionality-reduction/app.R index fabab12..b035684 100644 --- a/pokemon-dimensionality-reduction/app.R +++ b/pokemon-dimensionality-reduction/app.R @@ -29,7 +29,8 @@ apptheme <- bs_theme( bg = "#f5f7fb", fg = "#172033", primary = "#2a75bb", - secondary = "#ffcb05" + secondary = "#ffcb05", + "tooltip-bg" = "#495057" ) sidebar <- purrr::partial(bslib::sidebar, width = 305) @@ -224,7 +225,20 @@ ui <- page_fillable( "input.method === 'tsne'", sliderInput( "perplexity", - "Perplexity", + tagList( + "Perplexity", + bslib::tooltip( + tags$span( + bsicons::bs_icon("info-circle"), + class = "ms-1", + role = "button", + `aria-label` = "About perplexity" + ), + "Controls the effective neighborhood size t-SNE tries to preserve; larger values emphasize broader structure.", + placement = "right", + options = list(trigger = "hover focus click") + ) + ), min = 5, max = 100, value = 40, @@ -243,7 +257,20 @@ ui <- page_fillable( "input.method === 'umap'", sliderInput( "n_neighbors", - "Neighbors", + tagList( + "Neighbors", + bslib::tooltip( + tags$span( + bsicons::bs_icon("info-circle"), + class = "ms-1", + role = "button", + `aria-label` = "About UMAP neighbors" + ), + "Controls how many nearby observations UMAP uses to define local structure; larger values emphasize broader patterns.", + placement = "right", + options = list(trigger = "hover focus click") + ) + ), min = 2, max = 100, value = 30, @@ -251,7 +278,20 @@ ui <- page_fillable( ), sliderInput( "min_dist", - "Minimum distance", + tagList( + "Minimum distance", + bslib::tooltip( + tags$span( + bsicons::bs_icon("info-circle"), + class = "ms-1", + role = "button", + `aria-label` = "About UMAP minimum distance" + ), + "Controls how tightly UMAP can pack nearby points in the embedding; smaller values form denser clusters.", + placement = "right", + options = list(trigger = "hover focus click") + ) + ), min = 0, max = 0.95, value = 0.15,