diff --git a/.changeset/silent-console-logging.md b/.changeset/silent-console-logging.md new file mode 100644 index 0000000..af2e8c3 --- /dev/null +++ b/.changeset/silent-console-logging.md @@ -0,0 +1,5 @@ +--- +'@tanstack/keys': patch +--- + +Add silent option to checkHotkey function to suppress console output in production diff --git a/docs/framework/react/reference/functions/useHotkeyRecorder.md b/docs/framework/react/reference/functions/useHotkeyRecorder.md index ec63d2a..28a9734 100644 --- a/docs/framework/react/reference/functions/useHotkeyRecorder.md +++ b/docs/framework/react/reference/functions/useHotkeyRecorder.md @@ -9,7 +9,7 @@ title: useHotkeyRecorder function useHotkeyRecorder(options): ReactHotkeyRecorder; ``` -Defined in: [useHotkeyRecorder.ts:60](https://github.com/TanStack/keys/blob/main/packages/react-keys/src/useHotkeyRecorder.ts#L60) +Defined in: [useHotkeyRecorder.ts:57](https://github.com/TanStack/keys/blob/main/packages/react-keys/src/useHotkeyRecorder.ts#L57) React hook for recording keyboard shortcuts. diff --git a/docs/framework/react/reference/interfaces/ReactHotkeyRecorder.md b/docs/framework/react/reference/interfaces/ReactHotkeyRecorder.md index 98fd1a1..9c6d2c2 100644 --- a/docs/framework/react/reference/interfaces/ReactHotkeyRecorder.md +++ b/docs/framework/react/reference/interfaces/ReactHotkeyRecorder.md @@ -5,7 +5,7 @@ title: ReactHotkeyRecorder # Interface: ReactHotkeyRecorder -Defined in: [useHotkeyRecorder.ts:9](https://github.com/TanStack/keys/blob/main/packages/react-keys/src/useHotkeyRecorder.ts#L9) +Defined in: [useHotkeyRecorder.ts:6](https://github.com/TanStack/keys/blob/main/packages/react-keys/src/useHotkeyRecorder.ts#L6) ## Properties @@ -15,7 +15,7 @@ Defined in: [useHotkeyRecorder.ts:9](https://github.com/TanStack/keys/blob/main/ cancelRecording: () => void; ``` -Defined in: [useHotkeyRecorder.ts:19](https://github.com/TanStack/keys/blob/main/packages/react-keys/src/useHotkeyRecorder.ts#L19) +Defined in: [useHotkeyRecorder.ts:16](https://github.com/TanStack/keys/blob/main/packages/react-keys/src/useHotkeyRecorder.ts#L16) Cancel recording without saving @@ -31,7 +31,7 @@ Cancel recording without saving isRecording: boolean; ``` -Defined in: [useHotkeyRecorder.ts:11](https://github.com/TanStack/keys/blob/main/packages/react-keys/src/useHotkeyRecorder.ts#L11) +Defined in: [useHotkeyRecorder.ts:8](https://github.com/TanStack/keys/blob/main/packages/react-keys/src/useHotkeyRecorder.ts#L8) Whether recording is currently active @@ -43,7 +43,7 @@ Whether recording is currently active recordedHotkey: Hotkey | null; ``` -Defined in: [useHotkeyRecorder.ts:13](https://github.com/TanStack/keys/blob/main/packages/react-keys/src/useHotkeyRecorder.ts#L13) +Defined in: [useHotkeyRecorder.ts:10](https://github.com/TanStack/keys/blob/main/packages/react-keys/src/useHotkeyRecorder.ts#L10) The currently recorded hotkey (for live preview) @@ -55,7 +55,7 @@ The currently recorded hotkey (for live preview) startRecording: () => void; ``` -Defined in: [useHotkeyRecorder.ts:15](https://github.com/TanStack/keys/blob/main/packages/react-keys/src/useHotkeyRecorder.ts#L15) +Defined in: [useHotkeyRecorder.ts:12](https://github.com/TanStack/keys/blob/main/packages/react-keys/src/useHotkeyRecorder.ts#L12) Start recording a new hotkey @@ -71,7 +71,7 @@ Start recording a new hotkey stopRecording: () => void; ``` -Defined in: [useHotkeyRecorder.ts:17](https://github.com/TanStack/keys/blob/main/packages/react-keys/src/useHotkeyRecorder.ts#L17) +Defined in: [useHotkeyRecorder.ts:14](https://github.com/TanStack/keys/blob/main/packages/react-keys/src/useHotkeyRecorder.ts#L14) Stop recording (same as cancel) diff --git a/docs/reference/classes/HotkeyManager.md b/docs/reference/classes/HotkeyManager.md index 1c774d4..d2c0da4 100644 --- a/docs/reference/classes/HotkeyManager.md +++ b/docs/reference/classes/HotkeyManager.md @@ -34,7 +34,7 @@ unregister() destroy(): void; ``` -Defined in: [manager.ts:526](https://github.com/TanStack/keys/blob/main/packages/keys/src/manager.ts#L526) +Defined in: [manager.ts:520](https://github.com/TanStack/keys/blob/main/packages/keys/src/manager.ts#L520) Destroys the manager and removes all listeners. @@ -50,7 +50,7 @@ Destroys the manager and removes all listeners. getRegistrationCount(): number; ``` -Defined in: [manager.ts:497](https://github.com/TanStack/keys/blob/main/packages/keys/src/manager.ts#L497) +Defined in: [manager.ts:491](https://github.com/TanStack/keys/blob/main/packages/keys/src/manager.ts#L491) Gets the number of registered hotkeys. @@ -66,7 +66,7 @@ Gets the number of registered hotkeys. isRegistered(hotkey, target?): boolean; ``` -Defined in: [manager.ts:508](https://github.com/TanStack/keys/blob/main/packages/keys/src/manager.ts#L508) +Defined in: [manager.ts:502](https://github.com/TanStack/keys/blob/main/packages/keys/src/manager.ts#L502) Checks if a specific hotkey is registered. @@ -101,7 +101,7 @@ register( options): HotkeyRegistrationHandle; ``` -Defined in: [manager.ts:122](https://github.com/TanStack/keys/blob/main/packages/keys/src/manager.ts#L122) +Defined in: [manager.ts:120](https://github.com/TanStack/keys/blob/main/packages/keys/src/manager.ts#L120) Registers a hotkey handler and returns a handle for updating the registration. @@ -157,7 +157,7 @@ handle.unregister() static getInstance(): HotkeyManager; ``` -Defined in: [manager.ts:80](https://github.com/TanStack/keys/blob/main/packages/keys/src/manager.ts#L80) +Defined in: [manager.ts:78](https://github.com/TanStack/keys/blob/main/packages/keys/src/manager.ts#L78) Gets the singleton instance of HotkeyManager. @@ -173,7 +173,7 @@ Gets the singleton instance of HotkeyManager. static resetInstance(): void; ``` -Defined in: [manager.ts:90](https://github.com/TanStack/keys/blob/main/packages/keys/src/manager.ts#L90) +Defined in: [manager.ts:88](https://github.com/TanStack/keys/blob/main/packages/keys/src/manager.ts#L88) Resets the singleton instance. Useful for testing. diff --git a/docs/reference/classes/HotkeyRecorder.md b/docs/reference/classes/HotkeyRecorder.md index 46447a3..cd2b406 100644 --- a/docs/reference/classes/HotkeyRecorder.md +++ b/docs/reference/classes/HotkeyRecorder.md @@ -87,7 +87,7 @@ Use this to subscribe to state changes or access current state. cancel(): void; ``` -Defined in: [recorder.ts:212](https://github.com/TanStack/keys/blob/main/packages/keys/src/recorder.ts#L212) +Defined in: [recorder.ts:214](https://github.com/TanStack/keys/blob/main/packages/keys/src/recorder.ts#L214) Cancel recording without saving. @@ -106,7 +106,7 @@ the onCancel callback if provided. destroy(): void; ``` -Defined in: [recorder.ts:257](https://github.com/TanStack/keys/blob/main/packages/keys/src/recorder.ts#L257) +Defined in: [recorder.ts:259](https://github.com/TanStack/keys/blob/main/packages/keys/src/recorder.ts#L259) Clean up event listeners and reset state. @@ -168,7 +168,7 @@ a valid hotkey is recorded, Escape is pressed, or stop/cancel is called. stop(): void; ``` -Defined in: [recorder.ts:192](https://github.com/TanStack/keys/blob/main/packages/keys/src/recorder.ts#L192) +Defined in: [recorder.ts:194](https://github.com/TanStack/keys/blob/main/packages/keys/src/recorder.ts#L194) Stop recording (same as cancel, but doesn't call onCancel). diff --git a/docs/reference/functions/getHotkeyManager.md b/docs/reference/functions/getHotkeyManager.md index 9feff2a..c830f7a 100644 --- a/docs/reference/functions/getHotkeyManager.md +++ b/docs/reference/functions/getHotkeyManager.md @@ -9,7 +9,7 @@ title: getHotkeyManager function getHotkeyManager(): HotkeyManager; ``` -Defined in: [manager.ts:542](https://github.com/TanStack/keys/blob/main/packages/keys/src/manager.ts#L542) +Defined in: [manager.ts:536](https://github.com/TanStack/keys/blob/main/packages/keys/src/manager.ts#L536) Gets the singleton HotkeyManager instance. Convenience function for accessing the manager. diff --git a/packages/keys/src/recorder.ts b/packages/keys/src/recorder.ts index 99ee1f0..06762ce 100644 --- a/packages/keys/src/recorder.ts +++ b/packages/keys/src/recorder.ts @@ -163,7 +163,9 @@ export class HotkeyRecorder { // Validate: must have at least one non-modifier key if (hasNonModifierKey(finalHotkey, this.#platform)) { // Remove listener FIRST to prevent any additional events - const handlerToRemove = this.#keydownHandler as ((event: KeyboardEvent) => void) | null + const handlerToRemove = this.#keydownHandler as + | ((event: KeyboardEvent) => void) + | null if (handlerToRemove) { this.#removeListener(handlerToRemove) this.#keydownHandler = null diff --git a/packages/keys/src/validate.ts b/packages/keys/src/validate.ts index b982fcc..8432cff 100644 --- a/packages/keys/src/validate.ts +++ b/packages/keys/src/validate.ts @@ -202,6 +202,8 @@ export function assertValidHotkey(hotkey: Hotkey | (string & {})): void { * Useful for development-time feedback. * * @param hotkey - The hotkey string to validate + * @param options - Optional configuration + * @param options.silent - If true, suppresses console output (default: false) * @returns True if the hotkey is valid (may still have warnings) * * @example @@ -209,17 +211,26 @@ export function assertValidHotkey(hotkey: Hotkey | (string & {})): void { * checkHotkey('Alt+C') * // Console: Warning: Alt+C may not work reliably on macOS... * // Returns: true + * + * checkHotkey('Alt+C', { silent: true }) + * // No console output + * // Returns: true * ``` */ -export function checkHotkey(hotkey: Hotkey | (string & {})): boolean { +export function checkHotkey( + hotkey: Hotkey | (string & {}), + options?: { silent?: boolean }, +): boolean { const result = validateHotkey(hotkey) - if (result.errors.length > 0) { - console.error(`Hotkey '${hotkey}' errors:`, result.errors.join('; ')) - } + if (!options?.silent) { + if (result.errors.length > 0) { + console.error(`Hotkey '${hotkey}' errors:`, result.errors.join('; ')) + } - if (result.warnings.length > 0) { - console.warn(`Hotkey '${hotkey}' warnings:`, result.warnings.join('; ')) + if (result.warnings.length > 0) { + console.warn(`Hotkey '${hotkey}' warnings:`, result.warnings.join('; ')) + } } return result.valid diff --git a/packages/keys/tests/validate.test.ts b/packages/keys/tests/validate.test.ts index 3f38e56..ea71942 100644 --- a/packages/keys/tests/validate.test.ts +++ b/packages/keys/tests/validate.test.ts @@ -145,4 +145,29 @@ describe('checkHotkey', () => { errorSpy.mockRestore() }) + + it('should not log warnings when silent option is true', () => { + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}) + + checkHotkey('Alt+C', { silent: true }) + + expect(warnSpy).not.toHaveBeenCalled() + + warnSpy.mockRestore() + }) + + it('should not log errors when silent option is true', () => { + const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}) + + checkHotkey('', { silent: true }) + + expect(errorSpy).not.toHaveBeenCalled() + + errorSpy.mockRestore() + }) + + it('should still return correct validation result when silent', () => { + expect(checkHotkey('Control+A', { silent: true })).toBe(true) + expect(checkHotkey('', { silent: true })).toBe(false) + }) }) diff --git a/packages/react-keys/src/useHotkeyRecorder.ts b/packages/react-keys/src/useHotkeyRecorder.ts index 4307f1d..4beaaf9 100644 --- a/packages/react-keys/src/useHotkeyRecorder.ts +++ b/packages/react-keys/src/useHotkeyRecorder.ts @@ -1,11 +1,7 @@ import { useEffect, useRef } from 'react' import { useStore } from '@tanstack/react-store' -import { - - HotkeyRecorder - -} from '@tanstack/keys' -import type {Hotkey, HotkeyRecorderOptions} from '@tanstack/keys'; +import { HotkeyRecorder } from '@tanstack/keys' +import type { Hotkey, HotkeyRecorderOptions } from '@tanstack/keys' export interface ReactHotkeyRecorder { /** Whether recording is currently active */