From 5b50fefc29dbd0c91bb530db85113f8445e138a4 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 16 Jun 2026 04:38:31 +0000 Subject: [PATCH] feat: add filter count badge and enhance searchbar interaction - Add visual badge to Filter trigger showing number of active filters - Add Escape key support to Searchbar for clearing query or blurring input - Auto-focus Searchbar input after clicking clear button --- src/components/filter.tsx | 9 ++++- src/components/search.tsx | 16 +++++++- src/components/unified-filter-bar.tsx | 54 ++++++++++++++++----------- 3 files changed, 54 insertions(+), 25 deletions(-) diff --git a/src/components/filter.tsx b/src/components/filter.tsx index f1b2580..a2637fb 100644 --- a/src/components/filter.tsx +++ b/src/components/filter.tsx @@ -103,9 +103,11 @@ export const Selections = ({ export const Filter = ({ children, className, + activeCount = 0, }: { children: ReactNode; className?: string; + activeCount?: number; }) => { const [isOpen, setIsOpen] = useState(false); @@ -118,9 +120,14 @@ export const Filter = ({ isIconOnly aria-label="Open filters" aria-haspopup="dialog" - className={className} + className={`relative ${className}`} > + {activeCount > 0 && ( + + {activeCount} + + )} { + if (e.key === "Escape" && document.activeElement === inputRef.current) { + if (query) { + setQuery(""); + } else { + inputRef.current?.blur(); + } + return; + } + const isSearchShortcut = (e.key === "k" && (e.metaKey || e.ctrlKey)) || e.key === "/"; @@ -47,7 +56,7 @@ export const Searchbar = ({ globalThis.addEventListener("keydown", handleKeyDown); return () => globalThis.removeEventListener("keydown", handleKeyDown); - }, []); + }, [query, setQuery]); return (
@@ -88,7 +97,10 @@ export const Searchbar = ({ variant="ghost" size="sm" aria-label="Clear search" - onPress={() => setQuery("")} + onPress={() => { + setQuery(""); + inputRef.current?.focus(); + }} className="absolute right-2 top-1/2 -translate-y-1/2 text-zinc-500 hover:text-zinc-900 dark:hover:text-zinc-100 min-w-0 h-7 w-7" > diff --git a/src/components/unified-filter-bar.tsx b/src/components/unified-filter-bar.tsx index 68247ef..cfe3edd 100644 --- a/src/components/unified-filter-bar.tsx +++ b/src/components/unified-filter-bar.tsx @@ -38,28 +38,38 @@ const FilterDropdown = memo( }: { selected: Record; setSelected: (category: string, selected: string[]) => void; - }) => ( - - setSelected("areas", vals)} - /> - setSelected("skills", vals)} - /> - setSelected("roles", vals)} - /> - - ), + }) => { + const activeCount = Object.values(selected).reduce( + (acc, curr) => acc + curr.length, + 0, + ); + + return ( + + setSelected("areas", vals)} + /> + setSelected("skills", vals)} + /> + setSelected("roles", vals)} + /> + + ); + }, ); FilterDropdown.displayName = "FilterDropdown";