diff --git a/packages/components/date-picker/demo/OverlayRender.md b/packages/components/date-picker/demo/OverlayRender.md
new file mode 100644
index 000000000..2671ec9b7
--- /dev/null
+++ b/packages/components/date-picker/demo/OverlayRender.md
@@ -0,0 +1,14 @@
+---
+title:
+ zh: 自定义面板
+ en: Custom Panel
+order: 7
+---
+
+## zh
+
+使用 `overlayRender` 自定义面板渲染
+
+## en
+
+Customize overlay panel with `overlayRender` prop。
diff --git a/packages/components/date-picker/demo/OverlayRender.vue b/packages/components/date-picker/demo/OverlayRender.vue
new file mode 100644
index 000000000..c6ce2210c
--- /dev/null
+++ b/packages/components/date-picker/demo/OverlayRender.vue
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
diff --git a/packages/components/date-picker/index.ts b/packages/components/date-picker/index.ts
index d17d8270a..255950dcd 100644
--- a/packages/components/date-picker/index.ts
+++ b/packages/components/date-picker/index.ts
@@ -37,4 +37,5 @@ export type {
DateRangePanelInstance,
DateRangePanelComponent,
DateRangePanelPublicProps as DateRangePanelProps,
+ DatePickerType,
} from './src/types'
diff --git a/packages/components/date-picker/src/composables/useActiveValue.ts b/packages/components/date-picker/src/composables/useActiveValue.ts
index a4444aa2a..d4e2ec868 100644
--- a/packages/components/date-picker/src/composables/useActiveValue.ts
+++ b/packages/components/date-picker/src/composables/useActiveValue.ts
@@ -56,14 +56,37 @@ export function useRangeActiveValue(
const { set, get } = dateConfig
const now = dateConfig.now()
+ const viewType = computed(() => viewTypeMap[props.type])
+ const viewSpan = computed(() => (props.type === 'year' ? 12 : 1))
+
const fromPanelValue = computed(() => panelValue.value?.[0])
const toPanelValue = computed(() => panelValue.value?.[1])
+ // check if the panel view value provided by params is valid
+ const checkActiveDateValid = (from: Date | undefined, to: Date | undefined) => {
+ if (!from || !to) {
+ return false
+ }
+
+ const fromViewValue = get(from, viewType.value)
+ const toViewValue = get(to, viewType.value)
+
+ /* eslint-disable indent */
+ return props.type === 'year'
+ ? fromViewValue < toViewValue - viewSpan.value
+ : (() => {
+ const fromViewYearValue = get(from, 'year')
+ const toViewYearValue = get(to, 'year')
+
+ return fromViewValue < toViewValue && fromViewYearValue <= toViewYearValue
+ })()
+ /* eslint-enable indent */
+ }
+
+ // calculate valid active date based on given `from` and `to` active panel view value
const calcValidActiveDate = (from: Date | undefined, to: Date | undefined, type: 'from' | 'to') => {
- const viewType = viewTypeMap[props.type]
- const viewSpan = props.type === 'year' ? 12 : 1
const getViewDate = (value: Date) =>
- set(value, get(value, viewType) + (type === 'from' ? -viewSpan : viewSpan), viewType)
+ set(value, get(value, viewType.value) + (type === 'from' ? -viewSpan.value : viewSpan.value), viewType.value)
if (!from) {
return type === 'from' ? now : getViewDate(now)
@@ -73,21 +96,7 @@ export function useRangeActiveValue(
return type === 'from' ? from : getViewDate(from)
}
- const fromViewValue = get(from, viewType)
- const toViewValue = get(to, viewType)
-
- /* eslint-disable indent */
- const valid =
- props.type === 'year'
- ? fromViewValue < toViewValue - viewSpan
- : (() => {
- const fromViewYearValue = get(from, 'year')
- const toViewYearValue = get(to, 'year')
-
- return fromViewValue < toViewValue && fromViewYearValue <= toViewYearValue
- })()
- /* eslint-disable indent */
-
+ const valid = checkActiveDateValid(from, to)
if (type === 'from') {
return valid ? from : getViewDate(to)
}
@@ -118,7 +127,9 @@ export function useRangeActiveValue(
activeDate => yearValue === get(activeDate.value, 'year') && monthValue === get(activeDate.value, 'month'),
)
})
- if (valueAlreadyInView) {
+
+ // no need to reset panel view when current range is covered within panel view and panel view is valid
+ if (valueAlreadyInView && checkActiveDateValid(fromActiveValue.value, toActiveValue.value)) {
return
}
@@ -132,8 +143,8 @@ export function useRangeActiveValue(
const fromActiveValue = computed(() => activeValue.value[0])
const toActiveValue = computed(() => activeValue.value[1])
- watch(panelValue, initActiveDate)
- watch(() => props.visible, initActiveDate)
+ // reset panel active value when value, picker type, or visible state changes
+ watch([panelValue, () => props.visible, () => props.type], initActiveDate)
const handleFromActiveValueUpdate = (value: Date) => {
setActiveValue([value, calcValidActiveDate(value, toActiveValue.value, 'to')])
diff --git a/packages/components/date-picker/src/composables/usePickerState.ts b/packages/components/date-picker/src/composables/usePickerState.ts
index ae4d4070f..27eb43a2d 100644
--- a/packages/components/date-picker/src/composables/usePickerState.ts
+++ b/packages/components/date-picker/src/composables/usePickerState.ts
@@ -48,8 +48,8 @@ export function usePickerState
? oldValue.map(v => convertToDate(dateConfig, v, formatRef.value))
: convertToDate(dateConfig, oldValue, formatRef.value)
) as StateValueType
- callEmit(props.onChange as (value: StateValueType, oldValue: StateValueType) => void, newValue, oldValue)
accessor.setValue(value)
+ callEmit(props.onChange as (value: StateValueType, oldValue: StateValueType) => void, newValue, oldValue)
}
function handleClear(evt: Event) {
@@ -60,9 +60,9 @@ export function usePickerState
: convertToDate(dateConfig, oldValue, formatRef.value)
) as StateValueType
+ accessor.setValue(undefined)
callEmit(props.onClear, evt as MouseEvent)
callEmit(props.onChange as (value: StateValueType, oldValue: StateValueType) => void, undefined, oldValue)
- accessor.setValue(undefined)
}
function handleFocus(evt: FocusEvent) {
@@ -71,8 +71,8 @@ export function usePickerState
}
function handleBlur(evt: FocusEvent) {
- callEmit(props.onBlur, evt)
accessor.markAsBlurred()
+ callEmit(props.onBlur, evt)
setFocused(false)
}