--- title: Customization --- # Customization Extend and customize ArtisanPack UI Forms to fit your needs. ## Publishing Assets Publish package assets for customization: ```bash # Publish everything php artisan vendor:publish --provider="ArtisanPackUI\Forms\FormsServiceProvider" # Publish specific assets php artisan vendor:publish --tag=forms-config php artisan vendor:publish --tag=forms-views php artisan vendor:publish --tag=forms-migrations ``` ## Custom Views ### Publishing Views ```bash php artisan vendor:publish --tag=forms-views ``` Views are published to `resources/views/vendor/forms/`. ### View Structure ``` resources/views/vendor/forms/ ├── livewire/ │ ├── form-builder.blade.php │ ├── form-renderer.blade.php │ ├── forms-list.blade.php │ ├── submission-detail.blade.php │ ├── submissions-list.blade.php │ └── notification-editor.blade.php ├── partials/ │ ├── fields/ │ │ ├── text.blade.php │ │ ├── email.blade.php │ │ ├── textarea.blade.php │ │ └── ... │ ├── progress.blade.php │ └── navigation.blade.php └── emails/ ├── notification.blade.php └── notification-text.blade.php ``` ### Custom Field Templates Create custom field templates: ```blade {{-- resources/views/vendor/forms/partials/fields/text.blade.php --}}
@if ($field->help_text)

{{ $field->help_text }}

@endif @error('formData.' . $field->name)

{{ $message }}

@enderror
``` ## Custom Field Types ### Register a Field Type ```php // In a service provider use function addFilter; public function boot(): void { addFilter('forms.field_types', function ($types) { $types['color-picker'] = [ 'label' => 'Color Picker', 'icon' => 'palette', 'category' => 'advanced', 'view' => 'my-package::fields.color-picker', 'validation' => ['hex_color'], ]; return $types; }); } ``` ### Field View ```blade {{-- resources/views/vendor/forms/partials/fields/color-picker.blade.php --}}
@error('formData.' . $field->name) {{ $message }} @enderror
``` ## Filter Hooks ### Available Filters | Filter | Arguments | Description | |--------|-----------|-------------| | `forms.field_types` | `$types` | Modify available field types | | `forms.validation_rules` | `$rules, $form` | Modify validation rules | | `forms.notification_message` | `$message, $notification, $submission` | Modify notification content | | `forms.webhook_payload` | `$payload, $form, $submission` | Modify webhook data | | `forms.spam_check` | `$isSpam, $form, $data` | Custom spam detection | | `forms.settings_tabs` | `$tabs, $form` | Add admin settings tabs | ### Examples ```php use function addFilter; // Add custom validation addFilter('forms.validation_rules', function ($rules, $form) { if ($form->slug === 'job-application') { $rules['formData.resume'] = 'required|mimes:pdf,doc,docx|max:5120'; } return $rules; }); // Modify notification addFilter('forms.notification_message', function ($message, $notification, $submission) { return $message . "\n\n---\nProcessed by MyApp v" . config('app.version'); }); // Custom spam check addFilter('forms.spam_check', function ($isSpam, $form, $data) { // Block disposable email addresses $email = $data['email'] ?? ''; $disposableDomains = ['tempmail.com', 'throwaway.com']; $domain = substr(strrchr($email, '@'), 1); if (in_array($domain, $disposableDomains)) { return true; } return $isSpam; }); ``` ## Custom Policies ### Override Form Policy ```php // app/Policies/CustomFormPolicy.php namespace App\Policies; use App\Models\User; use ArtisanPackUI\Forms\Models\Form; use ArtisanPackUI\Forms\Policies\FormPolicy; class CustomFormPolicy extends FormPolicy { public function viewAny(User $user): bool { return $user->hasPermission('view-forms'); } public function create(User $user): bool { return $user->hasPermission('create-forms'); } public function update(User $user, Form $form): bool { return $user->hasPermission('edit-forms') || $form->user_id === $user->id; } } ``` ### Register Policy ```php // app/Providers/AuthServiceProvider.php use ArtisanPackUI\Forms\Models\Form; use App\Policies\CustomFormPolicy; protected $policies = [ Form::class => CustomFormPolicy::class, ]; ``` ## Custom Components ### Extend Livewire Components ```php // app/Livewire/CustomFormRenderer.php namespace App\Livewire; use ArtisanPackUI\Forms\Livewire\FormRenderer; class CustomFormRenderer extends FormRenderer { public function submit(): void { // Pre-processing $this->formData['submitted_by'] = auth()->id(); parent::submit(); // Post-processing $this->trackConversion(); } protected function trackConversion(): void { // Analytics tracking } } ``` ### Register Component ```php // app/Providers/AppServiceProvider.php use Livewire\Livewire; use App\Livewire\CustomFormRenderer; public function boot(): void { Livewire::component('custom-form-renderer', CustomFormRenderer::class); } ``` ## Custom Services ### Extend Services ```php // app/Services/CustomSubmissionService.php namespace App\Services; use ArtisanPackUI\Forms\Services\SubmissionService; use ArtisanPackUI\Forms\Models\Form; use ArtisanPackUI\Forms\Models\FormSubmission; class CustomSubmissionService extends SubmissionService { public function create(Form $form, array $data, array $metadata = []): FormSubmission { // Add custom metadata $metadata['processed_at'] = now(); $metadata['processor'] = 'custom'; return parent::create($form, $data, $metadata); } } ``` ### Bind in Container ```php // app/Providers/AppServiceProvider.php use ArtisanPackUI\Forms\Services\SubmissionService; use App\Services\CustomSubmissionService; public function register(): void { $this->app->bind(SubmissionService::class, CustomSubmissionService::class); } ``` ## Custom Admin Routes ### Add Admin Pages ```php // routes/web.php use App\Http\Controllers\FormReportsController; Route::middleware(['web', 'auth']) ->prefix('admin/forms') ->name('forms.') ->group(function () { Route::get('/reports', [FormReportsController::class, 'index']) ->name('reports'); Route::get('/analytics', [FormReportsController::class, 'analytics']) ->name('analytics'); }); ``` ## CSS Customization ### Override Styles ```css /* resources/css/forms.css */ .form-renderer { --form-bg: #ffffff; --form-border: #e5e7eb; --form-error: #ef4444; --form-success: #10b981; } .form-renderer .form-group { margin-bottom: 1.5rem; } .form-renderer input, .form-renderer textarea, .form-renderer select { border: 1px solid var(--form-border); border-radius: 0.375rem; padding: 0.5rem 0.75rem; } .form-renderer .error-message { color: var(--form-error); font-size: 0.875rem; } ``` ## Next Steps - [API Reference](../api/api.md) - Detailed class documentation - [Filter Hooks](../api/events.md) - Event handling - [Configuration](../installation/configuration.md) - All settings