{
e.preventDefault();
}}
diff --git a/components/vc-picker/PickerPanel.tsx b/components/vc-picker/PickerPanel.tsx
index 1ce896e68..8677db201 100644
--- a/components/vc-picker/PickerPanel.tsx
+++ b/components/vc-picker/PickerPanel.tsx
@@ -186,7 +186,6 @@ function PickerPanel
() {
const panelContext = useInjectPanel();
const {
operationRef,
- panelRef: panelDivRef,
onSelect: onContextSelect,
hideRanges,
defaultOpenValue,
@@ -601,7 +600,6 @@ function PickerPanel() {
onKeydown={onInternalKeydown}
onBlur={onInternalBlur}
onMousedown={onMousedown}
- ref={panelDivRef}
>
{panelNode}
{extraFooter || rangesNode || todayNode ? (
diff --git a/components/vc-picker/PresetPanel.tsx b/components/vc-picker/PresetPanel.tsx
new file mode 100644
index 000000000..7ee01bef8
--- /dev/null
+++ b/components/vc-picker/PresetPanel.tsx
@@ -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 (
+
+
+ {props.presets.map(({ label, value }, index) => (
+ - {
+ props.onClick(value);
+ }}
+ onMouseenter={() => {
+ props.onHover?.(value);
+ }}
+ onMouseleave={() => {
+ props.onHover?.(null);
+ }}
+ >
+ {label}
+
+ ))}
+
+
+ );
+ };
+ },
+});
diff --git a/components/vc-picker/RangePicker.tsx b/components/vc-picker/RangePicker.tsx
index 4f8b11cc0..d497b9511 100644
--- a/components/vc-picker/RangePicker.tsx
+++ b/components/vc-picker/RangePicker.tsx
@@ -1,9 +1,17 @@
-import type { DisabledTimes, PanelMode, PickerMode, RangeValue, EventValue } from './interface';
+import type {
+ DisabledTimes,
+ PanelMode,
+ PickerMode,
+ RangeValue,
+ EventValue,
+ PresetDate,
+} from './interface';
import type { PickerBaseProps, PickerDateProps, PickerTimeProps } from './Picker';
import type { SharedTimeProps } from './panels/TimePanel';
import PickerTrigger from './PickerTrigger';
import PickerPanel from './PickerPanel';
import usePickerInput from './hooks/usePickerInput';
+import PresetPanel from './PresetPanel';
import getDataOrAriaProps, { toArray, getValue, updateValues } from './utils/miscUtil';
import { getDefaultFormat, getInputSize, elementsContains } from './utils/uiUtil';
import type { ContextOperationRefProps } from './PanelContext';
@@ -19,6 +27,7 @@ import {
} from './utils/dateUtil';
import useValueTexts from './hooks/useValueTexts';
import useTextValueMapping from './hooks/useTextValueMapping';
+import usePresets from './hooks/usePresets';
import type { GenerateConfig } from './generate';
import type { PickerPanelProps } from '.';
import { RangeContextProvider } from './RangeContext';
@@ -91,6 +100,8 @@ export type RangePickerSharedProps = {
placeholder?: [string, string];
disabled?: boolean | [boolean, boolean];
disabledTime?: (date: EventValue, type: RangeType) => DisabledTimes;
+ presets?: PresetDate>[];
+ /** @deprecated Please use `presets` instead */
ranges?: Record<
string,
Exclude, null> | (() => Exclude, null>)
@@ -139,6 +150,7 @@ type OmitPickerProps = Omit<
| 'onPickerValueChange'
| 'onOk'
| 'dateRender'
+ | 'presets'
>;
type RangeShowTimeObject = Omit, 'defaultValue'> & {
@@ -238,13 +250,17 @@ function RangerPicker() {
'secondStep',
'hideDisabledOptions',
'disabledMinutes',
+ 'presets',
] as any,
setup(props, { attrs, expose }) {
const needConfirmButton = computed(
() => (props.picker === 'date' && !!props.showTime) || props.picker === 'time',
);
const getPortal = useProviderTrigger();
- // We record opened status here in case repeat open with picker
+ const presets = computed(() => props.presets);
+ const ranges = computed(() => props.ranges);
+ const presetList = usePresets(presets, ranges);
+ // We record oqqpened status here in case repeat open with picker
const openRecordsRef = ref>({});
const containerRef = ref(null);
@@ -830,28 +846,6 @@ function RangerPicker() {
},
});
- // ============================ Ranges =============================
-
- const rangeList = computed(() =>
- Object.keys(props.ranges || {}).map(label => {
- const range = props.ranges![label];
- const newValues = typeof range === 'function' ? range() : range;
-
- return {
- label,
- onClick: () => {
- triggerChange(newValues, null);
- triggerOpen(false, mergedActivePickerIndex.value);
- },
- onMouseenter: () => {
- setRangeHoverValue(newValues);
- },
- onMouseleave: () => {
- setRangeHoverValue(null);
- },
- };
- }),
- );
// ============================= Panel =============================
const panelHoverRangedValue = computed(() => {
if (
@@ -1044,7 +1038,6 @@ function RangerPicker() {
!getValue(selectedValue.value, mergedActivePickerIndex.value) ||
(disabledDate && disabledDate(selectedValue.value[mergedActivePickerIndex.value])),
locale,
- rangeList: rangeList.value,
onOk: () => {
if (getValue(selectedValue.value, mergedActivePickerIndex.value)) {
// triggerChangeOld(selectedValue.value);
@@ -1099,15 +1092,28 @@ function RangerPicker() {
}
let mergedNodes: VueNode = (
- <>
- {panels}
- {(extraNode || rangesNode) && (
-
- )}
- >
+
+
{
+ triggerChange(nextValue, null);
+ triggerOpen(false, mergedActivePickerIndex.value);
+ }}
+ onHover={hoverValue => {
+ setRangeHoverValue(hoverValue);
+ }}
+ />
+
+
{panels}
+ {(extraNode || rangesNode) && (
+
+ )}
+
+
);
if (panelRender) {
diff --git a/components/vc-picker/hooks/usePresets.ts b/components/vc-picker/hooks/usePresets.ts
new file mode 100644
index 000000000..9f2c4861c
--- /dev/null
+++ b/components/vc-picker/hooks/usePresets.ts
@@ -0,0 +1,30 @@
+import type { ComputedRef } from 'vue';
+import { computed } from 'vue';
+
+import warning from 'ant-design-vue/es/vc-util/warning';
+import type { PresetDate } from '../interface';
+
+export default function usePresets(
+ presets?: ComputedRef[]>,
+ legacyRanges?: ComputedRef T)>>,
+): ComputedRef[]> {
+ if (presets.value) {
+ return presets;
+ }
+ if (legacyRanges && legacyRanges.value) {
+ warning(false, '`ranges` is deprecated. Please use `presets` instead.');
+
+ return computed(() => {
+ const rangeLabels = Object.keys(legacyRanges.value);
+ return rangeLabels.map(label => {
+ const range = legacyRanges.value[label];
+ const newValues = typeof range === 'function' ? (range as any)() : range;
+ return {
+ label,
+ value: newValues,
+ };
+ });
+ });
+ }
+ return [] as unknown as ComputedRef[]>;
+}
diff --git a/components/vc-picker/interface.ts b/components/vc-picker/interface.ts
index fc710d812..58b7106da 100644
--- a/components/vc-picker/interface.ts
+++ b/components/vc-picker/interface.ts
@@ -98,14 +98,18 @@ export type RangeValue = [EventValue, EventValue]
export type Components = {
button?: any;
- rangeItem?: any;
};
export type RangeList = {
- label: string;
+ label: VueNode;
onClick: () => void;
onMouseenter: () => void;
onMouseleave: () => void;
}[];
export type CustomFormat = (value: DateType) => string;
+
+export interface PresetDate {
+ label: VueNode;
+ value: T;
+}
diff --git a/components/vc-picker/utils/getRanges.tsx b/components/vc-picker/utils/getRanges.tsx
index 5f1e68ce4..e6a200a72 100644
--- a/components/vc-picker/utils/getRanges.tsx
+++ b/components/vc-picker/utils/getRanges.tsx
@@ -1,9 +1,8 @@
import type { VueNode } from '../../_util/type';
-import type { Components, RangeList, Locale } from '../interface';
+import type { Components, Locale } from '../interface';
export type RangesProps = {
prefixCls: string;
- rangeList?: RangeList;
components?: Components;
needConfirmButton: boolean;
onNow?: null | (() => void) | false;
@@ -15,7 +14,6 @@ export type RangesProps = {
export default function getRanges({
prefixCls,
- rangeList = [],
components = {},
needConfirmButton,
onNow,
@@ -27,26 +25,10 @@ export default function getRanges({
let presetNode: VueNode;
let okNode: VueNode;
- if (rangeList.length) {
- const Item = (components.rangeItem || 'span') as any;
-
- presetNode = (
- <>
- {rangeList.map(({ label, onClick, onMouseenter, onMouseleave }) => (
-
- -
- {label}
-
-
- ))}
- >
- );
- }
-
if (needConfirmButton) {
const Button = (components.button || 'button') as any;
- if (onNow && !presetNode && showNow !== false) {
+ if (onNow && showNow !== false) {
presetNode = (