okipa/laravel-form-components
Ready-to-use, fully customizable Laravel form components that generate HTML for you. Livewire compatible, supports Bootstrap 4/5 (TailwindCSS 3 planned). Includes form, input, textarea and more, with model binding and flexible configuration.
Installation:
composer require okipa/laravel-form-components
Publish the config (if needed) via:
php artisan vendor:publish --provider="Okipa\LaravelFormComponents\FormComponentsServiceProvider"
First Use Case:
Replace a basic HTML form with the package’s <x:form::form> component in your Blade view:
<x:form::form method="POST" action="{{ route('posts.store') }}">
<x:form::input name="title" placeholder="Post Title" required />
<x:form::textarea name="content" placeholder="Write your post..." />
<x:form::button.submit>Create Post</x:form::button.submit>
</x:form::form>
Key Starting Points:
<x:form::input>, <x:form::select>, etc.:bind="$property" to sync with Livewire models (e.g., :bind="$user->name").Where to Look First:
Form Binding with Livewire:
<x:form::form wire:submit="save" :bind="$user">
<x:form::input name="email" type="email" />
<x:form::toggle-switch name="active" />
</x:form::form>
:bind to sync form fields with Livewire properties. The package auto-generates wire:model attributes.Dynamic Options:
<x:form::select
name="category"
:options="$categories->pluck('name', 'id')"
caption="Select a category"
/>
:locales="['en', 'fr']" for multilingual apps).Validation Integration:
<x:form::input
name="username"
:errors="$errors->get('username')"
rules="required|min:3|unique:users"
/>
Component Composition:
<x:form::input-group>
<x:form::input name="search" placeholder="Search..." />
<x:form::button.submit class="btn-sm">Search</x:form::button.submit>
</x:form::input-group>
<x:form::input-group>, <x:form::row>, or <x:form::col> for layout control.Customizing Appearance:
resources/views/vendor/okipa/form-components/ to resources/views/vendor/okipa/ and modify templates.<x:form::input class="form-control-lg" ... />).$errors to components for automatic error display:
<x:form::input name="email" :errors="$errors" />
wire:rules alongside package attributes:
<x:form::input
name="age"
wire:rules="required|min:18"
:errors="$errors"
/>
<x:form::button.link> for non-submit actions (e.g., cancel buttons):
<x:form::button.link href="{{ route('posts.index') }}" class="btn-secondary">
Cancel
</x:form::button.link>
Missing name Attribute:
name attribute won’t bind to Livewire or submit data.name="field" (e.g., <x:form::input name="email" />).Bootstrap 4 vs. 5 Class Conflicts:
app.blade.php loads only one Bootstrap version and configure the package via config:
'ui_framework' => 'bootstrap5', // or 'bootstrap4'
Livewire Binding Quirks:
:bind may not work if the Livewire property name differs from the form field name.wire:model explicitly:
<x:form::input name="user_name" wire:model="username" />
File Input Limitations:
label attribute:
<x:form::input type="file" name="avatar" label="Choose an image" />
TailwindCSS Support:
name, wire:model).php artisan config:clear if components render incorrectly after updates.$errors is passed to components or use wire:model for Livewire validation.Custom Components:
Extend the package by creating new Blade components in app/View/Components/Form/:
namespace App\View\Components\Form;
use Okipa\LaravelFormComponents\Components\FormComponent;
class CustomInput extends FormComponent { ... }
Register in AppServiceProvider:
View::addNamespace('form', app_path('View/Components/Form'));
Override Templates:
Copy vendor/okipa/laravel-form-components/resources/views/ to resources/views/vendor/okipa/ and modify as needed.
Add New UI Frameworks: The package’s modular design allows adding support for other CSS frameworks (e.g., Bulma, DaisyUI) by extending the base component classes.
:bind: Excessive binding can bloat Livewire’s state. Use wire:model selectively.<x:form::select name="category" wire:model="category_id">
<option value="">Loading...</option>
</x:form::select>
// Livewire component
public $category_id;
public $categories = [];
public function mount() {
$this->categories = Category::all();
}
How can I help you explore Laravel packages today?