Corex.Tooltip (Corex v0.1.0-rc.0)

View Source

Phoenix implementation of Zag.js Tooltip.

Anatomy

Minimal

<.tooltip class="tooltip" show_arrow={false}>
  <:trigger>Hover me</:trigger>
  <:content>Tooltip content</:content>
</.tooltip>

With arrow

<.tooltip class="tooltip">
  <:trigger>Hover me</:trigger>
  <:content>Tooltip content</:content>
</.tooltip>

Placement

<.tooltip class="tooltip" positioning={%Corex.Positioning{placement: "bottom"}}>
  <:trigger>Bottom</:trigger>
  <:content>Tooltip below</:content>
</.tooltip>

API

Requires a stable id on <.tooltip>.

FunctionActionReturns
set_open/2Set open state (client)%Phoenix.LiveView.JS{}
set_open/3Set open state (server)socket

Events

Pick an event name and pass it to on_* on <.tooltip>.

Server events

EventWhenPayload
on_open_change="tooltip_open_changed"Open state changes%{"id" => id, "open" => boolean}
on_trigger_value_change="tooltip_trigger_changed"Active trigger changes (multi-trigger)%{"id" => id, "value" => value}

on_open_change

<.tooltip class="tooltip" on_open_change="tooltip_open_changed">
  <:trigger>Hover me</:trigger>
  <:content>Tooltip content</:content>
</.tooltip>
def handle_event("tooltip_open_changed", %{"id" => _id, "open" => open}, socket) do
  {:noreply, assign(socket, :tooltip_open, open)}
end

Client events

EventWhenevent.detail
on_open_change_client="tooltip-open-changed"Open state changesid, open
on_trigger_value_change_client="tooltip-trigger-changed"Active trigger changesid, value

Patterns

Multi-trigger

One content panel, several triggers. Each trigger value must be unique.

<.tooltip
  class="tooltip"
  on_trigger_value_change="tooltip_trigger_changed"
>
  <:trigger value="a">First</:trigger>
  <:trigger value="b">Second</:trigger>
  <:content>Active: {@active_trigger}</:content>
</.tooltip>
def handle_event("tooltip_trigger_changed", %{"value" => value}, socket) do
  {:noreply, assign(socket, :active_trigger, value)}
end

Style

Target parts with data-scope and data-part, or use Corex Design: import tokens and tooltip.css, then set class="tooltip" on <.tooltip>.

[data-scope="tooltip"][data-part="trigger"] {}
[data-scope="tooltip"][data-part="positioner"] {}
[data-scope="tooltip"][data-part="content"] {}
[data-scope="tooltip"][data-part="arrow"] {}
@import "../corex/main.css";
@import "../corex/tokens/themes/neo/light.css";
@import "../corex/components/tooltip.css";

Stack modifiers on the host (class on <.tooltip>).

Color

ModifierClasses
Defaulttooltip
Accenttooltip tooltip--accent
Brandtooltip tooltip--brand
Alerttooltip tooltip--alert
Infotooltip tooltip--info
Successtooltip tooltip--success

Size

ModifierClasses
SMtooltip tooltip--sm
MDtooltip tooltip--md
LGtooltip tooltip--lg
XLtooltip tooltip--xl

Text

ModifierClasses
SMtooltip tooltip--text-sm
XLtooltip tooltip--text-xl

Summary

API

Set tooltip open state from a control (phx-click).

Set open state from handle_event.

Components

tooltip(assigns)

Attributes

  • id (:string) - The id of the tooltip, useful for API to identify the tooltip.
  • disabled (:boolean) - Whether the tooltip is disabled. Defaults to false.
  • dir (:string) - The direction of the tooltip. When nil, derived from document. Defaults to nil. Must be one of nil, "ltr", or "rtl".
  • orientation (:string) - Layout orientation for CSS. Defaults to "horizontal". Must be one of "horizontal", or "vertical".
  • open_delay (:integer) - Delay in ms before opening. Default from Zag is 400. Defaults to 0.
  • close_delay (:integer) - Delay in ms before closing. Default from Zag is 150. Defaults to 0.
  • positioning (Corex.Positioning) - Positioning options for the floating content. Defaults to %Corex.Positioning{hide_when_detached: true, strategy: "fixed", placement: "bottom", gutter: 8, shift: 0, overflow_padding: 0, arrow_padding: 4, flip: true, slide: true, overlap: false, same_width: false, fit_viewport: true, offset: nil}.
  • close_on_escape (:boolean) - Whether to close on Escape. Default true. Defaults to true.
  • close_on_click (:boolean) - Whether to close on click. Default true. Defaults to true.
  • close_on_pointer_down (:boolean) - Whether to close on pointer down on the trigger. Default false. Defaults to false.
  • close_on_scroll (:boolean) - Whether to close on scroll. Default false. Defaults to false.
  • interactive (:boolean) - Whether the tooltip content is interactive (stays open when hovering content). Defaults to true.
  • on_open_change (:string) - The server event name when the open state changes. Defaults to nil.
  • on_open_change_client (:string) - The client event name when the open state changes. Defaults to nil.
  • on_trigger_value_change (:string) - LiveView event when the active trigger value changes (multi-trigger). Params include id (tooltip root) and value (trigger value string). Defaults to nil.
  • on_trigger_value_change_client (:string) - The client event name when the active trigger value changes. Defaults to nil.
  • show_arrow (:boolean) - Whether to show an arrow pointing to the trigger. Defaults to true.
  • trigger_tag (:atom) - Use :span when the tooltip sits inside another button-like control (e.g. tree view row) to avoid nested <button> elements. Defaults to :button. Must be one of :button, or :span.
  • Global attributes are accepted.

Slots

  • trigger (required) - Trigger element content. Use :let={tooltip} for assigns such as disabled. With more than one <:trigger>, each must set value="…" (unique, stable across LiveView patches). Accepts attributes:
    • class (:string)
    • value (:string)
  • content (required) - Tooltip content. Use :let={tooltip} for assigns such as disabled. Accepts attributes:
    • class (:string)

API

set_open(tooltip_id, open)

Set tooltip open state from a control (phx-click).

<.action phx-click={Corex.Tooltip.set_open("my-tooltip", true)}>Show</.action>
<.tooltip id="my-tooltip" class="tooltip">
  <:trigger>Target</:trigger>
  <:content>Hint</:content>
</.tooltip>
document.getElementById("my-tooltip")?.dispatchEvent(
  new CustomEvent("corex:tooltip:set-open", {
    bubbles: false,
    detail: { open: true },
  })
);

set_open(socket, tooltip_id, open)

Set open state from handle_event.

<.action phx-click="show_tip">Show</.action>
<.tooltip id="my-tooltip" class="tooltip">
  <:trigger>Target</:trigger>
  <:content>Hint</:content>
</.tooltip>
def handle_event("show_tip", _, socket) do
  {:noreply, Corex.Tooltip.set_open(socket, "my-tooltip", true)}
end