Download the PHP package happenv-com/filament-comments without Composer
On this page you can find all versions of the php package happenv-com/filament-comments. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download happenv-com/filament-comments
More information about happenv-com/filament-comments
Files in happenv-com/filament-comments
Package filament-comments
Short Description Comments module for Filament
License MIT
Homepage https://github.com/happenv-com/filament-comments
Informations about the package filament-comments
Filament Comments
Polymorphic, paginated comments for Filament 4 and 5. Drop a Comments component into any infolist or form schema and
the current record gets a comment list with a rich-text (or Markdown) form, quoting, shareable deep links and
pagination.
Key features
- Comments on any record. Add the
HasCommentstrait to a model and aCommentscomponent to its schema — see Usage. - Rich text or Markdown. Comments are written in Filament's rich editor, with optional mentions, or in the Markdown editor — see Comment format.
- Quoting. One click quotes a comment into the form, as a blockquote in rich text or as
>lines in Markdown. - Shareable deep links. Every comment has a "copy link" action; opening the link jumps to the page containing the comment and highlights it — see Deep links.
- Three pagination types. Simple, standard (with page numbers) or cursor pagination, with a per-page selector above, below or on both sides of the list — see Pagination.
- Several lists per record. Each relationship (e.g.
commentsandinternalNotes) gets its own independent list on the same page. - Safe by default. The list's configuration is validated once and stored in a locked Livewire property, so the browser cannot change it — see Extending.
- Replaceable parts. The save action, the form, the comment item and every part of it are classes you can swap — see Customizing.
Requirements
| Package | Versions |
|---|---|
| PHP | 8.3 – 8.5 |
| Laravel | 12, 13 |
| Filament | 4 (^4.5.0), 5 (^5.0) |
| Livewire | 3 (Filament 4), 4 (Filament 5) |
Installation
Install the package via Composer:
Publish and run the migration that creates the comments table:
The table has an auto-incrementing id, a polymorphic commentable relation created with nullableMorphs() (so
commentable_id is an integer column), an author_id foreign key to the users table, a content text column and
timestamps. Edit the published migration before running it if your models use UUID or ULID keys (see
UUID or ULID keys) or your authors are not stored in users.
[!IMPORTANT] If you have not set up a custom theme and are using Filament Panels, follow the instructions in the Filament docs (4.x, 5.x) first.
Add the package's views to your theme's CSS file, so Tailwind generates the classes they use:
Configuration
Optionally publish the config file:
This is the content of the published config file, config/filament-comments.php:
| Key | Default | What it does |
|---|---|---|
author_model |
null |
Eloquent model of comment authors (Comment::author(), the default mention provider). null falls back to auth.providers.users.model. |
comment_model |
null |
Eloquent model of comments, used by HasComments. Must extend Happenv\FilamentComments\Models\Comment. null uses the package's own model. |
The author model does not depend on the logged-in user. If neither setting points to an Eloquent model, a
LogicException is thrown. For example:
Optionally, publish the views and translations:
UUID or ULID keys
The migration uses standard auto-incrementing keys. If your models use UUIDs (or ULIDs), change the published migration before running it:
- Commentable models with UUID keys — replace
nullableMorphs('commentable')withnullableUuidMorphs('commentable')(ornullableUlidMorphs()). - UUID keys for the comments themselves — replace
$table->id()with$table->uuid('id')->primary(), and pointcomment_modelto your own model that addsHasUuids:
Relationships you define yourself (such as internalNotes() below) should use the same model.
Usage
Make a model commentable
HasComments adds a comments() morph-many relationship. You can define more relationships on the same model (for
example internalNotes()); every relationship must declare its return type (MorphMany, HasMany, ...):
Add the component to a schema
Comments::make() takes the name of the relationship, comments by default. Two components on the same page (e.g.
Comments::make('comments') and Comments::make('internalNotes')) render two independent lists.
The component is hidden while the schema has no record (e.g. on a create page). It is a regular schema component, so
the usual methods such as visible() and hidden() work too.
Component options
Every setting accepts a value or a closure returning it. Closures are evaluated once, when the list is mounted, with
the usual Filament injections ($record, $livewire, ...).
| Method | Default | What it does |
|---|---|---|
formLocation() |
CommentFormLocation::Above |
Where the comment form is shown: Above or Below the list. |
paginationType() |
CommentsPaginationType::Simple |
Simple, Standard or Cursor pagination. |
paginationLocation() |
CommentsPaginationLocation::Below |
Where the pagination is shown: Above, Below, Both or None. |
paginationOptions() |
[10, 20, 50] |
Page sizes the user can pick. |
paginationDefaultPerPage() |
20 |
Initial page size; must be one of the options. |
commentFormat() |
CommentFormat::Html |
Html (rich editor) or Markdown (Markdown editor). |
sortColumn() |
'created_at' |
Column the list is sorted by, newest first. |
commentItemContentFieldName() |
'content' |
Attribute of the comment model that holds its content. |
canComment() |
true |
Whether the form and the quote action are shown and comments can be submitted. |
mentionProvider() / mentionProviders() |
none | Mention providers of the rich editor. |
saveAction() |
SaveCommentAction::class |
Class that saves a new comment. |
formSchema() |
CommentFormSchema::class |
Class that builds the comment form. |
itemSchema() |
CommentItemSchema::class |
Class that builds the schema of one comment. |
commentItemComponent() |
Comment::class |
Schema component that renders one comment. |
All of them together:
Form location
With the form above the list (the default), the newest comment is at the top. With the form below the list, each page is shown oldest to newest, so the conversation reads towards the form.
Pagination
paginationType():Simple(previous / next, the default),Standard(page numbers) orCursor.paginationLocation():Above,Below(the default),BothorNone. The pagination is not rendered while the list is empty.paginationOptions(): the page sizes in the per-page select,[10, 20, 50]by default. At least one, all positive integers.paginationDefaultPerPage(): the initial page size,20by default. It must be one of the options. A page size sent by the browser that is not one of the options falls back to this default.
The page is kept in the query string as {relationship}_page (e.g. comments_page), so two lists on one page
paginate independently. Changing the page size, or adding a comment, goes back to the first page.
Sorting
Comments are sorted by this column, newest first (created_at by default), and then by primary key, so pages are
stable when timestamps are equal. The column name must be a plain identifier (letters, digits and underscores).
Comment format
CommentFormat::Html(default): the form uses Filament's rich editor (bold, italic, strike, link, bullet and ordered lists, code block and blockquote, plus mentions). Comments are rendered as HTML.CommentFormat::Markdown: the form uses Filament's Markdown editor, and comments are rendered with the Markdown parser.
Content attribute
The attribute of the comment model that the form writes to and the list renders, content by default. It must be a
plain identifier.
Who can comment
true by default. When it is false, the form and the quote action are hidden and the list refuses to save a
comment. Submitting a comment also requires a logged-in user and non-empty content; otherwise the user gets a
notification and nothing is saved.
Mentions
Mention providers are only used by the rich editor (CommentFormat::Html). None are registered by default. A
provider is a class implementing Contracts\ProvidesMentions — a static make() method returning a Filament
MentionProvider:
The bundled UserMentionProvider searches the name column of the author model (up to 10 results)
with the @ character.
Deep links
Every comment has a "copy link" action that copies a link to the current page with the comment in the query string,
e.g. ?comments_comment_id=42 (the parameter is {relationship}_comment_id). Opening the link opens the page
containing the comment and highlights it. This works with all three pagination types.
Rendering comment content
The comment model registers its content attribute as Filament rich content. By default the attribute gets the
UserMentionProvider mentions. A commentable model can configure the attribute itself with a
setUpCommentsRichContent() method (called on a new instance of the commentable model), which returns a closure that
receives the attribute. The default mentions are then not added:
Events
The list dispatches two browser events, which you can listen to with Alpine or Livewire:
| Event | Parameters | When |
|---|---|---|
comment-added |
relationship |
After a comment is saved. |
highlight-comment |
commentId, relationship |
When a deep link opens; the list scrolls to the comment and highlights it. |
Validation
Invalid configuration throws an InvalidArgumentException when the list is built:
- the default page size must be one of
paginationOptions(), and the options must be positive integers; - the relationship name, sort column and content field must be plain identifiers;
- extension classes must implement their contracts (see Customizing);
- the relationship method must exist and declare a relation return type (e.g.
: MorphMany).
Extending
The list is rendered by a nested Livewire component (Livewire\CommentsList, registered as
happenv-filament-comments-list). The component receives its configuration as one validated, immutable
CommentsSettings object, stored in a locked Livewire property, so the browser can't change it. Build the settings
from a component with Comments::make('comments')->...->toSettings(). For the same reason, extension points are
class names that implement a contract, not closures.
Customizing
| Setting | Contract | Default |
|---|---|---|
saveAction() |
Contracts\SavesComment |
Actions\SaveCommentAction |
formSchema() |
Contracts\ConfiguresCommentForm |
Filament\Schemas\CommentFormSchema |
itemSchema() |
Contracts\ConfiguresCommentItem |
Filament\Schemas\CommentItemSchema |
commentItemComponent() |
extends Filament\Components\Comment |
Filament\Components\Comment |
mentionProviders() |
Contracts\ProvidesMentions |
none |
Each of them accepts a class name, or a closure that returns one.
Save action
The save action is invoked with the record, the validated form state, the logged-in author and the settings, and returns the saved comment. A custom save action, for example:
Form schema
The form schema class builds the comment form. Extend CommentFormSchema and override htmlFormatInput() or
markdownFormatInput() to change the editor, or implement ConfiguresCommentForm from scratch. The form must call
the list's submitComment method:
Item schema
The item schema class builds the schema of one comment. The default one renders commentItemComponent() for the
content field, in Markdown mode for CommentFormat::Markdown:
Comment item component
Filament\Components\Comment renders one comment: a header (author and date), the content and a footer (quote and
share actions). Every part accepts another component, a closure returning one, or false to remove it —
headerComponent(), authorComponent(), createdAtComponent(), contentComponent() and footerComponent() —
and markdown() switches the content to the Markdown parser. The parts are resolved lazily, so configuration applied
after make() takes effect.
To change the defaults for every comment, extend the component and override any of the getDefault*Component()
methods (header, author, created at, content, footer) or the getQuoteAction() / getShareAction() methods:
Comment model
HasComments resolves the comment model from the container, so you can replace it with a subclass of
Models\Comment in a service provider:
Testing your application
The comment model has a factory. Its withAuthor() state sets the author; without it, the factory creates an author
with the author model's own factory:
Translations
The package ships in every locale Filament ships:
am ar az bg bn bs ca ckb cs da de el en es et eu fa fi fil fr he hi hr hu hy id it ja ka km ko ku lt lus lv mk mn ms my nb ne nl pl pt pt_BR ro ru sk sl sq sr_Cyrl sr_Latn sv sw tg th tr uk ur uz vi zh_CN zh_HK zh_TW
Publish them to change the texts:
tests/Unit/TranslationsTest.php checks that every language has exactly the keys English has, that nothing is left in English, and that every locale Filament ships has a translation.
Development
The test suite runs on Pest against Filament 4 (Livewire 3) and Filament 5 (Livewire 4), on Laravel 12 and 13.
Upgrading
Breaking changes and how to migrate are described in UPGRADING for every major version.
Changelog
See CHANGELOG and GitHub releases for what has changed recently.
Contributing
See CONTRIBUTING for details.
Security vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). See License File for more information.
All versions of filament-comments with dependencies
filament/filament Version ^4.5.0 || ^5.0
spatie/laravel-package-tools Version ^1.15.0