Skip to content

🎨 Palette: [UX improvement] Add Cmd/Ctrl+K shortcut to search - #277

Open
mkk2026 wants to merge 1 commit into
masterfrom
palette-keyboard-shortcut-8498046087493958684
Open

🎨 Palette: [UX improvement] Add Cmd/Ctrl+K shortcut to search#277
mkk2026 wants to merge 1 commit into
masterfrom
palette-keyboard-shortcut-8498046087493958684

Conversation

@mkk2026

@mkk2026 mkk2026 commented May 6, 2026

Copy link
Copy Markdown
Owner

💡 What: Added a Cmd/Ctrl+K keyboard shortcut to immediately focus the search input, and a visual <kbd> hint that displays when the search is empty.
🎯 Why: Searching is the primary action on this dashboard. Power users and keyboard navigators need a quick way to jump to search without clicking, improving efficiency and accessibility.
📸 Before/After: Added a screenshot demonstrating the Ctrl K / ⌘ K visual hint inside the input.
Accessibility: Added aria-keyshortcuts to the search input, securely derived from the OS platform, and safely mounted in a useEffect to prevent SSR hydration mismatches. Recorded this learning in .Jules/palette.md.


PR created automatically by Jules for task 8498046087493958684 started by @corebrimtech

Summary by CodeRabbit

Release Notes

  • New Features
    • Added keyboard shortcut (Cmd+K on Mac, Ctrl+K on other platforms) to quickly focus the search input.
    • Added platform-aware visual hint displaying the correct keyboard shortcut for your device.
    • Improved accessibility with keyboard shortcut support and proper labeling.

Co-authored-by: corebrimtech <175357468+corebrimtech@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai

coderabbitai Bot commented May 6, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR adds keyboard shortcut functionality (Cmd/Ctrl+K) to a search input component. A platform-detection effect registers a global keyboard listener that focuses the search input on Mac (⌘K) or Windows/Linux (Ctrl+K). A journal entry documents the SSR hydration considerations resolved through client-side state initialization.

Changes

Keyboard Shortcut Feature

Layer / File(s) Summary
Documentation
.Jules/palette.md
New journal entry explains SSR hydration risks with OS-specific UI hints and recommends useEffect-based client-side state initialization to prevent mismatches.
Platform Detection & Event Binding
src/app/page.tsx
Added isMac state and searchInputRef; useEffect detects macOS platform and attaches a keydown listener for Cmd/Ctrl+K global shortcut with proper cleanup on unmount.
Input Element & Accessibility
src/app/page.tsx
Search input now accepts the ref, includes aria-keyshortcuts attribute documenting the keyboard shortcut.
UI Enhancement
src/app/page.tsx
Conditional hint UI renders platform-specific keyboard shortcut (⌘K or Ctrl+K) when search is empty and unfocused.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • mkk2026/Security.News.Scraper#46: Modifies the same search input component in src/app/page.tsx with related enhancements to input behavior and state handling.

Poem

A rabbit's shortcut, swift and keen,
⌘K or Ctrl—now you've seen!
No hydration fights on either shore,
Client-side magic, forevermore. 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: adding a Cmd/Ctrl+K keyboard shortcut to the search functionality. It directly aligns with the primary objective of the PR, though it includes an emoji and categorization tag.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch palette-keyboard-shortcut-8498046087493958684

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 746d82fdbf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/app/page.tsx
setIsMac(typeof window !== 'undefined' && navigator.platform.toUpperCase().indexOf('MAC') >= 0)

const handleKeyDown = (e: KeyboardEvent) => {
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restrict search shortcut to advertised modifier key

On macOS, the handler currently fires for both Meta+K and Control+K because the condition uses (e.metaKey || e.ctrlKey). That means pressing Ctrl+K (a common text-editing shortcut in Mac text fields) unexpectedly steals focus to the global search input, while aria-keyshortcuts advertises only Meta+K. Limiting the modifier to platform-specific behavior (Meta on Mac, Control elsewhere) avoids this shortcut conflict and keeps behavior aligned with the UI hint and accessibility metadata.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/app/page.tsx (2)

61-61: ⚡ Quick win

Replace deprecated navigator.platform with navigator.userAgentData + fallback

navigator.platform is deprecating for all browsers. The safer pattern is navigator?.userAgentData?.platform || navigator?.platform, since navigator.userAgentData is not yet implemented in all browsers (notably Firefox and Safari historically).

♻️ Proposed fix
-    setIsMac(typeof window !== 'undefined' && navigator.platform.toUpperCase().indexOf('MAC') >= 0)
+    const platform = (navigator.userAgentData?.platform ?? navigator.platform ?? '').toUpperCase()
+    setIsMac(platform.includes('MAC'))

The typeof window !== 'undefined' guard is also redundant here — useEffect only runs on the client.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/page.tsx` at line 61, In the useEffect that sets isMac (the setIsMac
call), replace the deprecated navigator.platform usage with a modern check using
navigator.userAgentData?.platform with a fallback to navigator.platform; e.g.
read const platform = navigator?.userAgentData?.platform || navigator?.platform
and setIsMac(platform?.toUpperCase().includes('MAC')); also remove the redundant
typeof window !== 'undefined' guard since useEffect only runs client-side.
Ensure you reference the setIsMac call and the enclosing useEffect when making
the change.

374-380: ⚡ Quick win

Consider hiding the kbd hint when the search input is focused

The !searchQuery condition alone keeps the ⌘K/Ctrl+K hint visible even when the input is already focused (and empty). Many search UIs (e.g., VS Code, Linear) hide the hint on focus to avoid visual clutter.

♻️ Suggested approach
+  const [searchFocused, setSearchFocused] = useState(false)
   ...
   <Input
     ref={searchInputRef}
+    onFocus={() => setSearchFocused(true)}
+    onBlur={() => setSearchFocused(false)}
     ...
   />
-  {!searchQuery && (
+  {!searchQuery && !searchFocused && (
     <div ...>
       <kbd ...>...</kbd>
     </div>
   )}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/page.tsx` around lines 374 - 380, The hint visibility should also
consider whether the search input is focused; update the render condition from
checking only !searchQuery to also require the input not be focused (e.g.,
{!searchQuery && !isSearchFocused}). Add focus tracking for the search input
(create a boolean state like isSearchFocused or use an input ref to compare to
document.activeElement) and wire it to the input's onFocus/onBlur (or set when
focus changes) so the kbd hint (the element using isMac and searchQuery) hides
while the user is actively focused in the search field.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/page.tsx`:
- Around line 365-366: The Input component is not forwarding refs so
searchInputRef.current stays null and focus() fails; update the Input component
(src/components/ui/input.tsx) to use React.forwardRef<HTMLInputElement,
React.ComponentProps<"input">> and accept (props, ref) then pass ref to the
underlying <input> element, set Input.displayName = "Input", and export the
forwarded component so searchInputRef in page.tsx can call focus() successfully.

---

Nitpick comments:
In `@src/app/page.tsx`:
- Line 61: In the useEffect that sets isMac (the setIsMac call), replace the
deprecated navigator.platform usage with a modern check using
navigator.userAgentData?.platform with a fallback to navigator.platform; e.g.
read const platform = navigator?.userAgentData?.platform || navigator?.platform
and setIsMac(platform?.toUpperCase().includes('MAC')); also remove the redundant
typeof window !== 'undefined' guard since useEffect only runs client-side.
Ensure you reference the setIsMac call and the enclosing useEffect when making
the change.
- Around line 374-380: The hint visibility should also consider whether the
search input is focused; update the render condition from checking only
!searchQuery to also require the input not be focused (e.g., {!searchQuery &&
!isSearchFocused}). Add focus tracking for the search input (create a boolean
state like isSearchFocused or use an input ref to compare to
document.activeElement) and wire it to the input's onFocus/onBlur (or set when
focus changes) so the kbd hint (the element using isMac and searchQuery) hides
while the user is actively focused in the search field.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1df5e646-b1c4-4a65-aebf-f8aab8012d6c

📥 Commits

Reviewing files that changed from the base of the PR and between 558fb10 and 746d82f.

📒 Files selected for processing (2)
  • .Jules/palette.md
  • src/app/page.tsx

Comment thread src/app/page.tsx
Comment on lines 365 to +366
<Input
ref={searchInputRef}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm Input component uses React.forwardRef
rg -n "forwardRef" --type=tsx --type=ts -g "**/components/ui/input*"
# fallback if type=tsx not supported
fd -i "input" --extension tsx --extension ts -p "components/ui" | xargs grep -n "forwardRef"

Repository: mkk2026/Security.News.Scraper

Length of output: 204


🏁 Script executed:

git ls-files --cached | head -30

Repository: mkk2026/Security.News.Scraper

Length of output: 670


🏁 Script executed:

find . -type d -name "components" | head -10

Repository: mkk2026/Security.News.Scraper

Length of output: 634


🏁 Script executed:

find ./src/components -type f -name "*.tsx" -o -name "*.ts" | grep -i input

Repository: mkk2026/Security.News.Scraper

Length of output: 137


🏁 Script executed:

cat ./src/components/ui/input.tsx

Repository: mkk2026/Security.News.Scraper

Length of output: 1040


🏁 Script executed:

sed -n '360,385p' ./src/app/page.tsx

Repository: mkk2026/Security.News.Scraper

Length of output: 2143


🏁 Script executed:

grep -n "searchInputRef" ./src/app/page.tsx | head -20

Repository: mkk2026/Security.News.Scraper

Length of output: 224


🏁 Script executed:

sed -n '55,75p' ./src/app/page.tsx

Repository: mkk2026/Security.News.Scraper

Length of output: 728


Wrap the Input component with React.forwardRef to enable ref forwarding

The Input component at src/components/ui/input.tsx does not use React.forwardRef, so searchInputRef will always be null. This breaks the Cmd/Ctrl+K keyboard shortcut at line 66, which attempts to call searchInputRef.current?.focus() — the focus() call silently fails because the ref is never forwarded to the underlying input element.

Fix the Input component:

const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
  ({ className, type, ...props }, ref) => (
    <input
      ref={ref}
      type={type}
      // ... rest of implementation
    />
  )
)
Input.displayName = "Input"
export { Input }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/page.tsx` around lines 365 - 366, The Input component is not
forwarding refs so searchInputRef.current stays null and focus() fails; update
the Input component (src/components/ui/input.tsx) to use
React.forwardRef<HTMLInputElement, React.ComponentProps<"input">> and accept
(props, ref) then pass ref to the underlying <input> element, set
Input.displayName = "Input", and export the forwarded component so
searchInputRef in page.tsx can call focus() successfully.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant