beartropy/ui
Beartropy UI is a small Laravel UI package providing ready-made components and helpers to speed up building admin and front-end screens. Drop in common layouts, forms, and UI utilities to get a consistent look fast with minimal setup.
<x-bt-file-dropzone />
FileDropzone → extends BeartropyComponent (no size support, color only)file-dropzone.blade.phpresources/views/presets/file-dropzone.php — 24 colors + primary alias (flat, no variants)support/field-help.blade.php for error and help textbeartropyFileDropzone Alpine data component via resources/js/modules/file-dropzone.js (bundled into beartropy-ui.js)livewire-upload-start/finish/error/progress on .window, property-scopedformatBytes(int): string, getAcceptHint(): string — used in Blade for the auto-generated hint subtext| Prop | PHP Type | Default | Blade Attribute |
|---|---|---|---|
| id | ?string |
auto-generated | id="my-dropzone" |
| name | ?string |
falls back to $id |
name="files" |
| label | ?string |
null |
label="Upload" |
| color | ?string |
'beartropy' (via config) |
color="blue" |
| multiple | bool |
true |
:multiple="false" |
| accept | ?string |
null |
accept="image/*" |
| maxFileSize | ?int |
null |
:max-file-size="5242880" |
| maxFiles | ?int |
null |
:max-files="3" |
| placeholder | ?string |
null (auto from multiple) |
placeholder="Drop here" |
| preview | bool |
true |
:preview="false" |
| clearable | bool |
true |
:clearable="false" |
| disabled | bool |
false |
:disabled="true" |
| customError | mixed |
null |
:custom-error="$error" |
| help | ?string |
null |
help="Help text" |
| hint | ?string |
null |
hint="Hint text" |
| existingFiles | array |
[] |
:existing-files="$files" |
beartropy)primary, beartropy, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose, slate, gray, zinc, neutral, stone
{
files: [], // [{file, id, status, progress, preview}]
existingFiles: [], // [{name, url, size, type, id}]
dragging: false,
uploading: false,
progress: 0,
errors: [], // client-side validation error strings
openPicker(), // clicks hidden file input (respects disabled)
addFiles(e), // from drop/input change, validates, adds to files[]
removeFile(id), // revoke object URL, remove from files[], sync input
removeExisting(id), // remove from existingFiles[], dispatch event
clearFiles(), // revoke all URLs, clear files[], sync input
formatSize(bytes), // human-readable: B, KB, MB, GB
getFileIcon(mimeType), // maps MIME → heroicon name
}
Performed before files are added to state:
| Check | Config Prop | Error Key |
|---|---|---|
| File type | accept |
file_type_not_accepted |
| File size | maxFileSize |
file_too_large |
| File count | maxFiles |
max_files_exceeded |
Error strings use i18n translations passed from PHP. Invalid files are rejected; valid files are added. In single mode (multiple: false), new selection replaces previous.
Listens on .window with property matching to scope events:
| Event | Action |
|---|---|
livewire-upload-start |
uploading = true, progress = 0 |
livewire-upload-finish |
uploading = false, files set to complete |
livewire-upload-error |
uploading = false, files set to error |
livewire-upload-progress |
progress = event.detail.progress |
Property matching: $event.detail?.property === wireModelValue or starts with wireModelValue.
<div> with x-data="beartropyFileDropzone({...})" + Livewire upload event listeners<label> above the dropzone<input type="file"> (sr-only)<x-beartropy-ui::support.field-help> for server errors and help textEach file shows:
preview enabled and file is image type) or file type iconFile type icons: photo (image/), document-text (PDF), film (video/), musical-note (audio/*), document (default)
Pass pre-uploaded files via :existing-files:
<x-bt-file-dropzone
:existing-files="[
['name' => 'report.pdf', 'url' => '/storage/report.pdf', 'size' => 1024, 'type' => 'application/pdf'],
]"
/>
Removing dispatches existing-file-removed Alpine event.
'dropzone' => '...', // base dropzone border/bg/rounded
'dropzone_hover' => '...', // hover state
'dropzone_drag' => '...', // drag-over state (ring, bg change)
'dropzone_error' => '...', // error border
'icon' => '...', // upload icon color
'text' => '...', // placeholder text
'subtext' => '...', // hint subtext
'label' => '...', // label text
'label_error' => '...', // label when error
'file_item' => '...', // file row bg/border
'file_name' => '...', // file name text
'file_size' => '...', // file size text
'progress' => '...', // progress bar fill
'progress_track' => '...', // progress bar track
'remove' => '...', // remove button
'clear_all' => '...', // clear all button
'disabled' => '...', // disabled overlay
{{-- Basic --}}
<x-bt-file-dropzone name="files" label="Upload" />
{{-- Single file --}}
<x-bt-file-dropzone name="avatar" :multiple="false" accept="image/*" />
{{-- With restrictions --}}
<x-bt-file-dropzone name="docs" accept=".pdf,.doc" :max-file-size="5242880" :max-files="3" />
{{-- Custom placeholder --}}
<x-bt-file-dropzone name="photos" placeholder="Drag your photos here!" />
{{-- No preview --}}
<x-bt-file-dropzone name="docs" :preview="false" />
{{-- Not clearable --}}
<x-bt-file-dropzone name="required" :clearable="false" />
{{-- Disabled --}}
<x-bt-file-dropzone name="locked" :disabled="true" />
{{-- Custom error --}}
<x-bt-file-dropzone name="file" :custom-error="'Upload failed.'" />
{{-- With help text --}}
<x-bt-file-dropzone name="file" help="Max 10MB per file." />
{{-- Livewire --}}
<x-bt-file-dropzone wire:model="documents" label="Documents" />
{{-- Color --}}
<x-bt-file-dropzone name="file" color="blue" />
<x-bt-file-dropzone name="file" green />
{{-- Existing files --}}
<x-bt-file-dropzone name="files" :existing-files="$existingFiles" />
{{-- Combined --}}
<x-bt-file-dropzone
label="Upload Documents"
accept=".pdf,.doc,.docx"
:max-file-size="10485760"
:max-files="5"
help="Max 10MB per file."
wire:model="documents"
color="blue"
/>
'file-dropzone' => [
'color' => env('BEARTROPY_UI_FILE_DROPZONE_COLOR', 'beartropy'),
],
<input type="file"> is sr-only; the visible area is a styled div with drag/drop/click/keyboard handlersid auto-generates as beartropy-filedropzone-{uniqid} if not provided; name falls back to idname attribute gets [] suffix automatically in multiple modehelp and hint are aliases; help takes precedence in field-helpaddFiles) before files are added to state — errors are shown inline below the dropzoneURL.createObjectURL) are properly revoked on remove/clear to prevent memory leaksDataTransfer API is used to sync the hidden input's FileList after add/remove (wrapped in try/catch for env compatibility)primary is an alias for beartropy in this component's presetpreview is false, the x-if="f.preview" image template is omitted at compile time (Blade [@if](https://github.com/if))accept matching supports: file extensions (.pdf), MIME wildcards (image/*), exact MIME types (application/pdf)url and type (starting with image/) are present; otherwise a generic document icon is shown[@click](https://github.com/click).stop on the file list prevents re-opening the picker when interacting with file itemsHow can I help you explore Laravel packages today?