Implementing a mentions system in a Filament RichEditor field can be a bit challenging, but with the right approach, you can achieve it. Below is a step-by-step guide to help you implement this feature using TributeJS, Livewire, and Alpine.js.
Step 1: Install TributeJS
First, you need to install TributeJS. You can do this via npm or by including the script directly in your project.
npm install tributejs
Step 2: Create a Custom Component
Create a custom component that extends the Filament RichEditor. This component will integrate TributeJS with the Trix editor.
// app/Http/Livewire/CustomRichEditor.php
namespace App\Http\Livewire;
use Filament\Forms\Components\RichEditor;
use Livewire\Component;
class CustomRichEditor extends Component
{
public $content;
public function render()
{
return view('livewire.custom-rich-editor');
}
}
Step 3: Create the Blade View
Create a Blade view file for the custom component. This file will include the Trix editor and the TributeJS integration.
<!-- resources/views/livewire/custom-rich-editor.blade.php -->
<div wire:ignore>
<trix-editor x-data x-init="initTribute" wire:model.defer="content"></trix-editor>
</div>
<script>
function initTribute() {
const tribute = new Tribute({
values: async (text, cb) => {
const response = await fetch('/api/users?query=' + text);
const users = await response.json();
cb(users.map(user => ({ key: user.name, value: user.username })));
}
});
tribute.attach(document.querySelector('trix-editor'));
}
</script>
Step 4: Create an API Endpoint
Create an API endpoint to fetch the list of mentionable users. This endpoint will be called by TributeJS to get the list of users based on the input text.
// routes/api.php
use App\Models\User;
use Illuminate\Http\Request;
Route::get('/users', function (Request $request) {
$query = $request->get('query');
return User::where('name', 'like', "%{$query}%")->get(['name', 'username']);
});
Step 5: Update Livewire Component
Ensure your Livewire component is updated to handle the content changes.
// app/Http/Livewire/CustomRichEditor.php
namespace App\Http\Livewire;
use Filament\Forms\Components\RichEditor;
use Livewire\Component;
class CustomRichEditor extends Component
{
public $content;
public function render()
{
return view('livewire.custom-rich-editor');
}
public function updatedContent($value)
{
// Handle real-time updates to the content if needed
}
}
Step 6: Integrate with Filament
Finally, integrate your custom component with Filament.
// app/Forms/Components/CustomRichEditor.php
namespace App\Forms\Components;
use Filament\Forms\Components\Field;
class CustomRichEditor extends Field
{
protected string $view = 'forms.components.custom-rich-editor';
}
And register the custom component in your Filament form.
// app/Filament/Resources/PostResource.php
use App\Forms\Components\CustomRichEditor;
use Filament\Forms;
public static function form(Forms\Form $form): Forms\Form
{
return $form
->schema([
CustomRichEditor::make('content')
->label('Content')
->required(),
]);
}
Conclusion
By following these steps, you should be able to implement a mentions system in a Filament RichEditor field. This solution leverages TributeJS for the mentions functionality, integrates it with the Trix editor, and ensures compatibility with Livewire and Alpine.js.