Components

OffCanvas

Basics

The Offcanvas component allows you to create side panels. You can create an Offcanvas using the static method make().

make(
Closure|string $title = '',
Closure|Renderable|string $content = '',
Closure|string $toggler = '',
Closure|string|null $asyncUrl = null,
iterable $components = [],
)
make(
Closure|string $title = '',
Closure|Renderable|string $content = '',
Closure|string $toggler = '',
Closure|string|null $asyncUrl = null,
iterable $components = [],
)
  • $title - the title of the side panel,
  • $content - the content of the side panel,
  • $toggler - the title for the button,
  • $asyncUrl - the URL for asynchronous content,
  • $components - components
 namespaces
use MoonShine\UI\Components\OffCanvas;
 
OffCanvas::make(
'Confirm',
static fn() => FormBuilder::make(route('password.confirm'))
->async()
->fields([
Password::make('Password')->eye(),
])
->submit('Confirm'),
'Show Panel'
)
 namespaces
use MoonShine\UI\Components\OffCanvas;
 
OffCanvas::make(
'Confirm',
static fn() => FormBuilder::make(route('password.confirm'))
->async()
->fields([
Password::make('Password')->eye(),
])
->submit('Confirm'),
'Show Panel'
)
<x-moonshine::off-canvas
title="Offcanvas"
:left="false"
>
<x-slot:toggler>
Open
</x-slot:toggler>
Content
</x-moonshine::off-canvas>
<x-moonshine::off-canvas
title="Offcanvas"
:left="false"
>
<x-slot:toggler>
Open
</x-slot:toggler>
Content
</x-moonshine::off-canvas>

The content parameter refers to the textual content of OffCanvas. It's suitable for displaying simple information (strings, HTML, etc.). However, if you want to embed components into OffCanvas — such as fields or forms that respond to value changes or rely on reactivity — it’s important to understand that MoonShine won’t be able to “see” components passed as plain strings. This limits functionality. To ensure MoonShine properly handles fields inside OffCanvas, you should pass them using the components parameter.

If you're building the content of OffCanvas entirely with MoonShine components (fields, forms, etc.), use the components parameter instead of content.

Events

You can trigger the opening/closing of the sidebar from outside the component via javascript events. To access the events, you need to set a unique name for the side panel using the name() method.

protected function components(): iterable
{
return [
Offcanvas::make(
'Title',
'Content...'
)
->name('my-canvas')
];
}
protected function components(): iterable
{
return [
Offcanvas::make(
'Title',
'Content...'
)
->name('my-canvas')
];
}

Triggering Event via ActionButton

The side panel event can be triggered using the ActionButton component.

Offcanvas::make(
'Title',
'Content...',
)
->name('my-canvas'),
 
ActionButton::make('Show Modal')
->toggleOffCanvas('my-canvas')
 
// or async
ActionButton::make(
'Show Panel',
'/endpoint'
)
->async(events: [AlpineJs::event(JsEvent::OFF_CANVAS_TOGGLED, 'my-canvas')])
Offcanvas::make(
'Title',
'Content...',
)
->name('my-canvas'),
 
ActionButton::make('Show Modal')
->toggleOffCanvas('my-canvas')
 
// or async
ActionButton::make(
'Show Panel',
'/endpoint'
)
->async(events: [AlpineJs::event(JsEvent::OFF_CANVAS_TOGGLED, 'my-canvas')])

Triggering Event Using Native Methods

Events can be triggered using native JavaScript methods:

document.addEventListener("DOMContentLoaded", () => {
this.dispatchEvent(new CustomEvent("off_canvas_toggled:my-canvas"))
})
document.addEventListener("DOMContentLoaded", () => {
this.dispatchEvent(new CustomEvent("off_canvas_toggled:my-canvas"))
})

Triggering Event Using Alpine.js Method

Or use the magic method $dispatch() from Alpine.js:

this.$dispatch('off_canvas_toggled:my-canvas')
this.$dispatch('off_canvas_toggled:my-canvas')

Triggering Event Using Global MoonShine Class

MoonShine.ui.toggleOffCanvas('my-canvas')
MoonShine.ui.toggleOffCanvas('my-canvas')

More detailed information can be found in the official Alpine.js documentation in the sections Events and $dispatch.

Events when opening/closing

You can also add events when opening/closing the side panel using the toggleEvents() method.

toggleEvents(
array $events,
bool $onlyOpening = false,
bool $onlyClosing = false
)
toggleEvents(
array $events,
bool $onlyOpening = false,
bool $onlyClosing = false
)
  • $events - events,
  • $onlyOpening - will only fire when opening,
  • $onlyClosing - will only fire when closing.
ActionButton::make('Open off-canvas')
->toggleOffCanvas('my-off-canvas'),
 
OffCanvas::make('My OffCanvas', asyncUrl: '/')
->name('my-off-canvas')
->toggleEvents([
AlpineJs::event(
JsEvent::TOAST,
params: ['text' => 'Hello off-canvas']
)
]),
ActionButton::make('Open off-canvas')
->toggleOffCanvas('my-off-canvas'),
 
OffCanvas::make('My OffCanvas', asyncUrl: '/')
->name('my-off-canvas')
->toggleEvents([
AlpineJs::event(
JsEvent::TOAST,
params: ['text' => 'Hello off-canvas']
)
]),

Default State

The open() method allows you to show the side panel on page load.

open(Closure|bool|null $condition = null)
open(Closure|bool|null $condition = null)
OffCanvas::make('Title', 'Content...', 'Show Panel')
->open()
OffCanvas::make('Title', 'Content...', 'Show Panel')
->open()

By default, the side panel will be hidden on page load.

Position

By default, the side panel is positioned on the right side of the screen; the left() method allows you to position the panel on the left side.

left(Closure|bool|null $condition = null)
left(Closure|bool|null $condition = null)
OffCanvas::make('Title', 'Content...', 'Show Panel')
->left()
OffCanvas::make('Title', 'Content...', 'Show Panel')
->left()

Width

The wide() method of the OffCanvas component allows you to make the panel wider.

wide(Closure|bool|null $condition = null)
wide(Closure|bool|null $condition = null)
  • $condition - method execution condition.
OffCanvas::make('Title', 'Content...', 'Show Panel')
->wide()
OffCanvas::make('Title', 'Content...', 'Show Panel')
->wide()

The full() method sets the maximum width for the panel.

full(Closure|bool|null $condition = null)
full(Closure|bool|null $condition = null)
  • $condition - method execution condition.
OffCanvas::make('Title', 'Content...', 'Show Panel')
->full()
OffCanvas::make('Title', 'Content...', 'Show Panel')
->full()

Asynchronous

OffCanvas::make('Title', '', 'Show Panel', asyncUrl: '/endpoint'),
OffCanvas::make('Title', '', 'Show Panel', asyncUrl: '/endpoint'),

The request will be sent only once, but if you need to send the request each time it opens, use the alwaysLoad() method.

OffCanvas::make(...)
->alwaysLoad(),
OffCanvas::make(...)
->alwaysLoad(),

Auto Close

By default, OffCanvas closes after the asynchronous form inside it has been successfully submitted. The autoClose() method allows you to control this behavior.

autoClose(Closure|bool|null $autoClose = null)
autoClose(Closure|bool|null $autoClose = null)
OffCanvas::make(
'Demo OffCanvas',
static fn() => FormBuilder::make(route('alert.post'))
->fields([
Text::make('Text'),
])
->submit('Submit', ['class' => 'btn-primary'])
->async(),
)
->name('demo-offcanvas')
->autoClose(false),
OffCanvas::make(
'Demo OffCanvas',
static fn() => FormBuilder::make(route('alert.post'))
->fields([
Text::make('Text'),
])
->submit('Submit', ['class' => 'btn-primary'])
->async(),
)
->name('demo-offcanvas')
->autoClose(false),

Auto Close

By default, off-canvas panels close after a successful request (for example, when submitting a form). The autoClose() method allows you to control this behavior.

autoClose(Closure|bool|null $autoClose = null)
autoClose(Closure|bool|null $autoClose = null)
OffCanvas::make(
'Title',
static fn() => FormBuilder::make(route('endpoint'))
->fields([
Text::make('Text'),
])
->submit('Submit', ['class' => 'btn-primary'])
->async(),
'Show Panel'
)
->autoClose(false),
OffCanvas::make(
'Title',
static fn() => FormBuilder::make(route('endpoint'))
->fields([
Text::make('Text'),
])
->submit('Submit', ['class' => 'btn-primary'])
->async(),
'Show Panel'
)
->autoClose(false),

Toggler Attributes

The togglerAttributes() method allows you to set additional attributes for the toggler $toggler.

togglerAttributes(array $attributes)
togglerAttributes(array $attributes)
OffCanvas::make('Title', 'Content...', 'Show Panel')
->togglerAttributes([
'class' => 'mt-2'
]),
OffCanvas::make('Title', 'Content...', 'Show Panel')
->togglerAttributes([
'class' => 'mt-2'
]),