Skip to content

Commit

Permalink
Merge branch 'promote-release-v5.0.0-prevent-repeat.0' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
dcneiner committed Apr 1, 2021
2 parents 480a19a + fd6b5e2 commit f9e4f48
Show file tree
Hide file tree
Showing 8 changed files with 5,220 additions and 3,671 deletions.
15 changes: 8 additions & 7 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"auxiliaryCommentBefore": "istanbul ignore next - babel generated code",
"compact": false,
"presets": [ "es2015-without-strict", "react", "stage-0" ],
"plugins": [ "transform-runtime", "add-module-exports" ],
"env": {
"development": {}
}
}
"presets": [
"@babel/env",
"@babel/react"
],
"plugins": [
"babel-plugin-add-module-exports"
]
}
8,723 changes: 5,111 additions & 3,612 deletions package-lock.json

Large diffs are not rendered by default.

67 changes: 38 additions & 29 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
"name": "lux-keyboard",
"version": "4.0.0",
"description": "React component + lux store utilities for managing contextual keyboard shortcut modes.",
"license": "MIT",
"main": "src/index.js",
"scripts": {
"lint": "eslint --fix ./",
"cover": "nyc -r text-summary -r html -- npm run test:only",
"cover:show": "open \"file://$PWD/coverage/index.html\"",
"pretest": "npm run lint",
"test": "npm run cover",
"test:only": "NODE_ENV=test mocha -r babel-register -R spec 'spec/**/*.spec.js' -r spec/node-setup.js",
"test:only": "NODE_ENV=test mocha 'spec/**/*.spec.js'",
"test:watch": "npm run test:only -- -w"
},
"repository": {
Expand Down Expand Up @@ -40,31 +41,28 @@
"node": ">=6.0.0"
},
"devDependencies": {
"babel-core": "^6.17.0",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-transform-runtime": "^6.15.0",
"babel-polyfill": "^6.16.0",
"babel-preset-es2015-without-strict": "0.0.4",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-0": "^6.5.0",
"babel-register": "^6.14.0",
"chai": "^4.1.0",
"chai-as-promised": "^5.3.0",
"chai-enzyme": "^1.0.0-beta.0",
"dirty-chai": "^1.2.2",
"enzyme": "^3.1.0",
"enzyme-adapter-react-16": "^1.0.0",
"eslint-config-leankit": "^4.0.0",
"event-emitter": "^0.3.4",
"jsdom": "^15.1.1",
"mocha": "^6.2.0",
"nyc": "^14.1.1",
"@babel/core": "^7.13.14",
"@babel/preset-env": "^7.13.12",
"@babel/preset-react": "^7.13.13",
"@babel/register": "^7.13.14",
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.0",
"babel-plugin-add-module-exports": "^1.0.4",
"chai": "^4.3.4",
"chai-as-promised": "^7.1.1",
"chai-enzyme": "^1.0.0-beta.1",
"core-js": "^3.9.1",
"dirty-chai": "^2.0.1",
"enzyme": "^3.11.0",
"eslint-config-leankit": "^6.0.0",
"jsdom": "^16.5.2",
"mocha": "^8.3.2",
"nyc": "^15.1.0",
"postal": "^2.0.4",
"proxyquire": "^1.7.10",
"react-dom": "^16.3.0",
"sinon": "^1.17.5",
"sinon-as-promised": "^4.0.2",
"sinon-chai": "^2.8.0"
"proxyquire": "^2.1.3",
"react-dom": "^17.0.2",
"regenerator-runtime": "^0.13.7",
"sinon": "^10.0.0",
"sinon-chai": "^3.6.0"
},
"nyc": {
"exclude": [
Expand All @@ -75,15 +73,26 @@
],
"all": true,
"require": [
"babel-register"
"@babel/register"
],
"sourceMap": true,
"instrument": true
},
"mocha": {
"require": [
"@babel/register",
"spec/pre-setup.js",
"spec/node-setup.js"
],
"reporters": [
"spec"
]
},
"dependencies": {
"lodash": "^4.17.15",
"lodash": "^4.17.21",
"lux.js": "^2.0.0",
"prop-types": "^15.6.1",
"react": "^16.3.0"
"mousetrap": "^1.6.5",
"prop-types": "^15.7.2",
"react": "^16.3.0 || ^17.0.2"
}
}
42 changes: 34 additions & 8 deletions spec/KeyboardInputManager.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { mount } from "enzyme";
import { act } from "react-dom/test-utils";

describe( "KeyboardInputManager", () => {
let keyMap, trapStub, luxConfig, dispatchStub, component, KeyboardInputManager;
Expand Down Expand Up @@ -29,6 +30,10 @@ describe( "KeyboardInputManager", () => {
actionName: "actionThree",
includeInputs: true,
preventDefault: false
},
c: {
actionName: "actionFour",
allowRepeat: true
}
};

Expand Down Expand Up @@ -65,27 +70,41 @@ describe( "KeyboardInputManager", () => {
.and.calledWith( "esc" )
.and.calledWith( "b" );

trapStub.bind.should.be.calledOnce
.and.calledWith( "a" );
trapStub.bind.should.be.calledTwice
.and.calledWith( "a" )
.and.calledWith( "c" );
} );

it( "should add keyMap that dispatches", () => {
it( "should add global handler that does not allow repeats", () => {
const preventDefault = sinon.stub();

trapStub.bindGlobal.getCall( 0 ).args[ 1 ]( { preventDefault } );
dispatchStub.should.be.calledWith( "actionOne" );
preventDefault.should.be.calledOnce();
trapStub.bindGlobal.getCall( 0 ).args[ 1 ]( { preventDefault, repeat: true } );
dispatchStub.should.be.calledOnce.and.calledWith( "actionOne" );
preventDefault.should.be.calledTwice();
} );

preventDefault.reset();
it( "should add global handler that does not prevent default", () => {
const preventDefault = sinon.stub();
trapStub.bindGlobal.getCall( 1 ).args[ 1 ]( { preventDefault } );
preventDefault.should.not.be.called();
dispatchStub.should.be.calledWith( "actionThree" );
} );

preventDefault.reset();
it( "should add local handler that dispatches", () => {
const preventDefault = sinon.stub();
trapStub.bind.getCall( 0 ).args[ 1 ]( { preventDefault } );
dispatchStub.should.be.calledWith( "actionTwo" );
preventDefault.should.be.calledOnce();
} );

it( "should add local handler that allows repeats", () => {
const preventDefault = sinon.stub();
trapStub.bind.getCall( 1 ).args[ 1 ]( { preventDefault } );
trapStub.bind.getCall( 1 ).args[ 1 ]( { preventDefault, repeat: true } );
dispatchStub.should.be.calledTwice.and.calledWith( "actionFour" );
preventDefault.should.be.calledTwice();
} );
} );

describe( "when updating the component", () => {
Expand Down Expand Up @@ -143,8 +162,15 @@ describe( "KeyboardInputManager", () => {
} );

describe( "when unmounting", () => {
beforeEach( () => {
render( { keyMap } );
} );

it( "should reset on unmount", () => {
component.unmount();
act( () => {
component.unmount();
component = null;
} );

trapStub.reset.should.be.calledOnce();
} );
Expand Down
7 changes: 6 additions & 1 deletion spec/KeyboardShortcutScope.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { mount } from "enzyme";
import { act } from "react-dom/test-utils";

describe( "KeyboardShortcutScope", () => {
let KeyboardShortcutScope, dispatchStub, component, TestComponent;
Expand Down Expand Up @@ -60,7 +61,11 @@ describe( "KeyboardShortcutScope", () => {
it( "should dispatch deactiveScope", () => {
render( { scope: "testScope" } );
dispatchStub.reset();
component.unmount();

act( () => {
component.unmount();
component = null;
} );

dispatchStub.should.be.calledOnce
.and.calledWith( "deactivateScope", "testScope" );
Expand Down
16 changes: 4 additions & 12 deletions spec/node-setup.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
import "babel-polyfill";
import "core-js/stable";
import "regenerator-runtime/runtime";
import proxyFn from "proxyquire";
import jsdom from "jsdom";
import chai from "chai";

import sinon from "sinon";
import "sinon-as-promised";
import postal from "postal";
import lux from "lux.js";

import Enzyme from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import Adapter from "@wojtekmaj/enzyme-adapter-react-17";

Enzyme.configure( {
adapter: new Adapter()
} );

global.proxyquire = proxyFn.noPreserveCache().noCallThru();
const { window } = new jsdom.JSDOM( "<html><body></body></html>" );
Object.assign( global, {
window,
document: window.document,
HTMLElement: window.HTMLElement,
navigator: { userAgent: "Not Chrom3" },
BROWSER: false
} );
global.navigator = { userAgent: "Not Chrom3" };
global.chai = chai;
chai.use( require( "dirty-chai" ) );
chai.use( require( "sinon-chai" ) );
Expand Down
11 changes: 11 additions & 0 deletions spec/pre-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const jsdom = require( "jsdom" );
const { window } = new jsdom.JSDOM( "<html><body></body></html>", { url: "http://localhost" } );
Object.assign( global, {
window,
self: window,
document: window.document,
HTMLElement: window.HTMLElement,
BROWSER: false,
navigator: { userAgent: "Not Chrom3" },
_babelPolyfill: true /* For lux */
} );
10 changes: 8 additions & 2 deletions src/KeyboardInputManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,26 @@ import { each } from "lodash";
import Mousetrap from "./MousetrapWrapper";

function catchThatMouse( handlers ) {
each( handlers, ( { actionName, includeInputs, preventDefault }, keyBinding ) => {
each( handlers, ( { actionName, includeInputs, preventDefault, allowRepeat }, keyBinding ) => {
const bindOption = includeInputs ? "bindGlobal" : "bind";
Mousetrap[ bindOption ]( keyBinding, e => {
// explicitly checking type, since preventDefault is optional + true by default
if ( preventDefault !== false ) {
e.preventDefault();
}

if ( !allowRepeat && e.repeat === true ) {
return;
}

dispatch( actionName );
} );
} );
}

export class MouseTrapped extends React.PureComponent {
componentWillMount() {
constructor( props ) {
super( props );
catchThatMouse( this.props.keyMap );
}

Expand Down

0 comments on commit f9e4f48

Please sign in to comment.