reactjs-virtual-keyboard
Version:
A customizable virtual keyboard component for React applications with support for multiple layouts, multi-language support, hardware keyboard sync, and touch devices
432 lines (330 loc) ⢠10.7 kB
Markdown
A lightweight, customizable virtual keyboard component for React applications. Features multiple layouts, multi-language support, hardware keyboard sync, extensive customization options, and full TypeScript support.
š **[Documentation & Live Demo](https://kalpesh442266.github.io/virtual-keyboard-lib/)**
- **š¹ Multiple Layouts**: QWERTY letters, symbols, and numeric keypad
- **š Multi-Language Support**: Built-in language switcher with custom language layouts
- **āØļø Hardware Keyboard Sync**: Virtual keyboard syncs with physical keyboard (Caps Lock, key presses)
- **š± Touch Optimized**: Continuous press support (hold backspace to delete)
- **šØ Highly Customizable**: Custom layouts, key labels, disabled/hidden keys, render functions
- **šŖ¶ Lightweight**: Only ~26 KB minified (~6.3 KB gzipped), no external dependencies
- **š TypeScript**: Full type definitions included
- **āæ Accessible**: Keyboard navigation and focus management
## š¦ Installation
```bash
npm install reactjs-virtual-keyboard
# or
yarn add reactjs-virtual-keyboard
# or
pnpm add reactjs-virtual-keyboard
```
## š Quick Start
### Option 1: GlobalVirtualKeyboard (Recommended)
Add once at your app root - automatically shows keyboard for all inputs:
```tsx
import { GlobalVirtualKeyboard } from 'reactjs-virtual-keyboard';
import 'reactjs-virtual-keyboard/styles.css';
function App() {
return (
<div>
<input type="text" placeholder="Click any input!" />
<input type="email" placeholder="Email" />
<input type="number" placeholder="Numbers" />
<GlobalVirtualKeyboard />
</div>
);
}
```
For more control over when and where the keyboard appears:
```tsx
import { useRef, useState } from 'react';
import { VirtualKeyboard } from 'reactjs-virtual-keyboard';
import 'reactjs-virtual-keyboard/styles.css';
function App() {
const inputRef = useRef<HTMLInputElement>(null);
const [isInputFocused, setIsInputFocused] = useState(false);
return (
<div>
<input
ref={inputRef}
type="text"
onFocus={() => setIsInputFocused(true)}
onBlur={() => setIsInputFocused(false)}
/>
{isInputFocused && (
<VirtualKeyboard
focusedInputRef={inputRef}
isInputFocused={isInputFocused}
/>
)}
</div>
);
}
```
Automatically manages keyboard visibility for all inputs on the page.
```tsx
interface GlobalVirtualKeyboardProps {
enabled?: boolean; // Enable/disable keyboard (default: true)
className?: string; // Custom CSS class
onVisibilityChange?: (visible: boolean) => void; // Visibility change callback
onEnterClick?: () => void; // Enter key callback
onChange?: (value: string) => void; // Value change callback
}
```
**Example:**
```tsx
<GlobalVirtualKeyboard
enabled={true}
onEnterClick={() => console.log('Enter pressed!')}
onChange={(value) => console.log('Value:', value)}
/>
```
---
Main keyboard component with extensive customization options.
```tsx
interface VirtualKeyboardProps {
// Required props
focusedInputRef: RefObject<HTMLInputElement | HTMLTextAreaElement | null>;
isInputFocused: boolean;
// Layout & behavior
inputType?: 'text' | 'email' | 'number' | etc; // HTML input type
defaultLayout?: 'letters' | 'symbols' | 'numbers';
syncWithHardwareKeyboard?: boolean; // Enable hardware sync (default: true)
// Callbacks
onEnterClick?: () => void;
onChange?: (value: string) => void;
validate?: (value: string) => boolean; // Custom validation
// Customization
className?: string;
theme?: VirtualKeyboardTheme;
customLayouts?: {
letters?: string[][];
symbols?: string[][];
numbers?: string[][];
};
// Key customization
keyLabels?: Record<string, string>; // Custom key labels
hiddenKeys?: string[]; // Keys to hide
disabledKeys?: string[]; // Keys to disable
renderKey?: (key: string, defaultRender: ReactNode) => ReactNode;
renderSpecialKey?: (type: string, defaultRender: ReactNode) => ReactNode;
// Behavior configuration
continuousPressConfig?: {
initialDelay?: number; // Default: 500ms
interval?: number; // Default: 50ms
};
scrollConfig?: {
enabled?: boolean;
offset?: number;
};
}
```
**Example with customization:**
```tsx
<VirtualKeyboard
focusedInputRef={inputRef}
isInputFocused={isInputFocused}
// Custom key labels
keyLabels={{
enter: 'Submit',
space: 'Space Bar',
backspace: 'Del'
}}
// Hide specific keys
hiddenKeys={['capslock']}
// Disable certain keys
disabledKeys={['@', '#']}
// Custom layout
customLayouts={{
letters: [
['q', 'w', 'e', 'r', 't', 'y'],
['a', 's', 'd', 'f', 'g', 'h'],
['z', 'x', 'c', 'v', 'b', 'n']
]
}}
// Adjust continuous press behavior
continuousPressConfig={{
initialDelay: 300,
interval: 40
}}
// Disable hardware keyboard sync
syncWithHardwareKeyboard={false}
/>
```
---
```css
.vk-container {
--vk-bg-color:
--vk-key-color:
--vk-key-text-color:
--vk-key-active-color:
--vk-key-hover-color:
--vk-active-state-color:
--vk-key-border-radius: 8px;
--vk-key-font-size: 18px;
--vk-key-height: 50px;
}
```
```tsx
const darkTheme = {
backgroundColor: '#1a1a1a',
keyColor: '#2d2d2d',
keyTextColor: '#ffffff',
keyActiveColor: '#0066cc',
keyHoverColor: '#3d3d3d',
activeStateColor: '#00cc66',
keyBorderRadius: '6px',
keyFontSize: '16px',
keyHeight: '48px'
};
<VirtualKeyboard theme={darkTheme} {...props} />
```
---
For advanced use cases, you can import utilities directly:
```tsx
import {
// Caret management
createCaretManager,
// Hardware keyboard event handling
setupHardwareKeyboard,
// Validation utilities
validateValueUtil,
getInitialLayout,
// Scroll utilities
scrollInputIntoView,
resetScrollPosition,
// Input value sync
setInputValueAndDispatchEvents,
// Hooks (only for React state/effects)
useContinuousPress,
useKeyboardScroll
} from 'reactjs-virtual-keyboard';
```
Pure function for managing caret position and text manipulation:
```tsx
import { createCaretManager } from 'reactjs-virtual-keyboard';
const inputRef = useRef<HTMLInputElement>(null);
const { insertText, backspace } = createCaretManager(() => inputRef.current);
// Insert text at caret position
insertText('Hello');
// Delete character before caret
backspace();
```
Set up hardware keyboard event listeners:
```tsx
import { setupHardwareKeyboard } from 'reactjs-virtual-keyboard';
useEffect(() => {
const cleanup = setupHardwareKeyboard({
onBackspace: () => console.log('Backspace'),
onEnter: () => console.log('Enter'),
onSpace: () => console.log('Space'),
onCapsToggle: () => console.log('Caps'),
onKeyClick: (key) => console.log('Key:', key)
});
return cleanup; // Clean up listeners
}, []);
```
---
The keyboard automatically adapts to different input types:
| Input Type | Layout | Special Keys | Validation |
|-----------|--------|--------------|------------|
| `text` | QWERTY | All | None |
| `email` | QWERTY + @ | Space, @ | Email chars only |
| `number` | Numbers only | Backspace, Enter | Digits only |
| `tel` | Numbers | Phone chars | Digits, +, - |
| `url` | QWERTY | .com, www. | URL chars |
---
```tsx
const customLayouts = {
letters: [
['a', 'b', 'c', 'd', 'e'],
['f', 'g', 'h', 'i', 'j'],
['k', 'l', 'm', 'n', 'o'],
['p', 'q', 'r', 's', 't'],
['u', 'v', 'w', 'x', 'y', 'z']
],
symbols: [
['!', '@', '#', '$', '%'],
['^', '&', '*', '(', ')'],
['-', '_', '=', '+', '['],
[']', '{', '}', '|', '\\']
]
};
<VirtualKeyboard
{...props}
customLayouts={customLayouts}
/>
```
---
```tsx
<VirtualKeyboard
{...props}
renderKey={(key, defaultRender) => (
<div className="my-custom-key">
{key.toUpperCase()}
</div>
)}
renderSpecialKey={(type, defaultRender) => {
if (type === 'enter') {
return <button className="submit-btn">Submit</button>;
}
return defaultRender;
}}
/>
```
---
- **ESM**: 26.14 kB minified (6.28 kB gzipped)
- **CJS**: 12.56 kB minified (4.69 kB gzipped)
- **CSS**: 6.03 kB (1.68 kB gzipped)
Tree-shaking enabled - import only what you need!
---
## š Browser Support
- **Modern Browsers**: Chrome, Firefox, Safari, Edge (last 2 versions)
- **Mobile**: iOS Safari, Chrome Mobile, Samsung Internet
- Requires React 16.8+ (hooks support)
---
## š ļø Development
```bash
# Clone repository
git clone https://github.com/yourusername/reactjs-virtual-keyboard.git
# Install dependencies
npm install
# Build library
npm run build
# Run demo (if available)
cd demo && npm install && npm run dev
```
---
## š License
MIT Ā© Kalpesh Rane
---
## š¤ Contributing
Contributions welcome! Please open an issue or submit a PR.
---
## š Changelog
### v2.0.0 (Latest)
- ⨠**New**: Multi-language support with built-in language switcher
- ⨠Added `languages`, `currentLanguage`, `onLanguageChange`, `showLanguageSwitcher` props
- ⨠Enhanced customization API (24+ new props)
- ā” Removed unnecessary hook wrappers for better performance
- š¦ Optimized bundle size with better tree-shaking
- šļø Reorganized file structure for clarity
- š§ Exported utility functions for advanced usage
- š Improved TypeScript types with ReadonlyArray support
- š Complete documentation website with interactive playground
### v1.0.0
- š Initial release