refactor: picker

pull/4499/head
tangjinzhou 2021-07-21 17:59:50 +08:00
parent 59085a1990
commit 229f6421ad
5 changed files with 114 additions and 89 deletions

View File

@ -23,7 +23,16 @@ export default function generatePicker<DateType>(generateConfig: GenerateConfig<
return defineComponent<InnerPickerProps>({ return defineComponent<InnerPickerProps>({
name: displayName, name: displayName,
inheritAttrs: false, inheritAttrs: false,
props: ['size', 'prefixCls', 'direction', 'getPopupContainer', 'locale', 'value'] as any, props: [
'size',
'prefixCls',
'direction',
'getPopupContainer',
'locale',
'value',
'showTime',
'showNow',
] as any,
slots: ['suffixIcon'], slots: ['suffixIcon'],
emits: ['change', 'panelChange', 'ok', 'openChange', 'update:value'], emits: ['change', 'panelChange', 'ok', 'openChange', 'update:value'],
setup(props, { slots, expose, attrs, emit }) { setup(props, { slots, expose, attrs, emit }) {
@ -56,7 +65,8 @@ export default function generatePicker<DateType>(generateConfig: GenerateConfig<
showToday = true, showToday = true,
...restProps ...restProps
} = p; } = p;
const { format, showTime } = p as any; const showTime = p.showTime === '' ? true : p.showTime;
const { format } = p as any;
let additionalOverrideProps: any = {}; let additionalOverrideProps: any = {};
if (picker) { if (picker) {
@ -66,7 +76,13 @@ export default function generatePicker<DateType>(generateConfig: GenerateConfig<
additionalOverrideProps = { additionalOverrideProps = {
...additionalOverrideProps, ...additionalOverrideProps,
...(showTime ? getTimeProps({ format, picker: mergedPicker, ...showTime }) : {}), ...(showTime
? getTimeProps({
format,
picker: mergedPicker,
...(typeof showTime === 'object' ? showTime : {}),
})
: {}),
...(mergedPicker === 'time' ...(mergedPicker === 'time'
? getTimeProps({ format, ...p, picker: mergedPicker }) ? getTimeProps({ format, ...p, picker: mergedPicker })
: {}), : {}),

View File

@ -91,6 +91,7 @@ export type PickerSharedProps<DateType> = {
autocomplete?: string; autocomplete?: string;
direction?: 'ltr' | 'rtl'; direction?: 'ltr' | 'rtl';
showToday?: boolean; showToday?: boolean;
showTime?: boolean | undefined | object;
} & HtmlHTMLAttributes; } & HtmlHTMLAttributes;
type OmitPanelProps<Props> = Omit< type OmitPanelProps<Props> = Omit<

View File

@ -134,8 +134,8 @@ function PickerPanel<DateType>() {
mode: String, mode: String,
picker: { type: String, default: 'date' }, picker: { type: String, default: 'date' },
tabindex: { type: [Number, String], default: 0 }, tabindex: { type: [Number, String], default: 0 },
showNow: Boolean, showNow: { type: Boolean, default: undefined },
showTime: Boolean, showTime: [Boolean, Object],
showToday: Boolean, showToday: Boolean,
renderExtraFooter: Function, renderExtraFooter: Function,
hideHeader: Boolean, hideHeader: Boolean,

View File

@ -3,6 +3,7 @@ import { useInjectPanel } from '../../PanelContext';
import classNames from '../../../_util/classNames'; import classNames from '../../../_util/classNames';
import { ref } from '@vue/reactivity'; import { ref } from '@vue/reactivity';
import { onBeforeUnmount, watch } from '@vue/runtime-core'; import { onBeforeUnmount, watch } from '@vue/runtime-core';
import { defineComponent } from 'vue';
export type Unit = { export type Unit = {
label: any; label: any;
@ -19,79 +20,79 @@ export type TimeUnitColumnProps = {
onSelect?: (value: number) => void; onSelect?: (value: number) => void;
}; };
function TimeUnitColumn(props: TimeUnitColumnProps) { export default defineComponent<TimeUnitColumnProps>({
const { prefixCls, units, onSelect, value, active, hideDisabledOptions } = props; name: 'TimeUnitColumn',
const cellPrefixCls = `${prefixCls}-cell`; props: ['prefixCls', 'units', 'onSelect', 'value', 'active', 'hideDisabledOptions'] as any,
const { open } = useInjectPanel(); setup(props) {
const { open } = useInjectPanel();
const ulRef = ref<HTMLUListElement>(null); const ulRef = ref<HTMLUListElement>(null);
const liRefs = ref<Map<number, HTMLElement | null>>(new Map()); const liRefs = ref<Map<number, HTMLElement | null>>(new Map());
const scrollRef = ref<Function>(); const scrollRef = ref<Function>();
watch( watch(
() => props.value, () => props.value,
() => { () => {
const li = liRefs.value.get(value!); const li = liRefs.value.get(props.value!);
if (li && open.value !== false) { if (li && open.value !== false) {
scrollTo(ulRef.value!, li.offsetTop, 120); scrollTo(ulRef.value!, li.offsetTop, 120);
}
},
);
onBeforeUnmount(() => {
scrollRef.value?.();
});
watch(open, () => {
scrollRef.value?.();
if (open.value) {
const li = liRefs.value.get(value!);
if (li) {
scrollRef.value = waitElementReady(li, () => {
scrollTo(ulRef.value!, li.offsetTop, 0);
});
}
}
});
return (
<ul
class={classNames(`${prefixCls}-column`, {
[`${prefixCls}-column-active`]: active,
})}
ref={ulRef}
style={{ position: 'relative' }}
>
{units!.map(unit => {
if (hideDisabledOptions && unit.disabled) {
return null;
} }
},
);
onBeforeUnmount(() => {
scrollRef.value?.();
});
return ( watch(open, () => {
<li scrollRef.value?.();
key={unit.value} if (open.value) {
ref={element => { const li = liRefs.value.get(props.value!);
liRefs.value.set(unit.value, element as HTMLElement); if (li) {
}} scrollRef.value = waitElementReady(li, () => {
class={classNames(cellPrefixCls, { scrollTo(ulRef.value!, li.offsetTop, 0);
[`${cellPrefixCls}-disabled`]: unit.disabled, });
[`${cellPrefixCls}-selected`]: value === unit.value, }
})} }
onClick={() => { });
if (unit.disabled) { return () => {
return; const { prefixCls, units, onSelect, value, active, hideDisabledOptions } = props;
} const cellPrefixCls = `${prefixCls}-cell`;
onSelect!(unit.value); return (
}} <ul
> class={classNames(`${prefixCls}-column`, {
<div class={`${cellPrefixCls}-inner`}>{unit.label}</div> [`${prefixCls}-column-active`]: active,
</li> })}
); ref={ulRef}
})} style={{ position: 'relative' }}
</ul> >
); {units!.map(unit => {
} if (hideDisabledOptions && unit.disabled) {
return null;
}
TimeUnitColumn.displayName = 'TimeUnitColumn'; return (
TimeUnitColumn.inheritAttrs = false; <li
key={unit.value}
export default TimeUnitColumn; ref={element => {
liRefs.value.set(unit.value, element as HTMLElement);
}}
class={classNames(cellPrefixCls, {
[`${cellPrefixCls}-disabled`]: unit.disabled,
[`${cellPrefixCls}-selected`]: value === unit.value,
})}
onClick={() => {
if (unit.disabled) {
return;
}
onSelect!(unit.value);
}}
>
<div class={`${cellPrefixCls}-inner`}>{unit.label}</div>
</li>
);
})}
</ul>
);
};
},
});

View File

@ -1,25 +1,32 @@
<template> <template>
<a-space direction="vertical"> <a-space direction="vertical">
<!-- <a-date-picker v-model:value="value1" /> --> <a-date-picker show-time placeholder="Select Time" @change="onChange" @ok="onOk" />
<!-- <a-month-picker v-model:value="value2" placeholder="Select month" /> <a-range-picker
<a-week-picker v-model:value="value4" placeholder="Select week" /> --> :show-time="{ format: 'HH:mm' }"
<a-range-picker v-model:value="value3" /> format="YYYY-MM-DD HH:mm"
:placeholder="['Start Time', 'End Time']"
@change="onChange"
@ok="onOk"
/>
</a-space> </a-space>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, ref, watch } from 'vue';
import { Moment } from 'moment'; import { Moment } from 'moment';
import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
setup() { setup() {
const value1 = ref<Moment>(); const onChange = (value: Moment[], dateString: string[]) => {
watch(value1, () => { console.log('Selected Time: ', value);
console.log(value1); console.log('Formatted Selected Time: ', dateString);
}); };
const onOk = (value: Moment[]) => {
console.log('onOk: ', value);
};
return { return {
value1, onChange,
value2: ref<Moment>(), onOk,
value3: ref<Moment[]>([]),
value4: ref<Moment>(),
}; };
}, },
}); });