UNPKG

@primer/react

Version:

An implementation of GitHub's Primer Design System using React

53 lines (52 loc) 2.24 kB
import { createContext, useContext, useSyncExternalStore } from "react"; import { isMacOS } from "@primer/behaviors/utils"; //#region src/KeybindingHint/platform.ts /** * The platform categories that affect how keyboard shortcut keys are displayed. * * - `apple`: Apple platforms (macOS and iOS/iPadOS), which use the Command and Option keys. * - `windows`: Windows, which uses the Windows (Meta) key. * - `other`: Any other platform (e.g. Linux, Android), where the Meta key does not map to a * consistent label. */ const subscribe = () => () => {}; /** SSR-unsafe detection of iOS/iPadOS (in addition to macOS, which is detected separately). */ const ssrUnsafeIsIOS = () => { if (typeof navigator === "undefined") return false; return /iphone|ipad|ipod/i.test(navigator.platform) || /iphone|ipad|ipod/i.test(navigator.userAgent); }; /** SSR-unsafe detection of Windows. */ const ssrUnsafeIsWindows = () => { if (typeof navigator === "undefined") return false; return /^win/i.test(navigator.platform); }; const getSnapshot = () => { if (isMacOS() || ssrUnsafeIsIOS()) return "apple"; if (ssrUnsafeIsWindows()) return "windows"; return "other"; }; const getServerSnapshot = () => "other"; /** * Allows overriding the detected platform. This is primarily intended for testing and * Storybook, where we want to preview how keyboard hints render on platforms other than the * one actually running. A `null` value (the default) means "use the detected platform". */ const PlatformOverrideContext = /*#__PURE__*/ createContext(null); PlatformOverrideContext.Provider; /** * SSR-safe hook for determining the current platform category used when displaying * keyboard shortcut keys. * * Mirrors the approach of `useIsMacOS`: on the client it reads the real value immediately, * and on the server it returns a safe default (`'other'`). * * If a `PlatformOverrideProvider` is present with a non-null value, that value is used * instead of the detected platform. */ function usePlatform() { const override = useContext(PlatformOverrideContext); const detected = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); return override !== null && override !== void 0 ? override : detected; } //#endregion export { usePlatform };