PHPackages                             andreia/filament-recurrence - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. andreia/filament-recurrence

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

andreia/filament-recurrence
===========================

A Filament plugin for handling recurrence patterns with form fields, table columns, and infolist components

v1.1.1(2w ago)1752↑100%4MITPHPPHP ^8.3

Since May 10Pushed 2w ago1 watchersCompare

[ Source](https://github.com/andreia/filament-recurrence)[ Packagist](https://packagist.org/packages/andreia/filament-recurrence)[ Fund](https://www.buymeacoffee.com/andreiabohner)[ Fund](https://donate.stripe.com/3cIeVf1x3eWS2xq8f3dby02)[ RSS](/packages/andreia-filament-recurrence/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (3)Dependencies (10)Versions (5)Used By (0)

Filament Recurrence Plugin
==========================

[](#filament-recurrence-plugin)

A full-featured Filament PHP plugin for handling recurrence patterns with form fields, table columns, and infolist components.

Features
--------

[](#features)

- **Complete Recurrence Support** - Daily, Weekly, Monthly, and Yearly patterns
- **Form Field Component** - Beautiful, reactive form fields for defining recurrence rules
- **Table Column Component** - Display recurrence patterns in your Filament tables
- **Infolist Entry Component** - Detailed recurrence information in your infolists
- **Type-Safe** - Full PHP 8.3+ type hints with RecurrenceData DTO
- **Eloquent Cast** - Easy model integration with custom cast
- **Model Trait** - Helper methods for working with recurring events
- **RRULE Compatible** - Full RFC 5545 iCalendar recurrence rule support
- **Customizable** - Extensive configuration options
- **Per-record timezone** - Timezone select stored with recurrence JSON; defaults from `config/filament-recurrence.php`

[![Filament Recurrence Demo Video](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/demo_video.jpg)](https://www.youtube.com/watch?v=NOg2IYgJ1W4)

Requirements
------------

[](#requirements)

- PHP 8.3+
- Laravel 12+
- Filament 4/5

Dependencies
------------

[](#dependencies)

Built on top of the powerful [simshaun/recurr](https://github.com/simshaun/recurr) package.

The recurrence form uses [`tapp/filament-timezone-field`](https://github.com/TappNetwork/filament-timezone-field) for the timezone dropdown.

Composer installs both automatically as a dependency of this package.

Appearance
----------

[](#appearance)

### Form Field

[](#form-field)

[![Form Field Example 1](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/form-field.png)](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/form-field.png)

[![Form Field Example 2](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/form-field1.png)](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/form-field1.png)

[![Form Field Example 3](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/form-field2.png)](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/form-field2.png)

[![Form Field Example 4](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/form-field3.png)](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/form-field3.png)

### Table Column

[](#table-column)

[![Table Column](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/table-column.png)](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/table-column.png)

### Infolist

[](#infolist)

[![Infolist Entry](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/infolist.png)](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/infolist.png)

Installation
------------

[](#installation)

Install the package via Composer:

```
composer require andreia/filament-recurrence
```

### Database

[](#database)

Recurrence is stored as JSON on **your** model’s table. Add a nullable `json` column (name it however you like; the docs assume `recurrence`):

```
php artisan make:migration add_recurrence_to_your_table
```

```
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::table('your_table', function (Blueprint $table) {
            $table->json('recurrence')->nullable()->after('your_column');
        });
    }

    public function down(): void
    {
        Schema::table('your_table', function (Blueprint $table) {
            $table->dropColumn('recurrence');
        });
    }
};
```

```
php artisan migrate
```

### Configuration (optional)

[](#configuration-optional)

Publish the configuration file:

```
php artisan vendor:publish --tag="filament-recurrence-config"
```

Available options in `config/filament-recurrence.php`:

The `timezone` value is the **default** for new recurrence records and data without a stored timezone. Each record can override it using the **Timezone** field; the chosen identifier (e.g. `Europe/Berlin`) is persisted in the recurrence payload alongside other fields.

```
return [
    'timezone' => 'UTC',
    'date_format' => 'Y-m-d',
    'time_format' => 'H:i',
    'max_preview_occurrences' => 10,
    'frequencies' => [
        'DAILY' => 'Daily',
        'WEEKLY' => 'Weekly',
        'MONTHLY' => 'Monthly',
        'YEARLY' => 'Yearly',
    ],
    'week_start_day' => 1, // Monday
    'enable_advanced_options' => true,
];
```

Add to your Filament `theme.css`:

```
@source '../../../../vendor/andreia/filament-recurrence';
```

and run `npm run build` or `bun run build`.

Model Setup
-----------

[](#model-setup)

### Using the Cast

[](#using-the-cast)

Add the cast to your model:

```
use Andreia\FilamentRecurrence\Casts\RecurrenceCast;

class Event extends Model
{
    protected $casts = [
        'recurrence' => RecurrenceCast::class,
    ];
}
```

### Using the Trait

[](#using-the-trait)

Add helpful methods to your model:

```
use Andreia\FilamentRecurrence\Concerns\HasRecurrence;

class Event extends Model
{
    use HasRecurrence;

    protected $casts = [
        'recurrence' => RecurrenceCast::class,
    ];
}

// Now you can use:
$event->getRecurrenceData(); // Get RecurrenceData object
$event->getNextOccurrence(); // Get next occurrence as Carbon
$event->getUpcomingOccurrences(10); // Get next 10 occurrences
$event->occursOn(Carbon::parse('2024-12-25')); // Check if occurs on date

// Query scopes:
Event::occursOn(Carbon::today())->get();
Event::occursBetween(Carbon::now(), Carbon::now()->addMonth())->get();
```

Basic Usage
-----------

[](#basic-usage)

### Form Field

[](#form-field-1)

Add the recurrence field to your Filament form:

```
use Andreia\FilamentRecurrence\Forms\Components\RecurrenceField;

public static function form(Form $form): Form
{
    return $form
        ->schema([
            TextInput::make('title')->required(),

            RecurrenceField::make('recurrence')
                ->showStartDate()
                ->showEndOptions()
                ->useDateTime(), // Use DateTimePicker instead of DatePicker
        ]);
}
```

### Table Column

[](#table-column-1)

Display recurrence patterns in your table:

```
use Andreia\FilamentRecurrence\Tables\Columns\RecurrenceColumn;

public static function table(Table $table): Table
{
    return $table
        ->columns([
            TextColumn::make('title'),

            RecurrenceColumn::make('recurrence')
                ->showNextOccurrences(limit: 3)
                ->showRule(),
        ]);
}
```

### Infolist Entry

[](#infolist-entry)

Show detailed recurrence information:

```
use Andreia\FilamentRecurrence\Infolists\Components\RecurrenceEntry;

public static function infolist(Infolist $infolist): Infolist
{
    return $infolist
        ->schema([
            TextEntry::make('title'),

            RecurrenceEntry::make('recurrence')
                ->showAllDetails()
                ->showNextOccurrences(limit: 10)
                ->showRule(),
        ]);
}
```

Advanced Usage
--------------

[](#advanced-usage)

### Working with RecurrenceData

[](#working-with-recurrencedata)

The `RecurrenceData` DTO provides a clean interface for working with recurrence patterns:

```
use Andreia\FilamentRecurrence\Data\RecurrenceData;
use Carbon\Carbon;

// Create from array
$data = RecurrenceData::fromArray([
    'frequency' => 'WEEKLY',
    'interval' => 2,
    'start_date' => Carbon::now(),
    'by_day' => ['MO', 'WE', 'FR'],
    'count' => 10,
]);

// Create from RRULE string
$data = RecurrenceData::fromRule('FREQ=DAILY;INTERVAL=1;COUNT=5');

// Convert to RRULE string
$rule = $data->toRule();

// Get human-readable description
$description = $data->toHumanReadable(); // "Every 2 weeks on Monday, Wednesday, Friday, 10 times"

// Get occurrences
$occurrences = $data->getOccurrences(limit: 5);

// Convert to array
$array = $data->toArray();
```

### Form Field Customization

[](#form-field-customization)

```
RecurrenceField::make('recurrence')
    ->showStartDate(true) // Show/hide start date picker
    ->showEndOptions(true) // Show/hide end options (never, until, count)
    ->showPreview(true) // Show/hide the live preview (human-readable rule + next occurrences); default is true
    ->previewOccurrencesLimit(5) // How many “next occurrences” rows to show in the preview; default is 5
    ->useDateTime(true) // Use datetime picker instead of date picker
    ->showTimezone(true) // Show/hide the per-record timezone select (default true); when false, config timezone is always used
    ->showAdvancedOptions(true) // Show advanced recurrence options

// Hide the preview (full-width form only):
RecurrenceField::make('recurrence')->showPreview(false);

// Use only `config('filament-recurrence.timezone')` for every record (hide the timezone field):
RecurrenceField::make('recurrence')->showTimezone(false);

// Show 10 upcoming dates in the preview:
RecurrenceField::make('recurrence')->previewOccurrencesLimit(10);
```

### Table Column Customization

[](#table-column-customization)

```
RecurrenceColumn::make('recurrence')
    ->showRule(true) // Display the RRULE string
    ->showNextOccurrences(true, limit: 5) // Show next N occurrences
```

### Infolist Entry Customization

[](#infolist-entry-customization)

```
RecurrenceEntry::make('recurrence')
    ->showRule(true) // Display the RRULE string
    ->showAllDetails(true) // Show all recurrence details
    ->showNextOccurrences(true, limit: 20) // Show next N occurrences
```

Recurrence Patterns Examples
----------------------------

[](#recurrence-patterns-examples)

### Daily Patterns

[](#daily-patterns)

```
// Every day
[
    'frequency' => 'DAILY',
    'interval' => 1,
    'start_date' => Carbon::now(),
]

// Every 3 days, 10 times
[
    'frequency' => 'DAILY',
    'interval' => 3,
    'count' => 10,
]
```

### Weekly Patterns

[](#weekly-patterns)

```
// Every week on Monday and Friday
[
    'frequency' => 'WEEKLY',
    'interval' => 1,
    'by_day' => ['MO', 'FR'],
]

// Every 2 weeks on weekdays
[
    'frequency' => 'WEEKLY',
    'interval' => 2,
    'by_day' => ['MO', 'TU', 'WE', 'TH', 'FR'],
]
```

### Monthly Patterns

[](#monthly-patterns)

```
// Every month on the 15th
[
    'frequency' => 'MONTHLY',
    'interval' => 1,
    'by_month_day' => [15],
]

// Every month on the first Monday
[
    'frequency' => 'MONTHLY',
    'interval' => 1,
    'by_day' => ['MO'],
    'by_set_pos' => 1,
]

// Every month on the last Friday
[
    'frequency' => 'MONTHLY',
    'interval' => 1,
    'by_day' => ['FR'],
    'by_set_pos' => -1,
]
```

### Yearly Patterns

[](#yearly-patterns)

```
// Every year on January 1st
[
    'frequency' => 'YEARLY',
    'interval' => 1,
    'by_month' => [1],
    'by_month_day' => [1],
]

// Every year in June and December
[
    'frequency' => 'YEARLY',
    'interval' => 1,
    'by_month' => [6, 12],
]
```

Testing
-------

[](#testing)

```
composer test
```

Code Formatting
---------------

[](#code-formatting)

```
composer format
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- Built on [simshaun/recurr](https://github.com/simshaun/recurr)
- Timezone select from [TappNetwork/filament-timezone-field](https://github.com/TappNetwork/filament-timezone-field)
- [Filament](https://filamentphp.com)

Love this project? Help keep it growing! 🚀
------------------------------------------

[](#love-this-project-help-keep-it-growing-)

I built Filament Recurrence to be a powerful tool for the community, and your support is what keeps it running. If this project has saved you time or solved a headache, consider showing your appreciation:

- **Spread the Word**: Share it, contribute code or feedback.
- **One-off Donation**: Support via [Stripe](https://donate.stripe.com/3cIeVf1x3eWS2xq8f3dby02).
- **Become a Sponsor**: Help me reach my next development milestone by [Sponsoring on GitHub](https://github.com/sponsors/andreia).
- **Buying me a Coffee** – If you prefer [Buy me a Coffee](https://buymeacoffee.com/andreiabohner) platform

Thank you for supporting open-source development! ❤️

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

---

Made with ❤️ for the Filament community

###  Health Score

47

—

FairBetter than 93% of packages

Maintenance96

Actively maintained with recent releases

Popularity22

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~5 days

Total

3

Last Release

18d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/413354?v=4)[andreiabohner](/maintainers/andreiabohner)[@andreiabohner](https://github.com/andreiabohner)

---

Tags

filamentfilamentphpfilamentphp-pluginphprecurrencerecurrence-rules

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/andreia-filament-recurrence/health.svg)

```
[![Health](https://phpackages.com/badges/andreia-filament-recurrence/health.svg)](https://phpackages.com/packages/andreia-filament-recurrence)
```

###  Alternatives

[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3913.7k](/packages/rawilk-profile-filament-plugin)[dotswan/filament-map-picker

Easily pick and retrieve geo-coordinates using a map-based interface in your Filament applications.

127173.7k3](/packages/dotswan-filament-map-picker)[stephenjude/filament-jetstream

A Laravel starter kit built with Filament inspired by Jetstream.

17758.9k2](/packages/stephenjude-filament-jetstream)[stephenjude/filament-debugger

About

103150.5k2](/packages/stephenjude-filament-debugger)[creagia/filament-code-field

A Filamentphp input field to edit or view code data.

57301.3k3](/packages/creagia-filament-code-field)[hydrat/filament-table-layout-toggle

Filament plugin adding a toggle button to tables, allowing user to switch between Grid and Table layouts.

63105.4k2](/packages/hydrat-filament-table-layout-toggle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
