mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-04 21:04:37 +08:00
Replace Cmd with Ctrl on Windows computers
This commit is contained in:
parent
1de8a17183
commit
22ae47fe73
@ -5,6 +5,7 @@ import { FormDialog } from "@/components/form-dialog";
|
||||
import { InputField } from "@/components/form-fields";
|
||||
import { useRouter } from "@/components/router";
|
||||
import { ActionDialog, Button, Typography } from "@/components/ui";
|
||||
import { getShortcutModifierKeyLabel } from "@/lib/keyboard-shortcuts";
|
||||
import { useUpdateConfig } from "@/lib/config-update";
|
||||
import {
|
||||
ChartBarIcon,
|
||||
@ -28,6 +29,7 @@ export default function PageClient() {
|
||||
const adminApp = useAdminApp();
|
||||
const project = adminApp.useProject();
|
||||
const config = project.useConfig();
|
||||
const modifierKeyLabel = getShortcutModifierKeyLabel();
|
||||
const updateConfig = useUpdateConfig();
|
||||
const router = useRouter();
|
||||
const [deleteDialogId, setDeleteDialogId] = useState<string | null>(null);
|
||||
@ -77,7 +79,9 @@ export default function PageClient() {
|
||||
<div>
|
||||
<Typography className="font-semibold text-foreground">No dashboards yet</Typography>
|
||||
<Typography variant="secondary" className="text-sm mt-1">
|
||||
Create a dashboard from the command palette (⌘ K) or click "New Dashboard" above.
|
||||
Create a dashboard from the command palette (
|
||||
<span suppressHydrationWarning>{modifierKeyLabel} K</span>
|
||||
) or click "New Dashboard" above.
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
import Editor from "@monaco-editor/react";
|
||||
import type { Monaco } from "@monaco-editor/react";
|
||||
import React, { useEffect, useMemo, useRef } from "react";
|
||||
import { getShortcutModifierKeyLabel } from "@/lib/keyboard-shortcuts";
|
||||
import { Alert, Button, Textarea, Typography } from "@/components/ui";
|
||||
import { PageLayout } from "../page-layout";
|
||||
import { useAdminApp } from "../use-admin-app";
|
||||
@ -21,6 +22,7 @@ type CompletionItem = Parameters<Monaco["languages"]["registerCompletionItemProv
|
||||
|
||||
export default function PageClient() {
|
||||
const adminApp = useAdminApp();
|
||||
const modifierKeyLabel = getShortcutModifierKeyLabel();
|
||||
const [query, setQuery] = React.useState("SELECT 1 AS value;");
|
||||
const [resultText, setResultText] = React.useState("");
|
||||
const [error, setError] = React.useState<string | null>(null);
|
||||
@ -168,7 +170,7 @@ export default function PageClient() {
|
||||
loading={loading}
|
||||
disabled={loading || !queryRef.current.trim()}
|
||||
>
|
||||
Run query (⌘ + enter)
|
||||
Run query (<span suppressHydrationWarning>{modifierKeyLabel}</span> + enter)
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useRouter } from "@/components/router";
|
||||
import { getShortcutModifierKeyLabel } from "@/lib/keyboard-shortcuts";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
LayoutIcon,
|
||||
@ -118,6 +119,8 @@ const CyclingPlaceholder = memo(function CyclingPlaceholder({
|
||||
}: {
|
||||
onSelectQuery?: (query: string) => void,
|
||||
}) {
|
||||
const modifierKeyLabel = getShortcutModifierKeyLabel();
|
||||
|
||||
return (
|
||||
<div className="h-full flex flex-col items-center select-none px-6">
|
||||
{/* Top spacer */}
|
||||
@ -149,7 +152,9 @@ const CyclingPlaceholder = memo(function CyclingPlaceholder({
|
||||
<div className="relative text-center mb-4">
|
||||
{/* Keybind reminder - like tape on the corner */}
|
||||
<span className="absolute -top-4 -right-8 rotate-[30deg] flex items-center gap-0.5 text-[10px] text-muted-foreground/40">
|
||||
<kbd className="px-1.5 py-0.5 rounded bg-foreground/[0.06] font-mono">⌘</kbd>
|
||||
<kbd suppressHydrationWarning className="px-1.5 py-0.5 rounded bg-foreground/[0.06] font-mono">
|
||||
{modifierKeyLabel}
|
||||
</kbd>
|
||||
+
|
||||
<kbd className="px-1.5 py-0.5 rounded bg-foreground/[0.06] font-mono">K</kbd>
|
||||
</span>
|
||||
@ -204,7 +209,9 @@ const CyclingPlaceholder = memo(function CyclingPlaceholder({
|
||||
{/* Keyboard hints footer */}
|
||||
<div className="py-3 border-t border-foreground/[0.06] w-full flex items-center justify-center gap-5 text-[10px] text-muted-foreground/40">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<kbd className="px-1.5 py-0.5 rounded bg-foreground/[0.06] font-mono">⌘</kbd>
|
||||
<kbd suppressHydrationWarning className="px-1.5 py-0.5 rounded bg-foreground/[0.06] font-mono">
|
||||
{modifierKeyLabel}
|
||||
</kbd>
|
||||
+
|
||||
<kbd className="px-1.5 py-0.5 rounded bg-foreground/[0.06] font-mono">K</kbd>
|
||||
<span>open</span>
|
||||
@ -999,6 +1006,7 @@ export function CmdKSearch({
|
||||
export function CmdKTrigger() {
|
||||
const mouseCursorRef = useRef<HTMLDivElement>(null);
|
||||
const mouseCursorParentRef = useRef<HTMLDivElement>(null);
|
||||
const modifierKeyLabel = getShortcutModifierKeyLabel();
|
||||
|
||||
useEffect(() => {
|
||||
const handleMouseMove = (e: MouseEvent) => {
|
||||
@ -1058,8 +1066,11 @@ export function CmdKTrigger() {
|
||||
Control Center
|
||||
</span>
|
||||
<div className="pointer-events-none flex items-center gap-1">
|
||||
<kbd className="flex h-5 min-w-[20px] select-none items-center justify-center rounded-md bg-foreground/[0.04] ring-1 ring-inset ring-foreground/[0.06] px-1.5 font-mono text-[10px] font-medium text-muted-foreground/50 group-hover:text-muted-foreground/70 transition-colors duration-300 group-hover:transition-none">
|
||||
⌘
|
||||
<kbd
|
||||
suppressHydrationWarning
|
||||
className="flex h-5 min-w-[20px] select-none items-center justify-center rounded-md bg-foreground/[0.04] ring-1 ring-inset ring-foreground/[0.06] px-1.5 font-mono text-[10px] font-medium text-muted-foreground/50 group-hover:text-muted-foreground/70 transition-colors duration-300 group-hover:transition-none"
|
||||
>
|
||||
{modifierKeyLabel}
|
||||
</kbd>
|
||||
<kbd className="flex h-5 min-w-[20px] select-none items-center justify-center rounded-md bg-foreground/[0.04] ring-1 ring-inset ring-foreground/[0.06] px-1.5 font-mono text-[10px] font-medium text-muted-foreground/50 group-hover:text-muted-foreground/70 transition-colors duration-300 group-hover:transition-none">
|
||||
K
|
||||
|
||||
19
apps/dashboard/src/lib/keyboard-shortcuts.ts
Normal file
19
apps/dashboard/src/lib/keyboard-shortcuts.ts
Normal file
@ -0,0 +1,19 @@
|
||||
export function getShortcutModifierKeyLabel() {
|
||||
if (typeof navigator === "undefined") {
|
||||
return "⌘";
|
||||
}
|
||||
|
||||
const platform = navigator.platform;
|
||||
const userAgent = navigator.userAgent;
|
||||
const isAppleDevice =
|
||||
platform.startsWith("Mac") ||
|
||||
platform === "iPhone" ||
|
||||
platform === "iPad" ||
|
||||
platform === "iPod" ||
|
||||
userAgent.includes("Macintosh") ||
|
||||
userAgent.includes("iPhone") ||
|
||||
userAgent.includes("iPad") ||
|
||||
userAgent.includes("iPod");
|
||||
|
||||
return isAppleDevice ? "⌘" : "Ctrl";
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user