diff --git a/src/_common b/src/_common
index 9522412be0..8c4538bfc2 160000
--- a/src/_common
+++ b/src/_common
@@ -1 +1 @@
-Subproject commit 9522412be07088be33820c1a573b882a742bccd9
+Subproject commit 8c4538bfc2ad902082f11cf365aee3756fb48fe6
diff --git a/src/date-picker/__tests__/__snapshots__/date-picker.test.tsx.snap b/src/date-picker/__tests__/__snapshots__/date-picker.test.tsx.snap
index 1e2c6cacb5..796e8e8fb6 100644
--- a/src/date-picker/__tests__/__snapshots__/date-picker.test.tsx.snap
+++ b/src/date-picker/__tests__/__snapshots__/date-picker.test.tsx.snap
@@ -2563,6 +2563,7 @@ exports[`panel.jsx 1`] = `
-
-
-
-
-
-
-
-
- = (props) => {
// 获取每个时间的高度
const getItemHeight = useCallback(() => {
const maskDom = maskRef?.current?.querySelector('div');
- const timeItemTotalHeight = maskDom.offsetHeight + parseInt(getComputedStyle(maskDom).marginTop, 10);
- return timeItemTotalHeight;
+ if (!maskDom) {
+ return {
+ offsetHeight: 0,
+ margin: 0,
+ };
+ }
+ return {
+ offsetHeight: maskDom.offsetHeight,
+ margin: parseInt(getComputedStyle(maskDom).marginTop, 10),
+ };
}, []);
+ const panelOffset = useRef({
+ top: 0,
+ bottom: 0,
+ });
+
+ useIsomorphicLayoutEffect(() => {
+ const { offsetHeight, margin } = getItemHeight();
+ panelOffset.current = {
+ top: offsetHeight * 0.5 + margin * 0.5,
+ bottom: offsetHeight * 0.5 + margin * 1.5,
+ };
+ }, [cols]);
+
const timeItemCanUsed = useCallback(
(col: EPickerCols, el: string | number) => {
const colIdx = timeArr.indexOf(col);
@@ -149,8 +171,9 @@ const SinglePanel: FC = (props) => {
(time as number) %= 12; // 一定是数字,直接 cast
const itemIdx = getColList(col).indexOf(padStart(String(time), 2, '0'));
- const timeItemTotalHeight = getItemHeight();
- const distance = Math.abs(itemIdx * timeItemTotalHeight + timeItemTotalHeight / 2);
+ const { offsetHeight, margin } = getItemHeight();
+ const timeItemTotalHeight = offsetHeight + margin;
+ const distance = Math.abs(itemIdx * timeItemTotalHeight);
return distance;
},
[getItemHeight, getColList, format],
@@ -160,8 +183,9 @@ const SinglePanel: FC = (props) => {
let val: number | string;
let formattedVal: string;
const scrollTop = colsRef.current[idx]?.scrollTop;
-
- let colStep = Math.abs(Math.round(scrollTop / getItemHeight() + 0.5));
+ const { offsetHeight, margin } = getItemHeight();
+ const timeItemTotalHeight = offsetHeight + margin;
+ let colStep = Math.abs(Math.round(scrollTop / timeItemTotalHeight + 0.5));
const meridiem = MERIDIEM_LIST[Math.min(colStep - 1, 1)].toLowerCase(); // 处理PM、AM与am、pm
if (Number.isNaN(colStep)) colStep = 1;
@@ -192,21 +216,21 @@ const SinglePanel: FC = (props) => {
const distance = getScrollDistance(col, val);
if (!dayjs(dayjsValue).isValid()) return;
- if (distance !== scrollTop) {
- if (timeArr.includes(col)) {
- if (timeItemCanUsed(col, val)) formattedVal = dayjsValue[col]?.(val).format(format);
- } else {
- const currentHour = dayjsValue.hour();
- if (meridiem === AM && currentHour >= 12) {
- formattedVal = dayjsValue.hour(currentHour - 12).format(format);
- } else if (meridiem === PM && currentHour < 12) {
- formattedVal = dayjsValue.hour(currentHour + 12).format(format);
- }
+ if (timeArr.includes(col)) {
+ if (timeItemCanUsed(col, val)) formattedVal = dayjsValue[col]?.(val).format(format);
+ } else {
+ const currentHour = dayjsValue.hour();
+ if (meridiem === AM && currentHour >= 12) {
+ formattedVal = dayjsValue.hour(currentHour - 12).format(format);
+ } else if (meridiem === PM && currentHour < 12) {
+ formattedVal = dayjsValue.hour(currentHour + 12).format(format);
}
- onChange(formattedVal);
- const scrollCtrl = colsRef.current[cols.indexOf(col)];
- if (!distance || !scrollCtrl || scrollCtrl.scrollTop === distance) return;
+ }
+ onChange(formattedVal);
+ const scrollCtrl = colsRef.current[cols.indexOf(col)];
+ if (!distance || !scrollCtrl || scrollCtrl.scrollTop === distance) return;
+ if (distance !== scrollTop) {
scrollCtrl.scrollTo?.({
top: distance,
behavior: 'smooth',
@@ -302,6 +326,12 @@ const SinglePanel: FC = (props) => {
ref={(el) => (colsRef.current[idx] = el)}
className={`${panelClassName}-body-scroll`}
onScroll={debounce(() => handleScroll(col, idx), 50)}
+ style={
+ {
+ '--timePickerPanelOffsetTop': panelOffset.current.top,
+ '--timePickerPanelOffsetBottom': panelOffset.current.bottom,
+ } as CSSProperties
+ }
>
{getColList(col).map((el) => (