diff --git a/docs/examples/range.tsx b/docs/examples/range.tsx index 35dccec54..7c00e8d34 100644 --- a/docs/examples/range.tsx +++ b/docs/examples/range.tsx @@ -69,7 +69,7 @@ export default () => { allowClear ref={rangePickerRef} showTime - style={{ width: 700 }} + style={{ width: 580 }} ranges={{ ranges: [moment(), moment().add(10, 'day')], }} diff --git a/src/RangePicker.tsx b/src/RangePicker.tsx index d4adfb95a..8c1349f73 100644 --- a/src/RangePicker.tsx +++ b/src/RangePicker.tsx @@ -894,16 +894,19 @@ function InnerRangePicker(props: RangePickerProps) { arrowLeft = startInputDivRef.current.offsetWidth + separatorRef.current.offsetWidth; // If panelWidth - arrowWidth - arrowMarginLeft < arrowLeft, panel should move to right side. - // If offsetLeft > arrowLeft, arrow position is absolutely right, because arrowLeft is not calculated with arrow margin. + // If arrowOffsetLeft > arrowLeft, arrowMarginLeft = arrowOffsetLeft - arrowLeft + const arrowMarginLeft = + arrowRef.current.offsetLeft > arrowLeft + ? arrowRef.current.offsetLeft - arrowLeft + : arrowRef.current.offsetLeft; + if ( panelDivRef.current.offsetWidth && arrowRef.current.offsetWidth && arrowLeft > panelDivRef.current.offsetWidth - arrowRef.current.offsetWidth - - (direction === 'rtl' || arrowRef.current.offsetLeft > arrowLeft - ? 0 - : arrowRef.current.offsetLeft) + (direction === 'rtl' ? 0 : arrowMarginLeft) ) { panelLeft = arrowLeft; } diff --git a/tests/range.spec.tsx b/tests/range.spec.tsx index 15fb77cfe..2b69841e0 100644 --- a/tests/range.spec.tsx +++ b/tests/range.spec.tsx @@ -1589,7 +1589,7 @@ describe('Picker.Range', () => { mock.mockRestore(); }); - it('panel should be stable: right', () => { + it('panel should be stable: arrow right and panel left', () => { const mock = spyElementPrototypes(HTMLElement, { offsetWidth: { get() { @@ -1624,4 +1624,40 @@ describe('Picker.Range', () => { expect(wrapper.find('.rc-picker-panel-container').getDOMNode().style.marginLeft).toBe('0px'); mock.mockRestore(); }); + + it('panel should be stable: arrow right and panel right', () => { + const mock = spyElementPrototypes(HTMLElement, { + offsetWidth: { + get() { + if (this.className.includes('range-arrow')) { + return 14; + } else if (this.className.includes('panel-container')) { + return 311; + } else if (this.className.includes('input')) { + return 285; + } else if (this.className.includes('range-separator')) { + return 10; + } + }, + }, + offsetLeft: { + get() { + if (this.className.includes('range-arrow')) { + return 305; + } + }, + }, + }); + const wrapper = mount( + X} + suffixIcon={O} + />, + ); + wrapper.openPicker(1); + expect(wrapper.find('.rc-picker-panel-container').getDOMNode().style.marginLeft).toBe('295px'); + mock.mockRestore(); + }); });