Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/examples/range.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,19 @@ export default () => {
disabledDate={disabledDate}
/>
</div>
<div>
<h3>needConfirm is false</h3>
<RangePicker<Moment>
{...sharedProps}
value={undefined}
locale={zhCN}
needConfirm={false}
picker="time"
ranges={{
test: [moment(), moment().add(1, 'hour')],
}}
/>
</div>
</div>
</div>
);
Expand Down
24 changes: 20 additions & 4 deletions src/PickerInput/Popup/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export interface PopupProps<DateType extends object = any, PresetValue = DateTyp
activeInfo?: [activeInputLeft: number, activeInputRight: number, selectorWidth: number];
// Direction
direction?: 'ltr' | 'rtl';
/** @internal: active input index for layout retry. Not part of public API. */
index?: number;

// Fill
/** TimePicker or showTime only */
Expand All @@ -58,7 +60,7 @@ export default function Popup<DateType extends object = any>(props: PopupProps<D
range,
multiple,
activeInfo = [0, 0, 0],

index,
// Presets
presets,
onPresetHover,
Expand All @@ -80,7 +82,6 @@ export default function Popup<DateType extends object = any>(props: PopupProps<D
onOk,
onSubmit,
} = props;

const { prefixCls } = React.useContext(PickerContext);
const panelPrefixCls = `${prefixCls}-panel`;

Expand Down Expand Up @@ -118,7 +119,13 @@ export default function Popup<DateType extends object = any>(props: PopupProps<D
// Arrow Offset
const wrapperRect = wrapperRef.current.getBoundingClientRect();
if (!wrapperRect.height || wrapperRect.right < 0) {
setRetryTimes((times) => Math.max(0, times - 1));
// This is a workaround to bypass the inconsistent useEffect behavior in React 18.
// When wrapperRef.current.getBoundingClientRect() fails to calculate the position correctly, it enters the retry logic.
// Under normal circumstances, retryTimes - 1 should equal 9, and useEffect would re-execute the side effect if dependencies change.
// However, in React 18, the side effect is no longer re-executed in such cases.
// By subtracting the index of the currently active input field (index, which is either 0 or 1), we compensate for this additional execution.
// Related issue: https://github.com/ant-design/ant-design/issues/54885
setRetryTimes((times) => Math.max(0, times - index - 1));
return;
}

Expand All @@ -138,7 +145,16 @@ export default function Popup<DateType extends object = any>(props: PopupProps<D
setContainerOffset(0);
}
}
}, [retryTimes, rtl, containerWidth, activeInputLeft, activeInputRight, selectorWidth, range]);
}, [
retryTimes,
rtl,
containerWidth,
activeInputLeft,
activeInputRight,
selectorWidth,
range,
index,
]);

// ======================== Custom ========================
function filterEmpty<T>(list: T[]) {
Expand Down
1 change: 1 addition & 0 deletions src/PickerInput/RangePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ function RangePicker<DateType extends object = any>(
range
multiplePanel={multiplePanel}
activeInfo={activeInfo}
index={activeIndex}
// Disabled
disabledDate={mergedDisabledDate}
// Focus
Expand Down
1 change: 1 addition & 0 deletions src/PickerInput/SinglePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@ function Picker<DateType extends object = any>(
// Focus
onFocus={onPanelFocus}
onBlur={onSharedBlur}
index={activeIndex}
// Mode
picker={picker}
mode={mergedMode}
Expand Down