此功能仍处于实验阶段。“Experimental”(实验性)意味着这是早期实现,可能会发生剧烈且破坏性的更改。

开发指南

TreeGrid、TreeGridRow 和 TreeGridCell 是用于创建树形层次结构的组件。它们不是具有视觉样式的组件,而是帮助在树形网格结构中添加键盘导航和动态 tabindex 行为。

树形网格是一种分层二维 UI 组件,例如可用于实现文件系统浏览器。

树形网格允许用户使用箭头键进行导航。向上/向下键可在行之间垂直导航,向左/向右键可在行内的可聚焦元素之间水平导航。

有关树形网格的更多信息,请参阅以下链接:

  • https://www.w3.org/TR/wai-aria-practices/examples/treegrid/treegrid-1.html

用法

TreeGrid 会渲染 table 和 tbody 元素,旨在与 TreeGridRow (tr) 和 TreeGridCell (td) 配合使用以构建网格。

function TreeMenu() {
    return (
        <TreeGrid>
            <TreeGridRow level={ 1 } positionInSet={ 1 } setSize={ 2 }>
                <TreeGridCell>
                    { ( props ) => (
                        <Button onClick={ onSelect } { ...props }>Select</Button>
                    ) }
                </TreeGridCell>
                <TreeGridCell>
                    { ( props ) => (
                        <Button onClick={ onMove } { ...props }>Move</Button>
                    ) }
                </TreeGridCell>
            </TreeGridRow>
            <TreeGridRow level={ 1 } positionInSet={ 2 } setSize={ 2 }>
                <TreeGridCell>
                    { ( props ) => (
                        <Button onClick={ onSelect } { ...props }>Select</Button>
                    ) }
                </TreeGridCell>
                <TreeGridCell>
                    { ( props ) => (
                        <Button onClick={ onMove } { ...props }>Move</Button>
                    ) }
                </TreeGridCell>
            </TreeGridRow>
            <TreeGridRow level={ 2 } positionInSet={ 1 } setSize={ 1 }>
                <TreeGridCell>
                    { ( props ) => (
                        <Button onClick={ onSelect } { ...props }>Select</Button>
                    ) }
                </TreeGridCell>
                <TreeGridCell>
                    { ( props ) => (
                        <Button onClick={ onMove } { ...props }>Move</Button>
                    ) }
                </TreeGridCell>
            </TreeGridRow>
        </TreeGrid>
    );
}

子组件

TreeGrid

Props

除了记录的回调函数外,任何指定的 props 都将传递给由 TreeGrid 渲染的 table 元素。

TreeGrid 始终应有子元素。

onFocusRow: ( event: KeyboardEvent, startRow: HTMLElement, destinationRow: HTMLElement ) => void

当焦点通过向上和向下键从一个行转移到另一行时触发的回调函数。当使用 Home 和 End 键将焦点从起始行移动到末尾行时,也会触发此回调函数。
该回调函数接收事件参数、焦点原本所在的起始行元素以及
焦点移动后的目标行元素。

  • Required: No
onCollapseRow: ( row: HTMLElement ) => void

一个传入要折叠的行元素的回调函数。

  • Required: No
onExpandRow: ( row: HTMLElement ) => void

一个传入要展开的行元素的回调函数。

  • Required: No

TreeGridRow

Props

除下面指定的 props 之外的其他 props 将传递给由 TreeGridRow 渲染的 tr 元素,因此,例如,也可以为行设置 className。

level: number

表示在分层树结构中的层级的整数值。计数从 1 开始。1 的值表示结构的根层级。

  • Required: Yes
positionInSet: number

表示在集合中位置的整数值。集合是指特定层级上的元素数量。计数从 1 开始。

  • Required: Yes
setSize: number

表示在该层级特定位置集合中项目总数的整数值。

  • Required: Yes
isExpanded: boolean

一个可选值,用于指定行是展开还是折叠。目前,此值仅在行上设置正确的 aria-expanded 属性,没有其他内置行为。

如果需要在行、单元格或单元格内的其他位置实现 aria-expanded,可以传递 isExpanded={ undefined }。为了使键盘导航继续正常工作,请添加带有 true/false 的 data-expanded 属性。这允许 TreeGrid 组件仍然管理键盘交互,同时允许将 aria-expanded 属性放置在其他位置。请参阅下面的示例。

  • Required: No
function TreeMenu() {
    return (
        <TreeGrid>
            <TreeGridRow level={ 1 } positionInSet={ 1 } setSize={ 2 } isExpanded={ undefined } data-expanded={ false }>
                <TreeGridCell>
                    { ( props ) => (
                        <Button aria-expanded="false" onClick={ onSelect } { ...props }>Select</Button>
                    ) }
                </TreeGridCell>
            </TreeGridRow>
        </TreeGrid>
    );
}

TreeGridCell

Props

TreeGridCell 不接受特定的 props。任何指定的 props 都将传递给由 TreeGridCell 渲染的 td 元素。

作为函数的 children

TreeGridCell 使用函数渲染子元素:

<TreeGridCell>
    { ( props ) => (
        <Button onClick={ doSomething } { ...props }>
            Do something
        </Button>
    ) }
</TreeGridCell>

作为 render prop 参数传递的 props 必须传递给单元格内的子可聚焦组件/元素。如果使用组件,它必须正确处理 onFocus、tabIndex 和 ref props,并将这些传递给其渲染的元素。这些 props 用于处理树形网格的动态 tabindex 功能。

相关组件

  • 此组件实现了 RovingTabIndex。