Calendar componentAvailable since EcoComposer 2.2
Classical calendar example :
GMT+0
09:00
10:00
11:00
12:00
13:00
14:00
15:00
16:00
17:00
18:00
The default values are :
calendar--actual-week--background-color : 'calendar--actual-week--background-color',
calendar--actual-week--background-image : 'calendar--actual-week--background-image',
calendar--actual-week--color : 'calendar--actual-week--color',
calendar--background--color : 'calendar--background--color',
calendar--background--lines-color : 'calendar--background--lines-color',
calendar--days--headers--background-color : 'calendar--days--headers--background-color',
calendar--days--headers--background-color--hover : 'calendar--days--headers--background-color--hover',
calendar--days--headers--color : 'calendar--days--headers--color',
calendar--days--today--background-color : 'calendar--days--today--background-color',
calendar--days--today-hour--background-color : 'calendar--days--today-hour--background-color',
calendar--event--border : 'calendar--event--border',
calendar--event--color : 'calendar--event--color',
calendar--event--drag-hover-error--box-shadow : 'calendar--event--drag-hover-error--box-shadow',
calendar--event--drag-hover--box-shadow : 'calendar--event--drag-hover--box-shadow',
calendar--sidebar--today-date--color : 'calendar--sidebar--today-date--color',
calendar--timeline--background-color : 'calendar--timeline--background-color',
calendar--timeline--color : 'calendar--timeline--color',
day--background-type : 'linear', // 'linear', 'radial' or 'no'
days-header--font-size : 2rem * theming.$font-size,
days-header--height : 4rem * theming.$font-size,
event--background-type : 'linear', // 'linear', 'radial' or 'no'
events : (
first : #fdd,
second : #ffa,
third : #eff,
fourth : #dfe
),
font-family : theming.$font-family,
gap-day : .1rem * theming.$font-size,
gap-hour : 1rem * theming.$font-size,
gap-date-between-number-and-string : 1rem * theming.$font-size,
num-days : 5,
num-hours : 10,
print : false,
sidebar-width : 17rem * theming.$font-size,
suffix : '',
themes : (
light : (
default--calendar--actual-week--background-color : #00ffb2,
default--calendar--actual-week--background-image : utils.fn-linear-gradient(45, #00ffb2),
default--calendar--actual-week--color : #fff,
default--calendar--background--color : #f2f2f2,
default--calendar--background--lines-color : #ddd,
default--calendar--days--headers--background-color : #eee,
default--calendar--days--headers--background-color--hover : #ddd,
default--calendar--days--headers--color : #333,
default--calendar--days--today--background-color : #00ffb2,
default--calendar--days--today-hour--background-color : #f55,
default--calendar--event--border : 1px solid #f2d3d8,
default--calendar--event--color : #444,
default--calendar--event--drag-hover-error--box-shadow : 0 0 .8rem * theming.$font-size .1rem * theming.$font-size #f44,
default--calendar--event--drag-hover--box-shadow : 0 0 .5rem * theming.$font-size #333,
default--calendar--sidebar--today-date--color : #eee,
default--calendar--timeline--background-color : #eee,
default--calendar--timeline--color : #444
),
dark : (
default--calendar--actual-week--background-color : #00ffb2,
default--calendar--actual-week--background-image : utils.fn-linear-gradient(45, #00ffb2),
default--calendar--actual-week--color : #fff,
default--calendar--background--color : #333, // main background under cells
default--calendar--background--lines-color : #555, // horizontal lines
default--calendar--days--headers--background-color : #444, // day headers
default--calendar--days--headers--background-color--hover : #555, // days headers hover background color
default--calendar--days--headers--color : #ccc, // days headers text color
default--calendar--days--today--background-color : #0a7, // today header background color
default--calendar--days--today-hour--background-color : #f55, // today hour line background color
default--calendar--event--border : 1px solid #555, // border around cells
default--calendar--event--color : #444, // event cell text color
default--calendar--event--drag-hover-error--box-shadow : 0 0 .8rem * theming.$font-size .1rem * theming.$font-size #f44, // event dragged on wrong area, added border
default--calendar--event--drag-hover--box-shadow : 0 0 .5rem * theming.$font-size #333, // event dragged, hovering a day, drop shadow
default--calendar--sidebar--today-date--color : #eee,
default--calendar--timeline--background-color : #444, // timeline headers
default--calendar--timeline--color : #fff // timeline text color
)
),
time-height : 6rem * theming.$font-size,
timeline-width : 6rem * theming.$font-size,
week-height : 12rem * theming.$font-size
We can implement it that way :
@include calendar.init();
@include calendar.create();
@include calendar.create(
(
suffix : '-2',
num-hours : 9,
)
);
We can implement it that way :
Beware, there is only the code of the day view here.
<?php
const
MINUTES_IN_AN_HOUR = 60,
DAYS_HEADER_HEIGHT = '4',
TIME_HEIGHT = 6;
?><div class=calendar-component>
<script nonce=yourGeneratedNonce>
window.calendarContainers = {}; // put your calendar containers JSON data here
window.calendarEvents = {}; // put your calendar events JSON data here
</script>
<style nonce=yourGeneratedNonce><?php
$colors = '@supports (accent-color: #000) {';
foreach ($calendarContainers[$displayedCalendarContainerId] as $calendarId => $calendar)
{
?>#cal-check-<?= $calendarId ?>:not(:checked)~.cal-container .cal--event-<?= $calendarId ?> {
opacity : 0;
}<?php ob_start(); ?>
#cal-check-<?= $calendarId ?> {
accent-color: <?= $calendar['color'] ?>
}
<?php
$colors .= ob_get_clean();
}
echo $colors . '}';
for ($dayToStyleIndex = 0; $dayToStyleIndex < 5; ++$dayToStyleIndex)
{
?>
.cal--day<?= $dayToStyleIndex ?>:target {
display: block;
}
<?php
}
?>
.cal--date-header:target ~ div {
display : none;
}
</style>
<p class="cal cal--sidebar--today-date"><?= $todayDate->format('F Y')?></p>
<div class=cal--sidebar>
<button type="button" class="cal ripple--cal--previous -cal--previous" title="Previous week"><</button><!--
-->
<button type="button" class="cal ripple--cal--change-date -cal--change-date" title="Change the displayed week"
data-day-number="<?= $todayDateString ?>" data-day-name="<?= $todayDate->format('D') ?>"
data-week="<?= $week ?>" data-month-number="<?= $todayDate->format('m') ?>"
data-year="<?= $todayDate->format('Y') ?>">
Week <?= $week ?></button><!--
--><button type="button" class="cal ripple--cal--next -cal--next" title="Next week">></button>
</div><?php
const
OPTION_WEEK_KEY = 1,
OPTIONS_LABELS = ['Day', 'Week', 'Month', 'Year'];
?><div class="cal--select select select-container">
<button type="button" role=menu class="cal--select-value select select-value" aria-labelledby="select-value--label">
<span id=select-value--label
class="select select-value--label cal--select-value--label"><?= OPTIONS_LABELS[OPTION_WEEK_KEY] ?></span>
<span>▼︎</span>
</button>
<div class="cal--select-container select select-list select-container"><?php
foreach (OPTIONS_LABELS as $optionKey => $option)
{
$lcFirstOption = lcfirst($option);
?>
<input type=radio role=menuitem id="chk-<?= $lcFirstOption ?>-option" name=calendar--change-view
class="select select-item--activator" value="<?= $option ?>"<?php
if ($optionKey === OPTION_WEEK_KEY)
echo ' checked';
?>/>
<label for="chk-<?= $lcFirstOption ?>-option"
class="select select-item--label -calendar--change-view"><?= $option ?></label><?php
}
?></div>
</div><?php
foreach ($calendarContainers[$displayedCalendarContainerId] as $calendarId => $calendar)
{
?>
<label for="cal-check-<?= $calendarId ?>" class=cal-check
title="Toggle the display of events related to '<?= $calendar['name'] ?>'"><?= $calendar['name'] ?></label>
<input type="checkbox" id="cal-check-<?= $calendarId ?>" checked
title="Toggle the display of events related to '<?= $calendar['name'] ?>'"/>
<?php
}
?>
<div class="cal cal-container" data-calendar-container-id="<?= $displayedCalendarContainerId ?>">
<div class="cal calendar">
<div class="cal cal--timeline">
<div class="cal cal--timeline--spacer"><?php
$offset = (new DateTimeZone(date_default_timezone_get()))->getOffset($todayDate) / 3600;
echo 'GMT';
if ($offset >= 0)
echo '+';
echo $offset;
?></div>
<div class="cal cal--timeline--hours">
<?php
for ($hour = $startHour; $hour < $endHour; ++$hour)
{
?><div><?php
if ($hour < 10)
echo '0';
echo $hour . ':00';
?></div><?php
}
?>
</div>
</div>
<div class="cal cal--days">
<div id=cal--day--dummy-activator0></div>
<?php
$dayHtml = '';
ob_start();
$dayPlanning(
0,
$firstMondayOfThisWeek,
$calendarEvents[$displayedCalendarContainerId],
$todayDateString
);
$dayHtml .= ob_get_clean();
$dayPlanning = function (int $dayIndex, DateTime $date, array $events, string $todayDateString)
use ($viewsPath) : void
{
$dayDateNumber = $date->format('d');
$isToday = $dayDateNumber === $todayDateString;
$fullDate = $date->format('Y-m-d');
$dayDateName = $date->format('D');
?><div class=cal--date-header><?php
if ($isToday)
{ ?>
<hr class="cal cal--days--date--hour"/><?php
}
?><a href="#cal--day--dummy-activator<?= $dayIndex ?>"
class="cal cal--days--date<?php if ($isToday) echo ' cal--days--today'; ?>" title="Only show this day"
data-day-number="<?= $dayDateNumber ?>" data-day-name="<?= $dayDateName ?>">
<p class="cal cal--days--date--num"><?= $dayDateNumber ?></p>
<p class="cal cal--days--date--day"><?= $dayDateName ?></p>
</a>
<div class="cal cal--days--events -cal--day--<?= $fullDate ?>" data-date="<?= $fullDate?>"><?php
foreach ($events as $eventId => $eventData)
{
$event = $eventData['event'];
if ($dayDateNumber === $event['fromDate']->format('d'))
{
$fromMinutes = $event['fromDate']->format('i');
$toMinutes = $event['toDate']->format('i');
?>
<a href="#cal--event-modal"
class="cal cal--days--events--event from-<?= $event['fromDate']->format('G')
?> to-<?php
echo $event['toDate'] ->format('G'), ' ', $event['cssClass'], ' cal--event-', $eventData['calendarId'];
if ($fromMinutes !== '00')
echo ' cal--from--min' . $fromMinutes;
if ($toMinutes !== '00')
echo ' cal--to--min' . $toMinutes;
?>"
data-event-id="<?= $eventId ?>"
data-event-title="<?= $event['title'] ?>"
data-event-description="<?= $event['description'] ?>"
draggable="true">
<p class="cal cal--days--events--event--title"><?= $event['title'] ?></p>
<p class=-cal--hours><?= $event['fromDate']->format('H:i') ?> - <?= $event['toDate']->format('H:i') ?></p>
</a>
<?php
}
}
?></div>
</div><?php
};
for ($day = 1; $day < $daysByWeek; ++$day)
{
ob_start();
$dayPlanning(
$day,
$firstMondayOfThisWeek->modify('+1 day'),
$calendarEvents[$displayedCalendarContainerId],
$todayDateString
);
$dayHtml .= ob_get_clean();
?><div id="cal--day--dummy-activator<?= $day ?>"></div>
<?php
}
echo $dayHtml;
</div>
</div>
<div class="cal cal--days--lines"></div>
<div id=cal--event-modal class=modal--container>
<form class="modal--container--element event--modal" method="post">
<a href="#" role=button class="ripple-2 modal--btn--close" aria-label="Close">X</a>
<div class=event--modal--group>
<label for="event--title" class="modal--event-label label required">Title</label>
<input id=event--title name=event--title class="modal--event-input field" required/>
</div>
<div class=event--modal--group>
<label for="event--date" class="modal--event-label label required">Date</label>
<input id=event--date name=event--date type="date" class="modal--event-input field" required/>
</div>
<div class=event--modal--group>
<label for="event--hour-from" class="modal--event-label label required">From</label>
<input id=event--hour-from name=event--hour-from type="time" class="modal--event-input field" required/>
</div>
<div class=event--modal--group>
<label for="event--hour-to" class="modal--event-label label required">To</label>
<input id=event--hour-to name=event--hour-to type="time" class="modal--event-input field" required/>
</div>
<label for="event--description" class="label required">Description</label>
<textarea id=event--description name=event--description class="modal--event-description field" required></textarea>
<button type="submit" class="ripple modal--btn--send -save-button margin-t10b20">Save</button>
</form>
</div>
</div>
</div>