Giter VIP home page Giter VIP logo

arrowhead's Introduction

Arrowhead

Move focus between DOM elements using the arrow keys, without writing any JavaScript!

Installation

Arrowhead is a single, dependency-free JavaScript file. Simply download the script and include it in your page using a <script> tag:

<script src="path/to/downloaded/arrowhead.min.js"></script>

Usage

Focus moves between elements marked with the ah-item attribute.

Use the ah-row and ah-col attributes to set the arrow key axis. Rows use the left/right ⇦/⇨ keys, while columns use the up/down ⇧/⇩ keys:

<div ah-row>
  <button ah-item>press left</button>
  <button ah-item>focused</button>
  <button ah-item>press right</button>
</div>

<div ah-col>
  <button ah-item>press up</button>
  <button ah-item>focused</button>
  <button ah-item>press down</button>
</div>

Items do not need to be on the same level:

<div ah-col>
  <button ah-item>press up</button>
  <div>
    <ul>
      <li><button ah-item>focused</button></li>
      <li><button ah-item>press down</button></li>
    </ul>
    <button ah-item>press down x2</button>
  </div>
</div>

By default, items can be 5 levels deep from a ah-row or ah-col element. This can be changed using the ah-depth attribute:

optimize performance
<div ah-col ah-depth="1">
  <div>...</div>
  <button ah-item>press up</button>
  <button ah-item>focused</button>
  <button ah-item>press down</button>
  <div>...</div>
</div>

or go crazy
<div ah-col ah-depth="24">
  <div>
    <div>
      <div>
        ...
        <button ah-item>...</button>
        ...
      </div>
    </div>
  </div>
</div>

Rows and columns can be nested. Focus can move between sibling rows and columns varying types:

<div ah-col>
  <div ah-row>
    <button ah-item>press up</button>
    <button ah-item>press up, right</button>
    <button ah-item>press up, right, right</button>
  </div>
  <div ah-row>
    <button ah-item>press left</button>
    <button ah-item>focused</button>
  </div>
  <div ah-row>
    <button ah-item>press down</button>
    <button ah-item>press down, right</button>
    <button ah-item>press down, right, right</button>
  </div>
</div>

Elements now marked with any Arrowhead attributes are not affected by Arrowhead.

Check out the demo.

Auto

Arrowhead can automatically assign the ah-item attribute to the child elements of an element. This is done by adding the ah-auto attribute to the parent and providing a CSS selector string.

This can be particularly useful when you do not have full control over the rendered HTML.

...
<div ah-auto="a, button">
  <p>This <a href="...">link</a> will be given the ah-item attribute.</p>
  <button>This button too!</button>
  <input value="But not this field" />
</div>
...

This becomes:

...
<div>
  <p>This <a href="..." ah-item>link</a> will be given the ah-item attribute.</p>
  <button ah-item>This button too!</button>
  <input value="But not this field" />
</div>
...

If the ah-auto attribute has no value or an empty one, the CSS selector a, button, input, textarea, select, summary will be used.

Auto is not enabled by default. You can "enable" it by running ArrowHead.auto() when the page content is ready. This function takes the root of the tree to be searched for ah-auto attributes.

document.addEventListener("DOMContentLoaded", function () {
  ArrowHead.auto(document.body);
});

If you're using [htmx], you may also want to run auto() on any new content that gets swapped into the DOM:

document.addEventListener("htmx:afterSwap", function (ev) {
  if (ev.target instanceof HTMLElement) {
    ArrowHead.auto(ev.target);
  }
});

How it works

Arrowhead is basically just a key listener on the document.

When an arrow key is pressed, Arrowhead will begin searching upwards in the DOM, starting from the currently focused element. The search stops when an element has the ah-layout attribute or the ah-row and ah-col shorthands:

<div ah-layout="row">...</div>
<div ah-layout="col">...</div>

<div ah-row>...</div>
<div ah-col>...</div>

When found, these enable Arrowhead navigation in their subtree, in either the horizonal or vertical axes:

row col
←/→ ↑/↓

If the axis of the pressed key does not match the axis of the found layout, Arrowhead repeats the search starting from the found layout element.

When a matching layout is found, a direction is determined as follows:

←/↑ →/↓
Backwards (BWD) Forwards (FWD)

Arrowhead now begins a search in the layout's subtree for all descendant layout elements and elements marked with the ah-item attribute (value unused). All other elements will be recursively searched up to a depth of 5. The depth can be changed by adding ah-depth attribute to the layout element.

The search stops when it finds the currently focused element. Then, depending on the direction, the search will either yield the previous search result (BWD) the next one (FWD), if they exist.

If a result is not found, Arrowhead will restart the process using the layout element as the currently focused element. This way, the key event "bubbles up".

If a result is found, that element becomes the target.

  1. If the target is a ah-item element, it recieves focus.
  2. If the target is a layout element, focus will be given to the layout's first or last item element, depending on the direction. If this element is also a layout, this process repeats.
  3. If the target is any other element, nothing happens.
<div ah-layout="col">
  <br />
  <div>
    <button ah-item>focused if up key is pressed</button>
  </div>
  <br />
  <button>currently focused</button>
  <br />
  <ul>
    <li>
      <button ah-item>focused if down key is pressed</button>
    </li>
  </ul>
  <br />
</div>

arrowhead's People

Contributors

mecha avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.