From 3eefb54b2ce0bfe49cf54049380c78340cc2a4ed Mon Sep 17 00:00:00 2001 From: Cirdes Date: Wed, 4 Nov 2026 11:56:29 -0300 Subject: [PATCH 1/3] [Feature] Tooltip: match shadcn (Base UI + vega) TooltipContent is now a role="tooltip" popover="manual" with vega's classes (bg-foreground text-background, text-xs, max-w-xs, inline-flex gap-1.5) and an arrow placed by Floating UI's arrow(). The controller places the content right after the trigger instead of in , so it stays inside its container, and adds flip() and Base UI's --transform-origin. TooltipTrigger becomes an inline-flex w-fit wrapper, so the hit area and the anchor are the button, and drops the stray variant="outline" attribute. The tooltip now opens on keyboard focus (focusin), closes on Escape, and stays open while the pointer is over it (WCAG 1.4.13). The focusable trigger gets aria-describedby, as the APG tooltip pattern asks. New options: Tooltip(open:, disabled:) with a ruby-ui--tooltip:change event, TooltipTrigger(delay:, close_delay:, close_on_click:) and TooltipContent(side:, side_offset:, align:, align_offset:). placement: still works as a fallback for side:. data-slot on every part. SidebarMenuButton hides its tooltip from its own sidebar's state, which fixes tooltips staying hidden when another sidebar on the page is expanded (follow-up from #644). Adds the audit map (with the drift baseline) and fixtures, updates the docs and rebuilds the MCP registry. Co-Authored-By: Claude Opus 5.5 --- audit/component_map/tooltip.yml | 32 ++ audit/fixtures/tooltip/content.yml | 3 + audit/fixtures/tooltip/rubyui.rb | 20 + audit/fixtures/tooltip/shadcn.tsx | 28 ++ docs/app/views/docs/tooltip.rb | 96 +++- .../ruby_ui/sidebar/sidebar_menu_button.rb | 21 +- gem/lib/ruby_ui/tooltip/tooltip.rb | 17 +- gem/lib/ruby_ui/tooltip/tooltip_content.rb | 76 ++- gem/lib/ruby_ui/tooltip/tooltip_controller.js | 433 ++++++++++++++++-- gem/lib/ruby_ui/tooltip/tooltip_docs.rb | 96 +++- gem/lib/ruby_ui/tooltip/tooltip_trigger.rb | 26 +- gem/test/ruby_ui/sidebar_test.rb | 16 +- gem/test/ruby_ui/tooltip_test.rb | 110 ++++- mcp/data/registry/components/sidebar.json | 2 +- mcp/data/registry/components/tooltip.json | 44 +- 15 files changed, 916 insertions(+), 104 deletions(-) create mode 100644 audit/component_map/tooltip.yml create mode 100644 audit/fixtures/tooltip/content.yml create mode 100644 audit/fixtures/tooltip/rubyui.rb create mode 100644 audit/fixtures/tooltip/shadcn.tsx diff --git a/audit/component_map/tooltip.yml b/audit/component_map/tooltip.yml new file mode 100644 index 000000000..d359fd86c --- /dev/null +++ b/audit/component_map/tooltip.yml @@ -0,0 +1,32 @@ +shadcn: tooltip +shadcn_sha: 8a3536678a528cc012b9e62484290e79d0be410f +kind: popover +docs_view: tooltip +# The fixture follows shadcn's "Basic" example: an outline Button as the +# trigger and a

in the content. Both sides open at once (delay 0) and stay +# open on click (closeOnClick false / close_on_click: false) so collect's +# click, which hovers the trigger first, reaches the open state. +parts: + Tooltip: tooltip + TooltipTrigger: tooltip-trigger + TooltipContent: tooltip-content +# TooltipTrigger is an inline-flex

wrapper in RubyUI; the Button inside +# it is what shadcn renders as the trigger (render={