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