Skip to content

Commit

Permalink
feat(timepicker): auto scroll when first mount
Browse files Browse the repository at this point in the history
  • Loading branch information
uyarn committed Jun 13, 2022
1 parent 86a747e commit b06a9b7
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 19 deletions.
1 change: 1 addition & 0 deletions src/time-picker/TimePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ const TimePicker = forwardRefWithStatics(
format={format}
value={currentValue}
isFooterDisplay={true}
isShowPanel={isPanelShowed}
disableTime={disableTime}
onChange={setCurrentValue}
hideDisabledTime={hideDisabledTime}
Expand Down
1 change: 1 addition & 0 deletions src/time-picker/TimeRangePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ const TimeRangePicker: FC<TimeRangePickerProps> = (props) => {
steps={steps}
format={format}
disableTime={disableTime}
isShowPanel={isPanelShowed}
hideDisabledTime={hideDisabledTime}
isFooterDisplay={true}
value={currentValue[currentPanelIdx || 0]}
Expand Down
52 changes: 36 additions & 16 deletions src/time-picker/panel/SinglePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,25 @@ export interface SinglePanelProps
context?: { partial: TimeRangePickerPartial },
) => Partial<{ hour: number[]; minute: number[]; second: number[] }>;
position?: TimeRangePickerPartial;
triggerScroll?: boolean;
resetTriggerScroll?: () => void;
}

// https://github.com/iamkun/dayjs/issues/1552
dayjs.extend(customParseFormat);

const SinglePanel: FC<SinglePanelProps> = (props) => {
const { steps, format, onChange = noop, value, hideDisabledTime = true, disableTime, position = 'start' } = props;
const {
steps,
format,
onChange = noop,
value,
hideDisabledTime = true,
disableTime,
position = 'start',
triggerScroll,
resetTriggerScroll,
} = props;
const { classPrefix } = useConfig();
const TEXT_CONFIG = useTimePickerTextConfig();
const panelClassName = `${classPrefix}-time-picker__panel`;
Expand Down Expand Up @@ -230,24 +242,32 @@ const SinglePanel: FC<SinglePanelProps> = (props) => {
};

// update each columns scroll distance
const updateTimeScrollPos = useCallback(() => {
const behavior = value ? 'smooth' : 'auto';
const isStepsSet = !!steps.filter((v) => v > 1).length;

cols.forEach((col: EPickerCols, idx: number) => {
if (!isStepsSet || (isStepsSet && value)) {
// 如果没有设置大于1的steps或设置了大于1的step 正常处理滚动
scrollToTime(col, timeArr.includes(col) ? dayjsValue[col]?.() : dayjsValue.format('a'), idx, behavior);
} else {
// 否则初始化到每列第一个选项
scrollToTime(col, getColList(col)?.[0], idx, behavior);
}
});
}, [cols, scrollToTime, dayjsValue, value, steps, getColList]);
const updateTimeScrollPos = useCallback(
(isAutoScroll = false) => {
const behavior = value && !isAutoScroll ? 'smooth' : 'auto';
const isStepsSet = !!steps.filter((v) => v > 1).length;

cols.forEach((col: EPickerCols, idx: number) => {
if (!isStepsSet || (isStepsSet && value)) {
// 如果没有设置大于1的steps或设置了大于1的step 正常处理滚动
scrollToTime(col, timeArr.includes(col) ? dayjsValue[col]?.() : dayjsValue.format('a'), idx, behavior);
} else {
// 否则初始化到每列第一个选项
scrollToTime(col, getColList(col)?.[0], idx, behavior);
}
});
resetTriggerScroll();
},
[cols, scrollToTime, dayjsValue, value, steps, getColList, resetTriggerScroll],
);

useEffect(() => {
updateTimeScrollPos();
});
}, [value, updateTimeScrollPos]);

useEffect(() => {
if (triggerScroll) updateTimeScrollPos(true);
}, [triggerScroll, updateTimeScrollPos]);

const isCurrent = useCallback(
(col: EPickerCols, colItem: string | number) => {
Expand Down
20 changes: 17 additions & 3 deletions src/time-picker/panel/TimePickerPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FC, useMemo } from 'react';
import React, { FC, useEffect, useMemo, useState } from 'react';
import dayjs from 'dayjs';
import SinglePanel, { SinglePanelProps } from './SinglePanel';

Expand All @@ -9,6 +9,7 @@ import { useTimePickerTextConfig } from '../hooks/useTimePickerTextConfig';
import { DEFAULT_STEPS, DEFAULT_FORMAT } from '../../_common/js/time-picker/const';

export interface TimePickerPanelProps extends SinglePanelProps {
isShowPanel?: boolean;
isFooterDisplay?: boolean; // 是否展示footer
handleConfirmClick?: (defaultValue: dayjs.Dayjs) => void;
}
Expand All @@ -21,8 +22,9 @@ const TimePickerPanel: FC<TimePickerPanelProps> = (props) => {
isFooterDisplay,
onChange,
value,
isShowPanel,
} = props;

const [triggerScroll, toggleTriggerScroll] = useState(false); // 触发滚动
const { classPrefix } = useConfig();

const TEXT_CONFIG = useTimePickerTextConfig();
Expand All @@ -40,10 +42,22 @@ const TimePickerPanel: FC<TimePickerPanelProps> = (props) => {
}
return dayjs();
}, [value, format, steps]);

useEffect(() => {
toggleTriggerScroll(true);
}, [isShowPanel]);

return (
<div className={panelClassName}>
<div className={`${panelClassName}-section-body`}>
<SinglePanel {...props} format={format} steps={steps} value={value} />
<SinglePanel
{...props}
format={format}
steps={steps}
value={value}
triggerScroll={triggerScroll}
resetTriggerScroll={() => toggleTriggerScroll(false)}
/>
</div>
{isFooterDisplay ? (
<div className={`${panelClassName}-section-footer`}>
Expand Down

0 comments on commit b06a9b7

Please sign in to comment.