chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
import { KeyboardDownIcon } from "~/assets/icons/KeyboardDownIcon";
|
||||
import { KeyboardLeftIcon } from "~/assets/icons/KeyboardLeftIcon";
|
||||
import { KeyboardRightIcon } from "~/assets/icons/KeyboardRightIcon";
|
||||
import { KeyboardUpIcon } from "~/assets/icons/KeyboardUpIcon";
|
||||
import { KeyboardWindowsIcon } from "~/assets/icons/KeyboardWindowsIcon";
|
||||
import { type Modifier, type Shortcut } from "~/hooks/useShortcutKeys";
|
||||
import { cn } from "~/utils/cn";
|
||||
import { useOperatingSystem } from "./OperatingSystemProvider";
|
||||
import { KeyboardEnterIcon } from "~/assets/icons/KeyboardEnterIcon";
|
||||
|
||||
const small =
|
||||
"justify-center text-[0.6rem] font-mono font-medium min-w-4 min-h-4 rounded-[2px] tabular-nums px-1 ml-1 -mr-0.5 flex items-center gap-x-1 border transition uppercase";
|
||||
|
||||
const medium =
|
||||
"justify-center min-w-5 min-h-5 text-[0.65rem] font-mono font-medium rounded-[2px] tabular-nums px-1 ml-1 -mr-0.5 flex items-center gap-x-1.5 border border-dimmed/40 text-text-dimmed group-hover:text-text-bright/80 group-hover:border-dimmed/60 transition uppercase";
|
||||
|
||||
export const variants = {
|
||||
small: cn(
|
||||
small,
|
||||
"border-text-dimmed/40 text-text-dimmed group-hover:text-text-bright/80 group-hover:border-text-dimmed/60"
|
||||
),
|
||||
"small/bright": cn(small, "bg-background-hover text-text-bright border-border-bright"),
|
||||
medium: cn(medium, "group-hover:border-border-brighter"),
|
||||
"medium/bright": cn(medium, "bg-background-hover text-text-bright border-border-bright"),
|
||||
};
|
||||
|
||||
export type ShortcutKeyVariant = keyof typeof variants;
|
||||
|
||||
type ShortcutKey = Partial<Shortcut>;
|
||||
|
||||
type ShortcutKeyDefinition =
|
||||
| {
|
||||
windows: ShortcutKey;
|
||||
mac: ShortcutKey;
|
||||
}
|
||||
| ShortcutKey;
|
||||
|
||||
type ShortcutKeyProps = {
|
||||
shortcut: ShortcutKeyDefinition;
|
||||
variant: ShortcutKeyVariant;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export function ShortcutKey({ shortcut, variant, className }: ShortcutKeyProps) {
|
||||
const { platform } = useOperatingSystem();
|
||||
const isMac = platform === "mac";
|
||||
let relevantShortcut = "mac" in shortcut ? (isMac ? shortcut.mac : shortcut.windows) : shortcut;
|
||||
const modifiers = relevantShortcut.modifiers ?? [];
|
||||
const character = relevantShortcut.key ? keyString(relevantShortcut.key, isMac, variant) : null;
|
||||
|
||||
return (
|
||||
<span className={cn(variants[variant], className)}>
|
||||
{modifiers.map((k) => (
|
||||
<span key={k}>
|
||||
<span>{modifierString(k, isMac, variant)}</span>
|
||||
</span>
|
||||
))}
|
||||
{character && <span>{character}</span>}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function keyString(key: string, isMac: boolean, variant: ShortcutKeyVariant) {
|
||||
key = key.toLowerCase();
|
||||
|
||||
const className = variant.startsWith("small") ? "w-2.5 h-4" : "w-2.5 h-4.5";
|
||||
|
||||
switch (key) {
|
||||
case "enter":
|
||||
return isMac ? (
|
||||
<KeyboardEnterIcon className={className} />
|
||||
) : (
|
||||
<span className="capitalize">Enter</span>
|
||||
);
|
||||
case "esc":
|
||||
return <span className="capitalize">Esc</span>;
|
||||
case "del":
|
||||
return <span className="capitalize">Del</span>;
|
||||
case "arrowdown":
|
||||
return <KeyboardDownIcon className={className} />;
|
||||
case "arrowup":
|
||||
return <KeyboardUpIcon className={className} />;
|
||||
case "arrowleft":
|
||||
return <KeyboardLeftIcon className={className} />;
|
||||
case "arrowright":
|
||||
return <KeyboardRightIcon className={className} />;
|
||||
default:
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
function modifierString(
|
||||
modifier: Modifier,
|
||||
isMac: boolean,
|
||||
variant: ShortcutKeyVariant
|
||||
): string | JSX.Element {
|
||||
const className = variant.startsWith("small") ? "w-2.5 h-4" : "w-3.5 h-5";
|
||||
|
||||
switch (modifier) {
|
||||
case "alt":
|
||||
return isMac ? "⌥" : <span className="capitalize">Alt</span>;
|
||||
case "ctrl":
|
||||
return isMac ? "⌃" : <span className="capitalize">Ctrl</span>;
|
||||
case "meta":
|
||||
return isMac ? "⌘" : <KeyboardWindowsIcon className={className} />;
|
||||
case "shift":
|
||||
return "⇧";
|
||||
case "mod":
|
||||
return isMac ? "⌘" : <span className="capitalize">Ctrl</span>;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user