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.
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"
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.
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.
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.
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,
];
});
}
Now you can include your calendar in any view using Blade components:
<livewire:my-calendar />
This will render a calendar grid.
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' />
To enable drag & drop, include @calendaxScripts
after your @livewireScripts
directive.
@livewireScripts
@livewireCalendarScripts
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.
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' />
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.
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'
/>
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.
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>
.
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();
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
);
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
- 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>
).
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.