Skip to content

Feat(DatePicker): increase presets prop #6387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Apr 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 37 additions & 9 deletions components/date-picker/demo/presetted-ranges.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ We can set presetted ranges to RangePicker to improve user experience.

<template>
<a-space direction="vertical" :size="12">
<a-range-picker v-model:value="value1" :ranges="ranges" />
<a-date-picker :presets="presets" @change="onChange" />
<a-range-picker :presets="rangePresets" @change="onRangeChange" />
<a-range-picker
v-model:value="value2"
style="width: 400px"
:ranges="ranges"
show-time
format="YYYY/MM/DD HH:mm:ss"
:presets="rangePresets"
@change="onRangeChange"
/>
</a-space>
</template>
Expand All @@ -34,13 +35,40 @@ import { defineComponent, ref } from 'vue';
type RangeValue = [Dayjs, Dayjs];
export default defineComponent({
setup() {
const onChange = (date: Dayjs) => {
if (date) {
console.log('Date: ', date);
} else {
console.log('Clear');
}
};
const onRangeChange = (dates: RangeValue, dateStrings: string[]) => {
if (dates) {
console.log('From: ', dates[0], ', to: ', dates[1]);
console.log('From: ', dateStrings[0], ', to: ', dateStrings[1]);
} else {
console.log('Clear');
}
};

const presets = ref([
{ label: 'Yesterday', value: dayjs().add(-1, 'd') },
{ label: 'Last Week', value: dayjs().add(-7, 'd') },
{ label: 'Last Month', value: dayjs().add(-1, 'month') },
]);

const rangePresets = ref([
{ label: 'Last 7 Days', value: [dayjs().add(-7, 'd'), dayjs()] },
{ label: 'Last 14 Days', value: [dayjs().add(-14, 'd'), dayjs()] },
{ label: 'Last 30 Days', value: [dayjs().add(-30, 'd'), dayjs()] },
{ label: 'Last 90 Days', value: [dayjs().add(-90, 'd'), dayjs()] },
]);
return {
value1: ref<RangeValue>(),
value2: ref<RangeValue>(),
ranges: {
Today: [dayjs(), dayjs()] as RangeValue,
'This Month': [dayjs(), dayjs().endOf('month')] as RangeValue,
},
presets,
rangePresets,

onChange,
onRangeChange,
};
},
});
Expand Down
6 changes: 6 additions & 0 deletions components/date-picker/generatePicker/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { CSSProperties } from 'vue';
import type { PickerLocale } from '.';
import type { SizeType } from '../../config-provider';
import type {
PresetDate,
CustomFormat,
DisabledTime,
DisabledTimes,
Expand Down Expand Up @@ -118,6 +119,7 @@ export interface CommonProps<DateType> {
* @deprecated `dropdownClassName` is deprecated which will be removed in next major
* version.Please use `popupClassName` instead.
*/

dropdownClassName?: string;
popupClassName?: string;
popupStyle?: CSSProperties;
Expand Down Expand Up @@ -176,6 +178,7 @@ function datePickerProps<DateType = any>() {
defaultPickerValue: someType<DateType | string>([Object, String]),
defaultValue: someType<DateType | string>([Object, String]),
value: someType<DateType | string>([Object, String]),
presets: arrayType<PresetDate<DateType>[]>(),
disabledTime: functionType<DisabledTime<DateType>>(),
renderExtraFooter: functionType<(mode: PanelMode) => VueNode>(),
showNow: booleanType(),
Expand All @@ -189,6 +192,7 @@ export interface DatePickerProps<DateType> {
defaultPickerValue?: DateType | string;
defaultValue?: DateType | string;
value?: DateType | string;
presets?: PresetDate<DateType>[];
disabledTime?: DisabledTime<DateType>;
renderExtraFooter?: (mode: PanelMode) => VueNode;
showNow?: boolean;
Expand All @@ -204,6 +208,7 @@ function rangePickerProps<DateType>() {
defaultPickerValue: arrayType<RangeValue<DateType> | RangeValue<string>>(),
defaultValue: arrayType<RangeValue<DateType> | RangeValue<string>>(),
value: arrayType<RangeValue<DateType> | RangeValue<string>>(),
presets: arrayType<PresetDate<Array<DateType>>[]>(),
disabledTime: functionType<(date: EventValue<DateType>, type: RangeType) => DisabledTimes>(),
disabled: someType<boolean | [boolean, boolean]>([Boolean, Array]),
renderExtraFooter: functionType<() => VueNode>(),
Expand Down Expand Up @@ -249,6 +254,7 @@ export interface RangePickerProps<DateType> {
defaultPickerValue?: RangeValue<DateType> | RangeValue<string>;
defaultValue?: RangeValue<DateType> | RangeValue<string>;
value?: RangeValue<DateType> | RangeValue<string>;
presets?: PresetDate<RangeValue<DateType>>[];
disabledTime?: (date: EventValue<DateType>, type: RangeType) => DisabledTimes;
disabled?: [boolean, boolean];
renderExtraFooter?: () => VueNode;
Expand Down
2 changes: 2 additions & 0 deletions components/date-picker/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ The following APIs are shared by DatePicker, RangePicker.
| placeholder | The placeholder of date input | string \| \[string,string] | - | |
| placement | The position where the selection box pops up | `bottomLeft` `bottomRight` `topLeft` `topRight` | bottomLeft | 3.3.0 |
| popupStyle | To customize the style of the popup calendar | CSSProperties | {} | |
| presets | The preset ranges for quick selection | { label: slot, value: [dayjs](https://day.js.org/) }[] | - | |
| prevIcon | The custom prev icon | slot | - | 3.0 |
| size | To determine the size of the input box, the height of `large` and `small`, are 40px and 24px respectively, while default size is 32px | `large` \| `middle` \| `small` | - | |
| status | Set validation status | 'error' \| 'warning' | - | 3.3.0 |
Expand Down Expand Up @@ -174,6 +175,7 @@ The following APIs are shared by DatePicker, RangePicker.
| disabled | If disable start or end | \[boolean, boolean] | - | |
| disabledTime | To specify the time that cannot be selected | function(date: dayjs, partial: `start` \| `end`) | - | |
| format | To set the date format, refer to [dayjs](https://day.js.org/) | [formatType](#formatType) | `YYYY-MM-DD HH:mm:ss` | |
| presets | The preset ranges for quick selection | { label: slot, value: [dayjs](https://day.js.org/)\[] }[] | - | |
| ranges | The preseted ranges for quick selection | { \[range: string]: [dayjs](https://day.js.org/)\[] } \| { \[range: string]: () => [dayjs](https://day.js.org/)\[] } | - | |
| renderExtraFooter | Render extra footer in panel | v-slot:renderExtraFooter="mode" | - | |
| separator | Set separator between inputs | string \| v-slot:separator | `<SwapRightOutlined />` | |
Expand Down
2 changes: 2 additions & 0 deletions components/date-picker/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*3OpRQKcygo8AAA
| placement | 选择框弹出的位置 | `bottomLeft` `bottomRight` `topLeft` `topRight` | bottomLeft | 3.3.0 |
| popupStyle | 额外的弹出日历样式 | CSSProperties | {} | |
| prevIcon | 自定义上一个图标 | slot | - | 3.0 |
| presets | 预设时间范围快捷选择 | { label: slot, value: [dayjs](https://day.js.org/) }[] | - | |
| size | 输入框大小,`large` 高度为 40px,`small` 为 24px,默认是 32px | `large` \| `middle` \| `small` | - | |
| status | 设置校验状态 | 'error' \| 'warning' | - | 3.3.0 |
| suffixIcon | 自定义的选择框后缀图标 | v-slot:suffixIcon | - | |
Expand Down Expand Up @@ -175,6 +176,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*3OpRQKcygo8AAA
| disabled | 禁用起始项 | \[boolean, boolean] | - | |
| disabledTime | 不可选择的时间 | function(date: dayjs, partial: `start` \| `end`) | - | |
| format | 展示的日期格式 | [formatType](#formatType) | `YYYY-MM-DD HH:mm:ss` | |
| presets | 预设时间范围快捷选择 | { label: slot, value: [dayjs](https://day.js.org/)\[] }[] | - | |
| ranges | 预设时间范围快捷选择 | { \[range: string]: [dayjs](https://day.js.org/)\[] } \| { \[range: string]: () => [dayjs](https://day.js.org/)\[] } | - | |
| renderExtraFooter | 在面板中添加额外的页脚 | v-slot:renderExtraFooter="mode" | - | |
| separator | 设置分隔符 | string \| v-slot:separator | `<SwapRightOutlined />` | |
Expand Down
55 changes: 36 additions & 19 deletions components/vc-picker/Picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,18 @@ import type {
} from './PickerPanel';
import PickerPanel from './PickerPanel';
import PickerTrigger from './PickerTrigger';
import PresetPanel from './PresetPanel';
import { formatValue, isEqual, parseValue } from './utils/dateUtil';
import getDataOrAriaProps, { toArray } from './utils/miscUtil';
import type { ContextOperationRefProps } from './PanelContext';
import { useProvidePanel } from './PanelContext';
import type { CustomFormat, PickerMode } from './interface';
import type { CustomFormat, PickerMode, PresetDate } from './interface';
import { getDefaultFormat, getInputSize, elementsContains } from './utils/uiUtil';
import usePickerInput from './hooks/usePickerInput';
import useTextValueMapping from './hooks/useTextValueMapping';
import useValueTexts from './hooks/useValueTexts';
import useHoverValue from './hooks/useHoverValue';
import usePresets from './hooks/usePresets';
import type { CSSProperties, HTMLAttributes, Ref } from 'vue';
import { computed, defineComponent, ref, toRef, watch } from 'vue';
import type { ChangeEvent, FocusEventHandler, MouseEventHandler } from '../_util/EventInterface';
Expand Down Expand Up @@ -61,6 +63,8 @@ export type PickerSharedProps<DateType> = {
inputReadOnly?: boolean;
id?: string;

presets?: PresetDate<DateType>[];

// Value
format?: string | CustomFormat<DateType> | (string | CustomFormat<DateType>)[];

Expand Down Expand Up @@ -163,6 +167,7 @@ function Picker<DateType>() {
'defaultOpen',
'defaultOpenValue',
'suffixIcon',
'presets',
'clearIcon',
'disabled',
'disabledDate',
Expand Down Expand Up @@ -203,6 +208,8 @@ function Picker<DateType>() {
// ],
setup(props, { attrs, expose }) {
const inputRef = ref(null);
const presets = computed(() => props.presets);
const presetList = usePresets(presets);
const picker = computed(() => props.picker ?? 'date');
const needConfirmButton = computed(
() => (picker.value === 'date' && !!props.showTime) || picker.value === 'time',
Expand Down Expand Up @@ -408,7 +415,6 @@ function Picker<DateType>() {
useProvidePanel({
operationRef,
hideHeader: computed(() => picker.value === 'time'),
panelRef: panelDivRef,
onSelect: onContextSelect,
open: mergedOpen,
defaultOpenValue: toRef(props, 'defaultOpenValue'),
Expand Down Expand Up @@ -477,23 +483,33 @@ function Picker<DateType>() {
};

let panelNode: VueNode = (
<PickerPanel
{...panelProps}
generateConfig={generateConfig}
value={selectedValue.value}
locale={locale}
tabindex={-1}
onSelect={date => {
onSelect?.(date);
setSelectedValue(date);
}}
direction={direction}
onPanelChange={(viewDate, mode) => {
const { onPanelChange } = props;
onLeave(true);
onPanelChange?.(viewDate, mode);
}}
/>
<div class={`${prefixCls}-panel-layout`}>
<PresetPanel
prefixCls={prefixCls}
presets={presetList.value}
onClick={nextValue => {
triggerChange(nextValue);
triggerOpen(false);
}}
/>
<PickerPanel
{...panelProps}
generateConfig={generateConfig}
value={selectedValue.value}
locale={locale}
tabindex={-1}
onSelect={date => {
onSelect?.(date);
setSelectedValue(date);
}}
direction={direction}
onPanelChange={(viewDate, mode) => {
const { onPanelChange } = props;
onLeave(true);
onPanelChange?.(viewDate, mode);
}}
/>
</div>
);

if (panelRender) {
Expand All @@ -503,6 +519,7 @@ function Picker<DateType>() {
const panel = (
<div
class={`${prefixCls}-panel-container`}
ref={panelDivRef}
onMousedown={e => {
e.preventDefault();
}}
Expand Down
2 changes: 0 additions & 2 deletions components/vc-picker/PickerPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@ function PickerPanel<DateType>() {
const panelContext = useInjectPanel();
const {
operationRef,
panelRef: panelDivRef,
onSelect: onContextSelect,
hideRanges,
defaultOpenValue,
Expand Down Expand Up @@ -601,7 +600,6 @@ function PickerPanel<DateType>() {
onKeydown={onInternalKeydown}
onBlur={onInternalBlur}
onMousedown={onMousedown}
ref={panelDivRef}
>
{panelNode}
{extraFooter || rangesNode || todayNode ? (
Expand Down
43 changes: 43 additions & 0 deletions components/vc-picker/PresetPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { defineComponent } from 'vue';

export default defineComponent({
name: 'PresetPanel',
props: {
prefixCls: String,
presets: {
type: Array,
default: () => [],
},
onClick: Function,
onHover: Function,
},
setup(props) {
return () => {
if (!props.presets.length) {
return null;
}
return (
<div class={`${props.prefixCls}-presets`}>
<ul>
{props.presets.map(({ label, value }, index) => (
<li
key={index}
onClick={() => {
props.onClick(value);
}}
onMouseenter={() => {
props.onHover?.(value);
}}
onMouseleave={() => {
props.onHover?.(null);
}}
>
{label}
</li>
))}
</ul>
</div>
);
};
},
});
Loading