diff --git a/site/mobile/mobile.config.js b/site/mobile/mobile.config.js index 147a1406..493095c6 100644 --- a/site/mobile/mobile.config.js +++ b/site/mobile/mobile.config.js @@ -110,7 +110,7 @@ export default { { title: 'BackTop 返回顶部', name: 'back-top', - component: () => import('tdesign-mobile-react/back-top/_example/index.jsx'), + component: () => import('tdesign-mobile-react/back-top/_example/index.tsx'), }, { title: 'Checkbox 多选框', diff --git a/src/_common b/src/_common index 05c1f59e..7631511a 160000 --- a/src/_common +++ b/src/_common @@ -1 +1 @@ -Subproject commit 05c1f59ef27bea7da2fcfd09f98b0b838516d538 +Subproject commit 7631511ac616f23495e3ecb4293dad10c9c62e1b diff --git a/src/back-top/Backtop.tsx b/src/back-top/Backtop.tsx index 9ba5cfd7..d8795458 100644 --- a/src/back-top/Backtop.tsx +++ b/src/back-top/Backtop.tsx @@ -18,10 +18,11 @@ export const defaultProps = { target: (() => window) as any, text: '', theme: 'round' as ThemeList, + visibilityHeight: 200, }; const BackTop: React.FC = (props) => { - const { fixed, icon, target, text, theme } = props; + const { fixed, icon, target, text, theme, onToTop, visibilityHeight, container } = props; const [show, { setTrue, setFalse }] = useBoolean(false); @@ -33,7 +34,16 @@ const BackTop: React.FC = (props) => { const name = `${classPrefix}-back-top`; - const scroll = useScroll(document); + const getContainer = (container: Function) => { + if (typeof container === 'function') { + return container(); + } + return document.documentElement; + }; + const containerDom = useRef(null); + containerDom.current = getContainer(container); + + const scroll = useScroll(typeof container === 'function' ? containerDom.current : document); useMount(() => { smoothscroll.polyfill(); @@ -44,31 +54,31 @@ const BackTop: React.FC = (props) => { const targetHeight = isWindow(backTopDom.current) ? 0 : backTopDom.current?.offsetTop || 0; useEffect(() => { - // 当滚动条滚动到超过锚点二分之一个屏幕后,显示回到顶部按钮 - const screenHeight = window.innerHeight; - if (scroll?.top > screenHeight / 2 + targetHeight) { + // 当滚动条滚动到 设置滚动高度时,显示回到顶部按钮 + if (scroll?.top >= visibilityHeight) { setTrue(); } else { setFalse(); } - }, [scroll, setTrue, setFalse, targetHeight]); + }, [scroll, setTrue, setFalse, visibilityHeight]); - const onClick = () => document.documentElement.scrollTo({ top: targetHeight, behavior: 'smooth' }); + const onClick = () => { + containerDom.current.scrollTo({ top: 0 + targetHeight, behavior: 'smooth' }); + onToTop?.(); + }; return withNativeProps( props,
{isString(icon) ? : icon} {text && ( -
+
{text}
)} diff --git a/src/back-top/_example/base.tsx b/src/back-top/_example/base.tsx new file mode 100644 index 00000000..35d7b245 --- /dev/null +++ b/src/back-top/_example/base.tsx @@ -0,0 +1,42 @@ +import React, { useState, useCallback } from 'react'; +import { BackTop, Button } from 'tdesign-mobile-react'; +import './style/index.less'; + +export default function Base({ visible, onClose, container }) { + const [theme, setTheme] = useState({ + theme: 'round', + text: '顶部', + }); + + // 切换主题 + const onClick = useCallback( + (theme, text) => { + setTheme({ + theme, + text, + }); + onClose(); + const containerElement = container(); + containerElement.scrollTop = 1200; + }, + [onClose, container], + ); + + function handleToTop() { + console.log('handleToTop'); + } + + return ( + <> + {visible ? : null} +
+ + +
+ + ); +} diff --git a/src/back-top/_example/half-round.jsx b/src/back-top/_example/half-round.jsx deleted file mode 100644 index 817f0486..00000000 --- a/src/back-top/_example/half-round.jsx +++ /dev/null @@ -1,35 +0,0 @@ -import React, { useState, useCallback } from 'react'; -import { BackTop, Button } from 'tdesign-mobile-react'; -import './style/index.less'; - -export default function HalfRound({ visible, onClose }) { - const [theme, setTheme] = useState({ - theme: 'half-round', - text: '返回顶部', - }); - - // 切换主题 - const onClick = useCallback( - (theme) => { - setTheme({ theme, text: '返回顶部' }); - onClose(); - window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); - }, - [onClose], - ); - - return ( - <> - {visible ? : null} - -
- - -
- - ); -} diff --git a/src/back-top/_example/index.jsx b/src/back-top/_example/index.tsx similarity index 59% rename from src/back-top/_example/index.jsx rename to src/back-top/_example/index.tsx index 7e0748a1..189b4427 100644 --- a/src/back-top/_example/index.jsx +++ b/src/back-top/_example/index.tsx @@ -1,23 +1,16 @@ -import React, { useState } from 'react'; +import React, { useRef, useState } from 'react'; import { Skeleton } from 'tdesign-mobile-react'; import TDemoHeader from '../../../site/mobile/components/DemoHeader'; import TDemoBlock from '../../../site/mobile/components/DemoBlock'; import './style/index.less'; -import RoundDemo from './round'; -import HalfRoundDemo from './half-round'; +import BaseDemo from './base'; export default function Base() { const [visible, setVisible] = useState(false); - const [visible1, setVisible1] = useState(false); + const containerRef = useRef(null); const onClose = () => { setVisible(true); - setVisible1(false); - }; - - const onClose1 = () => { - setVisible(false); - setVisible1(true); }; const rowCols = [ @@ -33,20 +26,17 @@ export default function Base() { ]; return ( -
+
- - - - - + + containerRef.current} />
- {Array.from(Array(4), (item, key) => ( + {Array.from(Array(6), (_, key) => (
diff --git a/src/back-top/_example/round.jsx b/src/back-top/_example/round.jsx deleted file mode 100644 index da33787d..00000000 --- a/src/back-top/_example/round.jsx +++ /dev/null @@ -1,43 +0,0 @@ -import React, { useState, useCallback } from 'react'; -import { BackTop, Button } from 'tdesign-mobile-react'; -import './style/index.less'; - -export default function Round({ visible, onClose }) { - const [theme, setTheme] = useState({ - theme: 'round', - text: '顶部', - }); - - // 切换主题 - const onClick = useCallback( - (theme, text) => { - setTheme({ - theme, - text, - }); - onClose(); - window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); - }, - [onClose], - ); - - return ( - <> - {visible ? : null} -
- - - - -
- - ); -} diff --git a/src/back-top/_example/style/index.less b/src/back-top/_example/style/index.less index 32c6c490..95bf62ee 100644 --- a/src/back-top/_example/style/index.less +++ b/src/back-top/_example/style/index.less @@ -1,5 +1,7 @@ .tdesign-mobile-react-demo { background: #fff; + overflow: auto; + height: 100vh; .button-group { display: flex; diff --git a/src/back-top/back-top.en-US.md b/src/back-top/back-top.en-US.md new file mode 100644 index 00000000..5029aad8 --- /dev/null +++ b/src/back-top/back-top.en-US.md @@ -0,0 +1,19 @@ +:: BASE_DOC :: + +## API + + +### BackTop Props + +name | type | default | description | required +-- | -- | -- | -- | -- +className | String | - | className of component | N +style | Object | - | CSS(Cascading Style Sheets),Typescript:`React.CSSProperties` | N +container | Function | - | Typescript:`() => HTMLElement` | N +fixed | Boolean | true | \- | N +icon | TNode | true | Typescript:`boolean \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +target | Function | - | Typescript:`() => HTMLElement` | N +text | String | '' | \- | N +theme | String | round | options: round/half-round/round-dark/half-round-dark | N +visibilityHeight | Number | 200 | \- | N +onToTop | Function | | Typescript:`() => void`
| N diff --git a/src/back-top/back-top.md b/src/back-top/back-top.md index 9ae7f716..db475e7d 100644 --- a/src/back-top/back-top.md +++ b/src/back-top/back-top.md @@ -4,12 +4,15 @@ ### BackTop Props -名称 | 类型 | 默认值 | 说明 | 必传 +名称 | 类型 | 默认值 | 描述 | 必传 -- | -- | -- | -- | -- className | String | - | 类名 | N style | Object | - | 样式,TS 类型:`React.CSSProperties` | N +container | Function | - | 滚动的容器。TS 类型:`() => HTMLElement` | N fixed | Boolean | true | 是否绝对定位固定到屏幕右下方 | N -icon | TNode | 'backtop' | 图标。TS 类型:`string | TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N -target | Object | () => window | 定位滚动到指定对象。TS 类型:`() => HTMLElement` | N +icon | TNode | true | 图标。TS 类型:`boolean \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +target | Function | - | 定位滚动到指定对象。TS 类型:`() => HTMLElement` | N text | String | '' | 文案 | N theme | String | round | 预设的样式类型。可选项:round/half-round/round-dark/half-round-dark | N +visibilityHeight | Number | 200 | 滚动高度达到此参数值才出现 | N +onToTop | Function | | TS 类型:`() => void`
点击触发 | N diff --git a/src/back-top/defaultProps.ts b/src/back-top/defaultProps.ts new file mode 100644 index 00000000..891a20d3 --- /dev/null +++ b/src/back-top/defaultProps.ts @@ -0,0 +1,13 @@ +/** + * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC + * */ + +import { TdBackTopProps } from './type'; + +export const backTopDefaultProps: TdBackTopProps = { + fixed: true, + icon: true, + text: '', + theme: 'round', + visibilityHeight: 200, +}; diff --git a/src/back-top/style/index.js b/src/back-top/style/index.js index 81872b59..7f80648b 100644 --- a/src/back-top/style/index.js +++ b/src/back-top/style/index.js @@ -1 +1 @@ -import '../../_common/style/mobile/components/back-top/_index.less'; +import '../../_common/style/mobile/components/back-top/v2/_index.less'; diff --git a/src/back-top/type.ts b/src/back-top/type.ts index f39aba05..ec78f381 100644 --- a/src/back-top/type.ts +++ b/src/back-top/type.ts @@ -7,6 +7,10 @@ import { TNode } from '../common'; export interface TdBackTopProps { + /** + * 滚动的容器 + */ + container?: () => HTMLElement; /** * 是否绝对定位固定到屏幕右下方 * @default true @@ -14,12 +18,11 @@ export interface TdBackTopProps { fixed?: boolean; /** * 图标 - * @default 'backtop' + * @default true */ icon?: TNode; /** * 定位滚动到指定对象 - * @default () => window */ target?: () => HTMLElement; /** @@ -32,4 +35,13 @@ export interface TdBackTopProps { * @default round */ theme?: 'round' | 'half-round' | 'round-dark' | 'half-round-dark'; + /** + * 滚动高度达到此参数值才出现 + * @default 200 + */ + visibilityHeight?: number; + /** + * 点击触发 + */ + onToTop?: () => void; } diff --git a/test/snap/__snapshots__/csr.test.jsx.snap b/test/snap/__snapshots__/csr.test.jsx.snap index cf509620..1e001f13 100644 --- a/test/snap/__snapshots__/csr.test.jsx.snap +++ b/test/snap/__snapshots__/csr.test.jsx.snap @@ -1,5 +1,293 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`csr snapshot test > csr test src/back-top/_example/base.tsx 1`] = ` +
+
+ + +
+
+`; + +exports[`csr snapshot test > csr test src/back-top/_example/index.tsx 1`] = ` +
+
+
+

+ BackTop 返回顶部 +

+

+ 当页面过长往下滑动是会出现返回顶部的便捷操作,帮助用户快速回到页面顶部 +

+
+
+
+

+ 形状 +

+ +
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`; + exports[`csr snapshot test > csr test src/divider/_example/base.tsx 1`] = `
csr test src/result/_example/theme.tsx 1`] = `
`; +exports[`ssr snapshot test > ssr test src/back-top/_example/base.tsx 1`] = `"
"`; + +exports[`ssr snapshot test > ssr test src/back-top/_example/index.tsx 1`] = `"

BackTop 返回顶部

当页面过长往下滑动是会出现返回顶部的便捷操作,帮助用户快速回到页面顶部

形状

"`; + exports[`ssr snapshot test > ssr test src/divider/_example/base.tsx 1`] = `"
水平分割线
带文字水平分割线
垂直分割线
文字信息文字信息文字信息
"`; exports[`ssr snapshot test > ssr test src/divider/_example/index.tsx 1`] = `"

Divider 分割符

用于分割、组织、细化有一定逻辑的组织元素内容和页面结构。

01 组件类型

水平分割线
带文字水平分割线
垂直分割线
文字信息文字信息文字信息

02 组件状态

虚线样式
"`; diff --git a/test/snap/__snapshots__/ssr.test.jsx.snap b/test/snap/__snapshots__/ssr.test.jsx.snap index e50fd44d..c889b0a4 100644 --- a/test/snap/__snapshots__/ssr.test.jsx.snap +++ b/test/snap/__snapshots__/ssr.test.jsx.snap @@ -1,5 +1,9 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`ssr snapshot test > ssr test src/back-top/_example/base.tsx 1`] = `"
"`; + +exports[`ssr snapshot test > ssr test src/back-top/_example/index.tsx 1`] = `"

BackTop 返回顶部

当页面过长往下滑动是会出现返回顶部的便捷操作,帮助用户快速回到页面顶部

形状

"`; + exports[`ssr snapshot test > ssr test src/divider/_example/base.tsx 1`] = `"
水平分割线
带文字水平分割线
垂直分割线
文字信息文字信息文字信息
"`; exports[`ssr snapshot test > ssr test src/divider/_example/index.tsx 1`] = `"

Divider 分割符

用于分割、组织、细化有一定逻辑的组织元素内容和页面结构。

01 组件类型

水平分割线
带文字水平分割线
垂直分割线
文字信息文字信息文字信息

02 组件状态

虚线样式
"`;