reactjs-virtual-keyboard 1.0.2 â 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +295 -191
- package/dist/index.d.ts +108 -27
- package/dist/index.esm.js +695 -485
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1 -7
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
# reactjs-virtual-keyboard
|
|
2
2
|
|
|
3
|
-
A customizable virtual keyboard component for React applications. Features multiple
|
|
3
|
+
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.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
ð **[Documentation & Live Demo](https://kalpesh442266.github.io/virtual-keyboard-lib/)**
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- **Hardware Keyboard Sync**: Virtual keyboard state syncs with physical keyboard (e.g., Caps Lock)
|
|
9
|
-
- **Touch Optimized**: Designed for touch screens with continuous press support (hold backspace to delete)
|
|
10
|
-
- **Customizable Themes**: CSS variables for easy theming, plus built-in theme classes
|
|
11
|
-
- **TypeScript Support**: Full type definitions included
|
|
12
|
-
- **Accessible**: Keyboard navigation and focus management
|
|
13
|
-
- **Lightweight**: No external dependencies except React
|
|
7
|
+
## âĻ Features
|
|
14
8
|
|
|
15
|
-
|
|
9
|
+
- **ðđ Multiple Layouts**: QWERTY letters, symbols, and numeric keypad
|
|
10
|
+
- **ð Multi-Language Support**: Built-in language switcher with custom language layouts
|
|
11
|
+
- **âĻïļ Hardware Keyboard Sync**: Virtual keyboard syncs with physical keyboard (Caps Lock, key presses)
|
|
12
|
+
- **ðą Touch Optimized**: Continuous press support (hold backspace to delete)
|
|
13
|
+
- **ðĻ Highly Customizable**: Custom layouts, key labels, disabled/hidden keys, render functions
|
|
14
|
+
- **ðŠķ Lightweight**: Only ~26 KB minified (~6.3 KB gzipped), no external dependencies
|
|
15
|
+
- **ð TypeScript**: Full type definitions included
|
|
16
|
+
- **âŋ Accessible**: Keyboard navigation and focus management
|
|
17
|
+
|
|
18
|
+
## ðĶ Installation
|
|
16
19
|
|
|
17
20
|
```bash
|
|
18
21
|
npm install reactjs-virtual-keyboard
|
|
@@ -22,11 +25,11 @@ yarn add reactjs-virtual-keyboard
|
|
|
22
25
|
pnpm add reactjs-virtual-keyboard
|
|
23
26
|
```
|
|
24
27
|
|
|
25
|
-
## Quick Start
|
|
28
|
+
## ð Quick Start
|
|
26
29
|
|
|
27
|
-
### Option 1: GlobalVirtualKeyboard (
|
|
30
|
+
### Option 1: GlobalVirtualKeyboard (Recommended)
|
|
28
31
|
|
|
29
|
-
Add once at your app root - automatically shows keyboard
|
|
32
|
+
Add once at your app root - automatically shows keyboard for all inputs:
|
|
30
33
|
|
|
31
34
|
```tsx
|
|
32
35
|
import { GlobalVirtualKeyboard } from 'reactjs-virtual-keyboard';
|
|
@@ -35,11 +38,10 @@ import 'reactjs-virtual-keyboard/styles.css';
|
|
|
35
38
|
function App() {
|
|
36
39
|
return (
|
|
37
40
|
<div>
|
|
38
|
-
<input type="text" placeholder="Click
|
|
39
|
-
<input type="email" placeholder="Email
|
|
40
|
-
<input type="number" placeholder="
|
|
41
|
+
<input type="text" placeholder="Click any input!" />
|
|
42
|
+
<input type="email" placeholder="Email" />
|
|
43
|
+
<input type="number" placeholder="Numbers" />
|
|
41
44
|
|
|
42
|
-
{/* Add once - works for all inputs */}
|
|
43
45
|
<GlobalVirtualKeyboard />
|
|
44
46
|
</div>
|
|
45
47
|
);
|
|
@@ -48,7 +50,7 @@ function App() {
|
|
|
48
50
|
|
|
49
51
|
### Option 2: VirtualKeyboard (Manual Control)
|
|
50
52
|
|
|
51
|
-
For more control over when the keyboard appears:
|
|
53
|
+
For more control over when and where the keyboard appears:
|
|
52
54
|
|
|
53
55
|
```tsx
|
|
54
56
|
import { useRef, useState } from 'react';
|
|
@@ -58,27 +60,20 @@ import 'reactjs-virtual-keyboard/styles.css';
|
|
|
58
60
|
function App() {
|
|
59
61
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
60
62
|
const [isInputFocused, setIsInputFocused] = useState(false);
|
|
61
|
-
const [value, setValue] = useState('');
|
|
62
63
|
|
|
63
64
|
return (
|
|
64
65
|
<div>
|
|
65
66
|
<input
|
|
66
67
|
ref={inputRef}
|
|
67
68
|
type="text"
|
|
68
|
-
value={value}
|
|
69
|
-
onChange={(e) => setValue(e.target.value)}
|
|
70
69
|
onFocus={() => setIsInputFocused(true)}
|
|
71
70
|
onBlur={() => setIsInputFocused(false)}
|
|
72
|
-
placeholder="Click to show keyboard"
|
|
73
71
|
/>
|
|
74
72
|
|
|
75
73
|
{isInputFocused && (
|
|
76
74
|
<VirtualKeyboard
|
|
77
75
|
focusedInputRef={inputRef}
|
|
78
76
|
isInputFocused={isInputFocused}
|
|
79
|
-
inputType="text"
|
|
80
|
-
onEnterClick={() => console.log('Enter pressed!')}
|
|
81
|
-
onChange={(newValue) => setValue(newValue)}
|
|
82
77
|
/>
|
|
83
78
|
)}
|
|
84
79
|
</div>
|
|
@@ -86,242 +81,351 @@ function App() {
|
|
|
86
81
|
}
|
|
87
82
|
```
|
|
88
83
|
|
|
89
|
-
##
|
|
84
|
+
## ð API Reference
|
|
85
|
+
|
|
86
|
+
### `<GlobalVirtualKeyboard />`
|
|
90
87
|
|
|
91
|
-
|
|
88
|
+
Automatically manages keyboard visibility for all inputs on the page.
|
|
92
89
|
|
|
93
|
-
|
|
90
|
+
```tsx
|
|
91
|
+
interface GlobalVirtualKeyboardProps {
|
|
92
|
+
enabled?: boolean; // Enable/disable keyboard (default: true)
|
|
93
|
+
className?: string; // Custom CSS class
|
|
94
|
+
onVisibilityChange?: (visible: boolean) => void; // Visibility change callback
|
|
95
|
+
onEnterClick?: () => void; // Enter key callback
|
|
96
|
+
onChange?: (value: string) => void; // Value change callback
|
|
97
|
+
}
|
|
98
|
+
```
|
|
94
99
|
|
|
100
|
+
**Example:**
|
|
95
101
|
```tsx
|
|
96
102
|
<GlobalVirtualKeyboard
|
|
97
|
-
enabled={true}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
onEnterClick={() => {}} // Called when Enter is pressed
|
|
101
|
-
onChange={(value) => {}} // Called when value changes
|
|
103
|
+
enabled={true}
|
|
104
|
+
onEnterClick={() => console.log('Enter pressed!')}
|
|
105
|
+
onChange={(value) => console.log('Value:', value)}
|
|
102
106
|
/>
|
|
103
107
|
```
|
|
104
108
|
|
|
105
|
-
|
|
106
|
-
|------|------|---------|-------------|
|
|
107
|
-
| `enabled` | `boolean` | `true` | Enable/disable the keyboard |
|
|
108
|
-
| `className` | `string` | - | Additional CSS class name |
|
|
109
|
-
| `onVisibilityChange` | `(isVisible: boolean) => void` | - | Callback when visibility changes |
|
|
110
|
-
| `onEnterClick` | `() => void` | - | Callback when Enter key is pressed |
|
|
111
|
-
| `onChange` | `(value: string) => void` | - | Callback when value changes |
|
|
112
|
-
|
|
113
|
-
### VirtualKeyboard
|
|
114
|
-
|
|
115
|
-
Manual control over keyboard display. Use when you need precise control.
|
|
116
|
-
|
|
117
|
-
| Prop | Type | Default | Description |
|
|
118
|
-
|------|------|---------|-------------|
|
|
119
|
-
| `focusedInputRef` | `RefObject<HTMLInputElement \| HTMLTextAreaElement>` | **required** | Ref to the currently focused input element |
|
|
120
|
-
| `isInputFocused` | `boolean` | **required** | Whether an input is currently focused |
|
|
121
|
-
| `inputType` | `HTMLInputTypeAttribute` | `'text'` | Type of input (affects layout and validation) |
|
|
122
|
-
| `onEnterClick` | `() => void` | - | Callback when Enter key is pressed |
|
|
123
|
-
| `onChange` | `(value: string) => void` | - | Callback when value changes |
|
|
124
|
-
| `className` | `string` | - | Additional CSS class name |
|
|
125
|
-
| `defaultLayout` | `'letters' \| 'symbols' \| 'numbers'` | `'letters'` | Default keyboard layout |
|
|
126
|
-
| `validate` | `(value: string) => boolean` | - | Custom validation function |
|
|
127
|
-
|
|
128
|
-
## Input Type Behaviors
|
|
109
|
+
---
|
|
129
110
|
|
|
130
|
-
|
|
111
|
+
### `<VirtualKeyboard />`
|
|
131
112
|
|
|
132
|
-
|
|
133
|
-
- **`email`**: Shows QWERTY layout with quick access `.` and `@` keys
|
|
134
|
-
- **`number`**: Shows numeric keypad, only allows digits
|
|
135
|
-
- **`tel`**: Shows QWERTY layout, validates phone characters
|
|
136
|
-
- **`password`**: Shows QWERTY layout, allows all characters
|
|
137
|
-
- **`url`**: Shows QWERTY layout, validates URL characters
|
|
113
|
+
Main keyboard component with extensive customization options.
|
|
138
114
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
115
|
+
```tsx
|
|
116
|
+
interface VirtualKeyboardProps {
|
|
117
|
+
// Required props
|
|
118
|
+
focusedInputRef: RefObject<HTMLInputElement | HTMLTextAreaElement | null>;
|
|
119
|
+
isInputFocused: boolean;
|
|
120
|
+
|
|
121
|
+
// Layout & behavior
|
|
122
|
+
inputType?: 'text' | 'email' | 'number' | etc; // HTML input type
|
|
123
|
+
defaultLayout?: 'letters' | 'symbols' | 'numbers';
|
|
124
|
+
syncWithHardwareKeyboard?: boolean; // Enable hardware sync (default: true)
|
|
125
|
+
|
|
126
|
+
// Callbacks
|
|
127
|
+
onEnterClick?: () => void;
|
|
128
|
+
onChange?: (value: string) => void;
|
|
129
|
+
validate?: (value: string) => boolean; // Custom validation
|
|
130
|
+
|
|
131
|
+
// Customization
|
|
132
|
+
className?: string;
|
|
133
|
+
theme?: VirtualKeyboardTheme;
|
|
134
|
+
customLayouts?: {
|
|
135
|
+
letters?: string[][];
|
|
136
|
+
symbols?: string[][];
|
|
137
|
+
numbers?: string[][];
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// Key customization
|
|
141
|
+
keyLabels?: Record<string, string>; // Custom key labels
|
|
142
|
+
hiddenKeys?: string[]; // Keys to hide
|
|
143
|
+
disabledKeys?: string[]; // Keys to disable
|
|
144
|
+
renderKey?: (key: string, defaultRender: ReactNode) => ReactNode;
|
|
145
|
+
renderSpecialKey?: (type: string, defaultRender: ReactNode) => ReactNode;
|
|
146
|
+
|
|
147
|
+
// Behavior configuration
|
|
148
|
+
continuousPressConfig?: {
|
|
149
|
+
initialDelay?: number; // Default: 500ms
|
|
150
|
+
interval?: number; // Default: 50ms
|
|
151
|
+
};
|
|
152
|
+
scrollConfig?: {
|
|
153
|
+
enabled?: boolean;
|
|
154
|
+
offset?: number;
|
|
155
|
+
};
|
|
157
156
|
}
|
|
158
157
|
```
|
|
159
158
|
|
|
160
|
-
|
|
161
|
-
|
|
159
|
+
**Example with customization:**
|
|
162
160
|
```tsx
|
|
163
161
|
<VirtualKeyboard
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
//
|
|
168
|
-
|
|
169
|
-
|
|
162
|
+
focusedInputRef={inputRef}
|
|
163
|
+
isInputFocused={isInputFocused}
|
|
164
|
+
|
|
165
|
+
// Custom key labels
|
|
166
|
+
keyLabels={{
|
|
167
|
+
enter: 'Submit',
|
|
168
|
+
space: 'Space Bar',
|
|
169
|
+
backspace: 'Del'
|
|
170
|
+
}}
|
|
171
|
+
|
|
172
|
+
// Hide specific keys
|
|
173
|
+
hiddenKeys={['capslock']}
|
|
174
|
+
|
|
175
|
+
// Disable certain keys
|
|
176
|
+
disabledKeys={['@', '#']}
|
|
177
|
+
|
|
178
|
+
// Custom layout
|
|
179
|
+
customLayouts={{
|
|
180
|
+
letters: [
|
|
181
|
+
['q', 'w', 'e', 'r', 't', 'y'],
|
|
182
|
+
['a', 's', 'd', 'f', 'g', 'h'],
|
|
183
|
+
['z', 'x', 'c', 'v', 'b', 'n']
|
|
184
|
+
]
|
|
185
|
+
}}
|
|
186
|
+
|
|
187
|
+
// Adjust continuous press behavior
|
|
188
|
+
continuousPressConfig={{
|
|
189
|
+
initialDelay: 300,
|
|
190
|
+
interval: 40
|
|
191
|
+
}}
|
|
192
|
+
|
|
193
|
+
// Disable hardware keyboard sync
|
|
194
|
+
syncWithHardwareKeyboard={false}
|
|
170
195
|
/>
|
|
171
196
|
```
|
|
172
197
|
|
|
173
|
-
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## ðĻ Theming
|
|
201
|
+
|
|
202
|
+
### Using CSS Variables
|
|
174
203
|
|
|
175
204
|
```css
|
|
176
|
-
.
|
|
177
|
-
--vk-bg-color: #
|
|
178
|
-
--vk-key-color: #
|
|
179
|
-
--vk-key-text-color: #
|
|
180
|
-
--vk-key-
|
|
181
|
-
--vk-key-
|
|
182
|
-
--vk-active-state-color: #
|
|
205
|
+
.vk-container {
|
|
206
|
+
--vk-bg-color: #2c3e50;
|
|
207
|
+
--vk-key-color: #34495e;
|
|
208
|
+
--vk-key-text-color: #ecf0f1;
|
|
209
|
+
--vk-key-active-color: #3498db;
|
|
210
|
+
--vk-key-hover-color: #2c3e50;
|
|
211
|
+
--vk-active-state-color: #e74c3c;
|
|
212
|
+
--vk-key-border-radius: 8px;
|
|
213
|
+
--vk-key-font-size: 18px;
|
|
214
|
+
--vk-key-height: 50px;
|
|
183
215
|
}
|
|
184
216
|
```
|
|
185
217
|
|
|
186
|
-
|
|
218
|
+
### Theme Object
|
|
187
219
|
|
|
188
|
-
|
|
220
|
+
```tsx
|
|
221
|
+
const darkTheme = {
|
|
222
|
+
backgroundColor: '#1a1a1a',
|
|
223
|
+
keyColor: '#2d2d2d',
|
|
224
|
+
keyTextColor: '#ffffff',
|
|
225
|
+
keyActiveColor: '#0066cc',
|
|
226
|
+
keyHoverColor: '#3d3d3d',
|
|
227
|
+
activeStateColor: '#00cc66',
|
|
228
|
+
keyBorderRadius: '6px',
|
|
229
|
+
keyFontSize: '16px',
|
|
230
|
+
keyHeight: '48px'
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
<VirtualKeyboard theme={darkTheme} {...props} />
|
|
234
|
+
```
|
|
189
235
|
|
|
190
|
-
|
|
236
|
+
---
|
|
191
237
|
|
|
192
|
-
|
|
193
|
-
import { useCaretManager } from 'reactjs-virtual-keyboard';
|
|
238
|
+
## ð§ Utility Functions & Hooks
|
|
194
239
|
|
|
195
|
-
|
|
196
|
-
const inputRef = useRef<HTMLInputElement>(null);
|
|
197
|
-
const { insertText, backspace } = useCaretManager(inputRef);
|
|
240
|
+
For advanced use cases, you can import utilities directly:
|
|
198
241
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
242
|
+
```tsx
|
|
243
|
+
import {
|
|
244
|
+
// Caret management
|
|
245
|
+
createCaretManager,
|
|
246
|
+
|
|
247
|
+
// Hardware keyboard event handling
|
|
248
|
+
setupHardwareKeyboard,
|
|
249
|
+
|
|
250
|
+
// Validation utilities
|
|
251
|
+
validateValueUtil,
|
|
252
|
+
getInitialLayout,
|
|
253
|
+
|
|
254
|
+
// Scroll utilities
|
|
255
|
+
scrollInputIntoView,
|
|
256
|
+
resetScrollPosition,
|
|
257
|
+
|
|
258
|
+
// Input value sync
|
|
259
|
+
setInputValueAndDispatchEvents,
|
|
260
|
+
|
|
261
|
+
// Hooks (only for React state/effects)
|
|
262
|
+
useContinuousPress,
|
|
263
|
+
useKeyboardScroll
|
|
264
|
+
} from 'reactjs-virtual-keyboard';
|
|
204
265
|
```
|
|
205
266
|
|
|
206
|
-
###
|
|
267
|
+
### `createCaretManager`
|
|
207
268
|
|
|
208
|
-
|
|
269
|
+
Pure function for managing caret position and text manipulation:
|
|
209
270
|
|
|
210
271
|
```tsx
|
|
211
|
-
import {
|
|
272
|
+
import { createCaretManager } from 'reactjs-virtual-keyboard';
|
|
212
273
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
initialDelay: 500, // Start repeating after 500ms
|
|
216
|
-
interval: 50, // Repeat every 50ms
|
|
217
|
-
});
|
|
274
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
275
|
+
const { insertText, backspace } = createCaretManager(() => inputRef.current);
|
|
218
276
|
|
|
219
|
-
|
|
220
|
-
|
|
277
|
+
// Insert text at caret position
|
|
278
|
+
insertText('Hello');
|
|
279
|
+
|
|
280
|
+
// Delete character before caret
|
|
281
|
+
backspace();
|
|
221
282
|
```
|
|
222
283
|
|
|
223
|
-
###
|
|
284
|
+
### `setupHardwareKeyboard`
|
|
224
285
|
|
|
225
|
-
|
|
286
|
+
Set up hardware keyboard event listeners:
|
|
226
287
|
|
|
227
288
|
```tsx
|
|
228
|
-
import {
|
|
289
|
+
import { setupHardwareKeyboard } from 'reactjs-virtual-keyboard';
|
|
229
290
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
isInputFocused: true,
|
|
291
|
+
useEffect(() => {
|
|
292
|
+
const cleanup = setupHardwareKeyboard({
|
|
233
293
|
onBackspace: () => console.log('Backspace'),
|
|
234
294
|
onEnter: () => console.log('Enter'),
|
|
235
295
|
onSpace: () => console.log('Space'),
|
|
236
|
-
onCapsToggle: () => console.log('Caps
|
|
237
|
-
onKeyClick: (key) => console.log('Key:', key)
|
|
296
|
+
onCapsToggle: () => console.log('Caps'),
|
|
297
|
+
onKeyClick: (key) => console.log('Key:', key)
|
|
238
298
|
});
|
|
239
|
-
|
|
299
|
+
|
|
300
|
+
return cleanup; // Clean up listeners
|
|
301
|
+
}, []);
|
|
240
302
|
```
|
|
241
303
|
|
|
242
|
-
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## ðą Input Type Behaviors
|
|
307
|
+
|
|
308
|
+
The keyboard automatically adapts to different input types:
|
|
309
|
+
|
|
310
|
+
| Input Type | Layout | Special Keys | Validation |
|
|
311
|
+
|-----------|--------|--------------|------------|
|
|
312
|
+
| `text` | QWERTY | All | None |
|
|
313
|
+
| `email` | QWERTY + @ | Space, @ | Email chars only |
|
|
314
|
+
| `number` | Numbers only | Backspace, Enter | Digits only |
|
|
315
|
+
| `tel` | Numbers | Phone chars | Digits, +, - |
|
|
316
|
+
| `url` | QWERTY | .com, www. | URL chars |
|
|
243
317
|
|
|
244
|
-
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## ðŊ Custom Layouts Example
|
|
245
321
|
|
|
246
322
|
```tsx
|
|
247
|
-
|
|
323
|
+
const customLayouts = {
|
|
324
|
+
letters: [
|
|
325
|
+
['a', 'b', 'c', 'd', 'e'],
|
|
326
|
+
['f', 'g', 'h', 'i', 'j'],
|
|
327
|
+
['k', 'l', 'm', 'n', 'o'],
|
|
328
|
+
['p', 'q', 'r', 's', 't'],
|
|
329
|
+
['u', 'v', 'w', 'x', 'y', 'z']
|
|
330
|
+
],
|
|
331
|
+
symbols: [
|
|
332
|
+
['!', '@', '#', '$', '%'],
|
|
333
|
+
['^', '&', '*', '(', ')'],
|
|
334
|
+
['-', '_', '=', '+', '['],
|
|
335
|
+
[']', '{', '}', '|', '\\']
|
|
336
|
+
]
|
|
337
|
+
};
|
|
248
338
|
|
|
249
|
-
|
|
250
|
-
|
|
339
|
+
<VirtualKeyboard
|
|
340
|
+
{...props}
|
|
341
|
+
customLayouts={customLayouts}
|
|
342
|
+
/>
|
|
343
|
+
```
|
|
251
344
|
|
|
252
|
-
|
|
253
|
-
const input = e.target as HTMLInputElement;
|
|
254
|
-
scrollInput(input); // Shifts content up if input would be covered
|
|
255
|
-
};
|
|
345
|
+
---
|
|
256
346
|
|
|
257
|
-
|
|
258
|
-
resetScroll(); // Restores original position
|
|
259
|
-
};
|
|
347
|
+
## ð Custom Render Functions
|
|
260
348
|
|
|
261
|
-
|
|
262
|
-
|
|
349
|
+
```tsx
|
|
350
|
+
<VirtualKeyboard
|
|
351
|
+
{...props}
|
|
352
|
+
renderKey={(key, defaultRender) => (
|
|
353
|
+
<div className="my-custom-key">
|
|
354
|
+
{key.toUpperCase()}
|
|
355
|
+
</div>
|
|
356
|
+
)}
|
|
357
|
+
renderSpecialKey={(type, defaultRender) => {
|
|
358
|
+
if (type === 'enter') {
|
|
359
|
+
return <button className="submit-btn">Submit</button>;
|
|
360
|
+
}
|
|
361
|
+
return defaultRender;
|
|
362
|
+
}}
|
|
363
|
+
/>
|
|
263
364
|
```
|
|
264
365
|
|
|
265
|
-
|
|
266
|
-
- Calculates if the input would be covered by the keyboard
|
|
267
|
-
- Smoothly transitions content up to keep input visible
|
|
268
|
-
- Resets position when keyboard hides
|
|
269
|
-
- Cleans up on component unmount
|
|
366
|
+
---
|
|
270
367
|
|
|
271
|
-
##
|
|
368
|
+
## ðĶ Bundle Size
|
|
272
369
|
|
|
273
|
-
|
|
370
|
+
- **ESM**: 26.14 kB minified (6.28 kB gzipped)
|
|
371
|
+
- **CJS**: 12.56 kB minified (4.69 kB gzipped)
|
|
372
|
+
- **CSS**: 6.03 kB (1.68 kB gzipped)
|
|
274
373
|
|
|
275
|
-
|
|
276
|
-
import {
|
|
277
|
-
KeyboardLayout,
|
|
278
|
-
TextLayout,
|
|
279
|
-
NumbersLayout,
|
|
280
|
-
QWERTY_LAYOUT,
|
|
281
|
-
SYMBOLS_LAYOUT,
|
|
282
|
-
NUMBERS_LAYOUT,
|
|
283
|
-
} from 'reactjs-virtual-keyboard';
|
|
374
|
+
Tree-shaking enabled - import only what you need!
|
|
284
375
|
|
|
285
|
-
|
|
286
|
-
const CUSTOM_LAYOUT = [
|
|
287
|
-
['A', 'B', 'C'],
|
|
288
|
-
['D', 'E', 'F'],
|
|
289
|
-
['G', 'H', 'I'],
|
|
290
|
-
];
|
|
291
|
-
```
|
|
376
|
+
---
|
|
292
377
|
|
|
293
|
-
##
|
|
378
|
+
## ð Browser Support
|
|
294
379
|
|
|
295
|
-
|
|
380
|
+
- **Modern Browsers**: Chrome, Firefox, Safari, Edge (last 2 versions)
|
|
381
|
+
- **Mobile**: iOS Safari, Chrome Mobile, Samsung Internet
|
|
382
|
+
- Requires React 16.8+ (hooks support)
|
|
296
383
|
|
|
297
|
-
|
|
298
|
-
- `aria-label` attributes on special keys
|
|
299
|
-
- Keyboard navigation support
|
|
300
|
-
- Respects `prefers-reduced-motion` for animations
|
|
384
|
+
---
|
|
301
385
|
|
|
302
|
-
##
|
|
386
|
+
## ð ïļ Development
|
|
303
387
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
- Edge 79+
|
|
388
|
+
```bash
|
|
389
|
+
# Clone repository
|
|
390
|
+
git clone https://github.com/yourusername/reactjs-virtual-keyboard.git
|
|
308
391
|
|
|
309
|
-
|
|
392
|
+
# Install dependencies
|
|
393
|
+
npm install
|
|
310
394
|
|
|
311
|
-
|
|
395
|
+
# Build library
|
|
396
|
+
npm run build
|
|
312
397
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
VirtualKeyboardProps,
|
|
316
|
-
VirtualKeyboardTheme,
|
|
317
|
-
GlobalVirtualKeyboardProps,
|
|
318
|
-
UseKeyboardScrollReturn,
|
|
319
|
-
LayoutType,
|
|
320
|
-
KeyboardLayoutProps,
|
|
321
|
-
} from 'reactjs-virtual-keyboard';
|
|
398
|
+
# Run demo (if available)
|
|
399
|
+
cd demo && npm install && npm run dev
|
|
322
400
|
```
|
|
323
401
|
|
|
324
|
-
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## ð License
|
|
405
|
+
|
|
406
|
+
MIT ÂĐ Kalpesh Rane
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
## ðĪ Contributing
|
|
411
|
+
|
|
412
|
+
Contributions welcome! Please open an issue or submit a PR.
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## ð Changelog
|
|
417
|
+
|
|
418
|
+
### v2.0.0 (Latest)
|
|
419
|
+
- âĻ **New**: Multi-language support with built-in language switcher
|
|
420
|
+
- âĻ Added `languages`, `currentLanguage`, `onLanguageChange`, `showLanguageSwitcher` props
|
|
421
|
+
- âĻ Enhanced customization API (24+ new props)
|
|
422
|
+
- ⥠Removed unnecessary hook wrappers for better performance
|
|
423
|
+
- ðĶ Optimized bundle size with better tree-shaking
|
|
424
|
+
- ðïļ Reorganized file structure for clarity
|
|
425
|
+
- ð§ Exported utility functions for advanced usage
|
|
426
|
+
- ð Improved TypeScript types with ReadonlyArray support
|
|
427
|
+
- ð Complete documentation website with interactive playground
|
|
325
428
|
|
|
326
|
-
|
|
429
|
+
### v1.0.0
|
|
430
|
+
- ð Initial release
|
|
327
431
|
|