Image Library
This component manages multiple image upload and is powered by Livewire`s file upload, including all features like file size/type validation and automatic storage persistence on local and S3 disks.
If you need to nicely display images see Image Gallery component.
Example
@php $files = $this->files; $library = $this->library; $user = $this->user; @endphp <x-image-library wire:model="files" {{-- Temprary files --}} wire:library="library" {{-- Library metadata property --}} :preview="$library" {{-- Preview control --}} label="Product images" hint="Max 100Kb" />
Setup
First, add Cropper.js and Sortable.js.
<head> ... {{-- Cropper.js --}} <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.6.1/cropper.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.6.1/cropper.min.css" /> {{-- Sortable.js --}} <script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.1/Sortable.min.js"></script></head>
Add a new json
column on your migration files to represent the image library metadata.
// Users table migration$table->json('library')->nullable();
Cast that column as AsCollection
.
// User modelprotected $casts = [ ... 'library' => AsCollection::class,];
Example
The following example considers that you named it as library
and you are editing an existing user.
use Livewire\WithFileUploads;use Mary\Traits\WithMediaSync;use Illuminate\Support\Collection; class extends Component { // Add these Traits use WithFileUploads, WithMediaSync; // Temporary files #[Rule(['files.*' => 'image|max:1024'])] public array $files = []; // Library metadata (optional validation) #[Rule('required')] public Collection $library; // Editing this user public User $user; public function mount(): void { // Load existing library metadata from your model $this->library = $this->user->library; // Or ... an empty collection if this component creates a user // $this->library = new Collection() } public function save(): void { // Your stuff ... // Sync files and updates library metadata $this->syncMedia($this->user); // Or ... first create the user, if this component creates a user // $user = User::create([...]); // $this->syncMedia($user); }}
S3 storage
Make sure to proper configure CDN CORS on your S3 provider, by listing your local and production environment addresses. Otherwise, cropper won't work.
Sync options
If you are using default variable names described on "Setup" and "Example" topics above, you are good to go. Otherwise, here are all options for syncing media on storage.
$this->syncMedia( model: $this->user, // A model that has an image library library: 'library', // The library metadata property on component files: 'files', // Temp files property on component storage_subpath: '', // Sub path on storage. Ex: '/users' model_field: 'library', // The model column that represents the library metadata visibility: 'public' // Visibility on storage disk: 'public' // Storage disk. Also works with 's3');
Labels
Here are all default labels.
<x-image-library ... change-text="Change" crop-text="Crop" remove-text="Remove" crop-title-text="Crop image" crop-cancel-text="Cancel" crop-save-text="Crop" add-files-text="Add images" />
Cropper settings
You can set or override any Cropper.js option.
@php $config = [ 'guides' => false ];@endphp <x-image-library ... :crop-config="$config" />
Once Cropper.js does not offer an easy way to customize its CSS, just inspect browser console to hack the CSS that works best for you. We are using the following on this page.
.cropper-point { width: 10px !important; height: 10px !important;}