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