Compare commits

..

20 Commits

Author SHA1 Message Date
Francisco Hodge
effee00b87 Added new inputPattern option 2019-01-24 23:04:59 -05:00
Francisco Hodge
90b408eff6 Tests update 2019-01-24 23:03:48 -05:00
Francisco Hodge
21fa732b1f Types update 2019-01-24 23:03:23 -05:00
Francisco Hodge
80f4307c36 Build update 2019-01-24 23:03:14 -05:00
Francisco Hodge
681bb3d0ee npm update 2019-01-24 23:02:59 -05:00
Francisco Hodge
e1fa685c6c Merge branch 'master' of https://github.com/hodgef/simple-keyboard 2019-01-17 18:37:07 -05:00
Francisco Hodge
2de7154128 npm update 2019-01-17 18:36:48 -05:00
Francisco Hodge
c9afe43f5b Build update 2019-01-17 18:36:36 -05:00
Francisco Hodge
c59f819db9 Tests update 2019-01-17 18:36:19 -05:00
Francisco Hodge
1f9efb0c66 Ensure caretPosition is unset on disableCaretPositioning 2019-01-17 18:36:09 -05:00
Francisco Hodge
32cbce8c8a Update issue templates 2019-01-17 09:20:47 -05:00
Francisco Hodge
6c2236f762 Adding types for disableCaretPositioning option 2019-01-16 19:38:42 -05:00
Francisco Hodge
23a50e6f44 Updated devDependencies 2019-01-06 15:44:07 -05:00
Francisco Hodge
c316d493c7 Tests update 2018-12-27 13:46:15 -05:00
Francisco Hodge
70e7635f25 npm update 2018-12-27 13:38:38 -05:00
Francisco Hodge
f5b73b09e7 Merge pull request #45 from mkusher/patch-1
fixed camelCase function
2018-12-27 13:33:09 -05:00
Aleh Kashnikau
7432e01740 fixed camelCase function
Added check for empty word
2018-12-27 21:29:05 +03:00
Francisco Hodge
459ab71c45 npm update 2018-12-24 13:31:13 -05:00
Francisco Hodge
a5c177e41c Specifying layout class on keyboard element 2018-12-24 13:30:52 -05:00
Francisco Hodge
d382945de7 Updated devDependencies 2018-12-23 17:42:02 -05:00
14 changed files with 1162 additions and 1448 deletions

View File

@@ -1,6 +1,9 @@
---
name: Bug report
about: Create a report to help improve simple-keyboard
title: ''
labels: ''
assignees: hodgef
---
@@ -8,7 +11,7 @@ about: Create a report to help improve simple-keyboard
As some bugs have been addressed in later versions, please ensure you are running the latest.
**Describe the bug**
A clear and concise description of what the bug is.
A clear and concise description of what the bug is. Providing a [sandbox example](https://codesandbox.io/s/vanilla) or code depicting the issue is important, as this will help us reproduce the issue.
**Screenshots**
If applicable, add screenshots to help explain your problem.

View File

@@ -1,6 +1,9 @@
---
name: Feature request
about: Suggest an idea you'd like to see in simple-keyboard
title: ''
labels: ''
assignees: ''
---

View File

@@ -1,6 +1,6 @@
/*!
*
* simple-keyboard v2.12.0
* simple-keyboard v2.14.0
* https://github.com/hodgef/simple-keyboard
*
* Copyright (c) Francisco Hodge (https://github.com/hodgef)

File diff suppressed because one or more lines are too long

10
build/index.d.ts vendored
View File

@@ -101,6 +101,16 @@ declare module 'simple-keyboard' {
*/
useButtonTag?: boolean;
/**
* A prop to ensure characters are always be added/removed at the end of the string.
*/
disableCaretPositioning?: boolean;
/**
* Restrains input(s) change to the defined regular expression pattern.
*/
inputPattern?: any;
/**
* Executes the callback function on key press. Returns button layout name (i.e.: "{shift}").
*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2329
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "simple-keyboard",
"version": "2.12.0",
"version": "2.14.0",
"description": "On-screen Javascript Virtual Keyboard",
"main": "build/index.js",
"types": "build/index.d.ts",
@@ -35,42 +35,43 @@
"touchscreen",
"touch-screen",
"kiosk",
"osk"
"osk",
"js"
],
"license": "MIT",
"devDependencies": {
"@babel/core": "7.2.0",
"@babel/plugin-proposal-class-properties": "^7.2.1",
"@babel/preset-env": "^7.2.0",
"@babel/core": "7.2.2",
"@babel/plugin-proposal-class-properties": "^7.2.3",
"@babel/preset-env": "^7.2.3",
"@babel/preset-react": "^7.0.0",
"@svgr/webpack": "4.1.0",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "9.0.0",
"babel-eslint": "10.0.1",
"babel-jest": "23.6.0",
"babel-loader": "8.0.4",
"babel-plugin-named-asset-import": "^0.2.3",
"babel-preset-react-app": "^6.1.0",
"babel-loader": "8.0.5",
"babel-plugin-named-asset-import": "^0.3.0",
"babel-preset-react-app": "^7.0.0",
"bfj": "6.1.1",
"case-sensitive-paths-webpack-plugin": "2.1.2",
"chalk": "2.4.1",
"chalk": "2.4.2",
"copy-webpack-plugin": "^4.6.0",
"css-loader": "2.0.0",
"css-loader": "2.1.0",
"dotenv": "6.2.0",
"dotenv-expand": "4.2.0",
"esdoc": "^1.1.0",
"esdoc-ecmascript-proposal-plugin": "^1.0.0",
"esdoc-standard-plugin": "^1.0.0",
"eslint": "5.9.0",
"eslint-config-react-app": "^3.0.5",
"eslint": "5.12.0",
"eslint-config-react-app": "^3.0.6",
"eslint-loader": "2.1.1",
"eslint-plugin-flowtype": "2.50.3",
"eslint-plugin-flowtype": "3.2.0",
"eslint-plugin-import": "2.14.0",
"eslint-plugin-jsx-a11y": "6.1.2",
"eslint-plugin-react": "7.11.1",
"file-loader": "2.0.0",
"eslint-plugin-react": "7.12.3",
"file-loader": "3.0.1",
"fork-ts-checker-webpack-plugin-alt": "0.4.14",
"fs-extra": "7.0.1",
"html-webpack-plugin": "4.0.0-beta.4",
"html-webpack-plugin": "4.0.0-beta.5",
"identity-obj-proxy": "3.0.0",
"jest": "23.6.0",
"jest-pnp-resolver": "1.0.2",
@@ -80,24 +81,30 @@
"pnp-webpack-plugin": "1.2.1",
"postcss-flexbugs-fixes": "4.1.0",
"postcss-loader": "3.0.0",
"postcss-preset-env": "6.4.0",
"postcss-preset-env": "6.5.0",
"postcss-safe-parser": "4.0.1",
"react": "^16.6.3",
"react-app-polyfill": "^0.1.3",
"react-dev-utils": "^6.1.1",
"react-dom": "^16.6.3",
"resolve": "1.8.1",
"react": "^16.7.0",
"react-app-polyfill": "^0.2.0",
"react-dev-utils": "^7.0.1",
"react-dom": "^16.7.0",
"resolve": "1.9.0",
"sass-loader": "7.1.0",
"style-loader": "0.23.1",
"terser-webpack-plugin": "1.1.0",
"terser-webpack-plugin": "1.2.1",
"url-loader": "1.1.2",
"webpack": "4.27.1",
"webpack-dev-server": "3.1.10",
"webpack": "4.28.3",
"webpack-dev-server": "3.1.14",
"webpack-manifest-plugin": "2.0.4",
"workbox-webpack-plugin": "3.6.3"
},
"eslintConfig": {
"extends": "react-app"
"extends": "react-app",
"settings": {
"react": {
"pragma": "React",
"version": "detect"
}
}
},
"browserslist": [
">0.2%",

View File

@@ -101,6 +101,16 @@ declare module 'simple-keyboard' {
*/
useButtonTag?: boolean;
/**
* A prop to ensure characters are always be added/removed at the end of the string.
*/
disableCaretPositioning?: boolean;
/**
* Restrains input(s) change to the defined regular expression pattern.
*/
inputPattern?: any;
/**
* Executes the callback function on key press. Returns button layout name (i.e.: "{shift}").
*/

View File

@@ -59,6 +59,8 @@ class SimpleKeyboard {
* @property {function} onInit Executes the callback function once simple-keyboard is rendered for the first time (on initialization).
* @property {function(inputs: object):object} onChangeAll Executes the callback function on input change. Returns the input object with all defined inputs.
* @property {boolean} useButtonTag Render buttons as a button element instead of a div element.
* @property {boolean} disableCaretPositioning A prop to ensure characters are always be added/removed at the end of the string.
* @property {object} inputPattern Restrains input(s) change to the defined regular expression pattern.
*/
this.options = options;
this.options.layoutName = this.options.layoutName || "default";
@@ -95,6 +97,7 @@ class SimpleKeyboard {
this.handleButtonMouseDown = this.handleButtonMouseDown.bind(this);
this.handleButtonHold = this.handleButtonHold.bind(this);
this.onModulesLoaded = this.onModulesLoaded.bind(this);
this.inputPatternIsValid = this.inputPatternIsValid.bind(this);
/**
* simple-keyboard uses a non-persistent internal input to keep track of the entered string (the variable `keyboard.input`).
@@ -180,7 +183,17 @@ class SimpleKeyboard {
button, this.input[this.options.inputName], this.options, this.caretPosition
);
if(this.input[this.options.inputName] !== updatedInput){
if(
// If input will change as a result of this button press
this.input[this.options.inputName] !== updatedInput &&
// This pertains to the "inputPattern" option:
(
// If inputPattern isn't set
!this.options.inputPattern ||
// Or, if it is set and if the pattern is valid - we proceed.
(this.options.inputPattern && this.inputPatternIsValid(updatedInput))
)
){
/**
* If maxLength and handleMaxLength yield true, halting
@@ -503,6 +516,39 @@ class SimpleKeyboard {
return output;
}
/**
* This handles the "inputPattern" option
* by checking if the provided inputPattern passes
*/
inputPatternIsValid(inputVal){
let inputPatternRaw = this.options.inputPattern;
let inputPattern;
/**
* Check if input pattern is global or targeted to individual inputs
*/
if(inputPatternRaw instanceof RegExp){
inputPattern = inputPatternRaw;
} else {
inputPattern = inputPatternRaw[this.options.inputName];
}
if(inputPattern && inputVal){
let didInputMatch = inputPattern.test(inputVal);
if(this.options.debug){
console.log(`inputPattern ("${inputPattern}"): ${didInputMatch ? "passed" : "did not pass!"}`);
}
return didInputMatch;
} else {
/**
* inputPattern doesn't seem to be set for the current input, or input is empty. Pass.
*/
return true;
}
}
/**
* Retrieves the current cursor position within a input or textarea (if any)
*/
@@ -541,24 +587,29 @@ class SimpleKeyboard {
this.dispatch(instance => {
if(instance.isMouseHold){
instance.isMouseHold = false;
}
instance.isMouseHold = false;
}
if(
(targetTagName === "textarea" ||
targetTagName === "input") &&
!instance.options.disableCaretPositioning
){
/**
* Tracks current cursor position
* As keys are pressed, text will be added/removed at that position within the input.
*/
instance.caretPosition = event.target.selectionStart;
if(
(targetTagName === "textarea" ||
targetTagName === "input") &&
!instance.options.disableCaretPositioning
){
/**
* Tracks current cursor position
* As keys are pressed, text will be added/removed at that position within the input.
*/
instance.caretPosition = event.target.selectionStart;
if(instance.options.debug){
console.log("Caret at: ", event.target.selectionStart, event.target.tagName.toLowerCase(), `(${instance.keyboardDOMClass})`);
}
}
if(instance.options.debug){
console.log("Caret at: ", event.target.selectionStart, event.target.tagName.toLowerCase(), `(${instance.keyboardDOMClass})`);
}
} else if(instance.options.disableCaretPositioning){
/**
* If we toggled off disableCaretPositioning, we must ensure caretPosition doesn't persist once reactivated.
*/
instance.caretPosition = null;
}
});
}
@@ -655,7 +706,7 @@ class SimpleKeyboard {
*/
this.clear();
let layoutClass = this.options.layout ? "hg-layout-custom" : `hg-layout-${this.options.layoutName}`;
let layoutClass = `hg-layout-${this.options.layoutName}`;
let layout = this.options.layout || KeyboardLayout.getDefaultLayout();
let useTouchEvents = this.options.useTouchEvents || false

View File

@@ -598,6 +598,42 @@ it('Keyboard caretEventHandler will detect input, textarea focus', () => {
expect(keyboard.caretPosition).toBe(3);
});
it('Keyboard caretEventHandler will not set caretPosition on disableCaretPositioning', () => {
testUtil.setDOM();
let keyboard = new Keyboard();
keyboard.caretEventHandler({
charCode: 0,
code: "KeyF",
key: "f",
which: 70,
target: {
tagName: "input",
selectionStart: 3
}
});
expect(keyboard.caretPosition).toBe(3);
keyboard.setOptions({
disableCaretPositioning: true
});
keyboard.caretEventHandler({
charCode: 0,
code: "KeyF",
key: "f",
which: 70,
target: {
tagName: "input",
selectionStart: 3
}
});
expect(keyboard.caretPosition).toBeFalsy();
});
it('Keyboard caretEventHandler ignore positioning if input, textarea is blur', () => {
testUtil.setDOM();
@@ -911,4 +947,46 @@ it('Keyboard onModulesLoaded will work', () => {
});
expect(foo).toBe("bar");
});
it('Keyboard inputPattern will work globally', () => {
testUtil.setDOM();
let keyboard = new Keyboard({
inputPattern: /^\d+$/
});
keyboard.getButtonElement("q").onclick();
expect(keyboard.getInput()).toBeFalsy();
keyboard.getButtonElement("1").onclick();
expect(keyboard.getInput()).toBe("1");
});
it('Keyboard inputPattern will work by input name', () => {
testUtil.setDOM();
let keyboard = new Keyboard({
debug: true,
inputName: "test1",
inputPattern: {
test1: /^\d+$/
}
});
keyboard.getButtonElement("q").onclick();
keyboard.getButtonElement("1").onclick();
expect(keyboard.getInput()).toBe("1");
keyboard.setOptions({
inputName: "default"
});
keyboard.getButtonElement("q").onclick();
keyboard.getButtonElement("1").onclick();
expect(keyboard.getInput()).toBe("q1");
});

View File

@@ -359,7 +359,14 @@ class Utilities {
* @param {string} string The string to transform.
*/
camelCase(string){
return string.toLowerCase().trim().split(/[.\-_\s]/g).reduce((string, word) => string + word[0].toUpperCase() + word.slice(1));
return string
.toLowerCase()
.trim()
.split(/[.\-_\s]/g)
.reduce(
(string, word) =>
word.length ? string + word[0].toUpperCase() + word.slice(1) : string
);
};
/**
@@ -373,4 +380,4 @@ class Utilities {
}
}
export default Utilities;
export default Utilities;

View File

@@ -477,4 +477,10 @@ it('Keyboard removeAt will remove regular strings', () => {
keyboard.caretPosition = 6;
output = keyboard.utilities.removeAt("testie", 6, true);
expect(keyboard.caretPosition).toBe(5);
});
it('Keyboard will work with custom (and weird) class', () => {
testUtil.setDOM("my--weird--class");
let keyboard = new Keyboard(".my--weird--class");
expect(keyboard.keyboardDOMClass).toBe("my--weird--class");
});