Skip to content

Commit

Permalink
Merge pull request #2613 from XiaoMi/feature/tree(scrolltop)
Browse files Browse the repository at this point in the history
feat(tree): 增加 scrollTo 方法
  • Loading branch information
solarjoker authored Oct 8, 2023
2 parents 0532f11 + e1da14c commit 15213b1
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/green-teachers-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hi-ui/tree": patch
---

feat: 增加 TreeHelper,支持 scrollTo 方法
5 changes: 5 additions & 0 deletions .changeset/sixty-fishes-tan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hi-ui/hiui": patch
---

Tree feat: 增加 TreeHelper,支持 scrollTo 方法
17 changes: 15 additions & 2 deletions packages/ui/tree/src/Tree.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { forwardRef, useMemo, useRef } from 'react'
import React, { forwardRef, useMemo, useRef, useImperativeHandle } from 'react'
import { HiBaseSizeEnum } from '@hi-ui/core'
import { cx, getPrefixCls } from '@hi-ui/classname'
import { __DEV__ } from '@hi-ui/env'
Expand All @@ -20,9 +20,10 @@ import {
TreeNodeRequiredProps,
TreeNodeEventData,
FlattedTreeNodeData,
TreeHelper,
} from './types'
import { TreeProvider } from './context'
import VirtualList from '@hi-ui/virtual-list'
import VirtualList, { ListRef } from '@hi-ui/virtual-list'
import { MotionTreeNode } from './MotionTreeNode'
import { TreeNode } from './TreeNode'
import { useLatestCallback } from '@hi-ui/use-latest'
Expand Down Expand Up @@ -86,6 +87,7 @@ export const Tree = forwardRef<HTMLUListElement | null, TreeProps>(
checkedMode = 'ALL',
expandOnSelect,
size = 'lg',
innerRef,
...rest
},
ref
Expand Down Expand Up @@ -217,6 +219,12 @@ export const Tree = forwardRef<HTMLUListElement | null, TreeProps>(
return Math.ceil(height / itemHeight) + 1
}, [virtual, height, itemHeight])

const listRef = useRef<ListRef>(null)

useImperativeHandle(innerRef, () => ({
scrollTo: listRef.current?.scrollTo,
}))

const cls = cx(prefixCls, className, `${prefixCls}--size-${size}`)

return (
Expand All @@ -231,6 +239,7 @@ export const Tree = forwardRef<HTMLUListElement | null, TreeProps>(
{...rest}
>
<VirtualList
ref={listRef}
itemKey="id"
fullHeight={false}
height={height}
Expand Down Expand Up @@ -456,6 +465,10 @@ export interface TreeProps {
* 设置大小
*/
size?: HiBaseSizeEnum
/**
* 提供辅助方法的内部引用
*/
innerRef?: React.Ref<TreeHelper>
}

if (__DEV__) {
Expand Down
17 changes: 17 additions & 0 deletions packages/ui/tree/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,20 @@ export type TreeEditActions = {
*/
closeMenu: () => void
}

export type ScrollAlign = 'top' | 'bottom' | 'auto'
export type ScrollConfig =
| {
index: number
align?: ScrollAlign
offset?: number
}
| {
key: React.Key
align?: ScrollAlign
offset?: number
}

export interface TreeHelper {
scrollTo?: (arg: number | ScrollConfig) => void
}
1 change: 1 addition & 0 deletions packages/ui/tree/stories/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export * from './custom-title.stories'
export * from './custom-icon.stories'
export * from './expand-on-click.stories'
export * from './size.stories'
export * from './scroll-to.stories'

export default {
title: 'Data Display/Tree',
Expand Down
59 changes: 59 additions & 0 deletions packages/ui/tree/stories/scroll-to.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react'
import Tree, { TreeHelper } from '../src'
import Button from '@hi-ui/button'

/**
* @title 设置滚动位置
* @desc 仅在设置 height 属性即虚拟列表下有效
*/
export const ScrollTo = () => {
const treeRef = React.useRef<TreeHelper>(null)

const [treeData] = React.useState(() => {
function dig(path = '0', level) {
const list: { title: string; id: string; children: any[] }[] = []

for (let i = 0; i < 5; i += 1) {
const id = `${path}-${i}`
const treeNode = {
title: id,
id,
children: [] as any[],
}

if (level > 0) {
treeNode.children = dig(id, level - 1)
}

list.push(treeNode)
}
return list
}

const treeData = dig('0', 4)
return treeData
})

return (
<>
<h1>ScrollTo for Tree</h1>
<div className="tree-scroll-to__wrap">
<Button
onClick={() => {
// key 为节点 id
treeRef.current?.scrollTo?.({ key: '0-2-2-0-0', align: 'top' })
}}
>
scroll to key: 0-2-2-0-0
</Button>
<Tree
innerRef={treeRef}
height={300}
defaultExpandAll
data={treeData}
expandOnSelect
></Tree>
</div>
</>
)
}

0 comments on commit 15213b1

Please sign in to comment.