@varlet/ui
Version:
A Vue3 component library based on Material Design 2 and 3, supporting mobile and desktop.
711 lines (710 loc) • 26.8 kB
JavaScript
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
import { computed, defineComponent, ref, watch } from "vue";
import { call, doubleRaf, error, isArray, toNumber } from "@varlet/shared";
import dayjs from "dayjs/esm/index.js";
import { t } from "../locale/index.mjs";
import { injectLocaleProvider } from "../locale-provider/provide.mjs";
import { createNamespace, formatElevation } from "../utils/components.mjs";
import { padStart } from "../utils/shared.mjs";
import {
MONTH_LIST,
props,
WEEK_HEADER
} from "./props.mjs";
import DayPickerPanel from "./src/day-picker-panel.mjs";
import MonthPickerPanel from "./src/month-picker-panel.mjs";
import YearPickerPanel from "./src/year-picker-panel.mjs";
const { name, n, classes } = createNamespace("date-picker");
import { toDisplayString as _toDisplayString, normalizeClass as _normalizeClass, createElementVNode as _createElementVNode, renderSlot as _renderSlot, createTextVNode as _createTextVNode, openBlock as _openBlock, createElementBlock as _createElementBlock, createCommentVNode as _createCommentVNode, normalizeProps as _normalizeProps, mergeProps as _mergeProps, Transition as _Transition, withCtx as _withCtx, createVNode as _createVNode, normalizeStyle as _normalizeStyle, resolveComponent as _resolveComponent, createBlock as _createBlock } from "vue";
function __render__(_ctx, _cache) {
var _a;
const _component_year_picker_panel = _resolveComponent("year-picker-panel");
const _component_month_picker_panel = _resolveComponent("month-picker-panel");
const _component_day_picker_panel = _resolveComponent("day-picker-panel");
return _openBlock(), _createElementBlock(
"div",
{
class: _normalizeClass(_ctx.classes(_ctx.n(), _ctx.formatElevation(_ctx.elevation, 2)))
},
[
_createElementVNode(
"div",
{
class: _normalizeClass(_ctx.n("title")),
style: _normalizeStyle({ background: _ctx.titleColor || _ctx.color })
},
[
_createElementVNode(
"div",
{
class: _normalizeClass(_ctx.n("title-select"))
},
[
_createElementVNode(
"div",
{
class: _normalizeClass(_ctx.n("title-hint"))
},
_toDisplayString((_a = _ctx.hint) != null ? _a : (_ctx.pt ? _ctx.pt : _ctx.t)("datePickerHint")),
3
/* TEXT, CLASS */
),
_ctx.type !== "year" ? (_openBlock(), _createElementBlock(
"div",
{
key: 0,
class: _normalizeClass(_ctx.classes(_ctx.n("title-year"), [_ctx.isYearPanel, _ctx.n("title-year--active")])),
onClick: _cache[0] || (_cache[0] = ($event) => _ctx.clickEl("year"))
},
[
_renderSlot(_ctx.$slots, "year", { year: _ctx.chooseYear }, () => [
_createTextVNode(
_toDisplayString(_ctx.chooseYear),
1
/* TEXT */
)
])
],
2
/* CLASS */
)) : _createCommentVNode("v-if", true)
],
2
/* CLASS */
),
_createElementVNode(
"div",
{
class: _normalizeClass(
_ctx.classes(
_ctx.n("title-date"),
[!_ctx.isYearPanel || _ctx.type === "year", _ctx.n("title-date--active")],
[_ctx.range, _ctx.n("title-date--range")]
)
),
onClick: _cache[1] || (_cache[1] = ($event) => _ctx.clickEl("date"))
},
[
_createVNode(_Transition, {
name: _ctx.multiple ? "" : `${_ctx.n()}${_ctx.reverse ? "-reverse" : ""}-translatey`
}, {
default: _withCtx(() => [
_ctx.type === "year" ? (_openBlock(), _createElementBlock("div", {
key: `${_ctx.chooseYear}`
}, [
_ctx.range ? _renderSlot(_ctx.$slots, "range", {
key: 0,
choose: _ctx.getChoose.chooseRangeYear
}, () => [
_createTextVNode(
_toDisplayString(_ctx.getYearTitle),
1
/* TEXT */
)
]) : _ctx.multiple ? _renderSlot(_ctx.$slots, "multiple", {
key: 1,
choose: _ctx.getChoose.chooseYears
}, () => [
_createTextVNode(
_toDisplayString(_ctx.getYearTitle),
1
/* TEXT */
)
]) : _renderSlot(_ctx.$slots, "year", {
key: 2,
year: _ctx.chooseYear
}, () => [
_createTextVNode(
_toDisplayString(_ctx.getYearTitle),
1
/* TEXT */
)
])
])) : _ctx.type === "month" ? (_openBlock(), _createElementBlock("div", {
key: `${_ctx.chooseYear}${_ctx.chooseMonth}`
}, [
_ctx.range ? _renderSlot(_ctx.$slots, "range", {
key: 0,
choose: _ctx.getChoose.chooseRangeMonth
}, () => [
_createTextVNode(
_toDisplayString(_ctx.getMonthTitle),
1
/* TEXT */
)
]) : _ctx.multiple ? _renderSlot(_ctx.$slots, "multiple", {
key: 1,
choose: _ctx.getChoose.chooseMonths
}, () => [
_createTextVNode(
_toDisplayString(_ctx.getMonthTitle),
1
/* TEXT */
)
]) : _renderSlot(_ctx.$slots, "month", {
key: 2,
month: _ctx.chooseMonth,
year: _ctx.chooseYear
}, () => [
_createTextVNode(
_toDisplayString(_ctx.getMonthTitle),
1
/* TEXT */
)
])
])) : (_openBlock(), _createElementBlock("div", {
key: `${_ctx.chooseYear}${_ctx.chooseMonth}${_ctx.chooseDay}`
}, [
_ctx.range ? _renderSlot(_ctx.$slots, "range", {
key: 0,
choose: _ctx.formatRange
}, () => [
_createTextVNode(
_toDisplayString(_ctx.getDateTitle),
1
/* TEXT */
)
]) : _ctx.multiple ? _renderSlot(_ctx.$slots, "multiple", {
key: 1,
choose: _ctx.getChoose.chooseDays
}, () => [
_createTextVNode(
_toDisplayString(_ctx.getDateTitle),
1
/* TEXT */
)
]) : _renderSlot(_ctx.$slots, "date", _normalizeProps(_mergeProps({ key: 2 }, _ctx.slotProps)), () => [
_createTextVNode(
_toDisplayString(_ctx.getDateTitle),
1
/* TEXT */
)
])
]))
]),
_: 3
/* FORWARDED */
}, 8, ["name"])
],
2
/* CLASS */
)
],
6
/* CLASS, STYLE */
),
_createElementVNode(
"div",
{
class: _normalizeClass(_ctx.n("body")),
onTouchstart: _cache[2] || (_cache[2] = (...args) => _ctx.handleTouchstart && _ctx.handleTouchstart(...args)),
onTouchmove: _cache[3] || (_cache[3] = (...args) => _ctx.handleTouchmove && _ctx.handleTouchmove(...args)),
onTouchend: _cache[4] || (_cache[4] = (...args) => _ctx.handleTouchend && _ctx.handleTouchend(...args))
},
[
_createVNode(_Transition, {
name: `${_ctx.n()}-panel-fade`
}, {
default: _withCtx(() => [
_ctx.getPanelType === "year" ? (_openBlock(), _createBlock(_component_year_picker_panel, {
key: 0,
ref: "yearPanelEl",
choose: _ctx.getChoose,
current: _ctx.currentDate,
"component-props": _ctx.componentProps,
preview: _ctx.previewYear,
onChooseYear: _ctx.getChooseYear
}, null, 8, ["choose", "current", "component-props", "preview", "onChooseYear"])) : _ctx.getPanelType === "month" ? (_openBlock(), _createBlock(_component_month_picker_panel, {
key: 1,
ref: "monthPanelEl",
current: _ctx.currentDate,
choose: _ctx.getChoose,
preview: _ctx.getPreview,
"click-year": () => _ctx.clickEl("year"),
"component-props": _ctx.componentProps,
onChooseMonth: _ctx.getChooseMonth,
onCheckPreview: _ctx.checkPreview
}, null, 8, ["current", "choose", "preview", "click-year", "component-props", "onChooseMonth", "onCheckPreview"])) : _ctx.getPanelType === "date" ? (_openBlock(), _createBlock(_component_day_picker_panel, {
key: 2,
ref: "dayPanelEl",
current: _ctx.currentDate,
choose: _ctx.getChoose,
preview: _ctx.getPreview,
"component-props": _ctx.componentProps,
"click-month": () => _ctx.clickEl("month"),
onChooseDay: _ctx.getChooseDay,
onCheckPreview: _ctx.checkPreview
}, null, 8, ["current", "choose", "preview", "component-props", "click-month", "onChooseDay", "onCheckPreview"])) : _createCommentVNode("v-if", true)
]),
_: 1
/* STABLE */
}, 8, ["name"])
],
34
/* CLASS, NEED_HYDRATION */
),
_ctx.$slots.actions ? (_openBlock(), _createElementBlock(
"div",
{
key: 0,
class: _normalizeClass(_ctx.n("actions"))
},
[
_renderSlot(_ctx.$slots, "actions")
],
2
/* CLASS */
)) : _createCommentVNode("v-if", true)
],
2
/* CLASS */
);
}
const __sfc__ = defineComponent({
name,
components: {
MonthPickerPanel,
YearPickerPanel,
DayPickerPanel
},
props,
setup(props2) {
const { t: pt } = injectLocaleProvider();
const currentDate = dayjs().format("YYYY-MM-D");
const [currentYear, currentMonth] = currentDate.split("-");
const monthDes = MONTH_LIST.find((month) => month === currentMonth);
const isYearPanel = ref(false);
const isMonthPanel = ref(false);
const rangeDone = ref(true);
const chooseMonth = ref();
const chooseYear = ref();
const chooseDay = ref();
const previewMonth = ref(monthDes);
const previewYear = ref(currentYear);
const reverse = ref(false);
const chooseYears = ref([]);
const chooseMonths = ref([]);
const chooseDays = ref([]);
const chooseRangeYear = ref([]);
const chooseRangeMonth = ref([]);
const chooseRangeDay = ref([]);
const yearPanelEl = ref(null);
const monthPanelEl = ref(null);
const dayPanelEl = ref(null);
const componentProps = computed(() => ({
allowedDates: props2.allowedDates,
type: props2.type,
color: props2.color,
firstDayOfWeek: props2.firstDayOfWeek,
min: props2.min,
max: props2.max,
showCurrent: props2.showCurrent,
multiple: props2.multiple,
range: props2.range,
buttonElevation: props2.buttonElevation
}));
const getChoose = computed(() => ({
chooseMonth: chooseMonth.value,
chooseYear: chooseYear.value,
chooseDay: chooseDay.value,
chooseYears: chooseYears.value,
chooseMonths: chooseMonths.value,
chooseDays: chooseDays.value,
chooseRangeYear: chooseRangeYear.value,
chooseRangeMonth: chooseRangeMonth.value,
chooseRangeDay: chooseRangeDay.value
}));
const getPreview = computed(() => ({
previewMonth: previewMonth.value,
previewYear: previewYear.value
}));
const getYearTitle = computed(() => {
var _a;
const { multiple, range } = props2;
if (range) {
return chooseRangeYear.value.length ? `${chooseRangeYear.value[0]} ~ ${chooseRangeYear.value[1]}` : "";
}
return multiple ? `${chooseYears.value.length}${(pt || t)("datePickerSelected")}` : (_a = chooseYear.value) != null ? _a : "";
});
const getMonthTitle = computed(() => {
var _a, _b;
const { multiple, range } = props2;
if (range) {
return chooseRangeMonth.value.length ? `${chooseRangeMonth.value[0]} ~ ${chooseRangeMonth.value[1]}` : "";
}
let monthName = "";
if (chooseMonth.value) {
monthName = (_b = (_a = (pt || t)("datePickerMonthDict")) == null ? void 0 : _a[chooseMonth.value].name) != null ? _b : "";
}
return multiple ? `${chooseMonths.value.length}${(pt || t)("datePickerSelected")}` : monthName;
});
const getDateTitle = computed(() => {
var _a, _b, _c, _d;
const { multiple, range } = props2;
if (range) {
const formatRangeDays = chooseRangeDay.value.map((date) => dayjs(date).format("YYYY-MM-DD"));
return formatRangeDays.length ? `${formatRangeDays[0]} ~ ${formatRangeDays[1]}` : "";
}
if (multiple) {
return `${chooseDays.value.length}${(pt || t)("datePickerSelected")}`;
}
if (!chooseYear.value || !chooseMonth.value || !chooseDay.value) {
return "";
}
const weekIndex = dayjs(`${chooseYear.value}-${chooseMonth.value}-${chooseDay.value}`).day();
const week = WEEK_HEADER.find((value) => value === `${weekIndex}`);
const weekName = (_b = (_a = (pt || t)("datePickerWeekDict")) == null ? void 0 : _a[week].name) != null ? _b : "";
const monthName = (_d = (_c = (pt || t)("datePickerMonthDict")) == null ? void 0 : _c[chooseMonth.value].name) != null ? _d : "";
const showDay = padStart(chooseDay.value, 2, "0");
if ((pt || t)("lang") === "zh-CN") {
return `${chooseMonth.value}-${showDay} ${weekName.slice(0, 3)}`;
}
return `${weekName.slice(0, 3)}, ${monthName.slice(0, 3)} ${chooseDay.value}`;
});
const getPanelType = computed(() => {
if (props2.type === "year" || isYearPanel.value) {
return "year";
}
if (props2.type === "month" || isMonthPanel.value) {
return "month";
}
if (props2.type === "date") {
return "date";
}
return "";
});
const isUntouchable = computed(() => !props2.touchable || !getPanelType.value);
const slotProps = computed(() => {
var _a, _b;
const weekIndex = dayjs(`${chooseYear.value}-${chooseMonth.value}-${chooseDay.value}`).day();
const date = chooseDay.value ? padStart(chooseDay.value, 2, "0") : "";
return {
week: `${weekIndex}`,
year: (_a = chooseYear.value) != null ? _a : "",
month: (_b = chooseMonth.value) != null ? _b : "",
date
};
});
const formatRange = computed(
() => getChoose.value.chooseRangeDay.map((choose) => dayjs(choose).format("YYYY-MM-DD"))
);
const isSameYear = computed(() => chooseYear.value === previewYear.value);
const isSameMonth = computed(() => chooseMonth.value === previewMonth.value);
let startX = 0;
let startY = 0;
let checkType = "";
let touchDirection;
watch(
() => props2.modelValue,
(value) => {
if (!checkValue() || invalidFormatDate(value)) {
return;
}
if (props2.range) {
if (!isArray(value)) {
return;
}
rangeDone.value = value.length !== 1;
rangeInit(value, props2.type);
} else if (props2.multiple) {
if (!isArray(value)) {
return;
}
multipleInit(value, props2.type);
} else {
dateInit(value);
}
},
{ immediate: true }
);
watch(getPanelType, resetState);
function clickEl(type) {
if (type === "year") {
isYearPanel.value = true;
} else if (type === "month") {
isMonthPanel.value = true;
} else {
isYearPanel.value = false;
isMonthPanel.value = false;
}
}
function handleTouchstart(event) {
if (isUntouchable.value) {
return;
}
const { clientX, clientY } = event.touches[0];
startX = clientX;
startY = clientY;
}
function getDirection(x, y) {
return x >= y && x > 20 ? "x" : "y";
}
function handleTouchmove(event) {
if (isUntouchable.value) {
return;
}
const { clientX, clientY } = event.touches[0];
const x = clientX - startX;
const y = clientY - startY;
touchDirection = getDirection(Math.abs(x), Math.abs(y));
checkType = x > 0 ? "prev" : "next";
}
function handleTouchend() {
return __async(this, null, function* () {
if (isUntouchable.value || touchDirection !== "x") {
return;
}
const componentRef = getPanelType.value === "year" ? yearPanelEl : getPanelType.value === "month" ? monthPanelEl : dayPanelEl;
yield doubleRaf();
componentRef.value.forwardRef(checkType);
resetState();
});
}
function updateRange(date, type) {
const rangeDate = type === "year" ? chooseRangeYear : type === "month" ? chooseRangeMonth : chooseRangeDay;
rangeDate.value = rangeDone.value ? [date, date] : [rangeDate.value[0], date];
rangeDone.value = !rangeDone.value;
if (rangeDone.value) {
const isChangeOrder = dayjs(rangeDate.value[0]).isAfter(rangeDate.value[1]);
const date2 = isChangeOrder ? [rangeDate.value[1], rangeDate.value[0]] : [...rangeDate.value];
call(props2["onUpdate:modelValue"], date2);
call(props2.onChange, date2);
}
}
function updateMultiple(date, type) {
const multipleDates = type === "year" ? chooseYears : type === "month" ? chooseMonths : chooseDays;
const formatType = type === "year" ? "YYYY" : type === "month" ? "YYYY-MM" : "YYYY-MM-DD";
const formatDates = multipleDates.value.map((date2) => dayjs(date2).format(formatType));
const index = formatDates.findIndex((choose) => choose === date);
if (index === -1) {
formatDates.push(date);
} else {
formatDates.splice(index, 1);
}
call(props2["onUpdate:modelValue"], formatDates);
call(props2.onChange, formatDates);
}
function getReverse(dateType, date) {
if (!chooseYear.value || !chooseMonth.value) {
return false;
}
if (!isSameYear.value) {
return chooseYear.value > previewYear.value;
}
if (dateType === "year") {
return date < toNumber(chooseYear.value);
}
if (dateType === "month") {
return date < chooseMonth.value;
}
return isSameMonth.value ? date < toNumber(chooseDay.value) : chooseMonth.value > previewMonth.value;
}
function getChooseDay(day) {
const { readonly, range, multiple, onChange, "onUpdate:modelValue": updateModelValue } = props2;
if (day < 0 || readonly) {
return;
}
reverse.value = getReverse("day", day);
const date = `${previewYear.value}-${previewMonth.value}-${day}`;
const formatDate = dayjs(date).format("YYYY-MM-DD");
if (range) {
updateRange(formatDate, "day");
} else if (multiple) {
updateMultiple(formatDate, "day");
} else {
call(updateModelValue, formatDate);
call(onChange, formatDate);
}
}
function getChooseMonth(month) {
const { type, readonly, range, multiple, onChange, onPreview, "onUpdate:modelValue": updateModelValue } = props2;
reverse.value = getReverse("month", month);
if (type === "month" && !readonly) {
const date = `${previewYear.value}-${month}`;
if (range) {
updateRange(date, "month");
} else if (multiple) {
updateMultiple(date, "month");
} else {
call(updateModelValue, date);
call(onChange, date);
}
} else {
previewMonth.value = month;
call(
onPreview,
toNumber(previewYear.value),
toNumber(previewMonth.value),
type === "date" ? toNumber(chooseDay.value) : void 0
);
}
isMonthPanel.value = false;
}
function getChooseYear(year) {
const { type, readonly, range, multiple, onChange, onPreview, "onUpdate:modelValue": updateModelValue } = props2;
reverse.value = getReverse("year", year);
if (type === "year" && !readonly) {
if (range) {
updateRange(`${year}`, "year");
} else if (multiple) {
updateMultiple(`${year}`, "year");
} else {
call(updateModelValue, `${year}`);
call(onChange, `${year}`);
}
} else {
previewYear.value = `${year}`;
call(
onPreview,
toNumber(previewYear.value),
toNumber(previewMonth.value),
type === "date" ? toNumber(chooseDay.value) : void 0
);
}
isYearPanel.value = false;
}
function checkPreview(type, checkType2) {
const changeValue = checkType2 === "prev" ? -1 : 1;
if (type === "year") {
previewYear.value = `${toNumber(previewYear.value) + changeValue}`;
} else {
let checkIndex = toNumber(previewMonth.value) + changeValue;
if (checkIndex < 1) {
previewYear.value = `${toNumber(previewYear.value) - 1}`;
checkIndex = 12;
}
if (checkIndex > 12) {
previewYear.value = `${toNumber(previewYear.value) + 1}`;
checkIndex = 1;
}
previewMonth.value = MONTH_LIST.find((month) => toNumber(month) === checkIndex);
}
call(
props2.onPreview,
toNumber(previewYear.value),
toNumber(previewMonth.value),
props2.type === "date" ? toNumber(chooseDay.value) : void 0
);
}
function checkValue() {
if ((props2.multiple || props2.range) && !isArray(props2.modelValue)) {
error("DatePicker", 'type of prop "modelValue" should be an Array');
return false;
}
if (!props2.multiple && !props2.range && isArray(props2.modelValue)) {
error("DatePicker", 'type of prop "modelValue" should be a String');
return false;
}
return true;
}
function invalidFormatDate(date) {
if (isArray(date)) {
return false;
}
if (date === "Invalid Date") {
error("DatePicker", '"modelValue" is an Invalid Date');
return true;
}
return false;
}
function rangeInit(value, type) {
const rangeDate = type === "year" ? chooseRangeYear : type === "month" ? chooseRangeMonth : chooseRangeDay;
const formatType = type === "year" ? "YYYY" : type === "month" ? "YYYY-MM" : "YYYY-MM-D";
const formatDateList = value.map((choose) => dayjs(choose).format(formatType)).slice(0, 2);
const isValid = rangeDate.value.some((date) => invalidFormatDate(date));
if (isValid) {
return;
}
rangeDate.value = formatDateList;
const isChangeOrder = dayjs(rangeDate.value[0]).isAfter(rangeDate.value[1]);
if (rangeDate.value.length === 2 && isChangeOrder) {
rangeDate.value = [rangeDate.value[1], rangeDate.value[0]];
}
}
function multipleInit(value, type) {
const rangeDate = type === "year" ? chooseYears : type === "month" ? chooseMonths : chooseDays;
const formatType = type === "year" ? "YYYY" : type === "month" ? "YYYY-MM" : "YYYY-MM-D";
const formatDateList = Array.from(new Set(value.map((choose) => dayjs(choose).format(formatType))));
rangeDate.value = formatDateList.filter((date) => date !== "Invalid Date");
}
function dateInit(value) {
const handleValue = value ? dayjs(value) : dayjs();
const formatDate = handleValue.format("YYYY-MM-D");
if (invalidFormatDate(formatDate)) {
return;
}
const [yearValue, monthValue, dayValue] = formatDate.split("-");
const monthDes2 = MONTH_LIST.find((month) => month === monthValue);
chooseMonth.value = monthDes2;
chooseYear.value = yearValue;
chooseDay.value = dayValue;
previewMonth.value = monthDes2;
previewYear.value = yearValue;
}
function resetState() {
startY = 0;
startX = 0;
checkType = "";
touchDirection = void 0;
}
return {
yearPanelEl,
monthPanelEl,
dayPanelEl,
reverse,
currentDate,
chooseMonth,
chooseYear,
chooseDay,
previewYear,
isYearPanel,
isMonthPanel,
getMonthTitle,
getDateTitle,
getYearTitle,
getPanelType,
getChoose,
getPreview,
componentProps,
slotProps,
formatRange,
pt,
t,
n,
classes,
clickEl,
handleTouchstart,
handleTouchmove,
handleTouchend,
getChooseDay,
getChooseMonth,
getChooseYear,
checkPreview,
formatElevation
};
}
});
__sfc__.render = __render__;
var stdin_default = __sfc__;
export {
stdin_default as default
};