reactjs-virtual-keyboard 1.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/LICENSE +22 -0
- package/README.md +327 -0
- package/dist/index.d.ts +346 -0
- package/dist/index.esm.js +678 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +1 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 HydraFacial
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
# reactjs-virtual-keyboard
|
|
2
|
+
|
|
3
|
+
A customizable virtual keyboard component for React applications. Features multiple keyboard layouts (QWERTY, symbols, numbers), hardware keyboard synchronization, touch device support, and full TypeScript support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Multiple Layouts**: QWERTY letters, symbols, and numeric keypad layouts
|
|
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
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install reactjs-virtual-keyboard
|
|
19
|
+
# or
|
|
20
|
+
yarn add reactjs-virtual-keyboard
|
|
21
|
+
# or
|
|
22
|
+
pnpm add reactjs-virtual-keyboard
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
### Option 1: GlobalVirtualKeyboard (Easiest)
|
|
28
|
+
|
|
29
|
+
Add once at your app root - automatically shows keyboard when any input is focused:
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
import { GlobalVirtualKeyboard } from 'reactjs-virtual-keyboard';
|
|
33
|
+
import 'reactjs-virtual-keyboard/styles.css';
|
|
34
|
+
|
|
35
|
+
function App() {
|
|
36
|
+
return (
|
|
37
|
+
<div>
|
|
38
|
+
<input type="text" placeholder="Click me!" />
|
|
39
|
+
<input type="email" placeholder="Email input" />
|
|
40
|
+
<input type="number" placeholder="Number input" />
|
|
41
|
+
|
|
42
|
+
{/* Add once - works for all inputs */}
|
|
43
|
+
<GlobalVirtualKeyboard />
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Option 2: VirtualKeyboard (Manual Control)
|
|
50
|
+
|
|
51
|
+
For more control over when the keyboard appears:
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { useRef, useState } from 'react';
|
|
55
|
+
import { VirtualKeyboard } from 'reactjs-virtual-keyboard';
|
|
56
|
+
import 'reactjs-virtual-keyboard/styles.css';
|
|
57
|
+
|
|
58
|
+
function App() {
|
|
59
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
60
|
+
const [isInputFocused, setIsInputFocused] = useState(false);
|
|
61
|
+
const [value, setValue] = useState('');
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<div>
|
|
65
|
+
<input
|
|
66
|
+
ref={inputRef}
|
|
67
|
+
type="text"
|
|
68
|
+
value={value}
|
|
69
|
+
onChange={(e) => setValue(e.target.value)}
|
|
70
|
+
onFocus={() => setIsInputFocused(true)}
|
|
71
|
+
onBlur={() => setIsInputFocused(false)}
|
|
72
|
+
placeholder="Click to show keyboard"
|
|
73
|
+
/>
|
|
74
|
+
|
|
75
|
+
{isInputFocused && (
|
|
76
|
+
<VirtualKeyboard
|
|
77
|
+
focusedInputRef={inputRef}
|
|
78
|
+
isInputFocused={isInputFocused}
|
|
79
|
+
inputType="text"
|
|
80
|
+
onEnterClick={() => console.log('Enter pressed!')}
|
|
81
|
+
onChange={(newValue) => setValue(newValue)}
|
|
82
|
+
/>
|
|
83
|
+
)}
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Components
|
|
90
|
+
|
|
91
|
+
### GlobalVirtualKeyboard
|
|
92
|
+
|
|
93
|
+
Automatically shows keyboard when any text input is focused. Best for most use cases.
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
<GlobalVirtualKeyboard
|
|
97
|
+
enabled={true} // Enable/disable the keyboard
|
|
98
|
+
className="my-theme" // Custom CSS class
|
|
99
|
+
onVisibilityChange={(visible) => {}} // Called when keyboard shows/hides
|
|
100
|
+
onEnterClick={() => {}} // Called when Enter is pressed
|
|
101
|
+
onChange={(value) => {}} // Called when value changes
|
|
102
|
+
/>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
| Prop | Type | Default | Description |
|
|
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`:
|
|
131
|
+
|
|
132
|
+
- **`text`**: Shows QWERTY layout, allows all characters
|
|
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
|
|
138
|
+
|
|
139
|
+
## Theming
|
|
140
|
+
|
|
141
|
+
### Using CSS Variables
|
|
142
|
+
|
|
143
|
+
```css
|
|
144
|
+
:root {
|
|
145
|
+
--vk-bg-color: #1a1a1a;
|
|
146
|
+
--vk-key-color: #444444;
|
|
147
|
+
--vk-key-text-color: #ffffff;
|
|
148
|
+
--vk-key-active-color: #666666;
|
|
149
|
+
--vk-key-hover-color: #555555;
|
|
150
|
+
--vk-active-state-color: #4a90e2;
|
|
151
|
+
--vk-key-border-radius: 0.5vw;
|
|
152
|
+
--vk-key-font-size: 32px;
|
|
153
|
+
--vk-gap: 0.75vw;
|
|
154
|
+
--vk-padding: 1vw;
|
|
155
|
+
--vk-height: 35vh;
|
|
156
|
+
--vk-z-index: 2001;
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Built-in Theme Classes
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
<VirtualKeyboard
|
|
164
|
+
className="vk-container--light" // Light theme
|
|
165
|
+
// or
|
|
166
|
+
className="vk-container--blue" // Blue theme
|
|
167
|
+
// or
|
|
168
|
+
className="vk-container--purple" // Purple theme
|
|
169
|
+
{...props}
|
|
170
|
+
/>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Custom Theme Example
|
|
174
|
+
|
|
175
|
+
```css
|
|
176
|
+
.my-custom-theme {
|
|
177
|
+
--vk-bg-color: #2d3748;
|
|
178
|
+
--vk-key-color: #4a5568;
|
|
179
|
+
--vk-key-text-color: #e2e8f0;
|
|
180
|
+
--vk-key-hover-color: #718096;
|
|
181
|
+
--vk-key-active-color: #a0aec0;
|
|
182
|
+
--vk-active-state-color: #48bb78;
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Hooks
|
|
187
|
+
|
|
188
|
+
### useCaretManager
|
|
189
|
+
|
|
190
|
+
Manages caret position and text insertion/deletion:
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
import { useCaretManager } from 'reactjs-virtual-keyboard';
|
|
194
|
+
|
|
195
|
+
function CustomKeyboard() {
|
|
196
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
197
|
+
const { insertText, backspace } = useCaretManager(inputRef);
|
|
198
|
+
|
|
199
|
+
return (
|
|
200
|
+
<button onClick={() => insertText('Hello')}>Insert Text</button>
|
|
201
|
+
<button onClick={backspace}>Delete</button>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### useContinuousPress
|
|
207
|
+
|
|
208
|
+
Handle hold-to-repeat functionality:
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
import { useContinuousPress } from 'reactjs-virtual-keyboard';
|
|
212
|
+
|
|
213
|
+
function DeleteButton({ onDelete }) {
|
|
214
|
+
const handlers = useContinuousPress(onDelete, {
|
|
215
|
+
initialDelay: 500, // Start repeating after 500ms
|
|
216
|
+
interval: 50, // Repeat every 50ms
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
return <button {...handlers}>Delete</button>;
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### useHardwareKeyboard
|
|
224
|
+
|
|
225
|
+
Sync with physical keyboard events:
|
|
226
|
+
|
|
227
|
+
```tsx
|
|
228
|
+
import { useHardwareKeyboard } from 'reactjs-virtual-keyboard';
|
|
229
|
+
|
|
230
|
+
function KeyboardHandler() {
|
|
231
|
+
useHardwareKeyboard({
|
|
232
|
+
isInputFocused: true,
|
|
233
|
+
onBackspace: () => console.log('Backspace'),
|
|
234
|
+
onEnter: () => console.log('Enter'),
|
|
235
|
+
onSpace: () => console.log('Space'),
|
|
236
|
+
onCapsToggle: () => console.log('Caps Lock'),
|
|
237
|
+
onKeyClick: (key) => console.log('Key:', key),
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### useKeyboardScroll
|
|
243
|
+
|
|
244
|
+
Automatically scroll inputs into view when keyboard appears:
|
|
245
|
+
|
|
246
|
+
```tsx
|
|
247
|
+
import { useKeyboardScroll } from 'reactjs-virtual-keyboard';
|
|
248
|
+
|
|
249
|
+
function MyComponent() {
|
|
250
|
+
const { scrollInput, resetScroll } = useKeyboardScroll();
|
|
251
|
+
|
|
252
|
+
const handleFocus = (e: FocusEvent) => {
|
|
253
|
+
const input = e.target as HTMLInputElement;
|
|
254
|
+
scrollInput(input); // Shifts content up if input would be covered
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
const handleBlur = () => {
|
|
258
|
+
resetScroll(); // Restores original position
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
return <input onFocus={handleFocus} onBlur={handleBlur} />;
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
The hook automatically:
|
|
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
|
|
270
|
+
|
|
271
|
+
## Custom Layouts
|
|
272
|
+
|
|
273
|
+
You can use the individual layout components:
|
|
274
|
+
|
|
275
|
+
```tsx
|
|
276
|
+
import {
|
|
277
|
+
KeyboardLayout,
|
|
278
|
+
TextLayout,
|
|
279
|
+
NumbersLayout,
|
|
280
|
+
QWERTY_LAYOUT,
|
|
281
|
+
SYMBOLS_LAYOUT,
|
|
282
|
+
NUMBERS_LAYOUT,
|
|
283
|
+
} from 'reactjs-virtual-keyboard';
|
|
284
|
+
|
|
285
|
+
// Use predefined layouts or create custom ones
|
|
286
|
+
const CUSTOM_LAYOUT = [
|
|
287
|
+
['A', 'B', 'C'],
|
|
288
|
+
['D', 'E', 'F'],
|
|
289
|
+
['G', 'H', 'I'],
|
|
290
|
+
];
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Accessibility
|
|
294
|
+
|
|
295
|
+
The keyboard includes:
|
|
296
|
+
|
|
297
|
+
- Focus management to prevent input blur when clicking keys
|
|
298
|
+
- `aria-label` attributes on special keys
|
|
299
|
+
- Keyboard navigation support
|
|
300
|
+
- Respects `prefers-reduced-motion` for animations
|
|
301
|
+
|
|
302
|
+
## Browser Support
|
|
303
|
+
|
|
304
|
+
- Chrome 60+
|
|
305
|
+
- Firefox 55+
|
|
306
|
+
- Safari 11+
|
|
307
|
+
- Edge 79+
|
|
308
|
+
|
|
309
|
+
## TypeScript
|
|
310
|
+
|
|
311
|
+
All types are exported:
|
|
312
|
+
|
|
313
|
+
```tsx
|
|
314
|
+
import type {
|
|
315
|
+
VirtualKeyboardProps,
|
|
316
|
+
VirtualKeyboardTheme,
|
|
317
|
+
GlobalVirtualKeyboardProps,
|
|
318
|
+
UseKeyboardScrollReturn,
|
|
319
|
+
LayoutType,
|
|
320
|
+
KeyboardLayoutProps,
|
|
321
|
+
} from 'reactjs-virtual-keyboard';
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## License
|
|
325
|
+
|
|
326
|
+
MIT © HydraFacial
|
|
327
|
+
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { HTMLInputTypeAttribute } from 'react';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
|
+
import { RefObject } from 'react';
|
|
5
|
+
import { SVGProps } from 'react';
|
|
6
|
+
|
|
7
|
+
export declare const BackspaceIcon: FC<IconProps>;
|
|
8
|
+
|
|
9
|
+
export declare const CapsLockIcon: FC<IconProps>;
|
|
10
|
+
|
|
11
|
+
export declare interface ContinuousPressOptions {
|
|
12
|
+
initialDelay?: number;
|
|
13
|
+
interval?: number;
|
|
14
|
+
shouldPreventDefault?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export declare const DEFAULT_THEME: {
|
|
18
|
+
backgroundColor: string;
|
|
19
|
+
keyColor: string;
|
|
20
|
+
keyTextColor: string;
|
|
21
|
+
keyActiveColor: string;
|
|
22
|
+
keyHoverColor: string;
|
|
23
|
+
activeStateColor: string;
|
|
24
|
+
keyBorderRadius: string;
|
|
25
|
+
keyFontSize: string;
|
|
26
|
+
keyHeight: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export declare const EnterIcon: FC<IconProps>;
|
|
30
|
+
|
|
31
|
+
declare type FocusedInputRef = RefObject<HTMLInputElement | HTMLTextAreaElement | null>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get the initial layout based on input type
|
|
35
|
+
*/
|
|
36
|
+
export declare const getInitialLayout: (inputType: HTMLInputTypeAttribute, defaultLayout: LayoutType) => LayoutType;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* GlobalVirtualKeyboard automatically shows a virtual keyboard when any
|
|
40
|
+
* text input or textarea is focused. It handles:
|
|
41
|
+
* - Automatic show/hide based on focus
|
|
42
|
+
* - Scrolling inputs into view
|
|
43
|
+
* - Form submission on Enter
|
|
44
|
+
* - Input type detection for appropriate layouts
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```tsx
|
|
48
|
+
* // Add once at the root of your app
|
|
49
|
+
* function App() {
|
|
50
|
+
* return (
|
|
51
|
+
* <div>
|
|
52
|
+
* <YourAppContent />
|
|
53
|
+
* <GlobalVirtualKeyboard />
|
|
54
|
+
* </div>
|
|
55
|
+
* );
|
|
56
|
+
* }
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```tsx
|
|
61
|
+
* // With controlled visibility
|
|
62
|
+
* function App() {
|
|
63
|
+
* const [keyboardEnabled, setKeyboardEnabled] = useState(true);
|
|
64
|
+
*
|
|
65
|
+
* return (
|
|
66
|
+
* <div>
|
|
67
|
+
* <button onClick={() => setKeyboardEnabled(!keyboardEnabled)}>
|
|
68
|
+
* Toggle Keyboard
|
|
69
|
+
* </button>
|
|
70
|
+
* <GlobalVirtualKeyboard enabled={keyboardEnabled} />
|
|
71
|
+
* </div>
|
|
72
|
+
* );
|
|
73
|
+
* }
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export declare const GlobalVirtualKeyboard: FC<GlobalVirtualKeyboardProps>;
|
|
77
|
+
|
|
78
|
+
export declare interface GlobalVirtualKeyboardProps {
|
|
79
|
+
/**
|
|
80
|
+
* Whether the virtual keyboard is enabled.
|
|
81
|
+
* When false, the keyboard will not appear on input focus.
|
|
82
|
+
* @default true
|
|
83
|
+
*/
|
|
84
|
+
enabled?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Additional CSS class name for the keyboard container
|
|
87
|
+
*/
|
|
88
|
+
className?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Callback fired when keyboard visibility changes
|
|
91
|
+
*/
|
|
92
|
+
onVisibilityChange?: (isVisible: boolean) => void;
|
|
93
|
+
/**
|
|
94
|
+
* Callback fired when Enter key is pressed
|
|
95
|
+
*/
|
|
96
|
+
onEnterClick?: () => void;
|
|
97
|
+
/**
|
|
98
|
+
* Callback fired when value changes
|
|
99
|
+
*/
|
|
100
|
+
onChange?: (value: string) => void;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Handle value change on the focused input
|
|
105
|
+
*/
|
|
106
|
+
export declare const handleValueChangeUtil: (focusedInputRef: FocusedInputRef, value: string) => void;
|
|
107
|
+
|
|
108
|
+
export declare interface HardwareKeyboardHandlers {
|
|
109
|
+
isInputFocused: boolean;
|
|
110
|
+
onBackspace: () => void;
|
|
111
|
+
onEnter: () => void;
|
|
112
|
+
onSpace: () => void;
|
|
113
|
+
onCapsToggle: () => void;
|
|
114
|
+
onKeyClick: (key: string) => void;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
declare type IconProps = SVGProps<SVGSVGElement>;
|
|
118
|
+
|
|
119
|
+
export declare type InputElement = HTMLInputElement | HTMLTextAreaElement;
|
|
120
|
+
|
|
121
|
+
export declare const KeyboardLayout: FC<KeyboardLayoutProps>;
|
|
122
|
+
|
|
123
|
+
export declare interface KeyboardLayoutProps {
|
|
124
|
+
currentLayout: LayoutType;
|
|
125
|
+
capsLock: boolean;
|
|
126
|
+
onKeyClick: (key: string) => void;
|
|
127
|
+
onBackspace: () => void;
|
|
128
|
+
onEnter: () => void;
|
|
129
|
+
onSpace: () => void;
|
|
130
|
+
onCapsToggle: () => void;
|
|
131
|
+
onLayoutToggle: () => void;
|
|
132
|
+
inputType: HTMLInputTypeAttribute;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export declare const KeyboardRow: FC<KeyboardRowProps>;
|
|
136
|
+
|
|
137
|
+
export declare interface KeyboardRowProps {
|
|
138
|
+
children: ReactNode;
|
|
139
|
+
className?: string;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export declare type LayoutType = 'letters' | 'symbols' | 'numbers';
|
|
143
|
+
|
|
144
|
+
export declare const NUMBERS_LAYOUT: string[][];
|
|
145
|
+
|
|
146
|
+
export declare const NumbersLayout: FC<NumbersLayoutProps>;
|
|
147
|
+
|
|
148
|
+
export declare interface NumbersLayoutProps {
|
|
149
|
+
currentLayoutData: string[][];
|
|
150
|
+
onBackspace: () => void;
|
|
151
|
+
onEnter: () => void;
|
|
152
|
+
onKeyClick: (key: string) => void;
|
|
153
|
+
capsLock: boolean;
|
|
154
|
+
currentLayout: LayoutType;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Handle Enter key click - blur input and submit form if applicable
|
|
159
|
+
*/
|
|
160
|
+
export declare const onEnterClickUtil: (focusedInputRef: FocusedInputRef) => void;
|
|
161
|
+
|
|
162
|
+
export declare const QWERTY_LAYOUT: string[][];
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Reset scroll position by removing transforms from shifted elements
|
|
166
|
+
*/
|
|
167
|
+
export declare function resetScrollPosition(): void;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Utility functions to handle layout shifting when virtual keyboard appears
|
|
171
|
+
*/
|
|
172
|
+
/**
|
|
173
|
+
* Scroll the input into view by shifting content elements up
|
|
174
|
+
*/
|
|
175
|
+
export declare function scrollInputIntoView(input: HTMLInputElement | HTMLTextAreaElement, keyboardContainerRef: HTMLSpanElement): void;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Update an input's value using the native setter (so React tracks it)
|
|
179
|
+
* and dispatch bubbled, cancelable input/change events to notify listeners.
|
|
180
|
+
*/
|
|
181
|
+
export declare const setInputValueAndDispatchEvents: (input: InputElement, value: string, options?: {
|
|
182
|
+
skipValueAssignment?: boolean;
|
|
183
|
+
}) => void;
|
|
184
|
+
|
|
185
|
+
export declare const SpacebarIcon: FC<IconProps>;
|
|
186
|
+
|
|
187
|
+
export declare const SpecialKey: FC<SpecialKeyProps>;
|
|
188
|
+
|
|
189
|
+
export declare interface SpecialKeyProps {
|
|
190
|
+
type: string;
|
|
191
|
+
onClick: () => void;
|
|
192
|
+
extraClass?: string;
|
|
193
|
+
text?: string | null;
|
|
194
|
+
icon?: ReactNode;
|
|
195
|
+
capsLock?: boolean;
|
|
196
|
+
enableContinuousPress?: boolean;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export declare const SYMBOLS_LAYOUT: string[][];
|
|
200
|
+
|
|
201
|
+
export declare const TextLayout: FC<TextLayoutProps>;
|
|
202
|
+
|
|
203
|
+
export declare interface TextLayoutProps {
|
|
204
|
+
inputType: HTMLInputTypeAttribute;
|
|
205
|
+
currentLayoutData: string[][];
|
|
206
|
+
onBackspace: () => void;
|
|
207
|
+
onEnter: () => void;
|
|
208
|
+
onSpace: () => void;
|
|
209
|
+
onCapsToggle: () => void;
|
|
210
|
+
onLayoutToggle: () => void;
|
|
211
|
+
onKeyClick: (key: string) => void;
|
|
212
|
+
capsLock: boolean;
|
|
213
|
+
currentLayout: LayoutType;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Hook to manage caret position and text insertion/deletion in input elements
|
|
218
|
+
*/
|
|
219
|
+
export declare function useCaretManager(focusedInputRef: RefObject<InputElement | null>): UseCaretManagerReturn;
|
|
220
|
+
|
|
221
|
+
export declare interface UseCaretManagerReturn {
|
|
222
|
+
insertText: (text: string) => void;
|
|
223
|
+
backspace: () => void;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Hook for handling continuous press events (like holding backspace to delete multiple characters)
|
|
228
|
+
*/
|
|
229
|
+
export declare function useContinuousPress(onPress: () => void, { initialDelay, interval, shouldPreventDefault, }?: ContinuousPressOptions): {
|
|
230
|
+
onMouseDown: (e: React.MouseEvent) => void;
|
|
231
|
+
onTouchStart: (e: React.TouchEvent) => void;
|
|
232
|
+
onMouseUp: () => void;
|
|
233
|
+
onMouseLeave: () => void;
|
|
234
|
+
onTouchEnd: (e: React.TouchEvent) => void;
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Hook to keep virtual keyboard in sync with hardware keyboard events
|
|
239
|
+
* (e.g., when pressing caps lock on hardware keyboard, virtual keyboard should reflect it)
|
|
240
|
+
*/
|
|
241
|
+
export declare function useHardwareKeyboard({ isInputFocused, onBackspace, onEnter, onSpace, onCapsToggle, onKeyClick, }: HardwareKeyboardHandlers): void;
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Hook to handle keyboard scrolling for input elements.
|
|
245
|
+
* Automatically shifts content up when the virtual keyboard would cover the input.
|
|
246
|
+
*
|
|
247
|
+
* @returns Object with scroll and reset functions
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```tsx
|
|
251
|
+
* const { scrollInput, resetScroll } = useKeyboardScroll();
|
|
252
|
+
*
|
|
253
|
+
* // When input is focused
|
|
254
|
+
* scrollInput(inputElement);
|
|
255
|
+
*
|
|
256
|
+
* // When keyboard is hidden
|
|
257
|
+
* resetScroll();
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
export declare function useKeyboardScroll(keyboardContainerRef: RefObject<HTMLSpanElement | null>): UseKeyboardScrollReturn;
|
|
261
|
+
|
|
262
|
+
export declare interface UseKeyboardScrollReturn {
|
|
263
|
+
/** Scroll the input into view when keyboard appears */
|
|
264
|
+
scrollInput: (input: HTMLInputElement | HTMLTextAreaElement) => void;
|
|
265
|
+
/** Reset scroll position when keyboard hides */
|
|
266
|
+
resetScroll: () => void;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Validate if the focused element should show the virtual keyboard
|
|
271
|
+
* Returns the input/textarea element or null if it shouldn't show keyboard
|
|
272
|
+
*/
|
|
273
|
+
export declare const validateFocusInputs: (event: Event) => HTMLInputElement | HTMLTextAreaElement | null;
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Validates a single character based on input type
|
|
277
|
+
*/
|
|
278
|
+
export declare const validateValueUtil: (value: string, inputType: HTMLInputTypeAttribute) => boolean;
|
|
279
|
+
|
|
280
|
+
export declare const VirtualKey: FC<VirtualKeyProps>;
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Virtual Keyboard Component
|
|
284
|
+
*
|
|
285
|
+
* A customizable on-screen keyboard for React applications.
|
|
286
|
+
* Supports multiple layouts (QWERTY, symbols, numbers), hardware keyboard sync,
|
|
287
|
+
* and touch device compatibility.
|
|
288
|
+
*/
|
|
289
|
+
export declare const VirtualKeyboard: FC<VirtualKeyboardProps>;
|
|
290
|
+
|
|
291
|
+
export declare const VirtualKeyboardContainer: FC<VirtualKeyboardContainerProps>;
|
|
292
|
+
|
|
293
|
+
declare interface VirtualKeyboardContainerProps {
|
|
294
|
+
children: ReactNode;
|
|
295
|
+
className?: string;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export declare interface VirtualKeyboardProps {
|
|
299
|
+
/** Ref to the currently focused input element */
|
|
300
|
+
focusedInputRef: RefObject<HTMLInputElement | HTMLTextAreaElement | null>;
|
|
301
|
+
/** Whether an input is currently focused */
|
|
302
|
+
isInputFocused: boolean;
|
|
303
|
+
/** Type of the input element (affects layout and validation) */
|
|
304
|
+
inputType?: HTMLInputTypeAttribute;
|
|
305
|
+
/** Callback fired when Enter key is pressed */
|
|
306
|
+
onEnterClick?: () => void;
|
|
307
|
+
/** Callback fired when value changes */
|
|
308
|
+
onChange?: (value: string) => void;
|
|
309
|
+
/** Additional CSS class name */
|
|
310
|
+
className?: string;
|
|
311
|
+
/** Default layout to show ('letters' | 'symbols' | 'numbers') */
|
|
312
|
+
defaultLayout?: LayoutType;
|
|
313
|
+
/** Custom validation function */
|
|
314
|
+
validate?: (value: string) => boolean;
|
|
315
|
+
/** Theme configuration */
|
|
316
|
+
theme?: VirtualKeyboardTheme;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export declare interface VirtualKeyboardTheme {
|
|
320
|
+
/** Background color of the keyboard container */
|
|
321
|
+
backgroundColor?: string;
|
|
322
|
+
/** Color of the keys */
|
|
323
|
+
keyColor?: string;
|
|
324
|
+
/** Text color on keys */
|
|
325
|
+
keyTextColor?: string;
|
|
326
|
+
/** Active/pressed key background color */
|
|
327
|
+
keyActiveColor?: string;
|
|
328
|
+
/** Hover key background color */
|
|
329
|
+
keyHoverColor?: string;
|
|
330
|
+
/** Active state color (e.g., caps lock on) */
|
|
331
|
+
activeStateColor?: string;
|
|
332
|
+
/** Border radius for keys */
|
|
333
|
+
keyBorderRadius?: string;
|
|
334
|
+
/** Font size for keys */
|
|
335
|
+
keyFontSize?: string;
|
|
336
|
+
/** Key height */
|
|
337
|
+
keyHeight?: string;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export declare interface VirtualKeyProps {
|
|
341
|
+
keyValue: string;
|
|
342
|
+
onClick: (key: string) => void;
|
|
343
|
+
className?: string;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export { }
|