Skip to content

Commit

Permalink
feat(tree): support scrollTo when virtual scrolling (#2460)
Browse files Browse the repository at this point in the history
* feat(tree): support scrollto when virtual scrolling

* chore: update snapshot
  • Loading branch information
uyarn authored Aug 23, 2023
1 parent 9e6d5de commit c596865
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 6 deletions.
4 changes: 3 additions & 1 deletion src/tree/Tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ const Tree = forwardRef((props: TreeProps, ref: React.Ref<TreeInstanceFunctions>
treeNodeStyle: virtualTreeNodeStyle,
cursorStyle,
handleRowMounted,
scrollToElement,
} = useTreeVirtualScroll({
treeRef,
scroll,
Expand Down Expand Up @@ -149,6 +150,7 @@ const Tree = forwardRef((props: TreeProps, ref: React.Ref<TreeInstanceFunctions>
ref,
() => ({
store,
scrollTo: scrollToElement,
appendTo(value, newData) {
let list = [];
if (Array.isArray(newData)) {
Expand Down Expand Up @@ -216,7 +218,7 @@ const Tree = forwardRef((props: TreeProps, ref: React.Ref<TreeInstanceFunctions>
}
},
}),
[store, setExpanded, setActived, setChecked],
[store, setExpanded, setActived, setChecked, scrollToElement],
);

/* ======== render ======= */
Expand Down
11 changes: 9 additions & 2 deletions src/tree/_example/vscroll.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { useEffect, useState } from 'react';
import { Tree, Switch, Space, Form } from 'tdesign-react';
import React, { useEffect, useState, useRef } from 'react';
import { Tree, Switch, Space, Form, Button } from 'tdesign-react';

export default () => {
const [checkable, setCheckable] = useState(true);
const [showLine, toggleShowLine] = useState(true);
const [options, setOptions] = useState([]);
const treeRef = useRef(null);

useEffect(() => {
const newOptions = [];
Expand All @@ -27,6 +28,10 @@ export default () => {
setOptions(newOptions);
}, []);

const handleScroll = () => {
treeRef.current.scrollTo({ index: 100, behavior: 'smooth' });
};

const defaultChecked = ['1.2', '2.2'];
return (
<Space direction="vertical">
Expand All @@ -38,6 +43,7 @@ export default () => {
<Switch onChange={toggleShowLine} />
</Form.FormItem>
</Form>
<Button onClick={handleScroll}>scroll to special node</Button>
<Tree
data={options}
defaultValue={defaultChecked}
Expand All @@ -49,6 +55,7 @@ export default () => {
hover
scroll={{ type: 'virtual' }}
style={{ height: '300px' }}
ref={treeRef}
/>
</Space>
);
Expand Down
2 changes: 2 additions & 0 deletions src/tree/hooks/useTreeVirtualScroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export default function useTreeVirtualScroll({
scrollHeight = null,
translateY = null,
handleRowMounted = null,
scrollToElement,
} = useVirtualScroll(treeRef, {
data: data || [],
scroll: scrollParams,
Expand Down Expand Up @@ -100,5 +101,6 @@ export default function useTreeVirtualScroll({
isVirtual,
cursorStyle,
treeNodeStyle,
scrollToElement,
};
}
1 change: 1 addition & 0 deletions src/tree/tree.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ getPath | `(value: TreeNodeValue)` | `TreeNodeModel<T>[]` | required
insertAfter | `(value: TreeNodeValue, newData: T)` | \- | required
insertBefore | `(value: TreeNodeValue, newData: T)` | \- | required
remove | `(value: TreeNodeValue)` | \- | required
scrollTo | `(scrollToParams: ScrollToElementParams)` | \- | support scrolling to a specific node when virtual scrolling
setItem | `(value: TreeNodeValue, options: TreeNodeState)` | \- | required

### TreeNodeState
Expand Down
1 change: 1 addition & 0 deletions src/tree/tree.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ getPath | `(value: TreeNodeValue)` | `TreeNodeModel<T>[]` | 必需。自下而
insertAfter | `(value: TreeNodeValue, newData: T)` | \- | 必需。插入新节点到指定节点后面,泛型 `T` 表示树节点 TS 类型
insertBefore | `(value: TreeNodeValue, newData: T)` | \- | 必需。插入新节点到指定节点前面,泛型 `T` 表示树节点 TS 类型
remove | `(value: TreeNodeValue)` | \- | 必需。移除指定节点
scrollTo | `(scrollToParams: ScrollToElementParams)` | \- | 虚拟滚动场景下 支持指定滚动到具体的节点
setItem | `(value: TreeNodeValue, options: TreeNodeState)` | \- | 必需。设置节点状态

### TreeNodeState
Expand Down
8 changes: 6 additions & 2 deletions src/tree/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* */

import { CheckboxProps } from '../checkbox';
import { TNode, TreeOptionData, TScroll } from '../common';
import { TNode, TreeOptionData, TScroll, ScrollToElementParams } from '../common';
import { MouseEvent, WheelEvent, DragEvent } from 'react';

export interface TdTreeProps<T extends TreeOptionData = TreeOptionData> {
Expand Down Expand Up @@ -118,7 +118,7 @@ export interface TdTreeProps<T extends TreeOptionData = TreeOptionData> {
*/
icon?: boolean | TNode<TreeNodeModel<T>>;
/**
* 用来定义 `value / label / children` 在 `data` 数据中对应的字段别名,示例:`{ value: 'key', label 'name', children: 'list' }`
* 用来定义 `value / label / disabled / children` 在 `data` 数据中对应的字段别名,示例:`{ value: 'key', label 'name', children: 'list' }`。其中,disabled 待开发。
*/
keys?: TreeKeysType;
/**
Expand Down Expand Up @@ -274,6 +274,10 @@ export interface TreeInstanceFunctions<T extends TreeOptionData = TreeOptionData
* 移除指定节点
*/
remove: (value: TreeNodeValue) => void;
/**
* 虚拟滚动场景下 支持指定滚动到具体的节点
*/
scrollTo?: (scrollToParams: ScrollToElementParams) => void;
/**
* 设置节点状态
*/
Expand Down
28 changes: 28 additions & 0 deletions test/snap/__snapshots__/csr.test.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -285176,6 +285176,20 @@ exports[`csr snapshot test > csr test src/tree/_example/vscroll.jsx 1`] = `
</div>
</form>
</div>
<div
class="t-space-item"
>
<button
class="t-button t-button--theme-primary t-button--variant-base"
type="button"
>
<span
class="t-button__text"
>
scroll to special node
</span>
</button>
</div>
<div
class="t-space-item"
>
Expand Down Expand Up @@ -285268,6 +285282,20 @@ exports[`csr snapshot test > csr test src/tree/_example/vscroll.jsx 1`] = `
</div>
</form>
</div>
<div
class="t-space-item"
>
<button
class="t-button t-button--theme-primary t-button--variant-base"
type="button"
>
<span
class="t-button__text"
>
scroll to special node
</span>
</button>
</div>
<div
class="t-space-item"
>
Expand Down
2 changes: 1 addition & 1 deletion test/snap/__snapshots__/ssr.test.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,7 @@ exports[`ssr snapshot test > ssr test src/tree/_example/state.jsx 1`] = `"<div s

exports[`ssr snapshot test > ssr test src/tree/_example/sync.jsx 1`] = `"<div style=\\"gap:16px;width:100%\\" class=\\"t-space t-space-vertical\\"><div class=\\"t-space-item\\"><div class=\\"t-input-adornment\\"><span class=\\"t-input-adornment__prepend\\"><span class=\\"t-input-adornment__text\\">checked:</span></span><div class=\\"t-input__wrap\\" value=\\"{1.1.1.1}, {1.1.1.2}\\"><div class=\\"t-input t-align-left\\"><input placeholder=\\"please enter\\" type=\\"text\\" class=\\"t-input__inner\\" value=\\"{1.1.1.1}, {1.1.1.2}\\"/></div></div></div></div><div class=\\"t-space-item\\"><div class=\\"t-input-adornment\\"><span class=\\"t-input-adornment__prepend\\"><span class=\\"t-input-adornment__text\\">expanded:</span></span><div class=\\"t-input__wrap\\" value=\\"{1}, {1.1}, {1.1.1}, {2}\\"><div class=\\"t-input t-align-left\\"><input placeholder=\\"please enter\\" type=\\"text\\" class=\\"t-input__inner\\" value=\\"{1}, {1.1}, {1.1.1}, {2}\\"/></div></div></div></div><div class=\\"t-space-item\\"><div class=\\"t-input-adornment\\"><span class=\\"t-input-adornment__prepend\\"><span class=\\"t-input-adornment__text\\">actived:</span></span><div class=\\"t-input__wrap\\" value=\\"{2}\\"><div class=\\"t-input t-align-left\\"><input placeholder=\\"please enter\\" type=\\"text\\" class=\\"t-input__inner\\" value=\\"{2}\\"/></div></div></div></div><div class=\\"t-space-item\\"><div class=\\"t-tree t-tree--checkable t-tree--transition\\">Tree Empty Data</div></div></div>"`;

exports[`ssr snapshot test > ssr test src/tree/_example/vscroll.jsx 1`] = `"<div style=\\"gap:16px\\" class=\\"t-space t-space-vertical\\"><div class=\\"t-space-item\\"><form class=\\"t-form\\"><div class=\\"t-form__item\\"><div class=\\"t-form__label t-form__label--right\\" style=\\"width:100px\\"><label>可选</label></div><div class=\\"t-form__controls\\" style=\\"margin-left:100px\\"><div class=\\"t-form__controls-content\\"><button type=\\"button\\" role=\\"switch\\" class=\\"t-switch t-is-checked t-size-m\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content\\"></div></button></div></div></div><div class=\\"t-form__item\\"><div class=\\"t-form__label t-form__label--right\\" style=\\"width:100px\\"><label>展示连线</label></div><div class=\\"t-form__controls\\" style=\\"margin-left:100px\\"><div class=\\"t-form__controls-content\\"><button type=\\"button\\" role=\\"switch\\" class=\\"t-switch t-is-checked t-size-m\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content\\"></div></button></div></div></div></form></div><div class=\\"t-space-item\\"><div class=\\"t-tree t-tree--hoverable t-tree--checkable t-tree--transition\\" style=\\"height:300px\\">Tree Empty Data</div></div></div>"`;
exports[`ssr snapshot test > ssr test src/tree/_example/vscroll.jsx 1`] = `"<div style=\\"gap:16px\\" class=\\"t-space t-space-vertical\\"><div class=\\"t-space-item\\"><form class=\\"t-form\\"><div class=\\"t-form__item\\"><div class=\\"t-form__label t-form__label--right\\" style=\\"width:100px\\"><label>可选</label></div><div class=\\"t-form__controls\\" style=\\"margin-left:100px\\"><div class=\\"t-form__controls-content\\"><button type=\\"button\\" role=\\"switch\\" class=\\"t-switch t-is-checked t-size-m\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content\\"></div></button></div></div></div><div class=\\"t-form__item\\"><div class=\\"t-form__label t-form__label--right\\" style=\\"width:100px\\"><label>展示连线</label></div><div class=\\"t-form__controls\\" style=\\"margin-left:100px\\"><div class=\\"t-form__controls-content\\"><button type=\\"button\\" role=\\"switch\\" class=\\"t-switch t-is-checked t-size-m\\"><span class=\\"t-switch__handle\\"></span><div class=\\"t-switch__content\\"></div></button></div></div></div></form></div><div class=\\"t-space-item\\"><button type=\\"button\\" class=\\"t-button t-button--theme-primary t-button--variant-base\\"><span class=\\"t-button__text\\">scroll to special node</span></button></div><div class=\\"t-space-item\\"><div class=\\"t-tree t-tree--hoverable t-tree--checkable t-tree--transition\\" style=\\"height:300px\\">Tree Empty Data</div></div></div>"`;

exports[`ssr snapshot test > ssr test src/tree-select/_example/base.jsx 1`] = `"<div class=\\"t-tree-select t-select-input\\" style=\\"width:300px\\"><div class=\\"t-input__wrap\\" value=\\"广东省\\"><div class=\\"t-input t-is-readonly t-align-left t-input--prefix t-input--suffix\\"><div class=\\"t-input__prefix\\"></div><input placeholder=\\"please select\\" type=\\"text\\" class=\\"t-input__inner\\" readonly=\\"\\" value=\\"广东省\\"/><span class=\\"t-input__suffix t-input__suffix-icon\\"><svg class=\\"t-fake-arrow\\" width=\\"16\\" height=\\"16\\" viewBox=\\"0 0 16 16\\" fill=\\"none\\" xmlns=\\"http://www.w3.org/2000/svg\\"><path d=\\"M3.75 5.7998L7.99274 10.0425L12.2361 5.79921\\" stroke=\\"black\\" stroke-opacity=\\"0.9\\" stroke-width=\\"1.3\\"></path></svg></span></div></div></div>"`;

Expand Down

0 comments on commit c596865

Please sign in to comment.