From e3d272ebc50739959a17b2fbb1a2506d4b0e2a4d Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 30 May 2026 04:28:08 +0000 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Search,=20Filter,?= =?UTF-8?q?=20and=20Header=20UX/A11y=20Improvements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Improved Searchbar: Added OS-aware shortcut hints (⌘K/Ctrl+K) and optional autoFocus. - Enhanced UnifiedFilterBar: Added smooth spring entry/exit animations using framer-motion and disabled autoFocus in the sticky bar to prevent scroll hijacking. - Improved Header: Added focus-visible ring styles and aria-label to the Title button for better accessibility. - UX Journal: Initialized .Jules/palette.md with critical learnings. --- src/app/page.tsx | 4 +++- src/components/header.tsx | 3 ++- src/components/search.tsx | 16 ++++++++++++++-- src/components/unified-filter-bar.tsx | 12 ++++++++++-- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index 75e4eb5e..e9fd9878 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -11,6 +11,8 @@ import { ExperienceSection } from "@/components/sections/experience"; import Intro from "@/components/sections/hero"; import { ProjectsSection } from "@/components/sections/projects"; import { PublicationsSection } from "@/components/sections/publications"; +import { AnimatePresence } from "framer-motion"; + import { SkillsSection } from "@/components/sections/skills"; import { UnifiedFilterBar } from "@/components/unified-filter-bar"; @@ -63,7 +65,7 @@ const Home = () => { - {showFilter && } + {showFilter && } ); }; diff --git a/src/components/header.tsx b/src/components/header.tsx index 044773c3..07e9dcdd 100644 --- a/src/components/header.tsx +++ b/src/components/header.tsx @@ -15,7 +15,8 @@ export const sections = [ const Title = ({ onClick }: { onClick: (e: React.MouseEvent) => void }) => ( diff --git a/src/components/search.tsx b/src/components/search.tsx index 5354ba49..4d22cc27 100644 --- a/src/components/search.tsx +++ b/src/components/search.tsx @@ -8,17 +8,25 @@ export const Searchbar = ({ query, setQuery, className, + autoFocus = false, }: { placeholder: string; query: string; setQuery: (query: string) => void; className?: string; + autoFocus?: boolean; }) => { const inputId = useId(); const inputRef = useRef(null); const [isFocused, setIsFocused] = useState(false); + const [isMac, setIsMac] = useState(false); useEffect(() => { + setIsMac( + typeof window !== "undefined" && + /Mac|iPod|iPhone|iPad/.test(navigator.platform), + ); + const handleKeyDown = (e: KeyboardEvent) => { const isSearchShortcut = (e.key === "k" && (e.metaKey || e.ctrlKey)) || e.key === "/"; @@ -56,7 +64,7 @@ export const Searchbar = ({ maxLength={100} onFocus={() => setIsFocused(true)} onBlur={() => setIsFocused(false)} - autoFocus + autoFocus={autoFocus} autoCapitalize="none" autoComplete="off" autoCorrect="off" @@ -64,7 +72,11 @@ export const Searchbar = ({ /> {!isFocused && !query && ( -
+
+ + {isMac ? "⌘" : "Ctrl"} K + + or / diff --git a/src/components/unified-filter-bar.tsx b/src/components/unified-filter-bar.tsx index f074d325..acf8c240 100644 --- a/src/components/unified-filter-bar.tsx +++ b/src/components/unified-filter-bar.tsx @@ -2,6 +2,7 @@ import { XMarkIcon } from "@heroicons/react/24/outline"; import { Button } from "@heroui/react"; +import { motion } from "framer-motion"; import { useFilter } from "@/contexts/filter"; import { useSearch } from "@/contexts/search"; @@ -25,7 +26,13 @@ export const UnifiedFilterBar = () => { }; return ( -
+
{ query={query} setQuery={setQuery} className="rounded-l-2xl rounded-r-none border-r-0" + autoFocus={false} /> {
)}
-
+ ); }; From 7d9be6797d9e755329ed75ae406a926076970fb6 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 30 May 2026 17:46:17 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Use=20globalThis?= =?UTF-8?q?=20for=20window=20and=20navigator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replaced `window` and `navigator` with `globalThis.window` and `globalThis.navigator` in `src/components/search.tsx` to address SonarCloud feedback. --- src/components/search.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/search.tsx b/src/components/search.tsx index 4d22cc27..bed9a7f3 100644 --- a/src/components/search.tsx +++ b/src/components/search.tsx @@ -23,8 +23,8 @@ export const Searchbar = ({ useEffect(() => { setIsMac( - typeof window !== "undefined" && - /Mac|iPod|iPhone|iPad/.test(navigator.platform), + typeof globalThis.window !== "undefined" && + /Mac|iPod|iPhone|iPad/.test(globalThis.navigator.platform), ); const handleKeyDown = (e: KeyboardEvent) => { From 75c272ebe1305da8abe087965729f5bb338b7224 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 10:03:26 +0000 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Compare=20window?= =?UTF-8?q?=20with=20undefined=20directly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Updated `src/components/search.tsx` to compare `globalThis.window` with `undefined` directly instead of using `typeof`, addressing SonarCloud feedback. --- src/components/search.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/search.tsx b/src/components/search.tsx index bed9a7f3..a46558a5 100644 --- a/src/components/search.tsx +++ b/src/components/search.tsx @@ -23,7 +23,7 @@ export const Searchbar = ({ useEffect(() => { setIsMac( - typeof globalThis.window !== "undefined" && + globalThis.window !== undefined && /Mac|iPod|iPhone|iPad/.test(globalThis.navigator.platform), );