Wirestrap is still in active development
This project is pre-1.0 and may introduce breaking changes at any time without prior notice.
Flyout
Generic floating panel built on @floating-ui/dom. Unlike tooltip and
popover, it carries no semantic meaning, making it suitable for any floating UI: forms,
navigation, previews, or custom content. Position and content stay in sync after
each Livewire morph. Nested flyouts work as expected: a floating element inside
another keeps its parent open.
Basic usage
The default slot is the trigger. Pass the panel content via the content
slot. The default placement is bottom-start and the default trigger is
hover. Set an id whenever you need teleport
or the $wirestrap.flyout magic helper.
<x-wirestrap::flyout>
<button>Jane Smith</button>
<x-slot:content>
Jane Smith
Administrator · jane@example.com
</x-slot:content>
</x-wirestrap::flyout>
Click trigger
Set trigger="click" to toggle the flyout on click instead of hover.
Clicking anywhere outside closes it. The flyout stays open while interacting with
its content: inputs, buttons, and nested floating elements all work as expected.
<x-wirestrap::flyout trigger="click"> ... </x-wirestrap::flyout>
Placement
Accepts top, bottom, left, right,
and their -start/-end variants. Defaults to
bottom-start. Flips automatically if there is not enough room on the
preferred side.
<x-wirestrap::flyout placement="bottom-start"> ... </x-wirestrap::flyout>
<x-wirestrap::flyout placement="bottom-end"> ... </x-wirestrap::flyout>
<x-wirestrap::flyout placement="top-start"> ... </x-wirestrap::flyout>
<x-wirestrap::flyout placement="right"> ... </x-wirestrap::flyout>
Anchor element
By default the flyout 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 flyout should appear near a specific part of it.
<x-wirestrap::flyout>
<div>
<span>Hover me</span>
<span data-ws-anchor></span>
</div>
<x-slot:content> ... </x-slot:content>
</x-wirestrap::flyout>
Clipping
The flyout 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 flyout outside the component's DOM tree entirely to the given selector, via Livewire's@teleportdirective. It escapes all stacking contexts and still usesabsolutepositioning relative to the target, so there is no viewport recalculation on scroll. This is the recommended approach. -
position="fixed"positions the flyout relative to the viewport, which escapes most clipping scenarios but not all. Every scroll event while the flyout is open triggers a viewport recalculation. Preferteleportunless you have a reason to avoid moving the flyout in the DOM.
{{-- Default: absolute positioning --}}
<x-wirestrap::flyout ...> ... </x-wirestrap::flyout>
{{-- Escape most clipping scenarios, at the cost of viewport recalculations --}}
<x-wirestrap::flyout ... position="fixed"> ... </x-wirestrap::flyout>
{{-- Move the flyout outside the DOM tree entirely, escaping all stacking contexts --}}
<x-wirestrap::flyout id="my-flyout" teleport="body"> ... </x-wirestrap::flyout>
External control
Use the $wirestrap.flyout Alpine magic helper to show, hide, or toggle
any flyout by id from anywhere on the page.
<button x-on:click="$wirestrap.flyout.show('action-menu')">Show</button>
<button x-on:click="$wirestrap.flyout.toggle('action-menu')">Toggle</button>
<x-wirestrap::flyout id="action-menu">
<span>Target</span>
<x-slot:content> ... </x-slot:content>
</x-wirestrap::flyout>
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::flyout
| Prop | Type | Default | Description |
|---|---|---|---|
id |
string|null |
null |
Element id. Required when using teleport or the $wirestrap.flyout magic helper. |
content |
ComponentSlot|string |
'' |
Panel content. Slot attributes are forwarded to the flyout panel element. |
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. |
interactive |
bool |
true |
When true, hovering the flyout panel keeps it visible. |
teleport |
string|null |
config |
CSS selector of the element to teleport the flyout into (e.g. body, #app). Avoids overflow clipping and z-index issues. Requires id. |
offset-distance |
int |
config |
Distance between the trigger and the flyout in px. |
offset-skidding |
int |
config |
Lateral offset in px. |
position |
string |
config |
CSS positioning strategy: absolute or fixed. |
|
No results
|
|||
$wirestrap.flyout
| Method | Type | Default | Description |
|---|---|---|---|
$wirestrap.flyout.show(id) |
-- |
-- |
Show the flyout with the given id. |
$wirestrap.flyout.hide(id) |
-- |
-- |
Hide the flyout with the given id. |
$wirestrap.flyout.toggle(id) |
-- |
-- |
Toggle the flyout 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
|
|||