@@ -8,7 +8,6 @@ import type {
88 ValueDate ,
99} from '../../interface' ;
1010import { toArray } from '../../utils/miscUtil' ;
11- import { getRealPlacement , getoffsetUnit } from '../../utils/uiUtil' ;
1211import PickerContext from '../context' ;
1312import Footer , { type FooterProps } from './Footer' ;
1413import PopupPanel , { type PopupPanelProps } from './PopupPanel' ;
@@ -32,8 +31,7 @@ export interface PopupProps<DateType extends object = any, PresetValue = DateTyp
3231 onPresetSubmit : ( presetValue : PresetValue ) => void ;
3332
3433 // Range
35- activeOffset ?: number ;
36- placement ?: string ;
34+ activeInfo ?: [ activeInputLeft : number , activeInputRight : number , selectorWidth : number ] ;
3735 // Direction
3836 direction ?: 'ltr' | 'rtl' ;
3937
@@ -59,8 +57,7 @@ export default function Popup<DateType extends object = any>(props: PopupProps<D
5957 // Range
6058 range,
6159 multiple,
62- activeOffset = 0 ,
63- placement,
60+ activeInfo = [ 0 , 0 , 0 ] ,
6461
6562 // Presets
6663 presets,
@@ -96,28 +93,43 @@ export default function Popup<DateType extends object = any>(props: PopupProps<D
9693 // ======================== Offset ========================
9794 const [ containerWidth , setContainerWidth ] = React . useState < number > ( 0 ) ;
9895 const [ containerOffset , setContainerOffset ] = React . useState < number > ( 0 ) ;
96+ const [ arrowOffset , setArrowOffset ] = React . useState < number > ( 0 ) ;
9997
10098 const onResize : ResizeObserverProps [ 'onResize' ] = ( info ) => {
101- if ( info . offsetWidth ) {
102- setContainerWidth ( info . offsetWidth ) ;
99+ if ( info . width ) {
100+ setContainerWidth ( info . width ) ;
103101 }
104102 } ;
105103
104+ const [ activeInputLeft , activeInputRight , selectorWidth ] = activeInfo ;
105+
106106 React . useEffect ( ( ) => {
107107 // `activeOffset` is always align with the active input element
108108 // So we need only check container contains the `activeOffset`
109- if ( range ) {
109+ if ( range && wrapperRef . current ) {
110110 // Offset in case container has border radius
111111 const arrowWidth = arrowRef . current ?. offsetWidth || 0 ;
112112
113- const maxOffset = containerWidth - arrowWidth ;
114- if ( activeOffset <= maxOffset ) {
115- setContainerOffset ( 0 ) ;
113+ // Arrow Offset
114+ const wrapperRect = wrapperRef . current . getBoundingClientRect ( ) ;
115+ const nextArrowOffset = rtl
116+ ? activeInputRight - arrowWidth
117+ : activeInputLeft - wrapperRect . left ;
118+ setArrowOffset ( nextArrowOffset ) ;
119+
120+ // Container Offset
121+ if ( containerWidth < selectorWidth ) {
122+ const offset = rtl
123+ ? wrapperRect . right - ( activeInputRight - arrowWidth + containerWidth )
124+ : activeInputLeft + arrowWidth - wrapperRect . left - containerWidth ;
125+
126+ const safeOffset = Math . max ( 0 , offset ) ;
127+ setContainerOffset ( safeOffset ) ;
116128 } else {
117- setContainerOffset ( activeOffset + arrowWidth - containerWidth ) ;
129+ setContainerOffset ( 0 ) ;
118130 }
119131 }
120- } , [ containerWidth , activeOffset , range ] ) ;
132+ } , [ rtl , containerWidth , activeInputLeft , activeInputRight , selectorWidth , range ] ) ;
121133
122134 // ======================== Custom ========================
123135 function filterEmpty < T > ( list : T [ ] ) {
@@ -213,19 +225,13 @@ export default function Popup<DateType extends object = any>(props: PopupProps<D
213225 ) ;
214226
215227 if ( range ) {
216- const realPlacement = getRealPlacement ( placement , rtl ) ;
217- const offsetUnit = getoffsetUnit ( realPlacement , rtl ) ;
218228 renderNode = (
219229 < div
220230 onMouseDown = { onPanelMouseDown }
221231 ref = { wrapperRef }
222232 className = { classNames ( `${ prefixCls } -range-wrapper` , `${ prefixCls } -${ picker } -range-wrapper` ) }
223233 >
224- < div
225- ref = { arrowRef }
226- className = { `${ prefixCls } -range-arrow` }
227- style = { { [ offsetUnit ] : activeOffset } }
228- />
234+ < div ref = { arrowRef } className = { `${ prefixCls } -range-arrow` } style = { { left : arrowOffset } } />
229235
230236 { /* Watch for container size */ }
231237 < ResizeObserver onResize = { onResize } > { renderNode } </ ResizeObserver >
0 commit comments