UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

395 lines (394 loc) 15.3 kB
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