UNPKG

device-navigation

Version:

Navigate HTML elements in two dimensions with non-pointer devices.

135 lines (111 loc) 4.12 kB
# device-navigation 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`](https://www.npmjs.com/package/lit) or [`element-vir`](https://www.npmjs.com/package/lit) HTML templates. - [demo](https://electrovir.github.io/device-navigation) - [docs](https://electrovir.github.io/device-navigation/docs) - [code](https://github.com/electrovir/device-navigation) - [npm](https://www.npmjs.com/package/device-navigation) ## Install ``` npm i device-navigation ``` ## Usage 1. Construct a `NavController` instance and pass it to all `nav` directive calls: <!-- example-link: src/readme-examples/nav-controller.example.ts --> ```TypeScript 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> `; }, }); ``` 2. Call `NavController` methods from within listeners: <!-- example-link: src/readme-examples/navigation.example.ts --> ```TypeScript 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](https://github.com/electrovir/device-navigation/blob/dev/src/test/elements/vir-test-app.element.ts). ## Styles Apply styles vis the `navAttribute.css` selector creator: <!-- example-link: src/readme-examples/styles.example.ts --> ```TypeScript 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> `; }, }); ```