nasirkhan/laravel-cube
Laravel Cube gives Laravel apps a unified set of reusable Blade UI, form, and navigation components with dual Tailwind CSS or Bootstrap 5 support. Switch frameworks per component or globally, with dark mode, Livewire compatibility, and publishable views.
Installation:
composer require nasirkhan/laravel-cube
Automatically registers the service provider.
Configure Default Framework:
Set CUBE_FRAMEWORK in .env to either tailwind or bootstrap.
Tailwind Setup (if using Tailwind CSS v4): Add to your main CSS file:
@import "../../vendor/nasirkhan/laravel-cube/resources/css/tailwind.css";
First Use Case: Use a basic button in a Blade view:
<x-cube::button variant="primary">Click Me</x-cube::button>
docs/icons.md for available icons and their usage.php artisan vendor:publish --tag=cube-views), inspect resources/views/vendor/cube/components/ for customization.backend.* components (e.g. backend.section-show-table) in the docs — these are aimed at admin/CRUD screens and are a good starting point for dashboard work.Framework Agnostic Components: Use the same Blade component syntax regardless of the underlying CSS framework:
<!-- Uses Tailwind by default -->
<x-cube::button variant="primary">Default</x-cube::button>
<!-- Override per component -->
<x-cube::button framework="bootstrap" variant="primary">Bootstrap</x-cube::button>
Form Handling: Group form inputs with labels, errors, and validation:
<x-cube::group name="email" label="Email" required>
<x-cube::input type="email" name="email" :value="old('email')" required />
<x-cube::error :messages="$errors->get('email')" />
</x-cube::group>
Image Uploads (v4.3.0+):
Use the new image upload component for file inputs with previews. Remember enctype="multipart/form-data" on the form and validate server-side:
<form method="POST" action="{{ route('profile.update') }}" enctype="multipart/form-data">
@csrf
<x-cube::group name="avatar" label="Avatar">
<x-cube::image-upload name="avatar" :value="old('avatar', $user->avatar)" accept="image/*" />
<x-cube::error :messages="$errors->get('avatar')" />
</x-cube::group>
<x-cube::button type="submit" variant="primary">Save</x-cube::button>
</form>
Validate in the controller as usual ('avatar' => ['nullable', 'image', 'max:2048']) and store via $request->file('avatar')->store('avatars').
Backend / Admin Tables (v4.3.0+):
Use the documented backend.section-show-table component to render admin list screens without hand-rolling table markup:
<x-cube::backend.section-show-table :rows="$users" :columns="['name', 'email', 'created_at']" />
Check the new docs for the exact prop contract before adopting it.
Navigation: Use responsive navigation components with active state support:
<x-cube::nav-link href="{{ route('dashboard') }}" :active="request()->routeIs('dashboard')">
Dashboard
</x-cube::nav-link>
Icons: Embed icons with customizable variants and classes:
<x-cube::icon name="bell" variant="solid" class="text-red-500" />
Livewire Integration: Cube components work seamlessly with Livewire. Use them in Livewire views like any other Blade component.
Component-Based Development:
<x-cube::button variant="primary">.Theming:
resources/views/vendor/cube/components/button.blade.php.Dark Mode:
Admin/CRUD Screens:
backend.* components (e.g. backend.section-show-table) instead of writing bespoke table markup; wrap them with your own controller/pagination logic.Progressive Adoption:
Tailwind CSS:
content configuration includes Cube’s views:
content: [
'./resources/views/**/*.blade.php',
'./vendor/nasirkhan/laravel-cube/resources/views/**/*.blade.php',
],
bg-blue-500 for buttons) directly in Blade.Bootstrap 5:
btn-primary).Livewire:
<x-cube::button wire:click="save" :loading="$processing">
Save
</x-cube::button>
wire:model on the image upload component with TemporaryUploadedFile handling rather than mixing a standard POST form.File Uploads:
Storage facade and File::image() validation rules; keep the component focused on markup only.Customization:
<!-- resources/views/vendor/cube/components/button.blade.php -->
@props(['customProp' => false])
<button {{ $attributes }}>
@if($customProp)
Custom Button
@else
{{ $slot }}
@endif
</button>
Tailwind CSS Setup:
@import "../../vendor/nasirkhan/laravel-cube/resources/css/tailwind.css") can break Tailwind-based components.Framework Mismatch:
bg-blue-500) in a Bootstrap component or vice versa.<x-cube::button framework="tailwind" class="bg-blue-500">Tailwind Button</x-cube::button>
Missing Form Enctype for Image Uploads:
<form> lacks enctype="multipart/form-data".upload_max_filesize / post_max_size in php.ini are adequate for real-world images.Backend Component Documentation Lag:
backend.* components (like backend.section-show-table) shipped with docs in v4.3.0 but have less field mileage than core components; prop names may shift in minor releases."nasirkhan/laravel-cube": "4.3.*") while adopting them, and publish views so you can diff against upstream changes.Icon Availability:
docs/icons.md for the full list of available icons.Published Views Overwrite:
mergeConfigPath in config/cube.php to preserve customizations.Livewire Conflicts:
wire: directives may conflict if not properly scoped.Component Not Rendering:
<x-cube::button>), including dotted backend namespaces (<x-cube::backend.section-show-table>).Styles Not Applying:
@import is in your CSS and Tailwind is scanning Cube’s views.Uploads Silently Failing:
filesystems.php defaults. Inspect the actual UploadedFile in the controller with dd($request->file('avatar')).Dark Mode Issues:
darkMode: 'class',
dark: variants to Cube’s published views if needed.Component Props:
php artisan vendor:publish --tag=cube-config to inspect available props for each component in config/cube.php.Dark Mode:
dark: classes to published views:
<button class="bg-blue-500 dark:bg-blue-700">
Performance:
Testing:
$this->blade('<x-cube::button>Test</x-cube::button>')->assertSee('button');
UploadedFile::fake()->image('avatar.jpg') and assert storage with Storage::assertExists().Custom Icons:
resources/views/vendor/cube/icons/.Framework-Specific Logic:
@if to conditionally render framework-specific markup:
@if($framework === 'tailwind')
<div class="p-4 bg-gray-100">
@else
<div class="p-4 bg-light">
@endif
Configuration:
config/cube.php:
'defaults' => [
'framework' => 'tailwind',
'button' => [
'size' => 'md',
],
],
Companion Packages:
nasirkhan/laravel-sharekit for social sharing without bloating Cube:
<x-sharekit::buttons :url="$post->url" />
How can I help you explore Laravel packages today?