{"id":30714294,"url":"https://github.com/codebyray/livewire-media-uploader","last_synced_at":"2026-04-12T17:52:07.262Z","repository":{"id":312503220,"uuid":"1047706919","full_name":"codebyray/livewire-media-uploader","owner":"codebyray","description":"Drop-in Livewire media uploader for Laravel with Spatie Media Library: drag-and-drop, presets, metadata, duplicate handling, and a publishable Blade view.","archived":false,"fork":false,"pushed_at":"2025-08-31T04:48:46.000Z","size":31,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-31T05:44:03.821Z","etag":null,"topics":["alpinejs","component","file-uploads","laravel","livewire","media-library","spatie","spatie-laravel-medialibrary","tailwindcss","uploader"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/codebyray.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-31T03:19:22.000Z","updated_at":"2025-08-31T04:45:49.000Z","dependencies_parsed_at":"2025-08-31T05:44:06.845Z","dependency_job_id":"a4e30ed7-9054-4999-b367-a5e168ef3deb","html_url":"https://github.com/codebyray/livewire-media-uploader","commit_stats":null,"previous_names":["codebyray/livewire-media-uploader"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/codebyray/livewire-media-uploader","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codebyray%2Flivewire-media-uploader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codebyray%2Flivewire-media-uploader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codebyray%2Flivewire-media-uploader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codebyray%2Flivewire-media-uploader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codebyray","download_url":"https://codeload.github.com/codebyray/livewire-media-uploader/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codebyray%2Flivewire-media-uploader/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273392298,"owners_count":25097259,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-03T02:00:09.631Z","response_time":76,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alpinejs","component","file-uploads","laravel","livewire","media-library","spatie","spatie-laravel-medialibrary","tailwindcss","uploader"],"created_at":"2025-09-03T05:00:46.627Z","updated_at":"2026-04-12T17:52:07.228Z","avatar_url":"https://github.com/codebyray.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg width=\"2655\" height=\"1419\" alt=\"media_uploader_screenshot\" src=\"https://github.com/user-attachments/assets/0852d2c2-762a-440c-ad61-8c0b6939f930\" /\u003e\n\n# Livewire Media Uploader\n\nLivewire Media Uploader is a reusable Livewire v3 component that integrates seamlessly with Spatie Laravel Media Library. It ships a clean Tailwind Blade view by default (fully publishable), Bootstrap theme as an option, Alpine overlays for previews/confirmations, drag-and-drop uploads, per-file metadata (caption/description/order), configurable presets, name-conflict strategies, and optional SHA-256 duplicate detection. Drop it in, point it at a model, and you’re shipping in minutes.\n\n---\n\n## Table of Contents\n\n- [Features](#features)\n- [Requirements](#requirements)\n- [Installation](#installation)\n- [Publishing Assets](#publishing-assets)\n- [Theme System](#theme-system-tailwind--bootstrap--custom)\n  - [Dark Mode - Tailwind](#dark-mode-tailwind-theme)\n  - [Custom Theme](#custom-themes)\n- [Quick Start](#quick-start)\n- [Usage Examples](#usage-examples)\n  - [Create flow (deferred uploads)](#create-flow-deferred-uploads)\n- [Configuration](#configuration)\n- [Props](#props)\n- [Events](#events)\n- [Model Setup (Spatie Media Library)](#model-setup-spatie-media-library)\n- [Overlays \u0026 UX Notes](#overlays--ux-notes)\n- [Troubleshooting](#troubleshooting)\n- [Roadmap](#roadmap)\n- [License](#license)\n\n---\n\n## Features\n\n- ✅ Livewire v3 component with themeable Blade UI\n  - Tailwind (default)\n  - Bootstrap (optional)\n  - Fully publishable and overridable\n- ✅ Spatie Media Library integration (attach, list, edit meta, delete)\n- ✅ **Publishable view** for per-project customization\n- ✅ Drag \u0026 drop uploads + progress bar\n- ✅ Inline edit of **caption / description / order**\n- ✅ Name-conflict strategies: **rename | replace | skip | allow**\n- ✅ Optional **exact duplicate** detection via SHA-256\n- ✅ Collection → preset mapping (auto `accept` attribute)\n- ✅ Image preview **overlay** + delete confirmation **modal**\n- ✅ Works with:\n    - Saved model instance (`:for=\"$model\"`)\n    - String model + id (`model=\"user\" :id=\"1\"`)\n    - FQCN, morph map alias, or dotted paths with custom namespaces\n    - Local alias map\n\n---\n\n## Requirements\n\n- PHP **8.1+**\n- Laravel **10.x | 11.x | 12.x**\n- Livewire **^3.0**\n- spatie/laravel-medialibrary **^10.12**\n- TailwindCSS (optional but recommended for the default view)\n- Alpine.js (used by overlays/progress; see [Overlays \u0026 UX Notes](#overlays--ux-notes))\n- CSS depending on theme:\n  - Tailwind theme → TailwindCSS (recommended)\n  - Bootstrap theme → Bootstrap CSS (no Bootstrap JS required; Alpine drives modals)\n\n---\n\n## Installation\n\n```bash\ncomposer require codebyray/livewire-media-uploader\n```\n\nAuto-discovery will register the service provider. If you disable discovery, add:\n\n```php\n// config/app.php\n'providers' =\u003e [\n    // ...\n    Codebyray\\LivewireMediaUploader\\MediaUploaderServiceProvider::class,\n],\n```\n\nThe component is registered under **both** aliases:\n\n- `\u003clivewire:media-uploader ... /\u003e`\n- `\u003clivewire:media.media-uploader ... /\u003e`\n\n---\n\n## Publishing Assets\n\n### Config:\n```bash\nphp artisan vendor:publish --tag=media-uploader-config\n```\n\n### Views:\n```bash\nphp artisan vendor:publish --tag=media-uploader-views\n```\n\nAfter publishing, customize the Blade at:\n```html\nresources/views/vendor/media-uploader/themes/tailwind/media-uploader.blade.php\nresources/views/vendor/media-uploader/themes/bootstrap/media-uploader.blade.php\n```\n## Theme System (Tailwind + Bootstrap + custom)\nSelect the theme in config/media-uploader.php:\n```php\n// config/media-uploader.php\nreturn [\n    'theme'  =\u003e 'tailwind', // 'tailwind' (default) or 'bootstrap'\n    'themes' =\u003e [\n        'tailwind'  =\u003e 'media-uploader::themes.tailwind.media-uploader',\n        'bootstrap' =\u003e 'media-uploader::themes.bootstrap.media-uploader',\n    ],\n    // ...\n];\n```\n### Dark mode (Tailwind theme)\nThis package’s Tailwind theme is dark-ready. Add this tiny snippet in your main layout `\u003chead\u003e` to apply the user’s saved choice / system default:\n\n```html\n\u003cscript\u003e\n    (() =\u003e {\n        const t = localStorage.theme ?? 'system';\n        const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;\n        const dark = t === 'dark' || (t === 'system' \u0026\u0026 prefersDark);\n        if (dark) document.documentElement.classList.add('dark');\n    })();\n\u003c/script\u003e\n```\n### Custom themes\n- Copy an existing theme directory (e.g. themes/tailwind) to themes/custom and edit the Blade.\n- Register it in the map and select it:\n    ```php\n    'theme'  =\u003e 'custom',\n    'themes' =\u003e [\n        'tailwind'  =\u003e 'media-uploader::themes.tailwind.media-uploader',\n        'bootstrap' =\u003e 'media-uploader::themes.bootstrap.media-uploader',\n        'custom'    =\u003e 'media-uploader::themes.custom.media-uploader',\n    ],\n    ```\n  \u003e Note: The component’s Livewire + Alpine behavior is identical across themes. Only classes/markup differ. If you use the Bootstrap theme, make sure your layout includes Bootstrap CSS.\n## Environment variables (optional)\nYou can override preset limits and accepted types/mimes via .env. These map directly to config/media-uploader.php:\n\n```dotenv\n# Livewire Media Uploader (optional)\n\n# Images\nMEDIA_TYPES_IMAGES=jpg,jpeg,png,webp,avif,gif\nMEDIA_MIMES_IMAGES=image/jpeg,image/png,image/webp,image/avif,image/gif\nMEDIA_MAXKB_IMAGES=10240\n\n# Documents\nMEDIA_TYPES_DOCS=pdf,doc,docx,xls,xlsx,ppt,pptx,txt\nMEDIA_MIMES_DOCS=application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml.presentation,text/plain\nMEDIA_MAXKB_DOCS=20480\n\n# Videos\nMEDIA_TYPES_VIDEOS=mp4,mov,webm\nMEDIA_MIMES_VIDEOS=video/mp4,video/quicktime,video/webm\nMEDIA_MAXKB_VIDEOS=102400\n\n# Fallback preset\nMEDIA_TYPES_DEFAULT=jpg,jpeg,png,webp,avif,gif,pdf,doc,docx,xls,xlsx,ppt,pptx,txt\nMEDIA_MIMES_DEFAULT=image/jpeg,image/png,image/webp,image/avif,image/gif,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml.presentation,text/plain\nMEDIA_MAXKB_DEFAULT=10240\n```\n\n### Notes\n- Values are comma-separated; spaces are OK (the package trims them).\n- After changing .env, run:\n```bash\n- php artisan config:clear\n# (or) php artisan config:cache\n```\n- The `````\u003cinput accept=\"…\"\u003e````` attribute is auto-filled from the active preset when accept_from_config is true (default). You can still override it per-component with the accept prop.\n- If uploads fail due to size, make sure your PHP/Server limits also allow it (e.g. upload_max_filesize, post_max_size).\n\n---\n\n## Quick Start\n\n1) Ensure your target Eloquent model implements `Spatie\\MediaLibrary\\HasMedia` and is **saved**.\n\n    #### Model Setup (Spatie Media Library)\n    \n    Your model must implement `HasMedia` and be **saved** before attaching media.\n    \n    ```php\n    use Spatie\\MediaLibrary\\HasMedia;\n    use Spatie\\MediaLibrary\\InteractsWithMedia;\n    use Spatie\\MediaLibrary\\MediaCollections\\Models\\Media;\n    \n    class Post extends Model implements HasMedia\n    {\n        use InteractsWithMedia;\n    \n        public function registerMediaCollections(): void\n        {\n            $this-\u003eaddMediaCollection('photos')        // matches collection=\"photos\"\n                -\u003euseDisk('public')                    // or 's3'\n                -\u003ewithResponsiveImages();             // optional\n    \n            // If you also have avatars somewhere:\n            $this-\u003eaddMediaCollection('avatars')-\u003esingleFile();\n        }\n    \n        public function registerMediaConversions(Media $media = null): void\n        {\n            $this-\u003eaddMediaConversion('thumb')\n                -\u003efit('contain', 256, 256)\n                -\u003eperformOnCollections('photos', 'avatars') // scope to specific collections\n                -\u003enonQueued();\n        }\n    }\n    ```\n2) Include Livewire \u0026 Alpine (usually in your app layout):\n\n    ```html\n    @livewireStyles\n    \u003cstyle\u003e[x-cloak]{ display:none !important; }\u003c/style\u003e\n    @livewireScripts\n    ```\n\n3) Drop the component into your Blade:\n\n    ```html\n    \u003clivewire:media-uploader :for=\"$user\" collection=\"avatars\" preset=\"images\" /\u003e\n    ```\n\n---\n\n## Usage Examples\n\n1) Pass a saved model instance\n    ```html\n    \u003clivewire:media-uploader :for=\"$user\" collection=\"avatars\" preset=\"images\" /\u003e\n    ```\n\n2) Short string model + id\n    ```html\n    \u003clivewire:media-uploader model=\"user\" :id=\"$user-\u003eid\" collection=\"images\" preset=\"images\" /\u003e\n    ```\n\n3) Morph map alias**\n    ```html\n    \u003clivewire:media-uploader model=\"users\" :id=\"$user-\u003eid\" collection=\"profile\" preset=\"images\" /\u003e\n    ```\n\n4) FQCN\n    ```html\n    \u003clivewire:media-uploader model=\"\\App\\Models\\User\" :id=\"$user-\u003eid\" collection=\"documents\" /\u003e\n    ```\n\n5) Dotted path + custom namespaces\n    ```html\n    \u003clivewire:media-uploader\n        model=\"crm.contact\"\n        :id=\"$contactId\"\n        :namespaces=\"['App\\\\Domain\\\\Crm\\\\Models', 'App\\\\Models']\"\n        collection=\"images\"\n        preset=\"images\"\n    /\u003e\n    ```\n\n6) Local aliases (per-instance)\n    ```html\n    \u003clivewire:media-uploader\n        model=\"profile\"\n        :id=\"$user-\u003eid\"\n        :aliases=\"['profile' =\u003e \\App\\Models\\User::class]\"\n        collection=\"gallery\"\n    /\u003e\n    ```\n\n7) Single-file mode + hide list\n    ```html\n    \u003clivewire:media-uploader\n        :for=\"$user\"\n        collection=\"avatar\"\n        :multiple=\"false\"\n        :showList=\"false\"\n        preset=\"images\"\n    /\u003e\n    ```\n\n8) Name conflict strategies\n    ```html\n    \u003clivewire:media-uploader :for=\"$user\" collection=\"files\" onNameConflict=\"rename\" /\u003e\n    \u003clivewire:media-uploader :for=\"$user\" collection=\"files\" onNameConflict=\"replace\" /\u003e\n    \u003clivewire:media-uploader :for=\"$user\" collection=\"files\" onNameConflict=\"skip\" /\u003e\n    \u003clivewire:media-uploader :for=\"$user\" collection=\"files\" onNameConflict=\"allow\" /\u003e\n    ```\n\n9) Duplicate detection by SHA-256\n    ```html\n    \u003clivewire:media-uploader :for=\"$user\" collection=\"images\" preset=\"images\" :skipExactDuplicates=\"true\" /\u003e\n    ```\n\n10) Restrict types/mimes/max size manually\n    ```html\n    \u003clivewire:media-uploader\n        :for=\"$user\"\n        collection=\"documents\"\n        :accept=\"'.pdf,.doc,.docx,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document'\"\n        :allowedTypes=\"['pdf','doc','docx']\"\n        :allowedMimes=\"['application/pdf','application/msword','application/vnd.openxmlformats-officedocument.wordprocessingml.document']\"\n        :maxSizeKb=\"5120\"\n    /\u003e\n    ```\n### Create flow (deferred uploads)\n\nYou can let users pick files **before** the model exists, and attach them **after** save.\n\n**Blade (create page)**\n```html\n\u003c!-- Note: pass model class/alias without id --\u003e\n\u003clivewire:media-uploader\n    model=\"post\"\n    collection=\"images\"\n    preset=\"images\"\n    :multiple=\"true\"\n    :showList=\"true\"\n/\u003e\n```\n#### Livewire component (simplified)\n```php\nuse App\\Models\\Post;\nuse Illuminate\\Support\\Facades\\Auth;\nuse Livewire\\Attributes\\On;\nuse Livewire\\Component;\n\nclass PostCreate extends Component\n{\n    public string $title = '';\n    public string $body  = '';\n    public ?int $pendingPostId = null;\n\n    protected function rules(): array\n    {\n        return ['title' =\u003e 'required|string|max:255', 'body' =\u003e 'required|string'];\n    }\n\n    public function save(): void\n    {\n        $post = Post::create([\n            'user_id' =\u003e Auth::id(),\n            'title'   =\u003e $this-\u003etitle,\n            'body'    =\u003e $this-\u003ebody,\n        ]);\n\n        // Let uploaders attach everything queued for this collection\n        $this-\u003ependingPostId = $post-\u003eid;\n\n        // Fire once per collection rendered on the page\n        $this-\u003edispatch('media:attach', model: 'post', id: $post-\u003eid, collection: 'images');\n    }\n\n    #[On('media-attached')]\n    public function afterMediaAttached(string $model, string|int $id): void\n    {\n        if ($this-\u003ependingPostId \u0026\u0026 (int)$id === (int)$this-\u003ependingPostId) {\n            $this-\u003ependingPostId = null;\n            $this-\u003eredirectRoute('posts.show', ['post' =\u003e $id], navigate: true);\n        }\n    }\n\n    public function render() { return view('livewire.posts.post-create'); }\n}\n```\n\n#### How it works\n- On create screens, the component accepts model=\"post\" without an id.\n- Files and per-file metadata are queued locally.\n- After you persist the model, dispatch:\n    ```php\n    $this-\u003edispatch('media:attach', model: 'post', id: $post-\u003eid, collection: 'images');\n    ```\n- The uploader resolves the saved target, attaches any queued files, and emits media-attached.\n---\n\n## Configuration\n\nThe package merges `config/media-uploader.php`:\n\n- `accept_from_config` — if `true`, auto-fills `\u003cinput accept\u003e` from the selected preset\n- `collections` — map collection name → preset key\n- `presets.*.types` — extensions (comma-separated)\n- `presets.*.mimes` — MIME types (comma-separated)\n- `presets.*.max_kb` — max file size per file in KB\n\nExample:\n```php\n'collections' =\u003e [\n    'avatars'     =\u003e 'images',\n    'images'      =\u003e 'images',\n    'attachments' =\u003e 'docs',\n],\n```\nShow all collections together (grouped)\nSet `:list-all=\"true\"` to render a grouped list of **every collection** on the target model. Items stay fully editable.\n\n```html\n\u003clivewire:media-uploader\n    :for=\"$post\"\n    :list-all=\"true\"\n    :showList=\"true\"\n/\u003e\n```\nThe component decides the active preset in this order:\n1. Explicit `$preset` prop\n2. Mapping from `collections`\n3. Fallback to `default`\n\n---\n\n## Props\n\n| Prop | Type | Default | Description |\n|---|---|---|---|\n| `for` | `Model` | — | Saved Eloquent model instance implementing `HasMedia`. |\n| `model` | `string` | — | Model resolver: alias, FQCN, morph alias, or dotted path. |\n| `id` | `int|string` | — | Target model id (used with `model`). |\n| `collection` | `string` | `images` | Media collection name. |\n| `disk` | `?string` | `null` | Storage disk (e.g. `s3`). |\n| `multiple` | `bool` | `true` | Toggle multi-file input. |\n| `accept` | `?string` | `null` | `\u003cinput accept\u003e` override (otherwise may be auto from config). |\n| `showList` | `bool` | `true` | Show the attached media list. |\n| `maxSizeKb` | `int` | `500` (overridden to preset’s `max_kb` if empty) | Max file size (KB). |\n| `preset` | `?string` | `null` | Choose a preset (`images`, `docs`, `videos`, `default`, etc.). |\n| `allowedTypes` | `array` | `[]` | Extensions filter (e.g. `['jpg','png']`). |\n| `allowedMimes` | `array` | `[]` | MIME filter (e.g. `['image/jpeg']`). |\n| `onNameConflict` | `string` | `rename` | Strategy: `rename` \\| `replace` \\| `skip` \\| `allow`. |\n| `skipExactDuplicates` | `bool` | `false` | Uses SHA-256 stored in `custom_properties-\u003esha256`. |\n| `namespaces` | `array` | `['App\\\\Models']` | Namespaces for dotted-path resolution. |\n| `aliases` | `array` | `[]` | Local alias map, e.g. `['profile' =\u003e \\App\\Models\\User::class]`. |\n| `attachedFilesTitle` | `string` | `\"Current gallery\"` | Heading text in the list card. |\n| `listAll` | `bool` | `false` | When `true`, the attached media list shows **all collections**, grouped by collection name (still editable). |\n\n---\n\n## Events\n\nThe component dispatches browser events you can listen for:\n\n- `media:attach` — **incoming** event the component listens for. Arguments: `model` (class/alias), `id`, optional `collection`, optional `disk`. Triggers attaching of any queued files to the now-saved target.\n- `media-attached` — emitted after a successful `media:attach`. Payload: `{ model: FQCN, id: string }`.\n- `media-uploaded` — emitted after an immediate upload (when a target already exists).\n- `media-deleted` — emitted after deletion (`detail.id` contains the Media ID).\n- `media-meta-updated` — emitted after inline metadata is saved.\n\nExample:\n```html\n\u003cdiv\n  x-data\n  x-on:media-uploaded.window=\"console.log('uploaded!')\"\n  x-on:media-deleted.window=\"console.log('deleted', $event.detail?.id)\"\n\u003e\n  \u003clivewire:media-uploader :for=\"$user\" collection=\"images\" preset=\"images\" /\u003e\n\u003c/div\u003e\n```\n\n---\n\n\u003e The list view tries `getUrl('thumb')` and falls back to `getUrl()` if no conversion is available.\n\n---\n\n## Overlays \u0026 UX Notes\n\n- **Image Preview Overlay** (lightbox): toggled by `x-show=\"preview.open\"`.\n- **Delete Confirmation Modal**: toggled by `$wire.confirmingDeleteId !== null`.\n- Add once in your layout to prevent flash-of-overlay:\n  ```html\n  \u003cstyle\u003e[x-cloak]{ display:none !important; }\u003c/style\u003e\n  ```\n- Z-index defaults: preview `z-[60]`, delete modal `z-50`. Adjust to your stack if you have higher layers.\n\n---\n\n## Troubleshooting\n\n- **“Target model must be saved…”**  \n  Ensure the model exists in DB (`$model-\u003eexists === true`) before rendering the component.\n\n- **“must implement Spatie\\MediaLibrary\\HasMedia”**  \n  Add `implements HasMedia` + `InteractsWithMedia` to your model.\n\n- **Unknown model class/alias**  \n  If using `model=\"something\"` + `:id`, make sure:\n    - It’s a valid FQCN, morph alias, or maps via dotted path within `namespaces`, or\n    - You passed a local alias via `:aliases=\"['something' =\u003e \\App\\Models\\YourModel::class]`.\n\n- **`accept` not applied**  \n  Set `accept_from_config=true` and ensure your preset has `types`/`mimes`. Or override via `accept` prop.\n\n- **No thumbnails**  \n  Add a `thumb` conversion (see [Model Setup](#model-setup-spatie-media-library)).\n\n---\n\n## Roadmap\n\n- Drag-to-reorder (update `order_column`).\n- Show document icon instead of thumbnail in Attached media list if the file is not an image.\n\nPRs welcome!\n\n---\n\n## License\n\n**MIT** © CodebyRay (Ray Cuzzart II)\n\n---\n\n**Component aliases:** `media-uploader` and `media.media-uploader`  \n**View namespace:** `media-uploader::livewire.media-uploader`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodebyray%2Flivewire-media-uploader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodebyray%2Flivewire-media-uploader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodebyray%2Flivewire-media-uploader/lists"}