PhiaUi.Components.Tooltip (phia_ui v0.1.17)

Copy Markdown View Source

Tooltip component powered by the PhiaTooltip vanilla JavaScript hook.

Tooltips provide short, supplementary information about an element when a user hovers over or focuses it. They are ideal for clarifying icon buttons, keyboard shortcuts, truncated text, or form field guidance.

The PhiaTooltip hook manages:

  • Show/hide on mouseenter/mouseleave and focus/blur events
  • Configurable delay before showing (avoids flash on quick mouse movement)
  • Smart viewport-edge flipping (repositions to the opposite side if the tooltip would overflow the viewport)
  • CSS opacity transition for a smooth reveal

Sub-components

FunctionElementPurpose
tooltip/1divRoot container — hook mount point
tooltip_trigger/1spanTrigger wrapper with aria-describedby
tooltip_content/1divFloating panel with role="tooltip"

Hook Setup

Copy the hook file via mix phia.add tooltip, then register it in app.js:

# assets/js/app.js
import PhiaTooltip from "./hooks/tooltip"

let liveSocket = new LiveSocket("/live", Socket, {
  hooks: { PhiaTooltip }
})

Basic Example — Icon Button Tooltip

The most common use case: explaining what an unlabelled icon button does.

<.tooltip id="delete-btn-tip" delay_ms={300}>
  <.tooltip_trigger tooltip_id="delete-btn-tip">
    <button phx-click="delete_record" aria-label="Delete record">
      <.icon name="trash" />
    </button>
  </.tooltip_trigger>
  <.tooltip_content tooltip_id="delete-btn-tip" position={:top}>
    Delete this record permanently
  </.tooltip_content>
</.tooltip>

Example — Keyboard Shortcut Hint

Show keyboard shortcuts for actions the user might not discover otherwise:

<.tooltip id="save-shortcut" delay_ms={500}>
  <.tooltip_trigger tooltip_id="save-shortcut">
    <.button phx-click="save">Save</.button>
  </.tooltip_trigger>
  <.tooltip_content tooltip_id="save-shortcut" position={:bottom}>
    Save changes (S)
  </.tooltip_content>
</.tooltip>

Example — Truncated Text Explanation

When table cells or list items may be truncated, a tooltip can show the full text on hover (use a unique id per row, e.g. "name-tip-#{item.id}"):

<.tooltip id="name-tip-42" delay_ms={200}>
  <.tooltip_trigger tooltip_id="name-tip-42">
    <span class="truncate max-w-xs block">{@item.long_name}</span>
  </.tooltip_trigger>
  <.tooltip_content tooltip_id="name-tip-42" position={:right}>
    {@item.long_name}
  </.tooltip_content>
</.tooltip>

Position Values

ValuePanel appears...
:topAbove the trigger (default)
:bottomBelow the trigger
:leftTo the left of the trigger
:rightTo the right of the trigger

The hook reads data-position and adjusts the absolute CSS offset. It also checks viewport boundaries and flips to the opposite side when needed.

Accessibility

  • tooltip_trigger/1 wraps the trigger with aria-describedby pointing at the tooltip content's id. This causes screen readers to announce the tooltip text when focus lands on the trigger element.
  • tooltip_content/1 uses role="tooltip" per the WAI-ARIA specification.
  • The tooltip is pointer-events-none so it does not interfere with mouse events on elements below it.
  • The hook also shows the tooltip on focus (keyboard) and hides it on blur, so keyboard-only users receive the same information.
  • Do not put interactive elements (links, buttons) inside a tooltip — use a popover/1 instead.

Summary

Functions

Renders the tooltip root container and attaches the PhiaTooltip hook.

Renders the floating tooltip content panel.

Renders the tooltip trigger wrapper.

Functions

tooltip(assigns)

Renders the tooltip root container and attaches the PhiaTooltip hook.

The container is relative inline-flex so the absolutely-positioned content panel is offset relative to this element. The data-delay attribute passes the delay to the JS hook.

Attributes

  • id (:string) (required) - Unique element ID. This ID is the coordination point: tooltip_trigger/1 and tooltip_content/1 both derive their IDs from it via the pattern "{id}-content". Must be unique on the page.

  • delay_ms (:integer) - Milliseconds to wait after mouseenter before showing the tooltip. A short delay (200–400ms) prevents the tooltip from flashing when the user's cursor merely passes over the element. Set to 0 for instant reveal (not recommended for most cases).

    Defaults to 200.

  • class (:string) - Additional CSS classes for the container. Defaults to nil.

  • Global attributes are accepted. Extra HTML attributes forwarded to the root <div>.

Slots

tooltip_content(assigns)

Renders the floating tooltip content panel.

Starts invisible via opacity-0 invisible (not display: none) so that CSS opacity transitions work smoothly. The hook adds/removes Tailwind visibility classes to reveal and hide the panel.

pointer-events-none prevents the panel from capturing mouse events, which would interfere with the mouseleave detection on the trigger.

The role="tooltip" attribute, combined with the trigger's aria-describedby, satisfies the WAI-ARIA tooltip pattern. The content must be short and supplementary — not critical or interactive.

Attributes

  • tooltip_id (:string) (required) - ID of the parent tooltip/1 container — used to build the panel's id.

  • position (:atom) - Preferred position of the tooltip panel relative to the trigger. The hook reads data-position and may flip to the opposite side if the panel would overflow the viewport edge.

    Defaults to :top. Must be one of :top, :bottom, :left, or :right.

  • class (:string) - Additional CSS classes. Defaults to nil.

  • Global attributes are accepted. Extra HTML attributes forwarded to the tooltip panel <div>.

Slots

  • inner_block (required) - Tooltip text or content — keep it brief.

tooltip_trigger(assigns)

Renders the tooltip trigger wrapper.

Sets aria-describedby pointing at "{tooltip_id}-content". This ARIA relationship ensures screen readers announce the tooltip text when the user focuses or hovers the trigger — even if the tooltip is not visually shown yet (screen readers read aria-describedby regardless of visual state).

The data-tooltip-trigger attribute is the hook's selector to attach mouseenter, mouseleave, focus, and blur event listeners.

Attributes

  • tooltip_id (:string) (required) - ID of the parent tooltip/1 container — used to build aria-describedby.
  • class (:string) - Additional CSS classes. Defaults to nil.
  • Global attributes are accepted. Extra HTML attributes forwarded to the wrapper <span>.

Slots

  • inner_block (required) - The element that triggers the tooltip — typically a <button>, link, or any focusable element. Wrap your trigger here rather than placing event handlers on the outer tooltip container.