forked from Automattic/wp-calypso
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
accessible-focus: Extract into package, re-write in TypeScript, test,…
… and handle deprecated APIs (Automattic#49351) * accessible-focus: Extract from lib * accessible-focus: Use extracted package * Clean up package
- Loading branch information
1 parent
2d340e0
commit 56f2a25
Showing
14 changed files
with
243 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## 1.0.0-alpha.0 | ||
|
||
Extracted from `accessible-focus` and transformed to TypeScript and tests added. |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports = { | ||
preset: '../../test/packages/jest-preset.js', | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
{ | ||
"name": "@automattic/accessible-focus", | ||
"version": "1.0.0-alpha.0", | ||
"description": "A package for detecting keyboard navigation.", | ||
"homepage": "https://github.com/Automattic/wp-calypso", | ||
"license": "GPL-2.0-or-later", | ||
"author": "Automattic Inc.", | ||
"sideEffects": false, | ||
"main": "dist/cjs/index.js", | ||
"module": "dist/esm/index.js", | ||
"calypso:src": "src/index.ts", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/Automattic/wp-calypso.git", | ||
"directory": "packages/accessible-focus" | ||
}, | ||
"files": [ | ||
"dist", | ||
"src" | ||
], | ||
"types": "dist/types", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/Automattic/wp-calypso/issues" | ||
}, | ||
"scripts": { | ||
"clean": "tsc --build ./tsconfig.json ./tsconfig-cjs.json --clean && npx rimraf dist", | ||
"build": "tsc --build ./tsconfig.json ./tsconfig-cjs.json", | ||
"prepack": "yarn run clean && yarn run build", | ||
"watch": "tsc --build ./tsconfig.json --watch" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#non-printable_keys_function_keys | ||
const keyboardNavigationKeycodes = [ 9, 32, 37, 38, 39, 40 ]; // keyCodes for tab, space, left, up, right, down respectively | ||
|
||
// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values | ||
const keyboardNavigationKeyValues = [ | ||
'Tab', | ||
' ', | ||
// Some browsers returned `'Spacebar'` rather than `' '` for the Space key | ||
'Spacebar', | ||
'ArrowDown', | ||
'ArrowUp', | ||
'ArrowLeft', | ||
'ArrowRight', | ||
]; | ||
|
||
declare global { | ||
interface KeyboardEvent { | ||
/** | ||
* https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyIdentifier | ||
* Provides Safari support | ||
* | ||
* @deprecated | ||
*/ | ||
keyIdentifier: string; | ||
} | ||
} | ||
|
||
/** | ||
* `event.keyCode` is [deprecated](https://stackoverflow.com/a/35395154), so we must check each of the following: | ||
* 1. `event.key` | ||
* 2. `event.keyIdentifier` | ||
* 3. `event.keyCode` (for posterity) | ||
* | ||
* However, [`event.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) | ||
* and [`event.keyIdentifier`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyIdentifier) | ||
* both return a string rather than a numerical key code as the old `keyCode` API did. | ||
* | ||
* Therefore, we have two arrays of keycodes, one for the string APIs and one for the | ||
* older number based API. | ||
* | ||
* @param event The keyboard event to detect keyboard navigation against. | ||
*/ | ||
export function detectKeyboardNavigation( event: KeyboardEvent ): boolean { | ||
let code: number | string | undefined; | ||
|
||
if ( event.key !== undefined ) { | ||
code = event.key; | ||
} else if ( event.keyIdentifier !== undefined ) { | ||
code = event.keyIdentifier; | ||
} else if ( event.keyCode !== undefined ) { | ||
code = event.keyCode; | ||
} | ||
|
||
// This shouldn't ever happen but we do it to appease TypeScript | ||
if ( code === undefined ) { | ||
return false; | ||
} | ||
|
||
if ( typeof code === 'string' ) { | ||
return keyboardNavigationKeyValues.indexOf( code ) !== -1; | ||
} | ||
|
||
return keyboardNavigationKeycodes.indexOf( code ) !== -1; | ||
} | ||
|
||
let keyboardNavigation = false; | ||
|
||
export default function accessibleFocus(): void { | ||
document.addEventListener( 'keydown', function ( event ) { | ||
if ( keyboardNavigation ) { | ||
return; | ||
} | ||
|
||
if ( detectKeyboardNavigation( event ) ) { | ||
keyboardNavigation = true; | ||
document.documentElement.classList.add( 'accessible-focus' ); | ||
} | ||
} ); | ||
document.addEventListener( 'mouseup', function () { | ||
if ( ! keyboardNavigation ) { | ||
return; | ||
} | ||
keyboardNavigation = false; | ||
document.documentElement.classList.remove( 'accessible-focus' ); | ||
} ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/** | ||
* @jest-environment jsdom | ||
*/ | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { detectKeyboardNavigation } from '..'; | ||
|
||
describe( 'detectKeyboardNavigation', () => { | ||
describe( 'keyCode', () => { | ||
it.each( [ 9, 32, 37, 38, 39, 40 ] )( | ||
'should return true when the keyCode is %s', | ||
( keyCode ) => { | ||
const event = { | ||
keyCode, | ||
}; | ||
|
||
expect( detectKeyboardNavigation( event ) ).toBeTruthy(); | ||
} | ||
); | ||
|
||
it( 'should be false when keyCode does not indicate keyboard navigation', () => { | ||
const event = { | ||
keyCode: 46, // delete | ||
}; | ||
|
||
expect( detectKeyboardNavigation( event ) ).toBeFalsy(); | ||
} ); | ||
} ); | ||
|
||
describe( 'keyIdentifier', () => { | ||
it.each( [ 'Tab', ' ', 'Spacebar', 'ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight' ] )( | ||
'should return true when keyIdenitifer is "%s"', | ||
( keyIdentifier ) => { | ||
const event = { | ||
keyIdentifier, | ||
}; | ||
|
||
expect( detectKeyboardNavigation( event ) ).toBeTruthy(); | ||
} | ||
); | ||
|
||
it( 'should be false when keyIdentifier does not indicate keyboard navigation', () => { | ||
const event = { | ||
keyIdenitifer: 'Delete', | ||
}; | ||
|
||
expect( detectKeyboardNavigation( event ) ).toBeFalsy(); | ||
} ); | ||
} ); | ||
|
||
describe( 'key', () => { | ||
it.each( [ 'Tab', ' ', 'Spacebar', 'ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight' ] )( | ||
'should return true when key is "%s"', | ||
( key ) => { | ||
const event = { key }; | ||
|
||
expect( detectKeyboardNavigation( event ) ).toBeTruthy(); | ||
} | ||
); | ||
|
||
it( 'should be false when key does not indicate keyboard navigation', () => { | ||
const event = { key: 'Delete' }; | ||
|
||
expect( detectKeyboardNavigation( event ) ).toBeFalsy(); | ||
} ); | ||
} ); | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"extends": "./tsconfig", | ||
"compilerOptions": { | ||
"module": "commonjs", | ||
"declaration": false, | ||
"declarationDir": null, | ||
"outDir": "dist/cjs", | ||
"composite": false, | ||
"incremental": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "ES5", | ||
"baseUrl": ".", | ||
"module": "esnext", | ||
"allowJs": false, | ||
"declaration": true, | ||
"declarationDir": "dist/types", | ||
"outDir": "dist/esm", | ||
"rootDir": "src", | ||
|
||
"strict": true, | ||
"noUnusedLocals": true, | ||
"noUnusedParameters": true, | ||
"noImplicitReturns": true, | ||
|
||
"moduleResolution": "node", | ||
"esModuleInterop": true, | ||
|
||
"forceConsistentCasingInFileNames": true, | ||
|
||
"typeRoots": [ "../../node_modules/@types" ], | ||
"types": [ "node" ], | ||
|
||
"noEmitHelpers": true, | ||
"importHelpers": true, | ||
|
||
"composite": true | ||
}, | ||
"include": [ "src" ], | ||
"exclude": [ "**/test/*" ] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters