Files
sure/app/components/DS/tooltip.html.erb
T
William Wei MingandCursor 819f62019b fix(ui): resolve DS Drift Patrol findings (#2745) (#2975)
* fix(ui): resolve DS Drift Patrol findings from #2745

Replace hand-rolled queue status chips and the insights nav tooltip/badge
with DS::Pill and DS::Tooltip.

Co-authored-by: Cursor <cursoragent@cursor.com>

* i18n: use a single key for background job queue pill labels

* fix(ui): address gariasf review on insights badge and queue pills

Keep the unread insights count on theme-aware inverse tokens (DS::Pill
filled neutral is not dark-mode safe). Extend DS::Tooltip with html_class
passthrough and a/summary focus ancestors so icon-only links keep full
hover + keyboard reveal. Add queue_label locales (de/uk/zh-TW), drop the
dead latency keys, and restore mono via DS::Pill mono: true.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-16 07:16:47 +02:00

41 lines
2.1 KiB
ERB

<span data-controller="DS--tooltip" data-DS--tooltip-placement-value="<%= placement %>" data-DS--tooltip-offset-value="<%= offset %>" data-DS--tooltip-cross-axis-value="<%= cross_axis %>" class="<%= class_names("inline-flex", html_class) %>">
<% if as == :button %>
<%# Wrap the trigger icon in a focusable `<button>` so AT users (and
keyboard-only users) can land on the tooltip anchor. The Lucide
icon itself carries `aria-hidden`, so the button's accessible
name comes from `aria-label`, and the tooltip text is exposed
via `aria-describedby`. %>
<button type="button"
class="inline-flex items-center cursor-default focus-ring rounded"
aria-describedby="<%= tooltip_id %>"
aria-label="<%= t("ds.tooltip.trigger_label", default: "More info") %>">
<%= helpers.icon icon_name, size: size, color: color %>
</button>
<% else %>
<%# `as: :span` — used when the tooltip is rendered inside an
already-focusable interactive ancestor (`<a>`, `<summary>`, …),
where nested interactive content is forbidden or undesirable.
Keyboard reveal is wired in the controller, which also binds
`focusin/focusout/keydown` on the closest `a`/`summary`
ancestor — because `focusin` only bubbles UP, a listener on
this descendant span would never fire when the ancestor
receives focus. Pass `html_class:` (e.g. size-full) when the
wrapper should fill an icon-only link's hit target. %>
<span class="inline-flex items-center"
aria-describedby="<%= tooltip_id %>">
<%= helpers.icon icon_name, size: size, color: color %>
</span>
<% end %>
<div role="tooltip"
id="<%= tooltip_id %>"
data-DS--tooltip-target="tooltip"
class="hidden absolute z-50 bg-inverse text-sm px-1.5 py-1 rounded-md">
<%# `max-w-[20rem]` scales with the root font-size so AT users with
a larger base font don't see the tooltip clipped. %>
<div class="text-inverse font-normal max-w-[20rem]">
<%= tooltip_content %>
</div>
</div>
</span>