husam-tariq/filament-timepicker
Installation:
composer require husam-tariq/filament-timepicker
No additional configuration is required unless you need to customize views.
First Use Case:
Add the TimePickerField to a Filament form resource or page:
use HusamTariq\FilamentTimePicker\Forms\Components\TimePickerField;
TimePickerField::make('event_time')
->label('Event Time')
->required(),
Where to Look First:
Basic Time Selection:
TimePickerField::make('start_time')
->label('Start Time')
->default(now()->format('H:i:s')),
Time Range Selection (e.g., for appointments):
$form->schema([
TimePickerField::make('start_time')->label('Start Time'),
TimePickerField::make('end_time')
->label('End Time')
->afterStateUpdated(fn ($state, callable $set) => $set('min', $state['start_time'])),
]);
Integration with Validation:
TimePickerField::make('deadline')
->label('Deadline')
->rules(['after:now', 'before:23:59:59']),
Dynamic Time Constraints:
Use afterStateUpdated or beforeStateHydrated to enforce logic:
TimePickerField::make('end_time')
->afterStateUpdated(fn ($state, callable $set) => $set('min', now()->format('H:i:s')))
->afterStateUpdated(fn ($state, callable $set) => $set('max', '23:59:59')),
Customizing UI:
php artisan vendor:publish --tag="filament-timepicker-views"
Filament Resources:
Use in create() or edit() methods of Filament resources:
public static function form(Form $form): Form
{
return $form
->schema([
TimePickerField::make('time_slot')->required(),
]);
}
Livewire Components: Works seamlessly with Filament’s Livewire integration. No extra setup needed.
Database Storage:
The field stores time in H:i:s format by default. Ensure your database column matches:
$table->time('time_slot')->nullable();
Localization:
Supports Filament’s localization system. Translate labels via filament.lang config.
Timezone Handling:
TimePickerField::make('time')
->timezone('UTC') // Explicitly set timezone
->default(now('UTC')->format('H:i:s')),
Carbon for conversion:
$time = Carbon::parse($record->time_slot)->timezone('America/New_York');
Validation Quirks:
after:now or before:yesterday may behave unexpectedly with time-only fields. Use explicit formats:
->rules(['after:'.now()->format('H:i:s')]),
View Publishing:
vendor:publish) is optional but required for customizations. Forgetting this may break UI changes.Step Increment:
TimePickerField::make('time')->step(15),
Console Logs: Enable Filament’s debug mode to inspect field state:
Filament::serving(function () {
\Log::debug('TimePicker state:', ['state' => $record->time_slot]);
});
State Hydration:
If beforeStateHydrated isn’t working, ensure the field is properly bound to the model attribute:
TimePickerField::make('time_slot')
->columnSpanFull()
->beforeStateHydrated(fn (set) => $set('time_slot', $record->time_slot ?? '00:00:00')),
Asset Conflicts: If the timepicker UI breaks, check for:
!important overrides).Custom Time Format:
Override the default H:i:s format by extending the field:
class CustomTimePickerField extends TimePickerField
{
protected string $format = 'h:i A';
public static function make(string $name): static
{
return parent::make($name);
}
}
Register it in AppServiceProvider:
Filament::registerFormComponentAs('custom-time-picker', CustomTimePickerField::class);
Event Listeners:
Hook into saving or created events to manipulate time values:
$form->afterStateUpdated(function (array $state, callable $set) {
if (isset($state['time_slot'])) {
$set('time_slot', Carbon::parse($state['time_slot'])->format('H:i:s'));
}
});
Accessibility: Add ARIA labels or keyboard shortcuts by extending the Blade view:
<x-dynamic-component :component="$getFieldWrapperView()" {{ $attributes }}>
<x-filament-timepicker::time-picker
wire:model="{{ $getWireModel() }}"
:min="{{ $getMinTime() }}"
:max="{{ $getMaxTime() }}"
:step="{{ $getStep() }}"
aria-label="{{ $getLabel() }}"
/>
</x-dynamic-component>
How can I help you explore Laravel packages today?