Files
llink/js/desktop/src/features/onboarding/onboarding-keyboard.tsx
T
2026-06-21 11:35:02 -07:00

78 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { cn } from '@/lib/utils';
type KeyState = 'idle' | 'active' | 'success';
interface OnboardingKeyboardProps {
/** The key to emphasise. Defaults to the record key. */
highlightKey?: string;
state: KeyState;
/** Hold progress (01), fills the emphasised key from the bottom. */
progress?: number;
}
interface KeyCapProps {
label: string;
hero?: boolean;
state?: KeyState;
progress?: number;
className?: string;
}
function KeyCap({
label,
hero,
state = 'idle',
progress = 0,
className,
}: KeyCapProps) {
return (
<div
className={cn(
'relative flex select-none items-center justify-center overflow-hidden rounded-lg border text-sm font-medium',
hero ? 'h-14 w-14 text-xl' : 'h-14',
!hero && 'border-white/10 bg-white/5 text-white/30',
hero &&
state === 'idle' &&
'border-white/25 bg-white/10 text-white motion-safe:animate-pulse',
hero && state === 'active' && 'border-white/50 bg-white/20 text-white',
hero &&
state === 'success' &&
'border-emerald-400/50 bg-emerald-500/20 text-emerald-200',
className,
)}
>
{hero && state !== 'success' && progress > 0 && (
<span
className="pointer-events-none absolute inset-x-0 bottom-0 bg-white/25"
style={{ height: `${progress * 100}%` }}
/>
)}
<span className="relative z-10">{label}</span>
</div>
);
}
/**
* Draws the record key in its physical context: Esc above, 1 to its right, and
* Tab / Q on the row below — so the key is recognisable on a real keyboard.
*/
export function OnboardingKeyboard({
highlightKey = '`',
state,
progress = 0,
}: OnboardingKeyboardProps) {
return (
<div className="flex flex-col items-start gap-1.5">
<KeyCap label="esc" className="w-14 text-xs" />
<div className="flex gap-1.5">
<KeyCap label={highlightKey} hero state={state} progress={progress} />
<KeyCap label="1" className="w-14" />
</div>
<div className="flex gap-1.5">
<KeyCap label="tab" className="w-20 text-xs" />
<KeyCap label="Q" className="w-12" />
</div>
</div>
);
}