mirror of
https://github.com/hodgef/simple-keyboard.git
synced 2026-02-03 00:06:50 +08:00
Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
effee00b87 | ||
|
|
90b408eff6 | ||
|
|
21fa732b1f | ||
|
|
80f4307c36 | ||
|
|
681bb3d0ee | ||
|
|
e1fa685c6c | ||
|
|
2de7154128 | ||
|
|
c9afe43f5b | ||
|
|
c59f819db9 | ||
|
|
1f9efb0c66 | ||
|
|
32cbce8c8a | ||
|
|
6c2236f762 | ||
|
|
23a50e6f44 | ||
|
|
c316d493c7 | ||
|
|
70e7635f25 | ||
|
|
f5b73b09e7 | ||
|
|
7432e01740 | ||
|
|
459ab71c45 | ||
|
|
a5c177e41c | ||
|
|
d382945de7 | ||
|
|
4335f477a1 | ||
|
|
d03f00c0d1 | ||
|
|
9cea07dd41 | ||
|
|
efe18e7240 | ||
|
|
82e242a806 | ||
|
|
4a9d485d5b | ||
|
|
6ffd2e77ad | ||
|
|
7753bc5ba3 | ||
|
|
9c4fa00363 | ||
|
|
251af057d8 | ||
|
|
e60574d56d | ||
|
|
b3b482e864 | ||
|
|
ff037ad5b7 | ||
|
|
ede2ce04b1 | ||
|
|
10380099e6 | ||
|
|
058b6774da | ||
|
|
b5cbfa780b | ||
|
|
5c40dd3109 |
5
.github/ISSUE_TEMPLATE/bug_report.md
vendored
5
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -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.
|
||||
|
||||
3
.github/ISSUE_TEMPLATE/feature_request.md
vendored
3
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,6 +1,9 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea you'd like to see in simple-keyboard
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
*
|
||||
* simple-keyboard v2.11.5
|
||||
* simple-keyboard v2.14.0
|
||||
* https://github.com/hodgef/simple-keyboard
|
||||
*
|
||||
* Copyright (c) Francisco Hodge (https://github.com/hodgef)
|
||||
@@ -8,5 +8,5 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
*/body,html{margin:0;padding:0}.simple-keyboard{font-family:HelveticaNeue-Light,Helvetica Neue Light,Helvetica Neue,Helvetica,Arial,Lucida Grande,sans-serif;width:100%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;box-sizing:border-box;overflow:hidden;touch-action:manipulation}.simple-keyboard .hg-row{display:flex}.simple-keyboard .hg-row:not(:last-child){margin-bottom:5px}.simple-keyboard .hg-row .hg-button:not(:last-child){margin-right:5px}.simple-keyboard .hg-button{display:inline-block;flex-grow:1;cursor:pointer}.hg-standardBtn{max-width:100px}.simple-keyboard.hg-theme-default{background-color:rgba(0,0,0,.1);padding:5px;border-radius:5px}.simple-keyboard.hg-theme-default .hg-button{box-shadow:0 0 3px -1px rgba(0,0,0,.3);height:40px;border-radius:5px;box-sizing:border-box;padding:5px;background:#fff;border-bottom:1px solid #b5b5b5;cursor:pointer;display:flex;align-items:center;justify-content:center}.simple-keyboard.hg-theme-default .hg-button:active{background:#e4e4e4}.simple-keyboard.hg-theme-default.hg-layout-numeric .hg-button{width:33.3%;height:60px;align-items:center;display:flex;justify-content:center}.simple-keyboard.hg-theme-default .hg-button.hg-button-numpadadd,.simple-keyboard.hg-theme-default .hg-button.hg-button-numpadenter{height:85px}.simple-keyboard.hg-theme-default .hg-button.hg-button-numpad0{width:105px}.simple-keyboard.hg-theme-default .hg-button.hg-button-com{max-width:85px}.simple-keyboard.hg-theme-default .hg-button.hg-standardBtn.hg-button-at{max-width:45px}.simple-keyboard.hg-theme-default .hg-button.hg-selectedButton{background:rgba(5,25,70,.53);color:#fff}.simple-keyboard.hg-theme-default .hg-button.hg-standardBtn[data-skbtn=".com"]{max-width:82px}.simple-keyboard.hg-theme-default .hg-button.hg-standardBtn[data-skbtn="@"]{max-width:60px}
|
||||
*/body,html{margin:0;padding:0}.simple-keyboard{font-family:HelveticaNeue-Light,Helvetica Neue Light,Helvetica Neue,Helvetica,Arial,Lucida Grande,sans-serif;width:100%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;box-sizing:border-box;overflow:hidden;touch-action:manipulation}.simple-keyboard .hg-row{display:flex}.simple-keyboard .hg-row:not(:last-child){margin-bottom:5px}.simple-keyboard .hg-row .hg-button:not(:last-child){margin-right:5px}.simple-keyboard .hg-button{display:inline-block;flex-grow:1;cursor:pointer}.hg-standardBtn{max-width:100px}.simple-keyboard.hg-theme-default{background-color:rgba(0,0,0,.1);padding:5px;border-radius:5px}.simple-keyboard.hg-theme-default .hg-button{box-shadow:0 0 3px -1px rgba(0,0,0,.3);height:40px;border-radius:5px;box-sizing:border-box;padding:5px;background:#fff;border-bottom:1px solid #b5b5b5;cursor:pointer;display:flex;align-items:center;justify-content:center}.simple-keyboard button.hg-button{border-width:0;outline:0;font-size:inherit}.simple-keyboard.hg-theme-default .hg-button:active{background:#e4e4e4}.simple-keyboard.hg-theme-default.hg-layout-numeric .hg-button{width:33.3%;height:60px;align-items:center;display:flex;justify-content:center}.simple-keyboard.hg-theme-default .hg-button.hg-button-numpadadd,.simple-keyboard.hg-theme-default .hg-button.hg-button-numpadenter{height:85px}.simple-keyboard.hg-theme-default .hg-button.hg-button-numpad0{width:105px}.simple-keyboard.hg-theme-default .hg-button.hg-button-com{max-width:85px}.simple-keyboard.hg-theme-default .hg-button.hg-standardBtn.hg-button-at{max-width:45px}.simple-keyboard.hg-theme-default .hg-button.hg-selectedButton{background:rgba(5,25,70,.53);color:#fff}.simple-keyboard.hg-theme-default .hg-button.hg-standardBtn[data-skbtn=".com"]{max-width:82px}.simple-keyboard.hg-theme-default .hg-button.hg-standardBtn[data-skbtn="@"]{max-width:60px}
|
||||
/*# sourceMappingURL=index.css.map */
|
||||
File diff suppressed because one or more lines are too long
199
build/index.d.ts
vendored
Normal file
199
build/index.d.ts
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
declare module 'simple-keyboard' {
|
||||
interface KeyboardLayoutObject {
|
||||
default: string[];
|
||||
shift?: string[];
|
||||
}
|
||||
|
||||
interface KeyboardButtonTheme {
|
||||
class: string;
|
||||
buttons: string;
|
||||
}
|
||||
|
||||
interface KeyboardOptions {
|
||||
/**
|
||||
* Modify the keyboard layout.
|
||||
*/
|
||||
layout?: KeyboardLayoutObject;
|
||||
|
||||
/**
|
||||
* Specifies which layout should be used.
|
||||
*/
|
||||
layoutName?: string;
|
||||
|
||||
/**
|
||||
* Replaces variable buttons (such as `{bksp}`) with a human-friendly name (e.g.: `backspace`).
|
||||
*/
|
||||
display?: { [button: string]: string };
|
||||
|
||||
/**
|
||||
* By default, when you set the display property, you replace the default one. This setting merges them instead.
|
||||
*/
|
||||
mergeDisplay?: boolean;
|
||||
|
||||
/**
|
||||
* A prop to add your own css classes to the keyboard wrapper. You can add multiple classes separated by a space.
|
||||
*/
|
||||
theme?: string;
|
||||
|
||||
/**
|
||||
* A prop to add your own css classes to one or several buttons.
|
||||
*/
|
||||
buttonTheme?: KeyboardButtonTheme[];
|
||||
|
||||
/**
|
||||
* Runs a `console.log` every time a key is pressed. Displays the buttons pressed and the current input.
|
||||
*/
|
||||
debug?: boolean;
|
||||
|
||||
/**
|
||||
* Specifies whether clicking the "ENTER" button will input a newline (`\n`) or not.
|
||||
*/
|
||||
newLineOnEnter?: boolean;
|
||||
|
||||
/**
|
||||
* Specifies whether clicking the "TAB" button will input a tab character (`\t`) or not.
|
||||
*/
|
||||
tabCharOnTab?: boolean;
|
||||
|
||||
/**
|
||||
* Allows you to use a single simple-keyboard instance for several inputs.
|
||||
*/
|
||||
inputName?: string;
|
||||
|
||||
/**
|
||||
* `number`: Restrains all of simple-keyboard inputs to a certain length. This should be used in addition to the input element’s maxlengthattribute.
|
||||
*
|
||||
* `{ [inputName: string]: number }`: Restrains simple-keyboard’s individual inputs to a certain length. This should be used in addition to the input element’s maxlengthattribute.
|
||||
*/
|
||||
maxLength?:
|
||||
| number
|
||||
| {
|
||||
[inputName: string]: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* When set to true, this option synchronizes the internal input of every simple-keyboard instance.
|
||||
*/
|
||||
syncInstanceInputs?: boolean;
|
||||
|
||||
/**
|
||||
* Enable highlighting of keys pressed on physical keyboard.
|
||||
*/
|
||||
physicalKeyboardHighlight?: boolean;
|
||||
|
||||
/**
|
||||
* Calling preventDefault for the mousedown events keeps the focus on the input.
|
||||
*/
|
||||
preventMouseDownDefault?: boolean;
|
||||
|
||||
/**
|
||||
* Define the text color that the physical keyboard highlighted key should have.
|
||||
*/
|
||||
physicalKeyboardHighlightTextColor?: string;
|
||||
|
||||
/**
|
||||
* Define the background color that the physical keyboard highlighted key should have.
|
||||
*/
|
||||
physicalKeyboardHighlightBgColor?: string;
|
||||
|
||||
/**
|
||||
* Render buttons as a button element instead of a div element.
|
||||
*/
|
||||
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}").
|
||||
*/
|
||||
onKeyPress?: (button: string) => any;
|
||||
|
||||
/**
|
||||
* Executes the callback function on input change. Returns the current input's string.
|
||||
*/
|
||||
onChange?: (input: string) => any;
|
||||
|
||||
/**
|
||||
* Executes the callback function every time simple-keyboard is rendered (e.g: when you change layouts).
|
||||
*/
|
||||
onRender?: () => void;
|
||||
|
||||
/**
|
||||
* Executes the callback function once simple-keyboard is rendered for the first time (on initialization).
|
||||
*/
|
||||
onInit?: () => void;
|
||||
|
||||
/**
|
||||
* Executes the callback function on input change. Returns the input object with all defined inputs.
|
||||
*/
|
||||
onChangeAll?: (inputs: any) => any;
|
||||
}
|
||||
|
||||
class Keyboard {
|
||||
constructor(selector: string, options: KeyboardOptions);
|
||||
constructor(options: KeyboardOptions);
|
||||
options: KeyboardOptions;
|
||||
|
||||
/**
|
||||
* Adds/Modifies an entry to the `buttonTheme`. Basically a way to add a class to a button.
|
||||
* @param {string} buttons List of buttons to select (separated by a space).
|
||||
* @param {string} className Classes to give to the selected buttons (separated by space).
|
||||
*/
|
||||
addButtonTheme(buttons: string, className: string): void;
|
||||
|
||||
/**
|
||||
* Removes/Amends an entry to the `buttonTheme`. Basically a way to remove a class previously added to a button through buttonTheme or addButtonTheme.
|
||||
* @param {string} buttons List of buttons to select (separated by a space).
|
||||
* @param {string} className Classes to give to the selected buttons (separated by space).
|
||||
*/
|
||||
removeButtonTheme(buttons: string, className: string): void;
|
||||
|
||||
/**
|
||||
* Clear the keyboard's input.
|
||||
*
|
||||
* @param {string} [inputName] optional - the internal input to select
|
||||
*/
|
||||
clearInput(inputName?: string): void;
|
||||
|
||||
/**
|
||||
* Get the keyboard’s input (You can also get it from the onChange prop).
|
||||
* @param {string} [inputName] optional - the internal input to select
|
||||
*/
|
||||
getInput(inputName?: string): string;
|
||||
|
||||
/**
|
||||
* Set the keyboard’s input.
|
||||
* @param {string} input the input value
|
||||
* @param {string} inputName optional - the internal input to select
|
||||
*/
|
||||
setInput(input: string, inputName?: string): void;
|
||||
|
||||
/**
|
||||
* Set new option or modify existing ones after initialization.
|
||||
* @param {KeyboardOptions} option The option to set
|
||||
*/
|
||||
setOptions(options: KeyboardOptions): void;
|
||||
|
||||
/**
|
||||
* Send a command to all simple-keyboard instances at once (if you have multiple instances).
|
||||
* @param {function(instance: object, key: string)} callback Function to run on every instance
|
||||
*/
|
||||
dispatch(callback: (instance: any, key: string) => void): void;
|
||||
|
||||
/**
|
||||
* Get the DOM Element of a button. If there are several buttons with the same name, an array of the DOM Elements is returned.
|
||||
* @param {string} button The button layout name to select
|
||||
*/
|
||||
getButtonElement(button: string): HTMLElement | HTMLElement[];
|
||||
}
|
||||
|
||||
export default Keyboard;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -79,6 +79,7 @@ module.exports = {
|
||||
appPackageJson: resolveApp('package.json'),
|
||||
appSrc: resolveApp('src'),
|
||||
appSrcLib: resolveApp('src/lib'),
|
||||
appSrcLibTypes: resolveApp('src/lib/@types'),
|
||||
appSrcDemo: resolveApp('src/demo'),
|
||||
appTsConfig: resolveApp('tsconfig.json'),
|
||||
yarnLockFile: resolveApp('yarn.lock'),
|
||||
|
||||
@@ -21,6 +21,7 @@ const getClientEnvironment = require('./env');
|
||||
const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
|
||||
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin-alt');
|
||||
const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const getPackageJson = require('./getPackageJson');
|
||||
|
||||
|
||||
@@ -510,6 +511,12 @@ module.exports = {
|
||||
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
|
||||
// You can remove this if you don't use Moment.js:
|
||||
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: `${paths.appSrcLibTypes}`,
|
||||
to: paths.appLayoutsBuild
|
||||
}
|
||||
]),
|
||||
// Generate a service worker script that will precache, and keep up to date,
|
||||
// the HTML & assets that are part of the Webpack build.
|
||||
/*new WorkboxWebpackPlugin.GenerateSW({
|
||||
|
||||
2353
package-lock.json
generated
2353
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
70
package.json
70
package.json
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"name": "simple-keyboard",
|
||||
"version": "2.11.5",
|
||||
"version": "2.14.0",
|
||||
"description": "On-screen Javascript Virtual Keyboard",
|
||||
"main": "build/index.js",
|
||||
"types": "build/index.d.ts",
|
||||
"scripts": {
|
||||
"start": "node scripts/start.js",
|
||||
"build": "node scripts/build.js",
|
||||
@@ -34,72 +35,79 @@
|
||||
"touchscreen",
|
||||
"touch-screen",
|
||||
"kiosk",
|
||||
"osk"
|
||||
"osk",
|
||||
"js"
|
||||
],
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.1.6",
|
||||
"@babel/plugin-proposal-class-properties": "^7.1.0",
|
||||
"@babel/preset-env": "^7.1.6",
|
||||
"@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",
|
||||
"css-loader": "1.0.1",
|
||||
"dotenv": "6.1.0",
|
||||
"chalk": "2.4.2",
|
||||
"copy-webpack-plugin": "^4.6.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",
|
||||
"jest-resolve": "23.6.0",
|
||||
"mini-css-extract-plugin": "0.4.4",
|
||||
"mini-css-extract-plugin": "0.5.0",
|
||||
"optimize-css-assets-webpack-plugin": "5.0.1",
|
||||
"pnp-webpack-plugin": "1.2.0",
|
||||
"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.1",
|
||||
"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.26.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%",
|
||||
"not dead",
|
||||
"not ie <= 11",
|
||||
"not op_mini all"
|
||||
],
|
||||
|
||||
@@ -31,7 +31,7 @@ class App {
|
||||
onChange: input => this.onChange(input),
|
||||
onKeyPress: button => this.onKeyPress(button),
|
||||
newLineOnEnter: true,
|
||||
physicalKeyboardHighlight: true,
|
||||
physicalKeyboardHighlight: true
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#root .simple-keyboard-preview {
|
||||
background: rgba(0,0,0,0.8);
|
||||
border: 20px solid rgba(0,0,0,0.1);
|
||||
height: 260px;
|
||||
height: 200px;
|
||||
border-top-right-radius: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
padding: 10px;
|
||||
|
||||
199
src/lib/@types/index.d.ts
vendored
Normal file
199
src/lib/@types/index.d.ts
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
declare module 'simple-keyboard' {
|
||||
interface KeyboardLayoutObject {
|
||||
default: string[];
|
||||
shift?: string[];
|
||||
}
|
||||
|
||||
interface KeyboardButtonTheme {
|
||||
class: string;
|
||||
buttons: string;
|
||||
}
|
||||
|
||||
interface KeyboardOptions {
|
||||
/**
|
||||
* Modify the keyboard layout.
|
||||
*/
|
||||
layout?: KeyboardLayoutObject;
|
||||
|
||||
/**
|
||||
* Specifies which layout should be used.
|
||||
*/
|
||||
layoutName?: string;
|
||||
|
||||
/**
|
||||
* Replaces variable buttons (such as `{bksp}`) with a human-friendly name (e.g.: `backspace`).
|
||||
*/
|
||||
display?: { [button: string]: string };
|
||||
|
||||
/**
|
||||
* By default, when you set the display property, you replace the default one. This setting merges them instead.
|
||||
*/
|
||||
mergeDisplay?: boolean;
|
||||
|
||||
/**
|
||||
* A prop to add your own css classes to the keyboard wrapper. You can add multiple classes separated by a space.
|
||||
*/
|
||||
theme?: string;
|
||||
|
||||
/**
|
||||
* A prop to add your own css classes to one or several buttons.
|
||||
*/
|
||||
buttonTheme?: KeyboardButtonTheme[];
|
||||
|
||||
/**
|
||||
* Runs a `console.log` every time a key is pressed. Displays the buttons pressed and the current input.
|
||||
*/
|
||||
debug?: boolean;
|
||||
|
||||
/**
|
||||
* Specifies whether clicking the "ENTER" button will input a newline (`\n`) or not.
|
||||
*/
|
||||
newLineOnEnter?: boolean;
|
||||
|
||||
/**
|
||||
* Specifies whether clicking the "TAB" button will input a tab character (`\t`) or not.
|
||||
*/
|
||||
tabCharOnTab?: boolean;
|
||||
|
||||
/**
|
||||
* Allows you to use a single simple-keyboard instance for several inputs.
|
||||
*/
|
||||
inputName?: string;
|
||||
|
||||
/**
|
||||
* `number`: Restrains all of simple-keyboard inputs to a certain length. This should be used in addition to the input element’s maxlengthattribute.
|
||||
*
|
||||
* `{ [inputName: string]: number }`: Restrains simple-keyboard’s individual inputs to a certain length. This should be used in addition to the input element’s maxlengthattribute.
|
||||
*/
|
||||
maxLength?:
|
||||
| number
|
||||
| {
|
||||
[inputName: string]: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* When set to true, this option synchronizes the internal input of every simple-keyboard instance.
|
||||
*/
|
||||
syncInstanceInputs?: boolean;
|
||||
|
||||
/**
|
||||
* Enable highlighting of keys pressed on physical keyboard.
|
||||
*/
|
||||
physicalKeyboardHighlight?: boolean;
|
||||
|
||||
/**
|
||||
* Calling preventDefault for the mousedown events keeps the focus on the input.
|
||||
*/
|
||||
preventMouseDownDefault?: boolean;
|
||||
|
||||
/**
|
||||
* Define the text color that the physical keyboard highlighted key should have.
|
||||
*/
|
||||
physicalKeyboardHighlightTextColor?: string;
|
||||
|
||||
/**
|
||||
* Define the background color that the physical keyboard highlighted key should have.
|
||||
*/
|
||||
physicalKeyboardHighlightBgColor?: string;
|
||||
|
||||
/**
|
||||
* Render buttons as a button element instead of a div element.
|
||||
*/
|
||||
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}").
|
||||
*/
|
||||
onKeyPress?: (button: string) => any;
|
||||
|
||||
/**
|
||||
* Executes the callback function on input change. Returns the current input's string.
|
||||
*/
|
||||
onChange?: (input: string) => any;
|
||||
|
||||
/**
|
||||
* Executes the callback function every time simple-keyboard is rendered (e.g: when you change layouts).
|
||||
*/
|
||||
onRender?: () => void;
|
||||
|
||||
/**
|
||||
* Executes the callback function once simple-keyboard is rendered for the first time (on initialization).
|
||||
*/
|
||||
onInit?: () => void;
|
||||
|
||||
/**
|
||||
* Executes the callback function on input change. Returns the input object with all defined inputs.
|
||||
*/
|
||||
onChangeAll?: (inputs: any) => any;
|
||||
}
|
||||
|
||||
class Keyboard {
|
||||
constructor(selector: string, options: KeyboardOptions);
|
||||
constructor(options: KeyboardOptions);
|
||||
options: KeyboardOptions;
|
||||
|
||||
/**
|
||||
* Adds/Modifies an entry to the `buttonTheme`. Basically a way to add a class to a button.
|
||||
* @param {string} buttons List of buttons to select (separated by a space).
|
||||
* @param {string} className Classes to give to the selected buttons (separated by space).
|
||||
*/
|
||||
addButtonTheme(buttons: string, className: string): void;
|
||||
|
||||
/**
|
||||
* Removes/Amends an entry to the `buttonTheme`. Basically a way to remove a class previously added to a button through buttonTheme or addButtonTheme.
|
||||
* @param {string} buttons List of buttons to select (separated by a space).
|
||||
* @param {string} className Classes to give to the selected buttons (separated by space).
|
||||
*/
|
||||
removeButtonTheme(buttons: string, className: string): void;
|
||||
|
||||
/**
|
||||
* Clear the keyboard's input.
|
||||
*
|
||||
* @param {string} [inputName] optional - the internal input to select
|
||||
*/
|
||||
clearInput(inputName?: string): void;
|
||||
|
||||
/**
|
||||
* Get the keyboard’s input (You can also get it from the onChange prop).
|
||||
* @param {string} [inputName] optional - the internal input to select
|
||||
*/
|
||||
getInput(inputName?: string): string;
|
||||
|
||||
/**
|
||||
* Set the keyboard’s input.
|
||||
* @param {string} input the input value
|
||||
* @param {string} inputName optional - the internal input to select
|
||||
*/
|
||||
setInput(input: string, inputName?: string): void;
|
||||
|
||||
/**
|
||||
* Set new option or modify existing ones after initialization.
|
||||
* @param {KeyboardOptions} option The option to set
|
||||
*/
|
||||
setOptions(options: KeyboardOptions): void;
|
||||
|
||||
/**
|
||||
* Send a command to all simple-keyboard instances at once (if you have multiple instances).
|
||||
* @param {function(instance: object, key: string)} callback Function to run on every instance
|
||||
*/
|
||||
dispatch(callback: (instance: any, key: string) => void): void;
|
||||
|
||||
/**
|
||||
* Get the DOM Element of a button. If there are several buttons with the same name, an array of the DOM Elements is returned.
|
||||
* @param {string} button The button layout name to select
|
||||
*/
|
||||
getButtonElement(button: string): HTMLElement | HTMLElement[];
|
||||
}
|
||||
|
||||
export default Keyboard;
|
||||
}
|
||||
@@ -57,6 +57,13 @@ body, html {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* When using option "useButtonTag" */
|
||||
.simple-keyboard button.hg-button {
|
||||
border-width: 0;
|
||||
outline: 0;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.simple-keyboard.hg-theme-default .hg-button:active {
|
||||
background: #e4e4e4;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ class SimpleKeyboard {
|
||||
* @param {Array} params If first parameter is a string, it is considered the container class. The second parameter is then considered the options object. If first parameter is an object, it is considered the options object.
|
||||
*/
|
||||
constructor(...params){
|
||||
let keyboardDOMQuery = typeof params[0] === "string" ? params[0] : '.simple-keyboard';
|
||||
let keyboardDOMQuery = typeof params[0] === "string" ? params[0] : ".simple-keyboard";
|
||||
let options = typeof params[0] === "object" ? params[0] : params[1];
|
||||
|
||||
if(!options)
|
||||
@@ -58,6 +58,9 @@ class SimpleKeyboard {
|
||||
* @property {function} onRender Executes the callback function every time simple-keyboard is rendered (e.g: when you change layouts).
|
||||
* @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";
|
||||
@@ -94,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`).
|
||||
@@ -179,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
|
||||
@@ -502,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)
|
||||
*/
|
||||
@@ -540,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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -621,7 +673,7 @@ class SimpleKeyboard {
|
||||
module.init(this);
|
||||
});
|
||||
|
||||
this.keyboardPluginClasses = this.keyboardPluginClasses + ' modules-loaded';
|
||||
this.keyboardPluginClasses = this.keyboardPluginClasses + " modules-loaded";
|
||||
|
||||
this.render();
|
||||
this.onModulesLoaded();
|
||||
@@ -654,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
|
||||
|
||||
@@ -668,7 +720,7 @@ class SimpleKeyboard {
|
||||
let themeButtons;
|
||||
|
||||
if(typeof themeObj.buttons === "string"){
|
||||
themeButtons = themeObj.buttons.split(' ');
|
||||
themeButtons = themeObj.buttons.split(" ");
|
||||
}
|
||||
|
||||
if(themeButtons){
|
||||
@@ -701,12 +753,12 @@ class SimpleKeyboard {
|
||||
* Iterating through each row
|
||||
*/
|
||||
layout[this.options.layoutName].forEach((row, rIndex) => {
|
||||
let rowArray = row.split(' ');
|
||||
let rowArray = row.split(" ");
|
||||
|
||||
/**
|
||||
* Creating empty row
|
||||
*/
|
||||
var rowDOM = document.createElement('div');
|
||||
let rowDOM = document.createElement("div");
|
||||
rowDOM.className += "hg-row";
|
||||
|
||||
/**
|
||||
@@ -720,7 +772,8 @@ class SimpleKeyboard {
|
||||
/**
|
||||
* Creating button
|
||||
*/
|
||||
var buttonDOM = document.createElement('div');
|
||||
let buttonType = this.options.useButtonTag ? "button" : "div";
|
||||
let buttonDOM = document.createElement(buttonType);
|
||||
buttonDOM.className += `hg-button ${fctBtnClass}${buttonThemeClass ? " "+buttonThemeClass : ""}`;
|
||||
|
||||
if (useTouchEvents) {
|
||||
@@ -761,7 +814,7 @@ class SimpleKeyboard {
|
||||
/**
|
||||
* Adding button label to button
|
||||
*/
|
||||
var buttonSpanDOM = document.createElement('span');
|
||||
let buttonSpanDOM = document.createElement('span');
|
||||
buttonSpanDOM.innerHTML = buttonDisplayName;
|
||||
buttonDOM.appendChild(buttonSpanDOM);
|
||||
|
||||
|
||||
@@ -137,7 +137,9 @@ it('Keyboard onKeyPress will work', () => {
|
||||
it('Keyboard standard function buttons will not change input', () => {
|
||||
testUtil.setDOM();
|
||||
|
||||
let keyboard = new Keyboard();
|
||||
let keyboard = new Keyboard({
|
||||
useButtonTag: true
|
||||
});
|
||||
|
||||
testUtil.iterateButtons((button) => {
|
||||
if(button.getAttribute("data-skbtn") === "{shift}"){
|
||||
@@ -596,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();
|
||||
|
||||
@@ -909,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");
|
||||
});
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
});
|
||||
Reference in New Issue
Block a user