koassi / filament-file-explorer
Finder-style file explorer for Filament v4 and v5, powered by Spatie Media Library.
Package info
github.com/KoassiAkakpo/filament-file-explorer
pkg:composer/koassi/filament-file-explorer
Requires
- php: ^8.2
- filament/filament: ^4.0 || ^5.0
- illuminate/contracts: ^11.0|^12.0|^13.0
- illuminate/database: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
- livewire/livewire: ^3.0 || ^4.0
- spatie/laravel-medialibrary: ^11.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.0
- orchestra/testbench: ^9.0 || ^10.0 || ^11.0
- pestphp/pest: ^4.7
- pestphp/pest-plugin-laravel: ^4.1
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
A Finder-style file explorer for Filament v4/v5, backed by Spatie Media Library over a folder tree. Icons, columns and details views; keyboard operation; drag and drop; trash, quotas, tags, versions and share links.
๐ Documentation
Install
composer require koassi/filament-file-explorer php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="medialibrary-migrations" php artisan migrate php artisan filament-file-explorer:install
Register the plugin in your panel provider:
use Koassi\FilamentFileExplorer\FilamentFileExplorerPlugin; public function panel(Panel $panel): Panel { return $panel->plugin(FilamentFileExplorerPlugin::make()); }
Add the package views to your Filament theme so Tailwind picks up their classes, then publish the assets:
@source '../../../../vendor/koassi/filament-file-explorer/resources/views/**/*.blade.php';
npm run build php artisan filament:assets
An Explorer entry appears in the navigation at /{panel}/file-explorer, and the root folder is created on first visit. Full steps: Installation.
php artisan file-explorer:demo # fill it with something to look at
It works two ways
A standalone page (default) โ a panel-level page in the navigation menu, backed by a single root folder. No model, no record. Where the root comes from is a resolver's decision: one shared library, one per user, one per tenant, or your own.
Record-scoped pages โ an explorer attached to an Eloquent record and reachable from its resource, so a project or a client has files of its own.
Both reduce to the same Livewire component driven by two values: a scope key and a root folder id.
What is in it
| Views | Icons, the Finder's cascading columns, details rows โ remembered per scope |
| Large libraries | Sorting, filtering and windowing in SQL; thousands of files stay responsive |
| Keyboard and touch | The listing is a listbox; a finger gets its own gestures |
| Large uploads | Sliced past post_max_size, or straight to S3 |
| Trash | Deleting moves aside, with restore and purge |
| File versions | Replacing a file keeps the last N |
| Tags and descriptions | A per-scope vocabulary, searchable, filterable through the subtree |
| Share links | A public link to one file โ expiring, revocable |
| Quotas | A cap per scope, in the sidebar and on the dashboard |
| Thumbnails | Images by default; PDF and video opt-in |
| The form field | The explorer in a modal, writing media ids into your form state |
| Events | Twenty of them, so audit, scan and index need no fork |
Two guards, on every entry point
- An ability check. Your
FileExplorerAuthorizeranswers what a scope may do. Nothing ever defaults to allowed. - A containment check. Folder and media ids arrive as user input, so every one is walked up the tree to prove it belongs to the root being browsed.
Both are required, on every action and every route. See Authorization.
Requirements
PHP 8.2+ ยท Laravel 11 or 12 ยท Filament v4 or v5 ยท Media Library v11
Contributing
composer install ./vendor/bin/pest # PHP suite node --test "tests/Js/*.test.mjs" # selection and keyboard logic
The JavaScript tests need nothing installed: they run the shipped script in a node:vm context with a stubbed Alpine and DOM. See Contributing.
License
MIT โ see LICENSE.
