fix(web-antdv-next): normalize date picker timestamp handling
Add DatePicker and RangePicker adapter wrappers for numeric timestamp values, route direct value-format="x" usages through the adapter, and keep ShortcutDateRangePicker values as Dayjs.pull/362/head
parent
2fc5575c30
commit
f152217c3c
|
|
@ -0,0 +1,86 @@
|
|||
import type { Component } from 'vue';
|
||||
|
||||
import type { Recordable } from '@vben/types';
|
||||
|
||||
import { defineAsyncComponent, defineComponent, h, ref } from 'vue';
|
||||
|
||||
const RawDatePicker = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/date-picker/index'),
|
||||
);
|
||||
const RawRangePicker = defineAsyncComponent(() =>
|
||||
import('antdv-next/dist/date-picker/index').then(
|
||||
(res) => res.DateRangePicker,
|
||||
),
|
||||
);
|
||||
|
||||
const TIMESTAMP_VALUE_FORMATS = new Set(['x', 'X']);
|
||||
|
||||
function isTimestampValueFormat(valueFormat: unknown) {
|
||||
return (
|
||||
typeof valueFormat === 'string' && TIMESTAMP_VALUE_FORMATS.has(valueFormat)
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeTimestampPickerValue(value: any, valueFormat: unknown): any {
|
||||
if (!isTimestampValueFormat(valueFormat)) {
|
||||
return value;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((item) => normalizeTimestampPickerValue(item, valueFormat));
|
||||
}
|
||||
return typeof value === 'number' ? String(value) : value;
|
||||
}
|
||||
|
||||
function withTimestampValueFormat(
|
||||
component: Component,
|
||||
name: 'DatePicker' | 'RangePicker',
|
||||
) {
|
||||
return defineComponent({
|
||||
name,
|
||||
inheritAttrs: false,
|
||||
setup(_, { attrs, expose, slots }) {
|
||||
const innerRef = ref();
|
||||
expose(
|
||||
new Proxy(
|
||||
{},
|
||||
{
|
||||
get: (_target, key) => innerRef.value?.[key],
|
||||
has: (_target, key) => key in (innerRef.value || {}),
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
return () => {
|
||||
const pickerAttrs: Recordable<any> = { ...attrs };
|
||||
if (
|
||||
'value-format' in pickerAttrs &&
|
||||
!Reflect.has(pickerAttrs, 'valueFormat')
|
||||
) {
|
||||
pickerAttrs.valueFormat = pickerAttrs['value-format'];
|
||||
}
|
||||
const valueFormat = pickerAttrs.valueFormat;
|
||||
|
||||
for (const key of [
|
||||
'value',
|
||||
'defaultValue',
|
||||
'pickerValue',
|
||||
'defaultPickerValue',
|
||||
]) {
|
||||
if (Reflect.has(pickerAttrs, key)) {
|
||||
pickerAttrs[key] = normalizeTimestampPickerValue(
|
||||
pickerAttrs[key],
|
||||
valueFormat,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return h(component, { ...pickerAttrs, ref: innerRef }, slots);
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const DatePicker = withTimestampValueFormat(RawDatePicker, 'DatePicker');
|
||||
const RangePicker = withTimestampValueFormat(RawRangePicker, 'RangePicker');
|
||||
|
||||
export { DatePicker, RangePicker };
|
||||
|
|
@ -75,6 +75,9 @@ import { message, Modal, notification } from 'antdv-next';
|
|||
import { uploadFile as uploadFileApi } from '#/api/infra/file';
|
||||
import { Tinymce as RichTextarea } from '#/components/tinymce';
|
||||
import { FileUpload, ImageUpload } from '#/components/upload';
|
||||
|
||||
import { DatePicker, RangePicker } from './date-picker';
|
||||
|
||||
type AdapterUploadProps = UploadProps & {
|
||||
aspectRatio?: string;
|
||||
crop?: boolean;
|
||||
|
|
@ -97,9 +100,6 @@ const Checkbox = defineAsyncComponent(
|
|||
const CheckboxGroup = defineAsyncComponent(() =>
|
||||
import('antdv-next/dist/checkbox/index').then((res) => res.CheckboxGroup),
|
||||
);
|
||||
const DatePicker = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/date-picker/index'),
|
||||
);
|
||||
const Divider = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/divider/index'),
|
||||
);
|
||||
|
|
@ -117,11 +117,6 @@ const Radio = defineAsyncComponent(() => import('antdv-next/dist/radio/index'));
|
|||
const RadioGroup = defineAsyncComponent(() =>
|
||||
import('antdv-next/dist/radio/index').then((res) => res.RadioGroup),
|
||||
);
|
||||
const RangePicker = defineAsyncComponent(() =>
|
||||
import('antdv-next/dist/date-picker/index').then(
|
||||
(res) => res.DateRangePicker,
|
||||
),
|
||||
);
|
||||
const Rate = defineAsyncComponent(() => import('antdv-next/dist/rate/index'));
|
||||
const Select = defineAsyncComponent(
|
||||
() => import('antdv-next/dist/select/index'),
|
||||
|
|
@ -794,4 +789,4 @@ async function initComponentAdapter() {
|
|||
});
|
||||
}
|
||||
|
||||
export { initComponentAdapter };
|
||||
export { DatePicker, initComponentAdapter, RangePicker };
|
||||
|
|
|
|||
|
|
@ -91,7 +91,6 @@ onMounted(() => {
|
|||
<DateRangePicker
|
||||
v-model:value="times"
|
||||
:format="rangePickerProps.format"
|
||||
:value-format="rangePickerProps.valueFormat"
|
||||
:placeholder="rangePickerProps.placeholder"
|
||||
:presets="rangePickerProps.presets"
|
||||
class="!w-full !max-w-96"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import { DICT_TYPE } from '@vben/constants';
|
|||
import { getDictOptions } from '@vben/hooks';
|
||||
|
||||
import {
|
||||
DatePicker,
|
||||
Form,
|
||||
Input,
|
||||
message,
|
||||
|
|
@ -16,6 +15,7 @@ import {
|
|||
RadioGroup,
|
||||
} from 'antdv-next';
|
||||
|
||||
import { DatePicker } from '#/adapter/component/date-picker';
|
||||
import {
|
||||
createDemo01Contact,
|
||||
getDemo01Contact,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import { DICT_TYPE } from '@vben/constants';
|
|||
import { getDictOptions } from '@vben/hooks';
|
||||
|
||||
import {
|
||||
DatePicker,
|
||||
Form,
|
||||
Input,
|
||||
message,
|
||||
|
|
@ -16,6 +15,7 @@ import {
|
|||
RadioGroup,
|
||||
} from 'antdv-next';
|
||||
|
||||
import { DatePicker } from '#/adapter/component/date-picker';
|
||||
import {
|
||||
createDemo03Student,
|
||||
getDemo03Student,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import { DICT_TYPE } from '@vben/constants';
|
|||
import { getDictOptions } from '@vben/hooks';
|
||||
|
||||
import {
|
||||
DatePicker,
|
||||
Form,
|
||||
Input,
|
||||
message,
|
||||
|
|
@ -17,6 +16,7 @@ import {
|
|||
Tabs,
|
||||
} from 'antdv-next';
|
||||
|
||||
import { DatePicker } from '#/adapter/component/date-picker';
|
||||
import {
|
||||
createDemo03Student,
|
||||
getDemo03Student,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import { DICT_TYPE } from '@vben/constants';
|
|||
import { getDictOptions } from '@vben/hooks';
|
||||
|
||||
import {
|
||||
DatePicker,
|
||||
Form,
|
||||
Input,
|
||||
message,
|
||||
|
|
@ -17,6 +16,7 @@ import {
|
|||
Tabs,
|
||||
} from 'antdv-next';
|
||||
|
||||
import { DatePicker } from '#/adapter/component/date-picker';
|
||||
import {
|
||||
createDemo03Student,
|
||||
getDemo03Student,
|
||||
|
|
|
|||
Loading…
Reference in New Issue