← Laracrate 15 / 17

Livewire UI

Livewire UI

Livewire components and themes

Laracrate ships an optional Livewire UI layer. The core (models, storage, pipeline, HTTP endpoints) works without Livewire, so you can ignore this section entirely and build your own front end against the methods in the "Working with files from your models" section. If you do use Livewire, these components wire the model trait, collection config, and upload flow together for you.

The components register only when Livewire is installed (registerLivewireComponents() no-ops otherwise). Each one resolves a Blade theme at render time, so the look is fully swappable.

Minimal example: a single-file uploader for a user avatar.

<livewire:laracrate-uploader :model="$user" collection="avatar" />

The six components

All six are registered in LaracrateServiceProvider with the tag names below. They split into two families: card uploaders (single file, in-place preview) and dropzones (presigned direct upload to R2/S3, see the "Upload modes" and "HTTP endpoints" sections). Each family has an instant variant and a deferred variant. Deferred means selecting a file stages it for review and only persists when the user confirms.

Tag Class Files Behavior Use case
laracrate-uploader LaracrateUploader single Instant: selecting a file calls setFile() immediately Avatar, logo, cover image
laracrate-uploader-deferred LaracrateUploaderDeferred single Deferred: preview, then submit() to persist or cancel() to discard Same as above when you want an explicit confirm step
laracrate-dropzone LaracrateDropzone multiple Instant direct upload per file, fires per-file and batch events Galleries, document libraries
laracrate-dropzone-deferred LaracrateDropzoneDeferred multiple Deferred: queue files, review, then upload the whole batch. Supports file slots and an integrated slot picker Forms where files are tied to slots or categories
laracrate-dropzone-single LaracrateDropzoneSingle single Instant direct upload, one file, in-place preview One large file (a video, a PDF) too big for the card uploader
laracrate-dropzone-single-deferred LaracrateDropzoneSingleDeferred single Deferred single direct upload, in-place preview Same, with an explicit confirm step

The card uploaders (laracrate-uploader, laracrate-uploader-deferred) push the file through Livewire's temporary upload, so the binary passes through PHP. The dropzones upload straight to your disk with a presigned PUT and the binary never touches PHP. Pick the dropzone variants for large files.

Props

Both card uploaders accept the same props:

Prop Type Default Purpose
model Eloquent model required The model the file belongs to (must use the HasFiles trait)
collection string required Collection name as declared on the model
variant string null Variant to show in the preview (falls back to the master, then the collection placeholder)
theme string null Theme name (falls back to laracrate.ui.default_theme)
layout string row row or portrait
rounded string null Override preview rounding: none, sm, md, lg, xl, 2xl, 3xl, full

The dropzone components share model, collection, and theme, plus their own props. Common ones across the dropzones: contextKey (an opaque identifier echoed back in the laracrate-file-uploaded event so you can route a file when several widgets share a page), folderId (target folder, see the "Folders" section), persistQueue, and maxFiles. LaracrateDropzoneDeferred adds slot support (slots, slotOptions, slotLabel, slotPlaceholder, slotOptional, selectedSlotId), a creator override (creator, or creatorType plus creatorId), hideActions, and a layout of grid or list. The single dropzones add hideExisting; the single deferred adds hideActions. See the "File slots" section for slot semantics.

Immediate vs deferred

Instant uploader, persists on selection:

<livewire:laracrate-uploader :model="$user" collection="avatar" theme="ios" variant="medium" />

Deferred uploader, shows a preview and waits for the user to confirm:

<livewire:laracrate-uploader-deferred
    :model="$user"
    collection="avatar"
    theme="studio"
    layout="portrait"
/>

A deferred multi-file dropzone, queue then batch upload:

<livewire:laracrate-dropzone-deferred :model="$organization" collection="gallery" theme="studio" />

All components dispatch browser events you can listen for: laracrate-file-uploaded (per file, with collection, fileId, and contextKey), laracrate-file-deleted or laracrate-file-removed, and on the dropzones laracrate-batch-completed (with ok and error counts). The deferred dropzone also dispatches laracrate-file-rejected when a file is refused by the collection or a slot quota. See the "Events" section for the server-side events fired during processing.

Themes and layouts

There are 11 themes: default, brutalist, material, ios, glassmorphism, neon, minimal, neumorphism, chatgpt, claude, and studio. Each card-uploader theme ships in 2 layouts, row and portrait, as resources/views/uploader/themes/{theme}/{row,portrait}.blade.php. The dropzone families resolve a single Blade per theme (for example dropzone/themes/{theme}.blade.php) and fall back to default when a theme has no matching view.

Set the project-wide default in config (the theme prop overrides it per component):

// config/laracrate.php
'ui' => [
    'default_theme' => env('LARACRATE_THEME', 'default'),
],
LARACRATE_THEME=studio

Customizing views

Publish the package views to override any theme or write a new one:

php artisan vendor:publish --tag=laracrate-views

The views land in resources/views/vendor/laracrate/. Edit a theme in place, or add a new theme by creating uploader/themes/{name}/row.blade.php and uploader/themes/{name}/portrait.blade.php (create matching files under dropzone/themes/, dropzone-single/themes/, etc. if you want the new theme available to those components too). Run php artisan view:clear after editing Blade files. The view contract (the variables each theme receives, such as $config, $file, $state, $previewUrl, $acceptAttr, $maxSizeKb, $pollMs, $roundedClass) is the same for every theme; copy an existing theme as your starting point.

Localization

The UI strings used by the Livewire components are translatable through the laracrate translation namespace, loaded by the service provider via loadTranslationsFrom(__DIR__ . '/../lang', 'laracrate'). The package ships English (lang/en/uploader.php) and Spanish (lang/es/uploader.php) out of the box, and resolves strings against your app's active locale.

Reference a string with the namespaced key:

{{ __('laracrate::uploader.upload') }}

The strings live in the uploader group. A sample of the keys (see the source files for the full list):

Key English Spanish
upload Upload file Subir archivo
select Select file Seleccionar archivo
replace Replace Reemplazar
delete Delete Eliminar
delete_confirm Delete this file? ¿Borrar este archivo?
submit Upload Subir
cancel Cancel Cancelar
uploading Uploading... Subiendo...
processing Processing Procesando
failed Error Error
slot_placeholder Unclassified Sin clasificar
max_size max :size MB máx :size MB

Keys like max_size and max_size_capital take a :size placeholder.

Overriding strings

Publish the translation files into your app, then edit them:

php artisan vendor:publish --tag=laracrate-translations

The files land in lang/vendor/laracrate/{locale}/uploader.php. Any key you define there overrides the package default for that locale; keys you leave out fall back to the package.

Adding a locale

Create lang/vendor/laracrate/{locale}/uploader.php for the new locale (copy en/uploader.php and translate the values, keeping the keys), then set your app locale. For example, to add French, add lang/vendor/laracrate/fr/uploader.php and the components will pick it up when app()->getLocale() returns fr.