Download the PHP package solution-forest/filament-nestable-tree without Composer
On this page you can find all versions of the php package solution-forest/filament-nestable-tree. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download solution-forest/filament-nestable-tree
More information about solution-forest/filament-nestable-tree
Files in solution-forest/filament-nestable-tree
Package filament-nestable-tree
Short Description A nestable drag-and-drop tree component for Filament v4 and v5. Supports Eloquent models (including kalnoy/nestedset), static record arrays, per-node actions, multi-tree pages, cross-tree drag-and-drop, lazy loading, and async child loading.
License MIT
Homepage https://github.com/solutionforest/filament-nestable-tree
Informations about the package filament-nestable-tree
Filament Nestable Tree
A nestable drag-and-drop tree component for Filament v4 and v5. Supports Eloquent models (including kalnoy/nestedset), static record arrays, per-node actions, multi-tree pages, cross-tree drag-and-drop, lazy loading, and async child loading.
Example usage — see the demo application and the ready-to-run fixture pages in this repository.
Which Package Should I Use?
- Need a simple tree solution with quick setup? Use filament-tree.
- Need to handle heavy-load menus or large, complex trees? Use this package (
filament-nestable-tree).
Installation
[!IMPORTANT] If you are using Filament Panels with a custom theme, add the plugin's views to your theme CSS file so Tailwind can scan them:
If you have not yet set up a custom theme, follow the Filament theming guide first.
Quick Start
1 — Standalone Tree Page
Create a Filament page that shows a tree:
2 — Resource Tree Page (replaces ListRecords)
Register the page in your resource's getPages():
3 — Tree Widget
4 — Embed in Any Livewire Component (InteractsWithTree)
Add the InteractsWithTree trait to any Livewire component (including custom pages, widgets, or plain Livewire components) to embed a tree without extending a base class:
Then render the tree in your Blade view:
Livewire automatically calls
mountInteractsWithTree()after your component'smount()to populate the tree nodes — no manual setup required.
Tree Configuration Reference
All options are fluent methods on the Tree instance returned from tree() or trees().
| Method | Default | Description |
|---|---|---|
->model(Category::class) |
null |
Eloquent model to load the tree from |
->records([...]) |
[] |
Static nested/flat array (alternative to model) |
->labelField('name') |
'name' |
Attribute used as the display label |
->recordKeyField('id') |
'id' |
Attribute used as the unique identifier |
->parentKeyField('parent_id') |
'parent_id' |
Attribute used as the parent reference |
->childrenField('children') |
'children' |
Attribute that holds nested children |
->maxDepth(3) |
-1 (unlimited) |
Maximum nesting depth for drag-and-drop |
->maxVisibleDepth(5) |
4 |
Maximum rendered depth in the flat list view |
->searchable() |
false |
Show the search input and highlight matching labels |
->draggable(false) |
true |
Enable or disable drag-and-drop reordering |
->allowCrossCategory() |
false |
Allow nodes to move between root-level branches |
->lazy() |
false |
Defer node loading until after first render |
->asyncChildren(fn) |
null |
Load children on-demand when a node is expanded |
->saveOrderUsing(fn) |
null |
Closure to persist reorder; receives the nested nodes array |
->getRecordUsing(fn) |
null |
Custom closure to resolve a node record by its ID |
->nodeActions([...]) |
[] |
Per-node action buttons (edit, delete, custom) |
->appendToolbarActions([...]) |
— | Add buttons to the toolbar (append to defaults) |
Saving Order After Drag & Drop
Option 1 — Automatic (kalnoy/nestedset)
If your model uses the kalnoy/nestedset NodeTrait, the tree calls rebuildTree() automatically when the Save button is clicked — no extra configuration required:
Option 2 — Custom callback
If neither option is configured, a MissingSaveOrderCallbackException is thrown at runtime when save is triggered.
Save button in toolbar
The default toolbar includes a Save button that is hidden until a drag-drop reorder occurs. You can also add your own conditional save action:
Node Actions
Add per-node action buttons:
Custom node actions
getRecordUsing — custom record resolution
By default, when a node action fires the plugin resolves the record from the database (for model-based trees) or the flat records() array (for static trees). Override this for custom lookups:
Toolbar Actions
Pass Action or ActionGroup instances via ->appendToolbarActions():
Multiple Trees on One Page
Override trees() instead of tree() to render multiple independent trees:
Cross-tree drag & drop
To allow nodes to be dragged from one named tree to another, enable ->allowCrossCategory() and handle the tree-cross-move event:
Static records partitioned by a field
Use ->records() closures to split a single flat array across multiple trees by a partition field (e.g. category_id). Each tree sees only its own nodes; cross-tree drags update the partition field; saving one tree leaves the other tree's nodes untouched.
Key points
->records()accepts aClosure— it is re-evaluated on every Livewire hydration so each tree always reflects the latest state of$nodes.saveOrderForCategory()merges the newly-ordered nodes back with nodes from other categories so a save on tree1 never discards tree2's data.TREE_CATEGORY_MAPis the single source of truth that links tree keys to partition values; add entries here when adding more trees.- For a database-backed version replace the
static::$nodesarray with Eloquent queries — the structure oftrees(),handleCrossTreeMove, andsaveOrderForCategorystays identical.
Async / Lazy Loading
->lazy() — defer initial load
Renders the component shell immediately and loads nodes in a second Livewire request. Useful for large trees:
->asyncChildren() — expand-on-demand
Load children only when a node is expanded for the first time. The closure receives the parent node's ID:
When async children are enabled, the root-level nodes are loaded normally on mount. Child nodes are fetched via a Livewire call when the user expands a parent for the first time, and cached client-side for subsequent toggles.
Plain Eloquent Model (no NodeTrait)
You can use the package with any plain Eloquent model that has a parent_id column.
No kalnoy/nestedset NodeTrait is required.
Minimal schema
Option A — model with a children() relationship
Define a self-referencing HasMany on the model:
Then pass the model to the tree. The package performs a recursive eager load via the relationship on initial mount:
Option B — manual tree build with records()
Use ->records() when you want full control over how the nested array is built
(e.g., no relationship on the model):
Async children with a plain model
Combine ->asyncChildren() with ->model(). On mount, only root nodes are returned.
Children are loaded by the callback when the user expands a node:
Artisan Generators
Testing
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
- carly
- All Contributors
License
The MIT License (MIT). Please see License File for more information.
All versions of filament-nestable-tree with dependencies
filament/filament Version ^4.0|^5.0
spatie/laravel-package-tools Version ^1.15.0
kalnoy/nestedset Version ^6.0|^7.0