josefbehr/filament-spatie-media-library-croppie
Installation:
composer require josefbehr/filament-spatie-media-library-croppie
Ensure spatie/laravel-medialibrary and filament/spatie-laravel-media-library-plugin are also installed.
Publish Assets (if not using Filament’s built-in asset handling):
npm run dev # or `npm run build` for production
Include the JS/CSS in your Vite/Mix config (as shown in README).
First Use Case: Add the field to a Filament resource form:
use JosefBehr\FilamentSpatieMediaLibraryCroppie\Fields\SpatieMediaLibraryCroppie;
SpatieMediaLibraryCroppie::make('avatar')
->label('Profile Image')
->imageEditor()
->required(),
SpatieMediaLibraryCroppie (extends Filament’s SpatieMediaLibrary).config/filament-spatie-media-library-croppie.php (if published).resources/dist/js/filament-spatie-media-library-croppie.js (customize via Vite).Basic Image Upload with Cropping:
SpatieMediaLibraryCroppie::make('cover_image')
->imageEditor() // Enables Croppie.js
->directory('covers') // Optional: Custom media directory
->maxFiles(1)
->imageEditorAspectRatio('16:9'), // Lock aspect ratio
Dynamic Boundary Sizing:
Use boundaryWidth/boundaryHeight to control the modal’s cropper dimensions:
SpatieMediaLibraryCroppie::make('thumbnail')
->boundaryWidth('800px')
->boundaryHeight('400px'),
Integration with Existing Media Library:
Leverage Spatie’s convertImage() or generateConversions() for post-upload processing:
// In your model:
public function registerMediaConversions(): void
{
$this->addMediaConversion('thumb')
->width(200)
->height(200);
}
Conditional Field Logic:
Combine with Filament’s visible()/rules():
SpatieMediaLibraryCroppie::make('logo')
->visible(fn ($record) => $record->isPremiumUser())
->rules(['dimensions:min_width=1000,min_height=500']),
Custom Croppie.js Options:
Override defaults via extraImageEditorOptions:
->extraImageEditorOptions([
'viewZoom': 2,
'enableOrientation': true,
]),
Multi-File Uploads:
Use maxFiles() and handle conversions in a saving() hook:
->maxFiles(5)
->saving(function ($record, $state) {
foreach ($state as $media) {
$media->registerMediaConversions();
}
}),
Reusable Field Components: Create a trait or base field for consistency:
trait UsesCroppieImageField
{
protected function configureCroppieField(string $name): SpatieMediaLibraryCroppie
{
return SpatieMediaLibraryCroppie::make($name)
->imageEditor()
->boundaryWidth('100%')
->boundaryHeight('500px');
}
}
Asset Loading Issues:
@vite() in your blade template before </body>:
@vite([
'resources/js/app.js',
'vendor/josefbehr/filament-spatie-media-library-croppie/resources/dist/js/filament-spatie-media-library-croppie.js',
])
CORS/Storage Errors:
[media] disk configuration in .env matches your storage setup. For local testing, use:
MEDIA_DRIVER=local
Aspect Ratio Conflicts:
imageEditorAspectRatio() or disable it (->imageEditor(false)) if using server-side cropping.Filament Version Mismatch:
4xx/5xx responses to /filament-media-library endpoints).saving() hook to debug state:
->saving(function ($record, $state) {
\Log::debug('Uploaded media:', $state);
}),
php artisan view:clear
npm run dev
Custom Croppie Plugins:
Extend Croppie’s functionality by modifying the bundled JS. Override the default file in resources/js/filament-spatie-media-library-croppie.js:
// Add to the existing Croppie initialization:
croppieInstance.bind({
setDragCursor: true,
setZoomCursor: true,
});
Server-Side Cropping:
Use Spatie’s convertImage() in a saved() hook for dynamic resizing:
->saved(function ($record, $state) {
if ($state) {
$record->media()->first()->convertImage('thumb');
}
}),
Localization: Override labels/placeholders via Filament’s translation system:
->label(__('filament-spatie-media-library-croppie::fields.spatie_media_library_croppie.label'))
->placeholder(__('filament-spatie-media-library-croppie::fields.spatie_media_library_croppie.placeholder')),
Testing: Mock the field in PHPUnit using Filament’s testing helpers:
$this->filament()->fillForm([
'spatie_media_library_croppie_field' => UploadedFile::fake()->image('test.jpg'),
]);
How can I help you explore Laravel packages today?