@nutui/nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
258 lines (257 loc) • 9.73 kB
JavaScript
import { _ as __rest } from "./tslib.es6-iWu3F_1J.js";
import React__default, { useState, useEffect } from "react";
import { View } from "@tarojs/components";
import { P as Picker } from "./picker.taro-Ctc0Wt4S.js";
import { u as useConfig } from "./configprovider.taro-DpK4IiCE.js";
import { u as usePropsValue } from "./use-props-value-SH9krhkx.js";
import { C as ComponentDefaults } from "./typings-DV9RBfhj.js";
import { p as padZero } from "./pad-zero-B2OUQfh7.js";
const isDate = (val) => {
return Object.prototype.toString.call(val) === "[object Date]" && !Number.isNaN(val.getTime());
};
const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
const defaultProps = Object.assign(Object.assign({}, ComponentDefaults), { visible: false, title: "", type: "date", showChinese: false, threeDimensional: true, minuteStep: 1, startDate: new Date(currentYear - 10, 0, 1), endDate: new Date(currentYear + 10, 11, 31) });
const DatePicker = (props) => {
const _a = Object.assign(Object.assign({}, defaultProps), props), { startDate, endDate, type, showChinese, minuteStep, visible, title, defaultValue, pickerProps = {}, formatter, onClose, onCancel, onConfirm, filter, onChange, threeDimensional, className, style } = _a, rest = __rest(_a, ["startDate", "endDate", "type", "showChinese", "minuteStep", "visible", "title", "defaultValue", "pickerProps", "formatter", "onClose", "onCancel", "onConfirm", "filter", "onChange", "threeDimensional", "className", "style"]);
const { locale } = useConfig();
const lang = locale.datepicker;
const zhCNType = {
day: lang.day,
year: lang.year,
month: lang.month,
hour: lang.hour,
minute: lang.min,
seconds: lang.seconds
};
const [pickerValue, setPickerValue] = useState([]);
const [pickerOptions, setPickerOptions] = useState([]);
const formatValue = (value) => {
if (!value || value && !isDate(value)) {
value = startDate;
}
return Math.min(Math.max(value.getTime(), startDate.getTime()), endDate.getTime());
};
const [selectedDate, setSelectedDate] = usePropsValue({
value: props.value && formatValue(props.value),
defaultValue: props.defaultValue && formatValue(props.defaultValue),
finalValue: 0
});
function getMonthEndDay(year, month) {
return new Date(year, month, 0).getDate();
}
const getBoundary = (type2, value) => {
const boundary = type2 === "min" ? startDate : endDate;
const year = boundary.getFullYear();
let month = 1;
let date = 1;
let hour = 0;
let minute = 0;
if (type2 === "max") {
month = 12;
date = getMonthEndDay(value.getFullYear(), value.getMonth() + 1);
hour = 23;
minute = 59;
}
const seconds = minute;
if (value.getFullYear() === year) {
month = boundary.getMonth() + 1;
if (value.getMonth() + 1 === month) {
date = boundary.getDate();
if (value.getDate() === date) {
hour = boundary.getHours();
if (value.getHours() === hour) {
minute = boundary.getMinutes();
}
}
}
}
return {
[`${type2}Year`]: year,
[`${type2}Month`]: month,
[`${type2}Date`]: date,
[`${type2}Hour`]: hour,
[`${type2}Minute`]: minute,
[`${type2}Seconds`]: seconds
};
};
const ranges = () => {
const selected = new Date(selectedDate);
if (!selected)
return [];
const { maxYear, maxDate, maxMonth, maxHour, maxMinute, maxSeconds } = getBoundary("max", selected);
const { minYear, minDate, minMonth, minHour, minMinute, minSeconds } = getBoundary("min", selected);
const result = [
{
type: "year",
range: [minYear, maxYear]
},
{
type: "month",
range: [minMonth, maxMonth]
},
{
type: "day",
range: [minDate, maxDate]
},
{
type: "hour",
range: [minHour, maxHour]
},
{
type: "minute",
range: [minMinute, maxMinute]
},
{
type: "seconds",
range: [minSeconds, maxSeconds]
}
];
switch (type.toLocaleLowerCase()) {
case "date":
return result.slice(0, 3);
case "datetime":
return result.slice(0, 5);
case "time":
return result.slice(3, 6);
case "year-month":
return result.slice(0, 2);
case "hour-minutes":
return result.slice(3, 5);
case "month-day":
return result.slice(1, 3);
case "datehour":
return result.slice(0, 4);
default:
return result;
}
};
const compareDateChange = (currentDate, newDate, selectedOptions, index) => {
var _a2;
const isEqual = ((_a2 = new Date(currentDate)) === null || _a2 === void 0 ? void 0 : _a2.getTime()) === (newDate === null || newDate === void 0 ? void 0 : newDate.getTime());
if (newDate && isDate(newDate)) {
if (!isEqual) {
setSelectedDate(formatValue(newDate));
}
onChange === null || onChange === void 0 ? void 0 : onChange(selectedOptions, [
String(newDate.getFullYear()),
String(newDate.getMonth() + 1),
String(newDate.getDate())
], index);
}
};
const handlePickerChange = (selectedOptions, selectedValue, index) => {
const rangeType = type.toLocaleLowerCase();
if (["date", "datetime", "datehour", "month-day", "year-month"].includes(rangeType)) {
const formatDate = [];
selectedValue.forEach((item) => {
formatDate.push(item);
});
if (rangeType === "month-day" && formatDate.length < 3) {
formatDate.unshift(new Date(defaultValue || startDate || endDate).getFullYear());
}
if (rangeType === "year-month" && formatDate.length < 3) {
formatDate.push(new Date(defaultValue || startDate || endDate).getDate());
}
const year = Number(formatDate[0]);
const month = Number(formatDate[1]) - 1;
const day = Math.min(Number(formatDate[2]), getMonthEndDay(Number(formatDate[0]), Number(formatDate[1])));
if (selectedOptions.length >= 2 && ["date", "datehour", "datetime", "month-day"].includes(rangeType)) {
const dayOption = formatOption("day", day);
if (rangeType === "month-day") {
selectedOptions[1] = dayOption;
} else {
selectedOptions[2] = dayOption;
}
}
let date = null;
if (rangeType === "date" || rangeType === "month-day" || rangeType === "year-month") {
date = new Date(year, month, day);
} else if (rangeType === "datetime") {
date = new Date(year, month, day, Number(formatDate[3]), Number(formatDate[4]));
} else if (rangeType === "datehour") {
date = new Date(year, month, day, Number(formatDate[3]));
}
compareDateChange(selectedDate, date, selectedOptions, index);
} else {
const [hour, minute, seconds] = selectedValue;
const currentDate = new Date(selectedDate);
const year = currentDate.getFullYear();
const month = currentDate.getMonth();
const day = currentDate.getDate();
const date = new Date(year, month, day, Number(hour), Number(minute), rangeType === "time" ? Number(seconds) : 0);
compareDateChange(selectedDate, date, selectedOptions, index);
}
};
const formatOption = (type2, value) => {
if (formatter) {
return formatter(type2, {
text: padZero(value, 2),
value: padZero(value, 2)
});
}
const padMin = padZero(value, 2);
const fatter = showChinese ? zhCNType[type2] : "";
return { text: padMin + fatter, value: padMin };
};
const generateColumn = (min, max, val, type2, columnIndex) => {
var _a2;
let cmin = min;
const arr = [];
let index = 0;
while (cmin <= max) {
arr.push(formatOption(type2, cmin));
if (type2 === "minute") {
cmin += minuteStep;
} else {
cmin++;
}
if (cmin <= Number(val)) {
index++;
}
}
pickerValue[columnIndex] = (_a2 = arr[index]) === null || _a2 === void 0 ? void 0 : _a2.value;
setPickerValue([...pickerValue]);
if (filter === null || filter === void 0 ? void 0 : filter(type2, arr)) {
return filter === null || filter === void 0 ? void 0 : filter(type2, arr);
}
return arr;
};
const getDateIndex = (type2) => {
const date = new Date(selectedDate);
if (!selectedDate)
return 0;
if (type2 === "year") {
return date.getFullYear();
}
if (type2 === "month") {
return date.getMonth() + 1;
}
if (type2 === "day") {
return date.getDate();
}
if (type2 === "hour") {
return date.getHours();
}
if (type2 === "minute") {
return date.getMinutes();
}
if (type2 === "seconds") {
return date.getSeconds();
}
return 0;
};
const columns = () => {
const val = ranges().map((res, columnIndex) => {
return generateColumn(res.range[0], res.range[1], getDateIndex(res.type), res.type, columnIndex);
});
return val || [];
};
useEffect(() => {
setPickerOptions(columns());
}, [selectedDate, startDate, endDate]);
return React__default.createElement(View, Object.assign({ className: `nut-datepicker ${className}`, style, catchMove: true }, rest), pickerOptions.length > 0 && React__default.createElement(Picker, Object.assign({}, pickerProps, { title, visible, options: pickerOptions, onClose, onCancel, value: pickerValue, onConfirm: (options, value) => onConfirm && onConfirm(options, value), onChange: (options, value, index) => handlePickerChange(options, value, index), threeDimensional })));
};
DatePicker.displayName = "NutDatePicker";
export {
DatePicker as D
};