buefy
Version:
Lightweight UI components for Vue.js (v3) based on Bulma
1,458 lines (1,450 loc) • 77.4 kB
JavaScript
'use strict';
var vue = require('vue');
var CompatFallthroughMixin = require('./CompatFallthroughMixin-hhK0Gkhr.js');
var FormElementMixin = require('./FormElementMixin-DavX4iOv.js');
var helpers = require('./helpers.js');
var config = require('./config-DR826Ki2.js');
var Dropdown = require('./Dropdown-DtpKU9qf.js');
var DropdownItem = require('./DropdownItem-IMOKyRGV.js');
var Input = require('./Input-BcloGeZ3.js');
var Field = require('./Field-19ZCJFF8.js');
var Select = require('./Select-DayPKwCY.js');
var Icon = require('./Icon-lsDKE2wQ.js');
var _pluginVue_exportHelper = require('./_plugin-vue_export-helper-Die8u8yB.js');
var _sfc_main$3 = vue.defineComponent({
name: "BDatepickerTableRow",
inject: {
$datepicker: { name: "$datepicker", default: false }
},
props: {
selectedDate: {
type: [Date, Array]
},
hoveredDateRange: Array,
day: {
type: Number
},
week: {
type: Array,
required: true
},
month: {
type: Number,
required: true
},
minDate: [Date, null],
maxDate: [Date, null],
disabled: Boolean,
unselectableDates: [Array, Function, null],
unselectableDaysOfWeek: [Array, null],
selectableDates: [Array, Function, null],
events: Array,
indicators: String,
dateCreator: Function,
nearbyMonthDays: Boolean,
nearbySelectableMonthDays: Boolean,
showWeekNumber: Boolean,
weekNumberClickable: Boolean,
range: Boolean,
multiple: Boolean,
rulesForFirstWeek: Number,
firstDayOfWeek: [Number, null]
},
emits: {
/* eslint-disable @typescript-eslint/no-unused-vars */
"change-focus": (_day) => true,
rangeHoverEndDate: (_day) => true,
select: (_day) => true
/* eslint-enable @typescript-eslint/no-unused-vars */
},
watch: {
day(day) {
const refName = `day-${this.month}-${day}`;
this.$nextTick(() => {
let cell;
if (Array.isArray(this.$refs[refName])) {
cell = this.$refs[refName][0];
} else {
cell = this.$refs[refName];
}
if (cell) {
cell.focus();
}
});
}
},
methods: {
firstWeekOffset(year, dow, doy) {
const fwd = 7 + dow - doy;
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 - +new Date(input.getFullYear(), 0, 1)) / 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;
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 { week: resWeek, year: resYear };
},
clickWeekNumber(weekData) {
if (this.weekNumberClickable) {
this.$datepicker.$emit("week-number-click", weekData.week, weekData.year);
}
},
/*
* 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) {
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.getDate() === enabledDate.getDate() && 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.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);
}
},
// TODO: return undefined instead of boolean if no events
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 classObject for cell using validations
*/
classObject(day) {
function dateMatch(dateOne, dateTwo, multiple) {
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) {
if (!Array.isArray(dates) || multiple) {
return false;
}
return dateOne > dates[0] && dateOne < dates[1];
}
return {
"is-selected": dateMatch(day, this.selectedDate) || dateWithin(day, this.selectedDate, this.multiple),
"is-first-selected": dateMatch(
day,
Array.isArray(this.selectedDate) ? this.selectedDate[0] : void 0,
this.multiple
),
"is-within-selected": dateWithin(day, this.selectedDate, this.multiple),
"is-last-selected": dateMatch(
day,
Array.isArray(this.selectedDate) ? this.selectedDate[1] : void 0,
this.multiple
),
"is-within-hovered-range": this.hoveredDateRange && this.hoveredDateRange.length === 2 && (dateMatch(day, this.hoveredDateRange) || dateWithin(day, this.hoveredDateRange)),
"is-first-hovered": dateMatch(
day,
Array.isArray(this.hoveredDateRange) ? this.hoveredDateRange[0] : void 0
),
"is-within-hovered": dateWithin(day, this.hoveredDateRange),
"is-last-hovered": dateMatch(
day,
Array.isArray(this.hoveredDateRange) ? this.hoveredDateRange[1] : void 0
),
"is-today": dateMatch(day, this.dateCreator()),
"is-selectable": this.selectableDate(day) && !this.disabled,
"is-unselectable": !this.selectableDate(day) || this.disabled,
"is-invisible": !this.nearbyMonthDays && day.getMonth() !== this.month,
"is-nearby": this.nearbySelectableMonthDays && day.getMonth() !== this.month,
"has-event": this.eventsDateMatch(day),
[this.indicators]: this.eventsDateMatch(day)
};
},
setRangeHoverEndDate(day) {
if (this.range) {
this.$emit("rangeHoverEndDate", day);
}
},
manageKeydown(event, weekDay) {
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(nextDay.getDate() + Math.sign(inc));
}
this.setRangeHoverEndDate(nextDay);
this.$emit("change-focus", nextDay);
}
}
});
const _hoisted_1$3 = { class: "datepicker-row" };
const _hoisted_2$3 = ["disabled", "onClick", "onMouseenter", "onKeydown", "tabindex"];
const _hoisted_3$2 = {
key: 0,
class: "events"
};
const _hoisted_4$2 = {
key: 0,
class: "events"
};
function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
return vue.openBlock(), vue.createElementBlock(
vue.Fragment,
null,
[
vue.createCommentVNode(" eslint-disable max-len "),
vue.createElementVNode("div", _hoisted_1$3, [
_ctx.showWeekNumber ? (vue.openBlock(), vue.createElementBlock(
"a",
{
key: 0,
class: vue.normalizeClass(["datepicker-cell is-week-number", { "is-clickable": _ctx.weekNumberClickable }]),
onClick: _cache[0] || (_cache[0] = vue.withModifiers(($event) => _ctx.clickWeekNumber(_ctx.getWeekNumber(_ctx.week[6])), ["prevent"]))
},
[
vue.createElementVNode(
"span",
null,
vue.toDisplayString(_ctx.getWeekNumber(_ctx.week[6]).week),
1
/* TEXT */
)
],
2
/* CLASS */
)) : vue.createCommentVNode("v-if", true),
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList(_ctx.week, (weekDay, index) => {
return vue.openBlock(), vue.createElementBlock(
vue.Fragment,
{ key: index },
[
_ctx.selectableDate(weekDay) && !_ctx.disabled ? (vue.openBlock(), vue.createElementBlock("a", {
key: 0,
ref_for: true,
ref: `day-${weekDay.getMonth()}-${weekDay.getDate()}`,
class: vue.normalizeClass([_ctx.classObject(weekDay), "datepicker-cell"]),
role: "button",
href: "#",
disabled: _ctx.disabled || void 0,
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() ? void 0 : -1
}, [
vue.createElementVNode(
"span",
null,
vue.toDisplayString(weekDay.getDate()),
1
/* TEXT */
),
_ctx.eventsDateMatch(weekDay) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$2, [
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList(_ctx.eventsDateMatch(weekDay), (event, evIdx) => {
return vue.openBlock(), vue.createElementBlock(
"div",
{
class: vue.normalizeClass(["event", event.type]),
key: evIdx
},
null,
2
/* CLASS */
);
}),
128
/* KEYED_FRAGMENT */
))
])) : vue.createCommentVNode("v-if", true)
], 42, _hoisted_2$3)) : (vue.openBlock(), vue.createElementBlock(
"div",
{
key: 1,
class: vue.normalizeClass([_ctx.classObject(weekDay), "datepicker-cell"])
},
[
vue.createElementVNode(
"span",
null,
vue.toDisplayString(weekDay.getDate()),
1
/* TEXT */
),
_ctx.eventsDateMatch(weekDay) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4$2, [
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList(_ctx.eventsDateMatch(weekDay), (event, evIdx) => {
return vue.openBlock(), vue.createElementBlock(
"div",
{
class: vue.normalizeClass(["event", event.type]),
key: evIdx
},
null,
2
/* CLASS */
);
}),
128
/* KEYED_FRAGMENT */
))
])) : vue.createCommentVNode("v-if", true)
],
2
/* CLASS */
))
],
64
/* STABLE_FRAGMENT */
);
}),
128
/* KEYED_FRAGMENT */
))
]),
vue.createCommentVNode(" eslint-enable max-len ")
],
2112
/* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
);
}
var BDatepickerTableRow = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main$3, [["render", _sfc_render$3]]);
var _sfc_main$2 = vue.defineComponent({
name: "BDatepickerTable",
components: {
BDatepickerTableRow
},
props: {
modelValue: {
type: [Date, Array, null]
},
dayNames: [Array, null],
monthNames: [Array, null],
firstDayOfWeek: [Number, null],
events: Array,
indicators: String,
minDate: [Date, null],
maxDate: [Date, null],
focused: Object,
disabled: Boolean,
dateCreator: Function,
unselectableDates: [Array, Function, null],
unselectableDaysOfWeek: [Array, null],
selectableDates: [Array, Function, null],
nearbyMonthDays: Boolean,
nearbySelectableMonthDays: Boolean,
showWeekNumber: Boolean,
weekNumberClickable: Boolean,
rulesForFirstWeek: Number,
range: Boolean,
multiple: Boolean
},
emits: {
/* eslint-disable @typescript-eslint/no-unused-vars */
"range-end": (_date) => true,
"range-start": (_date) => true,
"update:focused": (_focused) => true,
"update:modelValue": (_value) => true
/* eslint-enable @typescript-eslint/no-unused-vars */
},
data() {
return {
selectedBeginDate: void 0,
selectedEndDate: void 0,
hoveredEndDate: void 0
};
},
computed: {
multipleSelectedDates: {
get() {
return this.multiple && this.modelValue ? this.modelValue : [];
},
set(value) {
this.$emit("update:modelValue", value);
}
},
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;
},
hasEvents() {
return this.events && this.events.length;
},
/*
* 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, type: "is-primary" };
}
if (!Object.prototype.hasOwnProperty.call(event, "type")) {
event.type = "is-primary";
}
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() {
var _a, _b;
if (!this.range) {
return [];
}
if (!isNaN((_b = (_a = this.selectedEndDate) == null ? void 0 : _a.valueOf()) != null ? _b : NaN)) {
return [];
}
if (this.hoveredEndDate < this.selectedBeginDate) {
return [this.hoveredEndDate, this.selectedBeginDate].filter(helpers.isDefined);
}
return [this.selectedBeginDate, this.hoveredEndDate].filter(helpers.isDefined);
},
disabledOrUndefined() {
return this.disabled || void 0;
}
},
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 = void 0;
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) {
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 = [...this.multipleSelectedDates, date];
}
},
/*
* 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;
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) {
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.getDate() === enabledDate.getDate() && 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.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);
}
}
});
const _hoisted_1$2 = { class: "datepicker-table" };
const _hoisted_2$2 = { class: "datepicker-header" };
function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
const _component_b_datepicker_table_row = vue.resolveComponent("b-datepicker-table-row");
return vue.openBlock(), vue.createElementBlock("section", _hoisted_1$2, [
vue.createElementVNode("header", _hoisted_2$2, [
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList(_ctx.visibleDayNames, (day, index) => {
return vue.openBlock(), vue.createElementBlock("div", {
key: index,
class: "datepicker-cell"
}, [
vue.createElementVNode(
"span",
null,
vue.toDisplayString(day),
1
/* TEXT */
)
]);
}),
128
/* KEYED_FRAGMENT */
))
]),
vue.createElementVNode(
"div",
{
class: vue.normalizeClass(["datepicker-body", { "has-events": _ctx.hasEvents }])
},
[
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList(_ctx.weeksInThisMonth, (week, index) => {
return vue.openBlock(), vue.createBlock(_component_b_datepicker_table_row, {
key: index,
"selected-date": _ctx.modelValue ?? void 0,
day: _ctx.focused.day,
week,
month: _ctx.focused.month,
"min-date": _ctx.minDate,
"max-date": _ctx.maxDate,
disabled: _ctx.disabledOrUndefined,
"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,
onSelect: _ctx.updateSelectedDate,
onRangeHoverEndDate: _ctx.setRangeHoverEndDate,
multiple: _ctx.multiple,
onChangeFocus: _ctx.changeFocus
}, null, 8, ["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", "onSelect", "onRangeHoverEndDate", "multiple", "onChangeFocus"]);
}),
128
/* KEYED_FRAGMENT */
))
],
2
/* CLASS */
)
]);
}
var BDatepickerTable = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main$2, [["render", _sfc_render$2]]);
var _sfc_main$1 = vue.defineComponent({
name: "BDatepickerMonth",
props: {
modelValue: {
type: [Date, Array, null]
},
monthNames: [Array, null],
events: Array,
indicators: String,
minDate: [Date, null],
maxDate: [Date, null],
focused: Object,
disabled: Boolean,
dateCreator: Function,
unselectableDates: [Array, Function, null],
unselectableDaysOfWeek: [Array, null],
selectableDates: [Array, Function, null],
range: Boolean,
multiple: Boolean
},
emits: {
/* eslint-disable @typescript-eslint/no-unused-vars */
"change-focus": (_date) => true,
"range-end": (_date) => true,
"range-start": (_date) => true,
"update:modelValue": (_date) => true
/* eslint-enable @typescript-eslint/no-unused-vars */
},
data() {
return {
selectedBeginDate: void 0,
selectedEndDate: void 0,
hoveredEndDate: void 0,
multipleSelectedDates: this.multiple && this.modelValue ? this.modelValue : []
};
},
computed: {
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, type: "is-primary" };
}
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() {
var _a, _b;
if (!this.range) {
return [];
}
if (!isNaN((_b = (_a = this.selectedEndDate) == null ? void 0 : _a.valueOf()) != null ? _b : NaN)) {
return [];
}
if (this.hoveredEndDate < this.selectedBeginDate) {
return [this.hoveredEndDate, this.selectedBeginDate].filter(helpers.isDefined);
}
return [this.selectedBeginDate, this.hoveredEndDate].filter(helpers.isDefined);
},
disabledOrUndefined() {
return this.disabled || void 0;
}
},
watch: {
focusedMonth(month) {
const refName = `month-${month}`;
this.$nextTick(() => {
let cell;
if (Array.isArray(this.$refs[refName])) {
cell = this.$refs[refName][0];
} else {
cell = this.$refs[refName];
}
if (cell) {
cell.focus();
}
});
}
},
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;
},
// TODO: return undefined instead of false if no events
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 classObject for cell using validations
*/
classObject(day) {
function dateMatch(dateOne, dateTwo, multiple) {
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) {
if (!Array.isArray(dates) || multiple) {
return false;
}
return dateOne > dates[0] && dateOne < dates[1];
}
function dateMultipleSelected(dateOne, dates, multiple) {
if (!Array.isArray(dates) || !multiple) {
return false;
}
return dates.some((date) => dateOne.getDate() === date.getDate() && dateOne.getFullYear() === date.getFullYear() && dateOne.getMonth() === date.getMonth());
}
return {
"is-selected": dateMatch(day, this.modelValue, this.multiple) || dateWithin(day, this.modelValue, this.multiple) || dateMultipleSelected(day, this.multipleSelectedDates, this.multiple),
"is-first-selected": dateMatch(
day,
Array.isArray(this.modelValue) ? this.modelValue[0] : void 0,
this.multiple
),
"is-within-selected": dateWithin(day, this.modelValue, this.multiple),
"is-last-selected": dateMatch(
day,
Array.isArray(this.modelValue) ? this.modelValue[1] : void 0,
this.multiple
),
"is-within-hovered-range": this.hoveredDateRange && this.hoveredDateRange.length === 2 && (dateMatch(day, this.hoveredDateRange) || dateWithin(day, this.hoveredDateRange)),
"is-first-hovered": dateMatch(
day,
Array.isArray(this.hoveredDateRange) ? this.hoveredDateRange[0] : void 0
),
"is-within-hovered": dateWithin(day, this.hoveredDateRange),
"is-last-hovered": dateMatch(
day,
Array.isArray(this.hoveredDateRange) ? this.hoveredDateRange[1] : void 0
),
"is-today": dateMatch(day, this.dateCreator()),
"is-selectable": this.selectableDate(day) && !this.disabled,
"is-unselectable": !this.selectableDate(day) || this.disabled
};
},
manageKeydown({ key }, date) {
switch (key) {
case " ":
case "Space":
case "Spacebar":
case "Enter": {
this.updateSelectedDate(date);
break;
}
case "ArrowLeft":
case "Left": {
this.changeFocus(date, -1);
break;
}
case "ArrowRight":
case "Right": {
this.changeFocus(date, 1);
break;
}
case "ArrowUp":
case "Up": {
this.changeFocus(date, -3);
break;
}
case "ArrowDown":
case "Down": {
this.changeFocus(date, 3);
break;
}
}
},
/*
* Emit input event with selected date as payload for v-model in parent
*/
updateSelectedDate(date) {
if (!this.range && !this.multiple) {
this.emitChosenDate(date);
} else if (this.range) {
this.handleSelectRangeDate(date);
} else if (this.multiple) {
this.selectMultipleDates(date);
}
},
/*
* Emit select event with chosen date as payload
*/
emitChosenDate(day) {
if (this.disabled) return;
if (!this.multiple) {
if (this.selectableDate(day)) {
this.$emit("update:modelValue", day);
}
} else {
this.selectMultipleDates(day);
}
},
/*
* 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.disabled) return;
if (this.selectedBeginDate && this.selectedEndDate) {
this.selectedBeginDate = date;
this.selectedEndDate = void 0;
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);
}
},
setRangeHoverEndDate(day) {
if (this.range) {
this.hoveredEndDate = day;
}
},
changeFocus(month, inc) {
const nextMonth = month;
nextMonth.setMonth(month.getMonth() + inc);
this.$emit("change-focus", nextMonth);
}
}
});
const _hoisted_1$1 = { class: "datepicker-table" };
const _hoisted_2$1 = { class: "datepicker-months" };
const _hoisted_3$1 = ["disabled", "onClick", "onMouseenter", "onKeydown", "tabindex"];
const _hoisted_4$1 = {
key: 0,
class: "events"
};
function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
return vue.openBlock(), vue.createElementBlock("section", _hoisted_1$1, [
vue.createElementVNode(
"div",
{
class: vue.normalizeClass(["datepicker-body", { "has-events": _ctx.hasEvents }])
},
[
vue.createElementVNode("div", _hoisted_2$1, [
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList(_ctx.monthDates, (date, index) => {
return vue.openBlock(), vue.createElementBlock(
vue.Fragment,
{ key: index },
[
_ctx.selectableDate(date) && !_ctx.disabled ? (vue.openBlock(), vue.createElementBlock("a", {
key: 0,
ref_for: true,
ref: `month-${date.getMonth()}`,
class: vue.normalizeClass([[
_ctx.classObject(date),
{ "has-event": _ctx.eventsDateMatch(date) },
_ctx.indicators
], "datepicker-cell"]),
role: "button",
href: "#",
disabled: _ctx.disabledOrUndefined,
onClick: vue.withModifiers(($event) => _ctx.updateSelectedDate(date), ["prevent"]),
onMouseenter: ($event) => _ctx.setRangeHoverEndDate(date),
onKeydown: vue.withModifiers(($event) => _ctx.manageKeydown($event, date), ["prevent"]),
tabindex: _ctx.focused.month === date.getMonth() ? void 0 : -1
}, [
vue.createTextVNode(
vue.toDisplayString(_ctx.monthNames[date.getMonth()]) + " ",
1
/* TEXT */
),
_ctx.eventsDateMatch(date) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4$1, [
(vue.openBlock(true), vue.createElementBlock(
vue.Fragment,
null,
vue.renderList(_ctx.eventsDateMatch(date), (event, evIdx) => {
return vue.openBlock(), vue.createElementBlock(
"div",
{
class: vue.normalizeClass(["event", event.type]),
key: evIdx
},
null,
2
/* CLASS */
);
}),
128
/* KEYED_FRAGMENT */
))
])) : vue.createCommentVNode("v-if", true)
], 42, _hoisted_3$1)) : (vue.openBlock(), vue.createElementBlock(
"div",
{
key: 1,
class: vue.normalizeClass([_ctx.classObject(date), "datepicker-cell"])
},
vue.toDisplayString(_ctx.monthNames[date.getMonth()]),
3
/* TEXT, CLASS */
))
],
64
/* STABLE_FRAGMENT */
);
}),
128
/* KEYED_FRAGMENT */
))
])
],
2
/* CLASS */
)
]);
}
var BDatepickerMonth = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main$1, [["render", _sfc_render$1]]);
const defaultDateFormatter = (date, vm) => {
const targetDates = Array.isArray(date) ? date : [date];
const dates = targetDates.map((date2) => {
const d = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate(), 12);
return !vm.isTypeMonth ? vm.dtf.format(d) : vm.dtfMonth.format(d);
});
return !vm.multiple ? dates.join(" - ") : dates.join(", ");
};
const defaultDateParser = (date, vm) => {
if (vm.dtf.formatToParts && typeof vm.dtf.formatToParts === "function") {
const formatRegex = (vm.isTypeMonth ? vm.dtfMonth : vm.dtf).formatToParts(new Date(2e3, 11, 25)).map((part) => {
if (part.type === "literal") {
return part.value;
}
return `((?!=<${part.type}>)\\d+)`;
}).join("");
const dateGroups = helpers.matchWithGroups(formatRegex, date);
if (dateGroups.year && dateGroups.year.length === 4 && dateGroups.month && +dateGroups.month <= 12) {
if (vm.isTypeMonth) return new Date(+dateGroups.year, +dateGroups.month - 1);
else if (dateGroups.day && +dateGroups.day <= 31) {
return new Date(+dateGroups.year, +dateGroups.month - 1, +dateGroups.day, 12);
}
}
}
if (!vm.isTypeMonth) return new Date(Date.parse(date));
if (date) {
const s = date.split("/");
const year = s[0].length === 4 ? s[0] : s[1];
const month = s[0].length === 2 ? s[0] : s[1];
if (year && month) {
return new Date(parseInt(year, 10), parseInt(month, 10) - 1, 1, 0, 0, 0, 0);
}
}
return null;
};
var _sfc_main = vue.defineComponent({
name: "BDatepicker",
components: {
BDatepickerTable,
BDatepickerMonth,
BInput: Input.BInput,
BField: Field.Field,
BSelect: Select.BSelect,
BIcon: Icon.BIcon,
BDropdown: Dropdown.BDropdown,
BDropdownItem: DropdownItem.BDropdownItem
},
mixins: [CompatFallthroughMixin.CompatFallthroughMixin, FormElementMixin.FormElementMixin],
provide() {
return {
$datepicker: this
};
},
props: {
modelValue: {
type: [Date, Array, null]
},
dayNames: {
type: [Array, null],
default: () => {
if (!Array.isArray(config.config.defaultDayNames)) {
return void 0;
}
return config.config.defaultDayNames;
}
},
monthNames: {
type: [Array, null],
default: () => {
if (!Array.isArray(config.config.defaultMonthNames)) {
return void 0;
}
return config.config.defaultMonthNames;
}
},
firstDayOfWeek: {
type: Number,
default: () => {
if (typeof config.config.defaultFirstDayOfWeek === "number") {
return config.config.defaultFirstDayOfWeek;
} else {
return 0;
}
}
},
inline: Boolean,
minDate: [Date, null],
maxDate: [Date, null],
focusedDate: Date,
placeholder: String,
editable: Boolean,
disabled: Boolean,
horizontalTimePicker: Boolean,
unselectableDates: [Array, Function],
unselectableDaysOfWeek: {
type: [Array, null],
default: () => config.config.defaultUnselectableDaysOfWeek
},
selectableDates: [Array, Function],
dateFormatter: {
type: Function,
default: (date, vm) => {
if (typeof config.config.defaultDateFormatter === "function") {
return config.config.defaultDateFormatter(date);
} else {
return defaultDateFormatter(date, vm);
}
}
},
dateParser: {
type: Function,
default: (date, vm) => {
if (typeof config.config.defaultDateParser === "function") {
return config.config.defaultDateParser(date);
} else {
return defaultDateParser(date, vm);
}
}
},
dateCreator: {
type: Function,
default: () => {
if (typeof config.config.defaultDateCreator === "function") {
return config.config.defaultDateCreator();
} else {
return /* @__PURE__ */ new Date();
}
}
},
mobileNative: {
type: Boolean,
default: () => config.config.defaultDatepickerMobileNative
},
position: String,
iconRight: String,
iconRightClickable: Boolean,
events: Array,
indicators: {
type: String,
default: "dots"
},
openOnFocus: Boolean,
iconPrev: {
type: String,
default: () => config.config.defaultIconPrev
},
iconNext: {
type: String,
default: () => config.config.defaultIconNext
},
yearsRange: {
type: Array,
default: () => config.config.defaultDatepickerYearsRange
},
type: {
type: String,
validator: (value) => {
return [
"month"
].indexOf(value) >= 0;
}
},
nearbyMonthDays: {
type: Boolean,
default: () => config.config.defaultDatepickerNearbyMonthDays
},
nearbySelectableMonthDays: {
type: Boolean,
default: () => config.config.defaultDatepickerNearbySelectableMonthDays
},
showWeekNumber: {
type: Boolean,
default: () => config.config.defaultDatepickerShowWeekNumber
},
weekNumberClickable: {
type: Boolean,
default: () => config.config.defaultDatepickerWeekNumberClickable
},
rulesForFirstWeek: {
type: Number,
default: () => 4
},
range: {
type: Boolean,
default: false
},
closeOnClick: {
type: Boolean,
default: true
},
multiple: {
type: Boolean,
default: false
},
mobileModal: {
type: Boolean,
default: () => config.config.defaultDatepickerMobileModal
},
focusable: {
type: Boolean,
default: true
},
trapFocus: {
type: Boolean,
default: () => config.config.defaultTrapFocus
},
appendToBody: Boolean,
ariaNextLabel: String,
ariaPreviousLabel: String
},
emits: {
/* eslint-disable @typescript-eslint/no-unused-vars */
"active-change": (_active) => true,
"change-month": (_month) => true,
"change-year": (_year) => true,
"icon-right-click": (_event) => true,
"range-end": (_date) => true,
"range-start": (_date) => true,
"update:modelValue": (_value) => true,
"week-number-click": (_we