{"id":51137366,"url":"https://github.com/andreia/filament-recurrence","last_synced_at":"2026-06-25T19:02:56.323Z","repository":{"id":359427271,"uuid":"1228300374","full_name":"andreia/filament-recurrence","owner":"andreia","description":"A full-featured and flexible Filament PHP plugin for handling recurrence patterns with a beautiful UI","archived":false,"fork":false,"pushed_at":"2026-05-21T20:24:43.000Z","size":3012,"stargazers_count":17,"open_issues_count":2,"forks_count":3,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-22T05:47:18.909Z","etag":null,"topics":["filament","filamentphp","filamentphp-plugin","php","recurrence","recurrence-rules"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andreia.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"andreia","custom":"https://donate.stripe.com/3cIeVf1x3eWS2xq8f3dby02","buy_me_a_coffee":"andreiabohner"}},"created_at":"2026-05-03T21:15:46.000Z","updated_at":"2026-05-21T20:23:52.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/andreia/filament-recurrence","commit_stats":null,"previous_names":["andreia/filament-recurrence"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/andreia/filament-recurrence","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreia%2Ffilament-recurrence","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreia%2Ffilament-recurrence/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreia%2Ffilament-recurrence/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreia%2Ffilament-recurrence/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andreia","download_url":"https://codeload.github.com/andreia/filament-recurrence/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreia%2Ffilament-recurrence/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34788257,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-25T02:00:05.521Z","response_time":101,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["filament","filamentphp","filamentphp-plugin","php","recurrence","recurrence-rules"],"created_at":"2026-06-25T19:02:55.559Z","updated_at":"2026-06-25T19:02:56.301Z","avatar_url":"https://github.com/andreia.png","language":"PHP","funding_links":["https://github.com/sponsors/andreia","https://donate.stripe.com/3cIeVf1x3eWS2xq8f3dby02","https://buymeacoffee.com/andreiabohner"],"categories":[],"sub_categories":[],"readme":"# Filament Recurrence Plugin\n\nA full-featured Filament PHP plugin for handling recurrence patterns with form fields, table columns, and infolist components. \n\n## Features\n\n- **Complete Recurrence Support** - Daily, Weekly, Monthly, and Yearly patterns\n- **Form Field Component** - Beautiful, reactive form fields for defining recurrence rules\n- **Table Column Component** - Display recurrence patterns in your Filament tables\n- **Infolist Entry Component** - Detailed recurrence information in your infolists\n- **Type-Safe** - Full PHP 8.3+ type hints with RecurrenceData DTO\n- **Eloquent Cast** - Easy model integration with custom cast\n- **Model Trait** - Helper methods for working with recurring events\n- **RRULE Compatible** - Full RFC 5545 iCalendar recurrence rule support\n- **Customizable** - Extensive configuration options\n- **Per-record timezone** - Timezone select stored with recurrence JSON; defaults from `config/filament-recurrence.php`\n\n[![Filament Recurrence Demo Video](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/demo_video.jpg)](https://www.youtube.com/watch?v=NOg2IYgJ1W4)\n\n## Requirements\n\n- PHP 8.3+\n- Laravel 12+\n- Filament 4/5\n\n## Dependencies\n\nBuilt on top of the powerful [simshaun/recurr](https://github.com/simshaun/recurr) package.\n\nThe recurrence form uses [`tapp/filament-timezone-field`](https://github.com/TappNetwork/filament-timezone-field) for the timezone dropdown.\n\nComposer installs both automatically as a dependency of this package.\n\n## Appearance\n\n### Form Field\n\n![Form Field Example 1](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/form-field.png)\n\n![Form Field Example 2](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/form-field1.png)\n\n![Form Field Example 3](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/form-field2.png)\n\n![Form Field Example 4](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/form-field3.png)\n\n### Table Column\n\n![Table Column](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/table-column.png)\n\n### Infolist\n\n![Infolist Entry](https://raw.githubusercontent.com/andreia/filament-recurrence/main/art/infolist.png)\n\n## Installation\n\nInstall the package via Composer:\n\n```bash\ncomposer require andreia/filament-recurrence\n```\n\n### Database\n\nRecurrence is stored as JSON on **your** model’s table. Add a nullable `json` column (name it however you like; the docs assume `recurrence`):\n\n```bash\nphp artisan make:migration add_recurrence_to_your_table\n```\n\n```php\nuse Illuminate\\Database\\Migrations\\Migration;\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Support\\Facades\\Schema;\n\nreturn new class extends Migration\n{\n    public function up(): void\n    {\n        Schema::table('your_table', function (Blueprint $table) {\n            $table-\u003ejson('recurrence')-\u003enullable()-\u003eafter('your_column');\n        });\n    }\n\n    public function down(): void\n    {\n        Schema::table('your_table', function (Blueprint $table) {\n            $table-\u003edropColumn('recurrence');\n        });\n    }\n};\n```\n\n```bash\nphp artisan migrate\n```\n\n### Configuration (optional)\n\nPublish the configuration file:\n\n```bash\nphp artisan vendor:publish --tag=\"filament-recurrence-config\"\n```\n\nAvailable options in `config/filament-recurrence.php`:\n\nThe `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.\n\n```php\nreturn [\n    'timezone' =\u003e 'UTC',\n    'date_format' =\u003e 'Y-m-d',\n    'time_format' =\u003e 'H:i',\n    'max_preview_occurrences' =\u003e 10,\n    'frequencies' =\u003e [\n        'DAILY' =\u003e 'Daily',\n        'WEEKLY' =\u003e 'Weekly',\n        'MONTHLY' =\u003e 'Monthly',\n        'YEARLY' =\u003e 'Yearly',\n    ],\n    'week_start_day' =\u003e 1, // Monday\n    'enable_advanced_options' =\u003e true,\n];\n```\n\nAdd to your Filament `theme.css`:\n\n```css\n@source '../../../../vendor/andreia/filament-recurrence';\n```\n\nand run `npm run build` or `bun run build`.\n\n## Model Setup\n\n### Using the Cast\n\nAdd the cast to your model:\n\n```php\nuse Andreia\\FilamentRecurrence\\Casts\\RecurrenceCast;\n\nclass Event extends Model\n{\n    protected $casts = [\n        'recurrence' =\u003e RecurrenceCast::class,\n    ];\n}\n```\n\n### Using the Trait\n\nAdd helpful methods to your model:\n\n```php\nuse Andreia\\FilamentRecurrence\\Concerns\\HasRecurrence;\n\nclass Event extends Model\n{\n    use HasRecurrence;\n\n    protected $casts = [\n        'recurrence' =\u003e RecurrenceCast::class,\n    ];\n}\n\n// Now you can use:\n$event-\u003egetRecurrenceData(); // Get RecurrenceData object\n$event-\u003egetNextOccurrence(); // Get next occurrence as Carbon\n$event-\u003egetUpcomingOccurrences(10); // Get next 10 occurrences\n$event-\u003eoccursOn(Carbon::parse('2024-12-25')); // Check if occurs on date\n\n// Query scopes:\nEvent::occursOn(Carbon::today())-\u003eget();\nEvent::occursBetween(Carbon::now(), Carbon::now()-\u003eaddMonth())-\u003eget();\n```\n\n## Basic Usage\n\n### Form Field\n\nAdd the recurrence field to your Filament form:\n\n```php\nuse Andreia\\FilamentRecurrence\\Forms\\Components\\RecurrenceField;\n\npublic static function form(Form $form): Form\n{\n    return $form\n        -\u003eschema([\n            TextInput::make('title')-\u003erequired(),\n            \n            RecurrenceField::make('recurrence')\n                -\u003eshowStartDate()\n                -\u003eshowEndOptions()\n                -\u003euseDateTime(), // Use DateTimePicker instead of DatePicker\n        ]);\n}\n```\n\n### Table Column\n\nDisplay recurrence patterns in your table:\n\n```php\nuse Andreia\\FilamentRecurrence\\Tables\\Columns\\RecurrenceColumn;\n\npublic static function table(Table $table): Table\n{\n    return $table\n        -\u003ecolumns([\n            TextColumn::make('title'),\n            \n            RecurrenceColumn::make('recurrence')\n                -\u003eshowNextOccurrences(limit: 3)\n                -\u003eshowRule(),\n        ]);\n}\n```\n\n### Infolist Entry\n\nShow detailed recurrence information:\n\n```php\nuse Andreia\\FilamentRecurrence\\Infolists\\Components\\RecurrenceEntry;\n\npublic static function infolist(Infolist $infolist): Infolist\n{\n    return $infolist\n        -\u003eschema([\n            TextEntry::make('title'),\n            \n            RecurrenceEntry::make('recurrence')\n                -\u003eshowAllDetails()\n                -\u003eshowNextOccurrences(limit: 10)\n                -\u003eshowRule(),\n        ]);\n}\n```\n\n## Advanced Usage\n\n### Working with RecurrenceData\n\nThe `RecurrenceData` DTO provides a clean interface for working with recurrence patterns:\n\n```php\nuse Andreia\\FilamentRecurrence\\Data\\RecurrenceData;\nuse Carbon\\Carbon;\n\n// Create from array\n$data = RecurrenceData::fromArray([\n    'frequency' =\u003e 'WEEKLY',\n    'interval' =\u003e 2,\n    'start_date' =\u003e Carbon::now(),\n    'by_day' =\u003e ['MO', 'WE', 'FR'],\n    'count' =\u003e 10,\n]);\n\n// Create from RRULE string\n$data = RecurrenceData::fromRule('FREQ=DAILY;INTERVAL=1;COUNT=5');\n\n// Convert to RRULE string\n$rule = $data-\u003etoRule();\n\n// Get human-readable description\n$description = $data-\u003etoHumanReadable(); // \"Every 2 weeks on Monday, Wednesday, Friday, 10 times\"\n\n// Get occurrences\n$occurrences = $data-\u003egetOccurrences(limit: 5);\n\n// Convert to array\n$array = $data-\u003etoArray();\n```\n\n### Form Field Customization\n\n```php\nRecurrenceField::make('recurrence')\n    -\u003eshowStartDate(true) // Show/hide start date picker\n    -\u003eshowEndOptions(true) // Show/hide end options (never, until, count)\n    -\u003eshowPreview(true) // Show/hide the live preview (human-readable rule + next occurrences); default is true\n    -\u003epreviewOccurrencesLimit(5) // How many “next occurrences” rows to show in the preview; default is 5\n    -\u003euseDateTime(true) // Use datetime picker instead of date picker\n    -\u003eshowTimezone(true) // Show/hide the per-record timezone select (default true); when false, config timezone is always used\n    -\u003eshowAdvancedOptions(true) // Show advanced recurrence options\n\n// Hide the preview (full-width form only):\nRecurrenceField::make('recurrence')-\u003eshowPreview(false);\n\n// Use only `config('filament-recurrence.timezone')` for every record (hide the timezone field):\nRecurrenceField::make('recurrence')-\u003eshowTimezone(false);\n\n// Show 10 upcoming dates in the preview:\nRecurrenceField::make('recurrence')-\u003epreviewOccurrencesLimit(10);\n```\n\n### Table Column Customization\n\n```php\nRecurrenceColumn::make('recurrence')\n    -\u003eshowRule(true) // Display the RRULE string\n    -\u003eshowNextOccurrences(true, limit: 5) // Show next N occurrences\n```\n\n### Infolist Entry Customization\n\n```php\nRecurrenceEntry::make('recurrence')\n    -\u003eshowRule(true) // Display the RRULE string\n    -\u003eshowAllDetails(true) // Show all recurrence details\n    -\u003eshowNextOccurrences(true, limit: 20) // Show next N occurrences\n```\n\n## Recurrence Patterns Examples\n\n### Daily Patterns\n\n```php\n// Every day\n[\n    'frequency' =\u003e 'DAILY',\n    'interval' =\u003e 1,\n    'start_date' =\u003e Carbon::now(),\n]\n\n// Every 3 days, 10 times\n[\n    'frequency' =\u003e 'DAILY',\n    'interval' =\u003e 3,\n    'count' =\u003e 10,\n]\n```\n\n### Weekly Patterns\n\n```php\n// Every week on Monday and Friday\n[\n    'frequency' =\u003e 'WEEKLY',\n    'interval' =\u003e 1,\n    'by_day' =\u003e ['MO', 'FR'],\n]\n\n// Every 2 weeks on weekdays\n[\n    'frequency' =\u003e 'WEEKLY',\n    'interval' =\u003e 2,\n    'by_day' =\u003e ['MO', 'TU', 'WE', 'TH', 'FR'],\n]\n```\n\n### Monthly Patterns\n\n```php\n// Every month on the 15th\n[\n    'frequency' =\u003e 'MONTHLY',\n    'interval' =\u003e 1,\n    'by_month_day' =\u003e [15],\n]\n\n// Every month on the first Monday\n[\n    'frequency' =\u003e 'MONTHLY',\n    'interval' =\u003e 1,\n    'by_day' =\u003e ['MO'],\n    'by_set_pos' =\u003e 1,\n]\n\n// Every month on the last Friday\n[\n    'frequency' =\u003e 'MONTHLY',\n    'interval' =\u003e 1,\n    'by_day' =\u003e ['FR'],\n    'by_set_pos' =\u003e -1,\n]\n```\n\n### Yearly Patterns\n\n```php\n// Every year on January 1st\n[\n    'frequency' =\u003e 'YEARLY',\n    'interval' =\u003e 1,\n    'by_month' =\u003e [1],\n    'by_month_day' =\u003e [1],\n]\n\n// Every year in June and December\n[\n    'frequency' =\u003e 'YEARLY',\n    'interval' =\u003e 1,\n    'by_month' =\u003e [6, 12],\n]\n```\n\n## Testing\n\n```bash\ncomposer test\n```\n\n## Code Formatting\n\n```bash\ncomposer format\n```\n\n## Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.\n\n## Contributing\n\nPlease see [CONTRIBUTING](CONTRIBUTING.md) for details.\n\n## Security Vulnerabilities\n\nPlease review [our security policy](../../security/policy) on how to report security vulnerabilities.\n\n## Credits\n\n- Built on [simshaun/recurr](https://github.com/simshaun/recurr)\n- Timezone select from [TappNetwork/filament-timezone-field](https://github.com/TappNetwork/filament-timezone-field)\n- [Filament](https://filamentphp.com)\n\n## Love this project? Help keep it growing! 🚀\n\nI 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:\n\n- **Spread the Word**: Share it, contribute code or feedback.\n\n- **One-off Donation**: Support via [Stripe](https://donate.stripe.com/3cIeVf1x3eWS2xq8f3dby02). \n\n- **Become a Sponsor**: Help me reach my next development milestone by [Sponsoring on GitHub](https://github.com/sponsors/andreia).\n\n- **Buying me a Coffee** – If you prefer [Buy me a Coffee](https://buymeacoffee.com/andreiabohner) platform\n\nThank you for supporting open-source development! ❤️\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n\n---\n\nMade with ❤️ for the Filament community\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreia%2Ffilament-recurrence","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandreia%2Ffilament-recurrence","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreia%2Ffilament-recurrence/lists"}