@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
395 lines (394 loc) • 15.3 kB
JavaScript
import { DtIconChevronLeft as D, DtIconChevronsLeft as _, DtIconChevronRight as y, DtIconChevronsRight as m } from "@dialpad/dialtone-icons/vue2";
import { getMonth as o, getYear as l, getDate as k, set as $, addMonths as v, subMonths as R } from "date-fns";
import { getCalendarDays as E, formatMonth as b, getWeekDayNames as T, formatDate as g, calculateNextFocusDate as A, calculatePrevFocusDate as M } from "./utils.js";
import { INTL_MONTH_FORMAT as d, WEEK_START as C } from "./datepicker-constants.js";
import { n as h } from "../../_plugin-vue2_normalizer-DSLOjnn3.js";
import u from "../button/button.js";
import P from "../tooltip/tooltip.js";
import f from "../stack/stack.js";
import p from "../../common/mixins/localization.js";
import { warnIfUnmounted as x } from "../../common/utils/index.js";
const I = {
name: "DtDatepickerMonthYearPicker",
components: {
DtButton: u,
DtTooltip: P,
DtStack: f,
DtIconChevronLeft: D,
DtIconChevronsLeft: _,
DtIconChevronRight: y,
DtIconChevronsRight: m
},
mixins: [p],
props: {
selectedDate: {
type: Date,
required: !0
}
},
emits: [
/**
* Will retrieve the calendar days of the given date
*
* @event calendar-days
* @type {Array}
*/
"calendar-days",
/**
* Will focus first day in calendar
*
* @event focus-first-day
*/
"focus-first-day",
/**
* Will focus last day in calendar
*
* @event focus-last-day
*/
"focus-last-day",
/**
* Will close the datepicker
*
* @event close-datepicker
*/
"close-datepicker"
],
data() {
return {
selectMonth: o(this.selectedDate),
selectYear: l(this.selectedDate),
highlightedDay: null,
focusPicker: 0,
focusRefs: [],
refNames: ["prevYearButtonRef", "prevMonthButtonRef", "nextMonthButtonRef", "nextYearButtonRef"]
};
},
computed: {
// Get days for the currently selected month and year and highlight the selected day
calendarDays() {
return E(this.selectMonth, this.selectYear, this.highlightedDay);
},
formattedMonth() {
return (s) => b(s, d, this.i18n.currentLocale);
},
previousYearAriaLabel() {
return `${this.i18n.$t("DIALTONE_DATEPICKER_CHANGE_TO")} ${this.i18n.$t("DIALTONE_DATEPICKER_PREVIOUS_YEAR")} ${this.selectYear - 1}`;
},
previousMonthAriaLabel() {
return `${this.i18n.$t("DIALTONE_DATEPICKER_CHANGE_TO")} ${this.i18n.$t("DIALTONE_DATEPICKER_PREVIOUS_MONTH")} ${this.formattedMonth(this.selectMonth - 1)}`;
},
nextYearAriaLabel() {
return `${this.i18n.$t("DIALTONE_DATEPICKER_CHANGE_TO")} ${this.i18n.$t("DIALTONE_DATEPICKER_NEXT_YEAR")} ${this.selectYear + 1}`;
},
nextMonthAriaLabel() {
return `${this.i18n.$t("DIALTONE_DATEPICKER_CHANGE_TO")} ${this.i18n.$t("DIALTONE_DATEPICKER_NEXT_MONTH")} ${this.formattedMonth(this.selectMonth + 1)}`;
}
},
watch: {
selectMonth: {
handler() {
this.highlightDay(), this.$emit("calendar-days", this.calendarDays);
},
immediate: !0
},
selectYear: {
handler() {
this.highlightDay(), this.$emit("calendar-days", this.calendarDays);
},
immediate: !0
}
},
mounted() {
this.setButtonsRef(), this.focusMonthYearPicker();
},
methods: {
setButtonsRef() {
this.focusRefs = this.refNames.map((s) => this.$refs[s]);
},
focusMonthYearPicker() {
this.focusPicker = 0, this.focusRefs[0].$el.focus();
},
handleKeyDown(s) {
switch (s.key) {
case "ArrowLeft":
s.preventDefault(), this.focusPicker === 0 ? (this.focusPicker = 3, this.focusRefs[this.focusPicker].$el.focus()) : (this.focusPicker--, this.focusRefs[this.focusPicker].$el.focus());
break;
case "ArrowRight":
s.preventDefault(), this.focusPicker === 3 ? (this.focusPicker = 0, this.focusRefs[this.focusPicker].$el.focus()) : (this.focusPicker++, this.focusRefs[this.focusPicker].$el.focus());
break;
case "ArrowDown":
s.preventDefault(), this.$emit("focus-first-day");
break;
case "Tab":
s.preventDefault(), this.$emit("focus-first-day");
break;
case "Escape":
this.$emit("close-datepicker");
break;
}
},
highlightDay() {
const s = l(this.selectedDate), t = o(this.selectedDate);
s !== this.selectYear || t !== this.selectMonth ? this.highlightedDay = null : this.highlightedDay = k(this.selectedDate);
},
changeMonth(s) {
(this.selectMonth === 0 && s === -1 || this.selectMonth === 11 && s === 1) && (this.selectYear += s);
const t = $(this.selectedDate, { month: this.selectMonth, year: this.selectYear }), e = s === 1 ? v(t, 1) : R(t, 1);
this.selectMonth = o(e);
},
changeYear(s) {
this.selectYear = this.selectYear + s;
},
goToNextMonth() {
this.changeMonth(1);
},
goToPrevMonth() {
this.changeMonth(-1);
}
}
};
var N = function() {
var t = this, e = t._self._c;
return e("dt-stack", { staticClass: "d-datepicker__month-year", attrs: { direction: "row", gap: "300" } }, [e("dt-stack", { staticClass: "d-datepicker__nav", attrs: { as: "nav", direction: "row", gap: "200" } }, [e("dt-tooltip", { attrs: { "fallback-placements": ["top-start", "auto"], message: t.i18n.$t("DIALTONE_DATEPICKER_PREVIOUS_YEAR"), placement: "top" }, scopedSlots: t._u([{ key: "anchor", fn: function() {
return [e("dt-button", { ref: t.refNames[0], staticClass: "d-datepicker__nav-btn", attrs: { id: "prevYearButton", "aria-label": t.previousYearAriaLabel, circle: "", importance: "clear", kind: "muted", size: "xs", type: "button" }, on: { click: function(a) {
return t.changeYear(-1);
}, keydown: function(a) {
return t.handleKeyDown(a);
} } }, [e("dt-icon-chevrons-left", { attrs: { size: "200" } })], 1)];
}, proxy: !0 }]) }), e("dt-tooltip", { attrs: { "fallback-placements": ["top-start", "auto"], message: t.i18n.$t("DIALTONE_DATEPICKER_PREVIOUS_MONTH"), placement: "top" }, scopedSlots: t._u([{ key: "anchor", fn: function() {
return [e("dt-button", { ref: t.refNames[1], staticClass: "d-datepicker__nav-btn", attrs: { id: "prevMonthButton", "aria-label": t.previousMonthAriaLabel, circle: "", importance: "clear", kind: "muted", size: "xs", type: "button" }, on: { click: function(a) {
return t.changeMonth(-1);
}, keydown: function(a) {
return t.handleKeyDown(a);
} } }, [e("dt-icon-chevron-left", { attrs: { size: "200" } })], 1)];
}, proxy: !0 }]) })], 1), e("div", { staticClass: "d-datepicker__month-year-title", attrs: { id: "calendar-heading" } }, [t._v(" " + t._s(t.formattedMonth(t.selectMonth)) + " " + t._s(t.selectYear) + " ")]), e("dt-stack", { staticClass: "d-datepicker__nav", attrs: { as: "nav", direction: "row", gap: "200" } }, [e("dt-tooltip", { attrs: { "fallback-placements": ["top-end", "auto"], message: t.i18n.$t("DIALTONE_DATEPICKER_NEXT_MONTH"), placement: "top" }, scopedSlots: t._u([{ key: "anchor", fn: function() {
return [e("dt-button", { ref: t.refNames[2], staticClass: "d-datepicker__nav-btn", attrs: { id: "nextMonthButton", "aria-label": t.nextMonthAriaLabel, circle: "", importance: "clear", kind: "muted", size: "xs", type: "button" }, on: { click: function(a) {
return t.changeMonth(1);
}, keydown: function(a) {
return t.handleKeyDown(a);
} } }, [e("dt-icon-chevron-right", { attrs: { size: "200" } })], 1)];
}, proxy: !0 }]) }), e("dt-tooltip", { attrs: { "fallback-placements": ["top-end", "auto"], message: t.i18n.$t("DIALTONE_DATEPICKER_NEXT_YEAR"), placement: "top" }, scopedSlots: t._u([{ key: "anchor", fn: function() {
return [e("dt-button", { ref: t.refNames[3], staticClass: "d-datepicker__nav-btn", attrs: { id: "nextYearButton", "aria-label": t.nextYearAriaLabel, circle: "", importance: "clear", kind: "muted", size: "xs", type: "button" }, on: { click: function(a) {
return t.changeYear(1);
}, keydown: function(a) {
return t.handleKeyDown(a);
} } }, [e("dt-icon-chevrons-right", { attrs: { size: "200" } })], 1)];
}, proxy: !0 }]) })], 1)], 1);
}, Y = [], L = /* @__PURE__ */ h(
I,
N,
Y
);
const w = L.exports, O = {
name: "DtDatepickerCalendar",
components: { DtButton: u },
mixins: [p],
props: {
calendarDays: {
type: Array,
required: !0
}
},
emits: [
/**
* Event fired when a date is selected
*
* @event select-date
* @type {Date}
*/
"select-date",
/**
* Will focus the month and year picker
*
* @event focus-month-year-picker
*/
"focus-month-year-picker",
/**
* Will close the datepicker
*
* @event close-datepicker
*/
"close-datepicker"
],
data() {
return {
// local selectedDay to override the received by props calendarDays
selectedDay: null,
focusDay: 0,
daysRef: []
};
},
computed: {
weekDays() {
return T(this.i18n.currentLocale, C);
}
},
watch: {
calendarDays() {
this.focusDay = 0, this.selectedDay = null, this.daysRef = [], this.$nextTick(() => {
this.daysRef = [], this.setDayRef();
});
}
},
methods: {
dayAriaLabel(s) {
return this.i18n.$t("DIALTONE_DATEPICKER_SELECT_DAY") + ` ${g(s.value, d, this.i18n.currentLocale)}`;
},
setDayRef(s, t) {
this.calendarDays.forEach((e, a) => {
e.days.forEach((n, r) => {
const i = `buttonRef_${a}_${r}`, c = this.$refs[i];
c && n.currentMonth && this.daysRef.push({ el: c[0], day: n });
});
});
},
handleKeyDown(s) {
switch (s.key) {
case "ArrowUp":
s.preventDefault(), this.focusDay -= 7;
try {
this.daysRef[this.focusDay].el.$el.focus();
} catch {
const e = M(this.daysRef[this.focusDay + 7].day.value);
this.$emit("go-to-prev-month"), this.$nextTick(() => {
this.setDayRef(), this.daysRef[e - 1].el.$el.focus(), this.focusDay += e - 1;
});
}
break;
case "ArrowDown":
s.preventDefault(), this.focusDay += 7;
try {
this.daysRef[this.focusDay].el.$el.focus();
} catch {
const e = A(this.daysRef[this.focusDay - 7].day.value);
this.$emit("go-to-next-month"), this.$nextTick(() => {
this.setDayRef(), this.daysRef[e - 1].el.$el.focus(), this.focusDay += e - 1;
});
}
break;
case "ArrowLeft":
s.preventDefault(), this.focusDay > 0 ? (this.focusDay -= 1, this.daysRef[this.focusDay].el.$el.focus()) : (this.$emit("go-to-prev-month"), this.$nextTick(() => {
this.focusLastDay();
}));
break;
case "ArrowRight":
s.preventDefault(), this.focusDay < this.daysRef.length - 1 ? (this.focusDay += 1, this.daysRef[this.focusDay].el.$el.focus()) : (this.$emit("go-to-next-month"), this.$nextTick(() => {
this.focusFirstDay();
}));
break;
case "Tab":
s.preventDefault(), this.$emit("focus-month-year-picker");
break;
case "Escape":
this.$emit("close-datepicker");
break;
}
},
focusFirstDay() {
this.focusDay = 0, this.$nextTick(() => {
this.daysRef[this.focusDay].el.$el.focus();
});
},
focusLastDay() {
this.$nextTick(() => {
this.focusDay = this.daysRef.length - 1, this.daysRef[this.focusDay].el.$el.focus();
});
},
selectDay(s) {
s.currentMonth && (this.selectedDay = s.text, this.$emit("select-date", s.value));
}
}
};
var K = function() {
var t = this, e = t._self._c;
return e("table", { staticClass: "d-datepicker__calendar", attrs: { "aria-labelledby": "calendar-heading" } }, [e("thead", [e("tr", t._l(t.weekDays, function(a) {
return e("th", { key: a, staticClass: "d-datepicker__cell d-datepicker__cell--header", attrs: { scope: "col" } }, [e("span", { staticClass: "d-datepicker__weekday", attrs: { title: a, "aria-label": a } }, [t._v(" " + t._s(a))])]);
}), 0)]), e("tbody", t._l(t.calendarDays, function(a, n) {
return e("tr", { key: n }, t._l(a.days, function(r, i) {
return e("td", { key: n + i, staticClass: "d-datepicker__cell", attrs: { role: "listbox" } }, [e("dt-button", { ref: `buttonRef_${n}_${i}`, refInFor: !0, staticClass: "d-datepicker__day", class: {
"d-datepicker__day--disabled": !r.currentMonth,
"d-datepicker__day--selected": t.selectedDay ? r.text === t.selectedDay && r.currentMonth : r.selected
}, attrs: { circle: !0, size: "sm", importance: "clear", disabled: !r.currentMonth, type: "button", "aria-selected": t.selectedDay ? r.text === t.selectedDay && r.currentMonth : r.selected, "aria-label": t.dayAriaLabel(r), role: "option" }, on: { click: function(c) {
return t.selectDay(r);
}, keydown: function(c) {
return t.handleKeyDown(c);
} } }, [t._v(" " + t._s(r.text) + " ")])], 1);
}), 0);
}), 0)]);
}, B = [], F = /* @__PURE__ */ h(
O,
K,
B
);
const z = F.exports, S = {
name: "DtDatepicker",
components: { DtStack: f, MonthYearPicker: w, Calendar: z },
props: {
/**
* Selected date
*
* @type {Date}
*/
selectedDate: {
type: Date,
default: () => /* @__PURE__ */ new Date()
}
},
emits: [
/**
* Event fired when a date is selected
*
* @event selected-date
* @type {Date}
*/
"selected-date",
/**
* Event fired when user presses the esc key
*
* @event close-datepicker
*/
"close-datepicker"
],
data() {
return {
calendarDays: []
};
},
mounted() {
x(this.$el, this.$options.name);
},
methods: {
updateCalendarDays(s) {
this.calendarDays = s;
}
}
};
var H = function() {
var t = this, e = t._self._c;
return e("dt-stack", { staticClass: "d-datepicker", attrs: { gap: "400" } }, [e("div", { staticClass: "d-datepicker__hd" }, [e("month-year-picker", { ref: "monthYearPicker", attrs: { "selected-date": t.selectedDate }, on: { "calendar-days": t.updateCalendarDays, "focus-first-day": function(a) {
return t.$refs.calendar.focusFirstDay();
}, "focus-last-day": function(a) {
return t.$refs.calendar.focusLastDay();
}, "close-datepicker": function(a) {
return t.$emit("close-datepicker");
} } })], 1), e("div", { staticClass: "d-datepicker__bd" }, [e("calendar", { ref: "calendar", attrs: { "calendar-days": t.calendarDays }, on: { "select-date": function(a) {
return t.$emit("selected-date", a);
}, "focus-month-year-picker": function(a) {
return t.$refs.monthYearPicker.focusMonthYearPicker();
}, "close-datepicker": function(a) {
return t.$emit("close-datepicker");
}, "go-to-next-month": function(a) {
return t.$refs.monthYearPicker.goToNextMonth();
}, "go-to-prev-month": function(a) {
return t.$refs.monthYearPicker.goToPrevMonth();
} } })], 1)]);
}, U = [], G = /* @__PURE__ */ h(
S,
H,
U
);
const st = G.exports;
export {
st as default
};
//# sourceMappingURL=datepicker.js.map