brickx / calendax
Livewire calendar for Laravel
Installs: 48
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 2
Open Issues: 1
Type:package
Requires
- php: ^8.1
- illuminate/support: ^9.23
- livewire/livewire: ^2.10
- spatie/laravel-package-tools: ^1.9.2
Requires (Dev)
- laravel/pint: ^1.0
- nunomaduro/collision: ^6.0
- orchestra/testbench: ^7.0
- pestphp/pest: ^1.21
- pestphp/pest-plugin-laravel: ^1.1
- pestphp/pest-plugin-livewire: ^1.0
- pestphp/pest-plugin-parallel: ^1.2
- phpunit/phpunit: ^9.5
This package is auto-updated.
Last update: 2024-03-04 17:32:45 UTC
README
NOTE: This package is intended for my own use only, so a few things are very specific to my projects (e.g. importing
.tsx
&.scss
uncompiled files directly).If anyone is interested in making it easier to set up and more maintainable for a wider audience, please submit a PR or open a discussion!
Also, feel free to consider using the package on which this one is based as stated below.
Calendax allows you to build a Livewire calendar, filled with events of any kind. Events can be created from any model or dataset.
It is heavily inspired by Andrés Santibáñez's Livewire Calendar.
Preview
Table of contents
Installation
You can install the package via composer:
composer require brickx/calendax
You can publish the config file with:
php artisan vendor:publish --tag="calendax-config"
This is the contents of the published config file:
return [
];
Optionally, you can publish the views using
php artisan vendor:publish --tag="calendax-views"
Requirements
This package uses livewire/livewire
(https://laravel-livewire.com) under the hood.
It also uses TailwindCSS (https://tailwindcss.com) for styling. Please make sure you include both of these dependencies before using this component.
Usage
Initialization
First, create a new Livewire component that extends Calendax
.
You can use make:livewire
to create this component. For example:
php artisan make:livewire MyCalendar
Then, in the created MyCalendar
class, extend Calendax
instead of extending from the base Component
Livewire class:
class MyCalendar extends \Brickx\Calendax\Calendax { // }
In this class, you must override the following method in order to implement custom logic for loading events:
public function events() : Collection { // Return a Laravel collection }
Also remove the render
method, as it will be handled for you.
In the events()
method, you should return a collection containing the events that should be displayed on the calendar.
Loading events (using arrays)
Events must be keyed arrays holding at least the following keys: id
, title
, description
, date
(which must be a Carbon\Carbon
instance).
public function events() : Collection { return collect([ [ 'id' => 1, 'title' => 'Breakfast', 'description' => 'Pancakes! 🥞', 'date' => Carbon::today(), ], [ 'id' => 2, 'title' => 'Meeting with Camille', 'description' => 'Random chit-chat.', 'date' => Carbon::tomorrow(), ], ]); }
The date
value will be used to determine to which day the event will be displayed.
Loading events (using Eloquent query)
You can also load values dynamically in the events()
method. You can use the following component properties to filter your events:
startsAt
: starting date of the monthendsAt
: ending date of the monthgridStartsAt
: starting date of calendar grid (can be a date from the previous month).endingStartsAt
: ending date of calendar grid (can be a date from the previous month).
public function events(): Collection { return Model::query() ->whereDate('scheduled_at', '>=', $this->gridStartsAt) ->whereDate('scheduled_at', '<=', $this->gridEndsAt) ->get() ->map(function (Model $model) { return [ 'id' => $model->id, 'title' => $model->title, 'description' => $model->notes, 'date' => $model->scheduled_at, ]; }); }
Rendering the calendar
Now you can include your calendar in any view using Blade components:
<livewire:my-calendar />
This will render a calendar grid.
Choosing the starting month
By default, the component will render the current month. If you want to change the
starting month, you can set the year
and month
props.
<livewire:my-calendar year='2016' month='06' />
Enabling drag & drop
To enable drag & drop, include @calendaxScripts
after your @livewireScripts
directive.
@livewireScripts @livewireCalendarScripts
Handling navigation
The component has 4 public methods used to navigate between months:
public function goToPreviousMonth() public function goToCurrentMonth() public function goToNextMonth() public function goToMonth($month, $year = null)
For example, these methods can be used to build a navigation system using additional views. Check out below section for example usage.
Advanced usage
Blade customization
When rendering your Blade component, several additional attributes are available to customize the behavior of your calendar:
-
week-start
to indicate the starting day of the week. It can be a number from 0 to 6 according toCarbon
days of week (0 = sunday). -
drag-and-drop-classes
can be any CSS class used to render the hover effect when dragging & dropping an event in the calendar. By default, this value isborder border-4 border-blue-400
.
<livewire:my-calendar week-start=1 drag-and-drop-classes='bg-orange-500' />
Custom views
You can also use custom Blade views to render different parts of the calendar.
It is recommended to publish the base Blade views used by the component and extend their behavior and styling to your liking. To do this, please check out the Installation section.
Those views can be specified using the following attributes:
-
calendar-view
used to render the whole component. Please check out the package'scalendar.blade.php
view to know which attributes are available. -
dow-view
used to render each column header of the calendar (typically containing days of week). This view will receive the$day
property, which is aCarbon
instance of the associated day of the week. -
day-view
used to render each day of the month. This view will receive the following attributes:componentId
(the id of the Livewire component)day
(the day of the month as aCarbon
instance)dayInMonth
(boolean indicating if the day is part of the current month or not)isToday
(boolean indicating if the day is today)events
(events collection that corresponds to the day)
-
event-view
used to render the event card. This view will receive an$event
variable containing its data. -
before-calendar-view
andafter-calendar-view
can be any Blade views that will be rendered before or after the calendar itself. These can be used to add extra features ( e.g. navigation system) to your component.
<livewire:my-calendar calendar-view='path/to/view/calendar.blade.php' dow-view='path/to/view/dow.blade.php' day-view='path/to/view/day.blade.php' event-view='path/to/view/event.blade.php' before-calendar-view='path/to/view/before-calendar.blade.php' after-calendar-view='path/to/view/after-calendar.blade.php' />
All custom views paths must be relative to the resources/views
directory.
Interactivity
Several methods are available to interact with the calendar:
public function onDayClick($year, $month, $day) { // This event is triggered when a day is clicked } public function onEventClick($eventId) { // This event is triggered when an event card is clicked } public function onEventDropped($eventId, $year, $month, $day) { // This event is triggered when an event is dragged & dropped onto another calendar day }
You can override any of them to implement your custom logic.
By default, click and drag & drop events are enabled. To disable them you can use the following attributes when rendering the component
<livewire:my-calendar :day-click-enabled='false' :event-click-enabled='false' :drag-and-drop-enabled='false' />
Automatic polling
You can add automatic polling if need be by defining a $pollMillis
property in the Livewire component.
You can also combine it with $pollAction
in order to call a specific action in your component at the desired polling interval.
To learn more about polling, please check out https://laravel-livewire.com/docs/2.x/polling.
Flatpickr
To handle navigation between months, this package makes use of the Flatpickr library. It displays a calendar picker which is way more powerful than
simple <select>
.
Importing
First, add the Flatpickr library to your package.json
's dependencies:
{ "dependencies": { "flatpickr": "^4.6.13" } }
Then import this package's flatpickr.scss
and flatpickr.tsx
files to you main stylesheet & script.
app.scss
:
@use '../vendor/brickx/calendax/resources/sass/flatpickr';
app.js
:
import calendax from '../../../vendor/brickx/calendax/resources/scripts/flatpickr'; calendax();
Customization
You can customize the colors of the calendar picker to match your theme. To do so, simply override the Sass variables when importing flatpickr.scss
:
@use '../vendor/brickx/calendax/resources/sass/flatpickr' with ( $color-primary: saddlebrown, // Basic color $color-accent: #FDBA74, // Standard CSS color $color-contrast: rgb(118, 89, 71, 0.8), // RGB color $color-range: theme('colors.orange.100') // Tailwind theme color );
Testing
You can test the component using Pest
by running the following commands, depending on your needs.
Standard test:
composer test
With coverage:
composer test:coverage
Parallel test:
composer test:parallel
Parallel test with coverage:
composer test:parallel-coverage
Todo
- Ideally, users should not have to mess with their sass & script files in order to import the proper dependencies. Everything should be done inside Blade (at the very least importing styles & script directly in Blade layout). See: https://github.com/Laratipsofficial/laravel-flatpickr.
- Find a way to highlight events in Flatpickr component (so that users see immediately which days have events).
- Handle Shields properly in README.md. Check out: https://shields.io/.
-
Create tests for Flatpickr component -
Update README.md for how to properly setup Flatpickr component -
Add default navigation, ideally using a dynamic calendar picker (instead of basic<select>
).
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.