schmeits/filament-character-counter
Installation:
composer require schmeits/filament-character-counter:"^5.0"
Publish the config (optional, for customization):
php artisan vendor:publish --provider="Schmeits\FilamentCharacterCounter\FilamentCharacterCounterServiceProvider"
First Use Case:
Replace a standard TextField, Textarea, or RichEditor in a Filament form with the character-counter variant:
use Schmeits\FilamentCharacterCounter\Fields\CharacterCounterTextField;
CharacterCounterTextField::make('bio')
->maxLength(200)
->columnSpanFull(),
Where to Look First:
config/filament-character-counter.php for default styling/config.Basic Integration:
Replace any text-based field with its CharacterCounter* counterpart:
// Before
Textarea::make('description')->rows(5),
// After
CharacterCounterTextarea::make('description')
->maxLength(500)
->helperText('Max 500 characters.'),
Dynamic Limits: Use closures for runtime limits (e.g., based on user roles):
CharacterCounterTextField::make('tagline')
->maxLength(fn () => auth()->user()->isAdmin() ? 100 : 50),
RichEditor Integration:
use Schmeits\FilamentCharacterCounter\Fields\CharacterCounterRichEditor;
CharacterCounterRichEditor::make('content')
->maxLength(1000)
->toolbarButtons([
'bold', 'italic', 'link',
]),
Form-Level Validation: Combine with Filament’s built-in validation:
CharacterCounterTextField::make('title')
->required()
->maxLength(150)
->rules(['unique:posts']),
Conditional Rendering: Toggle the counter based on field state:
CharacterCounterTextarea::make('notes')
->maxLength(300)
->showCharacterCounter(fn ($state) => strlen($state) > 0),
Custom Styling: Override default CSS via the config:
// config/filament-character-counter.php
'character_counter' => [
'color' => 'text-red-500',
'font_size' => 'text-sm',
],
Localization: Translate counter labels:
CharacterCounterTextField::make('slogan')
->maxLength(80)
->characterCounterLabel(fn () => __('filament-character-counter::counter.label')),
Multi-Field Sync: Sync counters across related fields (e.g., title + excerpt):
// In a custom field widget or form component
$this->fields([
CharacterCounterTextField::make('title')->maxLength(100),
CharacterCounterTextField::make('excerpt')->maxLength(200),
]);
Version Mismatches:
^5.0 with Filament v3.x will fail silently.^1.0 for Filament v3.2 or ^5.0 for v4/v5.composer.json for filament/support version.RichEditor Quirks:
live prop or debounce updates:
CharacterCounterRichEditor::make('content')
->live()
->debounce(500),
CSS Conflicts:
.filament-character-counter__counter {
@apply text-primary-500 !important;
}
Max Length Validation:
maxLength.->maxLength() and Laravel validation rules:
->rules(['max:200'])
->maxLength(200),
Inspect Rendered HTML: Use browser dev tools to verify the counter element exists:
<div class="filament-character-counter__counter">120/200</div>
If missing, check for JavaScript errors in the console.
Log Field State:
Debug dynamic maxLength with:
->maxLength(fn () => log('Max length: ' . auth()->user()->role, 'debug'))
Disable Counter Temporarily: For testing, use:
->showCharacterCounter(false),
Custom Counter Logic: Extend the counter behavior by publishing and modifying the JS:
php artisan vendor:publish --tag=filament-character-counter-assets
Then edit resources/js/filament-character-counter.js.
Add Icons/Tooltips: Use Filament’s icon system:
->characterCounterIcon('heroicon-o-information-circle')
->characterCounterTooltip(__('Tip: Keep it under 150 chars!')),
Server-Side Processing:
Hook into saving to log character counts:
use Filament\Notifications\Notification;
$record->save();
Notification::make()
->title('Character count')
->body("Title: {$record->title->length()}/100")
->send();
Testing: Use Filament’s testing helpers:
$this->fillForm([
'bio' => str_repeat('a', 301), // Exceed max
]);
$this->assertHasErrors(['bio' => 'The bio may not be greater than 300 characters.']);
How can I help you explore Laravel packages today?