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-command-palette :items="$items" />
<x-bt-command-palette color="blue" :items="$items" />
<x-bt-command-palette src="palette.json" :allow-guests="true" />
<x-bt-command-palette :items="$items"><button>Open</button></x-bt-command-palette>
CommandPalette extends BeartropyComponent (inherits HasPresets, HasErrorBag)command-palette.blade.php — single template with inline <script> Alpine componentx-teleport="body" with x-cloak$getComponentPresets('command-palette') from presets/command-palette.phpCache::remember() keyed by auth ID + roles/permissions hashpermission (Laravel Gate), roles (Spatie hasAnyRole), admin bypass| Prop | Type | Default | Blade Attribute |
|---|---|---|---|
| color | string|null |
null |
color="blue" |
| items | array|null |
null |
:items="$items" |
| source | string|null |
null |
(legacy, unused) |
| src | string|null |
null |
src="palette.json" |
| allowGuests | bool |
false |
:allow-guests="true" |
| Property | Type | Description |
|---|---|---|
| bt_cp_data | array |
Filtered, permission-stripped items passed to Alpine |
// Each color in presets/command-palette.php has 4 keys:
'blue' => [
'modal_bg' => 'bg-blue-50/80 dark:bg-blue-950/80',
'text' => 'text-blue-900 dark:text-blue-100',
'hover_bg' => 'hover:bg-blue-100/60 dark:hover:bg-blue-800/60',
'selected_bg' => 'bg-blue-500/10 dark:bg-blue-400/20 ring-1 ring-blue-400/30',
],
Available colors: beartropy, neutral, blue, violet, emerald, red, green, yellow, purple, pink, gray, orange, amber, lime, teal, cyan, sky, indigo, rose, fuchsia, slate, stone, zinc.
[
'title' => 'Dashboard', // Display title
'description' => 'Go to dashboard', // Subtitle
'action' => '/dashboard', // Action string
'tags' => ['nav', 'home'], // Searchable/clickable tags
'permission' => 'view-dash', // Spatie permission (string|array, OR logic)
'roles' => 'admin', // Spatie role (string|array, OR logic)
'target' => '_blank', // Link target
]
{
title: 'Dashboard',
description: 'Go to dashboard',
action: '/dashboard',
tags: ['nav', 'home'],
target: '_blank' // or null
}
route:dashboard → Ziggy route() or fallback route map
url:/settings → Navigate to URL
/dashboard → Auto-detected relative URL
https://example.com → Auto-detected absolute URL
dispatch:theme-toggle → Alpine $dispatch()
js:alert('hi') → eval() execution
div[x-data="btCommandPalette"][Cmd+K/Ctrl+K]
├── div[[@click](https://github.com/click)="open = true"] (trigger)
│ ├── slot content (if provided)
│ └── x-beartropy-ui::input (default)
└── template[x-teleport="body"]
└── div.overlay[x-show="open"][x-cloak][role="dialog"]
└── div.panel[modal_bg][[@click](https://github.com/click).outside]
├── div.search-header
│ └── x-beartropy-ui::input[x-model="query"]
└── ul[role="listbox"]
├── template[x-for="filtered"]
│ └── li[role="option"][[@click](https://github.com/click)="execute(item)"]
│ ├── span.title[x-text]
│ ├── div.tags[x-for → span[[@click](https://github.com/click).stop="query = tag"]]
│ └── div.description[x-text]
├── li "No results." (when filtered.length === 0)
└── li "Showing first 5 results" (when !query && length === 5)
{
open: false, // Modal visibility
query: '', // Search input value
all: [], // All items (from bt_cp_data)
selectedIndex: 0, // Keyboard-selected item index
// Computed:
get filtered() // Multi-term search across title/desc/tags/action
// Returns all.slice(0,5) when no query
// Methods:
scrollIntoView() // Scroll selected item into view
handleKey(e) // Arrow/Tab/Enter keyboard handler
execute(item) // Dispatch action by type prefix
}
// In filterByPermissions():
// 1. Guest + !allowGuests → only items without permission/roles
// 2. Guest + allowGuests → all items
// 3. Admin bypass: config('beartropyui.admin_roles') + hasAnyRole → all items
// 4. Normal user: visible if (permission matches via can()) OR (role matches via hasAnyRole())
// 5. Items with neither permission nor roles → always visible
// Cache key format: "bt-cp:{userKey}:v{version}{srcKey}"
// userKey: "{userId}:{md5(roles|perms)}" or "guest"
// version: file mtime (src) or crc32(json_encode(items))
// srcKey: "|src:path" or "|inline"
// TTL: 1 day
{{-- Basic with inline items --}}
<x-bt-command-palette :items="[
['title' => 'Dashboard', 'action' => '/dashboard', 'tags' => ['nav']],
]" />
{{-- Blue color from JSON file --}}
<x-bt-command-palette color="blue" src="palette.json" />
{{-- Custom trigger button --}}
<x-bt-command-palette :items="$items">
<button>Open Palette</button>
</x-bt-command-palette>
{{-- With permission-gated items --}}
<x-bt-command-palette :items="[
['title' => 'Public', 'action' => '/'],
['title' => 'Admin', 'action' => '/admin', 'permission' => 'admin-access'],
['title' => 'Editor', 'action' => '/edit', 'roles' => ['editor', 'admin']],
]" />
{{-- Allow all items for guests --}}
<x-bt-command-palette :items="$items" :allow-guests="true" />
action (not route or url) as the primary action fieldpermission and roles are stripped before sending to client (security)roles key (plural) — matches normalize() output; supports string or arrayconfig('beartropyui.admin_roles') (no hyphen in config namespace)selected_bg from color preset (not hardcoded)x-cloak to prevent flash-of-content on page loadHow can I help you explore Laravel packages today?