PHPackages                             athuli7/temp-guava-calendar - 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. athuli7/temp-guava-calendar

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

athuli7/temp-guava-calendar
===========================

Adds support for vkurko/calendar to Filament PHP.

v0.0.1(1y ago)02MITPHPPHP ^8.1|^8.2

Since Apr 25Pushed 1y agoCompare

[ Source](https://github.com/Athuli7/guavaCZ-calendar)[ Packagist](https://packagist.org/packages/athuli7/temp-guava-calendar)[ Docs](https://github.com/Athuli7/guavaCZ-calendar)[ GitHub Sponsors](https://github.com/GuavaCZ)[ RSS](/packages/athuli7-temp-guava-calendar/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (14)Versions (3)Used By (0)

[![calendar Banner](https://github.com/GuavaCZ/calendar/raw/main/docs/images/banner.jpg)](https://github.com/GuavaCZ/calendar/raw/main/docs/images/banner.jpg)

Adds support for vkurko/calendar to Filament PHP.
=================================================

[](#adds-support-for-vkurkocalendar-to-filament-php)

[![Latest Version on Packagist](https://camo.githubusercontent.com/ed9385ddfb568731d0a659e46860154e53c3b29b8a84c6ac8202d868e5dd5614/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f67756176612f63616c656e6461722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/guava/calendar)[![GitHub Tests Action Status](https://camo.githubusercontent.com/6ab63fbd38f5818d833f4a536d1c8ef325f6856aeac2a432371d154039e61328/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f67756176612f63616c656e6461722f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/GuavaCZ/calendar/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/91b2dfcc16f720b9ad90694078cd1ede3d0c3829a29be780f14ce1495c5aa6f3/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f67756176612f63616c656e6461722f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/GuavaCZ/calendar/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/bf7fd3091ea44ef05dc4f9c4f78185393b6399be73bbd64cb8cb46ba377dd284/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f67756176612f63616c656e6461722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/guava/calendar)

This package adds support for [vkurko/calendar](https://github.com/vkurko/calendar) (free, open-source alternative to FullCalendar) to your FilamentPHP panels.

Showcase
--------

[](#showcase)

[![Showcase 01](https://github.com/GuavaCZ/calendar/raw/main/docs/images/showcase_01.png)](https://github.com/GuavaCZ/calendar/raw/main/docs/images/showcase_01.png)[![Showcase 02](https://github.com/GuavaCZ/calendar/raw/main/docs/images/showcase_02.png)](https://github.com/GuavaCZ/calendar/raw/main/docs/images/showcase_02.png)

    Screen.Recording.2024-07-15.at.9.31.47.mp4    Support us
----------

[](#support-us)

Your support is key to the continual advancement of our plugin. We appreciate every user who has contributed to our journey so far.

While our plugin is available for all to use, if you are utilizing it for commercial purposes and believe it adds significant value to your business, we kindly ask you to consider supporting us through GitHub Sponsors. This sponsorship will assist us in continuous development and maintenance to keep our plugin robust and up-to-date. Any amount you contribute will greatly help towards reaching our goals. Join us in making this plugin even better and driving further innovation.

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

[](#installation)

You can install the package via composer:

```
composer require guava/calendar
```

Make sure to publish the package assets using:

```
php artisan filament:assets
```

Make sure you have a custom filament theme (read [here](https://filamentphp.com/docs/3.x/panels/themes#creating-a-custom-theme) how to create one) and add the following to the `content` property of your theme's tailwind.config.js:

```
{
    content: [
        //...

        './vendor/guava/calendar/resources/**/*.blade.php',
    ]
}
```

This ensures that the CSS is properly built.

Usage
-----

[](#usage)

Creating the calendar Widget
============================

[](#creating-the-calendar-widget)

First you need to create a custom widget and extend the `CalendarWidget` class. Make sure to remove the `view` property from the generated widget class!

Either use the artisan command or simply create an empty class and extend `CalendarWidget`:

```
php artisan make:filament-widget
```

The widget class should look like this:

```
use \Guava\Calendar\Widgets\CalendarWidget;

class MyCalendarWidget extends CalendarWidget
{
}
```

Add the widget like a regular widget to any filament page you like, such as your `Dashboard`.

Customizing the calendar view
-----------------------------

[](#customizing-the-calendar-view)

By default, we show the `dayGridMonth` view. You can customize the view by overriding the `calendarView` property on the widget class:

```
protected string $calendarView = 'resourceTimeGridWeek';
```

All available views are listed in the [calendar documentation](https://github.com/vkurko/calendar?tab=readme-ov-file#view).

Other options
-------------

[](#other-options)

In addition of that, you can configure almost all [options from the underlying calendar package](https://github.com/vkurko/calendar?tab=readme-ov-file#options) using the `getOptions` method:

```
public function getOptions(): array
{
    return [
        'nowIndicator' => true,
        'slotDuration' => '00:15:00'
    ];
}
```

Adding events
-------------

[](#adding-events)

By default, the calendar will be empty. To add events, simply override the `getEvents` method:

```
use Illuminate\Support\Collection;
use Guava\Calendar\ValueObjects\CalendarEvent;

public function getEvents(array $fetchInfo = []): Collection | array
    {
        return [
            // Chainable object-oriented variant
            CalendarEvent::make()
                ->title('My first event')
                ->start(today())
                ->end(today()),

            // Array variant
            ['title' => 'My second event', 'start' => today()->addDays(3), 'end' => today()->addDays(3)],

            // Eloquent model implementing the `Eventable` interface
            MyEvent::find(1),
        ];
    }
```

### Creating events

[](#creating-events)

As shown in the example, there are multiple ways to create events. At the very least, an array object with a `title`, `start` and `end` properties is required.

To help you with creating events, we provide an `Event` ValueObject which contains methods with all available properties an event can have.

This is possible because the `Event` clas implements the `Eventable` interface, which returns the array object. You can add this interface to any class you want which should be treated as an event, such as your eloquent models.

Here is an example:

#### using an Eloquent model as Events

[](#using-an-eloquent-model-as-events)

```
class Foo extends Model implements Eventable
{
    // ...

    public function toCalendarEvent(): CalendarEvent|array {
        return CalendarEvent::make($this)
            ->title($this->name)
            ->start($this->starts_at)
            ->end($this->ends_at);
    }
}
```

Notice that the model is passed to the `Event` constructor in the `make` method. This sets the `key` and `model` properties to the event object, so it can be used to trigger actions.

### Event object

[](#event-object)

The event object takes all available options like the underlying calendar package, for more info [read here](https://github.com/vkurko/calendar?tab=readme-ov-file#event-object).

Below is a list of available methods on the event object:

#### Setting the title

[](#setting-the-title)

Sets the title of the event that is rendered in the calendar.

```
CalendarEvent::make()->title('My event');
```

#### Customizing the start/end date

[](#customizing-the-startend-date)

Sets the start or end date (and time) of the event in the calendar.

```
CalendarEvent::make()
    ->start(today())
    ->end(today()->addDays(3));
```

#### Making the event all-day

[](#making-the-event-all-day)

Sets whether the event is an all-day event or not.

```
CalendarEvent::make()->allDay();
```

#### Customizing the background / text color

[](#customizing-the-background--text-color)

Sets the background color of the event (by default it is the primary color of the panel).

```
CalendarEvent::make()
->backgroundColor('#ff0000')
->textColor('#ffffff');
```

#### Customizing Event Styles

[](#customizing-event-styles)

You can add custom styles to your event elements by using the styles method. This method accepts an array where each entry can be a CSS style declaration. The styles will be directly applied to the event element in the view. You can define styles in three ways:

- As a key-value pair where the key is the CSS property and value is the condition under which the style should apply.
- As a key-value pair where the key is the CSS property and the value is directly the CSS value.
- As a single string for static styles that always apply.

Here's how you can use it:

```
CalendarEvent::make()->styles([
    'color: red' => true,            // Applies the style if the condition (true) is met
    'background-color' => '#ffff00', // Directly applies the background color
    'font-size: 12px'                // Always applies this font size
]);
```

##### Usage Notes:

[](#usage-notes)

- The first format ('color: red' =&gt; true) is useful for conditional styling based on dynamic conditions. For instance, changing the text color based on an event's type or status.
- The second format ('background-color' =&gt; '#ffff00') is straightforward for applying styles where the values do not depend on conditions.
- The third format ('font-size: 12px') is used when the style does not require any condition and is always applied to the event. This flexibility allows you to easily customize the appearance of events based on dynamic conditions or predefined settings.

#### Customizing Event Classes

[](#customizing-event-classes)

Following the same pattern as with the styles property, it is possible to inject custom classes into the Event element using the `classNames` or `classes` property.

Here's how you can use it:

```
CalendarEvent::make()->classNames([
    'class-1',
    'class-2' => true  // Applies the class if the condition (true) is met
]);
```

##### Usage Notes:

[](#usage-notes-1)

- The second format ('class-2' =&gt; true) is useful for conditional classes based on dynamic conditions.

#### Customizing the display

[](#customizing-the-display)

By default, events are rendered as `blocks`. This is when the display is set to `auto`, which it is by default. You can also change the event to be rendered as a background event, which then fills the whole date cell. To do so, you can set `display` to `background` on the event:

This doesn't work always though, it only works on all day events and in specific views. If the `background` event is unsupported, the event will not be rendered at all.

```
CalendarEvent::make()
->display('background') // or 'auto'
->displayAuto() // short-hand for ->display('auto')
->displayBackground(); // short-hand for ->display('background')
```

#### Setting the action on click

[](#setting-the-action-on-click)

This sets the action that should be mounted when the event is clicked. It can be any name of a filament action you defined in your widget, such as `edit` or `view`.

By default, all `CalendarWidget` classes already include a `view` and `edit` action.

```
CalendarEvent::make()->action('edit');
```

#### Set the model and record key

[](#set-the-model-and-record-key)

To mount the action with the correct record, we need to pass the model type and primary key of the record.

The model is also required if you want to display multiple types of events and have each be rendered differently (see customizing event content).

```
$record = MyModel::find(1);
// 1. variant
CalendarEvent::make($record);

// 2. variant
CalendarEvent::make()
    ->model($record::class)
    ->key($record->getKey());
```

#### Passing custom data

[](#passing-custom-data)

You can pass any custom data to the event that you wish:

```
CalendarEvent::make()
->extendedProp('foo', 'bar')
// or
->extendedProps(['baz' => 'qux', 'quux' => 'corge']);
```

Available Methods
-----------------

[](#available-methods)

### Refresh events

[](#refresh-events)

If you need to trigger a refresh of the events in the calendar, you can call `refreshRecords()` on the widget.

```
$this->refreshRecords();
```

### Refresh resources

[](#refresh-resources)

If you need to trigger a refresh of the resources in the calendar, you can call `refreshResources()` on the widget.

```
$this->refreshResources();
```

### Set Option

[](#set-option)

To change any calendar option during runtime, you can use the `setOption()` method on the widget.

For example to programmatically change the date, you can use:

```
$this->setOption('date', today()->addDay()->toIso8601String());
```

Custom Event Content
--------------------

[](#custom-event-content)

By default, we use the default view from the calendar package. However, you are able to use your own by overriding the `getEventContent` method on your calendar widget class.

In order to keep things performant, the blade view is rendered **once** on the server and then re-used for every event. Thus, you **cannot** access the event data from the server side via Blade or Laravel, or do any server-side operations.

However, each event is wrapped in an alpine component, which exposes the event data that you can freely use using [AlpineJS](https://alpinejs.dev/).

If you only have one type of events or events that render the same way, you can simply return a view or a HtmlString from the getEventContent method:

```
public function getEventContent(): null|string|array
{
    // return a blade view
    return view('calendar.event');

    // return a HtmlString
    return new HtmlString('My event');
}
```

Example of the `calendar.event` view blade file:

```

```

If you want to render events differently based on their model type, you can return an array like so:

```
public function getEventContent(): null|string|array
{
    return [
        MyModel::class => view('calendar.my-model-event'),
        AnotherModel::class => view('calendar.another-model-event'),
    ];
}
```

Custom resource label content
-----------------------------

[](#custom-resource-label-content)

By default, we use the default view from the calendar package. However, you are able to use your own by overriding the `getResourceLabelContent` method on your calendar widget class.

```
public function getResourceLabelContent(): null|string|array
{
    // return a blade view
    return view('calendar.resource');

    // return a HtmlString
    return new HtmlString('My resource');
}
```

Customize the form schema
-------------------------

[](#customize-the-form-schema)

When an event triggers an action (such as view or edit actions), a modal with a form is mounted.

You can customize the form schema by overriding the `getSchema` method in your widget class:

```
public function getSchema(?string $model = null): ?array
{
    // If you only work with one model type, you can ignore the $model parameter and simply return a schema
    return [
        TextInput::make('title')
    ];

    // If you have multiple model types on your calendar, you can return different schemas based on the $model property
    return match($model) {
        Foo::class => [
            TextInput::make('name'),
        ],
        Bar::class => [
            TextInput::make('title'),
            TextArea::make('description'),
        ],
    }
}
```

Resources
---------

[](#resources)

Resource views (their names start with `resource`) allow you to group events into resources (such as rooms, projects, etc.).

To use resource views, you need to create resources and assign your events to these resources.

[![Resources Screenshot 01](https://github.com/GuavaCZ/calendar/raw/main/docs/images/resources_screenshot_01.png)](https://github.com/GuavaCZ/calendar/raw/main/docs/images/resources_screenshot_01.png)

### Creating resources

[](#creating-resources)

To create resources, you need to override the `getResources` method on your calendar widget class. Just like events, there are three options you can choose from to create resources:

```
public function getResources(): Collection|array
{
    return [
        // Chainable object-oriented variant
        CalendarResource::make('foo')
            ->title('Room 1'),

        // Array variant
        ['id' => 'bar', 'title' => 'Room 2'],

        // Eloquent model implementing the `Resourceable` interface
        MyRoom::find(1),
    ];
}
```

Handling events
---------------

[](#handling-events)

By default, the calendar is a view-only collection of events. You can enable more functionalities by configuring various events as described below.

### Event-click event

[](#event-click-event)

An event click event is triggered when an event in the calendar is clicked. By default, a click event mounts the `view` action.

To listen to click events, simply override the `eventClickEnabled` property:

```
protected bool $eventClickEnabled = true;
```

You can set the default click action by overriding the `defaultEventClickAction` property of the widget. This simply needs to be the name of an action that you can freely define in your widget, like regular Filament actions:

```
protected ?string $defaultEventClickAction = 'edit';
```

And that's it! As long as pass your model policy checks, an edit modal will be mounted when you click on an event.

If you want to handle the event click logic completely by yourself, you may override the `onEventClick` method:

```
    public function onEventClick(array $info = [], ?string $action = null): void
{
    // do something on click
    // $info contains the event data:
    // $info['event'] - the event object
    // $info['view'] - the view object
}
```

### Event Resize event

[](#event-resize-event)

A resize event is triggered when an event is resized at the ending edge of the event. This allows you to quickly modify the duration of an event.

To listen to resize events, simply override the `eventResizeEnabled` property:

```
protected bool $eventResizeEnabled = true;
```

Except for resolving the (event) record the event is related to, there is no default action and it's up to you to implement the logic. To do that, override the `onEventResize` method:

```
public function onEventResize(array $info = []): bool
{
    // Don't forget to call the parent method to resolve the event record
    parent::onEventResize($info);

    // Validate the data
    // Update the record ($this->getEventRecord())
    // $info contains the event data:
    // $info['event'] - the event object
    // $info['oldEvent'] - the event object before resizing
    // $info['endDelta'] - the difference in time between the old and new event

    // Return true if the event was resized successfully
    // Return false if the event was not resized and should be reverted on the client-side
}
```

### Event Drag &amp; Drop event

[](#event-drag--drop-event)

A drop event is triggered when an event is dragged and dropped to a different slot in the calendar. This allows you to quicky move the start (and end) date of an event.

To listen to drag and drop events, simply override the `eventDragEnabled` property:

```
protected bool $eventDragEnabled = true;
```

Except for resolving the (event) record the event is related to, there is no default action and it's up to you to implement the logic. To do that, override the `onEventDrop` method:

```
public function onEventDrop(array $info = []): bool
{
    // Don't forget to call the parent method to resolve the event record
    parent::onEventDrop($info);

    // Validate the data
    // Update the record ($this->getEventRecord())
    // $info contains the event data:
    // $info['event'] - the event object
    // $info['oldEvent'] - the event object before resizing
    // $info['oldResource'] - the old resource object
    // $info['newResource'] - the new resource object
    // $info['delta'] - the duration object representing the amount of time the event was moved by
    // $info['view'] - the view object

    // Return true if the event was moved successfully
    // Return false if the event was not moved and should be reverted on the client-side
}
```

### Date Click event

[](#date-click-event)

A date click event is triggered when an date cell is clicked in the calendar.

To listen to date click events, simply override the `dateClickEnabled` property:

```
protected bool $dateClickEnabled = true;
```

By default, nothing happens on date click. You can either use the `date click context menu feature` (more info below in the `Context Menu` section **[here](#date-click-context-menu)**) or implement your own logic, by overriding the `onDateClick` method:

```
public function onDateClick(array $info = []): bool
{
    // Validate the data
    // $info contains the event data:
    // $info['date'] - the date clicked on
    // $info['dateStr'] - the date clicked on as a UTC string
    // $info['allDay'] - whether the date is an all-day slot
    // $info['view'] - the view object
    // $info['resource'] - the resource object
}
```

### Date Select event

[](#date-select-event)

A date select event is triggered when a date range is selected in the calendar.

To listen to date select events, simply override the `dateSelectEnabled` property:

```
protected bool $dateSelectEnabled = true;
```

By default, nothing happens on date select. You can either use the `date select context menu feature` (more info below in the `Context Menu` section **[here](#date-select-context-menu)**) or implement your own logic, by overriding the `onDateSelect` method:

```
public function onDateSelect(array $info = []): bool
{
    // Validate the data
    // $info contains the event data:
    // $info['start'] - the start date of the range
    // $info['startStr'] - the start date as an UTC string
    // $info['end'] - the end date of the range
    // $info['endStr'] - the end date as an UTC string
    // $info['allDay'] - whether the date is an all-day slot
    // $info['view'] - the view object
    // $info['resource'] - the resource object
}
```

### No-events-click event

[](#no-events-click-event)

A no-events-click event is applicable only on `list` views and is triggered when a user clicks on the `no events` cell. By default, this event does nothing and it's up to you to implement the logic.

To listen to no-events-click events, simply override the `noEventsClickEnabled` property:

```
protected bool $noEventsClickEnabled = true;
```

To handle the no-events-click logic, override the `onNoEventsClick` method:

```
public function onNoEventsClick(array $info = []): void
{
    // do something on click
    // $info contains the event data:
    // $info['view'] - the view object
}
```

Context menu
------------

[](#context-menu)

Optionally you can add a context menu to your calendar, which allows you to create events by clicking on a date cell or by selecting a date/time range by dragging.

There are multiple places where you can use context menus at.

    context\_menu\_preview.mp4        context\_menu\_preview\_2.mp4    ### Date click context menu

[](#date-click-context-menu)

This context menu is triggered when a user clicks on a date cell in the calendar.

To enable the context menu, all you need to do is enable date clicks and implement the `getDateClickContextMenuActions` method:

For example:

```
protected bool $dateClickEnabled = true;

public function getDateClickContextMenuActions(): array
{
    return [
        CreateAction::make('foo')
            ->model(Foo::class)
            ->mountUsing(fn ($arguments, $form) => $form->fill([
                'starts_at' => data_get($arguments, 'dateStr'),
                'ends_at' => data_get($arguments, 'dateStr'),
            ])),
    ];
}
```

The mount using function is used to fill the form with the arguments from the calendar. It contains all information that vkurko/calendar provides in the `select` and `dateClick` events, but most importantly:

- `startStr` and `endStr` for range selection
- `dateStr` for date clicks

### Date select context menu

[](#date-select-context-menu)

This context menu is triggered when a user selects on a date range in the calendar.

To enable the context menu, all you need to do is enable date selects and implement the `getDateSelectContextMenuActions` method:

For example:

```
protected bool $dateSelectEnabled = true;

public function getDateSelectContextMenuActions(): array
{
    return [
        CreateAction::make('foo')
            ->model(Foo::class)
            ->mountUsing(fn ($arguments, $form) => $form->fill([
                'starts_at' => data_get($arguments, 'startStr'),
                'ends_at' => data_get($arguments, 'endStr'),
            ])),
    ];
}
```

### Event click context menu

[](#event-click-context-menu)

This context menu is triggered when a user clicks on an event in the calendar.

To enable the context menu, all you need to do is enabled event Clicks and implement the `getEventClickContextMenuActions` method:

For example:

```
protected bool $eventClickEnabled = true;

public function getEventClickContextMenuActions(): array
{
    return [
        $this->viewAction(),
        $this->editAction(),
        $this->deleteAction(),
    ];
}
```

### No events click context menu

[](#no-events-click-context-menu)

This context menu is only rendered on `list` views and is triggered when a user clicks on the `no events` cell when there are no events.

To enable the context menu, all you need to do is implement the `getNoEventsClickContextMenuActions` method. Also, make sure that the `noEventsClickEnabled` property is set to `true`.

```
public function getNoEventsClickContextMenuActions(): array
{
    return [
        CreateAction::make('foo')
            ->model(Foo::class)
    ];
}
```

    no\_events\_context\_menu.mp4    Customization
-------------

[](#customization)

### Locale

[](#locale)

By default, the calendar will use the app's locale.

The underlying calendar package doesn't support locales as a combination of language and region/country code, so locales such as `fr_CA` or `en_US` become invalid.

We attempt to resolve this by only using the first language part of the locale. If you still run into any issues with the localization, you can override the calendar's locale manually using the `locale` property:

```
protected ?string $locale = 'en';
```

Troubleshooting
---------------

[](#troubleshooting)

### Context menu actions don't work

[](#context-menu-actions-dont-work)

If you encounter issues with the context menu, either that the actions don't mount correctly or that the arguments array is empty, make sure that the name of the action is unique across the whole widget. If there is another action with the same name, it might be mounted instead of the one you want.

### Record vs Event record

[](#record-vs-event-record)

When working with resource widgets, `$record` is the record of the currently opened resource record, whereas `$eventRecord` is the record of the calendar event (during event actions, context menus, etc.).

Authorization
-------------

[](#authorization)

Due to security reasons, actions use Laravel's default authorization mechanism to check if user is allowed to perform actions.

This means that most likely your actions might not work when you add them (such as view or edit actions on event click). If that's the case, please create a policy for your model and add the necessary checks to the policy.

You can also overide the `authorize` method on your widget class and handle all authorization logic on your own.

```
// $ability will contain the name of the action
public function authorize($ability, $arguments = []);
```

Security measures
-----------------

[](#security-measures)

Keep in mind that a lot of the data in this package comes from the client side JavaScript and could be tampered with. Always validate the data on the server side and never trust the data from the client side.

Testing
-------

[](#testing)

```
composer test
```

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)

- [Lukas Frey](https://github.com/GuavaCZ)
- [All Contributors](../../contributors)
- Spatie - Our package skeleton is a modified version of [Spatie's Package Skeleton](https://github.com/spatie/package-skeleton-laravel)
- [vkurko/calendar](https://github.com/vkurko/calendar) - free, open-source alternative to FullCalendar
- [saade/filament-fullcalendar](https://github.com/saade/filament-fullcalendar) - heavy inspiration for this package

License
-------

[](#license)

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

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance48

Moderate activity, may be stable

Popularity2

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 78% of commits — single point of failure

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

Unknown

Total

1

Last Release

381d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/6816da33fbd1d68f0263dde5153601800bc756eb5f2030b5596cdf1c23c69b1b?d=identicon)[ScaleXY](/maintainers/ScaleXY)

---

Top Contributors

[![lukas-frey](https://avatars.githubusercontent.com/u/10926334?v=4)](https://github.com/lukas-frey "lukas-frey (96 commits)")[![mwagena](https://avatars.githubusercontent.com/u/1246801?v=4)](https://github.com/mwagena "mwagena (8 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (5 commits)")[![p3dro-docplanner](https://avatars.githubusercontent.com/u/60880234?v=4)](https://github.com/p3dro-docplanner "p3dro-docplanner (4 commits)")[![Athuli7](https://avatars.githubusercontent.com/u/4718029?v=4)](https://github.com/Athuli7 "Athuli7 (2 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (2 commits)")[![hammadzafar05](https://avatars.githubusercontent.com/u/75698921?v=4)](https://github.com/hammadzafar05 "hammadzafar05 (2 commits)")[![ibrahem-kamal](https://avatars.githubusercontent.com/u/38753243?v=4)](https://github.com/ibrahem-kamal "ibrahem-kamal (1 commits)")[![pauloffb](https://avatars.githubusercontent.com/u/3179361?v=4)](https://github.com/pauloffb "pauloffb (1 commits)")[![sparksp](https://avatars.githubusercontent.com/u/243893?v=4)](https://github.com/sparksp "sparksp (1 commits)")[![yanntyb](https://avatars.githubusercontent.com/u/69966391?v=4)](https://github.com/yanntyb "yanntyb (1 commits)")

---

Tags

laravelcalendarGuava

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/athuli7-temp-guava-calendar/health.svg)

```
[![Health](https://phpackages.com/badges/athuli7-temp-guava-calendar/health.svg)](https://phpackages.com/packages/athuli7-temp-guava-calendar)
```

###  Alternatives

[guava/calendar

Adds support for vkurko/calendar to Filament PHP.

298241.0k3](/packages/guava-calendar)[pboivin/filament-peek

Full-screen page preview modal for Filament

253319.6k12](/packages/pboivin-filament-peek)[dotswan/filament-map-picker

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

124139.3k2](/packages/dotswan-filament-map-picker)[creagia/filament-code-field

A Filamentphp input field to edit or view code data.

58289.3k3](/packages/creagia-filament-code-field)[swisnl/filament-backgrounds

Beautiful backgrounds for Filament auth pages

54149.2k6](/packages/swisnl-filament-backgrounds)[hydrat/filament-table-layout-toggle

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

6292.3k1](/packages/hydrat-filament-table-layout-toggle)

PHPackages © 2026

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