From 622901821ec986fa975846eb8fa4cd00aa2a2d40 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Tue, 18 Jun 2024 10:19:53 -0700 Subject: [PATCH] Fix keyboard shortcut. Add isShortcutEnabled and buttonLabel props. (#72) --- docs/package-lock.json | 2 +- docs/src/components/ConfigurationDrawer.tsx | 30 +++++++++++++++++++++ docs/src/index.tsx | 23 ++++++++++++++++ package-lock.json | 4 +-- src/index.tsx | 22 +++++++++++++-- src/types.ts | 6 +++++ 6 files changed, 82 insertions(+), 5 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 8ed4196..d06484b 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -14,7 +14,7 @@ }, "..": { "name": "@vectara/react-search", - "version": "1.0.3", + "version": "1.1.0", "license": "Apache-2.0", "dependencies": { "@testing-library/react-hooks": "^8.0.1", diff --git a/docs/src/components/ConfigurationDrawer.tsx b/docs/src/components/ConfigurationDrawer.tsx index 14eefc6..9dcca44 100644 --- a/docs/src/components/ConfigurationDrawer.tsx +++ b/docs/src/components/ConfigurationDrawer.tsx @@ -21,6 +21,10 @@ type Props = { setCustomerId: (customerId: string) => void; apiKey: string; setApiKey: (apiKey: string) => void; + isShortcutEnabled: boolean; + setIsShortcutEnabled: (isShortcutEnabled: boolean) => void; + buttonLabel: string; + setButtonLabel: (buttonLabel: string) => void; placeholder: string; setPlaceholder: (placeholder: string) => void; isDeepLinkable: boolean; @@ -46,6 +50,10 @@ export const ConfigurationDrawer = ({ setCustomerId, apiKey, setApiKey, + isShortcutEnabled, + setIsShortcutEnabled, + buttonLabel, + setButtonLabel, placeholder, setPlaceholder, isDeepLinkable, @@ -112,6 +120,28 @@ export const ConfigurationDrawer = ({ + +

Search button

+
+ + + + + setIsShortcutEnabled(e.target.checked)} + id="isKeyboardShortcutEnabled" + /> + + + + + + setButtonLabel(e.target.value)} fullWidth /> + + + +

Search input

diff --git a/docs/src/index.tsx b/docs/src/index.tsx index 840776c..25818f7 100644 --- a/docs/src/index.tsx +++ b/docs/src/index.tsx @@ -27,6 +27,8 @@ const generateCodeSnippet = ({ customerId, corpusId, apiKey, + isShortcutEnabled, + buttonLabel, placeholder, isDeepLinkable = false, openResultsInNewTab = false, @@ -38,6 +40,8 @@ const generateCodeSnippet = ({ customerId?: string; corpusId?: string; apiKey?: string; + isShortcutEnabled?: boolean; + buttonLabel?: string; placeholder?: string; isDeepLinkable: boolean; openResultsInNewTab: boolean; @@ -62,6 +66,15 @@ const generateCodeSnippet = ({ `apiKey="${apiKey === "" ? "" : apiKey}"` ]; + // True is the default so only show it if it's false. + if (!isShortcutEnabled) { + props.push(`isShortcutEnabled={${isShortcutEnabled}}`); + } + + if (buttonLabel) { + props.push(`buttonLabel="${buttonLabel}"`); + } + if (placeholder) { props.push(`placeholder=${quotedPlaceholder}`); } @@ -113,6 +126,8 @@ const App = () => { const [corpusId, setCorpusId] = useState(""); const [customerId, setCustomerId] = useState(""); const [apiKey, setApiKey] = useState(""); + const [isShortcutEnabled, setIsShortcutEnabled] = useState(true); + const [buttonLabel, setButtonLabel] = useState("Search"); const [placeholder, setPlaceholder] = useState(DEFAULT_PLACEHOLDER); const [isDeepLinkable, setIsDeepLinkable] = useState(false); const [openResultsInNewTab, setOpenResultsInNewTab] = useState(false); @@ -190,6 +205,8 @@ const App = () => { corpusId={corpusId === "" ? DEFAULT_CORPUS_ID : corpusId} customerId={customerId === "" ? DEFAULT_CUSTOMER_ID : customerId} apiKey={apiKey === "" ? DEFAULT_API_KEY : apiKey} + isShortcutEnabled={isShortcutEnabled} + buttonLabel={buttonLabel} placeholder={placeholder} isDeepLinkable={isDeepLinkable} openResultsInNewTab={openResultsInNewTab} @@ -236,6 +253,8 @@ const App = () => { customerId, corpusId, apiKey, + isShortcutEnabled, + buttonLabel, placeholder, isDeepLinkable, openResultsInNewTab, @@ -310,6 +329,10 @@ export const App = () => { setCustomerId={setCustomerId} apiKey={apiKey} setApiKey={setApiKey} + isShortcutEnabled={isShortcutEnabled} + setIsShortcutEnabled={setIsShortcutEnabled} + buttonLabel={buttonLabel} + setButtonLabel={setButtonLabel} placeholder={placeholder} setPlaceholder={setPlaceholder} isDeepLinkable={isDeepLinkable} diff --git a/package-lock.json b/package-lock.json index e7e316a..ca8ca31 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@vectara/react-search", - "version": "1.0.3", + "version": "1.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@vectara/react-search", - "version": "1.0.3", + "version": "1.1.0", "license": "Apache-2.0", "dependencies": { "@testing-library/react-hooks": "^8.0.1", diff --git a/src/index.tsx b/src/index.tsx index 5581df7..bc2f5ee 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -38,6 +38,8 @@ const ReactSearchInternal = ({ corpusId, apiUrl, historySize = 10, + isShortcutEnabled = true, + buttonLabel = "Search", placeholder = "Search", isDeepLinkable = false, openResultsInNewTab = false, @@ -68,6 +70,22 @@ const ReactSearchInternal = ({ const selectedResultRef = useRef(null); const searchCount = useRef(0); + useEffect(() => { + const onDocumentKeyDown = ({ key, metaKey }: KeyboardEvent) => { + if (metaKey && key === "k") { + setIsOpen(true); + } + }; + + if (isShortcutEnabled) { + document.addEventListener("keydown", onDocumentKeyDown); + } + + return () => { + document.removeEventListener("keydown", onDocumentKeyDown); + }; + }, [isShortcutEnabled]); + useEffect(() => { setIsSummaryEnabled(isSummaryToggleInitiallyEnabled); }, [isSummaryToggleInitiallyEnabled]); @@ -250,13 +268,13 @@ const ReactSearchInternal = ({ -
Search
+
{buttonLabel}
-
Ctrl + K
+ {isShortcutEnabled &&
Ctrl + K
} diff --git a/src/types.ts b/src/types.ts index 69f0381..ca1d3cc 100644 --- a/src/types.ts +++ b/src/types.ts @@ -15,6 +15,12 @@ export interface Props { // Default is 0. historySize?: number; + // Whether users can use the keyboard shortcut to open the search modal. Defaults to true. + isShortcutEnabled?: boolean; + + // The label on the button that opens the search modal. + buttonLabel?: string; + // The search input placeholder. placeholder?: string;