UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

197 lines (196 loc) 6.53 kB
import { getWeekDayNames, calculateNextFocusDate, calculatePrevFocusDate } from "../utils.js"; import { MONTH_FORMAT, WEEK_START } from "../datepicker_constants.js"; import { format, getYear } from "date-fns"; import DtButton from "../../button/button.vue.js"; import normalizeComponent from "../../../_virtual/_plugin-vue2_normalizer.js"; const _sfc_main = { name: "DtDatepickerCalendar", components: { DtButton }, props: { calendarDays: { type: Array, required: true }, locale: { type: String, required: true }, selectDayLabel: { type: String, required: true } }, 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 getWeekDayNames(this.locale, WEEK_START); } }, watch: { calendarDays() { this.focusDay = 0; this.selectedDay = null; this.daysRef = []; this.$nextTick(() => { this.daysRef = []; this.setDayRef(); }); } }, methods: { dayAriaLabel(day) { return `${this.selectDayLabel} ${day.text} ${format(day.value, MONTH_FORMAT)} ${getYear(day.value)}`; }, setDayRef(el, day) { this.calendarDays.forEach((week, weekIndex) => { week.days.forEach((day2, dayIndex) => { const refKey = `buttonRef_${weekIndex}_${dayIndex}`; const dayButton = this.$refs[refKey]; if (dayButton && day2.currentMonth) { this.daysRef.push({ el: dayButton[0], day: day2 }); } }); }); }, handleKeyDown(event) { switch (event.key) { case "ArrowUp": event.preventDefault(); this.focusDay -= 7; try { this.daysRef[this.focusDay].el.$el.focus(); } catch (error) { const prevFocusDate = calculatePrevFocusDate(this.daysRef[this.focusDay + 7].day.value); this.$emit("go-to-prev-month"); this.$nextTick(() => { this.setDayRef(); this.daysRef[prevFocusDate - 1].el.$el.focus(); this.focusDay += prevFocusDate - 1; }); } break; case "ArrowDown": event.preventDefault(); this.focusDay += 7; try { this.daysRef[this.focusDay].el.$el.focus(); } catch (error) { const nextFocusDate = calculateNextFocusDate(this.daysRef[this.focusDay - 7].day.value); this.$emit("go-to-next-month"); this.$nextTick(() => { this.setDayRef(); this.daysRef[nextFocusDate - 1].el.$el.focus(); this.focusDay += nextFocusDate - 1; }); } break; case "ArrowLeft": event.preventDefault(); if (this.focusDay > 0) { this.focusDay -= 1; this.daysRef[this.focusDay].el.$el.focus(); } else { this.$emit("go-to-prev-month"); this.$nextTick(() => { this.focusLastDay(); }); } break; case "ArrowRight": event.preventDefault(); if (this.focusDay < this.daysRef.length - 1) { this.focusDay += 1; this.daysRef[this.focusDay].el.$el.focus(); } else { this.$emit("go-to-next-month"); this.$nextTick(() => { this.focusFirstDay(); }); } break; case "Tab": event.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(day) { if (!day.currentMonth) { return; } this.selectedDay = day.text; this.$emit("select-date", day.value); } } }; var _sfc_render = function render() { var _vm = this, _c = _vm._self._c; return _c("table", { staticClass: "d-datepicker__calendar", attrs: { "aria-labelledby": "calendar-heading" } }, [_c("thead", [_c("tr", _vm._l(_vm.weekDays, function(day) { return _c("th", { key: day, staticClass: "d-datepicker__cell d-datepicker__cell--header", attrs: { "scope": "col" } }, [_c("span", { staticClass: "d-datepicker__weekday", attrs: { "title": day, "aria-label": day } }, [_vm._v(" " + _vm._s(day))])]); }), 0)]), _c("tbody", _vm._l(_vm.calendarDays, function(week, indexWeek) { return _c("tr", { key: indexWeek }, _vm._l(week.days, function(day, indexDays) { return _c("td", { key: indexWeek + indexDays, staticClass: "d-datepicker__cell", attrs: { "role": "listbox" } }, [_c("dt-button", { ref: `buttonRef_${indexWeek}_${indexDays}`, refInFor: true, staticClass: "d-datepicker__day", class: { "d-datepicker__day--disabled": !day.currentMonth, "d-datepicker__day--selected": _vm.selectedDay ? day.text === _vm.selectedDay && day.currentMonth : day.selected }, attrs: { "circle": true, "size": "sm", "importance": "clear", "disabled": !day.currentMonth, "type": "button", "aria-selected": !!_vm.selectedDay ? day.text === _vm.selectedDay && day.currentMonth : day.selected, "aria-label": _vm.dayAriaLabel(day), "role": "option" }, on: { "click": function($event) { return _vm.selectDay(day); }, "keydown": function($event) { return _vm.handleKeyDown($event); } } }, [_vm._v(" " + _vm._s(day.text) + " ")])], 1); }), 0); }), 0)]); }; var _sfc_staticRenderFns = []; var __component__ = /* @__PURE__ */ normalizeComponent( _sfc_main, _sfc_render, _sfc_staticRenderFns ); const Calendar = __component__.exports; export { Calendar as default }; //# sourceMappingURL=calendar.vue.js.map