From d484e1f6a098fa9c85d2c92c842bc56d2c5e2af8 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Mon, 7 Nov 2022 15:23:24 +0800 Subject: [PATCH] fix: rangePicker popup pos, close #6073, #6074 --- components/vc-picker/RangePicker.tsx | 78 +++++++++++++++++----------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/components/vc-picker/RangePicker.tsx b/components/vc-picker/RangePicker.tsx index 46f64577c..4f8b11cc0 100644 --- a/components/vc-picker/RangePicker.tsx +++ b/components/vc-picker/RangePicker.tsx @@ -37,6 +37,7 @@ import useState from '../_util/hooks/useState'; import classNames from '../_util/classNames'; import { useProviderTrigger } from '../vc-trigger/context'; import { legacyPropsWarning } from './utils/warnUtil'; +import { useElementSize } from '../_util/hooks/_vueuse/useElementSize'; function reorderValues( values: RangeValue, @@ -372,15 +373,55 @@ function RangerPicker() { const startOpen = computed(() => mergedOpen.value && mergedActivePickerIndex.value === 0); const endOpen = computed(() => mergedOpen.value && mergedActivePickerIndex.value === 1); - + const panelLeft = ref(0); + const arrowLeft = ref(0); // ============================= Popup ============================= // Popup min width const popupMinWidth = ref(0); - watch(mergedOpen, () => { + const { width: containerWidth } = useElementSize(containerRef); + watch([mergedOpen, containerWidth], () => { if (!mergedOpen.value && containerRef.value) { - popupMinWidth.value = containerRef.value.offsetWidth; + popupMinWidth.value = containerWidth.value; } }); + const { width: panelDivWidth } = useElementSize(panelDivRef); + const { width: arrowWidth } = useElementSize(arrowRef); + const { width: startInputDivWidth } = useElementSize(startInputDivRef); + const { width: separatorWidth } = useElementSize(separatorRef); + watch( + [ + mergedActivePickerIndex, + mergedOpen, + panelDivWidth, + arrowWidth, + startInputDivWidth, + separatorWidth, + () => props.direction, + ], + () => { + arrowLeft.value = 0; + if (mergedOpen.value && mergedActivePickerIndex.value) { + if (startInputDivRef.value && separatorRef.value && panelDivRef.value) { + arrowLeft.value = startInputDivWidth.value + separatorWidth.value; + if ( + panelDivWidth.value && + arrowWidth.value && + arrowLeft.value > + panelDivWidth.value - + arrowWidth.value - + (props.direction === 'rtl' || arrowRef.value.offsetLeft > arrowLeft.value + ? 0 + : arrowRef.value.offsetLeft) + ) { + panelLeft.value = arrowLeft.value; + } + } + } else if (mergedActivePickerIndex.value === 0) { + panelLeft.value = 0; + } + }, + { immediate: true }, + ); // ============================ Trigger ============================ const triggerRef = ref(); @@ -981,32 +1022,11 @@ function RangerPicker() { direction, autocomplete = 'off', } = props; - let arrowLeft = 0; - let panelLeft = 0; - if ( - mergedActivePickerIndex.value && - startInputDivRef.value && - separatorRef.value && - panelDivRef.value - ) { - // Arrow offset - arrowLeft = startInputDivRef.value.offsetWidth + separatorRef.value.offsetWidth; - if ( - panelDivRef.value.offsetWidth && - arrowRef.value.offsetWidth && - arrowLeft > - panelDivRef.value.offsetWidth - - arrowRef.value.offsetWidth - - (direction === 'rtl' || arrowRef.value.offsetLeft > arrowLeft - ? 0 - : arrowRef.value.offsetLeft) - ) { - panelLeft = arrowLeft; - } - } const arrowPositionStyle = - direction === 'rtl' ? { right: `${arrowLeft}px` } : { left: `${arrowLeft}px` }; + direction === 'rtl' + ? { right: `${arrowLeft.value}px` } + : { left: `${arrowLeft.value}px` }; function renderPanels() { let panels: VueNode; @@ -1097,7 +1117,7 @@ function RangerPicker() { return (
{ e.preventDefault(); @@ -1168,7 +1188,7 @@ function RangerPicker() { if (mergedActivePickerIndex.value === 0) { activeBarWidth = startInputDivRef.value.offsetWidth; } else { - activeBarLeft = arrowLeft; + activeBarLeft = arrowLeft.value; activeBarWidth = endInputDivRef.value.offsetWidth; } }