diff --git a/src/packages/infiniteloading/__tests__/__snapshots__/infiniteloading.spec.tsx.snap b/src/packages/infiniteloading/__tests__/__snapshots__/infiniteloading.spec.tsx.snap index ba919cda48..618803b87e 100644 --- a/src/packages/infiniteloading/__tests__/__snapshots__/infiniteloading.spec.tsx.snap +++ b/src/packages/infiniteloading/__tests__/__snapshots__/infiniteloading.spec.tsx.snap @@ -118,7 +118,7 @@ exports[`pull base 01 1`] = ` >
Promise` | `-` | | onLoadMore | Callback function to continue loading | `() => Promise` | `-` | | onScroll | Monitor scroll height in real time | `(param: number) => void` | `-` | diff --git a/src/packages/infiniteloading/doc.md b/src/packages/infiniteloading/doc.md index 820c0b9cb0..554a2c208f 100644 --- a/src/packages/infiniteloading/doc.md +++ b/src/packages/infiniteloading/doc.md @@ -65,6 +65,7 @@ import { InfiniteLoading } from '@nutui/nutui-react' | pullRefresh | 是否开启下拉刷新 | `boolean` | `false` | | pullingText | 下拉刷新提示文案 | `ReactNode` | `松手刷新` | | loadingText | 上拉加载提示文案 | `ReactNode` | `刷新中` | +| refreshDistance | 下拉刷新触发距离 | `number` | `100` | | onRefresh | 下拉刷新事件回调 | `() => Promise` | `-` | | onLoadMore | 继续加载的回调函数 | `() => Promise` | `-` | | onScroll | 实时监听滚动高度 | `(param: number) => void` | `-` | diff --git a/src/packages/infiniteloading/doc.taro.md b/src/packages/infiniteloading/doc.taro.md index ff5948c2b0..b434098d1d 100644 --- a/src/packages/infiniteloading/doc.taro.md +++ b/src/packages/infiniteloading/doc.taro.md @@ -56,6 +56,7 @@ import { InfiniteLoading } from '@nutui/nutui-react-taro' | pullRefresh | 是否开启下拉刷新 | `boolean` | `false` | | pullingText | 下拉刷新提示文案 | `ReactNode` | `松手刷新` | | loadingText | 上拉加载提示文案 | `ReactNode` | `刷新中` | +| refreshDistance | 下拉刷新触发距离 | `number` | `100` | | onRefresh | 下拉刷新事件回调 | `() => Promise` | `-` | | onLoadMore | 继续加载的回调函数 | `() => Promise` | `-` | | onScroll | 实时监听滚动高度 | `(param: number) => void` | `-` | diff --git a/src/packages/infiniteloading/doc.zh-TW.md b/src/packages/infiniteloading/doc.zh-TW.md index 5fbd19f646..c43d6844cb 100644 --- a/src/packages/infiniteloading/doc.zh-TW.md +++ b/src/packages/infiniteloading/doc.zh-TW.md @@ -65,6 +65,7 @@ import { InfiniteLoading } from '@nutui/nutui-react' | pullRefresh | 是否開啟下拉刷新 | `boolean` | `false` | | pullingText | 下拉刷新提示文案 | `ReactNode` | `鬆手刷新` | | loadingText | 上拉加載提示文案 | `ReactNode` | `加載中...` | +| refreshDistance | 下拉刷新觸發距離 | `number` | `100` | | onRefresh | 下拉刷新事件回調 | `() => Promise` | `-` | | onLoadMore | 繼續加載的回調函數 | `() => Promise` | `-` | | onScroll | 實時監聽滾動高度 | `(param: number) => void` | `-` | diff --git a/src/packages/infiniteloading/infiniteloading.taro.tsx b/src/packages/infiniteloading/infiniteloading.taro.tsx index 53c8535d8b..4c4a730501 100644 --- a/src/packages/infiniteloading/infiniteloading.taro.tsx +++ b/src/packages/infiniteloading/infiniteloading.taro.tsx @@ -6,14 +6,16 @@ import { useConfig } from '@/packages/configprovider/index.taro' import { ComponentDefaults } from '@/utils/typings' import { TaroInfiniteLoadingProps } from '@/types' import { pxTransform } from '@/utils/taro/px-transform' +import { mergeProps } from '@/utils' const defaultProps = { ...ComponentDefaults, type: 'default', hasMore: true, - threshold: 40, + threshold: 200, target: '', pullRefresh: false, + refreshDistance: 100, } as TaroInfiniteLoadingProps const classPrefix = `nut-infiniteloading` @@ -36,11 +38,9 @@ export const InfiniteLoading: FunctionComponent< onRefresh, onLoadMore, onScroll, + refreshDistance, ...rest - } = { - ...defaultProps, - ...props, - } + } = mergeProps(defaultProps, props) const [isInfiniting, setIsInfiniting] = useState(false) const [topDisScoll, setTopDisScoll] = useState(0) const refreshTop = useRef(null) @@ -48,18 +48,16 @@ export const InfiniteLoading: FunctionComponent< const scrollTop = useRef(0) const isTouching = useRef(false) const y = useRef(0) - const refreshMaxH = useRef(0) const distance = useRef(0) const classes = classNames(classPrefix, className, `${classPrefix}-${type}`) useEffect(() => { - refreshMaxH.current = threshold - const timer = setTimeout(() => { + const timer = setTimeout(async () => { getScrollHeight() }, 200) return () => clearTimeout(timer) - }, [hasMore, isInfiniting, threshold]) + }, [hasMore, isInfiniting]) /** 获取需要滚动的距离 */ const getScrollHeight = () => { @@ -111,21 +109,25 @@ export const InfiniteLoading: FunctionComponent< } const touchStart = (event: any) => { - if (scrollTop.current === 0 && !isTouching.current && pullRefresh) { + if (!isTouching.current && pullRefresh) { y.current = event.touches[0].pageY + distance.current = 0 + setTopDisScoll(0) isTouching.current = true } } const touchMove = (event: any) => { - distance.current = event.touches[0].pageY - y.current - if (distance.current > 0 && isTouching.current) { + if (!isTouching.current) return + const currentY = event.touches[0].pageY + const newDistance = Math.max(0, currentY - y.current) + distance.current = newDistance + + if (newDistance > 0) { event.preventDefault() - setTopDisScoll(distance.current) - if (distance.current >= refreshMaxH.current) { - distance.current = refreshMaxH.current - setTopDisScoll(refreshMaxH.current) - } + const finalDistance = Math.min(newDistance, refreshDistance) + distance.current = finalDistance + setTopDisScoll(finalDistance) } else { distance.current = 0 setTopDisScoll(0) @@ -134,14 +136,17 @@ export const InfiniteLoading: FunctionComponent< } const touchEnd = async () => { - if (distance.current < refreshMaxH.current) { + if (!isTouching.current) return + + if (distance.current < refreshDistance) { distance.current = 0 setTopDisScoll(0) - isTouching.current = false - } else { - await onRefresh?.() - refreshDone() + } else if (onRefresh) { + await onRefresh() } + + isTouching.current = false + refreshDone() } function getBottomTipsText() { @@ -161,6 +166,7 @@ export const InfiniteLoading: FunctionComponent< scrollY id="scroller" type="list" + lowerThreshold={threshold} style={{ height: '100%' }} onScroll={scrollAction} onScrollToLower={lower} diff --git a/src/packages/infiniteloading/infiniteloading.tsx b/src/packages/infiniteloading/infiniteloading.tsx index 55fdd73622..97df8076ce 100644 --- a/src/packages/infiniteloading/infiniteloading.tsx +++ b/src/packages/infiniteloading/infiniteloading.tsx @@ -3,6 +3,7 @@ import classNames from 'classnames' import { useConfig } from '@/packages/configprovider' import { ComponentDefaults } from '@/utils/typings' import { WebInfiniteLoadingProps } from '@/types' +import { mergeProps } from '@/utils/merge-props' declare let window: Window & { webkitRequestAnimationFrame: any } & { mozRequestAnimationFrame: any @@ -16,6 +17,7 @@ const defaultProps = { target: '', capture: false, pullRefresh: false, + refreshDistance: 100, } as WebInfiniteLoadingProps const classPrefix = `nut-infiniteloading` @@ -35,22 +37,19 @@ export const InfiniteLoading: FunctionComponent< pullingText, loadingText, loadMoreText, + refreshDistance, className, onRefresh, onLoadMore, onScroll, ...restProps - } = { - ...defaultProps, - ...props, - } + } = mergeProps(defaultProps, props) const [isInfiniting, setIsInfiniting] = useState(false) const scroller = useRef(null) const refreshTop = useRef(null) const scrollEl = useRef(null) const isTouching = useRef(false) const beforeScrollTop = useRef(0) - const refreshMaxH = useRef(0) const y = useRef(0) const distance = useRef(0) @@ -118,7 +117,6 @@ export const InfiniteLoading: FunctionComponent< isTouching.current = true const childHeight = (getRefreshTop().firstElementChild as HTMLElement) .offsetHeight - refreshMaxH.current = Math.floor(childHeight * 1 + 10) } } @@ -126,8 +124,8 @@ export const InfiniteLoading: FunctionComponent< distance.current = event.touches[0].pageY - y.current if (distance.current > 0 && isTouching.current) { event.preventDefault() - if (distance.current >= refreshMaxH.current) { - distance.current = refreshMaxH.current + if (distance.current >= refreshDistance) { + distance.current = refreshDistance getRefreshTop().style.height = `${distance.current}px` } else { getRefreshTop().style.height = `${distance.current}px` @@ -140,7 +138,7 @@ export const InfiniteLoading: FunctionComponent< } const touchEnd = async () => { - if (distance.current < refreshMaxH.current) { + if (distance.current < refreshDistance) { distance.current = 0 getRefreshTop().style.height = `${distance.current}px` isTouching.current = false diff --git a/src/sites/sites-react/doc/docs/react/migrate-from-v2.en-US.md b/src/sites/sites-react/doc/docs/react/migrate-from-v2.en-US.md index ec6b4f6106..ba9a8b992d 100644 --- a/src/sites/sites-react/doc/docs/react/migrate-from-v2.en-US.md +++ b/src/sites/sites-react/doc/docs/react/migrate-from-v2.en-US.md @@ -1,4 +1,4 @@ -# Upgrade from v2 to v3. +# Upgrade from v2 to v3 This document will assist you in upgrading from NutUI React 2.x to NutUI React 3.x. @@ -214,6 +214,7 @@ If your project uses these components, please read the documentation carefully a #### InfiniteLoading - The target attribute is used to obtain the element that is being listened to. +- `refreshDistance` The distance to trigger the pull-down refresh. [//]: # '#### Notify' [//]: # '#### PullToRefresh' diff --git a/src/sites/sites-react/doc/docs/react/migrate-from-v2.md b/src/sites/sites-react/doc/docs/react/migrate-from-v2.md index f986185539..a7233c607f 100644 --- a/src/sites/sites-react/doc/docs/react/migrate-from-v2.md +++ b/src/sites/sites-react/doc/docs/react/migrate-from-v2.md @@ -221,6 +221,7 @@ plugins: [ #### InfiniteLoading - `target` 属性获取监听的目标元素 +- `refreshDistance` 下拉刷新触发距离 #### Notify diff --git a/src/sites/sites-react/doc/docs/react/official-theme-react.md b/src/sites/sites-react/doc/docs/react/official-theme-react.md index e851e1c5b8..3d641eb27c 100644 --- a/src/sites/sites-react/doc/docs/react/official-theme-react.md +++ b/src/sites/sites-react/doc/docs/react/official-theme-react.md @@ -12,7 +12,6 @@ NutUI 默认提供多套官方`UI`主题,同时允许在一定程度上定制 | 京东 JDesign 主题 ([预览](https://nutui.jd.com/h5/react/jdesign-3x/#/zh-CN/component/button)) | `variables-jmapp.scss` | | 京东 JRKF 主题 | `variables-jrkf.scss` | - ## 使用方式 需要注意的是,配置主题时,你还需要在入口文件中引入 global 类的文件来加载一些 NutUI React 的全局性逻辑和样式: diff --git a/src/sites/sites-react/doc/docs/taro/migrate-from-v2.en-US.md b/src/sites/sites-react/doc/docs/taro/migrate-from-v2.en-US.md index ec6b4f6106..ba9a8b992d 100644 --- a/src/sites/sites-react/doc/docs/taro/migrate-from-v2.en-US.md +++ b/src/sites/sites-react/doc/docs/taro/migrate-from-v2.en-US.md @@ -1,4 +1,4 @@ -# Upgrade from v2 to v3. +# Upgrade from v2 to v3 This document will assist you in upgrading from NutUI React 2.x to NutUI React 3.x. @@ -214,6 +214,7 @@ If your project uses these components, please read the documentation carefully a #### InfiniteLoading - The target attribute is used to obtain the element that is being listened to. +- `refreshDistance` The distance to trigger the pull-down refresh. [//]: # '#### Notify' [//]: # '#### PullToRefresh' diff --git a/src/sites/sites-react/doc/docs/taro/migrate-from-v2.md b/src/sites/sites-react/doc/docs/taro/migrate-from-v2.md index e7f888b66d..db5546329c 100644 --- a/src/sites/sites-react/doc/docs/taro/migrate-from-v2.md +++ b/src/sites/sites-react/doc/docs/taro/migrate-from-v2.md @@ -220,6 +220,7 @@ plugins: [ #### InfiniteLoading - `target` 属性获取监听的目标元素 +- `refreshDistance` 下拉刷新触发距离 #### Notify diff --git a/src/types/spec/infiniteloading/base.ts b/src/types/spec/infiniteloading/base.ts index ea60bda4dd..d8c5acb37f 100644 --- a/src/types/spec/infiniteloading/base.ts +++ b/src/types/spec/infiniteloading/base.ts @@ -8,6 +8,7 @@ export interface BaseInfiniteLoading extends BaseProps { type: InfiniteLoadingType hasMore: boolean threshold: number + refreshDistance: number target: string capture: boolean pullRefresh: boolean