Keyboard
An on-screen virtual keyboard component designed for touch interfaces and accessibility, with configurable layouts and physical keyboard synchronization.
Import
Usage
KeyboardProvider is a global feature provider. Wrap your application root once, placed strictly below <AsheeUIProvider>. The provider automatically renders the keyboard at the bottom of the screen when needed.
Then enable the virtual keyboard on any Input component by setting enableVirtualKeyboard={true} (it's true by default).
Examples
Size variants
Tap to open the small keyboard variant
Tap to open the medium keyboard variant
Tap to open the large keyboard variant
Multiple input fields
Tap any field to open the keyboard. The keyboard stays open when switching between inputs.
Disable virtual keyboard on specific inputs
This input opens the keyboard
This input also opens the keyboard
This input does NOT open the keyboard
This input also does NOT open the keyboard
The last two inputs have enableVirtualKeyboard=false.
Custom layouts
Tap to open a keyboard with custom layouts
The keyboard uses custom layouts with different key arrangements.
Custom display labels
Tap to see custom labels on special keys
Special keys use custom display labels like #+= for symbols and ␣ for space.
Styling keyboard keys
Solid variant with radius
Bordered variant with success color
Ghost variant with warning color
Each input uses different keyboard styling (variant, color, radius).
Manual control with useKeyboard
Keyboard Status: Closed
Active Input: None
Current Layout: default
Keyboard is disabled for this input
This input has enableVirtualKeyboard=false. Use the buttons above to manually control the keyboard.
KeyboardProvider Props
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | None | App content (required) |
layouts | KeyboardLayouts | Default layouts | Key layout definitions |
display | KeyDisplayMap | Default display | Display labels for keys |
defaultLayout | LayoutName | "default"* | Initial layout name |
size | "sm" | "md" | "lg" | "md"* | Size scale for keyboard keys and container height |
autoShiftBack | boolean | true* | Auto-return from shift layout |
closeDelay | number | 500* | Close delay in ms after blur |
variant | "solid" | "ghost" | "bordered" | "faded" | "underlined" | "solid"* | Visual style of keys |
color | "none" | "primary" | "secondary" | "danger" | "warning" | "success" | "primary"* | Semantic color of keys |
radius | "none" | "xs" | "sm" | "md" | "lg" | "xl" | "full" | "md"* | Corner rounding of keys |
portal | boolean | true* | Whether to render the keyboard in a portal |
disabled | boolean | false* | Whether the keyboard system is globally disabled |
className | string | None | Extra classes for keyboard container |
keyClassName | string | None | Extra classes for individual keys |
* Falls back through Global Configuration if not set. See below.
useKeyboard API
| Property | Type | Description |
|---|---|---|
isOpen | boolean | Whether keyboard is visible |
activeInputId | string | null | ID of active input |
activeElement | KeyboardElement | null | Active DOM element |
config | KeyboardConfig | Merged configuration |
resolvedSize | KeyboardSizeKey | Resolved size |
resolvedVariant | Variant | Resolved variant |
resolvedColor | Color | Resolved color |
resolvedRadius | Radius | Resolved radius |
resolvedPortal | boolean | Resolved portal setting |
currentLayout | LayoutName | Current active layout |
isDisabled | boolean | Whether the system is disabled |
openKeyboard(id, el, options?) | (id: string, el: KeyboardElement, options?: KeyboardOpenOptions) => void | Open keyboard for an element |
requestClose(id) | (id: string) => void | Request closure with delay |
forceClose() | () => void | Immediately close keyboard |
setLayout(layout) | (layout: LayoutName) => void | Switch to a different layout |
KeyboardOpenOptions
| Prop | Type | Description |
|---|---|---|
layout | LayoutName | Layout to show when opened |
size | KeyboardSizeKey | Override size for this instance |
variant | Variant | Override variant for this instance |
color | Color | Override color for this instance |
radius | Radius | Override radius for this instance |
portal | boolean | Override portal for this instance |
Portal Behavior
The OnScreenKeyboard is rendered in a Floating UI portal by default. This means the keyboard is attached to document.body rather than staying in the component's DOM hierarchy.
Why use a portal?
- Escapes CSS containment: The keyboard appears at the bottom of the screen even when the input is inside containers with
overflow: hiddenorcontain: layout - Avoids stacking context issues: The keyboard maintains proper z-index regardless of parent stacking contexts
- Works with any parent: The keyboard functions correctly regardless of where the input is placed in the component tree
- Prevents clipping: The keyboard is never clipped by parent containers
When to disable the portal
You may want to disable the portal (by setting portal={false}) when:
- You need the keyboard to stay within a specific container for testing purposes
- You are rendering inside a shadow DOM or iframe where
document.bodyis not appropriate - You have specific layout requirements that depend on the keyboard remaining in the DOM hierarchy
Global Configuration
Keyboard reads defaults from four places, in this order of precedence:
- Instance prop: set directly on
<KeyboardProvider /> - Component config:
components.keyboardin yourashee.config - Theme default:
defaultVariant/defaultColor/defaultRadiusin yourashee.config - Built-in fallback: component's internal default values
Component config
Built-in fallbacks
Input Integration
The virtual keyboard integrates directly with AsheeUI's Input component. Set enableVirtualKeyboard={true} (default) to enable keyboard support.
Input props for keyboard integration
| Prop | Type | Default | Description |
|---|---|---|---|
enableVirtualKeyboard | boolean | true | Enables virtual keyboard on focus |
The useKeyboardField hook handles the focus/blur events automatically: no additional wiring needed.
Layouts
The keyboard comes with four default layouts:
Default Layout
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
{shift} z x c v b n m {shift}
{symbols} , {space} . {enter}
Shift Layout
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
{shift} Z X C V B N M {shift}
{symbols} , {space} . {enter}
Symbols Layout
1 2 3 4 5 6 7 8 9 0 {bksp}
@ # $ _ & - + ( )
* " ' : ; ! ? %
{abc} / \ ~ ` = {abc}
{abc} , {space} . {enter}
Numeric Layout
1 2 3 {bksp}
4 5 6 {clear}
7 8 9 {enter}
0 . {space}
Special Keys
| Token | Display | Description |
|---|---|---|
{bksp} | ⌫ | Backspace |
{enter} | ↵ | Enter/Return |
{shift} | ⇧ | Shift (toggles shift layout) |
{symbols} | ?123 | Switch to symbols layout |
{abc} | ABC | Switch back to default layout |
{space} | space | Space character |
{clear} | C | Clear input value |
Accessibility
- Keyboard has
aria-label="Virtual Keyboard"for screen readers - Supports physical keyboard input with visual key highlighting
- Escape key closes the keyboard
- Focus management with cursor position preservation
- All keys are accessible via keyboard navigation
- Keyboard stays open while interacting with keys
- Clicking outside the input area doesn't immediately close the keyboard (uses close delay)
Notes
- Provider Required: The
KeyboardProvidermust wrap your app root (placed below<AsheeUIProvider>) for the keyboard to work. - Automatic Rendering: The
KeyboardProviderautomatically renders the keyboard at the bottom of the screen. You don't need to manually add<OnScreenKeyboard />anywhere. - Default Layouts: The keyboard comes with
default,shift,symbols, andnumericlayouts out of the box. - Custom Layouts: You can provide custom layouts and display labels via the
layoutsanddisplayprops. - Auto Shift Back: When
autoShiftBackistrue, the keyboard automatically returns to the default layout after pressing a key in shift mode. - Close Delay: The
closeDelayprop prevents accidental closures when moving focus between inputs. - Portal: The keyboard is portaled to
document.bodyby default. This can be disabled via theportalprop or component config. - Per-Instance Overrides: Each keyboard instance can override size, variant, color, radius, and portal settings via
KeyboardOpenOptions. - Physical Keyboard Sync: The virtual keyboard highlights keys when the physical keyboard is used, providing a consistent experience.
- Cursor Management: The keyboard preserves cursor position and handles selections when inserting or deleting characters.