Maintainers
Pricing
Enterprise
More
More
Documentation
Try Live
Rankings
Install
Blog
Docs7
Ask
New
Add Docs
Filament Timeline View
https://github.com/devletes/filament-timeline-view
Admin
Render Filament Tables as a chronological timeline.
Tokens:
20,526
Snippets:
160
Trust Score:
6.4
License:
MIT
Update:
1 month ago
Context
Chat
Benchmark
Latest
Show doc for...
Code
Info
Show Results
Tokens:
Raw
Copy
Link
Tokens:
Raw
Copy
Link
### Install and publish assets Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-view-service-provider.md Commands to install the package and publish the CSS asset. ```bash composer require devletes/filament-timeline-view php artisan filament:assets ``` -------------------------------- ### Install via Composer Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Install the package using Composer. No plugin registration is needed; the service provider auto-loads and registers the table macros and CSS asset. ```bash composer require devletes/filament-timeline-view ``` -------------------------------- ### Basic TimelineEntry usage Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Basic usage example showing how to create a TimelineEntry with fluent setters for title, content, image, author, and time fields. ```php use Devletes\FilamentTimelineView\Tables\Columns\TimelineEntry; TimelineEntry::make() ->title('title') ->content('body') ->image('hero_image_url') ->author('author.name', 'author.avatar_url') ->time('published_at'); ``` -------------------------------- ### Example — mixed string and closure setters Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Shows chaining all five setters with a mix of dot-notation field paths and closures. Demonstrates the fluent interface and closure usage for dynamic values. ```php TimelineEntry::make() ->title('title') // dot-notation field path ->content(fn ($record) => strip_tags($record->html_body)) // closure ->image(fn ($record) => $record->cover?->getUrl('thumb')) // closure ->author( 'author.name', // string path fn ($record) => $record->author?->getFilamentAvatarUrl(), // closure ) ->time(fn () => now() /* Carbon */, 'H:i'); ``` -------------------------------- ### Example — mixed string and closure setters Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Demonstrates chaining all five setters with a mix of dot-notation field paths and closures. ```APIDOC ## Example — mixed string and closure setters ### Description Demonstrates chaining all five setters with a mix of dot-notation field paths and closures. ### Code ```php TimelineEntry::make() ->title('title') // dot-notation field path ->content(fn ($record) => strip_tags($record->html_body)) // closure ->image(fn ($record) => $record->cover?->getUrl('thumb')) // closure ->author( 'author.name', // string path fn ($record) => $record->author?->getFilamentAvatarUrl(), // closure ) ->time(fn () => now() /* Carbon */, 'H:i'); ``` ``` -------------------------------- ### Resource list page with asTimeline() Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/table-macros.md Example table() method for a resource list page that uses TimelineEntry, defaultGroup, recordActions, and paginated, then applies asTimeline() (or asDoubleSidedTimeline()). ```php use Devletes\FilamentTimelineView\Tables\Columns\TimelineEntry; use Filament\Actions\ActionGroup; use Filament\Tables\Grouping\Group; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([ TimelineEntry::make()->title('title')->content('body')->time('published_at'), ]) ->defaultGroup(Group::make('published_at')->date()) ->recordActions([ActionGroup::make([/* ViewAction, EditAction, DeleteAction */])]) ->paginated([10]) ->asTimeline(); // or ->asDoubleSidedTimeline() } ``` -------------------------------- ### Publish Filament assets Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Publish the package's CSS asset once after installation using Filament's asset system. ```bash php artisan filament:assets ``` -------------------------------- ### Render timeline entry in isolation Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Example of rendering the timeline entry in isolation, as used by tests. It sets title, content, and a time closure, then calls toEmbeddedHtml() on a record with the given fields. ```php use Carbon\CarbonInterface; use Illuminate\Support\Carbon; use Devletes\FilamentTimelineView\Tables\Columns\TimelineEntry; $entry = TimelineEntry::make() ->title('subject') ->content('body') ->time(fn () => Carbon::parse('2026-04-25 09:15:00'), 'g:i A'); $html = $entry->record(['subject' => 'Quarterly review', 'body' => "line one\nline two"]) ->toEmbeddedHtml(); // "<h3 class=\"ftv-card-title\">Quarterly review</h3><p ...>line one<br>line two</p>" ``` -------------------------------- ### Error-tolerant rendering with null fields Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Example of error-tolerant rendering: null or missing fields never raise exceptions; the affected sections are omitted. The resulting HTML contains the empty ftv-card-layout wrapper with no title, no footer, and no ftv-card-layout-has-media modifier. ```php // Null/missing fields never raise — the affected section is omitted. $record = ['subject' => null, 'author' => null, 'published_at' => null]; $html = TimelineEntry::make() ->title('subject') ->author('author.name') ->time('published_at', 'H:i') ->record($record) ->toEmbeddedHtml(); // $html contains the empty ftv-card-layout wrapper, with no title, no footer, // and (because filled($image) is false) no ftv-card-layout-has-media modifier. ``` -------------------------------- ### Change filter layout with FiltersLayout Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Pass a `FiltersLayout` enum case as the second argument to `->filters(...)` to move the filter form into a modal, full-width panel, or sidebar. The example shows `FiltersLayout::BeforeContent`, which places the form before the timeline content. See Filament's filter layout docs for all options. ```php use Filament\Tables\Enums\FiltersLayout; ->filters([...], FiltersLayout::BeforeContent) ``` -------------------------------- ### Configure per-card actions with recordActions and ActionGroup Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Sets up a single kebab dropdown per card. Pass a single `ActionGroup` to preserve its settings, or a flat array of actions to be wrapped in a new `ActionGroup` with gray color. Hidden actions are filtered per record. ```php ->recordActions([ ActionGroup::make([ ViewAction::make(), EditAction::make()->color('primary'), DeleteAction::make()->requiresConfirmation()->color('danger'), ])->color('gray'), ]) ``` -------------------------------- ### Import TimelineViewServiceProvider Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-view-service-provider.md Import the TimelineViewServiceProvider class from the Devletes\FilamentTimelineView namespace. ```php use Devletes\FilamentTimelineView\TimelineViewServiceProvider; ``` -------------------------------- ### boot() method signature Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-view-service-provider.md Signature of the boot() method that runs automatically when Laravel boots the provider. ```php public function boot(): void ``` -------------------------------- ### Import TimelineEntry Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Import the TimelineEntry layout column class before using it in a Filament table's columns configuration. ```php use Devletes\FilamentTimelineView\Tables\Columns\TimelineEntry; ``` -------------------------------- ### make() Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Static factory method that creates a configured TimelineEntry instance by resolving it from the Filament app container and calling its inherited configure() method. ```APIDOC ## make() ### Description Creates a configured `TimelineEntry` instance by resolving it from the Filament app container (`app(static::class)`) and calling its inherited `configure()` method. The returned instance is a `TimelineEntry` ready for fluent field setters. ### Method Static factory method ### Signature ```php public static function make(): static ``` ### Parameters No parameters. ### Returns - **static** - A `TimelineEntry` instance (the class's own instance type). ### Example ```php use Devletes\FilamentTimelineView\Tables\Columns\TimelineEntry; TimelineEntry::make() ->title('title') ->content('body') ->image('hero_image_url') ->author('author.name', 'author.avatar_url') ->time('published_at'); ``` ``` -------------------------------- ### Constructor Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Empty constructor that takes no arguments. Instances are normally obtained through the static factory make() rather than new. ```APIDOC ## Constructor ### Description Empty constructor; takes no arguments. Instances are normally obtained through the static factory `make()` rather than `new` — `make()` resolves the component from the Filament app container, which applies container configuration. ### Method Constructor ### Signature ```php final public function __construct() {} ``` ### Parameters No parameters. ### Returns No return value. ### Throws No throws. ``` -------------------------------- ### Publish translations Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-view-service-provider.md Command to publish the language files for customization. ```bash php artisan vendor:publish --tag=filament-timeline-view-translations ``` -------------------------------- ### TimelineEntry::make() factory method Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Creates a configured TimelineEntry instance by resolving it from the Filament app container (app(static::class)) and calling its inherited configure() method. The returned instance is a TimelineEntry ready for fluent field setters. ```php public static function make(): static ``` -------------------------------- ### Publish translations with vendor:publish --tag=filament-timeline-view-translations Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/configuration.md Publishes the package's translation files to the application's lang/vendor/filament-timeline-view/ directory. The tag is registered at boot as publishable. After running, edit or add files under the published directory. ```bash php artisan vendor:publish --tag=filament-timeline-view-translations # edit / add files under lang/vendor/filament-timeline-view/ ``` -------------------------------- ### Enable Load more pagination with ->paginated([5]) Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Call `->paginated([5])` on the timeline to enable pagination. The package replaces Filament's prev/next links with a single Load more button that increases `tableRecordsPerPage` by 5 per click. Pass a single-value array; only the first integer is used as the increment. ```php ->paginated([5]) ``` -------------------------------- ### TimelineEntry with field setters Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Shows how to configure a TimelineEntry column using string field paths and closures. Each setter accepts either a dot-notation path resolved via data_get or a Closure receiving the record. For time(), a closure may return a Carbon instance or a pre-formatted string. ```php TimelineEntry::make() ->title('title') // dot-notation field path ->content(fn ($record) => strip_tags($record->html_body)) // closure ->image(fn ($record) => $record->cover?->getUrl('thumb')) // closure ->author( 'author.name', // string path fn ($record) => $record->author?->getFilamentAvatarUrl(), // closure ) ->time('published_at') ``` -------------------------------- ### Resource list page with asTimeline() Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Configures a Filament ListRecords table to render as a single-column timeline using the asTimeline() macro. Uses TimelineEntry with title, content, image, author, and time methods, plus defaultGroup, recordActions, and paginated. The recordActions include ViewAction, EditAction, and DeleteAction in an ActionGroup. ```php use Devletes\FilamentTimelineView\Tables\Columns\TimelineEntry; use Filament\Actions\ActionGroup; use Filament\Actions\ViewAction; use Filament\Actions\EditAction; use Filament\Actions\DeleteAction; use Filament\Tables\Grouping\Group; use Filament\Tables\Table; class ListPulses extends ListRecords { protected static string $resource = PulseResource::class; public function table(Table $table): Table { return $table ->columns([ TimelineEntry::make() ->title('title') ->content('body') ->image('hero_image_url') ->author('author.name', 'author.avatar_url') ->time('published_at'), ]) ->defaultGroup(Group::make('published_at')->date()) ->recordActions([ ActionGroup::make([ ViewAction::make(), EditAction::make(), DeleteAction::make(), ]), ]) ->paginated([10]) ->asTimeline(); } } ``` -------------------------------- ### asTimeline() Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/table-macros.md Switches the table's view to the timeline view with a single-sided layout. Takes no parameters and returns the table instance for chaining. ```APIDOC ## asTimeline() ### Description Switches the table's view to `filament-timeline-view::tables.timeline` and sets the view data `timelineLayout` to `'single'`. Takes no parameters and returns the table instance. ### Method Macro (instance method on `Filament\Tables\Table`) ### Endpoint `->asTimeline()` ### Parameters No parameters. ### Returns - **Table** - The same table instance, chainable. ### Example ```php $table->asTimeline(); ``` ### Response No response body; the table's view and view data are modified in place. ``` -------------------------------- ### TimelineEntry constructor Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Empty constructor that takes no arguments. Instances are normally obtained through the static factory make() rather than new, because make() resolves the component from the Filament app container, which applies container configuration. ```php final public function __construct() {} ``` -------------------------------- ### Configure search options: searchPlaceholder, searchDebounce, searchOnBlur Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Filament's search options pass through unchanged. Use `->searchPlaceholder()` to set placeholder text, `->searchDebounce()` to set debounce time, and `->searchOnBlur()` to trigger search on blur. `->searchUsing()` also works for custom query control. ```php ->searchable(['title', 'body']) ->searchPlaceholder('Search updates') ->searchDebounce('700ms') ->searchOnBlur() ``` -------------------------------- ### TimelineEntry imports Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Imports all types used in the TimelineEntry class signatures. ```php use Carbon\CarbonInterface; use Closure; use Filament\Support\Components\Contracts\HasEmbeddedView; use Filament\Tables\Columns\Layout\Component; use Illuminate\Support\Carbon; ``` -------------------------------- ### Equivalent effect after building a table Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/table-macros.md Shows the view and view data after applying the macro in a widget context. The getView() returns the timeline view and getViewData() returns the timelineLayout. ```php $table = $widget->table(Table::make($widget)); $table->getView(); // 'filament-timeline-view::tables.timeline' $table->getViewData();// ['timelineLayout' => 'single'] ``` -------------------------------- ### image() method signature Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Signature for the image() setter. Accepts a string field path or closure, returns static for chaining. Renders as <img class="ftv-card-image"> inside a ftv-card-media block; adds modifier class ftv-card-layout-has-media when filled. ```php public function image(string|Closure $field): static ``` -------------------------------- ### content() method signature Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Signature for the content() setter. Accepts a string field path or closure, returns static for chaining. Renders as <p class="ftv-card-content">; newlines are converted to <br> via nl2br(). ```php public function content(string|Closure $field): static ``` -------------------------------- ### Register asTimeline and asDoubleSidedTimeline macros Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-view-service-provider.md Registers the 'asTimeline' and 'asDoubleSidedTimeline' macros on the Table class, returning the table with the appropriate timeline view. ```php Table::macro('asTimeline', function (): Table { return $this->view('filament-timeline-view::tables.timeline', [ 'timelineLayout' => 'single', ]); }); Table::macro('asDoubleSidedTimeline', function (): Table { return $this->view('filament-timeline-view::tables.timeline', [ 'timelineLayout' => 'double', ]); }); ``` -------------------------------- ### Enable search with ->searchable(['title', 'body']) Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Adds a search field to the header toolbar. Pass the column names to search. Prefer naming columns on the table rather than marking a column `->searchable()`, because the timeline renders every column passed to `->columns()` inside the card, causing stray text. ```php ->searchable(['title', 'body']) ``` -------------------------------- ### time() method signature Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Signature for the time() setter. Accepts a field path or closure and an optional format string (default 'g:i A'). String paths are Carbon-parsed and formatted with translatedFormat; closure results are passed through resolveTimeValue(). ```php public function time(string|Closure $field, string $format = 'g:i A'): static ``` -------------------------------- ### Macro signatures and view data Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/table-macros.md Shows the chainable usage of both macros and the view data they set. The comments indicate the timelineLayout value for each variant. ```php // Both macros: no parameters, chainable, return the table. ->asTimeline() // sets view data: ['timelineLayout' => 'single'] ->asDoubleSidedTimeline() // sets view data: ['timelineLayout' => 'double'] ``` -------------------------------- ### Dashboard widget with TimelineEntry and Livewire Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Shows how to embed a timeline in a custom dashboard page using Filament's Livewire component. The widget uses TimelineEntry with title, content, image, author, and time methods, and configures the table with defaultSort, defaultGroup, recordActions, and paginated. ```php use Devletes\FilamentTimelineView\Tables\Columns\TimelineEntry; use Filament\Tables\Grouping\Group; use Filament\Tables\Table; use Filament\Widgets\TableWidget; class CompanyPulseWidget extends TableWidget { protected int|string|array $columnSpan = 'full'; public function table(Table $table): Table { return $table ->heading('Company Pulse') ->description('Latest updates across the company.') ->query(fn () => app(EmployeeDashboardService::class) ->pulseFeedQuery(Filament::auth()->user()) ->with(['author'])) ->defaultSort('published_at', 'desc') ->columns([ TimelineEntry::make() ->title('title') ->content('excerpt') ->image('hero_url') ->author('author.name', 'author.avatar_url') ->time('published_at'), ]) ->defaultGroup(Group::make('published_at')->date()) ->recordActions([ Action::make('view') ->icon('heroicon-m-eye') ->url(fn ($record) => PulsePostResource::getUrl('view', ['record' => $record])), ]) ->paginated([5]) ->asTimeline(); } } ``` ```php use Filament\Schemas\Components\Livewire; public function content(Schema $schema): Schema { return $schema->components([ Livewire::make(CompanyPulseWidget::class)->columnSpan('full'), ]); } ``` -------------------------------- ### author() method signature Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Signature for the author() setter. Accepts a name field path or closure and an optional avatar field path or closure. Returns static for chaining. Footer renders when either name or time is filled; avatar renders only when avatar is filled. ```php public function author(string|Closure $name, string|Closure|null $avatar = null): static ``` -------------------------------- ### asDoubleSidedTimeline() Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/table-macros.md Switches the table's view to the timeline view with a double-sided layout. Takes no parameters and returns the table instance for chaining. ```APIDOC ## asDoubleSidedTimeline() ### Description Switches the table's view to `filament-timeline-view::tables.timeline` and sets the view data `timelineLayout` to `'double'`. Takes no parameters and returns the table instance. ### Method Macro (instance method on `Filament\Tables\Table`) ### Endpoint `->asDoubleSidedTimeline()` ### Parameters No parameters. ### Returns - **Table** - The same table instance, chainable. ### Example ```php $table->asDoubleSidedTimeline(); ``` ### Response No response body; the table's view and view data are modified in place. ``` -------------------------------- ### image() Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Sets a media image, rendered as an img element inside a media block. The wrapper card receives a modifier class when the resolved image is filled. ```APIDOC ## image() ### Description Sets a media image, rendered as `<img class="ftv-card-image">` inside a `ftv-card-media` block. The wrapper card additionally receives the modifier class `ftv-card-layout-has-media` whenever the resolved image is filled. ### Method `public function image(string|Closure $field): static` ### Parameters - **$field** (string|Closure) - Required - Image URL field path or closure ### Returns `static` - `$this`, for chaining. ``` -------------------------------- ### Double-sided timeline with asDoubleSidedTimeline() Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Swaps asTimeline() for asDoubleSidedTimeline() to render a double-sided timeline where cards alternate left/right per date. The first item of each date always appears on the left, and the layout collapses to a single column below 768px. ```php return $table ->columns([TimelineEntry::make()->...]) ->groups([Group::make('published_at')->date()]) ->asDoubleSidedTimeline(); ``` -------------------------------- ### toEmbeddedHtml() Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Renders the card's inner HTML from the current record. It resolves title, content, image, authorName, authorAvatar, and time fields, and returns the HTML fragment. ```APIDOC ## toEmbeddedHtml() ### Description Renders the card's inner HTML from the current record (fetched with the inherited getRecord()). Implements HasEmbeddedView. ### Method public function toEmbeddedHtml(): string ### Parameters None. ### Returns string - The card's inner HTML fragment (the partial wraps it in the .ftv-card chrome). ### Throws The package itself throws nothing; exceptions may only originate from a user closure ($field($record)) or from Carbon::parse($value) on an unparseable value. Neither is caught. A missing field path makes data_get() resolve to null, which the filled() guards turn into omitted markup rather than an error. ### Resolution Order 1. Resolves title, content, image, authorName, authorAvatar via resolveFieldValue() and time via resolveTimeValue(). 2. $hasMedia = filled($image) - adds ftv-card-layout-has-media to the wrapper and renders the media block. 3. $hasFooter = filled($authorName) || filled($time) - renders the ftv-card-meta footer only when true. 4. Title and content elements are each wrapped in filled() guards; blank values omit the element entirely. 5. All output is escaped with e(); content additionally passes nl2br(). ### Example - rendering in isolation (as used by tests) ```php use Carbon\CarbonInterface; use Illuminate\Support\Carbon; use Devletes\FilamentTimelineView\Tables\Columns\TimelineEntry; $entry = TimelineEntry::make() ->title('subject') ->content('body') ->time(fn () => Carbon::parse('2026-04-25 09:15:00'), 'g:i A'); $html = $entry->record(['subject' => 'Quarterly review', 'body' => "line one\nline two"]) ->toEmbeddedHtml(); // "<h3 class=\"ftv-card-title\">Quarterly review</h3><p ...>line one<br>line two</p>" ``` ### Example - error-tolerant rendering ```php // Null/missing fields never raise - the affected section is omitted. $record = ['subject' => null, 'author' => null, 'published_at' => null]; $html = TimelineEntry::make() ->title('subject') ->author('author.name') ->time('published_at', 'H:i') ->record($record) ->toEmbeddedHtml(); // $html contains the empty ftv-card-layout wrapper, with no title, no footer, // and (because filled($image) is false) no ftv-card-layout-has-media modifier. ``` ``` -------------------------------- ### time() Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Sets the card footer time stamp. String field paths are Carbon-parsed and formatted; closure results are passed through a resolution method. ```APIDOC ## time() ### Description Sets the card footer time stamp (`ftv-card-meta-time`). A **string** field path is Carbon-parsed and formatted with `translatedFormat($format)`. A **closure** result is passed through `resolveTimeValue()`: a `CarbonInterface` instance is formatted with `$format`; any other non-blank value is cast to string and used verbatim. ### Method `public function time(string|Closure $field, string $format = 'g:i A'): static` ### Parameters - **$field** (string|Closure) - Required - Time field path or closure returning a Carbon instance or pre-formatted string - **$format** (string) - Optional, default `'g:i A'` - Carbon `translatedFormat()` pattern (e.g. `'H:i'`, `'g:i A'`) ### Returns `static` - `$this`, for chaining. ``` -------------------------------- ### Imports used by TimelineViewServiceProvider Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-view-service-provider.md Imports the Filament and Laravel classes used within the service provider. ```php use Filament\Support\Assets\Css; use Filament\Support\Facades\FilamentAsset; use Filament\Tables\Table; use Illuminate\Support\ServiceProvider; ``` -------------------------------- ### Class declaration for TimelineViewServiceProvider Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-view-service-provider.md Declares the TimelineViewServiceProvider class extending the Laravel ServiceProvider base class. ```php class TimelineViewServiceProvider extends ServiceProvider ``` -------------------------------- ### Custom layout with Stack and Split Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Shows a custom inner layout for TimelineEntry using Stack and Split components. This replaces the default TimelineEntry structure while the timeline still provides the card chrome, dot, caret, and actions kebab. ```php use Filament\Tables\Columns\ImageColumn; use Filament\Tables\Columns\Layout\Split; use Filament\Tables\Columns\Layout\Stack; use Filament\Tables\Columns\TextColumn; ->columns([ Stack::make([ Split::make([ ImageColumn::make('cover_url')->circular()->size(60)->grow(false), Stack::make([ TextColumn::make('title')->weight('bold')->size('lg'), TextColumn::make('summary')->color('gray'), Split::make([ TextColumn::make('author.name')->size('xs')->color('gray'), TextColumn::make('published_at')->time()->size('xs')->color('gray')->alignEnd(), ]), ]), ]), ]), ]) ``` -------------------------------- ### Verify macros are registered Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/table-macros.md PHPUnit assertions that check the asTimeline and asDoubleSidedTimeline macros exist on the Table class. Used in the test suite to confirm registration. ```php expect(Table::hasMacro('asTimeline'))->toBeTrue(); expect(Table::hasMacro('asDoubleSidedTimeline'))->toBeTrue(); ``` -------------------------------- ### TimelineEntry class declaration Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Declares the TimelineEntry class, extending Filament's layout Component and implementing the HasEmbeddedView contract. ```php class TimelineEntry extends Component implements HasEmbeddedView ``` -------------------------------- ### Group by date with newest-first ordering Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Use this snippet to group by date and order groups newest-first. Filament's date grouping defaults to ascending order, which puts Today at the bottom; this overrides that with orderByDesc on the query. ```php ->defaultGroup( Group::make('published_at') ->date() ->orderQueryUsing(fn ($query) => $query->orderByDesc('published_at')) ) ``` -------------------------------- ### formatTime method signature Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Blank input returns null; otherwise parses via $value instanceof CarbonInterface ? $value : Carbon::parse($value) and returns $carbon->translatedFormat($this->timeFormat). Source line 161. ```php protected function formatTime(mixed $value): ?string ``` -------------------------------- ### Group by date with defaultGroup Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Use this snippet to group timeline entries by the 'published_at' date. Pass the Group instance directly to ->defaultGroup(...); no separate ->groups([...]) array is needed unless you want the group selector in the toolbar. ```php ->defaultGroup(Group::make('published_at')->date()) ``` -------------------------------- ### title() method signature Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Signature for the title() setter. Accepts a string field path or closure, returns static for chaining. Renders as <h3 class="ftv-card-title"> only when the resolved value is filled. ```php public function title(string|Closure $field): static ``` -------------------------------- ### content() Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Sets the card body/excerpt field, rendered as a paragraph element with newlines converted to line breaks. Accepts a field path string or a closure. ```APIDOC ## content() ### Description Sets the card body/excerpt field, rendered as `<p class="ftv-card-content">`; newlines are converted to `<br>` via `nl2br()`. ### Method `public function content(string|Closure $field): static` ### Parameters - **$field** (string|Closure) - Required - Content field path or closure ### Returns `static` - `$this`, for chaining. ``` -------------------------------- ### Both variants from one widget Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/table-macros.md Widget class that selects between asDoubleSidedTimeline() and asTimeline() based on a variant property. The default case uses asTimeline(). ```php class StubTimelineWidget extends TableWidget { public string $variant = 'single'; public function table(Table $table): Table { return match ($this->variant) { 'double' => $table->columns([])->asDoubleSidedTimeline(), default => $table->columns([])->asTimeline(), }; } } ``` -------------------------------- ### Apply filters with SelectFilter Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Use `->filters([...])` on the timeline to add a multiple-select filter for the 'category' column. The filter UI matches Filament's standard table filters, including deferred filters, session persistence, indicators, and reset action. By default, filters are behind a funnel trigger in the header toolbar, badged with the active filter count. ```php ->filters([ SelectFilter::make('category') ->multiple() ->options([ 'Announcement' => 'Announcement', 'Article' => 'Article', ]), ]) ``` -------------------------------- ### author() Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Sets the card footer author with an optional avatar image. The footer renders when either the name or time field resolves to a filled value. ```APIDOC ## author() ### Description Sets the card footer author: a small avatar image (`ftv-card-meta-user-avatar`) plus the author's name (`ftv-card-meta-user-name`). The footer (`ftv-card-meta`) renders when either `$name` or the `time` field resolves to a filled value; the avatar image renders only when `$avatar` is filled. ### Method `public function author(string|Closure $name, string|Closure|null $avatar = null): static` ### Parameters - **$name** (string|Closure) - Required - Author name field path (e.g. `'author.name'`) or closure - **$avatar** (string|Closure|null) - Optional, default `null` - Author avatar URL field path or closure; `null` omits the avatar ### Returns `static` - `$this`, for chaining. ``` -------------------------------- ### Make day groups collapsible Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Use this snippet to make day groups collapsible. Call ->collapsible() on the Group; when enabled, each date header shows a chevron toggle that hides/shows the day's cards via Alpine.js (no Livewire round-trip). Collapsed groups show a translated 'N posts hidden' pill (collapsed_summary translation key). ```php ->defaultGroup(Group::make('published_at')->date()->collapsible()) ``` -------------------------------- ### registerTableMacros() method signature Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-view-service-provider.md Signature of the protected registerTableMacros() method that registers timeline macros on the Table class. ```php protected function registerTableMacros(): void ``` -------------------------------- ### Load-more pagination step calculation in timeline.blade.php Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/table-macros.md Computes the load-more step from the first integer in pagination page options (default 5), determines the next per-page value, and checks if more pages exist. Used to render the load-more button that increments the table's records per page. ```php $loadMoreStep = (int) (collect($getPaginationPageOptions())->first(fn ($option) => is_int($option)) ?? 5); $currentPerPage = $records instanceof \Illuminate\Contracts\Pagination\Paginator ? (int) $records->perPage() : null; $loadMoreNextPerPage = ($currentPerPage !== null) ? ($currentPerPage + $loadMoreStep) : null; $hasMorePages = $hasPagination && method_exists($records, 'hasMorePages') && $records->hasMorePages(); ``` -------------------------------- ### toEmbeddedHtml() method signature Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Signature of the method that implements HasEmbeddedView. It renders the card's inner HTML from the current record fetched with the inherited getRecord(). ```php public function toEmbeddedHtml(): string ``` -------------------------------- ### TimelineEntry Class Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md The TimelineEntry class is a layout column for timeline cards. It extends Filament\Tables\Columns\Layout\Component and implements HasEmbeddedView. It is used inside the columns array of a Filament Table. ```APIDOC ## TimelineEntry Class ### Description The `TimelineEntry` class is a layout column that produces the inner content of a single timeline card. It is used inside `->columns([...])` on a `Filament\Tables\Table`, combined with the `->asTimeline()` / `->asDoubleSidedTimeline()` macros. ### Class Declaration ```php class TimelineEntry extends Component implements HasEmbeddedView ``` - Extends `Filament\Tables\Columns\Layout\Component` - Implements `Filament\Support\Components\Contracts\HasEmbeddedView` (contract: `toEmbeddedHtml(): string`) ### Import Path ```php use Devletes\FilamentTimelineView\Tables\Columns\TimelineEntry; ``` ### Type Semantics | Type | Meaning | |---|---| | `Closure` | A callable; invoked with the record, e.g. `fn ($record) => $record->getUrl('thumb')`. | | `string\|Closure\|null` | Either a dot-notation field path (resolved with `data_get($record, $field)`), a callable receiving the record, or unset (`null`). | | `static` | The instance type of the declaring class (fluent chain return); for `TimelineEntry` this is a `TimelineEntry` instance. | | `CarbonInterface` | Any Carbon date/time instance (`Illuminate\Support\Carbon` or compatible). | | `mixed` | Any record attribute value (the raw field value before formatting). | ### Usage Used inside `->columns([...])` on a `Filament\Tables\Table`, combined with the `->asTimeline()` / `->asDoubleSidedTimeline()` macros. The card chrome (border, padding, dot, caret, actions kebab) is rendered by the package blade regardless of which layout column is used, so `TimelineEntry` may be dropped in favour of any other layout component (`Stack::make([...])`, `Split::make([...])`) without losing the timeline rendering. ``` -------------------------------- ### title() Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Sets the card title field, rendered as an h3 element only when the resolved value is filled. Accepts a field path string or a closure receiving the record. ```APIDOC ## title() ### Description Sets the card title field, rendered as `<h3 class="ftv-card-title">` only when the resolved value is filled. ### Method `public function title(string|Closure $field): static` ### Parameters - **$field** (string|Closure) - Required - Title field path (e.g. `'title'`) or a closure receiving the record ### Returns `static` - `$this`, for chaining. ### Throws None (blank values make the element render omitted). ``` -------------------------------- ### resolveTimeValue method signature Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Resolves the time stamp. null time field returns null. Closure branch: blank result returns null; CarbonInterface result returns translatedFormat($this->timeFormat); anything else returns (string) $value verbatim. String branch delegates to formatTime(data_get($record, $this->timeField)). Source line 138. ```php protected function resolveTimeValue(mixed $record): ?string ``` -------------------------------- ### resolveFieldValue method signature Source: https://github.com/devletes/filament-timeline-view/blob/main/_autodocs/api-reference/timeline-entry.md Resolves one field: null returns null; Closure invokes $field($record); otherwise data_get($record, $field). Source line 125. ```php protected function resolveFieldValue(string|Closure|null $field, mixed $record): mixed ``` -------------------------------- ### Override timeline CSS custom properties Source: https://github.com/devletes/filament-timeline-view/blob/main/README.md Add these CSS rules to your panel's theme CSS to customize the timeline's appearance. The `.fi-ta-timeline` rule overrides container padding, and the `.dark .ftv-shell` rule adjusts the line color for dark mode. ```css .fi-ta-timeline { /* Override container padding, e.g. flush against the section card. */ padding: 0; } .dark .ftv-shell { --ftv-line-color: oklch(50% 0.04 240); } ```