defstudio/filament-column-length-limiter
A Filament plugin that automatically truncates long table column text, keeping your admin tables tidy and readable. It limits displayed character counts with sensible defaults, so overflowing values no longer break layouts or blow up row heights.
composer require defstudio/filament-column-length-limiter:^5.0
config/ to publish — limits are set per column, not globally.TextColumn that renders long text (body, description, notes) and swap it for the limiter so cells truncate at a word boundary with an ellipsis and expose the full value in a tooltip, instead of blowing up row height or forcing a ->wrap().TextColumn::make('description')
->limit(80) // the package's limiter macro
->tooltip(fn ($state) => $state),
src/ (small surface area — one column + one macro) and the tests/ directory, which is the de-facto usage documentation for edge cases. Then composer.lock in your app to confirm filament/filament:^5.0 resolved.Shared limit constants. Don't sprinkle magic numbers across resources. Define limits next to the model or in a Support/ColumnLimits.php and reference them, so a UI tweak is a one-line change:
TextColumn::make('excerpt')->limit(ColumnLimits::EXCERPT);
Tooltip only when truncated. The full-value tooltip is noisy on short values. Feed the macro the raw state and let it no-op below the threshold, or gate the tooltip:
TextColumn::make('notes')
->limit(120)
->tooltip(fn ($state) => strlen($state) > 120 ? $state : null),
Keep the raw state for exports and actions. Truncation is a render-time concern. Anything downstream that reads the record — CSV export, ->action() modals, copy-to-clipboard — should read the Eloquent attribute, not the formatted column state. If you build a custom export, use $record->notes, not the column's displayed string.
Tables and infolists. The same limiter works in infolists where a long text entry would otherwise dominate the section; it's the cheapest fix for "my view page is 6000px tall."
Consistent table-wide treatment. For resources with many free-text columns, apply the limiter via a configureUsing() hook on the column class in a service provider, then override per-column where needed. This keeps every resource consistent without touching each file.
Relationship columns. Works on TextColumn backed by relationships (author.bio) since it only touches the resolved state — just be aware the relationship is still fully loaded (see Gotchas).
^4.0 — installing ^5.0 alongside Filament 4 will fail resolution or, worse, pass on a loose constraint and break at render time. This is the entire substance of the release; there are no deprecations or new features to migrate for.->limit(100) column still transfers every byte. If payload matters, select a substring in the query or use a dedicated short column.->sortable() orders by the DB column, and ->searchable() matches the full text — so a row can appear in results for a term that's hidden by the limiter. Expected, but it confuses users who search for a visible substring.strip_tags($state)) or use HtmlString with a sanitizer before limiting. Same for Markdown.mb_substr; a byte-based cut mangles accented characters and emoji, and can produce invalid UTF-8 in the JSON payload.->action() that opens a modal showing the full record field.TextColumn subclass — override formatStateUsing() in your own subclass if you need domain-specific shortening (e.g. sentence-aware cuts) rather than editing vendor code. Keep any custom logic in a subclass, since the package has a small maintainer surface and Filament major bumps arrive regularly.->wrap()/->html()/->formatStateUsing() on the same column that replaces the state after the limiter runs, and confirm the macro registration happened (a missing provider after composer install --no-scripts in CI is the usual culprit).How can I help you explore Laravel packages today?