* feat(shortcuts): add tinykeys + core infrastructure (useHotkeys, shortcut-map, KbdHint) Install tinykeys (~400B) for declarative keyboard shortcut handling. Add useHotkeys React hook with input-guarding logic, centralized shortcut definitions, and a reusable KbdHint badge component. Ref #113 * feat(shortcuts): wire j/k navigation and 1-4 tab switching Add useHotkeys call to OrchestratorPage with: - j/ArrowDown to navigate to next job in list - k/ArrowUp to navigate to previous job - 1/2/3/4 to switch between Ready/Discovered/Applied/All tabs Auto-scrolls the list to keep the selected job visible. Ref #113 * feat(shortcuts): add context action shortcuts (s/a/t/p/d/o/x/Esc) Wire keyboard shortcuts for all primary actions: - s: skip job (discovered/ready tabs) - a: mark applied (ready tab) - t: toggle tailor mode (discovered/ready tabs) - p: view PDF in new tab (ready tab) - d: download PDF (ready tab) - o: open job listing (all tabs) - x: toggle select current job - /: open search (command bar) - Escape: clear selection Actions are tab-scoped and guard against in-flight state. Thread tailorTrigger counter prop through JobDetailPanel to DiscoveredPanel and ReadyPanel for keyboard-driven tailor toggle. Ref #113 * feat(shortcuts): add bottom hint bar and help dialog (? key) Add KeyboardShortcutBar -- a Superhuman-style bottom bar showing available shortcuts for the current tab. Dismissible with X button, preference stored in localStorage. Add KeyboardShortcutDialog -- a grouped help overlay triggered by '?' showing all shortcuts with their key bindings in a two-column layout. Both components are context-aware, only displaying shortcuts valid for the active tab. Ref #113 * feat(shortcuts): add visual KbdHint badges on action buttons Show keyboard shortcut key caps on primary action buttons: - DecideMode: 's' on Skip, 't' on Start Tailoring - ReadyPanel: 'p' on View PDF, 'd' on Download, 'o' on Open Listing, 'a' on Mark Applied - OrchestratorFilters: '1'-'4' on tab triggers All hints are desktop-only (hidden below lg breakpoint). Ref #113 * refactor(shortcuts): migrate Cmd+K to useHotkeys in JobCommandBar Replace manual window.addEventListener keydown handler with the shared useHotkeys hook for consistency across all keyboard shortcuts. Ref #113 * fix(test): mock getProfile in OrchestratorPage tests * style: move tab shortcut indicator before label * feat: add ArrowLeft/Right shortcuts for tab navigation * feat: show keyboard helpers only when Control is held down * feat: expand shortcut bar with multiline layout * feat: show keyboard shortcut help on first launch * 1 * 2 * 3 * better modifier pattern * 5 * tailoring is a toggle * tests * tests is passing * r to move to ready * tests
33 lines
1.0 KiB
TypeScript
33 lines
1.0 KiB
TypeScript
import { useModifierPressed } from "@client/hooks/useModifierPressed";
|
|
import type React from "react";
|
|
|
|
interface KbdHintProps {
|
|
/** The key to display, e.g. "s", "Cmd+K", "?" */
|
|
shortcut: string;
|
|
/** Additional className */
|
|
className?: string;
|
|
}
|
|
|
|
/**
|
|
* Inline keyboard-hint badge for action buttons.
|
|
*
|
|
* Rendered as a small `<kbd>` element styled to look like a physical key cap.
|
|
* Hidden on mobile (below `lg` breakpoint) since keyboard shortcuts are only
|
|
* useful with a physical keyboard.
|
|
*
|
|
* Only visible when the Control key is held down.
|
|
*/
|
|
export const KbdHint: React.FC<KbdHintProps> = ({ shortcut, className }) => {
|
|
const isControlPressed = useModifierPressed("Control");
|
|
|
|
if (!isControlPressed) return null;
|
|
|
|
return (
|
|
<kbd
|
|
className={`hidden lg:inline-flex items-center justify-center min-w-[1.25rem] h-5 px-1 rounded border border-border/60 bg-muted/40 text-[10px] font-mono font-medium text-muted-foreground leading-none ${className ?? ""}`}
|
|
>
|
|
{shortcut}
|
|
</kbd>
|
|
);
|
|
};
|