UNPKG

@tanstack/hotkeys

Version:

Type-safe, framework-agnostic keyboard hotkey management for the browser

69 lines (67 loc) • 2.55 kB
import { isServerRuntime } from "./_server.js"; //#region src/platform.ts /** * Detects a platform from a user agent string, or from the browser's * `navigator` when called without one. * * Used internally to resolve platform-adaptive modifiers like 'Mod' (Command on Mac, * Control elsewhere) and for platform-specific hotkey formatting. During server * rendering, pass the request's `User-Agent` header to detect the user's * platform instead of the server's. * * @param userAgent - A user agent string, such as a request's `User-Agent` header. * When omitted or `null` (a missing header), reads `navigator`. * @returns The detected platform: 'mac', 'windows', or 'linux' * @remarks Without a user agent, returns 'linux' on a server runtime (no * `navigator`, or Node, Deno, Bun, or Cloudflare Workers), where `navigator` * describes the server. * * @example * ```ts * const platform = detectPlatform() // 'mac' | 'windows' | 'linux' * const modifier = resolveModifier('Mod', platform) // 'Meta' on Mac, 'Control' elsewhere * * // On the server * detectPlatform(request.headers.get('user-agent')) * ``` */ function detectPlatform(userAgent) { let platform = ""; let agent = userAgent; if (agent == null) { if (isServerRuntime()) return "linux"; platform = navigator.platform?.toLowerCase() ?? ""; agent = navigator.userAgent ?? ""; } agent = agent.toLowerCase(); if (platform.includes("mac") || agent.includes("mac")) return "mac"; if (platform.includes("win") || agent.includes("win")) return "windows"; return "linux"; } /** * Resolves the platform-adaptive 'Mod' modifier to the appropriate canonical modifier. * * The 'Mod' token represents the "primary modifier" on each platform: * - macOS: 'Meta' (Command key ⌘) * - Windows/Linux: 'Control' (Ctrl key) * * This enables cross-platform hotkey definitions like 'Mod+S' that automatically * map to Command+S on Mac and Ctrl+S on Windows/Linux. * * @param modifier - The modifier to resolve. If 'Mod', resolves based on platform. * @param platform - The target platform. Defaults to auto-detection. * @returns The canonical modifier name ('Control', 'Shift', 'Alt', or 'Meta') * * @example * ```ts * resolveModifier('Mod', 'mac') // 'Meta' * resolveModifier('Mod', 'windows') // 'Control' * resolveModifier('Control', 'mac') // 'Control' (unchanged) * ``` */ function resolveModifier(modifier, platform = detectPlatform()) { if (modifier === "Mod") return platform === "mac" ? "Meta" : "Control"; return modifier; } //#endregion export { detectPlatform, resolveModifier };