I'm using material-ui to make an electron application. Some screens are master-detail and I'm using a list to show the overview. I would like to make it possible to navigate this list with arrow keys. Is there a builtin option to do this?
If it is not built in, what is the best approach to make this?
Update: I made my own component for now. Not sure if it is the best solution, but seems to work:
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>
);
}
Here is an example how it can be used:
<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>
You could use a List for the master-interface and a Card for the detail-interface.
Your parent component will handle List
selection changes from your master-interface and be responsible for sending the correct detail data to the Card
.
Here's an example of how this structure would look like using Material-UI components:
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>
);
};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With