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
Copied!
Copy failed!
Installation
Using RubyUI CLI
Run the install command
rails g ruby_ui:component Tooltip
Copied!
Copy failed!
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
Copied!
Copy failed!
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-max 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
Copied!
Copy failed!
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 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
Copied!
Copy failed!
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
Copied!
Copy failed!
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`, }); }); }); } }
Copied!
Copy failed!
6
Update the Stimulus controllers manifest file
Importmap!
You don't need to run this command if you are using Importmap
rake stimulus:manifest:update
Copied!
Copy failed!
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
Copied!
Copy failed!
Components
| Component | Built using | Source |
|---|---|---|
Tooltip | Phlex | |
TooltipContent | Phlex | |
TooltipDocs | Phlex | |
TooltipTrigger | Phlex | |
TooltipController | Stimulus JS |