UNPKG

@dialpad/dialtone-vue

Version:

Vue component library for Dialpad's design system Dialtone

395 lines (394 loc) 15.4 kB
import { DtIconChevronsRight as D, DtIconChevronRight as _, DtIconChevronsLeft as y, DtIconChevronLeft as m } from "@dialpad/dialtone-icons/vue2"; import { set as k, addMonths as $, subMonths as v, getMonth as c, getYear as l, getDate as R } from "date-fns"; import { formatMonth as E, getCalendarDays as b, calculateNextFocusDate as T, calculatePrevFocusDate as g, formatDate as A, getWeekDayNames as M } from "./utils.js"; import { INTL_MONTH_FORMAT as u, WEEK_START as C } from "./datepicker-constants.js"; import { DialtoneLocalization as d } from "../../localization/index.js"; import { n as i } from "../../_plugin-vue2_normalizer-DSLOjnn3.js"; import f from "../stack/stack.js"; import P from "../tooltip/tooltip.js"; import p from "../button/button.js"; import { warnIfUnmounted as I } from "../../common/utils/index.js"; const N = { name: "DtDatepickerMonthYearPicker", components: { DtButton: p, DtTooltip: P, DtStack: f, DtIconChevronLeft: m, DtIconChevronsLeft: y, DtIconChevronRight: _, DtIconChevronsRight: D }, 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: c(this.selectedDate), selectYear: l(this.selectedDate), highlightedDay: null, focusPicker: 0, focusRefs: [], refNames: ["prevYearButtonRef", "prevMonthButtonRef", "nextMonthButtonRef", "nextYearButtonRef"], i18n: new d() }; }, computed: { // Get days for the currently selected month and year and highlight the selected day calendarDays() { return b(this.selectMonth, this.selectYear, this.highlightedDay); }, formattedMonth() { return (e) => E(e, u, 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((e) => this.$refs[e]); }, focusMonthYearPicker() { this.focusPicker = 0, this.focusRefs[0].$el.focus(); }, handleKeyDown(e) { switch (e.key) { case "ArrowLeft": e.preventDefault(), this.focusPicker === 0 ? (this.focusPicker = 3, this.focusRefs[this.focusPicker].$el.focus()) : (this.focusPicker--, this.focusRefs[this.focusPicker].$el.focus()); break; case "ArrowRight": e.preventDefault(), this.focusPicker === 3 ? (this.focusPicker = 0, this.focusRefs[this.focusPicker].$el.focus()) : (this.focusPicker++, this.focusRefs[this.focusPicker].$el.focus()); break; case "ArrowDown": e.preventDefault(), this.$emit("focus-first-day"); break; case "Tab": e.preventDefault(), this.$emit("focus-first-day"); break; case "Escape": this.$emit("close-datepicker"); break; } }, highlightDay() { const e = l(this.selectedDate), t = c(this.selectedDate); e !== this.selectYear || t !== this.selectMonth ? this.highlightedDay = null : this.highlightedDay = R(this.selectedDate); }, changeMonth(e) { (this.selectMonth === 0 && e === -1 || this.selectMonth === 11 && e === 1) && (this.selectYear += e); const t = k(this.selectedDate, { month: this.selectMonth, year: this.selectYear }), s = e === 1 ? $(t, 1) : v(t, 1); this.selectMonth = c(s); }, changeYear(e) { this.selectYear = this.selectYear + e; }, goToNextMonth() { this.changeMonth(1); }, goToPrevMonth() { this.changeMonth(-1); } } }; var Y = function() { var t = this, s = t._self._c; return s("dt-stack", { staticClass: "d-datepicker__month-year", attrs: { direction: "row", gap: "300" } }, [s("dt-stack", { staticClass: "d-datepicker__nav", attrs: { as: "nav", direction: "row", gap: "200" } }, [s("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 [s("dt-button", { ref: t.refNames[0], staticClass: "d-datepicker__nav-btn", attrs: { id: "prevYearButton", "aria-label": t.previousYearAriaLabel, circle: !0, importance: "clear", kind: "muted", size: "xs", type: "button" }, on: { click: function(a) { return t.changeYear(-1); }, keydown: function(a) { return t.handleKeyDown(a); } } }, [s("dt-icon-chevrons-left", { attrs: { size: "200" } })], 1)]; }, proxy: !0 }]) }), s("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 [s("dt-button", { ref: t.refNames[1], staticClass: "d-datepicker__nav-btn", attrs: { id: "prevMonthButton", "aria-label": t.previousMonthAriaLabel, circle: !0, importance: "clear", kind: "muted", size: "xs", type: "button" }, on: { click: function(a) { return t.changeMonth(-1); }, keydown: function(a) { return t.handleKeyDown(a); } } }, [s("dt-icon-chevron-left", { attrs: { size: "200" } })], 1)]; }, proxy: !0 }]) })], 1), s("div", { staticClass: "d-datepicker__month-year-title", attrs: { id: "calendar-heading" } }, [t._v(" " + t._s(t.formattedMonth(t.selectMonth)) + " " + t._s(t.selectYear) + " ")]), s("dt-stack", { staticClass: "d-datepicker__nav", attrs: { as: "nav", direction: "row", gap: "200" } }, [s("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 [s("dt-button", { ref: t.refNames[2], staticClass: "d-datepicker__nav-btn", attrs: { id: "nextMonthButton", "aria-label": t.nextMonthAriaLabel, circle: !0, importance: "clear", kind: "muted", size: "xs", type: "button" }, on: { click: function(a) { return t.changeMonth(1); }, keydown: function(a) { return t.handleKeyDown(a); } } }, [s("dt-icon-chevron-right", { attrs: { size: "200" } })], 1)]; }, proxy: !0 }]) }), s("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 [s("dt-button", { ref: t.refNames[3], staticClass: "d-datepicker__nav-btn", attrs: { id: "nextYearButton", "aria-label": t.nextYearAriaLabel, circle: !0, importance: "clear", kind: "muted", size: "xs", type: "button" }, on: { click: function(a) { return t.changeYear(1); }, keydown: function(a) { return t.handleKeyDown(a); } } }, [s("dt-icon-chevrons-right", { attrs: { size: "200" } })], 1)]; }, proxy: !0 }]) })], 1)], 1); }, w = [], x = /* @__PURE__ */ i( N, Y, w ); const L = x.exports, O = { name: "DtDatepickerCalendar", components: { DtButton: 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: [], i18n: new d() }; }, computed: { weekDays() { return M(this.i18n.currentLocale, C); } }, watch: { calendarDays() { this.focusDay = 0, this.selectedDay = null, this.daysRef = [], this.$nextTick(() => { this.daysRef = [], this.setDayRef(); }); } }, methods: { dayAriaLabel(e) { return this.i18n.$t("DIALTONE_DATEPICKER_SELECT_DAY") + ` ${A(e.value, u, this.i18n.currentLocale)}`; }, setDayRef() { this.calendarDays.forEach((e, t) => { e.days.forEach((s, a) => { const n = `buttonRef_${t}_${a}`, r = this.$refs[n]; r && s.currentMonth && this.daysRef.push({ el: r[0], day: s }); }); }); }, handleKeyDown(e) { switch (e.key) { case "ArrowUp": e.preventDefault(), this.focusDay -= 7; try { this.daysRef[this.focusDay].el.$el.focus(); } catch { const t = g(this.daysRef[this.focusDay + 7].day.value); this.$emit("go-to-prev-month"), this.$nextTick(() => { this.setDayRef(), this.daysRef[t - 1].el.$el.focus(), this.focusDay += t - 1; }); } break; case "ArrowDown": e.preventDefault(), this.focusDay += 7; try { this.daysRef[this.focusDay].el.$el.focus(); } catch { const t = T(this.daysRef[this.focusDay - 7].day.value); this.$emit("go-to-next-month"), this.$nextTick(() => { this.setDayRef(), this.daysRef[t - 1].el.$el.focus(), this.focusDay += t - 1; }); } break; case "ArrowLeft": e.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": e.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": e.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(e) { e.currentMonth && (this.selectedDay = e.text, this.$emit("select-date", e.value)); } } }; var K = function() { var t = this, s = t._self._c; return s("table", { staticClass: "d-datepicker__calendar", attrs: { "aria-labelledby": "calendar-heading" } }, [s("thead", [s("tr", t._l(t.weekDays, function(a) { return s("th", { key: a, staticClass: "d-datepicker__cell d-datepicker__cell--header", attrs: { scope: "col" } }, [s("span", { staticClass: "d-datepicker__weekday", attrs: { title: a, "aria-label": a } }, [t._v(" " + t._s(a))])]); }), 0)]), s("tbody", t._l(t.calendarDays, function(a, n) { return s("tr", { key: n }, t._l(a.days, function(r, o) { return s("td", { key: n + o, staticClass: "d-datepicker__cell", attrs: { role: "listbox" } }, [s("dt-button", { ref: `buttonRef_${n}_${o}`, 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(h) { return t.selectDay(r); }, keydown: function(h) { return t.handleKeyDown(h); } } }, [t._v(" " + t._s(r.text) + " ")])], 1); }), 0); }), 0)]); }, B = [], F = /* @__PURE__ */ i( O, K, B ); const z = F.exports, S = { name: "DtDatepicker", components: { DtStack: f, MonthYearPicker: L, 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() { I(this.$el, this.$options.name); }, methods: { updateCalendarDays(e) { this.calendarDays = e; } } }; var H = function() { var t = this, s = t._self._c; return s("dt-stack", { staticClass: "d-datepicker", attrs: { gap: "400" } }, [s("div", { staticClass: "d-datepicker__hd" }, [s("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), s("div", { staticClass: "d-datepicker__bd" }, [s("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__ */ i( S, H, U ); const st = G.exports; export { st as default }; //# sourceMappingURL=datepicker.js.map