Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(pull-down-refresh): update api #479

Merged
merged 11 commits into from
Oct 9, 2024
74 changes: 57 additions & 17 deletions src/pull-down-refresh/PullDownRefresh.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,26 @@ import uniqueId from 'lodash/uniqueId';
import { useDrag } from '@use-gesture/react';
import { useSpring, animated } from '@react-spring/web';
anlyyao marked this conversation as resolved.
Show resolved Hide resolved
import isBoolean from 'lodash/isBoolean';
import isNumber from 'lodash/isNumber';
import debounce from 'lodash/debounce';
import { Loading } from 'tdesign-mobile-react';
import useConfig from '../_util/useConfig';
import withNativeProps, { NativeProps } from '../_util/withNativeProps';
novlan1 marked this conversation as resolved.
Show resolved Hide resolved
import getScrollParent from '../_util/getScrollParent';
import useDefault from '../_util/useDefault';
import delay from '../_util/delay';
import { TdPullDownRefreshProps } from './type';

const convertUnit = (val: string | number | undefined) => {
if (val == null) return 0;
return isNumber(val) ? `${val}px` : val;
};
novlan1 marked this conversation as resolved.
Show resolved Hide resolved

const reconvertUnit = (val: string | number | undefined) => {
if (val == null) return 0;
return isNumber(val) ? Number(val) : Number(val.slice(0, -2));
};

export enum PullStatusEnum {
normal,
loading,
Expand Down Expand Up @@ -64,12 +77,12 @@ const PullDownRefresh: React.FC<PullDownRefreshProps> = (props) => {
refreshTimeout,
onRefresh,
onTimeout,
value,
onChange,
} = props;
const [status, originalSetStatus] = useState(PullStatusEnum.normal);
const rootRef = useRef<HTMLDivElement>(null);
const scrollParentRef = useRef<Element | Window>(null);
const [value, onChange] = useDefault(props.value, props.defaultValue, props.onChange);
novlan1 marked this conversation as resolved.
Show resolved Hide resolved

const { classPrefix } = useConfig();
novlan1 marked this conversation as resolved.
Show resolved Hide resolved
const name = `${classPrefix}-pull-down-refresh`;
const setStatus = (nextStatus: PullStatusEnum) => {
Expand Down Expand Up @@ -98,9 +111,32 @@ const PullDownRefresh: React.FC<PullDownRefreshProps> = (props) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [value]);

const onReachBottom = debounce(
() => {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; // 滚动高度
const { clientHeight, scrollHeight } = document.documentElement; // 可视区域/屏幕高度, 页面高度
const distance = 20; // 距离视窗 20 时,开始触发
if (scrollTop + clientHeight >= scrollHeight - distance) {
props.onScrolltolower?.();
}
},
300,
{
leading: true,
trailing: false,
},
);
novlan1 marked this conversation as resolved.
Show resolved Hide resolved

useEffect(() => {
window.addEventListener('scroll', onReachBottom);
return () => {
window.removeEventListener('scroll', onReachBottom);
};
}, [onReachBottom]);

const doRefresh = async () => {
setStatus(PullStatusEnum.loading);
api.start({ y: loadingBarHeight });
api.start({ y: reconvertUnit(loadingBarHeight) });
try {
const timeoutId = uniqueId(`${name}-timeout_`);
let timeoutTid: any;
Expand Down Expand Up @@ -165,26 +201,30 @@ const PullDownRefresh: React.FC<PullDownRefreshProps> = (props) => {
);

const statusText = getStatusText(status, loadingTexts);
let statusNode: ReactNode = statusText;
let statusNode: ReactNode = <div className={`${name}__text`}>{statusText}</div>;
if (status === PullStatusEnum.loading) {
statusNode = (
<Loading
className={`${name}__loading`}
text={<span className={`${name}__loading-icon`}>{statusText}</span>}
{...loadingProps}
/>
);
statusNode = <Loading text={statusText} size="24px" {...loadingProps} />;
}
const loadingHeight = convertUnit(loadingBarHeight);

return withNativeProps(
props,
<div className={name} ref={rootRef}>
<animated.div className={`${name}__track`} style={{ y }}>
<div
className={classNames(`${name}__loading`, `${name}__loading-icon`, `${name}__max`)}
style={{ height: loadingBarHeight }}
>
{statusNode}
<animated.div
className={classNames(`${name}__track`, { [`${name}__track--loosing`]: status !== PullStatusEnum.pulling })}
style={{ y }}
>
<div className={`${name}__tips`}>
<div
className={`${name}__loading`}
style={{
height: loadingHeight,
maxHeight: loadingHeight,
color: 'red',
}}
>
{statusNode}
</div>
</div>
{children}
HaixingOoO marked this conversation as resolved.
Show resolved Hide resolved
</animated.div>
Expand Down
6 changes: 2 additions & 4 deletions src/pull-down-refresh/_example/base.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ export default function BaseDemo({ children }) {
return (
<div className="tdesign-mobile-wrapper">
<PullDownRefresh
loadingBarHeight={80}
loadingProps={{
layout: 'vertical',
}}
loadingBarHeight={66}
loadingProps={{}}
loadingTexts={['下拉刷新', '松开刷新', '正在刷新', '刷新完成']}
onRefresh={() =>
new Promise((resolve) => {
Expand Down
6 changes: 5 additions & 1 deletion src/pull-down-refresh/pull-down-refresh.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@
-- | -- | -- | -- | --
novlan1 marked this conversation as resolved.
Show resolved Hide resolved
className | String | - | 类名 | N
style | Object | - | 样式,TS 类型:`React.CSSProperties` | N
loadingBarHeight | Number | 50 | 加载中下拉高度 | N
loadingBarHeight | String / Number | 50 | 加载中下拉高度,如果值为数字则单位是:'px' | N
loadingProps | Object | - | 加载loading样式。TS 类型:`TdLoadingProps`,[Loading API Documents](./loading?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/pull-down-refresh/type.ts) | N
loadingTexts | Array | [] | 提示语,组件内部默认值为 ['下拉刷新', '松手刷新', '正在刷新', '刷新完成']。TS 类型:`string[]` | N
maxBarHeight | Number | 80 | 最大下拉高度 | N
refreshTimeout | Number | 3000 | 刷新超时时间 | N
value | Boolean | false | 组件状态,值为 `true` 表示下拉状态,值为 `false` 表示收起状态。 | N
defaultValue | Boolean | false | 组件状态,值为 `true` 表示下拉状态,值为 `false` 表示收起状态。非受控属性 | N
onChange | Function | | TS 类型:`(value: boolean) => void`<br/>下拉或收起时触发,用户手势往下滑动触发下拉状态,手势松开触发收起状态 | N
onRefresh | Function | | TS 类型:`() => void`<br/>结束下拉时触发 | N
onScrolltolower | Function | | TS 类型:`() => void`<br/>滚动到页面底部时触发 | N
onTimeout | Function | | TS 类型:`() => void`<br/>刷新超时触发 | N
2 changes: 1 addition & 1 deletion src/pull-down-refresh/style/index.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import '../../_common/style/mobile/components/pull-down-refresh/_index.less';
import '../../_common/style/mobile/components/pull-down-refresh/v2/_index.less';
14 changes: 12 additions & 2 deletions src/pull-down-refresh/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface TdPullDownRefreshProps {
* 加载中下拉高度
* @default 50
*/
loadingBarHeight?: number;
loadingBarHeight?: number | string;
/**
* 加载loading样式
*/
Expand Down Expand Up @@ -40,9 +40,19 @@ export interface TdPullDownRefreshProps {
*/
onTimeout?: () => void;
/**
* 控制是否正在加载
* 组件状态,值为 `true` 表示下拉状态,值为 `false` 表示收起状态
* @default false
*/
value?: boolean | undefined;
/**
* 组件状态,值为 `true` 表示下拉状态,值为 `false` 表示收起状态,非受控属性
* @default false
*/
defaultValue?: boolean;
/**
* 滚动到页面底部时触发
*/
onScrolltolower?: () => void;
/**
* 刷新过程中加载状态的更改
*/
Expand Down
Loading