From 5be3e846a9df0c4aabfd47dd7c4ef3f7860885f0 Mon Sep 17 00:00:00 2001 From: Greg Brimble Date: Thu, 4 Sep 2025 09:05:08 -0400 Subject: [PATCH] Add keyboardShortcuts property to allow users to customize shortcuts (#2740) Co-authored-by: Paul Jankowski <33367713+8bittitan@users.noreply.github.com> --- packages/docsearch-react/src/DocSearch.tsx | 20 ++- .../docsearch-react/src/DocSearchButton.tsx | 15 +- .../src/__tests__/keyboardShortcuts.test.tsx | 152 ++++++++++++++++++ .../src/constants/keyboardShortcuts.ts | 24 +++ .../src/types/KeyboardShortcuts.ts | 14 ++ packages/docsearch-react/src/types/index.ts | 1 + .../src/useDocSearchKeyboardEvents.ts | 17 +- packages/website/docs/api.mdx | 91 +++++++++++ 8 files changed, 324 insertions(+), 10 deletions(-) create mode 100644 packages/docsearch-react/src/__tests__/keyboardShortcuts.test.tsx create mode 100644 packages/docsearch-react/src/constants/keyboardShortcuts.ts create mode 100644 packages/docsearch-react/src/types/KeyboardShortcuts.ts diff --git a/packages/docsearch-react/src/DocSearch.tsx b/packages/docsearch-react/src/DocSearch.tsx index 1c5a292b..a9f09c42 100644 --- a/packages/docsearch-react/src/DocSearch.tsx +++ b/packages/docsearch-react/src/DocSearch.tsx @@ -5,7 +5,13 @@ import { createPortal } from 'react-dom'; import { DocSearchButton } from './DocSearchButton'; import { DocSearchModal } from './DocSearchModal'; -import type { DocSearchHit, DocSearchTheme, InternalDocSearchHit, StoredDocSearchHit } from './types'; +import type { + DocSearchHit, + DocSearchTheme, + InternalDocSearchHit, + KeyboardShortcuts, + StoredDocSearchHit, +} from './types'; import { useDocSearchKeyboardEvents } from './useDocSearchKeyboardEvents'; import { useTheme } from './useTheme'; @@ -155,6 +161,10 @@ export interface DocSearchProps { * @default 4 */ recentSearchesWithFavoritesLimit?: number; + /** + * Configuration for keyboard shortcuts. Allows enabling/disabling specific shortcuts. + */ + keyboardShortcuts?: KeyboardShortcuts; } export function DocSearch({ indexName, searchParameters, indices = [], ...props }: DocSearchProps): JSX.Element { @@ -212,6 +222,7 @@ export function DocSearch({ indexName, searchParameters, indices = [], ...props isAskAiActive, onAskAiToggle, searchButtonRef, + keyboardShortcuts: props.keyboardShortcuts, }); useTheme({ theme: props.theme }); @@ -237,7 +248,12 @@ export function DocSearch({ indexName, searchParameters, indices = [], ...props return ( <> - + {isOpen && createPortal( diff --git a/packages/docsearch-react/src/DocSearchButton.tsx b/packages/docsearch-react/src/DocSearchButton.tsx index d155da40..fc1096e6 100644 --- a/packages/docsearch-react/src/DocSearchButton.tsx +++ b/packages/docsearch-react/src/DocSearchButton.tsx @@ -1,8 +1,9 @@ import React, { useEffect, useState, type JSX } from 'react'; +import { getKeyboardShortcuts } from './constants/keyboardShortcuts'; import { ControlKeyIcon, KKeyIcon, MetaKeyIcon } from './icons/MetaKeysIcon'; import { SearchIcon } from './icons/SearchIcon'; -import type { DocSearchTheme } from './types'; +import type { DocSearchTheme, KeyboardShortcuts } from './types'; import { useTheme } from './useTheme'; export type ButtonTranslations = Partial<{ @@ -13,6 +14,7 @@ export type ButtonTranslations = Partial<{ export type DocSearchButtonProps = React.ComponentProps<'button'> & { theme?: DocSearchTheme; translations?: ButtonTranslations; + keyboardShortcuts?: KeyboardShortcuts; }; const ACTION_KEY_DEFAULT = 'Ctrl' as const; @@ -23,8 +25,9 @@ function isAppleDevice(): boolean { } export const DocSearchButton = React.forwardRef( - ({ translations = {}, ...props }, ref) => { + ({ translations = {}, keyboardShortcuts, ...props }, ref) => { const { buttonText = 'Search', buttonAriaLabel = 'Search' } = translations; + const resolvedShortcuts = getKeyboardShortcuts(keyboardShortcuts); const [key, setKey] = useState(null); useTheme({ theme: props.theme }); @@ -41,13 +44,15 @@ export const DocSearchButton = React.forwardRef] as const); + const isCtrlCmdKEnabled = resolvedShortcuts['Ctrl/Cmd+K']; const shortcut = `${actionKeyAltText}+k`; + return (