使用箭头键导航 material-ui 列表

IT技术 reactjs material-ui
2021-05-24 17:18:45

我正在使用 material-ui 制作电子应用程序。有些屏幕是主从,我使用列表来显示概览。我想让使用箭头键浏览此列表成为可能。是否有内置选项可以执行此操作?

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

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

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个回答

您可以使用主界面列表详细界面卡片

您的父组件将处理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({ currentDetailIndex: this.state.currentDetailIndex - 1 });
        }
    }

    moveDown = () => {
        if (this.state.currentDetailIndex < this.state.numOfListItems - 1) {
            this.setState({ currentDetailIndex: 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>
        );
    };
}