types(DatetimePicker): use tsx (#8181)

This commit is contained in:
neverland 2021-02-19 20:21:42 +08:00 committed by GitHub
parent d092d669f2
commit 7daca89102
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 77 additions and 47 deletions

View File

@ -1,15 +1,23 @@
import { ref, watch, computed, nextTick, onMounted } from 'vue';
import { ref, watch, computed, nextTick, onMounted, PropType } from 'vue';
// Utils
import { isDate } from '../utils/validate/date';
import { pick, padZero, createNamespace } from '../utils';
import { times, sharedProps, getTrueValue, getMonthEndDay } from './utils';
import { pick, range, padZero, createNamespace } from '../utils';
import {
times,
ColumnType,
pickerKeys,
sharedProps,
getTrueValue,
getMonthEndDay,
DatetimePickerType,
} from './utils';
// Composition
import { useExpose } from '../composables/use-expose';
// Components
import Picker, { pickerProps } from '../picker';
import Picker from '../picker';
const currentYear = new Date().getFullYear();
const [createComponent] = createNamespace('date-picker');
@ -17,17 +25,18 @@ const [createComponent] = createNamespace('date-picker');
export default createComponent({
props: {
...sharedProps,
modelValue: Date as PropType<Date>,
type: {
type: String,
type: String as PropType<DatetimePickerType>,
default: 'datetime',
},
minDate: {
type: Date,
type: Date as PropType<Date>,
default: () => new Date(currentYear - 10, 0, 1),
validator: isDate,
},
maxDate: {
type: Date,
type: Date as PropType<Date>,
default: () => new Date(currentYear + 10, 11, 31),
validator: isDate,
},
@ -36,22 +45,23 @@ export default createComponent({
emits: ['confirm', 'cancel', 'change', 'update:modelValue'],
setup(props, { emit, slots }) {
const formatValue = (value) => {
if (!isDate(value)) {
value = props.minDate;
const formatValue = (value?: Date) => {
if (isDate(value)) {
const timestamp = range(
value.getTime(),
props.minDate.getTime(),
props.maxDate.getTime()
);
return new Date(timestamp);
}
value = Math.max(value, props.minDate.getTime());
value = Math.min(value, props.maxDate.getTime());
return new Date(value);
return props.minDate;
};
const picker = ref();
const currentDate = ref(formatValue(props.modelValue));
const getBoundary = (type, value) => {
const boundary = props[`${type}Date`];
const getBoundary = (type: 'max' | 'min', value: Date) => {
const boundary = props[`${type}Date` as const];
const year = boundary.getFullYear();
let month = 1;
let date = 1;
@ -98,7 +108,7 @@ export default createComponent({
currentDate.value
);
let result = [
let result: Array<{ type: ColumnType; range: number[] }> = [
{
type: 'year',
range: [minYear, maxYear],
@ -205,7 +215,7 @@ export default createComponent({
const { type } = props;
const indexes = picker.value.getIndexes();
const getValue = (type) => {
const getValue = (type: ColumnType) => {
let index = 0;
originColumns.value.forEach((column, columnIndex) => {
if (type === column.type) {
@ -301,11 +311,10 @@ export default createComponent({
v-slots={slots}
ref={picker}
columns={columns.value}
readonly={props.readonly}
onChange={onChange}
onCancel={onCancel}
onConfirm={onConfirm}
{...pick(props, Object.keys(pickerProps))}
{...pick(props, pickerKeys)}
/>
);
},

View File

@ -284,8 +284,8 @@ export default {
| show-toolbar | Whether to show toolbar | _boolean_ | `true` |
| loading | Whether to show loading prompt | _boolean_ | `false` |
| readonly | Whether to be readonly | _boolean_ | `false` |
| filter | Option filter | _(type, vals) => vals_ | - |
| formatter | Option text formatter | _(type, val) => val_ | - |
| filter | Option filter | _(type: string, values: string[]) => string[]_ | - |
| formatter | Option text formatter | _(type: string, value: string) => string_ | - |
| columns-order | Array for ordering columns, where item can be set to<br> `year`, `month`, `day`, `hour` and `minute` | _string[]_ | - |
| item-height | Option height, supports `px` `vw` `vh` `rem` unit, default `px` | _number \| string_ | `44` |
| visible-item-count | Count of visible columns | _number \| string_ | `6` |

View File

@ -293,8 +293,8 @@ export default {
| show-toolbar | 是否显示顶部栏 | _boolean_ | `true` |
| loading | 是否显示加载状态 | _boolean_ | `false` |
| readonly | 是否为只读状态,只读状态下无法切换选项 | _boolean_ | `false` |
| filter | 选项过滤函数 | _(type, vals) => vals_ | - |
| formatter | 选项格式化函数 | _(type, val) => val_ | - |
| filter | 选项过滤函数 | _(type: string, values: string[]) => string[]_ | - |
| formatter | 选项格式化函数 | _(type: string, value: string) => string_ | - |
| columns-order | 自定义列排序数组, 子项可选值为<br> `year``month``day``hour``minute` | _string[]_ | - |
| item-height | 选项高度,支持 `px` `vw` `vh` `rem` 单位,默认 `px` | _number \| string_ | `44` |
| visible-item-count | 可见的选项个数 | _number \| string_ | `6` |

View File

@ -1,20 +1,27 @@
import { ref, watch, computed, nextTick, onMounted } from 'vue';
// Utils
import { pick, range, padZero, createNamespace } from '../utils';
import { times, sharedProps } from './utils';
import {
pick,
range,
padZero,
createNamespace,
ComponentInstance,
} from '../utils';
import { times, sharedProps, pickerKeys } from './utils';
// Composition
import { useExpose } from '../composables/use-expose';
// Components
import Picker, { pickerProps } from '../picker';
import Picker from '../picker';
const [createComponent] = createNamespace('time-picker');
export default createComponent({
props: {
...sharedProps,
modelValue: String,
minHour: {
type: [Number, String],
default: 0,
@ -36,7 +43,7 @@ export default createComponent({
emits: ['confirm', 'cancel', 'change', 'update:modelValue'],
setup(props, { emit, slots }) {
const formatValue = (value) => {
const formatValue = (value?: string) => {
const { minHour, maxHour, maxMinute, minMinute } = props;
if (!value) {
@ -44,13 +51,13 @@ export default createComponent({
}
let [hour, minute] = value.split(':');
hour = padZero(range(hour, minHour, maxHour));
minute = padZero(range(minute, minMinute, maxMinute));
hour = padZero(range(+hour, +minHour, +maxHour));
minute = padZero(range(+minute, +minMinute, +maxMinute));
return `${hour}:${minute}`;
};
const picker = ref();
const picker = ref<ComponentInstance>();
const currentDate = ref(formatValue(props.modelValue));
const ranges = computed(() => [
@ -97,12 +104,12 @@ export default createComponent({
];
nextTick(() => {
picker.value.setValues(values);
picker.value!.setValues(values);
});
};
const updateInnerValue = () => {
const [hourIndex, minuteIndex] = picker.value.getIndexes();
const [hourIndex, minuteIndex] = picker.value!.getIndexes();
const [hourColumn, minuteColumn] = originColumns.value;
const hour = hourColumn.values[hourIndex] || hourColumn.values[0];
@ -173,11 +180,10 @@ export default createComponent({
v-slots={slots}
ref={picker}
columns={columns.value}
readonly={props.readonly}
onChange={onChange}
onCancel={onCancel}
onConfirm={onConfirm}
{...pick(props, Object.keys(pickerProps))}
{...pick(props, pickerKeys)}
/>
);
},

View File

@ -1,5 +1,5 @@
import { ref } from 'vue';
import { pick, createNamespace } from '../utils';
import { pick, createNamespace, ComponentInstance } from '../utils';
import { useExpose } from '../composables/use-expose';
import TimePicker from './TimePicker';
import DatePicker from './DatePicker';
@ -13,10 +13,11 @@ export default createComponent({
props: {
...TimePicker.props,
...DatePicker.props,
modelValue: [String, Date],
},
setup(props, { attrs, slots }) {
const root = ref();
const root = ref<ComponentInstance>();
useExpose({
getPicker: () => root.value?.getPicker(),

View File

@ -1,20 +1,34 @@
import { PropType } from 'vue';
import { isNaN } from '../utils/validate/number';
import { pickerProps } from '../picker';
export type ColumnType = 'year' | 'month' | 'day' | 'hour' | 'minute';
export type DatetimePickerType =
| 'date'
| 'time'
| 'datetime'
| 'datehour'
| 'month-day'
| 'year-month';
export const sharedProps = {
...pickerProps,
filter: Function,
modelValue: null,
columnsOrder: Array,
filter: Function as PropType<(type: string, values: string[]) => string[]>,
columnsOrder: Array as PropType<ColumnType[]>,
formatter: {
type: Function,
default: (type: string, value: unknown) => value,
type: Function as PropType<(type: string, value: string) => string>,
default: (type: string, value: string) => value,
},
};
export function times(n: number, iteratee: (index: number) => any[]) {
export const pickerKeys = Object.keys(pickerProps) as Array<
keyof typeof pickerProps
>;
export function times<T>(n: number, iteratee: (index: number) => T) {
let index = -1;
const result = Array(n);
const result: T[] = Array(n);
while (++index < n) {
result[index] = iteratee(index);

View File

@ -1,8 +1,8 @@
import { isNaN } from './number';
export function isDate(val: Date): val is Date {
export function isDate(val: unknown): val is Date {
return (
Object.prototype.toString.call(val) === '[object Date]' &&
!isNaN(val.getTime())
!isNaN((val as Date).getTime())
);
}