tapp / blade-uppy
Uppy Blade components for Laravel
Requires
- php: ^7.4|^8.0
- illuminate/contracts: ^8.0|^9.0|^10.0|^11.0
Requires (Dev)
- orchestra/testbench: ^6.0|^7.0|^8.0|^9.0
- pestphp/pest: ^1.23
- phpstan/extension-installer: ^1.1
- phpstan/phpstan-deprecation-rules: ^1.0
- phpstan/phpstan-phpunit: ^1.0
- phpunit/phpunit: ^9.3
- spatie/laravel-ray: ^1.9
- vimeo/psalm: ^4.4
README
This package adds Blade components for Uppy to use in your Laravel Blade views.
Installation
Install the package via Composer
composer require tapp/blade-uppy
Add required JS libraries
Add in your package.json
file the AlpineJS library and all the Uppy libraries you need (or install them directly according to the Uppy site doc):
...
"devDependencies": {
"alpinejs": "^3.11.1",
...
},
"dependencies": {
"@uppy/aws-s3-multipart": "^3.1.2",
"@uppy/core": "^3.0.5",
"@uppy/drag-drop": "^3.0.1",
"@uppy/status-bar": "^3.0.1"
...
}
...
Add the Uppy libraries in your resources/js/bootstrap.js
file:
... require('@uppy/core/dist/style.min.css') require('@uppy/drag-drop/dist/style.min.css') require('@uppy/status-bar/dist/style.min.css') import Uppy from '@uppy/core' import DragDrop from '@uppy/drag-drop' import StatusBar from '@uppy/status-bar' import AwsS3Multipart from '@uppy/aws-s3-multipart' window.Uppy = Uppy window.DragDrop = DragDrop window.StatusBar = StatusBar window.AwsS3Multipart = AwsS3Multipart
Add in your resources/js/app.js
:
... import Alpine from 'alpinejs'; window.Alpine = Alpine; Alpine.start();
Install the JS libraries:
using Mix:
npm install
npm run dev
using Vite:
npm install
npm run build
Publish config file (optional)
Publish the config file with:
php artisan vendor:publish --tag=blade-uppy-config
The published config file contains the Uppy events that are loaded as components:
return [ 'events' => [ 'cancel-all', 'complete', 'dashboard-file-edit-complete', 'dashboard-file-edit-start', 'dashboard-modal-closed', 'dashboard-modal-open', 'error', 'file-added', 'file-editor-cancel', 'file-editor-complete', 'file-editor-start', 'file-removed', 'files-added', 'info-hidden', 'info-visible', 'postprocess-progress', 'preprocces-progress', 'progress', 'reset-progress', 'restriction-failed', 'retry-all', 'thumbnail-generated', 'upload-error', 'upload-progress', 'upload-retry', 'upload-stalled', 'upload-success', 'upload', ], ];
Publish view files (optional)
php artisan vendor:publish --tag=blade-uppy-views
Usage
Uppy uploaders are available as Blade components:
- AWS S3
<x-input.uppy.s3>
- AWS S3 Multipart
<x-input.uppy.s3-multipart>
- XHR
<x-input.uppy.xhr>
- Tus
<x-input.uppy.tus>
- Transloadit
<x-input.uppy.transloadit>
This is the component skeleton (using the s3
blade component as an example, but it's the same for s3-multipart
, xhr
, tus
, and transloadit
):
<x-input.uppy.s3 attribute="attribute value" ... > <!-- here in the component body, you can define the HTML to be used --> </x-input.uppy.s3>
The UI that should be used (dashboard
or drag-drop
) can be defined with the ui
attribute and UI options with uiOptions
attribute:
<x-input.uppy.s3 ui="drag-drop" uiOptions="{ target: '.upload' }" ... >
Any plugin can be added using the plugins
array attribute, where the key is the plugin name and the value is the plugin options:
@php $plugins = [ 'StatusBar' => "{ target: '.upload', hideAfterFinish: false }", ]; @endphp <x-input.uppy.s3 :plugins="$plugins" ... >
Add any event using the events
array attribute, where the key is the event name and the value is the event code:
@php $plugins = [ 'StatusBar' => "{ target: '.upload', hideAfterFinish: false }", ]; @endphp <x-input.uppy.s3 :events="$events" ... >
If you need to add extra JS code, use the extraJs
attribute:
<x-input.uppy.s3 extraJs="your JS code here" ... >
Uploaders
S3
Add the input.uppy.s3
blade component to your blade view:
<x-input.uppy.s3 ui="dashboard" uiOptions="{ inline: true, target: '#uppy-dashboard'}" > <div id="uppy-dashboard"> </div> </x-input.uppy.s3>
S3 Multipart
Add the input.uppy.s3-multipart
blade component to your blade view.
E.g. using the Dashboard UI:
<x-input.uppy.s3-multipart uiOptions="{ inline: true, target: '#uppy-dashboard'}" audio="{ target: Dashboard }" instanceName="file" > <div id="uppy-dashboard"> </div> </x-input.uppy.s3-multipart>
XHR
Add the input.uppy.xhr
blade component to your blade view.
E.g. using the Drag and Drop UI:
@php $events = [ 'upload-success' => " const url = response.uploadURL; const fileName = file.name; const aleatorio = 1; const uploadedFileData = JSON.stringify(response.body); const li = document.createElement('li'); const a = document.createElement('a'); a.href = url; a.target = '_blank'; a.appendChild(document.createTextNode(fileName)); li.appendChild(a); document.querySelector('.upload .uploaded-files ol').appendChild(li); var inputElementUrlUploadFile = document.getElementById('file2'); inputElementUrlUploadFile.value = url; inputElementUrlUploadFile.dispatchEvent(new Event('input')); ", ]; $plugins = [ 'StatusBar' => "{ target: '.upload .for-ProgressBar', hideAfterFinish: false }", ]; @endphp <div class="flex items-center"> <input type="hidden" name="file" id="file" /> <x-input.uppy.xhr ui="drag-drop" uiOptions="{ target: '.upload .for-ProgressBar' }" :events="$events" :plugins="$plugins" > <section class="upload"> <div class="for-DragDrop" x-ref="input"></div> <div class="for-ProgressBar"></div> <div id="progress-bar"></div> <div class="uploaded-files"> <h5>{{ __('Uploaded file:') }}</h5> <ol></ol> </div> </section> </x-input.uppy.xhr> </div>
Tus
Add the input.uppy.tus
blade component to your blade view:
<x-input.uppy.tus uiOptions="{ inline: true, target: '#uppy-dashboard'}" > <div id="uppy-dashboard"> </div> </x-input.uppy.tus>
Transloadit
Add the input.uppy.transloadit
blade component to your blade view:
<x-input.uppy.transloadit uiOptions="{ inline: true, target: '#uppy-dashboard'}" > <div id="uppy-dashboard"> </div> </x-input.uppy.transloadit>
Available attributes for each component:
Uppy instance name
Use the instanceName
attribute to define the Uppy instance name.
Default: uppyUpload
Core Options
Core Uppy options are defined with the coreOptions
attribute.
Default:
{ debug: true, autoProceed: true, allowMultipleUploads: false, }
Uploader Options
Can be defined using uploaderOptions
attribute.
Default:
{ companionUrl: '/', companionHeaders: { 'X-CSRF-TOKEN': window.csrfToken, }, }
User Interface
ui attribute
Define the User Interface (UI) that should be used (Dashboard or Drag&Drop). Possible values:
- dashboard
- drag-drop
E.g.:
ui="dashboard"
Default: dashboard
uiOptions attribute
You may pass the Uppy UI JS options via uiOptions
attribute.
E.g.:
uiOptions="{ target: '.upload .for-ProgressBar' }"
Default: {}
Docs:
Dashboard example:
@php $plugins = [ 'Audio' => "{ target: Dashboard }", ]; @endphp <x-input.uppy.s3-multipart ui="dashboard" uiOptions="{ inline: true, target: '#uppy-dashboard'}" instanceName="file" :plugins="$plugins" > <div id="uppy-dashboard"> </div> </x-input.uppy.s3-multipart>
Drag & Drop example:
@php $plugins = [ 'StatusBar' => "{ target: '.upload .for-ProgressBar', hideAfterFinish: false }", ]; @endphp <x-input.uppy.s3 ui="drag-drop" coreOptions="{ debug: true, autoProceed: true, allowMultipleUploads: false, }" uiOptions="{ target: '.upload .for-ProgressBar' }" :plugins="$plugins" > <section class="upload"> <div class="for-DragDrop" x-ref="input"></div> <div class="for-ProgressBar"></div> <div class="uploaded-files"> <h5>{{ __('Uploaded file:') }}</h5> <ol></ol> </div> </section> </x-input.uppy.s3>
Plugins
User Interface Elements
UI elements can be added using the plugins
attribute associative array, where the key should be the same name as the UI element (E.g. the key for Status Bar
element is StatusBar
) and the value is the JS options to be passed to the UI element.
UI elements Plugins:
- StatusBar
- ProgressBar
- DropTarget
- Informer
- ImageEditor
- ThumbnailGenerator
E.g.:
@php $plugins = [ 'StatusBar' => "{ target: '.upload .for-ProgressBar', hideAfterFinish: false }", ]; @endphp <x-input.uppy.s3-multipart ... :plugins="$plugins" > ...
Sources
Define the sources to be used for upload using the plugins
associative array attribute.
Source Plugins:
- Webcam
- Audio
- ScreenCapture
E.g.:
@php $plugins = [ 'Audio' => "{ target: '#dashboard' }", ]; @endphp <x-input.uppy.s3-multipart ... :plugins="$plugins" > ...
Misc
Another misc plugins can be added using the component's plugins
associative array attribute.
Misc Plugins:
- Golden Retriever
- Compressor
- Locales
- Form
For example to use the GoldenRetriever
(uppy.use(GoldenRetriever, { serviceWorker: false })
) and Compressor
(uppy.use(Compressor, { quality: 0.6 })
) plugins:
@php $plugins = [ 'GoldenRetriever' => "{ serviceWorker: false }", 'Compressor' => "{ quality: 0.6 }", ]; @endphp <x-input.uppy.s3-multipart ... :plugins="$plugins" > ... </x-input.uppy.s3-multipart>
Events
Define the events as a PHP associative array (key is the event name and value is the JS content of the event) passed to events
attribute:
@php $events = [ 'upload-success' => " const url = response.uploadURL; const fileName = file.name; const aleatorio = 1; const uploadedFileData = JSON.stringify(response.body); const li = document.createElement('li'); const a = document.createElement('a'); a.href = url; a.target = '_blank'; a.appendChild(document.createTextNode(fileName)); li.appendChild(a); document.querySelector('.upload .uploaded-files ol').appendChild(li); var inputElementUrlUploadFile = document.getElementById('file2'); inputElementUrlUploadFile.value = url; inputElementUrlUploadFile.dispatchEvent(new Event('input')); ", ]; @endphp <x-input.uppy.s3 ... :events="$events" > ... </x-input.uppy.s3>
Adding extra JS code
You can add some extra JS code using extraJs
attribute.
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
If you discover any security-related issues, please email security@tappnetwork.com.
Credits
Libraries used in this package:
License
The MIT License (MIT). Please see License File for more information.