Virtual Keyboard
On-screen keyboard for touch interfaces, kiosks, and POS terminals.
Keyboard Buttons
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center;">
<button class="virtual-keyboard-btn">A</button>
<button class="virtual-keyboard-btn">B</button>
<button class="virtual-keyboard-btn">C</button>
<button class="virtual-keyboard-btn virtual-keyboard-btn-primary">Enter</button>
<button class="virtual-keyboard-btn" disabled>Locked</button>
</div> Requires: ux.min.css
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center;">
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">A</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">B</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">C</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium bg-primary text-primary-content border border-primary rounded-xl cursor-pointer select-none hover:brightness-90 active:scale-[0.97]">Enter</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl opacity-50 cursor-not-allowed" disabled>Locked</button>
</div> Requires: tw.min.css
// No JavaScript required - pure CSS component Sizes & Icon Buttons
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center;">
<!-- Small -->
<button class="virtual-keyboard-btn virtual-keyboard-btn-sm">sm</button>
<!-- Default -->
<button class="virtual-keyboard-btn">Default</button>
<!-- Large -->
<button class="virtual-keyboard-btn virtual-keyboard-btn-lg">Large</button>
<!-- Icon with text -->
<button class="virtual-keyboard-btn">
<svg class="virtual-keyboard-btn-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9.75 14.25 12m0 0 2.25 2.25M14.25 12l2.25-2.25M14.25 12 12 14.25m-2.58 4.92-6.374-6.375a1.125 1.125 0 0 1 0-1.59L9.42 4.83a1.125 1.125 0 0 1 1.59 0l6.374 6.375a1.125 1.125 0 0 1 0 1.59l-6.374 6.375a1.125 1.125 0 0 1-1.59 0Z" /></svg>
Delete
</button>
<!-- Icon only -->
<button class="virtual-keyboard-btn virtual-keyboard-btn-icon-only" aria-label="Backspace">
<svg class="virtual-keyboard-btn-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9.75 14.25 12m0 0 2.25 2.25M14.25 12l2.25-2.25M14.25 12 12 14.25m-2.58 4.92-6.374-6.375a1.125 1.125 0 0 1 0-1.59L9.42 4.83a1.125 1.125 0 0 1 1.59 0l6.374 6.375a1.125 1.125 0 0 1 0 1.59l-6.374 6.375a1.125 1.125 0 0 1-1.59 0Z" /></svg>
</button>
</div> Requires: ux.min.css
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center;">
<!-- Small -->
<button class="inline-flex items-center justify-center min-w-[36px] h-9 px-2 text-[0.8125rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">sm</button>
<!-- Default -->
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">Default</button>
<!-- Large -->
<button class="inline-flex items-center justify-center min-w-[52px] h-[52px] px-6 text-base font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">Large</button>
<!-- Icon with text -->
<button class="inline-flex items-center justify-center gap-2 min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">
<svg class="shrink-0 w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9.75 14.25 12m0 0 2.25 2.25M14.25 12l2.25-2.25M14.25 12 12 14.25m-2.58 4.92-6.374-6.375a1.125 1.125 0 0 1 0-1.59L9.42 4.83a1.125 1.125 0 0 1 1.59 0l6.374 6.375a1.125 1.125 0 0 1 0 1.59l-6.374 6.375a1.125 1.125 0 0 1-1.59 0Z" /></svg>
Delete
</button>
<!-- Icon only -->
<button class="inline-flex items-center justify-center w-11 h-11 p-0 text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]" aria-label="Backspace">
<svg class="shrink-0 w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9.75 14.25 12m0 0 2.25 2.25M14.25 12l2.25-2.25M14.25 12 12 14.25m-2.58 4.92-6.374-6.375a1.125 1.125 0 0 1 0-1.59L9.42 4.83a1.125 1.125 0 0 1 1.59 0l6.374 6.375a1.125 1.125 0 0 1 0 1.59l-6.374 6.375a1.125 1.125 0 0 1-1.59 0Z" /></svg>
</button>
</div> Requires: tw.min.css
// No JavaScript required - pure CSS component Numeric Keypad Layout
<div style="display: inline-grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; max-width: 200px;">
<button class="virtual-keyboard-btn">1</button>
<button class="virtual-keyboard-btn">2</button>
<button class="virtual-keyboard-btn">3</button>
<button class="virtual-keyboard-btn">4</button>
<button class="virtual-keyboard-btn">5</button>
<button class="virtual-keyboard-btn">6</button>
<button class="virtual-keyboard-btn">7</button>
<button class="virtual-keyboard-btn">8</button>
<button class="virtual-keyboard-btn">9</button>
<button class="virtual-keyboard-btn">.</button>
<button class="virtual-keyboard-btn">0</button>
<button class="virtual-keyboard-btn virtual-keyboard-btn-icon-only" aria-label="Backspace">
<svg class="virtual-keyboard-btn-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9.75 14.25 12m0 0 2.25 2.25M14.25 12l2.25-2.25M14.25 12 12 14.25m-2.58 4.92-6.374-6.375a1.125 1.125 0 0 1 0-1.59L9.42 4.83a1.125 1.125 0 0 1 1.59 0l6.374 6.375a1.125 1.125 0 0 1 0 1.59l-6.374 6.375a1.125 1.125 0 0 1-1.59 0Z" /></svg>
</button>
</div> Requires: ux.min.css
<div style="display: inline-grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; max-width: 200px;">
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">1</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">2</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">3</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">4</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">5</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">6</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">7</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">8</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">9</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">.</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">0</button>
<button class="inline-flex items-center justify-center w-11 h-11 p-0 text-base-content bg-base-100 border border-base-300 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]" aria-label="Backspace">
<svg class="shrink-0 w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9.75 14.25 12m0 0 2.25 2.25M14.25 12l2.25-2.25M14.25 12 12 14.25m-2.58 4.92-6.374-6.375a1.125 1.125 0 0 1 0-1.59L9.42 4.83a1.125 1.125 0 0 1 1.59 0l6.374 6.375a1.125 1.125 0 0 1 0 1.59l-6.374 6.375a1.125 1.125 0 0 1-1.59 0Z" /></svg>
</button>
</div> Requires: tw.min.css
// ERPlora POS numeric keypad input handler:
const display = document.querySelector('#pos-display');
document.querySelectorAll('.virtual-keyboard-btn').forEach(btn => {
btn.addEventListener('click', () => {
const key = btn.textContent.trim();
if (key === '') {
// Backspace icon button
display.value = display.value.slice(0, -1);
} else {
display.value += key;
}
});
}); Glass Variant & Status Indicator
ERPlora Keyboard Active
Keyboard Unavailable
Detecting...
<!-- Glass variant buttons -->
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; padding: 1.5rem; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 1rem;">
<button class="virtual-keyboard-btn glass">1</button>
<button class="virtual-keyboard-btn glass">2</button>
<button class="virtual-keyboard-btn glass">3</button>
<button class="virtual-keyboard-btn virtual-keyboard-btn-primary">OK</button>
</div>
<!-- Status indicators -->
<div style="display: flex; gap: 1.5rem; flex-wrap: wrap; margin-top: 1rem;">
<span class="virtual-keyboard-status virtual-keyboard-status-supported">
<span class="virtual-keyboard-status-dot"></span>
ERPlora Keyboard Active
</span>
<span class="virtual-keyboard-status virtual-keyboard-status-unsupported">
<span class="virtual-keyboard-status-dot"></span>
Keyboard Unavailable
</span>
<span class="virtual-keyboard-status">
<span class="virtual-keyboard-status-dot"></span>
Detecting...
</span>
</div> Requires: ux.min.css
<!-- Glass variant buttons -->
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; padding: 1.5rem; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 1rem;">
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100/60 backdrop-blur-[20px] border border-base-content/10 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">1</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100/60 backdrop-blur-[20px] border border-base-content/10 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">2</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium text-base-content bg-base-100/60 backdrop-blur-[20px] border border-base-content/10 rounded-xl cursor-pointer select-none hover:bg-base-200 active:scale-[0.97]">3</button>
<button class="inline-flex items-center justify-center min-w-[44px] h-11 px-4 text-[0.9375rem] font-medium bg-primary text-primary-content border border-primary rounded-xl cursor-pointer select-none hover:brightness-90 active:scale-[0.97]">OK</button>
</div>
<!-- Status indicators -->
<div style="display: flex; gap: 1.5rem; flex-wrap: wrap; margin-top: 1rem;">
<span class="inline-flex items-center gap-1 text-xs text-base-content/40">
<span class="w-2 h-2 rounded-full bg-success"></span>
ERPlora Keyboard Active
</span>
<span class="inline-flex items-center gap-1 text-xs text-base-content/40">
<span class="w-2 h-2 rounded-full bg-error"></span>
Keyboard Unavailable
</span>
<span class="inline-flex items-center gap-1 text-xs text-base-content/40">
<span class="w-2 h-2 rounded-full bg-base-content/40"></span>
Detecting...
</span>
</div> Requires: tw.min.css
// Check virtual keyboard API support:
const statusEl = document.querySelector('.virtual-keyboard-status');
if ('virtualKeyboard' in navigator) {
statusEl.classList.add('virtual-keyboard-status-supported');
statusEl.querySelector('.virtual-keyboard-status-dot');
} else {
statusEl.classList.add('virtual-keyboard-status-unsupported');
} Classes Reference
| Class | Description |
|---|---|
| .virtual-keyboard-btn | Base keyboard button |
| .virtual-keyboard-btn-sm | Small button (36px) |
| .virtual-keyboard-btn-lg | Large button (52px) |
| .virtual-keyboard-btn-primary | Primary color button (action keys) |
| .virtual-keyboard-btn-icon | Icon element inside button |
| .virtual-keyboard-btn-icon-only | Icon-only button (square, no padding) |
| .virtual-keyboard-btn.glass | Glass morphism variant |
| .virtual-keyboard-status | Status indicator container |
| .virtual-keyboard-status-dot | Status dot indicator |
| .virtual-keyboard-status-supported | Supported status (green dot) |
| .virtual-keyboard-status-unsupported | Unsupported status (red dot) |