JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 475
  • Score
    100M100P100Q95555F
  • License (MIT or CC0 1.0)

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

Package Exports

  • device-navigation
  • device-navigation/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (device-navigation) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

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 or element-vir HTML templates.

Install

npm i device-navigation

Usage

  1. 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>
            `;
        },
    });
  2. 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.

Styles

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>
        `;
    },
});