import React from 'react';
import { fonts } from '../lib/theme';
type IOSKeyboardProps = {
activeKey?: string;
/** How many frames since the key was pressed (for highlight decay) */
pressAge?: number;
};
const ROW_1 = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'];
const ROW_2 = ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'];
const ROW_3 = ['z', 'x', 'c', 'v', 'b', 'n', 'm'];
const KEY_H = 42;
const KEY_GAP = 6;
const ROW_GAP = 11;
const SIDE_PAD = 3;
const KEYBOARD_BG = '#1c1c1e';
const KEY_BG = '#3a3a3c';
const KEY_BG_ACTIVE = '#636366';
const KEY_TEXT = '#fff';
const SPECIAL_BG = '#2c2c2e';
const Key: React.FC<{
label: string;
width: number;
isActive: boolean;
pressAge: number;
fontSize?: number;
}> = ({ label, width, isActive, pressAge, fontSize = 22 }) => {
// Highlight decays over 4 frames
const highlightOpacity = isActive && pressAge < 4 ? 1 - pressAge / 4 : 0;
const bg = highlightOpacity > 0
? lerpColor(KEY_BG, KEY_BG_ACTIVE, highlightOpacity)
: KEY_BG;
return (
{label}
);
};
function lerpColor(a: string, b: string, t: number): string {
const pa = parseInt(a.slice(1), 16);
const pb = parseInt(b.slice(1), 16);
const r = Math.round(((pa >> 16) & 0xff) * (1 - t) + ((pb >> 16) & 0xff) * t);
const g = Math.round(((pa >> 8) & 0xff) * (1 - t) + ((pb >> 8) & 0xff) * t);
const bl = Math.round((pa & 0xff) * (1 - t) + (pb & 0xff) * t);
return `#${((r << 16) | (g << 8) | bl).toString(16).padStart(6, '0')}`;
}
export const IOSKeyboard: React.FC = ({ activeKey, pressAge = 99 }) => {
const isActive = (key: string) =>
activeKey !== undefined && key.toLowerCase() === activeKey.toLowerCase();
const age = (key: string) => (isActive(key) ? pressAge : 99);
// Backspace/delete key highlight
const deleteHighlight = activeKey === '⌫' && pressAge < 4 ? 1 - pressAge / 4 : 0;
const deleteBg = deleteHighlight > 0 ? lerpColor(SPECIAL_BG, KEY_BG_ACTIVE, deleteHighlight) : SPECIAL_BG;
// Key widths: 10 keys + 9 gaps in ~375px row → each key ~33px
const letterKeyW = 33;
// Row 2 has 9 keys → same key width but centered with side padding
// Row 3 has shift + 7 keys + delete
return (
{/* Row 1: q-p */}
{ROW_1.map((k) => (
))}
{/* Row 2: a-l */}
{ROW_2.map((k) => (
))}
{/* Row 3: shift + z-m + delete */}
{/* Row 4: 123 / globe / space / return */}
123
{/* Space bar */}
return
);
};