Skip to content

Commit

Permalink
Renaming bootstrap to helpers and updating README and some defaults
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt Gaunt committed Jun 10, 2020
1 parent b40baaa commit 13652c5
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 53 deletions.
125 changes: 96 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,31 @@

This library makes it quick and easy to support D-Pad Navigation in a web app.

## Install
## Details

```shell
npm install @gauntface/dpad-nav --save-dev
```
This library is broken up into two parts, the **library** itself and some **helpers**.

Alternatively, you can use a CDN to import one of the following:
The **library** contains the logic for the dpad navigation and debugging.

**DPad Helper & (Optional) Debugger Helper**
The **helpers** are lightweight wrappers that can be dropped into a web page and provide
the common logic / make it east to add d-pad navigation with little to no Javascript
needing to be written. Add these JavaScript files to your HTML page, and away you go.

```html
<script src="https://unpkg.com/@gauntface/dpad-nav@2.0.1/build/cdn/bootstrap/dpad.js" async defer></script>
<script src="https://unpkg.com/@gauntface/dpad-nav@2.0.1/build/cdn/bootstrap/dpad-debugger.js" async defer></script>
```
The helpers are the easiest way to try out this library, but may not be appropriate if:

**DPad Library & (Optional) Debugger Library**

```html
<script src="https://unpkg.com/@gauntface/dpad-nav@2.0.1/build/cdn/lib/dpad-controller.js" async defer></script>
<script src="https://unpkg.com/@gauntface/dpad-nav@2.0.1/build/cdn/lib/debug-controller.js" async defer></script>
```
1. You have a build process, and you'd like to make this library a part of it
1. Your web app is a single-page app, and you need this library to follow it's lifecycle.

The sections below will cover these options as necessary.

## Usage

To support D-Pad navigation with this library, you need to do the following:

- Add a `tabindex` and `class="dpad-focusable"` for any element you want to be focusable.
- Add a `tabindex` and `class="dpad-focusable"` for any element you want to be focusable
via the d-pad.
For Example:

```html
<div class="dpad-focusable" tabindex="0">Example</div>
```
Expand All @@ -45,11 +41,92 @@ To support D-Pad navigation with this library, you need to do the following:
}
```

With this, you're ready to support D-Pad navigation.
With this alone, you should be able to use the "tab" key to test the styles
and navigation of your site without this library.

With this, you're ready to add the D-Pad navigation library.

## Using the Helpers

With the HTML setup, you can use the helper library by adding the following to your
HTML pages:

```html
<script src="https://unpkg.com/@gauntface/dpad-nav@3.0.0/build/helper/helper/dpad.js" async defer></script>
<script src="https://unpkg.com/@gauntface/dpad-nav@3.0.0/build/helper/helper/dpad-debugger.js" async defer></script>
```

These scripts will add listeners to apply the dpad library to your pages and the `dpad-debugger.js` will
give your debug UI so you can see what the navigation will be and remove it once everything is working
as you'd expect.

You can interact with the library via `window.dpad` and `window.dpaddebug` which are instances of
a `DpadController` and `DebugController`, which are discussing in the "Library API" section below.

### Using the helpers via NPM

If you want to use the helper files but prefer to self-host the files, you can get them from npm via:

```shell
npm install @gauntface/dpad-nav --save-dev
cp ./node_modules/@gauntface/dpad-nav/build/helper/*.js ./src/third_party/dpad-nav/
```

## Using the library

If you want to use the library directly and avoid the helpers, you can take one of the following options:

### Using the library via CDN

Use a CDN hosted copy of the library:

```html
<script src="https://unpkg.com/@gauntface/dpad-nav@3.0.0/build/browser/dpad-controller.js" async defer></script>
<script src="https://unpkg.com/@gauntface/dpad-nav@3.0.0/build/browser/debug-controller.js" async defer></script>
```

The libraries will be accesible via `window.gauntface.dpad.DpadController` and `window.gauntface.dpad.DebugController`;

### Using the library via NPM

If you use NPM to manage your JavaScript dependencies, you can install and use this
library as an npm module:

```shell
npm install @gauntface/dpad-nav --save-dev
```

Then include the scripts like so:

```javascript
const {DpadController, DebugController} = require('@gauntface/dpad-nav');
```

## Library API

Typical usage of the library API would look like so:

```javascript
// Create a new dpad controller
const dpad = new DpadController();
// Call update to get the focusable items in the DOM
dpad.update();

// To enable debugging, create debug controller
const debug = new DebugController(dpad);
// Turn on debugging
debug.setDebugMode(true);
```

If your DOM changes, you can call `<DpadController>.update()` and
`<DebugController>.updateDisplay()` to force the controllers to handle
the changes.

## Events

This library will trigger a regular focus and click event.
This library will trigger normal focus and click events for your focusable
elemens, so adding event listeners can be useful if you want to listen for
events:

```js
element.addEventListener('focus', function(e) {
Expand All @@ -61,16 +138,6 @@ element.addEventListener('click', function() {
});
```

## Adding and Removing DOM Elements

The library works is that on page load or page resize, it will calculate the graph of where each node's closest neighbors are, based purely on each element's position in the viewport.

What the library does not do, is recalculate the graph if you add or remove elements. To update the graph when elements are added or removed from the DOM call `update()` like so:

```js
window.dpad.update();
```

## Tabindex and Browser Focus

With the tabindex property, you can determine the order of which view is focused when the user presses the tab key. This library ignores the tabindex order but requires it to ensure the browser allows an element to gain focus.
Expand Down
10 changes: 5 additions & 5 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ gulp.task('clean', gulp.series(
gulp.task('build-browser-lib', gulp.series(
tsBrowser.gulpBuild('gauntface.dpad', {
src: path.join(src, 'lib'),
dst: path.join(dst, 'browser-lib'),
dst: path.join(dst, 'browser'),
})
));

gulp.task('build-browser-bootstrap', gulp.series(
gulp.task('build-browser-helper', gulp.series(
tsBrowser.gulpBuild('gauntface.dpad', {
src: path.join(src, 'bootstrap'),
dst: path.join(dst, 'cdn'),
src: path.join(src, 'helper'),
dst: path.join(dst, 'helper'),
rootDir: src,
})
));
Expand All @@ -38,7 +38,7 @@ gulp.task('build',
'clean',
gulp.parallel(
'build-browser-lib',
'build-browser-bootstrap',
'build-browser-helper',
'build-node-lib',
),
)
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"gulp": "^4.0.2"
},
"files": [
"build/"
"build/",
"src/"
]
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import {DPadController} from '../lib/dpad-controller';
import {DpadController} from '../lib/dpad-controller';
import {DebugController} from '../lib/debug-controller';

declare global {
interface Window {
dpad: DPadController|null;
dpad: DpadController|null;
dpaddebug: DebugController;
}
}

window.addEventListener('load', () => {
window.dpaddebug = window.dpaddebug || new DebugController(window.dpad);
window.dpaddebug.setDebugMode(true);
});

window.addEventListener('resize', () => {
Expand Down
7 changes: 4 additions & 3 deletions src/bootstrap/dpad.ts → src/helper/dpad.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import {DPadController} from '../lib/dpad-controller';
import {DpadController} from '../lib/dpad-controller';

declare global {
interface Window { dpad: DPadController; }
interface Window { dpad: DpadController; }
}

window.addEventListener('load', () => {
window.dpad = window.dpad || new DPadController();
window.dpad = window.dpad || new DpadController();
window.dpad.update();
});

window.addEventListener('resize', () => {
Expand Down
6 changes: 3 additions & 3 deletions src/lib/debug-controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {DPadController} from './dpad-controller';
import {DpadController} from './dpad-controller';
import { FocusableItem } from './_focusable-item';
import {calcDistance} from './_calc-distance';

Expand All @@ -19,10 +19,10 @@ const MARKER_COLORS = [
];

export class DebugController {
private dpad: DPadController;
private dpad: DpadController;
private debugMode: boolean;

constructor(dpad: DPadController|null) {
constructor(dpad: DpadController|null) {
if (!dpad) {
console.error(`Unable to debug since the dpad controller is not defined.`);
}
Expand Down
12 changes: 3 additions & 9 deletions src/lib/dpad-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,14 @@ import {calcDistance} from './_calc-distance';

const FOCUSABLE_ITEM_SELECTOR = '.dpad-focusable';

export class DPadController {
export class DpadController {
private focusableItems: Array<FocusableItem> = [];
private currentlyFocusedItem: FocusableItem|null = null;
private enabled: boolean = false;

constructor() {
this.focusableItems = [];

this.findFocusableItems();

if(this.focusableItems.length > 0) {
this.setCurrentFocusItem(0);
}

this.update();

// Set up binding to listen for key presses
document.addEventListener('keydown', (e) => {
this.onKeyDown(e);
Expand Down Expand Up @@ -88,6 +80,8 @@ export class DPadController {
}

update() {
this.findFocusableItems();

for(const fi of this.focusableItems) {
// If the element can't be focused, skip it.
if(!fi.isFocusable()) {
Expand Down

0 comments on commit 13652c5

Please sign in to comment.