schaefersoft/laravel-headless-ui

An accessible slide-out panel built on the native <dialog> element. Supports all four positions, transitions, focus
trapping, and a responsive inline mode for sidebar layouts.
Blade components: x-hui::flyout, x-hui::flyout.background, x-hui::flyout.panel, x-hui::flyout.title,
x-hui::flyout.description
<button data-hui-flyout-trigger="my-flyout">Open</button>
<x-hui::flyout id="my-flyout" position="right">
<x-hui::flyout.background class="bg-black/40"/>
<x-hui::flyout.panel class="w-80 h-full bg-white shadow-xl">
<x-hui::flyout.title>Panel Title</x-hui::flyout.title>
<x-hui::flyout.description>Some description.</x-hui::flyout.description>
<button data-hui-flyout-close>Close</button>
</x-hui::flyout.panel>
</x-hui::flyout>
The position prop controls which edge the panel slides from.
<x-hui::flyout position="right">...</x-hui::flyout> {{-- Slides from right (default) --}}
<x-hui::flyout position="left">...</x-hui::flyout> {{-- Slides from left --}}
<x-hui::flyout position="top">...</x-hui::flyout> {{-- Slides from top --}}
<x-hui::flyout position="bottom">...</x-hui::flyout> {{-- Bottom sheet --}}
The flyout can be closed by:
data-hui-flyout-close element inside the flyoutEscapecloseFlyout('id') from JavaScript
<x-hui::flyout id="locked" :close-on-escape="false" :close-on-backdrop-click="false">
...
</x-hui::flyout>
<x-hui::flyout id="my-flyout" :scroll-lock="true">
...
</x-hui::flyout>
Use the inline prop to specify a breakpoint (in pixels). Above this width, the flyout becomes a static sidebar visible
in the document flow. Below it, the flyout behaves as a slide-out panel opened via trigger.
<div class="flex">
<x-hui::flyout id="sidebar" position="left" :inline="1024">
<x-hui::flyout.panel class="w-64 bg-white border-r">
{{-- Navigation content --}}
</x-hui::flyout.panel>
</x-hui::flyout>
<main class="flex-1">
<button data-hui-flyout-trigger="sidebar" class="lg:hidden">
Open menu
</button>
{{-- Page content --}}
</main>
</div>
In inline mode:
<dialog> becomes display: block; position: staticposition: staticlg:hidden)Flyouts can be nested. Each opens in the browser's top layer, stacking naturally. Escape closes only the topmost flyout, and focus is restored to the previous one.
<x-hui::flyout id="parent-flyout" position="right">
<x-hui::flyout.panel class="w-80 bg-white">
<button data-hui-flyout-trigger="child-flyout">Open nested</button>
</x-hui::flyout.panel>
</x-hui::flyout>
<x-hui::flyout id="child-flyout" position="right">
<x-hui::flyout.panel class="w-64 bg-white">
<button data-hui-flyout-close>Close</button>
</x-hui::flyout.panel>
</x-hui::flyout>
import {openFlyout, closeFlyout} from '../../vendor/schaefersoft/laravel-headless-ui/dist/js/hui.js'
openFlyout('my-flyout')
closeFlyout('my-flyout')
Add transition attributes to the background and/or panel for animated open/close. Use position-appropriate transforms.
<x-hui::flyout id="my-flyout" position="right">
<x-hui::flyout.background class="bg-black/40"
data-hui-flyout-enter="transition duration-200 ease-out"
data-hui-flyout-enter-from="opacity-0"
data-hui-flyout-enter-to="opacity-100"
data-hui-flyout-leave="transition duration-150 ease-in"
data-hui-flyout-leave-from="opacity-100"
data-hui-flyout-leave-to="opacity-0"/>
<x-hui::flyout.panel class="w-80 h-full bg-white"
data-hui-flyout-enter="transition duration-300 ease-out"
data-hui-flyout-enter-from="translate-x-full"
data-hui-flyout-enter-to="translate-x-0"
data-hui-flyout-leave="transition duration-200 ease-in"
data-hui-flyout-leave-from="translate-x-0"
data-hui-flyout-leave-to="translate-x-full">
...
</x-hui::flyout.panel>
</x-hui::flyout>
Suggested transforms per position:
| Position | Enter from | Leave to |
|---|---|---|
right |
translate-x-full |
translate-x-full |
left |
-translate-x-full |
-translate-x-full |
bottom |
translate-y-full |
translate-y-full |
top |
-translate-y-full |
-translate-y-full |
| Event | When |
|---|---|
hui:flyout:open |
Flyout has opened |
hui:flyout:close |
Flyout has closed |
| Prop | Type | Default | Description |
|---|---|---|---|
class |
string |
"" |
Custom classes for the flyout. |
position |
string |
"right" |
Panel position: left, right, top, bottom. |
open |
boolean |
false |
Opens the flyout on page load. |
close-on-escape |
boolean |
true |
Whether Escape closes the flyout. |
close-on-backdrop-click |
boolean |
true |
Whether backdrop click closes the flyout. |
scroll-lock |
boolean |
false |
Locks body scroll while open. |
inline |
int |
null |
Breakpoint (px) above which the flyout is a sidebar. |
| Prop | Type | Default | Description |
|---|---|---|---|
class |
string |
"" |
Custom classes for the panel. |
| Prop | Type | Default | Description |
|---|---|---|---|
class |
string |
"" |
Custom classes for the background. |
| Prop | Type | Default | Description |
|---|---|---|---|
class |
string |
"" |
Custom classes for the title. |
[!NOTE] Renders an
<h2/>. Automatically linked viaaria-labelledby.
| Prop | Type | Default | Description |
|---|---|---|---|
class |
string |
"" |
Custom classes for the description. |
[!NOTE] Renders a
<p/>. Automatically linked viaaria-describedby.
| Key | Action |
|---|---|
Escape |
Close the flyout |
Tab |
Cycle focus within the flyout |
Shift+Tab |
Cycle focus backwards |
<dialog> element with showModal() for modal behavior.aria-labelledby is set automatically from flyout.title.aria-describedby is set automatically from flyout.description.aria-hidden="true".How can I help you explore Laravel packages today?