Keyboard

Keyboard

An on-screen virtual keyboard component designed for touch interfaces and accessibility, with configurable layouts and physical keyboard synchronization.


Import

tsx
import { KeyboardProvider, useKeyboard } from "asheeui";

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).

tsx
import {
AsheeUIProvider,
KeyboardProvider,
Input,
} from "asheeui";
function App() {
return (
<AsheeUIProvider>
{/* Feature providers MUST be placed below AsheeUIProvider */}
<KeyboardProvider size="md">
<div>
<Input name="username" placeholder="Enter username" enableVirtualKeyboard />
<Input name="password" placeholder="Enter password" enableVirtualKeyboard />
</div>
</KeyboardProvider>
</AsheeUIProvider>
);
}

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

PropTypeDefaultDescription
childrenReactNodeNoneApp content (required)
layoutsKeyboardLayoutsDefault layoutsKey layout definitions
displayKeyDisplayMapDefault displayDisplay labels for keys
defaultLayoutLayoutName"default"*Initial layout name
size"sm" | "md" | "lg""md"*Size scale for keyboard keys and container height
autoShiftBackbooleantrue*Auto-return from shift layout
closeDelaynumber500*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
portalbooleantrue*Whether to render the keyboard in a portal
disabledbooleanfalse*Whether the keyboard system is globally disabled
classNamestringNoneExtra classes for keyboard container
keyClassNamestringNoneExtra classes for individual keys

* Falls back through Global Configuration if not set. See below.

useKeyboard API

PropertyTypeDescription
isOpenbooleanWhether keyboard is visible
activeInputIdstring | nullID of active input
activeElementKeyboardElement | nullActive DOM element
configKeyboardConfigMerged configuration
resolvedSizeKeyboardSizeKeyResolved size
resolvedVariantVariantResolved variant
resolvedColorColorResolved color
resolvedRadiusRadiusResolved radius
resolvedPortalbooleanResolved portal setting
currentLayoutLayoutNameCurrent active layout
isDisabledbooleanWhether the system is disabled
openKeyboard(id, el, options?)(id: string, el: KeyboardElement, options?: KeyboardOpenOptions) => voidOpen keyboard for an element
requestClose(id)(id: string) => voidRequest closure with delay
forceClose()() => voidImmediately close keyboard
setLayout(layout)(layout: LayoutName) => voidSwitch to a different layout

KeyboardOpenOptions

PropTypeDescription
layoutLayoutNameLayout to show when opened
sizeKeyboardSizeKeyOverride size for this instance
variantVariantOverride variant for this instance
colorColorOverride color for this instance
radiusRadiusOverride radius for this instance
portalbooleanOverride 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: hidden or contain: 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.body is 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:

  1. Instance prop: set directly on <KeyboardProvider />
  2. Component config: components.keyboard in your ashee.config
  3. Theme default: defaultVariant / defaultColor / defaultRadius in your ashee.config
  4. Built-in fallback: component's internal default values

Component config

ts
// ashee.config.ts
import type { ExternalConfig } from "asheeui";
export const config: ExternalConfig = {
components: {
keyboard: {
defaultLayout: "default",
size: "md",
autoShiftBack: true,
variant: "solid",
color: "primary",
radius: "md",
portal: true,
disabled: false,
},
},
};

Built-in fallbacks

ts
{
defaultLayout: "default",
size: "md",
variant: "solid",
color: "primary",
radius: "md",
portal: true,
disabled: false,
closeDelay: 500,
autoShiftBack: true,
}

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

PropTypeDefaultDescription
enableVirtualKeyboardbooleantrueEnables virtual keyboard on focus
tsx
<Input
name="username"
label="Username"
enableVirtualKeyboard // default: true
/>

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

TokenDisplayDescription
{bksp}Backspace
{enter}Enter/Return
{shift}Shift (toggles shift layout)
{symbols}?123Switch to symbols layout
{abc}ABCSwitch back to default layout
{space}spaceSpace character
{clear}CClear 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 KeyboardProvider must wrap your app root (placed below <AsheeUIProvider>) for the keyboard to work.
  • Automatic Rendering: The KeyboardProvider automatically 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, and numeric layouts out of the box.
  • Custom Layouts: You can provide custom layouts and display labels via the layouts and display props.
  • Auto Shift Back: When autoShiftBack is true, the keyboard automatically returns to the default layout after pressing a key in shift mode.
  • Close Delay: The closeDelay prop prevents accidental closures when moving focus between inputs.
  • Portal: The keyboard is portaled to document.body by default. This can be disabled via the portal prop 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.
Previous

← Input

Next

Link →