@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
554 lines (553 loc) • 16.8 kB
JavaScript
import { ref as E, computed as B, watch as F, onMounted as V, createBlock as G, openBlock as $, unref as e, withCtx as m, createVNode as i, createElementVNode as M, toDisplayString as P, nextTick as N, createElementBlock as g, Fragment as x, renderList as Y, normalizeClass as q, createTextVNode as W, getCurrentInstance as j } from "vue";
import { DtIconChevronsLeft as J, DtIconChevronLeft as Q, DtIconChevronRight as Z, DtIconChevronsRight as ee } from "@dialpad/dialtone-icons/vue3";
import { getMonth as K, getYear as S, getDate as te, set as ae, addMonths as ne, subMonths as re } from "date-fns";
import { getCalendarDays as le, formatMonth as oe, getWeekDayNames as se, calculateNextFocusDate as ce, calculatePrevFocusDate as ue, formatDate as ie } from "./utils.js";
import { INTL_MONTH_FORMAT as U, WEEK_START as de } from "./datepicker-constants.js";
import { returnFirstEl as p, warnIfUnmounted as fe } from "../../common/utils/index.js";
import { DialtoneLocalization as z } from "../../localization/index.js";
import R from "../stack/stack.js";
import w from "../tooltip/tooltip.js";
import I from "../button/button.js";
function ve(d, s) {
const c = E(K(d.selectedDate)), t = E(S(d.selectedDate)), n = E(null), r = E(0), D = E([]), v = new z(), b = B(() => le(c.value, t.value, n.value));
F(c, () => {
l(), s("calendar-days", b.value);
}, { immediate: !0 }), F(t, () => {
l(), s("calendar-days", b.value);
}, { immediate: !0 });
function k(a) {
return oe(a, U, v.currentLocale);
}
function h(a) {
D.value.includes(a) || D.value.push(a);
}
function _() {
p(D.value[0].$el).focus();
}
function A(a) {
switch (a.key) {
case "ArrowLeft":
a.preventDefault(), r.value === 0 ? (r.value = 3, p(D.value[r.value].$el).focus()) : (r.value--, p(D.value[r.value].$el).focus());
break;
case "ArrowRight":
a.preventDefault(), r.value === 3 ? (r.value = 0, p(D.value[r.value].$el).focus()) : (r.value++, p(D.value[r.value].$el).focus());
break;
case "ArrowDown":
a.preventDefault(), s("focus-first-day");
break;
case "Tab":
a.preventDefault(), s("focus-first-day");
break;
case "Escape":
s("close-datepicker");
break;
}
}
function l() {
const a = S(d.selectedDate), L = K(d.selectedDate);
a !== t.value || L !== c.value ? n.value = null : n.value = te(d.selectedDate);
}
function o(a) {
(c.value === 0 && a === -1 || c.value === 11 && a === 1) && (t.value += a);
const L = ae(d.selectedDate, { month: c.value, year: t.value }), X = a === 1 ? ne(L, 1) : re(L, 1);
c.value = K(X);
}
function T(a) {
t.value = t.value + a;
}
function f() {
o(1);
}
function C() {
o(-1);
}
function y() {
return `${v.$t("DIALTONE_DATEPICKER_CHANGE_TO")} ${v.$t("DIALTONE_DATEPICKER_PREVIOUS_YEAR")} ${t.value - 1}`;
}
function O() {
return `${v.$t("DIALTONE_DATEPICKER_CHANGE_TO")} ${v.$t("DIALTONE_DATEPICKER_PREVIOUS_MONTH")} ${k(c.value - 1)}`;
}
function H() {
return `${v.$t("DIALTONE_DATEPICKER_CHANGE_TO")} ${v.$t("DIALTONE_DATEPICKER_NEXT_YEAR")} ${t.value + 1}`;
}
function u() {
return `${v.$t("DIALTONE_DATEPICKER_CHANGE_TO")} ${v.$t("DIALTONE_DATEPICKER_NEXT_MONTH")} ${k(c.value + 1)}`;
}
return {
selectMonth: c,
selectYear: t,
formattedMonth: k,
setDayRef: h,
focusMonthYearPicker: _,
handleKeyDown: A,
changeMonth: o,
changeYear: T,
goToNextMonth: f,
goToPrevMonth: C,
previousYearAriaLabel: y,
previousMonthAriaLabel: O,
nextYearAriaLabel: H,
nextMonthAriaLabel: u
};
}
const pe = {
id: "calendar-heading",
class: "d-datepicker__month-year-title"
}, De = {
__name: "month-year-picker",
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"
],
setup(d, { expose: s, emit: c }) {
const t = d, n = c, r = new z(), {
selectMonth: D,
selectYear: v,
formattedMonth: b,
setDayRef: k,
focusMonthYearPicker: h,
handleKeyDown: _,
changeMonth: A,
changeYear: l,
goToNextMonth: o,
goToPrevMonth: T,
previousYearAriaLabel: f,
previousMonthAriaLabel: C,
nextMonthAriaLabel: y,
nextYearAriaLabel: O
} = ve(t, n);
return V(() => {
h();
}), s({
focusMonthYearPicker: h,
goToNextMonth: o,
goToPrevMonth: T
}), (H, u) => ($(), G(e(R), {
class: "d-datepicker__month-year",
direction: "row",
gap: "300"
}, {
default: m(() => [
i(e(R), {
as: "nav",
class: "d-datepicker__nav",
direction: "row",
gap: "200"
}, {
default: m(() => [
i(e(w), {
"fallback-placements": ["top-start", "auto"],
message: e(r).$t("DIALTONE_DATEPICKER_PREVIOUS_YEAR"),
placement: "top"
}, {
anchor: m(() => [
i(e(I), {
id: "prevYearButton",
ref: (a) => {
a && e(k)(a);
},
"aria-label": e(f)(),
circle: !0,
class: "d-datepicker__nav-btn",
importance: "clear",
kind: "muted",
size: "xs",
type: "button",
onClick: u[0] || (u[0] = (a) => e(l)(-1)),
onKeydown: u[1] || (u[1] = (a) => e(_)(a))
}, {
default: m(() => [
i(e(J), { size: "200" })
]),
_: 1
}, 8, ["aria-label"])
]),
_: 1
}, 8, ["message"]),
i(e(w), {
"fallback-placements": ["top-start", "auto"],
message: e(r).$t("DIALTONE_DATEPICKER_PREVIOUS_MONTH"),
placement: "top"
}, {
anchor: m(() => [
i(e(I), {
id: "prevMonthButton",
ref: (a) => {
a && e(k)(a);
},
"aria-label": e(C)(),
circle: !0,
class: "d-datepicker__nav-btn",
importance: "clear",
kind: "muted",
size: "xs",
type: "button",
onClick: u[2] || (u[2] = (a) => e(A)(-1)),
onKeydown: u[3] || (u[3] = (a) => e(_)(a))
}, {
default: m(() => [
i(e(Q), { size: "200" })
]),
_: 1
}, 8, ["aria-label"])
]),
_: 1
}, 8, ["message"])
]),
_: 1
}),
M("div", pe, P(e(b)(e(D))) + " " + P(e(v)), 1),
i(e(R), {
as: "nav",
class: "d-datepicker__nav",
direction: "row",
gap: "200"
}, {
default: m(() => [
i(e(w), {
"fallback-placements": ["top-end", "auto"],
message: e(r).$t("DIALTONE_DATEPICKER_NEXT_MONTH"),
placement: "top"
}, {
anchor: m(() => [
i(e(I), {
id: "nextMonthButton",
ref: (a) => {
a && e(k)(a);
},
"aria-label": e(y)(),
circle: !0,
class: "d-datepicker__nav-btn",
importance: "clear",
kind: "muted",
size: "xs",
type: "button",
onClick: u[4] || (u[4] = (a) => e(A)(1)),
onKeydown: u[5] || (u[5] = (a) => e(_)(a))
}, {
default: m(() => [
i(e(Z), { size: "200" })
]),
_: 1
}, 8, ["aria-label"])
]),
_: 1
}, 8, ["message"]),
i(e(w), {
"fallback-placements": ["top-end", "auto"],
message: e(r).$t("DIALTONE_DATEPICKER_NEXT_YEAR"),
placement: "top"
}, {
anchor: m(() => [
i(e(I), {
id: "nextYearButton",
ref: (a) => {
a && e(k)(a);
},
"aria-label": e(O)(),
circle: !0,
class: "d-datepicker__nav-btn",
importance: "clear",
kind: "muted",
size: "xs",
type: "button",
onClick: u[6] || (u[6] = (a) => e(l)(1)),
onKeydown: u[7] || (u[7] = (a) => e(_)(a))
}, {
default: m(() => [
i(e(ee), { size: "200" })
]),
_: 1
}, 8, ["aria-label"])
]),
_: 1
}, 8, ["message"])
]),
_: 1
})
]),
_: 1
}));
}
};
function me(d, s) {
const c = E(null), t = E(0), n = E([]), r = new z(), D = B(() => se(d.locale, de));
F(() => d.calendarDays, () => {
t.value = 0, n.value = [], c.value = null;
});
function v(l) {
return r.$t("DIALTONE_DATEPICKER_SELECT_DAY") + ` ${ie(l.value, U, r.currentLocale)}`;
}
function b(l, o) {
!n.value.some((T) => T.el === l) && o.currentMonth && n.value.push({ el: l, day: o });
}
function k(l) {
switch (l.key) {
case "ArrowUp":
l.preventDefault(), t.value -= 7;
try {
p(n.value[t.value].el.$el).focus();
} catch {
const o = ue(n.value[t.value + 7].day.value);
s("go-to-prev-month"), N(() => {
p(n.value[o - 1].el.$el).focus(), t.value += o - 1;
});
}
break;
case "ArrowDown":
l.preventDefault(), t.value += 7;
try {
p(n.value[t.value].el.$el).focus();
} catch {
const o = ce(n.value[t.value - 7].day.value);
s("go-to-next-month"), N(() => {
p(n.value[o - 1].el.$el).focus(), t.value += o - 1;
});
}
break;
case "ArrowLeft":
l.preventDefault(), t.value > 0 ? (t.value -= 1, p(n.value[t.value].el.$el).focus()) : (s("go-to-prev-month"), _());
break;
case "ArrowRight":
l.preventDefault(), t.value < n.value.length - 1 ? (t.value += 1, p(n.value[t.value].el.$el).focus()) : (s("go-to-next-month"), h());
break;
case "Tab":
l.preventDefault(), s("focus-month-year-picker");
break;
case "Escape":
s("close-datepicker");
break;
}
}
function h() {
t.value = 0, N(() => {
p(n.value[t.value].el.$el).focus();
});
}
function _() {
N(() => {
t.value = n.value.length - 1, p(n.value[t.value].el.$el).focus();
});
}
function A(l) {
l.currentMonth && (c.value = l.text, s("select-date", l.value));
}
return {
selectedDay: c,
weekDays: D,
dayAriaLabel: v,
setDayRef: b,
handleKeyDown: k,
focusFirstDay: h,
selectDay: A
};
}
const ke = {
class: "d-datepicker__calendar",
"aria-labelledby": "calendar-heading"
}, _e = ["title", "aria-label"], he = {
__name: "calendar",
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",
/**
* Will go to the next month
*
* @event go-to-next-month
*/
"go-to-next-month",
/**
* Will go to the previous month
*
* @event go-to-prev-month
*/
"go-to-prev-month"
],
setup(d, { expose: s, emit: c }) {
const t = d, n = c, {
selectedDay: r,
weekDays: D,
dayAriaLabel: v,
setDayRef: b,
handleKeyDown: k,
focusFirstDay: h,
selectDay: _
} = me(t, n);
return s({
focusFirstDay: h
}), (A, l) => ($(), g("table", ke, [
M("thead", null, [
M("tr", null, [
($(!0), g(x, null, Y(e(D), (o) => ($(), g("th", {
key: o,
scope: "col",
class: "d-datepicker__cell d-datepicker__cell--header"
}, [
M("span", {
class: "d-datepicker__weekday",
title: o,
"aria-label": o
}, P(o), 9, _e)
]))), 128))
])
]),
M("tbody", null, [
($(!0), g(x, null, Y(d.calendarDays, (o, T) => ($(), g("tr", { key: T }, [
($(!0), g(x, null, Y(o.days, (f, C) => ($(), g("td", {
key: T + C,
class: "d-datepicker__cell",
role: "listbox"
}, [
i(e(I), {
ref_for: !0,
ref: (y) => {
y && e(b)(y, f);
},
class: q(["d-datepicker__day", {
"d-datepicker__day--disabled": !f.currentMonth,
"d-datepicker__day--selected": e(r) ? f.text === e(r) && f.currentMonth : f.selected
}]),
circle: !0,
size: "sm",
importance: "clear",
disabled: !f.currentMonth,
type: "button",
"aria-selected": e(r) ? f.text === e(r) && f.currentMonth : f.selected,
"aria-label": e(v)(f),
role: "option",
onClick: (y) => e(_)(f),
onKeydown: l[0] || (l[0] = (y) => e(k)(y))
}, {
default: m(() => [
W(P(f.text), 1)
]),
_: 2
}, 1032, ["disabled", "class", "aria-selected", "aria-label", "onClick"])
]))), 128))
]))), 128))
])
]));
}
}, ye = { class: "d-datepicker__hd" }, $e = { class: "d-datepicker__bd" }, we = {
__name: "datepicker",
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"
],
setup(d) {
const s = E([]);
function c(t) {
s.value = t;
}
return V(() => {
const t = j();
fe(p(t.proxy.$el), "datepicker");
}), (t, n) => ($(), G(e(R), {
class: "d-datepicker",
gap: "400"
}, {
default: m(() => [
M("div", ye, [
i(De, {
ref: "monthYearPicker",
"selected-date": d.selectedDate,
onCalendarDays: c,
onFocusFirstDay: n[0] || (n[0] = (r) => t.$refs.calendar.focusFirstDay()),
onFocusLastDay: n[1] || (n[1] = (r) => t.$refs.calendar.focusLastDay()),
onCloseDatepicker: n[2] || (n[2] = (r) => t.$emit("close-datepicker"))
}, null, 8, ["selected-date"])
]),
M("div", $e, [
i(he, {
ref: "calendar",
"calendar-days": s.value,
onSelectDate: n[3] || (n[3] = (r) => t.$emit("selected-date", r)),
onFocusMonthYearPicker: n[4] || (n[4] = (r) => t.$refs.monthYearPicker.focusMonthYearPicker()),
onCloseDatepicker: n[5] || (n[5] = (r) => t.$emit("close-datepicker")),
onGoToNextMonth: n[6] || (n[6] = (r) => t.$refs.monthYearPicker.goToNextMonth()),
onGoToPrevMonth: n[7] || (n[7] = (r) => t.$refs.monthYearPicker.goToPrevMonth())
}, null, 8, ["calendar-days"])
])
]),
_: 1
}));
}
};
export {
we as default
};
//# sourceMappingURL=datepicker.js.map