beartropy/ui
Beartropy UI is a small Laravel UI package providing ready-made components and helpers to speed up building admin and front-end screens. Drop in common layouts, forms, and UI utilities to get a consistent look fast with minimal setup.
<x-bt-toast />
<x-bt-toast position="bottom-left" bottom-offset="64px" :max-visible="8" />
Toast → extends BeartropyComponenttoast.blade.php with partials/toast-item.blade.php (shared between mobile/desktop)$store.toasts) manages all toast stateHasToasts traitwindow.$beartropy.toast (from resources/js/modules/toast.js)| Prop | PHP Type | Default | Blade Attribute |
|---|---|---|---|
| position | string |
'top-right' |
position="bottom-left" |
| bottomOffset | string |
'1rem' |
bottom-offset="64px" |
| maxVisible | int |
5 |
:max-visible="8" |
$store.toasts){
items: [], // array of toast objects
add(toast) {}, // add toast, assign ID + defaults
remove(id) {}, // remove by ID
grouped() {}, // group items by position → { pos: [toasts] }
get(id) {}, // find by ID
}
{
id: 'uuid', // auto-generated UUID
type: 'success', // success | error | warning | info
title: 'Title', // required
message: 'Body text', // optional (empty = single-line mode)
single: true, // true when message is empty
duration: 4000, // ms, 0 = sticky
position: 'top-right', // override per-toast
action: 'Undo', // optional action button label
actionUrl: '/restore/123', // optional URL to navigate on action click
}
use Beartropy\Ui\Traits\HasToasts;
// Basic
$this->toast()->success('Title', 'Message', $duration, $position);
$this->toast()->error('Title');
// With action button
$this->toast()->success('Deleted', 'Item removed.', 5000, null, 'Undo', '/restore/123');
Method signature: success(title, message='', duration=4000, position=null, action=null, actionUrl=null)
Dispatches beartropy-add-toast Livewire event with toast payload.
window.$beartropy.toast)window.$beartropy.toast.success('Title', 'Message', duration, position, action, actionUrl);
window.$beartropy.toast('type', 'Title', 'Message', duration, position, action, actionUrl);
Tries Alpine store first, falls back to Livewire dispatch.
section[x-data][role="status"][aria-live="polite"]
├── template x-for (mobile)
│ └── div.md:hidden.fixed.z-[100] ← centered snackbar
│ └── template x-for toast.slice(-3)
│ └── [@include](https://github.com/include) toast-item (variant=mobile)
└── [@foreach](https://github.com/foreach) 4 positions (desktop)
└── div.hidden.md:flex.fixed.z-[100] ← corner-positioned
└── template x-for toast.slice(-maxVisible)
└── [@include](https://github.com/include) toast-item (variant=desktop-left|desktop-right)
partials/toast-item.blade.php)Accepts $variant: mobile, desktop-right, or desktop-left.
| Aspect | Mobile | Desktop-Right | Desktop-Left |
|---|---|---|---|
| Card | rounded-2xl, shadow-lg, backdrop-blur |
rounded-xl, shadow |
rounded-xl, shadow |
| Enter | vertical translate-y-2 |
translate-x-6 |
-translate-x-6 |
| Leave | vertical translate-y-2 |
translate-x-6 |
-translate-x-6 |
| Icon colors | -500 |
-400 |
-400 |
| Progress | h-[2px], -500 |
h-[1px], -400 |
h-[1px], -400 |
<button> with underline styleactionUrl is set, navigates via window.location.hrefslice(-min(maxVisible, 3)) — default 3 visibleslice(-maxVisible) — default 5 visiblewindow.bt_toast_timers global object to track timeouts per toast IDinit(): starts countdown, animates progress bar width from 100% → 0%pause(): freezes timer + progress bar on mouseenterresume(): resumes countdown + animation on mouseleaveduration <= 0) skip timer entirely{{-- Layout: place once --}}
<x-bt-toast />
{{-- Custom position + limit --}}
<x-bt-toast position="bottom-right" :max-visible="3" />
// Simple
$this->toast()->success('Saved!');
// With message
$this->toast()->error('Error', 'Could not save.');
// Sticky
$this->toast()->error('Fatal', 'Contact support.', 0);
// With action
$this->toast()->success('Deleted', 'Removed.', 5000, null, 'Undo', '/restore');
// Custom position
$this->toast()->info('Update', 'New version.', 4000, 'bottom-left');
position — always centered snackbar at bottom[@foreach](https://github.com/foreach) over 4 positions for correct transition directionactionUrl is set, always dismisses toastmaxVisible limits rendered toasts; excess remain in store with running timersdestroy()How can I help you explore Laravel packages today?