使用箭头键浏览物料用户界面列表

时间:2018-11-25 15:25:48

标签: reactjs material-ui

我正在使用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 个答案:

答案 0 :(得分:1)

您可以在主界面上使用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>
        );
    };
}