keyborg 1.2.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Keyborg.d.ts CHANGED
@@ -11,6 +11,10 @@ interface WindowWithKeyborg extends Window {
11
11
  };
12
12
  };
13
13
  }
14
+ export interface KeyborgProps {
15
+ triggerKeys?: number[];
16
+ dismissKeys?: number[];
17
+ }
14
18
  export declare type KeyborgCallback = (isNavigatingWithKeyboard: boolean) => void;
15
19
  /**
16
20
  * Source of truth for all the keyborg core instances and the current keyboard navigation state
@@ -29,9 +33,11 @@ export declare class KeyborgState {
29
33
  declare class KeyborgCore implements Disposable {
30
34
  readonly id: string;
31
35
  private _win?;
32
- private _isMouseUsed;
36
+ private _isMouseUsedTimer;
33
37
  private _dismissTimer;
34
- constructor(win: WindowWithKeyborg);
38
+ private _triggerKeys?;
39
+ private _dismissKeys?;
40
+ constructor(win: WindowWithKeyborg, props?: KeyborgProps);
35
41
  dispose(): void;
36
42
  isDisposed(): boolean;
37
43
  /**
@@ -51,7 +57,7 @@ export declare class Keyborg {
51
57
  private _win?;
52
58
  private _core?;
53
59
  private _cb;
54
- static create(win: WindowWithKeyborg): Keyborg;
60
+ static create(win: WindowWithKeyborg, props?: KeyborgProps): Keyborg;
55
61
  static dispose(instance: Keyborg): void;
56
62
  /**
57
63
  * Updates all subscribed callbacks with the keyboard navigation state
@@ -76,6 +82,6 @@ export declare class Keyborg {
76
82
  */
77
83
  setVal(isNavigatingWithKeyboard: boolean): void;
78
84
  }
79
- export declare function createKeyborg(win: Window): Keyborg;
85
+ export declare function createKeyborg(win: Window, props?: KeyborgProps): Keyborg;
80
86
  export declare function disposeKeyborg(instance: Keyborg): void;
81
87
  export {};
package/dist/index.js CHANGED
@@ -181,11 +181,8 @@ function getLastFocusedProgrammatically(win) {
181
181
  * Copyright (c) Microsoft Corporation. All rights reserved.
182
182
  * Licensed under the MIT License.
183
183
  */
184
- const KeyTab = 9;
185
- const KeyEsc = 27;
186
- const _dismissTimeout = 500; // When Esc is pressed and the focused is not moved
187
- // during _dismissTimeout time, dismiss the keyboard
188
- // navigation mode.
184
+ const _dismissTimeout = 500; // When a key from dismissKeys is pressed and the focus is not moved
185
+ // during _dismissTimeout time, dismiss the keyboard navigation mode.
189
186
 
190
187
  let _lastId = 0;
191
188
  /**
@@ -246,12 +243,14 @@ const _state = /*#__PURE__*/new KeyborgState();
246
243
 
247
244
 
248
245
  class KeyborgCore {
249
- constructor(win) {
250
- this._isMouseUsed = false;
251
-
246
+ constructor(win, props) {
252
247
  this._onFocusIn = e => {
253
- if (this._isMouseUsed) {
254
- this._isMouseUsed = false;
248
+ // When the focus is moved not programmatically and without keydown events,
249
+ // it is likely that the focus is moved by screen reader (as it might swallow
250
+ // the events when the screen reader shortcuts are used). The screen reader
251
+ // usage is keyboard navigation.
252
+ if (this._isMouseUsedTimer) {
253
+ // There was a mouse event recently.
255
254
  return;
256
255
  }
257
256
 
@@ -281,17 +280,32 @@ class KeyborgCore {
281
280
  return;
282
281
  }
283
282
 
284
- this._isMouseUsed = true;
283
+ const win = this._win;
284
+
285
+ if (win) {
286
+ if (this._isMouseUsedTimer) {
287
+ win.clearTimeout(this._isMouseUsedTimer);
288
+ }
289
+
290
+ this._isMouseUsedTimer = win.setTimeout(() => {
291
+ delete this._isMouseUsedTimer;
292
+ }, 1000); // Keeping the indication of the mouse usage for some time.
293
+ }
285
294
 
286
295
  _state.setVal(false);
287
296
  };
288
297
 
289
298
  this._onKeyDown = e => {
299
+ var _a;
300
+
290
301
  const isNavigatingWithKeyboard = _state.getVal();
291
302
 
292
- if (!isNavigatingWithKeyboard && e.keyCode === KeyTab) {
303
+ const keyCode = e.keyCode;
304
+ const triggerKeys = this._triggerKeys;
305
+
306
+ if (!isNavigatingWithKeyboard && (!triggerKeys || triggerKeys.has(keyCode))) {
293
307
  _state.setVal(true);
294
- } else if (isNavigatingWithKeyboard && e.keyCode === KeyEsc) {
308
+ } else if (isNavigatingWithKeyboard && ((_a = this._dismissKeys) === null || _a === void 0 ? void 0 : _a.has(keyCode))) {
295
309
  this._scheduleDismiss();
296
310
  }
297
311
  };
@@ -299,6 +313,20 @@ class KeyborgCore {
299
313
  this.id = "c" + ++_lastId;
300
314
  this._win = win;
301
315
  const doc = win.document;
316
+
317
+ if (props) {
318
+ const triggerKeys = props.triggerKeys;
319
+ const dismissKeys = props.dismissKeys;
320
+
321
+ if (triggerKeys === null || triggerKeys === void 0 ? void 0 : triggerKeys.length) {
322
+ this._triggerKeys = new Set(triggerKeys);
323
+ }
324
+
325
+ if (dismissKeys === null || dismissKeys === void 0 ? void 0 : dismissKeys.length) {
326
+ this._dismissKeys = new Set(dismissKeys);
327
+ }
328
+ }
329
+
302
330
  doc.addEventListener(KEYBORG_FOCUSIN, this._onFocusIn, true); // Capture!
303
331
 
304
332
  doc.addEventListener("mousedown", this._onMouseDown, true); // Capture!
@@ -314,6 +342,11 @@ class KeyborgCore {
314
342
  const win = this._win;
315
343
 
316
344
  if (win) {
345
+ if (this._isMouseUsedTimer) {
346
+ win.clearTimeout(this._isMouseUsedTimer);
347
+ this._isMouseUsedTimer = undefined;
348
+ }
349
+
317
350
  if (this._dismissTimer) {
318
351
  win.clearTimeout(this._dismissTimer);
319
352
  this._dismissTimer = undefined;
@@ -383,7 +416,7 @@ class KeyborgCore {
383
416
 
384
417
 
385
418
  class Keyborg {
386
- constructor(win) {
419
+ constructor(win, props) {
387
420
  this._cb = [];
388
421
  this._id = "k" + ++_lastId;
389
422
  this._win = win;
@@ -393,7 +426,7 @@ class Keyborg {
393
426
  this._core = current.core;
394
427
  current.refs[this._id] = this;
395
428
  } else {
396
- this._core = new KeyborgCore(win);
429
+ this._core = new KeyborgCore(win, props);
397
430
  win.__keyborg = {
398
431
  core: this._core,
399
432
  refs: {
@@ -403,8 +436,8 @@ class Keyborg {
403
436
  }
404
437
  }
405
438
 
406
- static create(win) {
407
- return new Keyborg(win);
439
+ static create(win, props) {
440
+ return new Keyborg(win, props);
408
441
  }
409
442
 
410
443
  static dispose(instance) {
@@ -478,8 +511,8 @@ class Keyborg {
478
511
  }
479
512
 
480
513
  }
481
- function createKeyborg(win) {
482
- return Keyborg.create(win);
514
+ function createKeyborg(win, props) {
515
+ return Keyborg.create(win, props);
483
516
  }
484
517
  function disposeKeyborg(instance) {
485
518
  Keyborg.dispose(instance);
@@ -489,7 +522,7 @@ function disposeKeyborg(instance) {
489
522
  * Copyright (c) Microsoft Corporation. All rights reserved.
490
523
  * Licensed under the MIT License.
491
524
  */
492
- const version = "1.2.1";
525
+ const version = "2.1.0";
493
526
 
494
527
  exports.KEYBORG_FOCUSIN = KEYBORG_FOCUSIN;
495
528
  exports.Keyborg = Keyborg;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -177,11 +177,8 @@ function getLastFocusedProgrammatically(win) {
177
177
  * Copyright (c) Microsoft Corporation. All rights reserved.
178
178
  * Licensed under the MIT License.
179
179
  */
180
- const KeyTab = 9;
181
- const KeyEsc = 27;
182
- const _dismissTimeout = 500; // When Esc is pressed and the focused is not moved
183
- // during _dismissTimeout time, dismiss the keyboard
184
- // navigation mode.
180
+ const _dismissTimeout = 500; // When a key from dismissKeys is pressed and the focus is not moved
181
+ // during _dismissTimeout time, dismiss the keyboard navigation mode.
185
182
 
186
183
  let _lastId = 0;
187
184
  /**
@@ -242,12 +239,14 @@ const _state = /*#__PURE__*/new KeyborgState();
242
239
 
243
240
 
244
241
  class KeyborgCore {
245
- constructor(win) {
246
- this._isMouseUsed = false;
247
-
242
+ constructor(win, props) {
248
243
  this._onFocusIn = e => {
249
- if (this._isMouseUsed) {
250
- this._isMouseUsed = false;
244
+ // When the focus is moved not programmatically and without keydown events,
245
+ // it is likely that the focus is moved by screen reader (as it might swallow
246
+ // the events when the screen reader shortcuts are used). The screen reader
247
+ // usage is keyboard navigation.
248
+ if (this._isMouseUsedTimer) {
249
+ // There was a mouse event recently.
251
250
  return;
252
251
  }
253
252
 
@@ -277,17 +276,32 @@ class KeyborgCore {
277
276
  return;
278
277
  }
279
278
 
280
- this._isMouseUsed = true;
279
+ const win = this._win;
280
+
281
+ if (win) {
282
+ if (this._isMouseUsedTimer) {
283
+ win.clearTimeout(this._isMouseUsedTimer);
284
+ }
285
+
286
+ this._isMouseUsedTimer = win.setTimeout(() => {
287
+ delete this._isMouseUsedTimer;
288
+ }, 1000); // Keeping the indication of the mouse usage for some time.
289
+ }
281
290
 
282
291
  _state.setVal(false);
283
292
  };
284
293
 
285
294
  this._onKeyDown = e => {
295
+ var _a;
296
+
286
297
  const isNavigatingWithKeyboard = _state.getVal();
287
298
 
288
- if (!isNavigatingWithKeyboard && e.keyCode === KeyTab) {
299
+ const keyCode = e.keyCode;
300
+ const triggerKeys = this._triggerKeys;
301
+
302
+ if (!isNavigatingWithKeyboard && (!triggerKeys || triggerKeys.has(keyCode))) {
289
303
  _state.setVal(true);
290
- } else if (isNavigatingWithKeyboard && e.keyCode === KeyEsc) {
304
+ } else if (isNavigatingWithKeyboard && ((_a = this._dismissKeys) === null || _a === void 0 ? void 0 : _a.has(keyCode))) {
291
305
  this._scheduleDismiss();
292
306
  }
293
307
  };
@@ -295,6 +309,20 @@ class KeyborgCore {
295
309
  this.id = "c" + ++_lastId;
296
310
  this._win = win;
297
311
  const doc = win.document;
312
+
313
+ if (props) {
314
+ const triggerKeys = props.triggerKeys;
315
+ const dismissKeys = props.dismissKeys;
316
+
317
+ if (triggerKeys === null || triggerKeys === void 0 ? void 0 : triggerKeys.length) {
318
+ this._triggerKeys = new Set(triggerKeys);
319
+ }
320
+
321
+ if (dismissKeys === null || dismissKeys === void 0 ? void 0 : dismissKeys.length) {
322
+ this._dismissKeys = new Set(dismissKeys);
323
+ }
324
+ }
325
+
298
326
  doc.addEventListener(KEYBORG_FOCUSIN, this._onFocusIn, true); // Capture!
299
327
 
300
328
  doc.addEventListener("mousedown", this._onMouseDown, true); // Capture!
@@ -310,6 +338,11 @@ class KeyborgCore {
310
338
  const win = this._win;
311
339
 
312
340
  if (win) {
341
+ if (this._isMouseUsedTimer) {
342
+ win.clearTimeout(this._isMouseUsedTimer);
343
+ this._isMouseUsedTimer = undefined;
344
+ }
345
+
313
346
  if (this._dismissTimer) {
314
347
  win.clearTimeout(this._dismissTimer);
315
348
  this._dismissTimer = undefined;
@@ -379,7 +412,7 @@ class KeyborgCore {
379
412
 
380
413
 
381
414
  class Keyborg {
382
- constructor(win) {
415
+ constructor(win, props) {
383
416
  this._cb = [];
384
417
  this._id = "k" + ++_lastId;
385
418
  this._win = win;
@@ -389,7 +422,7 @@ class Keyborg {
389
422
  this._core = current.core;
390
423
  current.refs[this._id] = this;
391
424
  } else {
392
- this._core = new KeyborgCore(win);
425
+ this._core = new KeyborgCore(win, props);
393
426
  win.__keyborg = {
394
427
  core: this._core,
395
428
  refs: {
@@ -399,8 +432,8 @@ class Keyborg {
399
432
  }
400
433
  }
401
434
 
402
- static create(win) {
403
- return new Keyborg(win);
435
+ static create(win, props) {
436
+ return new Keyborg(win, props);
404
437
  }
405
438
 
406
439
  static dispose(instance) {
@@ -474,8 +507,8 @@ class Keyborg {
474
507
  }
475
508
 
476
509
  }
477
- function createKeyborg(win) {
478
- return Keyborg.create(win);
510
+ function createKeyborg(win, props) {
511
+ return Keyborg.create(win, props);
479
512
  }
480
513
  function disposeKeyborg(instance) {
481
514
  Keyborg.dispose(instance);
@@ -485,7 +518,7 @@ function disposeKeyborg(instance) {
485
518
  * Copyright (c) Microsoft Corporation. All rights reserved.
486
519
  * Licensed under the MIT License.
487
520
  */
488
- const version = "1.2.1";
521
+ const version = "2.1.0";
489
522
 
490
523
  export { KEYBORG_FOCUSIN, Keyborg, createKeyborg, disposeKeyborg, getLastFocusedProgrammatically, nativeFocus, version };
491
524
  //# sourceMappingURL=keyborg.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"keyborg.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"keyborg.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keyborg",
3
- "version": "1.2.1",
3
+ "version": "2.1.0",
4
4
  "description": "Keyboard Navigation Detection for Web",
5
5
  "author": "Marat Abdullin <marata@microsoft.com>",
6
6
  "license": "MIT",
@@ -46,7 +46,7 @@
46
46
  "eslint-plugin-import": "^2.25.3",
47
47
  "node-fetch": "^2.6.6",
48
48
  "prettier": "^2.4.1",
49
- "release-it": "^14.11.8",
49
+ "release-it": "^15.6.0",
50
50
  "rimraf": "^3.0.2",
51
51
  "rollup": "^2.60.1",
52
52
  "rollup-plugin-sourcemaps": "^0.6.3",