
A simple yet customizable, fully responsive on-screen virtual keyboard for mobile, tablet, and desktop.
How to use it:
1. Install & Download with NPM.
# NPM $ npm install simple-keyboard --save
2. Import the package as a module.
import Keyboard from 'simple-keyboard';
3. Import the necessary stylesheet.
import 'simple-keyboard/build/css/index.css';
4. Or load the necessary files from a CDN.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/simple-keyboard@latest/build/css/index.css"> <script src="https://cdn.jsdelivr.net/npm/simple-keyboard@latest/build/index.js"></script>
5. Create the keyboard container & matched input field.
<input class="input"> <div class="simple-keyboard"></div>
6. Attach the Virtual Keyboard to the input field.
// Default Theme
const Keyboard = window.SimpleKeyboard.default;
// initialize
const myKeyboard = new Keyboard({
onChange: input => onChange(input),
onKeyPress: button => onKeyPress(button)
});
// events
function onChange(input) {
document.querySelector(".input").value = input;
console.log("Input changed", input);
}
function onKeyPress(button) {
console.log("Button pressed", button);
}7. Available options.
/**
* Modify the keyboard layout.
*/
/*
{
'default': [
'` 1 2 3 4 5 6 7 8 9 0 - = {bksp}',
'{tab} q w e r t y u i o p [ ] \\',
'{lock} a s d f g h j k l ; \' {enter}',
'{shift} z x c v b n m , . / {shift}',
'.com @ {space}'
],
'shift': [
'~ ! @ # $ % ^ & * ( ) _ + {bksp}',
'{tab} Q W E R T Y U I O P { } |',
'{lock} A S D F G H J K L : " {enter}',
'{shift} Z X C V B N M < > ? {shift}',
'.com @ {space}'
]
}
*/
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[];
/**
* A prop to add your own attributes to one or several buttons.
*/
buttonAttributes?: KeyboardButtonAttributes[];
/**
* 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?: any;
/**
* 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;
/**
* Calls handler for a button highlighted by physicalKeyboardHighlight
* In other words, this calls keyboard.handleButtonClicked(buttonName) on the highlighted button
*/
physicalKeyboardHighlightPress?: boolean;
/**
* Trigger click on a button's element when using physicalKeyboardHighlightPress
* In other words, this calls button.click() on the highlighted button
*/
physicalKeyboardHighlightPressUseClick?: boolean;
/**
* Whether physicalKeyboardHighlightPress should use pointer events to trigger buttons.
*/
physicalKeyboardHighlightPressUsePointerEvents?: 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;
/**
* Whether physicalKeyboardHighlight should use preventDefault to disable default browser actions.
*/
physicalKeyboardHighlightPreventDefault?: boolean;
/**
* Calling preventDefault for the mousedown events keeps the focus on the input.
*/
preventMouseDownDefault?: boolean;
/**
* Calling preventDefault for the mouseup events.
*/
preventMouseUpDefault?: boolean;
/**
* Stops pointer down events on simple-keyboard buttons from bubbling to parent elements.
*/
stopMouseDownPropagation?: boolean;
/**
* Stops pointer up events on simple-keyboard buttons from bubbling to parent elements.
*/
stopMouseUpPropagation?: boolean;
/**
* 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;
/**
* Instructs simple-keyboard to use touch events instead of click events.
*/
useTouchEvents?: boolean;
/**
* Enable useTouchEvents automatically when touch device is detected.
*/
autoUseTouchEvents?: boolean;
/**
* Opt out of PointerEvents handling, falling back to the prior mouse event logic.
*/
useMouseEvents?: boolean;
/**
* Disable button hold action.
*/
disableButtonHold?: boolean;
/**
* Adds unicode right-to-left control characters to input return values.
*/
rtl?: boolean;
/**
* Enable input method editor candidate list support.
*/
enableLayoutCandidates?: boolean;
/**
* Character suggestions to be shown on certain key presses
*/
layoutCandidates?: {
[key: string]: string;
};
/**
* Exclude buttons from layout
*/
excludeFromLayout?: {
[key: string]: string[];
};
/**
* Determines size of layout candidate list
*/
layoutCandidatesPageSize?: number;
/**
* Determines whether layout candidate match should be case sensitive.
*/
layoutCandidatesCaseSensitiveMatch?: boolean;
/**
* Disables the automatic normalization for selected layout candidates
*/
disableCandidateNormalization?: boolean;
/**
* Enables onKeyPress triggering for layoutCandidate items
*/
enableLayoutCandidatesKeyPress?: boolean;
/**
* Executes the callback function every time simple-keyboard is rendered (e.g: when you change layouts).
*/
onRender?: (instance?: SimpleKeyboard) => void;
/**
* Executes the callback function once simple-keyboard is rendered for the first time (on initialization).
*/
onInit?: (instance?: SimpleKeyboard) => void;
/**
* Retrieves the current input
*/
onChange?: (input: string, e?: MouseEvent) => any;
/**
* Retrieves all inputs
*/
onChangeAll?: (inputObj: KeyboardInput, e?: MouseEvent) => any;
/**
* Retrieves the pressed key
*/
onKeyPress?: (button: string, e?: MouseEvent) => any;
/**
* Retrieves the released key
*/
onKeyReleased?: (button: string, e?: MouseEvent) => any;
/**
* Module options can have any format
*/
[name: string]: any;8. API methods.
keyboard.clearInput("myInputName");
keyboard.getInput("myInputName");
keyboard.setInput("Hello World!", "myInputName");
keyboard.replaceInput({default: "My Value", input2: "My Other Value"});
keyboard.setOptions({
theme: "my-custom-theme"
});
keyboard.destroy();
keyboard.dispatch(instance => {
instance.setOptions({
buttonTheme: [
{
class: "myClass",
buttons: `a b c`
}
]
})
});
keyboard.getButtonElement('a');
keyboard.addButtonTheme("a b c {enter}", "myClass1 myClass2");
keyboard.removeButtonTheme("b c", "myClass1 myClass2");
keyboard.recurseButtons(buttonElement => {
console.log('buttonElement', buttonElement);
});
keyboard.setCaretPosition(1);
// caretStart = 1, caretEnd = 2
keyboard.setCaretPosition(1, 2);
keyboard.getCaretPosition();
keyboard.getCaretPositionEnd();Changelog:
3.8.0 (09/12/2024)
- Fixed caret positioning issue
3.7.0 (08/20/2023)
- ESM output has been added.







