@@ -8,7 +8,7 @@ import type {
88 ValueDate ,
99} from '../../interface' ;
1010import { toArray } from '../../utils/miscUtil' ;
11- import { getRealPlacement , getoffsetUnit } from '../../utils/uiUtil' ;
11+ import { getRealPlacement , getOffsetUnit } from '../../utils/uiUtil' ;
1212import PickerContext from '../context' ;
1313import Footer , { type FooterProps } from './Footer' ;
1414import PopupPanel , { type PopupPanelProps } from './PopupPanel' ;
@@ -32,7 +32,7 @@ export interface PopupProps<DateType extends object = any, PresetValue = DateTyp
3232 onPresetSubmit : ( presetValue : PresetValue ) => void ;
3333
3434 // Range
35- activeOffset ?: number ;
35+ activeInfo ?: [ activeInputLeft : number , activeInputRight : number , selectorWidth : number ] ;
3636 placement ?: string ;
3737 // Direction
3838 direction ?: 'ltr' | 'rtl' ;
@@ -59,7 +59,7 @@ export default function Popup<DateType extends object = any>(props: PopupProps<D
5959 // Range
6060 range,
6161 multiple,
62- activeOffset = 0 ,
62+ activeInfo = [ 0 , 0 , 0 ] ,
6363 placement,
6464
6565 // Presets
@@ -96,28 +96,46 @@ export default function Popup<DateType extends object = any>(props: PopupProps<D
9696 // ======================== Offset ========================
9797 const [ containerWidth , setContainerWidth ] = React . useState < number > ( 0 ) ;
9898 const [ containerOffset , setContainerOffset ] = React . useState < number > ( 0 ) ;
99+ const [ arrowOffset , setArrowOffset ] = React . useState < number > ( 0 ) ;
99100
100101 const onResize : ResizeObserverProps [ 'onResize' ] = ( info ) => {
101102 if ( info . offsetWidth ) {
102103 setContainerWidth ( info . offsetWidth ) ;
103104 }
104105 } ;
105106
107+ const [ activeInputLeft , activeInputRight , selectorWidth ] = activeInfo ;
108+
106109 React . useEffect ( ( ) => {
107110 // `activeOffset` is always align with the active input element
108111 // So we need only check container contains the `activeOffset`
109- if ( range ) {
112+ if ( range && wrapperRef . current ) {
110113 // Offset in case container has border radius
111114 const arrowWidth = arrowRef . current ?. offsetWidth || 0 ;
112115
113- const maxOffset = containerWidth - arrowWidth ;
114- if ( activeOffset <= maxOffset ) {
115- setContainerOffset ( 0 ) ;
116+ // Arrow Offset
117+ const wrapperRect = wrapperRef . current . getBoundingClientRect ( ) ;
118+ const nextArrowOffset = rtl
119+ ? activeInputRight - arrowWidth
120+ : activeInputLeft - wrapperRect . left ;
121+ setArrowOffset ( nextArrowOffset ) ;
122+
123+ // Container Offset
124+ if ( containerWidth < selectorWidth ) {
125+ if ( rtl ) {
126+ const offset = wrapperRect . right - ( activeInputRight - arrowWidth + containerWidth ) ;
127+ const safeOffset = Math . max ( 0 , offset ) ;
128+ setContainerOffset ( safeOffset ) ;
129+ } else {
130+ const offset = activeInputLeft + arrowWidth - wrapperRect . left - containerWidth ;
131+ const safeOffset = Math . max ( 0 , offset ) ;
132+ setContainerOffset ( safeOffset ) ;
133+ }
116134 } else {
117- setContainerOffset ( activeOffset + arrowWidth - containerWidth ) ;
135+ setContainerOffset ( 0 ) ;
118136 }
119137 }
120- } , [ containerWidth , activeOffset , range ] ) ;
138+ } , [ rtl , containerWidth , activeInputLeft , activeInputRight , selectorWidth , range ] ) ;
121139
122140 // ======================== Custom ========================
123141 function filterEmpty < T > ( list : T [ ] ) {
@@ -213,19 +231,13 @@ export default function Popup<DateType extends object = any>(props: PopupProps<D
213231 ) ;
214232
215233 if ( range ) {
216- const realPlacement = getRealPlacement ( placement , rtl ) ;
217- const offsetUnit = getoffsetUnit ( realPlacement , rtl ) ;
218234 renderNode = (
219235 < div
220236 onMouseDown = { onPanelMouseDown }
221237 ref = { wrapperRef }
222238 className = { classNames ( `${ prefixCls } -range-wrapper` , `${ prefixCls } -${ picker } -range-wrapper` ) }
223239 >
224- < div
225- ref = { arrowRef }
226- className = { `${ prefixCls } -range-arrow` }
227- style = { { [ offsetUnit ] : activeOffset } }
228- />
240+ < div ref = { arrowRef } className = { `${ prefixCls } -range-arrow` } style = { { left : arrowOffset } } />
229241
230242 { /* Watch for container size */ }
231243 < ResizeObserver onResize = { onResize } > { renderNode } </ ResizeObserver >
0 commit comments