@ishitatsuyuki/oruga-next
Version:
UI components for Vue.js and CSS framework agnostic
1,170 lines (1,160 loc) • 97.2 kB
JavaScript
'use strict';
var vue = require('vue');
var helpers = require('./helpers.js');
var config = require('./config.js');
var BaseComponentMixin = require('./BaseComponentMixin-a03c02e3.js');
var Icon = require('./Icon-172f9998.js');
var FormElementMixin = require('./FormElementMixin-facf6e30.js');
var Input = require('./Input-7b380647.js');
var MatchMediaMixin = require('./MatchMediaMixin-08658b15.js');
var DropdownItem = require('./DropdownItem-839d8767.js');
var Field = require('./Field-b201302d.js');
var Select = require('./Select-db9aed9e.js');
var script = vue.defineComponent({
name: 'ODatepickerTableRow',
mixins: [BaseComponentMixin.BaseComponentMixin],
configField: 'datepicker',
inject: {
$datepicker: { from: '$datepicker', default: false }
},
emits: ['select', 'rangeHoverEndDate', 'change-focus'],
props: {
selectedDate: {
type: [Date, Array]
},
hoveredDateRange: Array,
day: {
type: Number
},
week: {
type: Array,
required: true
},
month: {
type: Number,
required: true
},
showWeekNumber: Boolean,
minDate: Date,
maxDate: Date,
disabled: Boolean,
unselectableDates: Array,
unselectableDaysOfWeek: Array,
selectableDates: Array,
events: Array,
indicators: String,
dateCreator: Function,
nearbyMonthDays: Boolean,
nearbySelectableMonthDays: Boolean,
weekNumberClickable: Boolean,
range: Boolean,
multiple: Boolean,
rulesForFirstWeek: Number,
firstDayOfWeek: Number,
tableRowClass: [String, Function, Array],
tableCellClass: [String, Function, Array],
tableCellSelectedClass: [String, Function, Array],
tableCellFirstSelectedClass: [String, Function, Array],
tableCellWithinSelectedClass: [String, Function, Array],
tableCellLastSelectedClass: [String, Function, Array],
tableCellFirstHoveredClass: [String, Function, Array],
tableCellInvisibleClass: [String, Function, Array],
tableCellWithinHoveredClass: [String, Function, Array],
tableCellLastHoveredClass: [String, Function, Array],
tableCellTodayClass: [String, Function, Array],
tableCellSelectableClass: [String, Function, Array],
tableCellUnselectableClass: [String, Function, Array],
tableCellNearbyClass: [String, Function, Array],
tableCellEventsClass: [String, Function, Array],
tableEventClass: [String, Function, Array],
tableEventIndicatorsClass: [String, Function, Array],
tableEventsClass: [String, Function, Array],
tableEventVariantClass: [String, Function, Array],
},
computed: {
tableRowClasses() {
return [
this.computedClass('tableRowClass', 'o-dpck__table__row'),
];
},
tableCellClasses() {
return [
this.computedClass('tableCellClass', 'o-dpck__table__cell'),
];
},
tableEventsClasses() {
return [
this.computedClass('tableEventsClass', 'o-dpck__table__events'),
];
},
hasEvents() {
return this.events && this.events.length;
}
},
watch: {
day(day) {
const refName = `day-${this.month}-${day}`;
this.$nextTick(() => {
if (this.$refs[refName] && this.$refs[refName].length > 0) {
if (this.$refs[refName][0]) {
this.$refs[refName][0].focus();
}
}
}); // $nextTick needed when month is changed
}
},
methods: {
firstWeekOffset(year, dow, doy) {
// first-week day -- which january is always in the first week (4 for iso, 1 for other)
const fwd = 7 + dow - doy;
// first-week day local weekday -- which local weekday is fwd
const firstJanuary = new Date(year, 0, fwd);
const fwdlw = (7 + firstJanuary.getDay() - dow) % 7;
return -fwdlw + fwd - 1;
},
daysInYear(year) {
return this.isLeapYear(year) ? 366 : 365;
},
isLeapYear(year) {
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
},
getSetDayOfYear(input) {
return Math.round((input.getTime() - new Date(input.getFullYear(), 0, 1).getTime()) / 864e5) + 1;
},
weeksInYear(year, dow, doy) {
const weekOffset = this.firstWeekOffset(year, dow, doy);
const weekOffsetNext = this.firstWeekOffset(year + 1, dow, doy);
return (this.daysInYear(year) - weekOffset + weekOffsetNext) / 7;
},
getWeekNumber(mom) {
const dow = this.firstDayOfWeek; // first day of week
// Rules for the first week : 1 for the 1st January, 4 for the 4th January
const doy = this.rulesForFirstWeek;
const weekOffset = this.firstWeekOffset(mom.getFullYear(), dow, doy);
const week = Math.floor((this.getSetDayOfYear(mom) - weekOffset - 1) / 7) + 1;
let resWeek;
let resYear;
if (week < 1) {
resYear = mom.getFullYear() - 1;
resWeek = week + this.weeksInYear(resYear, dow, doy);
}
else if (week > this.weeksInYear(mom.getFullYear(), dow, doy)) {
resWeek = week - this.weeksInYear(mom.getFullYear(), dow, doy);
resYear = mom.getFullYear() + 1;
}
else {
resYear = mom.getFullYear();
resWeek = week;
}
return resWeek;
},
clickWeekNumber(week) {
if (this.weekNumberClickable) {
this.$datepicker.$emit('week-number-click', week);
}
},
/*
* Check that selected day is within earliest/latest params and
* is within this month
*/
selectableDate(day) {
const validity = [];
if (this.minDate) {
validity.push(day >= this.minDate);
}
if (this.maxDate) {
validity.push(day <= this.maxDate);
}
if (this.nearbyMonthDays && !this.nearbySelectableMonthDays) {
validity.push(day.getMonth() === this.month);
}
if (this.selectableDates) {
for (let i = 0; i < this.selectableDates.length; i++) {
const enabledDate = this.selectableDates[i];
if (day.getDate() === enabledDate.getDate() &&
day.getFullYear() === enabledDate.getFullYear() &&
day.getMonth() === enabledDate.getMonth()) {
return true;
}
else {
validity.push(false);
}
}
}
if (this.unselectableDates) {
for (let i = 0; i < this.unselectableDates.length; i++) {
const disabledDate = this.unselectableDates[i];
validity.push(day.getDate() !== disabledDate.getDate() ||
day.getFullYear() !== disabledDate.getFullYear() ||
day.getMonth() !== disabledDate.getMonth());
}
}
if (this.unselectableDaysOfWeek) {
for (let i = 0; i < this.unselectableDaysOfWeek.length; i++) {
const dayOfWeek = this.unselectableDaysOfWeek[i];
validity.push(day.getDay() !== dayOfWeek);
}
}
return validity.indexOf(false) < 0;
},
/*
* Emit select event with chosen date as payload
*/
emitChosenDate(day) {
if (this.disabled)
return;
if (this.selectableDate(day)) {
this.$emit('select', day);
}
},
eventsDateMatch(day) {
if (!this.events || !this.events.length)
return false;
const dayEvents = [];
for (let i = 0; i < this.events.length; i++) {
if (this.events[i].date.getDay() === day.getDay()) {
dayEvents.push(this.events[i]);
}
}
if (!dayEvents.length) {
return false;
}
return dayEvents;
},
/*
* Build cellClasses for cell using validations
*/
cellClasses(day) {
function dateMatch(dateOne, dateTwo, multiple = false) {
// if either date is null or undefined, return false
// if using multiple flag, return false
if (!dateOne || !dateTwo || multiple) {
return false;
}
if (Array.isArray(dateTwo)) {
return dateTwo.some((date) => (dateOne.getDate() === date.getDate() &&
dateOne.getFullYear() === date.getFullYear() &&
dateOne.getMonth() === date.getMonth()));
}
return (dateOne.getDate() === dateTwo.getDate() &&
dateOne.getFullYear() === dateTwo.getFullYear() &&
dateOne.getMonth() === dateTwo.getMonth());
}
function dateWithin(dateOne, dates, multiple = false) {
if (!Array.isArray(dates) || multiple) {
return false;
}
return dateOne > dates[0] && dateOne < dates[1];
}
return [
...this.tableCellClasses,
{
[this.computedClass('tableCellSelectedClass', 'o-dpck__table__cell--selected')]: dateMatch(day, this.selectedDate) || dateWithin(day, this.selectedDate, this.multiple)
},
{
[this.computedClass('tableCellFirstSelectedClass', 'o-dpck__table__cell--first-selected')]: dateMatch(day, Array.isArray(this.selectedDate) && this.selectedDate[0], this.multiple),
},
{
[this.computedClass('tableCellWithinSelectedClass', 'o-dpck__table__cell--within-selected')]: dateWithin(day, this.selectedDate, this.multiple)
},
{
[this.computedClass('tableCellLastSelectedClass', 'o-dpck__table__cell--last-selected')]: dateMatch(day, Array.isArray(this.selectedDate) && this.selectedDate[1], this.multiple),
},
{
[this.computedClass('tableCellFirstHoveredClass', 'o-dpck__table__cell--first-hovered')]: dateMatch(day, Array.isArray(this.hoveredDateRange) && this.hoveredDateRange[0]),
},
{
[this.computedClass('tableCellWithinHoveredClass', 'o-dpck__table__cell--within-hovered')]: dateWithin(day, this.hoveredDateRange)
},
{
[this.computedClass('tableCellLastHoveredClass', 'o-dpck__table__cell--last-hovered')]: dateMatch(day, Array.isArray(this.hoveredDateRange) && this.hoveredDateRange[1])
},
{
[this.computedClass('tableCellTodayClass', 'o-dpck__table__cell--today')]: dateMatch(day, this.dateCreator())
},
{
[this.computedClass('tableCellSelectableClass', 'o-dpck__table__cell--selectable')]: this.selectableDate(day) && !this.disabled
},
{
[this.computedClass('tableCellUnselectableClass', 'o-dpck__table__cell--unselectable')]: !this.selectableDate(day) || this.disabled
},
{
[this.computedClass('tableCellInvisibleClass', 'o-dpck__table__cell--invisible')]: !this.nearbyMonthDays && day.getMonth() !== this.month
},
{
[this.computedClass('tableCellNearbyClass', 'o-dpck__table__cell--nearby')]: this.nearbySelectableMonthDays && day.getMonth() !== this.month
},
{
[this.computedClass('tableCellEventsClass', 'o-dpck__table__cell--events')]: this.hasEvents
},
{
[this.computedClass('tableCellTodayClass', 'o-dpck__table__cell--today')]: dateMatch(day, this.dateCreator())
}
];
},
eventClasses(event) {
return [
this.computedClass('tableEventClass', 'o-dpck__table__event'),
{ [this.computedClass('tableEventVariantClass', 'o-dpck__table__event--', event.type)]: event.type },
{ [this.computedClass('tableEventIndicatorsClass', 'o-dpck__table__event--', this.indicators)]: this.indicators }
];
},
setRangeHoverEndDate(day) {
if (this.range) {
this.$emit('rangeHoverEndDate', day);
}
},
manageKeydown(event, weekDay) {
// https://developer.mozilla.org/fr/docs/Web/API/KeyboardEvent/key/Key_Values#Navigation_keys
const { key } = event;
let preventDefault = true;
switch (key) {
case 'Tab': {
preventDefault = false;
break;
}
case ' ':
case 'Space':
case 'Spacebar':
case 'Enter': {
this.emitChosenDate(weekDay);
break;
}
case 'ArrowLeft':
case 'Left': {
this.changeFocus(weekDay, -1);
break;
}
case 'ArrowRight':
case 'Right': {
this.changeFocus(weekDay, 1);
break;
}
case 'ArrowUp':
case 'Up': {
this.changeFocus(weekDay, -7);
break;
}
case 'ArrowDown':
case 'Down': {
this.changeFocus(weekDay, 7);
break;
}
}
if (preventDefault) {
event.preventDefault();
}
},
changeFocus(day, inc) {
const nextDay = new Date(day.getTime());
nextDay.setDate(day.getDate() + inc);
while ((!this.minDate || nextDay > this.minDate) &&
(!this.maxDate || nextDay < this.maxDate) &&
!this.selectableDate(nextDay)) {
nextDay.setDate(day.getDate() + Math.sign(inc));
}
this.setRangeHoverEndDate(nextDay);
this.$emit('change-focus', nextDay);
}
}
});
function render(_ctx, _cache, $props, $setup, $data, $options) {
return vue.openBlock(), vue.createBlock("div", {
class: _ctx.tableRowClasses
}, [_ctx.showWeekNumber ? (vue.openBlock(), vue.createBlock("a", {
key: 0,
class: _ctx.tableCellClasses,
style: {
'cursor: pointer': _ctx.weekNumberClickable
},
onClick: _cache[1] || (_cache[1] = vue.withModifiers($event => _ctx.clickWeekNumber(_ctx.getWeekNumber(_ctx.week[6])), ["prevent"]))
}, [vue.createVNode("span", null, vue.toDisplayString(_ctx.getWeekNumber(_ctx.week[6])), 1
/* TEXT */
)], 6
/* CLASS, STYLE */
)) : vue.createCommentVNode("v-if", true), (vue.openBlock(true), vue.createBlock(vue.Fragment, null, vue.renderList(_ctx.week, (weekDay, index) => {
return vue.openBlock(), vue.createBlock(vue.Fragment, {
key: index
}, [_ctx.selectableDate(weekDay) && !_ctx.disabled ? (vue.openBlock(), vue.createBlock("a", {
key: 0,
ref: `day-${weekDay.getMonth()}-${weekDay.getDate()}`,
class: _ctx.cellClasses(weekDay),
role: "button",
href: "#",
disabled: _ctx.disabled,
onClick: vue.withModifiers($event => _ctx.emitChosenDate(weekDay), ["prevent"]),
onMouseenter: $event => _ctx.setRangeHoverEndDate(weekDay),
onKeydown: $event => _ctx.manageKeydown($event, weekDay),
tabindex: _ctx.day === weekDay.getDate() && _ctx.month === weekDay.getMonth() ? null : -1
}, [vue.createVNode("span", null, vue.toDisplayString(weekDay.getDate()), 1
/* TEXT */
), _ctx.eventsDateMatch(weekDay) ? (vue.openBlock(), vue.createBlock("div", {
key: 0,
class: _ctx.tableEventsClasses
}, [(vue.openBlock(true), vue.createBlock(vue.Fragment, null, vue.renderList(_ctx.eventsDateMatch(weekDay), (event, index) => {
return vue.openBlock(), vue.createBlock("div", {
class: _ctx.eventClasses(event),
key: index
}, null, 2
/* CLASS */
);
}), 128
/* KEYED_FRAGMENT */
))], 2
/* CLASS */
)) : vue.createCommentVNode("v-if", true)], 42
/* CLASS, PROPS, HYDRATE_EVENTS */
, ["disabled", "onClick", "onMouseenter", "onKeydown", "tabindex"])) : (vue.openBlock(), vue.createBlock("div", {
key: index,
class: _ctx.cellClasses(weekDay)
}, [vue.createVNode("span", null, vue.toDisplayString(weekDay.getDate()), 1
/* TEXT */
)], 2
/* CLASS */
))], 64
/* STABLE_FRAGMENT */
);
}), 128
/* KEYED_FRAGMENT */
))], 2
/* CLASS */
);
}
script.render = render;
script.__file = "src/components/datepicker/DatepickerTableRow.vue";
var script$1 = vue.defineComponent({
name: 'ODatepickerTable',
mixins: [BaseComponentMixin.BaseComponentMixin],
configField: 'datepicker',
components: {
[script.name]: script
},
emits: ['update:modelValue', 'range-start', 'range-end', 'update:focused'],
props: {
modelValue: {
type: [Date, Array]
},
dayNames: Array,
monthNames: Array,
firstDayOfWeek: Number,
events: Array,
indicators: String,
minDate: Date,
maxDate: Date,
focused: Object,
disabled: Boolean,
dateCreator: Function,
unselectableDates: Array,
unselectableDaysOfWeek: Array,
selectableDates: Array,
nearbyMonthDays: Boolean,
nearbySelectableMonthDays: Boolean,
showWeekNumber: Boolean,
weekNumberClickable: Boolean,
rulesForFirstWeek: Number,
range: Boolean,
multiple: Boolean,
tableClass: [String, Function, Array],
tableHeadClass: [String, Function, Array],
tableHeadCellClass: [String, Function, Array],
tableBodyClass: [String, Function, Array],
tableRowClass: [String, Function, Array],
tableCellClass: [String, Function, Array],
tableCellSelectedClass: [String, Function, Array],
tableCellFirstSelectedClass: [String, Function, Array],
tableCellInvisibleClass: [String, Function, Array],
tableCellWithinSelectedClass: [String, Function, Array],
tableCellLastSelectedClass: [String, Function, Array],
tableCellFirstHoveredClass: [String, Function, Array],
tableCellWithinHoveredClass: [String, Function, Array],
tableCellLastHoveredClass: [String, Function, Array],
tableCellTodayClass: [String, Function, Array],
tableCellSelectableClass: [String, Function, Array],
tableCellUnselectableClass: [String, Function, Array],
tableCellNearbyClass: [String, Function, Array],
tableCellEventsClass: [String, Function, Array],
tableEventClass: [String, Function, Array],
tableEventIndicatorsClass: [String, Function, Array],
tableEventsClass: [String, Function, Array],
tableEventVariantClass: [String, Function, Array],
},
data() {
return {
selectedBeginDate: undefined,
selectedEndDate: undefined,
hoveredEndDate: undefined
};
},
computed: {
tableClasses() {
return [
this.computedClass('tableClass', 'o-dpck__table')
];
},
tableHeadClasses() {
return [
this.computedClass('tableHeadClass', 'o-dpck__table__head')
];
},
tableHeadCellClasses() {
return [
this.computedClass('tableHeadCellClass', 'o-dpck__table__head-cell'),
...this.tableCellClasses
];
},
tableBodyClasses() {
return [
this.computedClass('tableBodyClass', 'o-dpck__table__body')
];
},
tableCellClasses() {
return [
this.computedClass('tableCellClass', 'o-dpck__table__cell'),
];
},
visibleDayNames() {
const visibleDayNames = [];
let index = this.firstDayOfWeek;
while (visibleDayNames.length < this.dayNames.length) {
const currentDayName = this.dayNames[(index % this.dayNames.length)];
visibleDayNames.push(currentDayName);
index++;
}
if (this.showWeekNumber)
visibleDayNames.unshift('');
return visibleDayNames;
},
/*
* Return array of all events in the specified month
*/
eventsInThisMonth() {
if (!this.events)
return [];
const monthEvents = [];
for (let i = 0; i < this.events.length; i++) {
let event = this.events[i];
if (!Object.prototype.hasOwnProperty.call(event, 'date')) {
event = { date: event };
}
if (event.date.getMonth() === this.focused.month &&
event.date.getFullYear() === this.focused.year) {
monthEvents.push(event);
}
}
return monthEvents;
},
/*
* Return array of all weeks in the specified month
*/
weeksInThisMonth() {
this.validateFocusedDay();
const month = this.focused.month;
const year = this.focused.year;
const weeksInThisMonth = [];
let startingDay = 1;
while (weeksInThisMonth.length < 6) {
const newWeek = this.weekBuilder(startingDay, month, year);
weeksInThisMonth.push(newWeek);
startingDay += 7;
}
return weeksInThisMonth;
},
hoveredDateRange() {
if (!this.range) {
return [];
}
if (!isNaN(this.selectedEndDate)) {
return [];
}
if (this.hoveredEndDate < this.selectedBeginDate) {
return [this.hoveredEndDate, this.selectedBeginDate].filter(d => d !== undefined);
}
return [this.selectedBeginDate, this.hoveredEndDate].filter(d => d !== undefined);
}
},
methods: {
/*
* Emit input event with selected date as payload for v-model in parent
*/
updateSelectedDate(date) {
if (!this.range && !this.multiple) {
this.$emit('update:modelValue', date);
}
else if (this.range) {
this.handleSelectRangeDate(date);
}
else if (this.multiple) {
this.handleSelectMultipleDates(date);
}
},
/*
* If both begin and end dates are set, reset the end date and set the begin date.
* If only begin date is selected, emit an array of the begin date and the new date.
* If not set, only set the begin date.
*/
handleSelectRangeDate(date) {
if (this.selectedBeginDate && this.selectedEndDate) {
this.selectedBeginDate = date;
this.selectedEndDate = undefined;
this.$emit('range-start', date);
}
else if (this.selectedBeginDate && !this.selectedEndDate) {
if (this.selectedBeginDate > date) {
this.selectedEndDate = this.selectedBeginDate;
this.selectedBeginDate = date;
}
else {
this.selectedEndDate = date;
}
this.$emit('range-end', date);
this.$emit('update:modelValue', [this.selectedBeginDate, this.selectedEndDate]);
}
else {
this.selectedBeginDate = date;
this.$emit('range-start', date);
}
},
/*
* If selected date already exists list of selected dates, remove it from the list
* Otherwise, add date to list of selected dates
*/
handleSelectMultipleDates(date) {
let multipleSelectedDates = this.modelValue;
const multipleSelect = multipleSelectedDates.filter((selectedDate) => selectedDate.getDate() === date.getDate() &&
selectedDate.getFullYear() === date.getFullYear() &&
selectedDate.getMonth() === date.getMonth());
if (multipleSelect.length) {
multipleSelectedDates = multipleSelectedDates.filter((selectedDate) => selectedDate.getDate() !== date.getDate() ||
selectedDate.getFullYear() !== date.getFullYear() ||
selectedDate.getMonth() !== date.getMonth());
}
else {
multipleSelectedDates = [...multipleSelectedDates, date];
}
this.$emit('update:modelValue', multipleSelectedDates);
},
/*
* Return array of all days in the week that the startingDate is within
*/
weekBuilder(startingDate, month, year) {
const thisMonth = new Date(year, month);
const thisWeek = [];
const dayOfWeek = new Date(year, month, startingDate).getDay();
const end = dayOfWeek >= this.firstDayOfWeek
? (dayOfWeek - this.firstDayOfWeek)
: ((7 - this.firstDayOfWeek) + dayOfWeek);
let daysAgo = 1;
for (let i = 0; i < end; i++) {
thisWeek.unshift(new Date(thisMonth.getFullYear(), thisMonth.getMonth(), startingDate - daysAgo));
daysAgo++;
}
thisWeek.push(new Date(year, month, startingDate));
let daysForward = 1;
while (thisWeek.length < 7) {
thisWeek.push(new Date(year, month, startingDate + daysForward));
daysForward++;
}
return thisWeek;
},
validateFocusedDay() {
const focusedDate = new Date(this.focused.year, this.focused.month, this.focused.day);
if (this.selectableDate(focusedDate))
return;
let day = 0;
// Number of days in the current month
const monthDays = new Date(this.focused.year, this.focused.month + 1, 0).getDate();
let firstFocusable = null;
while (!firstFocusable && ++day < monthDays) {
const date = new Date(this.focused.year, this.focused.month, day);
if (this.selectableDate(date)) {
firstFocusable = focusedDate;
const focused = {
day: date.getDate(),
month: date.getMonth(),
year: date.getFullYear()
};
this.$emit('update:focused', focused);
}
}
},
/*
* Check that selected day is within earliest/latest params and
* is within this month
*/
selectableDate(day) {
const validity = [];
if (this.minDate) {
validity.push(day >= this.minDate);
}
if (this.maxDate) {
validity.push(day <= this.maxDate);
}
if (this.nearbyMonthDays && !this.nearbySelectableMonthDays) {
validity.push(day.getMonth() === this.focused.month);
}
if (this.selectableDates) {
for (let i = 0; i < this.selectableDates.length; i++) {
const enabledDate = this.selectableDates[i];
if (day.getDate() === enabledDate.getDate() &&
day.getFullYear() === enabledDate.getFullYear() &&
day.getMonth() === enabledDate.getMonth()) {
return true;
}
else {
validity.push(false);
}
}
}
if (this.unselectableDates) {
for (let i = 0; i < this.unselectableDates.length; i++) {
const disabledDate = this.unselectableDates[i];
validity.push(day.getDate() !== disabledDate.getDate() ||
day.getFullYear() !== disabledDate.getFullYear() ||
day.getMonth() !== disabledDate.getMonth());
}
}
if (this.unselectableDaysOfWeek) {
for (let i = 0; i < this.unselectableDaysOfWeek.length; i++) {
const dayOfWeek = this.unselectableDaysOfWeek[i];
validity.push(day.getDay() !== dayOfWeek);
}
}
return validity.indexOf(false) < 0;
},
eventsInThisWeek(week) {
return this.eventsInThisMonth.filter((event) => {
const stripped = new Date(Date.parse(event.date));
stripped.setHours(0, 0, 0, 0);
const timed = stripped.getTime();
return week.some((weekDate) => weekDate.getTime() === timed);
});
},
setRangeHoverEndDate(day) {
this.hoveredEndDate = day;
},
changeFocus(day) {
const focused = {
day: day.getDate(),
month: day.getMonth(),
year: day.getFullYear()
};
this.$emit('update:focused', focused);
}
}
});
function render$1(_ctx, _cache, $props, $setup, $data, $options) {
const _component_o_datepicker_table_row = vue.resolveComponent("o-datepicker-table-row");
return vue.openBlock(), vue.createBlock("section", {
class: _ctx.tableClasses
}, [vue.createVNode("header", {
class: _ctx.tableHeadClasses
}, [(vue.openBlock(true), vue.createBlock(vue.Fragment, null, vue.renderList(_ctx.visibleDayNames, (day, index) => {
return vue.openBlock(), vue.createBlock("div", {
key: index,
class: _ctx.tableHeadCellClasses
}, [vue.createVNode("span", null, vue.toDisplayString(day), 1
/* TEXT */
)], 2
/* CLASS */
);
}), 128
/* KEYED_FRAGMENT */
))], 2
/* CLASS */
), vue.createVNode("div", {
class: _ctx.tableBodyClasses
}, [(vue.openBlock(true), vue.createBlock(vue.Fragment, null, vue.renderList(_ctx.weeksInThisMonth, (week, index) => {
return vue.openBlock(), vue.createBlock(_component_o_datepicker_table_row, {
key: index,
"selected-date": _ctx.modelValue,
day: _ctx.focused.day,
week: week,
month: _ctx.focused.month,
"min-date": _ctx.minDate,
"max-date": _ctx.maxDate,
disabled: _ctx.disabled,
"unselectable-dates": _ctx.unselectableDates,
"unselectable-days-of-week": _ctx.unselectableDaysOfWeek,
"selectable-dates": _ctx.selectableDates,
events: _ctx.eventsInThisWeek(week),
indicators: _ctx.indicators,
"date-creator": _ctx.dateCreator,
"nearby-month-days": _ctx.nearbyMonthDays,
"nearby-selectable-month-days": _ctx.nearbySelectableMonthDays,
"show-week-number": _ctx.showWeekNumber,
"week-number-clickable": _ctx.weekNumberClickable,
"first-day-of-week": _ctx.firstDayOfWeek,
"rules-for-first-week": _ctx.rulesForFirstWeek,
range: _ctx.range,
"hovered-date-range": _ctx.hoveredDateRange,
multiple: _ctx.multiple,
"table-row-class": _ctx.tableRowClass,
"table-cell-class": _ctx.tableCellClass,
"table-cell-selected-class": _ctx.tableCellSelectedClass,
"table-cell-first-selected-class": _ctx.tableCellFirstSelectedClass,
"table-cell-invisible-class": _ctx.tableCellInvisibleClass,
"table-cell-within-selected-class": _ctx.tableCellWithinSelectedClass,
"table-cell-last-selected-class": _ctx.tableCellLastSelectedClass,
"table-cell-first-hovered-class": _ctx.tableCellFirstHoveredClass,
"table-cell-within-hovered-class": _ctx.tableCellWithinHoveredClass,
"table-cell-last-hovered-class": _ctx.tableCellLastHoveredClass,
"table-cell-today-class": _ctx.tableCellTodayClass,
"table-cell-selectable-class": _ctx.tableCellSelectableClass,
"table-cell-unselectable-class": _ctx.tableCellUnselectableClass,
"table-cell-nearby-class": _ctx.tableCellNearbyClass,
"table-cell-events-class": _ctx.tableCellEventsClass,
"table-events-class": _ctx.tableEventsClass,
"table-event-variant-class": _ctx.tableEventVariantClass,
"table-event-class": _ctx.tableEventClass,
"table-event-indicators-class": _ctx.tableEventIndicatorsClass,
onSelect: _ctx.updateSelectedDate,
onRangeHoverEndDate: _ctx.setRangeHoverEndDate,
"onChange-focus": _ctx.changeFocus
}, null, 8
/* PROPS */
, ["selected-date", "day", "week", "month", "min-date", "max-date", "disabled", "unselectable-dates", "unselectable-days-of-week", "selectable-dates", "events", "indicators", "date-creator", "nearby-month-days", "nearby-selectable-month-days", "show-week-number", "week-number-clickable", "first-day-of-week", "rules-for-first-week", "range", "hovered-date-range", "multiple", "table-row-class", "table-cell-class", "table-cell-selected-class", "table-cell-first-selected-class", "table-cell-invisible-class", "table-cell-within-selected-class", "table-cell-last-selected-class", "table-cell-first-hovered-class", "table-cell-within-hovered-class", "table-cell-last-hovered-class", "table-cell-today-class", "table-cell-selectable-class", "table-cell-unselectable-class", "table-cell-nearby-class", "table-cell-events-class", "table-events-class", "table-event-variant-class", "table-event-class", "table-event-indicators-class", "onSelect", "onRangeHoverEndDate", "onChange-focus"]);
}), 128
/* KEYED_FRAGMENT */
))], 2
/* CLASS */
)], 2
/* CLASS */
);
}
script$1.render = render$1;
script$1.__file = "src/components/datepicker/DatepickerTable.vue";
var DatepickerMixin = {
methods: {
manageKeydown(event, weekDay) {
// https://developer.mozilla.org/fr/docs/Web/API/KeyboardEvent/key/Key_Values#Navigation_keys
const { key } = event;
let preventDefault = true;
switch (key) {
case 'Tab': {
preventDefault = false;
break;
}
case ' ':
case 'Space':
case 'Spacebar':
case 'Enter': {
this.emitChosenDate(weekDay);
break;
}
case 'ArrowLeft':
case 'Left': {
this.changeFocus(weekDay, -1);
break;
}
case 'ArrowRight':
case 'Right': {
this.changeFocus(weekDay, 1);
break;
}
case 'ArrowUp':
case 'Up': {
this.changeFocus(weekDay, -7);
break;
}
case 'ArrowDown':
case 'Down': {
this.changeFocus(weekDay, 7);
break;
}
}
if (preventDefault) {
event.preventDefault();
}
}
}
};
var script$2 = {
name: 'ODatepickerMonth',
mixins: [BaseComponentMixin.BaseComponentMixin, DatepickerMixin],
configField: 'datepicker',
emits: ['update:modelValue', 'range-start', 'range-end', 'updated:focused'],
props: {
modelValue: {
type: [Date, Array]
},
monthNames: Array,
events: Array,
indicators: String,
minDate: Date,
maxDate: Date,
focused: Object,
disabled: Boolean,
dateCreator: Function,
unselectableDates: [Array, Function],
unselectableDaysOfWeek: Array,
selectableDates: [Array, Function],
range: Boolean,
multiple: Boolean,
monthClass: [String, Function, Array],
monthBodyClass: [String, Function, Array],
monthTableClass: [String, Function, Array],
monthCellClass: [String, Function, Array],
monthCellSelectedClass: [String, Function, Array],
monthCellFirstSelectedClass: [String, Function, Array],
monthCellWithinSelectedClass: [String, Function, Array],
monthCellLastSelectedClass: [String, Function, Array],
monthCellWithinHoveredRangeClass: [String, Function, Array],
monthCellFirstHoveredClass: [String, Function, Array],
monthCellWithinHoveredClass: [String, Function, Array],
monthCellLastHoveredClass: [String, Function, Array],
monthCellTodayClass: [String, Function, Array],
monthCellSelectableClass: [String, Function, Array],
monthCellUnselectableClass: [String, Function, Array],
monthCellEventsClass: [String, Function, Array]
},
data() {
return {
selectedBeginDate: undefined,
selectedEndDate: undefined,
hoveredEndDate: undefined,
multipleSelectedDates: this.multiple && this.modelValue ? this.modelValue : []
};
},
computed: {
monthClasses() {
return [
this.computedClass('monthClass', 'o-dpck__month')
];
},
monthBodyClasses() {
return [
this.computedClass('monthBodyClass', 'o-dpck__month__body')
];
},
monthTableClasses() {
return [
this.computedClass('monthTableClass', 'o-dpck__month__table')
];
},
monthCellClasses() {
return [
this.computedClass('monthCellClass', 'o-dpck__month__cell')
];
},
hasEvents() {
return this.events && this.events.length;
},
/*
* Return array of all events in the specified month
*/
eventsInThisYear() {
if (!this.events)
return [];
const yearEvents = [];
for (let i = 0; i < this.events.length; i++) {
let event = this.events[i];
if (!Object.prototype.hasOwnProperty.call(event, 'date')) {
event = { date: event };
}
if (!Object.prototype.hasOwnProperty.call(event, 'type')) {
event.type = 'is-primary';
}
if (event.date.getFullYear() === this.focused.year) {
yearEvents.push(event);
}
}
return yearEvents;
},
monthDates() {
const year = this.focused.year;
const months = [];
for (let i = 0; i < 12; i++) {
const d = new Date(year, i, 1);
d.setHours(0, 0, 0, 0);
months.push(d);
}
return months;
},
focusedMonth() {
return this.focused.month;
},
hoveredDateRange() {
if (!this.range) {
return [];
}
if (!isNaN(this.selectedEndDate)) {
return [];
}
if (this.hoveredEndDate < this.selectedBeginDate) {
return [this.hoveredEndDate, this.selectedBeginDate].filter(helpers.isDefined);
}
return [this.selectedBeginDate, this.hoveredEndDate].filter(helpers.isDefined);
}
},
watch: {
focusedMonth(month) {
const refName = `month-${month}`;
if (this.$refs[refName] && this.$refs[refName].length > 0) {
this.$nextTick(() => {
if (this.$refs[refName][0]) {
this.$refs[refName][0].focus();
}
}); // $nextTick needed when year is changed
}
}
},
methods: {
selectMultipleDates(date) {
const multipleSelect = this.multipleSelectedDates.filter((selectedDate) => selectedDate.getDate() === date.getDate() &&
selectedDate.getFullYear() === date.getFullYear() &&
selectedDate.getMonth() === date.getMonth());
if (multipleSelect.length) {
this.multipleSelectedDates = this.multipleSelectedDates.filter((selectedDate) => selectedDate.getDate() !== date.getDate() ||
selectedDate.getFullYear() !== date.getFullYear() ||
selectedDate.getMonth() !== date.getMonth());
}
else {
this.multipleSelectedDates.push(date);
}
this.$emit('update:modelValue', this.multipleSelectedDates);
},
selectableDate(day) {
const validity = [];
if (this.minDate) {
validity.push(day >= this.minDate);
}
if (this.maxDate) {
validity.push(day <= this.maxDate);
}
validity.push(day.getFullYear() === this.focused.year);
if (this.selectableDates) {
if (typeof this.selectableDates === 'function') {
if (this.selectableDates(day)) {
return true;
}
else {
validity.push(false);
}
}
else {
for (let i = 0; i < this.selectableDates.length; i++) {
const enabledDate = this.selectableDates[i];
if (day.getFullYear() === enabledDate.getFullYear() &&
day.getMonth() === enabledDate.getMonth()) {
return true;
}
else {
validity.push(false);
}
}
}
}
if (this.unselectableDates) {
if (typeof this.unselectableDates === 'function') {
validity.push(!this.unselectableDates(day));
}
else {
for (let i = 0; i < this.unselectableDates.length; i++) {
const disabledDate = this.unselectableDates[i];
validity.push(day.getFullYear() !== disabledDate.getFullYear() ||
day.getMonth() !== disabledDate.getMonth());
}
}
}
if (this.unselectableDaysOfWeek) {
for (let i = 0; i < this.unselectableDaysOfWeek.length; i++) {
const dayOfWeek = this.unselectableDaysOfWeek[i];
validity.push(day.getDay() !== dayOfWeek);
}
}
return validity.indexOf(false) < 0;
},
eventsDateMatch(day) {
if (!this.eventsInThisYear.length)
return false;
const monthEvents = [];
for (let i = 0; i < this.eventsInThisYear.length; i++) {
if (this.eventsInThisYear[i].date.getMonth() === day.getMonth()) {
monthEvents.push(this.events[i]);
}
}
if (!monthEvents.length) {
return false;
}
return monthEvents;
},
/*
* Build cellClasses for cell using validations
*/
cellClasses(day) {
function dateMatch(dateOne, dateTwo, multiple = false) {
// if either date is null or undefined, return false
if (!dateOne || !dateTwo || multiple) {
return false;
}
if (Array.isArray(dateTwo)) {
return dateTwo.some((date) => (dateOne.getFullYear() === date.getFullYear() &&
dateOne.getMonth() === date.getMonth()));
}
return (dateOne.getFullYear() === dateTwo.getFullYear() &&
dateOne.getMonth() === dateTwo.getMonth());
}
function dateWithin(dateOne, dates, multiple = false) {
if (!Array.isArray(dates) || multiple) {
return false;
}
return dateOne > dates[0] && dateOne < dates[1];
}
function dateMultipleSelected(dateOne, dates, multiple = false) {
if (!Array.isArray(dates) || !multiple) {
return false;
}
return dates.some((date) => (dateOne.getDate() === date.getDate() &&
dateOne.getFullYear() === date.getFullYear() &&
dateOne.getMonth() === date.getMonth()));
}
return [
...this.monthCellClasses,
{
[this.computedClass('monthCellSelectedClass', 'o-dpck__month__cell--selected')]: dateMatch(day, this.modelValue, this.multiple) ||
dateWithin(day, this.modelValue, this.multiple) ||
dateMultipleSelected(day, this.multipleSelectedDates, this.multiple)
},
{
[this.computedClass('monthCellFirstSelectedClass', 'o-dpck__month__cell--first-selected')]: dateMatch(day, Array.isArray(this.modelValue) && this.modelValue[0], this.multiple)
},
{
[this.computedClass('monthCellWithinSelectedClass', 'o-dpck__month__cell--within-selected')]: dateWithin(day, this.modelValue, this.multiple)
},
{
[this.computedClass('monthCellLastSelectedClass', 'o-dpck__month__cell--last-selected')]: dateMatch(day, Array.isArray(this.modelValue) && this.modelValue[1], this.multiple)
},
{
[this.computedClass('monthCellWithinHoveredRangeClass', 'o-dpck__month__cell--within-hovered-range')]: this.hoveredDateRange && this.hoveredDateRange.length === 2 &&
(dateMatch(day, this.hoveredDateRange) ||
dateWithin(day, this.hoveredDateRange))
},
{
[this.computedClass('monthCellFirstHoveredClass', 'o-dpck__month__cell--first-hovered')]: dateMatch(day, Array.isArray(this.hoveredDateRange) && this.hoveredDateRange[0])
},
{
[this.computedClass('monthCellWithinHoveredClass', 'o-dpck__month__cell--within-hovered')]: dateWithin(day, this.hoveredDateRange)
},
{
[this.computedClass('monthCellLastHoveredClass', 'o-dpck__month__cell--last-hovered')]: dateMatch(day, Array.isArray(this.hoveredDateRange) && this.hoveredDateRange[1])
},
{
[this.computedClass('monthCellTodayClass', 'o-dpck__month__cell--today')]: dateMatch(day, this.dateCreator())
},
{
[this.computedClass('monthCellSelectableclass', 'o-dpck__month__cell--selectable')]: this.selectableDate(day) && !this.disabled
},
{
[this.computedClass('monthCellUnselectableClass', 'o-dpck__month__cell--unselectable')]: !this.selectableDate(day) || this.disabled
},
{
[this.computedClass('monthCellEventsClass', 'o-dpck__month__cell--events')]: this.hasEvents
},
];
},
/*
* Emit update:modelValue event with selected date as payload for v-model in parent
*/
updateSelectedDate(date) {
if (!this.range && !this.multiple) {
this.emitChosenDate(date);