Tooltip
A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.
Usage
Example
Add to library
Tooltip do TooltipTrigger do Button(variant: :outline, icon: true) do bookmark_icon end end TooltipContent do Text { "Add to library" } end end
Long content
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Tooltip do TooltipTrigger do Button(variant: :outline) { "Hover me" } end TooltipContent do Text { "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat." } end end
Installation
Using RubyUI CLI
Run the install command
rails g ruby_ui:component Tooltip
Manual installation
1
Add RubyUI::Tooltip to app/components/ruby_ui/tooltip/tooltip.rb
# frozen_string_literal: true module RubyUI class Tooltip < Base def initialize(placement: "top", **attrs) @placement = placement super(**attrs) end def view_template(&) div(**attrs, &) end private def default_attrs { data: { controller: "ruby-ui--tooltip", ruby_ui__tooltip_placement_value: @placement }, class: "group" } end end end
2
Add RubyUI::TooltipContent to app/components/ruby_ui/tooltip/tooltip_content.rb
# frozen_string_literal: true module RubyUI class TooltipContent < Base def initialize(**attrs) @id = "tooltip#{SecureRandom.hex(4)}" super end def view_template(&) div(**attrs, &) end private def default_attrs { id: @id, data: { ruby_ui__tooltip_target: "content" }, class: "invisible peer-hover:visible peer-focus:visible w-fit max-w-[calc(100vw-2rem)] text-balance break-words absolute top-0 left-0 z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md peer-focus:zoom-in-95 animate-out fade-out-0 zoom-out-95 peer-hover:animate-in peer-focus:animate-in peer-hover:fade-in-0 peer-focus:fade-in-0 peer-hover:zoom-in-95 group-data-[ruby-ui--tooltip-placement-value=bottom]:slide-in-from-top-2 group-data-[ruby-ui--tooltip-placement-value=left]:slide-in-from-right-2 group-data-[ruby-ui--tooltip-placement-value=right]:slide-in-from-left-2 group-data-[ruby-ui--tooltip-placement-value=top]:slide-in-from-bottom-2 delay-500" } end end end
3
Add RubyUI::TooltipDocs to app/components/ruby_ui/tooltip/tooltip_docs.rb
# frozen_string_literal: true class Views::Docs::Tooltip < Views::Base def view_template component = "Tooltip" div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do render Docs::Header.new(title: "Tooltip", description: "A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.") Heading(level: 2) { "Usage" } render Docs::VisualCodeExample.new(title: "Example", context: self) do <<~RUBY Tooltip do TooltipTrigger do Button(variant: :outline, icon: true) do bookmark_icon end end TooltipContent do Text { "Add to library" } end end RUBY end render Docs::VisualCodeExample.new(title: "Long content", context: self) do <<~RUBY Tooltip do TooltipTrigger do Button(variant: :outline) { "Hover me" } end TooltipContent do Text { "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat." } end end RUBY end render Components::ComponentSetup::Tabs.new(component_name: component) render Docs::ComponentsTable.new(component_files(component)) end end private def bookmark_icon svg( xmlns: "http://www.w3.org/2000/svg", fill: "none", viewbox: "0 0 24 24", stroke_width: "1.5", stroke: "currentColor", class: "w-4 h-4" ) do |s| s.path( stroke_linecap: "round", stroke_linejoin: "round", d: "M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0111.186 0z" ) end end end
4
Add RubyUI::TooltipTrigger to app/components/ruby_ui/tooltip/tooltip_trigger.rb
# frozen_string_literal: true module RubyUI class TooltipTrigger < Base def view_template(&) div(**attrs, &) end private def default_attrs { data: {ruby_ui__tooltip_target: "trigger"}, variant: :outline, class: "peer" } end end end
5
Add tooltip_controller.js to app/javascript/controllers/ruby_ui/tooltip_controller.js
import { Controller } from "@hotwired/stimulus"; import { computePosition, autoUpdate, offset, shift } from "@floating-ui/dom"; export default class extends Controller { static targets = ["trigger", "content"]; static values = { placement: String } constructor(...args) { super(...args); this.cleanup; } connect() { this.setFloatingElement(); const tooltipId = this.contentTarget.getAttribute("id"); this.triggerTarget.setAttribute("aria-describedby", tooltipId); } disconnect() { this.cleanup(); } setFloatingElement() { this.cleanup = autoUpdate(this.triggerTarget, this.contentTarget, () => { computePosition(this.triggerTarget, this.contentTarget, { placement: this.placementValue, middleware: [offset(4), shift()] }).then(({ x, y }) => { Object.assign(this.contentTarget.style, { left: `${x}px`, top: `${y}px`, }); }); }); } }
6
Update the Stimulus controllers manifest file
Importmap!
rake stimulus:manifest:update
7
Install @floating-ui/dom Javascript dependency
// with yarn yarn add @floating-ui/dom // with npm npm install @floating-ui/dom // with importmaps bin/importmap pin @floating-ui/dom
8
Install required components
Component Tooltip relies on the following RubyUI components. Refer to their individual installation guides for setup instructions:
Components
| Component | Built using | Source |
|---|---|---|
Tooltip | Phlex | |
TooltipContent | Phlex | |
TooltipDocs | Phlex | |
TooltipTrigger | Phlex | |
TooltipController | Stimulus JS |