Wirestrap is still in active development

This project is pre-1.0 and may introduce breaking changes at any time without prior notice.

Tooltip

Floating tooltip built on @floating-ui/dom. It wraps any trigger element and positions itself relative to it, automatically flipping and shifting to stay within the viewport. Position and content stay in sync after each Livewire morph. Nested tooltips work as expected: a floating element inside another keeps its parent open.

Basic usage

Pass the text as the content prop. The default slot is the trigger. Set an id whenever you need teleport or the $wirestrap.tooltip magic helper.

<x-wirestrap::tooltip content="I'm a tooltip">
    <button>Hover me</button>
</x-wirestrap::tooltip>

Focus behavior

The trigger can wrap any element, including interactive ones. Focusing an input inside the slot keeps the tooltip open.

<x-wirestrap::tooltip>
    <x-wirestrap::input label="Password" password floating />

    <x-slot:content> ... </x-slot:content>
</x-wirestrap::tooltip>

Placement

Accepts top, bottom, left, right, and their -start/-end variants. If there is not enough room on the preferred side, the tooltip flips to the opposite side and shifts to stay visible.

<x-wirestrap::tooltip placement="top" content="Top"> ... </x-wirestrap::tooltip>
<x-wirestrap::tooltip placement="bottom" content="Bottom"> ... </x-wirestrap::tooltip>
<x-wirestrap::tooltip placement="left" content="Left"> ... </x-wirestrap::tooltip>
<x-wirestrap::tooltip placement="right" content="Right"> ... </x-wirestrap::tooltip>

Rich content

Use the content slot instead of the prop when the content contains HTML.

<x-wirestrap::tooltip>
    <span>?</span>

    <x-slot:content>
        <strong>Required.</strong> Must be unique across the workspace.
    </x-slot:content>
</x-wirestrap::tooltip>

Anchor element

By default the tooltip anchors to the trigger wrapper. Add data-ws-anchor to any element inside the slot to use it as the anchor instead, useful when the trigger covers a larger area but the tooltip should appear near a specific part of it.

Hover me
<x-wirestrap::tooltip ... >
    <div>
        <span>Hover me</span>
        <span data-ws-anchor></span>
    </div>
</x-wirestrap::tooltip>

Click trigger

Set trigger="click" to toggle the tooltip on click instead of hover. Clicking anywhere outside closes it.

<x-wirestrap::tooltip ... trigger="click"> ... </x-wirestrap::tooltip>

Clipping

The tooltip uses position: absolute by default, which means it can be clipped by a parent with overflow: hidden or confined to a CSS stacking context. Two escape hatches are available:

  • teleport="body" moves the tooltip outside the component's DOM tree entirely to the given selector, via Livewire's @teleport directive. It escapes all stacking contexts and still uses absolute positioning relative to the target, so there is no viewport recalculation on scroll. This is the recommended approach.
  • position="fixed" positions the tooltip relative to the viewport, which escapes most clipping scenarios but not all. Every scroll event while the tooltip is open triggers a viewport recalculation. Prefer teleport unless you have a reason to avoid moving the tooltip in the DOM.
{{-- Default: absolute positioning --}}
<x-wirestrap::tooltip ...> ... </x-wirestrap::tooltip>

{{-- Escape most clipping scenarios, at the cost of viewport recalculations --}}
<x-wirestrap::tooltip ... position="fixed"> ... </x-wirestrap::tooltip>

{{-- Move the tooltip outside the DOM tree entirely, escaping all stacking contexts --}}
<x-wirestrap::tooltip id="my-tooltip" teleport="body"> ... </x-wirestrap::tooltip>

External control

Use the $wirestrap.tooltip Alpine magic helper to show, hide, or toggle any tooltip by id from anywhere on the page.

Target
<button x-on:click="$wirestrap.tooltip.show('help-tip')">Show</button>
<button x-on:click="$wirestrap.tooltip.toggle('help-tip')">Toggle</button>

<x-wirestrap::tooltip id="help-tip" content="Shown programmatically.">
    <span>Target</span>
</x-wirestrap::tooltip>

Global configuration

Call Wirestrap.floating.configure() once at boot to configure shared behavior across all floating components (flyout, popover, tooltip).

Wirestrap.floating.configure({
    keepShownFor: ['.flatpickr-calendar', '.my-select-panel'],
});

Props

Global configuration

Most prop defaults can be overridden globally via config/wirestrap.php.

x-wirestrap::tooltip

Prop Type Default Description
id string|null null Element id. Required when using teleport or the $wirestrap.tooltip magic helper.
content ComponentSlot|string '' Tooltip text. Use the content slot for HTML content.
placement string config Preferred placement: top, bottom, left, right, and -start/-end variants. Flips automatically if out of bounds.
trigger string config Show trigger: hover or click.
arrow bool true Show the directional arrow.
interactive bool false When true, hovering the tooltip panel keeps it visible.
teleport string|null config CSS selector of the element to teleport the tooltip into (e.g. body, #app). Avoids overflow clipping and z-index issues. Requires id.
offset-distance int config Distance between the trigger and the tooltip in px.
offset-skidding int config Lateral offset in px.
position string config CSS positioning strategy: absolute or fixed.
No results

$wirestrap.tooltip

Method Type Default Description
$wirestrap.tooltip.show(id) -- -- Show the tooltip with the given id.
$wirestrap.tooltip.hide(id) -- -- Hide the tooltip with the given id.
$wirestrap.tooltip.toggle(id) -- -- Toggle the tooltip with the given id.
No results

Wirestrap.floating.configure()

Option Type Default Description
keepShownFor string[] [] CSS selectors whose matching elements are treated as in-scope. Prevents the floating element from closing when interacting with third-party widgets (datepickers, selects…) that teleport their panel outside the floating element.
No results