pushery/wirekit
WireKit is a free, open-source UI component library for Laravel Livewire. Build dashboards and marketing pages with Tailwind CSS v4 and Alpine.js—themeable, accessible, dark-mode aware components for forms, navigation, overlays, layouts, and more.
Installation
composer require pushery/wirekit
Add to your layout:
<head>
@wirekitStyles
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
{{ $slot }}
@wirekitScripts
</body>
Include Blade source path in app.css:
@source '../../vendor/pushery/wirekit/resources/views/**/*.blade.php';
First Component Use a basic form component in a Livewire blade:
<x-wirekit::input
label="Email"
type="email"
name="email"
wire:model="email"
/>
Verify Setup Run the CLI doctor to check for common issues:
php artisan wirekit:doctor
Replace a vanilla Livewire form with WireKit’s pre-styled components:
<x-wirekit::form wire:submit="save">
<x-wirekit::input label="Username" wire:model="username" />
<x-wirekit::button type="submit">Save</x-wirekit::button>
</x-wirekit::form>
Key: Leverage wire:model for Livewire integration while gaining Tailwind-styled UI.
Component Composition Use slots for custom content (e.g., dropdown triggers):
<x-wirekit::dropdown>
<x-slot:trigger>
<x-wirekit::button>Menu</x-wirekit::button>
</x-slot:trigger>
<x-wirekit::dropdown.item>Item 1</x-wirekit::dropdown.item>
</x-wirekit::dropdown>
Livewire Integration
Bind stateful controls with wire:model:
<x-wirekit::slider
label="Volume"
wire:model="volume"
:min="0"
:max="100"
/>
Tip: Use .debounce or .lazy for sliders to avoid excessive Livewire updates.
Theming
Override CSS variables in app.css:
@layer base {
:root {
--color-wk-accent: var(--color-blue-600);
}
}
Dark Mode
WireKit is dark-mode aware by default. Use dark: variants in Tailwind:
<x-wirekit::button class="dark:bg-gray-800">Toggle</x-wirekit::button>
icon="copy"). Configure presets in config/wirekit.php:
'icons' => [
'presets' => ['heroicons', 'lucide'],
],
'charts' => [
'library' => 'apexcharts', // or 'chartjs'
],
<x-wirekit::form> with wire:submit for validation-aware submissions.Event Listeners Listen to component events (e.g., tab changes):
<x-wirekit::tabs x-on:wirekit:tab-changed="$wire.onTabChanged($event.detail.tab)">
<!-- tabs -->
</x-wirekit::tabs>
Livewire Method:
public function onTabChanged($tab) {
$this->activeTab = $tab;
}
Custom Components Extend WireKit’s structure:
<x-wirekit::card>
<x-slot:header>
<h3>Custom Card</h3>
</x-slot:header>
<p>Content here.</p>
</x-wirekit::card>
CLI Introspection Inspect components dynamically:
php artisan wirekit:show dropdown --as=json
Livewire Binding
<x-wirekit::slider>) may trigger excessive Livewire updates if not debounced.wire:model.lazy or wire:model.debounce.500ms.Icon Aliases
config/wirekit.php.Editor Extensions
<x-wirekit::editor>’s extensions prop defaults to [] (not ['StarterKit']).window.tiptapEditor factory handles extensions independently.Dark Mode Contrast
wirekit:doctor:a11y --theme-contrast to audit and exempt decorative borders.Multi-Select Pre-Selection
:value prop on <x-wirekit::multi-select> may not work if passed incorrectly.:value="['php', 'js']").// In a test:
$this->assertWireKitPropWarning('invalid-prop');
php artisan wirekit:doctor to diagnose setup issues.wirekit:export-json to generate machine-readable component schemas.Custom Themes Override CSS variables globally or per-component:
.custom-theme .wk-button {
--color-wk-accent: #ff0000;
}
Slot Overrides
Replace default slots (e.g., <x-slot:trigger> in dropdowns) for full control.
Chart Libraries
Mix chartjs and apexcharts by overriding per-instance:
<x-wirekit::chart library="apexcharts" ...>
Accessibility
Use wirekit:doctor:a11y to audit contrast and keyboard navigation.
<x-wirekit::chart x-data="{ loaded: false }" x-on:load="loaded = true" ...>
<div x-show="loaded">...</div>
</x-wirekit::chart>
wire:model with Alpine for reactive UIs:
<x-wirekit::input
wire:model="search"
x-model="localSearch"
x-on:input="$wire.set('search', $event.target.value)"
/>
How can I help you explore Laravel packages today?