All checks were successful
Mirror to GitHub / mirror (push) Successful in 4s
- WhatWeKnow shows a "synthesizing" indicator + skeleton pulse while the chat cycle is in-flight; task-lane header mirrors the signal with a "thinking" pip so engineers know the AI is still working. - Quiet-state hint when the lane is open (facts exist) but no open questions, checks, or active fix — keeps the surface from looking "finished" when the AI is about to follow up. - Keyboard shortcuts: ⌘↵/Ctrl+↵ send in the composer (plain Enter still sends), ⌘G toggles the Script Generator panel for the active fix, `?` opens a new ShortcutsHelpOverlay listing all bindings. ⌘K palette was already wired in TopBar. - Responsive: below 1200px the task lane collapses to a bottom drawer with a backdrop + a floating "Tasks ●" toggle button. TaskLane now takes a `variant: 'side' | 'drawer'` prop; drawer variant drops the resize handle and uses the shared slide-in-bottom animation. - Build hygiene: fixed a pre-existing TS error in confirm-post error handling (duplicate `response` type keys) and an unused-import warning in TemplatizePrompt. Verified: `npx tsc -b` and `npm run build` both clean against the dev stack; Vite HMR applied each change without errors. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
79 lines
2.5 KiB
TypeScript
79 lines
2.5 KiB
TypeScript
/**
|
|
* ShortcutsHelpOverlay — Phase 7 keyboard-shortcut reference modal.
|
|
*
|
|
* Opened by `?` from anywhere inside /pilot (the global useKeyboardShortcuts
|
|
* hook skips keypresses inside inputs, so `?` is safe from composer collisions).
|
|
*/
|
|
import { X } from 'lucide-react'
|
|
|
|
interface ShortcutsHelpOverlayProps {
|
|
open: boolean
|
|
onClose: () => void
|
|
}
|
|
|
|
interface Row {
|
|
keys: string[]
|
|
label: string
|
|
}
|
|
|
|
const ROWS: Row[] = [
|
|
{ keys: ['⌘', 'K'], label: 'Open command palette' },
|
|
{ keys: ['⌘', '↵'], label: 'Send the current message' },
|
|
{ keys: ['⌘', 'G'], label: 'Toggle Script Generator for the active fix' },
|
|
{ keys: ['?'], label: 'Show this shortcut reference' },
|
|
{ keys: ['Esc'], label: 'Close modal / cancel edit' },
|
|
]
|
|
|
|
export function ShortcutsHelpOverlay({ open, onClose }: ShortcutsHelpOverlayProps) {
|
|
if (!open) return null
|
|
return (
|
|
<div
|
|
className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4"
|
|
onClick={onClose}
|
|
role="dialog"
|
|
aria-modal="true"
|
|
aria-label="Keyboard shortcuts"
|
|
>
|
|
<div
|
|
className="relative w-full max-w-md rounded-xl border border-default bg-bg-page shadow-2xl"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<div className="flex items-center justify-between px-4 py-3 border-b border-default">
|
|
<h2 className="font-heading text-sm font-semibold text-heading">
|
|
Keyboard shortcuts
|
|
</h2>
|
|
<button
|
|
onClick={onClose}
|
|
className="p-1 rounded text-muted-foreground hover:text-heading hover:bg-elevated/40 transition-colors"
|
|
aria-label="Close shortcuts"
|
|
>
|
|
<X size={14} />
|
|
</button>
|
|
</div>
|
|
<div className="px-4 py-3 space-y-2">
|
|
{ROWS.map((row) => (
|
|
<div
|
|
key={row.label}
|
|
className="flex items-center justify-between gap-3 text-[0.8125rem]"
|
|
>
|
|
<span className="text-muted-foreground">{row.label}</span>
|
|
<span className="flex items-center gap-1">
|
|
{row.keys.map((k, i) => (
|
|
<kbd
|
|
key={i}
|
|
className="inline-flex items-center justify-center rounded border border-white/[0.06] bg-white/[0.08] px-1.5 py-0.5 text-[0.6875rem] font-mono text-heading min-w-[20px]"
|
|
>
|
|
{k}
|
|
</kbd>
|
|
))}
|
|
</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default ShortcutsHelpOverlay
|