refactor: shortcuts help

This commit is contained in:
Maze Winther 2025-08-15 22:34:04 +02:00
parent 32d263fccc
commit aa5cd1edca
1 changed files with 90 additions and 96 deletions

View File

@ -19,96 +19,7 @@ import {
DialogTrigger,
} from "./ui/dialog";
const ShortcutItem = ({
shortcut,
isRecording,
onStartRecording,
}: {
shortcut: KeyboardShortcut;
isRecording: boolean;
onStartRecording: (shortcut: KeyboardShortcut) => void;
}) => {
// Filter out lowercase duplicates for display - if both "j" and "J" exist, only show "J"
const displayKeys = shortcut.keys.filter((key: string) => {
if (
key.includes("Cmd") &&
shortcut.keys.includes(key.replace("Cmd", "Ctrl"))
)
return false;
return true;
});
return (
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
{shortcut.icon && (
<div className="text-muted-foreground">{shortcut.icon}</div>
)}
<span className="text-sm">{shortcut.description}</span>
</div>
<div className="flex items-center gap-1">
{displayKeys.map((key: string, index: number) => (
<div key={key} className="flex items-center gap-1">
<div className="flex items-center">
{key.split("+").map((keyPart: string, partIndex: number) => {
const keyId = `${shortcut.id}-${index}-${partIndex}`;
return (
<EditableShortcutKey
key={keyId}
isRecording={isRecording}
onStartRecording={() => onStartRecording(shortcut)}
>
{keyPart}
</EditableShortcutKey>
);
})}
</div>
{index < displayKeys.length - 1 && (
<span className="text-xs text-muted-foreground">or</span>
)}
</div>
))}
</div>
</div>
);
};
const EditableShortcutKey = ({
children,
isRecording,
onStartRecording,
}: {
children: React.ReactNode;
isRecording: boolean;
onStartRecording: () => void;
}) => {
const handleClick = (e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
onStartRecording();
};
return (
<Button
variant="text"
size="sm"
className={`inline-flex font-sans text-xs rounded px-2 min-w-6 min-h-6 leading-none items-center justify-center shadow-xs border mr-1 cursor-pointer hover:bg-opacity-80 ${
isRecording
? "border-primary bg-primary/10"
: "border bg-accent"
}`}
onClick={handleClick}
title={
isRecording ? "Press any key combination..." : "Click to edit shortcut"
}
>
{children}
</Button>
);
};
export const KeyboardShortcutsHelp = () => {
export function KeyboardShortcutsHelp() {
const [open, setOpen] = useState(false);
const [recordingShortcut, setRecordingShortcut] =
useState<KeyboardShortcut | null>(null);
@ -237,15 +148,98 @@ export const KeyboardShortcutsHelp = () => {
</div>
</div>
<DialogFooter className="flex-shrink-0 p-6 pt-4">
<Button
size="sm"
variant="destructive"
onClick={resetToDefaults}
>
<Button size="sm" variant="destructive" onClick={resetToDefaults}>
Reset to Default
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
};
}
function ShortcutItem({
shortcut,
isRecording,
onStartRecording,
}: {
shortcut: KeyboardShortcut;
isRecording: boolean;
onStartRecording: (shortcut: KeyboardShortcut) => void;
}) {
// Filter out lowercase duplicates for display - if both "j" and "J" exist, only show "J"
const displayKeys = shortcut.keys.filter((key: string) => {
if (
key.includes("Cmd") &&
shortcut.keys.includes(key.replace("Cmd", "Ctrl"))
)
return false;
return true;
});
return (
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
{shortcut.icon && (
<div className="text-muted-foreground">{shortcut.icon}</div>
)}
<span className="text-sm">{shortcut.description}</span>
</div>
<div className="flex items-center gap-1">
{displayKeys.map((key: string, index: number) => (
<div key={key} className="flex items-center gap-1">
<div className="flex items-center">
{key.split("+").map((keyPart: string, partIndex: number) => {
const keyId = `${shortcut.id}-${index}-${partIndex}`;
return (
<EditableShortcutKey
key={keyId}
isRecording={isRecording}
onStartRecording={() => onStartRecording(shortcut)}
>
{keyPart}
</EditableShortcutKey>
);
})}
</div>
{index < displayKeys.length - 1 && (
<span className="text-xs text-muted-foreground">or</span>
)}
</div>
))}
</div>
</div>
);
}
function EditableShortcutKey({
children,
isRecording,
onStartRecording,
}: {
children: React.ReactNode;
isRecording: boolean;
onStartRecording: () => void;
}) {
const handleClick = (e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
onStartRecording();
};
return (
<Button
variant="text"
size="sm"
className={`inline-flex font-sans text-xs rounded px-2 min-w-6 min-h-6 leading-none items-center justify-center shadow-xs border mr-1 cursor-pointer hover:bg-opacity-80 ${
isRecording ? "border-primary bg-primary/10" : "border bg-accent"
}`}
onClick={handleClick}
title={
isRecording ? "Press any key combination..." : "Click to edit shortcut"
}
>
{children}
</Button>
);
}