Allows navigation between HTML elements in one or two dimensions with mouse and non-mouse devices in a unified API.
Note that this is specifically built for usage within lit
or element-vir
HTML templates.
npm i device-navigation
Construct a NavController
instance and pass it to all nav
directive calls:
import {defineElementNoInputs, html} from 'element-vir';
import {nav, NavController} from 'device-navigation';
export const MyElement = defineElementNoInputs({
tagName: 'my-element',
state({host}) {
return {
navController: new NavController(host),
};
},
render({state}) {
return html`
<main>
<div ${nav(state.navController)}></div>
<div ${nav(state.navController)}></div>
<div ${nav(state.navController)}></div>
</main>
`;
},
});
Call NavController
methods from within listeners:
import {defineElementNoInputs, html} from 'element-vir';
import {nav, NavController, NavDirection} from 'device-navigation';
export const MyElement = defineElementNoInputs({
tagName: 'my-element',
state({host}) {
const navController = new NavController(host);
window.addEventListener('keydown', (event) => {
if (event.code === 'ArrowUp') {
navController.navigate({
allowWrapping: true,
direction: NavDirection.Up,
});
} else if (event.code === 'ArrowDown') {
navController.navigate({
allowWrapping: true,
direction: NavDirection.Down,
});
} else if (event.code === 'Enter') {
navController.enterInto();
}
// etc.
});
return {
navController,
};
},
render({state}) {
return html`
<main>
<div ${nav(state.navController)}></div>
<div ${nav(state.navController)}></div>
<div ${nav(state.navController)}></div>
</main>
`;
},
});
To see a full example, see the demo element.
Apply styles vis the navAttribute.css
selector creator:
import {css, defineElementNoInputs, html} from 'element-vir';
import {nav, navAttribute, NavController, NavValue} from 'device-navigation';
export const MyElement = defineElementNoInputs({
tagName: 'my-element',
styles: css`
div {
border: 2px solid blue;
}
${navAttribute.css({navValue: NavValue.Active})} {
border-color: red;
}
${navAttribute.css({navValue: NavValue.Focused})} {
border-color: green;
}
`,
state({host}) {
return {
navController: new NavController(host),
};
},
render({state}) {
return html`
<main>
<div ${nav(state.navController)}></div>
<div ${nav(state.navController)}></div>
<div ${nav(state.navController)}></div>
</main>
`;
},
});