PHPackages                             artflow-studio/uploader - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [File &amp; Storage](/categories/file-storage)
4. /
5. artflow-studio/uploader

ActiveLibrary[File &amp; Storage](/categories/file-storage)

artflow-studio/uploader
=======================

A professional Livewire file uploader with built-in image cropping, progress tracking, and perfect instance isolation.

0.1.0(3mo ago)02MITBladePHP ^8.2

Since Mar 24Pushed 3mo agoCompare

[ Source](https://github.com/rahee554/livewire-uploader)[ Packagist](https://packagist.org/packages/artflow-studio/uploader)[ RSS](/packages/artflow-studio-uploader/feed)WikiDiscussions main Synced 3w ago

READMEChangelogDependencies (2)Versions (2)Used By (0)

ArtFlow Uploader
================

[](#artflow-uploader)

> A production-grade Livewire file uploader with a built-in image editor, progress tracking, and perfect multi-instance isolation.

[![Version](https://camo.githubusercontent.com/3fb4be5dc3c1df885e1ba26b96adcd365a07351f276a4a4370e36a07906260a1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d302e312e302d626c75652e737667)](https://camo.githubusercontent.com/3fb4be5dc3c1df885e1ba26b96adcd365a07351f276a4a4370e36a07906260a1/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d302e312e302d626c75652e737667)[![Laravel](https://camo.githubusercontent.com/2c3c8e91a3f0bca708c77b11d1eeaab0292356b823054f95866653594ff8a1d6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31322532422d7265642e737667)](https://camo.githubusercontent.com/2c3c8e91a3f0bca708c77b11d1eeaab0292356b823054f95866653594ff8a1d6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31322532422d7265642e737667)[![Livewire](https://camo.githubusercontent.com/c775a468968650cb10a85ce4abc5e29b9fe7b905e38a7cae43e0aa8f7ba21dda/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c697665776972652d342e782d707572706c652e737667)](https://camo.githubusercontent.com/c775a468968650cb10a85ce4abc5e29b9fe7b905e38a7cae43e0aa8f7ba21dda/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c697665776972652d342e782d707572706c652e737667)[![PHP](https://camo.githubusercontent.com/0f16581d1180dbfd4c0e13166ec1267d4ad2f2fab8281ea6d6b284cf5c65d921/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322532422d626c75652e737667)](https://camo.githubusercontent.com/0f16581d1180dbfd4c0e13166ec1267d4ad2f2fab8281ea6d6b284cf5c65d921/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322532422d626c75652e737667)[![License](https://camo.githubusercontent.com/8bb50fd2278f18fc326bf71f6e88ca8f884f72f179d3e555e20ed30157190d0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e2e737667)](https://camo.githubusercontent.com/8bb50fd2278f18fc326bf71f6e88ca8f884f72f179d3e555e20ed30157190d0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e2e737667)

---

Features
--------

[](#features)

- **Drop-in Blade component** — one tag, zero configuration required
- **Five layout variants** — `plain`, `squared`, `rect`, `circled`, `inline`
- **Built-in image editor** — crop, zoom, pan, rotate with multi-ratio support (1:1, 16:9, 4:3, free)
- **Circular crop mode** — perfect for profile picture / avatar workflows
- **Instant file preview** — thumbnail for images, file-type icon for documents and videos
- **Circular progress spinner** — live upload percentage display
- **Perfect instance isolation** — any number of uploaders on the same page, no state bleed
- **Tab persistence** — files persist when switching between tabs in a multi-section form
- **Metadata cleanup** — temp uploads and their `.json` metadata files are always cleaned up
- **`wire:navigate` support** — works in Livewire SPA mode
- **Dark mode ready** — CSS variables, works with Tailwind's `dark:` strategy
- **Mobile first** — drag-and-drop, pinch-to-zoom, touch-optimised controls
- **No extra JS dependencies** — Alpine.js (bundled with Livewire) + vanilla JS only

---

Requirements
------------

[](#requirements)

MinimumPHP8.2Laravel11 or 12Livewire4.xAlpine.jsBundled with Livewire 4---

Installation
------------

[](#installation)

### 1. Install

[](#1-install)

```
composer require artflow-studio/uploader
```

### 2. Publish assets

[](#2-publish-assets)

```
php artisan vendor:publish --tag=af-uploader-assets
```

### 3. Add the directive to your layout

[](#3-add-the-directive-to-your-layout)

In your main Blade layout, add `@afUploaderAssets` **after** `@livewireStyles`:

```

       {{-- required --}}

    @livewireStyles
    @afUploaderAssets

    {{ $slot }}
    @livewireScripts

```

---

Quick Start
-----------

[](#quick-start)

### Blade Component

[](#blade-component)

```

```

### Livewire Component

[](#livewire-component)

```
use ArtflowStudio\FileUploader\Traits\WithAFUploader;
use Illuminate\Contracts\View\View;
use Livewire\Component;

class UploadPhoto extends Component
{
    use WithAFUploader;

    public $photo;

    public function save(): void
    {
        $this->validate(['photo' => ['required', 'image', 'max:5120']]);

        $path = $this->storeAFUpload($this->photo, 'photos');
        // Persist $path to your database...
    }

    public function render(): View
    {
        return view('livewire.upload-photo');
    }
}
```

---

Component Props
---------------

[](#component-props)

PropTypeDefaultDescription`wire:model`string**required**Livewire property to bind`accept`string`image/*`MIME type filter (`video/*`, `.pdf,.doc`, etc.)`max-size`int`10`Max file size in **MB**`label`string`Drop file or click`Dropzone placeholder text`variant`string`plain``plain` · `squared` · `rect` · `circled` · `inline``width`string`null`CSS width e.g. `200px`, `100%``height`string`null`CSS height e.g. `180px``cropper`string`false`Enable image editor`ratio`string`null`Crop ratio: `16/9` · `4/3` · `1/1` · `3/2``is-circle`string`false`Circular mask + circular preview`max-width`int`2000`Maximum export width in px`quality`float`0.92`JPEG/WebP output quality (0–1)`target-size`string`null`Target export size e.g. `500KB` — iterative compression`convert`string`null`Force output format: `webp` · `jpeg` · `png``preview`string`true`Show file preview after upload`auto-upload`string`true`Upload immediately on file selection`multiple`bool`false`Allow multi-file selection---

Layout Variants
---------------

[](#layout-variants)

```
{{-- Plain — full-width, uses specified height --}}

{{-- Squared — enforced square aspect ratio --}}

{{-- Rect — 16:9 aspect ratio --}}

{{-- Circled — perfect for profile pictures --}}

{{-- Inline — compact horizontal layout --}}

```

---

Image Cropper
-------------

[](#image-cropper)

```
{{-- Basic crop with 16:9 ratio --}}

{{-- Circular avatar with circle mask --}}

{{-- Free-form crop (no locked ratio) --}}

```

**In-editor controls:** 1:1 · 4:3 · 3:2 · 16:9 · Free · Circle toggle · Rotate left/right · Zoom in/out · Auto-fit

---

File Types
----------

[](#file-types)

```
{{-- Images only (default) --}}

{{-- Video --}}

{{-- Documents --}}

{{-- Any file --}}

```

---

Multiple Instances
------------------

[](#multiple-instances)

Each uploader is fully isolated — you can place as many as needed on a single Livewire component:

```

```

**In loops**, always add `wire:key`:

```
@foreach ($slides as $i => $slide)

@endforeach
```

---

`WithAFUploader` Trait
----------------------

[](#withafuploader-trait)

The trait wraps Livewire's `WithFileUploads` with proper temp-file cleanup.

### `storeAFUpload()`

[](#storeafupload)

```
// Auto-named
$path = $this->storeAFUpload($this->photo, 'photos');

// Custom filename
$path = $this->storeAFUpload($this->photo, 'photos', 'public', 'profile.webp');
```

### Upload hooks

[](#upload-hooks)

```
// Server-side success notification → JS shows "Stored Successfully"
$this->dispatchUploadSuccess('my-uploader-id');

// Server-side error notification → JS shows error message
$this->dispatch('af-upload-error', inputId: 'my-uploader-id', message: 'File rejected');
```

### Removing files

[](#removing-files)

```
// Remove a temporary (not yet stored) upload
$this->revertUpload('photo', $filename);

// Remove a permanently stored file from disk
$this->removeUpload('photo', $storedPath);
```

---

Artisan Commands
----------------

[](#artisan-commands)

```
# Check if published assets are stale vs package source
php artisan af-uploader:update-assets

# Force re-publish
php artisan vendor:publish --tag=af-uploader-assets --force
```

---

Testing
-------

[](#testing)

```
# Run package tests
cd packages/artflow-studio/file-uploader
vendor/bin/phpunit
```

The test suite covers:

- Component rendering
- File upload with Storage fake
- File validation (type, size)
- File removal
- Multi-instance independence
- Asset publishing

---

Customisation
-------------

[](#customisation)

### Override CSS variables

[](#override-css-variables)

In your `app.css`:

```
:root {
    --af-primary:  #your-brand-color;
    --af-radius:   12px;
    --af-bg:       #f8fafc;
}
```

### Publish views

[](#publish-views)

```
php artisan vendor:publish --tag=af-uploader-views
```

Views are published to `resources/views/vendor/af-uploader/`.

---

Troubleshooting
---------------

[](#troubleshooting)

ProblemSolutionAssets not loadingRun `vendor:publish --tag=af-uploader-assets --force`419 CSRF error on uploadAdd `` to ``Multiple uploaders sharing stateEnsure each has a distinct `wire:model` propertyPreview missing after navigateEnsure `wire:model` is not null when the component mountsFile dialog opens automaticallyDo not call `input.click()` in Alpine `init()``livewire-tmp` accumulating filesUse `storeAFUpload()` — it cleans up the `.json` metadata---

Documentation
-------------

[](#documentation)

FileContents[docs/INTEGRATION.md](docs/INTEGRATION.md)Full installation, trait API, props reference[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)Package structure, design decisions, data flow[docs/JAVASCRIPT.md](docs/JAVASCRIPT.md)JS engine modules, Alpine integration, CSS variables[docs/CHANGELOG.md](docs/CHANGELOG.md)Version history and migration notes[docs/AUDIT.md](docs/AUDIT.md)Complete code audit, findings, and recommendations---

License
-------

[](#license)

MIT © ArtFlow Studio

✨ Features
----------

[](#-features)

- 🎨 **Beautiful UI**: Modern glassmorphic design with smooth animations
- 📸 **Instant Preview**: Shows thumbnail and filename immediately
- 📐 **Flexible Layouts**: Plain, Squared, Rect, Circled, and Inline variants
- ✂️ **Built-in Cropper**: Mobile-friendly image editor with multi-ratio support
- ⚡ **Livewire 3/4 Optimized**: Seamless integration with latest Livewire
- 🔒 **Perfect Isolation**: Multiple instances work independently
- 🔄 **Tab Persistence**: Files persist when switching tabs
- 🎯 **Zero Config**: Drop in and it works with `wire:model`
- 📱 **Responsive**: Works on desktop, tablet, and mobile
- 🌙 **Dark Mode Ready**: Built-in dark mode support
- 🚀 **Performance Optimized**: Handles large files efficiently
- ⏱️ **Circular Progress**: Beautiful spinner with upload percentage
- 🛡️ **Error Handling**: Auto-reset on upload failures
- 🔗 **wire:navigate Support**: Works with Livewire SPA navigation

Requirements
------------

[](#requirements-1)

- PHP 8.2+
- Laravel 11+ (tested with Laravel 12)
- Livewire 3.x or 4.x
- Alpine.js (included with Livewire)

Installation
------------

[](#installation-1)

### 1. Install via Composer

[](#1-install-via-composer)

```
composer require artflow-studio/file-uploader
```

### 2. Publish Assets

[](#2-publish-assets-1)

```
php artisan vendor:publish --tag=af-uploader-assets
```

### 3. Add Assets to Layout

[](#3-add-assets-to-layout)

Add the assets directive to your layout (before ``):

```

    @livewireStyles
    @afUploaderAssets

    {{ $slot }}

    @livewireScripts

```

> **Important:** The CSRF meta tag is required for file uploads to work.

Quick Start
-----------

[](#quick-start-1)

### Basic Usage

[](#basic-usage)

```

```

### In Your Livewire Component

[](#in-your-livewire-component)

```
