@@ -8,7 +8,6 @@ import type {
8
8
ValueDate ,
9
9
} from '../../interface' ;
10
10
import { toArray } from '../../utils/miscUtil' ;
11
- import { getRealPlacement , getoffsetUnit } from '../../utils/uiUtil' ;
12
11
import PickerContext from '../context' ;
13
12
import Footer , { type FooterProps } from './Footer' ;
14
13
import PopupPanel , { type PopupPanelProps } from './PopupPanel' ;
@@ -32,8 +31,7 @@ export interface PopupProps<DateType extends object = any, PresetValue = DateTyp
32
31
onPresetSubmit : ( presetValue : PresetValue ) => void ;
33
32
34
33
// Range
35
- activeOffset ?: number ;
36
- placement ?: string ;
34
+ activeInfo ?: [ activeInputLeft : number , activeInputRight : number , selectorWidth : number ] ;
37
35
// Direction
38
36
direction ?: 'ltr' | 'rtl' ;
39
37
@@ -59,8 +57,7 @@ export default function Popup<DateType extends object = any>(props: PopupProps<D
59
57
// Range
60
58
range,
61
59
multiple,
62
- activeOffset = 0 ,
63
- placement,
60
+ activeInfo = [ 0 , 0 , 0 ] ,
64
61
65
62
// Presets
66
63
presets,
@@ -96,28 +93,43 @@ export default function Popup<DateType extends object = any>(props: PopupProps<D
96
93
// ======================== Offset ========================
97
94
const [ containerWidth , setContainerWidth ] = React . useState < number > ( 0 ) ;
98
95
const [ containerOffset , setContainerOffset ] = React . useState < number > ( 0 ) ;
96
+ const [ arrowOffset , setArrowOffset ] = React . useState < number > ( 0 ) ;
99
97
100
98
const onResize : ResizeObserverProps [ 'onResize' ] = ( info ) => {
101
- if ( info . offsetWidth ) {
102
- setContainerWidth ( info . offsetWidth ) ;
99
+ if ( info . width ) {
100
+ setContainerWidth ( info . width ) ;
103
101
}
104
102
} ;
105
103
104
+ const [ activeInputLeft , activeInputRight , selectorWidth ] = activeInfo ;
105
+
106
106
React . useEffect ( ( ) => {
107
107
// `activeOffset` is always align with the active input element
108
108
// So we need only check container contains the `activeOffset`
109
- if ( range ) {
109
+ if ( range && wrapperRef . current ) {
110
110
// Offset in case container has border radius
111
111
const arrowWidth = arrowRef . current ?. offsetWidth || 0 ;
112
112
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 ) ;
116
128
} else {
117
- setContainerOffset ( activeOffset + arrowWidth - containerWidth ) ;
129
+ setContainerOffset ( 0 ) ;
118
130
}
119
131
}
120
- } , [ containerWidth , activeOffset , range ] ) ;
132
+ } , [ rtl , containerWidth , activeInputLeft , activeInputRight , selectorWidth , range ] ) ;
121
133
122
134
// ======================== Custom ========================
123
135
function filterEmpty < T > ( list : T [ ] ) {
@@ -213,19 +225,13 @@ export default function Popup<DateType extends object = any>(props: PopupProps<D
213
225
) ;
214
226
215
227
if ( range ) {
216
- const realPlacement = getRealPlacement ( placement , rtl ) ;
217
- const offsetUnit = getoffsetUnit ( realPlacement , rtl ) ;
218
228
renderNode = (
219
229
< div
220
230
onMouseDown = { onPanelMouseDown }
221
231
ref = { wrapperRef }
222
232
className = { classNames ( `${ prefixCls } -range-wrapper` , `${ prefixCls } -${ picker } -range-wrapper` ) }
223
233
>
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 } } />
229
235
230
236
{ /* Watch for container size */ }
231
237
< ResizeObserver onResize = { onResize } > { renderNode } </ ResizeObserver >
0 commit comments