hodgef / simple-keyboard Goto Github PK
View Code? Open in Web Editor NEWJavascript Virtual Keyboard - Customizable, responsive and lightweight
Home Page: https://virtual-keyboard.js.org/
License: MIT License
Javascript Virtual Keyboard - Customizable, responsive and lightweight
Home Page: https://virtual-keyboard.js.org/
License: MIT License
Is your feature request related to a problem? Please describe.
No.
Describe the solution you'd like
I would like to be able to toggle to a mode where I can navigate through the keys in the keyboard using some configurable input. For example, a cursor would start at the top-left most key in the keyboard [0,0]. Pressing the right arrow key on the physical keyboard as an input (or any other configurable input) would move the cursor one column to the right to [0,1]. For example, on a QWERTY layout: if cursor is on 's', moving right will move cursor to 'd'.
Describe alternatives you've considered
The Motte keyboard offers a similar feature: https://jsfiddle.net/Mottie/c6ftvy7r/
Is your feature request related to a problem? Please describe.
I am trying to create a vertical square-like keyboard with simple-keyboard, it involves creating a lot of empty space between each letter. I want simple-keyboard to register those as empty, disabled buttons but it's registering each space as a button.
Describe the solution you'd like
I tried using display: { ' ':'' }. However it didn't work.
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
Additional context
Add any other context or screenshots about the feature request here.
Simple-keyboard version
2.21.0
Describe the bug
When using the preventMouseDownDefault property together with useTouchEvents, the input field looses focus when typing on the keyboard. I've attached listeners for focus and blur on my input to toggle visibility of the keyboard. Whenever the textfield looses focus the keyboard hides. It works as expected works correctly with mouse events.
I'm noticing this in the demo as well, but when you type a left or right brace, the onChange callback does not fire. We have a keyboard config setup such as this:
/*
* u20AC=€ (euro) u00A3=£ (pound)
* u00A5=¥ (yen) u00A7=§ (section [for law])
* u007B == { u007D == }
*/
symbols: [
'@gmail.com @yahoo.com @outlook.com @hotmail.com @mail.com @aol.com',
'1 2 3 4 5 6 7 8 9 0 {bksp}',
'\u20AC \u00A3 \u00A5 _ ^ [ ] \u007B \u007D {enter}',
'{numbers} \u00A7 | ~ ... \\ < > ! ? {numbers}',
'{abc} .com {space} {abc}'
]
Only the button press event fires when you type either the left or right brace, so in that callback, I explicitly check for the values, and reset the simple keyboard input and the value of my text box.
if (button === '\u007B' || button === '\u007D') {
const newValue = `${keyboard.getInput()}${button}`;
keyboard.setInput(newValue);
emailInput.setValue(newValue);
}
The above solution works for my purposes, but I'm assuming this is a bug in the library. I'll continue to investigate to see where there's an issue.
Describe the bug
Expected:
Cursor should have stayed at start of input box and delete nothing
Actual:
It deletes 9
Hi Team,
Is there a documentation or any lead on how can we use this keyboard on Nuxt apps?
Thanks
Currently, if you have multiple instances of simple-keyboard, each instance sets caret handling events so they can update their internal cursor position.
It would be more efficient to make only the first instance set these events, then this instance would update all other instances.
As per:
hodgef/react-simple-keyboard#34
Demo (react-simple-keyboard):
https://codesandbox.io/s/w2z8mjx167
Is your feature request related to a problem? Please describe.
No, i want customize the layout of keyboard [Angular].
Describe the solution you'd like
I want to achieve keyboard same attached image below.
Describe alternatives you've considered
I can change button style by myself but problem is i want larger width space button and other key buttons height and width should be same and also spacing need to be same as attached screenshot.
Additional context
Keyboard I want
Keyboard looks right now
Simple-keyboard version
2.13.2
Describe the bug
I'm following the sample, here, to show/hide the keyboard on input focus.
I notice that when the Caps or Shift buttons are clicked, the keyboard is hidden. I'm guessing this is some behavior related to switching out the keyboard layout when those buttons are clicked, but I would expect that the keyboard would remain visible.
@hodgef
Can this be done only with the features of that application? If yes, what would the implementation be like?
I need 'ç' or 'à' type characters when I click on a button, similar to what is done on Google Keyboard.
Tnks!
Hi,
I am having an issue which is that I would like to be able to type on my physical keyboard and have the keys trigger click events on the virtual keyboard - this is for typing on an american keyboard and having the input field be in Arabic.
I've found the physicalKeyboardHighlight and actually it doesn't seem to highlight any of my letter keys (using Chrome on Linux). I've also found the physicalKeyboardInterface method, and used the initKeyboardListener, however this does not appear to do anything. I don't know if that's because there is an issue as described with highlights issue, or if I am using it wrong.
Thanks!!
Simple-keyboard version
2.14.2
Bug
Following this reddit thread, some users (including me) reported that CSS is not loaded in Angular 6+ using an import statement to load CSS file.
Solution
Just don't import the css using "import 'simple-keyboard/build/css/index.css';"
in the component file. Instead, open angular.json
at the root of your project, find the styles
array, and add "node_modules/simple-keyboard/build/css/index.css"
to it.
It seems it's a new way to load CSS files in new angular. Doing this, I had no further problems with CSS loading.
Hello there! Is there a way to prevent events from firing multiple times on key-down? Thank you in advance!
Hi,
I can't delete from last character if a value exist in my input
<input class="input" type="text" name="lastName" value="FOO" id="lastName">
any idea ?
Hi thanks for the great work you have done..
how to limit the number of character in the input. Normally we will use maxlength attribute. But in this case maxlength is does not working..
And also is it possible to move to next input box by clicking at tab or enter button?
cheers
zul
Simple-keyboard version
2.20.3
Describe the bug
In your demo example, you add a custom layout name to the layout object. However, the interface does not support it, and is impossible to extend, as it is not exported.
interface KeyboardLayoutObject {
default: string[];
shift?: string[];
}
Perhaps it should be like this?
interface KeyboardLayoutObject {
default: string[];
shift?: string[];
[key: string]: string[];
}
Simple-keyboard version
"react-simple-keyboard": "^1.21.2"
Describe the bug
I have added logic to keep track of cursor position. This works fine. But have two problems.
if you use the js keyboard to type abc
and move the cursor to be behind a
. Click backspace
. The cursor is moved to the back of bc
. This is the expected behaviour. Now any input from the js keyboard is still typed behind the beginning of the bc
. Typing 1
. Expected should be bc1
. Actual is 1bc
. The cursor is currently positioned at the back of bc
. It seems like the keyboard cursor position have not moved. This only happens when removing the first charactor.
Referring to the unit test below. It seems like the keyboard cursor did not move.
// unit test
it('should type on the onscreen keyboard with correct cursor position', () => {
const mountNode = document.createElement('div');
document.body.appendChild(mountNode);
const component = mount(<Input {...defaultProps} />, {attachTo: mountNode});
const input = document.querySelector('input');
document.querySelector('[data-skbtn="1"]').click();
document.querySelector('[data-skbtn="2"]').click();
document.querySelector('[data-skbtn="3"]').click();
document.querySelector('[data-skbtn="4"]').click();
expect(input.selectionStart).toBe(4);
expect(input.value).toBe('1234');
document.querySelector('[data-skbtn="{bksp}"]').click();
expect(input.selectionStart).toBe(3);
expect(input.value).toBe('123');
input.setSelectionRange(1, 1);
document.querySelector('[data-skbtn="a"]').click();
expect(input.selectionStart).toBe(2);
// currently this cannot be tested. It works fine on screen.
// expect(input.value).toBe('1a23');
component.unmount();
});
import React from 'react';
import * as PropTypes from 'prop-types';
import Keyboard from 'react-simple-keyboard';
import classNames from 'classnames';
import Portal from '@material-ui/core/Portal';
import 'react-simple-keyboard/build/css/index.css';
import styles from './Input.module.scss';
class Input extends React.PureComponent {
static propTypes = {
placeholder: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
onFocus: PropTypes.func,
value: PropTypes.string,
className: PropTypes.string,
enableVirtualKeyboard: PropTypes.bool,
};
static defaultProps = {
enableVirtualKeyboard: false,
};
state = {
layoutName: 'default',
value: '',
showKeyboard: false,
};
keyboardRef = React.createRef(); // the keyboard div
simpleKeyboardRef = React.createRef(); // the keyboard component
inputRef = React.createRef(); // the input element
showKeyboard = enable => {
if (!this.props.enableVirtualKeyboard) return;
if (this.state.showKeyboard !== enable) {
this.setState({showKeyboard: enable});
if (!enable) {
window.removeEventListener('mousedown', this.handleWindowMousedown);
}
}
};
handleWindowMousedown = e => {
// Clicks outside the keyboard should close the keyboard except the input element
if (
!(this.keyboardRef.current && this.keyboardRef.current.contains(e.target)) &&
!this.inputRef.current.contains(e.target)
) {
this.showKeyboard(false);
}
};
componentWillUnmount() {
window.removeEventListener('mousedown', this.handleWindowMousedown);
}
onChangeKeyboard = input => {
let inputValue = input;
// physical keyboard give input as an event object
if (typeof input === 'object') {
inputValue = input.target.value;
}
const inputElement = this.inputRef.current;
// get the current cursor position and increment to the next position
let cursorNextPosition =
inputElement.selectionStart + inputValue.length - this.state.value.length;
// if the next cursor is 0 at the beginning return the cursor to the back of the input
cursorNextPosition = !cursorNextPosition ? inputValue.length : cursorNextPosition;
this.setState({value: inputValue}, () =>
this.simpleKeyboardRef.keyboard.setInput(inputValue)
);
this.props.onChange(inputValue);
// only adjust cursor when input is from virtual keyboard
if (typeof input !== 'object') {
inputElement.focus();
inputElement.setSelectionRange(cursorNextPosition, cursorNextPosition);
}
};
componentDidUpdate(prevProps) {
// parent clearing the input value
if (this.props.value !== prevProps.value && this.props.value === '') {
this.onChangeKeyboard('');
}
}
onKeyPress = button => {
// handle the shift and caps lock buttons
if (button === '{shift}' || button === '{lock}') this.handleShift();
};
handleShift = () => {
const layoutName = this.state.layoutName;
this.setState({
layoutName: layoutName === 'default' ? 'shift' : 'default',
});
};
render() {
const keyboardClasses = classNames(styles.keyboard, {
[styles.keyboardHide]: !this.state.showKeyboard, // defaults to hide
});
return (
<React.Fragment>
<input
ref={this.inputRef}
className={this.props.className}
value={this.state.value}
placeholder={this.props.placeholder}
onChange={this.onChangeKeyboard}
onFocus={e => {
this.props.onFocus(e.target.value);
this.showKeyboard(true);
}}
/>
<Portal>
<div ref={this.keyboardRef} className={keyboardClasses}>
<Keyboard
ref={r => {
this.simpleKeyboardRef = r;
}}
layoutName={this.state.layoutName}
onChange={this.onChangeKeyboard}
onKeyPress={this.onKeyPress}
preventMouseDownDefault
stopMouseDownPropagation
useMouseEvents
useButtonTag
beforeRender={() =>
window.addEventListener('mousedown', this.handleWindowMousedown)
}
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}',
'@ {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}',
'{space}',
],
}}
/>
</div>
</Portal>
</React.Fragment>
);
}
}
export default Input;
[ts]
Could not find a declaration file for module 'simple-keyboard'. 'd:/.../node_modules/simple-keyboard/build/index.js' implicitly has an 'any' type.
Try npm install @types/simple-keyboard
if it exists or add a new declaration (.d.ts) file containing declare module 'simple-keyboard';
Hi,
I see some caret implementation in the code but I don't know how to handle the caret or at least show it to the users.
Thanks.
Is your feature request related to a problem? Please describe.
I can't add some Chinese words
Describe the solution you'd like
Add the options to choose the words or phrase.
Describe alternatives you've considered
no
Additional context
no
Backspace key is always deleting last character.
Steps to reproduce:
'|' is showing cursor position
Type few characters for example - "REACT|"
move cursor in between some where - for example - "REA|CT"
Press backspace - it deletes 'T' rather than 'A'
caps lock isn't working on keyboard
Simple-keyboard version
Latest build from the CDN.
Describe the bug
The backspace button doesn't work if input focus is changed by JavaScript. It still works if the input is focused by a mouse click though.
Demo: https://codesandbox.io/s/3y2r1lzlpq
Update to js-library-boilerplate 2.0
Simple-keyboard version
2.21.0
Describe the bug
When typing some long content inside a small input field, once the input is full with content for the current width, you cannot see what you are typing. The expected behaviour should be like the normal input where the text scrolls once you reach the end on the field so you can actually see the characters you type in.
I made an example code here, just try to write a long text with the simple keyboard, and you will no longer see what you type --> https://codesandbox.io/s/simplekeyboardnpmdemos-jydqh
Hey, can i use that keyboard with angular 7 version or do you have in that version? the projet i start not work version 5.2 =/
Excellent work!
I'm actually working on adding an option useTouchEvents
, because I need it for my project. Are you interested to see it as PR?
The package.json specifies react as a peer dependency but it's my understanding the vanillaJS version shouldn't depend on it correct?
Hello, we have a "PIN pad" and are trying to figure out how we can map the normal keyboard number keys and the number pad keys together so that they will both highlight the same simple-keyboard key.
For example, if we use the {numpad1} key in simple-keyboard, it only highlights when using the number pad key, but not the "1" key on the keyboard. And vice versa, if we use the 1 key, only the "1" key on the keyboard will highlight, but not the number pad key.
Is there a configuration item that I have missed, or something that I can do to have this type of function?
Thank you!
Simple-keyboard version
2.14.3
Describe the bug
In Angular 6, when trying to include multiple keyboards in a component (embedding simple keyboard as a component itself), only the first one is displayed/working.
Here is a minimal Github project that shows the issue: https://github.com/ddahan/pockey
Screenshots
Debug
As you can see, the first app-simple-component
div contains a keyboard html content, but the second div contains nothing.
Simple-keyboard version
v2.13.4
Describe the bug
I tried to put a negative or floating point number in a number type input field, when I put - or .(for example only -, or only 2.), the input field comes empty.
Also if i enter a negative number(lets say -9) and try to use backspace, I can't remove that character. Seems only work around is to define that input as text field.
Please let me know any solution.
Simple-keyboard version
2.15.2
Describe the bug
On a touch device in Edge browser, there is an issue with synchronizing the caret position. The problem is that Edge doesn't seem to allow placing the caret by clicking somewhere within the bounds of the text, but allows the user to drag the caret cursor. This 'dragging' doesn't fire touchend event, so the input's cursor and virtual keyboard caret go out of sync (the caretEventHandler is not executed). Does anyone know if this dragging behaviour in Edge (on touch device) can be prevented or changed to allow positioning within the text with a simple touch or if there is some Edge specific event for dragging the cursor and calliing caretEventHandler in it ?
Hi, I very love your library. It's easy to use and simple. Once I tried it, I fund I couldn't hide the keyboard. I would like to open the keyboard when people are clicking on the text box and when they finish typing, they just click on the outside and dismiss the keyboard
Using simple-keyboard v2.6.8. Testing in Chrome 70.0.3538.77 (Official Build) (64-bit) on macOS 10.12.6.
When selecting a text input, it gets a CSS :focus
selector. When interacting with the keyboard to enter text into the input field, the keyboard steals focus and the :focus
selector and cursor both disappear.
Simple-keyboard version
1.14 and 1.13 versions of react-simple-keyboard are affected
Describe the bug
function camelCase
(https://github.com/hodgef/simple-keyboard/blob/master/src/lib/services/Utilities.js#L362) from utils will fail on a class name with two dashes, e.g. 'my--weird--class`
Hi. Can we use theme to style individual buttons? I've been unable to do so or to target the buttons themselves, and I'd love to make those buttons taller, adjust padding, etc. Thanks!
Hi,
the simple keyboard works very good, but unfortunately now all tests of components that use it fail like this:
WARN: '".simple-keyboard" was not found in the DOM.'
HeadlessChrome 72.0.3626 (Mac OS X 10.14.3) RegistrationComponent should create FAILED
Error: KEYBOARD_DOM_ERROR
Is there a good solution to this?
Simple-keyboard version
"version": "2.21.1",
Describe the bug
Getting type-error in a typescript environment:
ERROR in .../node_modules/simple-keyboard/build/index.d.ts
4:5 Property 'shift' of type 'string[] | undefined' is not assignable to string index type 'string[]'.
2 | interface KeyboardLayoutObject {
3 | default: string[];
> 4 | shift?: string[];
| ^
5 | [key: string]: string[];
6 | }
7 |
making shift not optional removes the error - but I don't know if this is the best or even correct way to go.
Just wondering if this the correct way to make custom buttons since it wasn't documented.
const keyboardLayout = {
default: [
'1 2 3 4 5 6 7 8 9 0 - = {bksp}',
'Q W E R T Y U I O P [ ] \\',
"A S D F G H J K L ; ' {enter}",
'Z X C V B N M , . /',
'{space} {close}',
],
};
const keyboardDisplay = {
'{close}': '↓',
}
It would be nice to add keyup
even listeners for development so we can quickly type stuff without having to press it.
If you have a readOnly input field and you have keyup
even listener on the page you still may want to have the field change by injecting the e.key onto the component. right now all logic is handled internally and the onChange event changes the input field. Would be nice to add a e.key in a prop
Is your feature request related to a problem? Please describe.
Clicking a button makes the browser focusing the button - the focus on the input field gets lost
Describe the solution you'd like
It would be nice to add an option to keep the focus on the input field. This can be achieved by using the mouse down event in combination with preventDefault()
.
Additional context
Pretty similar to the issue addressed in #14. I could help with the implementation if you would consider this as a good new feature :)
Here is an example:
https://jsfiddle.net/m4a67w1u/
Renders full keyboard demo unusable. Will release fix asap.
This is probably more an issue of your demo and the documentation than of the library: if you quickly type on an iPad there is a high chance you will trigger a double tap zoom, which is built into mobile safari. So on the page, zooming should probably be disabled for the keyboard to be useful on an iPad.
But great library!
Simple-keyboard version
Running 2.20.3
I have noticed that when using Angular form validation that even though the input does show (visually), the form.controls value and Angular validation (like ng-invalid if a field is set to required) do not update.
If you type into an input with the virtual keyboard and inspect the element the ng-reflect-model doesnt update.
This can be replicated within the simple-keyboard Angular demo in codesandbox.io. Importing FormModule in app.module.ts and NgForm in your component and creating a basic template driven form.
Any idea on a workaround for this? Forcing the form.controls to get the value doesn't work because the value still appears to be empty.
Thanks.
Would be nice if non-minified files (simple-keyboard.js, simple-keyboard.css) were available as well as the minified versions provided in /build
Use-case: people who have their own project build steps that bundle / minify code don't necessarily want to use the already minified files; and having non-minified files are much easier to develop with / debug etc..
(Note: I tried un-minifying from index.js and index.js.map, but ended up essentially back to the development source code / modules. Would be great if the simple-keyboard.js had all the required JS in a single file, but just not minified...)
What I did was execute "npm install simple-keyboard --save"
and after I ran my app I received this erro:
ERROR Failed to compile with 35 errors 3:49:41 PM
These dependencies were not found:
- child_process in ./node_modules/protractor/built/runner.js, ./node_modules/protractor/built/debugger.js and 4 others
- fs in ./node_modules/blocking-proxy/built/lib/webdriver_logger.js, ./node_modules/fs.realpath/index.js and 21 others
- net in ./node_modules/https-proxy-agent/index.js, ./node_modules/protractor/built/debugger.js and 1 other
- repl in ./node_modules/protractor/built/debugger.js
- tls in ./node_modules/https-proxy-agent/index.js
To install them, you can run: npm install --save child_process fs net repl tls
This relative module was not found:
- ./lib-cov/SauceLabs in ./node_modules/saucelabs/index.js
I'd like to use this keyboard when mouse is not available (e.g. keyboard, controller, remote control only). Im currently trying to combine this library with this spatial navigation library. That works great, except onClick the key loses its focus.
I've read the source, and it doesn't look like you're rerendering the DOM every press, so do you have any idea what could be causing this?
I'm using this library with react-simple-keyboard by the way, but since that React Component is only some small wrapper for this library, I'm asking here :)
My current options are
useButtonTag={true}
preventMouseDownDefault={true}
Hi all-
I'm using the on-screen keyboard for a project I've been working on that will be displayed on a touch screen monitor in the cafeteria at my company for employees to enter in their e-mail address and send themselves an email with some info about various topics. I built this web app using Ionic 4 and am running into an issue while building a production version of the application.
The error I'm seeing is as follows:
Error: ./node_modules/simple-keyboard/build/css/index.css Module parse failed: Unexpected token (12:10) You may need an appropriate loader to handle this file type.
I've done some messing around myself and can't seem to figure out the issue. Has anyone seen this issue thus far?
Thanks all,
-Mike
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.