From c7794d9a1f3c91c9ff55a2fbdff5c99e3608c612 Mon Sep 17 00:00:00 2001 From: Steve Smith Date: Fri, 13 Mar 2026 00:13:53 +0000 Subject: [PATCH] feat: add onEmpty callback to Command Event handler called when the search query produces no results. Useful for analytics, triggering AI fallback, or capturing unmet user intent. --- README.md | 10 ++++++++++ cmdk/src/index.tsx | 11 +++++++++++ test/pages/props.tsx | 3 +++ test/props.test.ts | 13 +++++++++++++ 4 files changed, 37 insertions(+) diff --git a/README.md b/README.md index d1c98b0a..ff20ca6a 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,16 @@ A third argument, `keywords`, can also be provided to the filter function. Keywo /> ``` +You can listen for when a search query produces no results with `onEmpty`. Useful for analytics, triggering an AI fallback, or capturing unmet user intent: + +```tsx + { + console.log('No results for', search) + }} +/> +``` + Or disable filtering and sorting entirely: ```tsx diff --git a/cmdk/src/index.tsx b/cmdk/src/index.tsx index 3131c7b6..1ded37ed 100644 --- a/cmdk/src/index.tsx +++ b/cmdk/src/index.tsx @@ -118,6 +118,10 @@ type CommandProps = Children & * Set to `false` to disable ctrl+n/j/p/k shortcuts. Defaults to `true`. */ vimBindings?: boolean + /** + * Event handler called when the search query produces no results. + */ + onEmpty?: (search: string) => void } type Context = { @@ -198,6 +202,7 @@ const Command = React.forwardRef((props, forwarded loop, disablePointerSelection = false, vimBindings = true, + onEmpty, ...etc } = props @@ -240,6 +245,12 @@ const Command = React.forwardRef((props, forwarded filterItems() sort() schedule(1, selectFirstItem) + + // Notify when filtering produces no results + const search = value as string + if (state.current.filtered.count === 0 && search.trim()) { + propsRef.current.onEmpty?.(search) + } } else if (key === 'value') { // Force focus input or root so accessibility works if (document.activeElement.hasAttribute('cmdk-input') || document.activeElement.hasAttribute('cmdk-root')) { diff --git a/test/pages/props.tsx b/test/pages/props.tsx index 7e9b23b3..f3355fcb 100644 --- a/test/pages/props.tsx +++ b/test/pages/props.tsx @@ -7,6 +7,7 @@ const Page = () => { const [search, setSearch] = React.useState('') const [shouldFilter, setShouldFilter] = React.useState(true) const [customFilter, setCustomFilter] = React.useState(false) + const [emptySearch, setEmptySearch] = React.useState('') const router = useRouter() React.useEffect(() => { @@ -21,6 +22,7 @@ const Page = () => {
{value}
{search}
+
{emptySearch}