refactor: date

pull/4499/head
tangjinzhou 2021-07-21 12:05:03 +08:00
parent 4a21e41223
commit e1277cdee0
12 changed files with 102 additions and 57 deletions

View File

@ -13,7 +13,7 @@ export default function useMergedState<T, R = Ref<T>>(
postState?: (val: T) => T;
},
): [R, (val: T) => void] {
const { defaultValue, value } = option || {};
const { defaultValue, value = ref() } = option || {};
let initValue: T =
typeof defaultStateValue === 'function' ? (defaultStateValue as any)() : defaultStateValue;
if (value.value !== undefined) {

View File

@ -51,7 +51,13 @@ export { default as Comment } from './comment';
export { default as ConfigProvider } from './config-provider';
export type { DatePickerProps } from './date-picker';
export { default as DatePicker } from './date-picker';
export {
default as DatePicker,
MonthPicker,
WeekPicker,
RangePicker,
QuarterPicker,
} from './date-picker';
export type { DescriptionsProps } from './descriptions';
export { default as Descriptions, DescriptionsItem } from './descriptions';

View File

@ -17,9 +17,10 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
const RangePicker = defineComponent<RangePickerProps<DateType>>({
name: 'ARangePicker',
inheritAttrs: false,
props: ['size', 'prefixCls', 'direction', 'getPopupContainer', 'locale'] as any,
props: ['size', 'prefixCls', 'direction', 'getPopupContainer', 'locale', 'value'] as any,
slots: ['suffixIcon'],
setup(props, { expose, slots, attrs }) {
emits: ['change', 'panelChange', 'ok', 'openChange', 'update:value', 'calendarChange'],
setup(props, { expose, slots, attrs, emit }) {
const { prefixCls, direction, getPopupContainer, size, rootPrefixCls } = useConfigInject(
'picker',
props,
@ -33,6 +34,10 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
pickerRef.value?.blur();
},
});
const onChange = (dates: [DateType, DateType], dateStrings: [string, string]) => {
emit('update:value', dates);
emit('change', dates, dateStrings);
};
const [contextLocale] = useLocaleReceiver('DatePicker', enUS);
return () => {
const locale = { ...contextLocale.value, ...props.locale };
@ -88,6 +93,7 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
superNextIcon={<span class={`${pre}-super-next-icon`} />}
components={Components}
direction={direction.value}
onChange={onChange}
/>
);
};

View File

@ -23,9 +23,10 @@ export default function generatePicker<DateType>(generateConfig: GenerateConfig<
return defineComponent<InnerPickerProps>({
name: displayName,
inheritAttrs: false,
props: ['size', 'prefixCls', 'direction', 'getPopupContainer', 'locale'] as any,
props: ['size', 'prefixCls', 'direction', 'getPopupContainer', 'locale', 'value'] as any,
slots: ['suffixIcon'],
setup(props, { slots, expose, attrs }) {
emits: ['change', 'panelChange', 'ok', 'openChange', 'update:value'],
setup(props, { slots, expose, attrs, emit }) {
const { prefixCls, direction, getPopupContainer, size, rootPrefixCls } = useConfigInject(
'picker',
props,
@ -39,6 +40,11 @@ export default function generatePicker<DateType>(generateConfig: GenerateConfig<
pickerRef.value?.blur();
},
});
const onChange = (date: DateType, dateString: string) => {
emit('update:value', date);
emit('change', date, dateString);
};
const [contextLocale] = useLocaleReceiver('DatePicker', enUS);
return () => {
const locale = { ...contextLocale.value, ...props.locale };
@ -47,14 +53,11 @@ export default function generatePicker<DateType>(generateConfig: GenerateConfig<
bordered = true,
placeholder,
suffixIcon = slots.suffixIcon?.(),
showToday = true,
...restProps
} = p;
const { format, showTime } = p as any;
const additionalProps = {
showToday: true,
};
let additionalOverrideProps: any = {};
if (picker) {
additionalOverrideProps.picker = picker;
@ -80,9 +83,9 @@ export default function generatePicker<DateType>(generateConfig: GenerateConfig<
clearIcon={<CloseCircleFilled />}
allowClear
transitionName={`${rootPrefixCls.value}-slide-up`}
{...additionalProps}
{...restProps}
{...additionalOverrideProps}
showToday={showToday}
locale={locale!.lang}
class={classNames(
{
@ -100,6 +103,7 @@ export default function generatePicker<DateType>(generateConfig: GenerateConfig<
superNextIcon={<span class={`${pre}-super-next-icon`} />}
components={Components}
direction={direction.value}
onChange={onChange}
/>
);
};

View File

@ -1,6 +1,6 @@
import type { Moment } from 'moment';
import { App } from 'vue';
import momentGenerateConfig from '../vc-picker/generate/moment';
import { withInstall } from '../_util/type';
import type {
PickerProps,
PickerDateProps,
@ -15,4 +15,21 @@ export type RangePickerProps = BaseRangePickerProps<Moment>;
const DatePicker = generatePicker<Moment>(momentGenerateConfig);
export default withInstall(DatePicker);
const RangePicker = DatePicker.RangePicker;
const MonthPicker = DatePicker.MonthPicker;
const WeekPicker = DatePicker.WeekPicker;
const QuarterPicker = DatePicker.QuarterPicker;
/* istanbul ignore next */
DatePicker.install = function (app: App) {
app.component(DatePicker.name, DatePicker);
app.component(RangePicker.name, RangePicker);
app.component(MonthPicker.name, MonthPicker);
app.component(WeekPicker.name, WeekPicker);
app.component(QuarterPicker.name, QuarterPicker);
return app;
};
export { RangePicker, WeekPicker, MonthPicker, QuarterPicker };
export default DatePicker as typeof DatePicker & Plugin;

View File

@ -90,6 +90,7 @@ export type PickerSharedProps<DateType> = {
autocomplete?: string;
direction?: 'ltr' | 'rtl';
showToday?: boolean;
} & HtmlHTMLAttributes;
type OmitPanelProps<Props> = Omit<
@ -173,6 +174,7 @@ function Picker<DateType>() {
'onSelect',
'direction',
'autocomplete',
'showToday',
] as any,
slots: [
'suffixIcon',
@ -440,6 +442,7 @@ function Picker<DateType>() {
const panelProps = {
// Remove `picker` & `format` here since TimePicker is little different with other panel
...(props as Omit<MergedPickerProps<DateType>, 'picker' | 'format'>),
...attrs,
pickerValue: undefined,
onPickerValueChange: undefined,
onChange: null,
@ -538,7 +541,7 @@ function Picker<DateType>() {
<div
class={classNames(prefixCls, attrs.class, {
[`${prefixCls}-disabled`]: disabled,
[`${prefixCls}-focused`]: focused,
[`${prefixCls}-focused`]: focused.value,
[`${prefixCls}-rtl`]: direction === 'rtl',
})}
style={attrs.style}
@ -562,7 +565,7 @@ function Picker<DateType>() {
readonly={
inputReadOnly || typeof formatList.value[0] === 'function' || !typing.value
}
value={hoverValue || text}
value={hoverValue.value || text.value}
onChange={(e: ChangeEvent) => {
triggerTextChange(e.target.value);
}}

View File

@ -122,35 +122,35 @@ function PickerPanel<DateType>() {
return defineComponent<MergedPickerPanelProps<DateType>>({
name: 'PickerPanel',
inheritAttrs: false,
props: [
'prefixCls',
'locale',
'generateConfig',
'value',
'defaultValue',
'pickerValue',
'defaultPickerValue',
'disabledDate',
'mode',
{ picker: { default: 'date' } },
{ tabindex: { default: 0 } },
'showNow',
'showTime',
'showToday',
'renderExtraFooter',
'hideHeader',
'onSelect',
'onChange',
'onPanelChange',
'onMousedown',
'onPickerValueChange',
'onOk',
'components',
'direction',
{ hourStep: { default: 1 } },
{ minuteStep: { default: 1 } },
{ secondStep: { default: 1 } },
] as any,
props: {
prefixCls: String,
locale: Object,
generateConfig: Object,
value: Object,
defaultValue: Object,
pickerValue: Object,
defaultPickerValue: Object,
disabledDate: Function,
mode: String,
picker: String,
tabindex: [Number, String],
showNow: Boolean,
showTime: Boolean,
showToday: Boolean,
renderExtraFooter: Function,
hideHeader: Boolean,
onSelect: Function,
onChange: Function,
onPanelChange: Function,
onMousedown: Function,
onPickerValueChange: Function,
onOk: Function,
components: Object,
direction: String,
hourStep: { type: Number, default: 1 },
minuteStep: { type: Number, default: 1 },
secondStep: { type: Number, default: 1 },
} as any,
setup(props, { attrs }) {
const needConfirmButton = computed(
() => (props.picker === 'date' && !!props.showTime) || props.picker === 'time',
@ -197,7 +197,7 @@ function PickerPanel<DateType>() {
value: toRef(props, 'value'),
defaultValue: props.defaultValue,
postState: val => {
if (!val && defaultOpenValue.value && props.picker === 'time') {
if (!val && defaultOpenValue?.value && props.picker === 'time') {
return defaultOpenValue.value;
}
return val;
@ -534,7 +534,7 @@ function PickerPanel<DateType>() {
let extraFooter: VueNode;
let rangesNode: VueNode;
if (!hideRanges) {
if (!hideRanges?.value) {
extraFooter = getExtraFooter(prefixCls, mergedMode.value, renderExtraFooter);
rangesNode = getRanges({
prefixCls,

View File

@ -31,7 +31,12 @@ export const useProvideRange = (props: RangeContextProps) => {
};
export const useInjectRange = () => {
return inject(RangeContextKey);
return inject(RangeContextKey, {
rangedValue: ref(),
hoverRangedValue: ref(),
inRange: ref(),
panelPosition: ref(),
});
};
export const RangeContextProvider = defineComponent({

View File

@ -823,7 +823,7 @@ function RangerPicker<DateType>() {
{...panelProps}
dateRender={panelDateRender}
showTime={panelShowTime}
mode={mergedModes[mergedActivePickerIndex.value]}
mode={mergedModes.value[mergedActivePickerIndex.value]}
generateConfig={generateConfig}
style={undefined}
direction={direction}
@ -859,7 +859,7 @@ function RangerPicker<DateType>() {
let viewDate = date;
if (
panelPosition === 'right' &&
mergedModes[mergedActivePickerIndex.value] === newMode
mergedModes.value[mergedActivePickerIndex.value] === newMode
) {
viewDate = getClosingViewDate(viewDate, newMode as any, generateConfig, -1);
}
@ -958,7 +958,7 @@ function RangerPicker<DateType>() {
let panels: VueNode;
const extraNode = getExtraFooter(
prefixCls,
mergedModes[mergedActivePickerIndex.value],
mergedModes.value[mergedActivePickerIndex.value],
renderExtraFooter,
);
@ -987,7 +987,7 @@ function RangerPicker<DateType>() {
? startViewDate.value
: endViewDate.value;
const nextViewDate = getClosingViewDate(viewDate, picker, generateConfig);
const currentMode = mergedModes[mergedActivePickerIndex.value];
const currentMode = mergedModes.value[mergedActivePickerIndex.value];
const showDoublePanel = currentMode === picker;
const leftPanel = renderPanel(showDoublePanel ? 'left' : false, {

View File

@ -45,7 +45,7 @@ export default function useRangeDisabled<DateType>(
}
const disabledStartDate = (date: DateType) => {
if (disabledDate && disabledDate.value(date)) {
if (disabledDate && disabledDate?.value?.(date)) {
return true;
}

View File

@ -27,7 +27,7 @@ export default function useValueTexts<DateType>(
const fullValueTexts: string[] = [];
for (let i = 0; i < formatList.value.length; i += 1) {
const format = formatList[i];
const format = formatList.value[i];
const formatStr = formatValue(value.value, {
generateConfig: generateConfig.value,
locale: locale.value,

View File

@ -1,18 +1,22 @@
<template>
<a-space direction="vertical">
<a-date-picker v-model:value="value1" />
<!-- <a-date-picker v-model:value="value1" /> -->
<!-- <a-month-picker v-model:value="value2" placeholder="Select month" />
<a-range-picker v-model:value="value3" />
<a-week-picker v-model:value="value4" placeholder="Select week" /> -->
<a-range-picker v-model:value="value3" />
</a-space>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { defineComponent, ref, watch } from 'vue';
import { Moment } from 'moment';
export default defineComponent({
setup() {
const value1 = ref<Moment>();
watch(value1, () => {
console.log(value1);
});
return {
value1: ref<Moment>(),
value1,
value2: ref<Moment>(),
value3: ref<Moment[]>([]),
value4: ref<Moment>(),