diff --git a/test/components/previews/pathogen/tooltip_preview.rb b/test/components/previews/pathogen/tooltip_preview.rb index e775bf40..cf69c96a 100644 --- a/test/components/previews/pathogen/tooltip_preview.rb +++ b/test/components/previews/pathogen/tooltip_preview.rb @@ -1,38 +1,28 @@ # frozen_string_literal: true module Pathogen - # ViewComponent preview for demonstrating Pathogen::Tooltip usage - # Showcases placement options, accessibility features, animations, and browser compatibility class TooltipPreview < ViewComponent::Preview include Pathogen::ViewHelper - # @!group Pathogen Tooltip Component + # @!group Pathogen Tooltip - # @label Basic Usage & Getting Started - # Simple examples showing all four placement options and basic tooltip functionality - def basic_usage; end + # @label Overview + # Placement reference, sizing behaviour, and specimen toolbar examples + def overview; end - # @label Accessibility & Keyboard Navigation - # Demonstrates accessibility features, ARIA patterns, hover/focus triggers, and keyboard support - def accessibility; end + # @label In context + # Icon-only actions, collapsed navigation, and grid row utilities + def in_context; end - # @label Link Component Integration - # Shows integration with Pathogen::Link component in various real-world contexts - def link_integration; end + # @label Accessibility patterns + # Hover and focus triggers, ARIA wiring, and keyboard navigation + def accessibility; end - # @label Visual Test: Click-through after hide + # @label Visual test: Click-through after hide # Repro for "tooltip hides but still blocks clicks" issues. # After the tooltip closes, the button underneath should be clickable immediately. def click_through_after_hide; end - # @label Advanced Features & Edge Cases - # Demonstrates long text handling, max-width constraint, animations, and edge cases - def advanced_features; end - - # @label Browser Compatibility - # Information about CSS anchor positioning support and fallback behavior - def browser_compatibility; end - # @!endgroup end end diff --git a/test/components/previews/pathogen/tooltip_preview/accessibility.html.erb b/test/components/previews/pathogen/tooltip_preview/accessibility.html.erb index 64ae07e2..25e64bec 100644 --- a/test/components/previews/pathogen/tooltip_preview/accessibility.html.erb +++ b/test/components/previews/pathogen/tooltip_preview/accessibility.html.erb @@ -1,347 +1,96 @@ <%# herb:formatter ignore %> -
- Demonstrating ARIA compliance, keyboard accessibility, and screen reader support -
-- Tooltips appear when you hover over the trigger element with your mouse. -
- -- Tooltips also appear when you focus the element using Tab key navigation. -
- -- Why Both Triggers? -
+- Supporting both hover and focus ensures the tooltip is accessible to all users: mouse users see it on - hover, while keyboard and screen reader users see it on focus. -
-- Tooltips follow W3C ARIA best practices to ensure screen reader compatibility: -
- - role="tooltip"
-
- The tooltip element has role="tooltip" to inform screen readers that this is supplementary
- information.
-
aria-describedby
-
- The trigger element references the tooltip via aria-describedby, creating an accessible
- relationship between them. Screen readers announce the tooltip content when the trigger receives focus.
-
- Each tooltip is automatically assigned a unique ID to ensure proper ARIA connections and avoid conflicts. -
-- Example HTML Structure: -
- -<a href="/samples" aria-describedby="tooltip-abc123"
- data-pathogen--tooltip-target="trigger"> Samples </a>
- <div id="tooltip-abc123" role="tooltip"
- data-pathogen--tooltip-target="tooltip"> View all samples
- </div>
-
- <a href="/specimens" aria-describedby="tooltip-abc123"
+ data-pathogen--tooltip-target="trigger">Specimens</a>
+<div id="tooltip-abc123" role="tooltip"
+ data-pathogen--tooltip-target="tooltip">Browse submitted specimens</div>
- Use the Tab key to - navigate through these links. The tooltip will appear when each link receives focus. -
+ <%= pathogen_supporting(variant: :muted, class: "mb-4") do %> + Tab through the links below. Each trigger should announce its tooltip when focused. + <% end %> -- Press Tab to move to the next focusable element -
-- Press Shift+Tab to move to the previous element -
-- Tooltips should provide brief, supplementary information. Avoid lengthy descriptions. -
-- Tooltips should enhance understanding, not be the sole source of critical information. -
-- Always ensure tooltips appear on focus, not just hover, for keyboard users. -
-- Proper ARIA attributes ensure screen readers announce tooltip content naturally. -
-- Exploring edge cases, long text handling, animations, and advanced tooltip behaviors -
-- Tooltips automatically wrap long text and enforce a max-width of 320px (max-w-xs) to prevent excessively wide - tooltips. -
- -- Short tooltips size to fit their content tightly. -
-- Long text wraps naturally within the 320px max-width. -
-- Content-Adaptive Design -
- -
- Tooltips use inline-block display to wrap tightly around short content, while
- max-w-xs ensures long text doesn't create unwieldy wide tooltips.
-
- Tooltips feature a polished 200ms animation combining opacity fade-in and subtle scale transition (0.9 → 1.0). -
- -
- Scales from origin-bottom (appears to grow from trigger)
-
- Scales from origin-top (appears to grow from trigger)
-
- Scales from origin-right (appears to grow from trigger)
-
- Scales from origin-left (appears to grow from trigger)
-
- Smooth & Natural Animation -
- -
- The ease-out timing function creates a natural deceleration, while the subtle scale (0.9 to
- 1.0) combined with opacity fade creates a polished, professional feel inspired by Primer's design system.
-
- The tooltip component includes sophisticated viewport boundary detection that automatically adjusts tooltip - placement when near the edges of the browser window. -
- -- Automatic Collision Detection -
- -- When a tooltip would overflow the viewport, the JavaScript positioning algorithm automatically: -
- -- Note: This feature works automatically in the application. Test it by hovering over links near the edges - of your browser window while using IRIDA Next. -
-- Multiple tooltips can coexist on the same page without conflicts. Each has a unique ID for proper ARIA - connections. -
- -transition-all duration-200 ease-out -
- Smooth animation
- opacity-0 scale-90 invisible - Hidden
- state
- opacity-100 scale-100 visible -
- Visible state
- max-w-xs inline-block -
- Content-adaptive sizing
- getBoundingClientRect() - Gets trigger
- element coordinates
- position: fixed - Viewport-relative
- positioning
- Viewport detection - Automatic
- placement flipping
- transform-origin - Scale animation
- origin
- mouseenter - Show on hover
- mouseleave - Hide on hover out
- focusin - Show on focus
- focusout - Hide on blur
- - Accessible tooltips with JavaScript positioning, smooth animations, and Primer-inspired design. -
-Top Placement (Default)
- - <%= render Pathogen::Link.new(href: "#") do |link| %> - <% link.with_tooltip(text: "This tooltip appears above the link", placement: :top) %> Hover or focus me - (top) - <% end %> -Left Placement
- - <%= render Pathogen::Link.new(href: "#") do |link| %> - <% link.with_tooltip(text: "This tooltip appears to the left", placement: :left) %> Hover or focus me - (left) - <% end %> -Right Placement
- - <%= render Pathogen::Link.new(href: "#") do |link| %> - <% link.with_tooltip(text: "This tooltip appears to the right", placement: :right) %> Hover or focus me - (right) - <% end %> -Bottom Placement
- - <%= render Pathogen::Link.new(href: "#") do |link| %> - <% link.with_tooltip( - text: "This tooltip appears below the link", - placement: :bottom, - ) %> - Hover or focus me (bottom) - <% end %> -| Parameter | -Type | -Required | -Description | -
|---|---|---|---|
| text | -String | - -- - Required - - | - -The tooltip text content | -
| placement | -Symbol | - -- - Optional - - | - -- Position: :top (default), :bottom, :left, :right - | -
- If you don't specify a placement, tooltips will appear above the trigger element -
-- Tooltips automatically size to fit content with a max width of 320px -
-- 200ms fade-in and scale animation for a polished feel -
-- Uses Floating UI for precise positioning instead of Flowbite/Popper.js -
-- JavaScript positioning with viewport detection for broad browser compatibility -
-- This tooltip component uses JavaScript-based positioning for maximum browser compatibility. Works in all modern - browsers with ES6+ JavaScript support: -
- -JavaScript Positioning
- -- The tooltip uses JavaScript-based positioning with `getBoundingClientRect()` for precise placement. This - approach provides sophisticated features like viewport boundary detection and automatic placement flipping - that work consistently across all modern browsers. -
-- The tooltip component uses JavaScript-based positioning with sophisticated viewport detection: -
- -- Tooltips calculate their optimal position using `getBoundingClientRect()` to get exact trigger element - coordinates, then apply calculated positions via inline styles. -
- -position: fixed; top: ${top}px; left: ${left}px;
- - The Stimulus controller detects when tooltips would overflow viewport edges and automatically flips - placement: -
- -- If a tooltip can't fit in its preferred placement even after flipping, the positioning algorithm clamps it - to viewport bounds to ensure it remains fully visible with proper padding. -
-- The decision to use custom JavaScript positioning instead of external libraries or cutting-edge CSS features - brings several advantages: -
- -- Works in all modern browsers (Chrome, Firefox, Safari, Edge) without feature flags or polyfills. -
-- No need to include Popper.js, Floating UI, or other positioning libraries, reducing JavaScript payload. -
-- Automatic placement flipping and position clamping ensure tooltips always stay within viewport bounds. -
-- Custom implementation allows precise control over positioning logic and edge cases. -
-- Uses Floating UI instead of Flowbite, reducing maintenance burden and improving positioning accuracy. -
-- JavaScript positioning provides consistent behavior across all browsers without browser-specific quirks. -
-- This tooltip component was redesigned to remove the Flowbite dependency, which used Popper.js for positioning. -
- -- Learn about the DOM API used for precise element positioning calculations. -
- - - MDN: getBoundingClientRect() → - -- Explore GitHub's Primer design system for tooltip design inspiration and patterns. -
- - - Primer Tooltip Component → - -- Learn about the Stimulus JavaScript framework used for the tooltip controller. -
- - - Stimulus Documentation → - -- W3C WAI-ARIA best practices for implementing accessible tooltip components. -
- - - WAI-ARIA: Tooltip Pattern → - -- This preview is a manual visual regression check for a bug where a tooltip becomes hidden but still blocks clicks - on elements underneath it. -
-Underlying action clicks
-0
+ <%= pathogen_supporting(tag: :span, variant: :muted) { "Underlying action clicks" } %> + +0
- Tooltip placement is bottom. While open, it should overlap the button above; after it hides,
- the button must be clickable immediately.
-
What “broken” looks like
- -- If the tooltip is visually hidden but still sitting on top of the page (e.g. due to not being truly hidden - or still catching pointer events), clicks on “Underlying action” won’t increment the counter even though - the tooltip looks gone. -
-