代码之家  ›  专栏  ›  技术社区  ›  roeland

使用箭头键导航材质用户界面列表

  •  1
  • roeland  · 技术社区  · 6 年前

    我正在使用MaterialUI制作电子应用程序。有些屏幕是主细节,我使用列表来显示概述。我想用箭头键来导航这个列表。有内置选项吗?

    如果它不是内置的,那么最好的方法是什么?

    更新: 现在我自己做了一个组件。不确定这是否是最佳解决方案,但似乎有效:

    export default function NavigateList(props) {
        const { children, data, ...other } = props;
        const elements = data.map((val, i) => children(val, i));
    
        function gotoPrevElement() {
            const selected = elements.findIndex(e => e.props.selected);
            if (selected > 0) {
                const el = elements[selected - 1];
                el.props.onClick(data[selected - 1]);
            }
        }
        function gotoNextElement() {
            const selected = elements.findIndex(e => e.props.selected);
            if (selected > -1 && selected < elements.length - 1) {
                const el = elements[selected + 1];
                el.props.onClick(data[selected + 1]);
            }
        }
    
        function handleKey(e) {
            if (e.key === "ArrowDown") {
                gotoNextElement();
            }
            if (e.key === "ArrowUp") {
                gotoPrevElement();
            }
        }
    
        return (
            <List onKeyDown={handleKey} {...other}>
                {elements}
            </List>
        );
    }
    

    下面是一个如何使用它的示例:

    <NavigateList data={people}>
        {(p, i) => (
            <ListItem
                button
                key={i}
                selected={checkIfSelected(p)}
                onClick={e => setSelected(p)}
            >
                <ListItemText
                    primary={p.primary}
                    secondary={p.secondary}
                />
            </ListItem>
        )}
    </NavigateList>
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Shawn Andrews    6 年前

    你可以使用 List 对于主界面和 Card 用于细节界面。

    您的父组件将处理 List 从主界面选择更改,并负责将正确的详细数据发送到 Card .

    以下是使用Material UI组件时此结构的外观示例:

    class ParentComponent extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                currentDetailIndex: 0,
                numOfListItems: 10,
                detailData: [
                    {...},
                    {...},
                    ...
                ]
            };
        }
    
        changeDetailIndex = (newIndex) => {
            this.setState({ currentDetailIndex: newIndex });
        }
    
        moveUp = () => {
            if (this.state.currentDetailIndex > 0) {
                this.setState({ this.state.currentDetailIndex - 1 });
            }
        }
    
        moveDown = () => {
            if (this.state.currentDetailIndex < this.state.numOfListItems - 1) {
                this.setState({ this.state.currentDetailIndex + 1 });
            }
        }
    
        onKeyPressed(e) {
            if (e.keyCode == '38') {
                // up arrow
                this.moveUp();
            }
            else if (e.keyCode == '40') {
                // down arrow
                this.moveDown();
            }
        }
    
        render() {
            return (
                <div>
                    <List component="nav" onKeyDown={this.onKeyPressed}>
                        <ListItem onClick={() => { this.changeDetailIndex(someIndex); }}>'s... 
                    </List>
                    <Card>
                        <CardContent>
                            <SomeDetailComponent data={this.state.detailData[this.state.currentDetailIndex]} />
                        </CardContent>
                    </Card>
                </div>
            );
        };
    }