Skip to content

Comments

feat: autofocus first search result#89

Open
scrap-bot wants to merge 3 commits intojoyco-studio:mainfrom
scrap-bot:fix/search-autofocus-first-result
Open

feat: autofocus first search result#89
scrap-bot wants to merge 3 commits intojoyco-studio:mainfrom
scrap-bot:fix/search-autofocus-first-result

Conversation

@scrap-bot
Copy link

@scrap-bot scrap-bot commented Feb 17, 2026

Cuando buscás algo en el registry, ahora el primer resultado viene selected automáticamente.

Changes:

  • Agregué state controlado al componente Command para manejar la selección
  • El primer resultado se auto-selecciona cuando aparecen resultados de búsqueda
  • Mejora keyboard navigation y UX

Fixes feedback de kahdri: el primer match ahora viene selected por default.

Greptile Summary

This PR adds auto-selection of the first search result in the registry sidebar. When search results arrive, a new controlled value/onValueChange pair is wired to the Command component, and a useEffect sets selectedValue to the URL of the first result. This enables immediate keyboard-driven navigation (pressing Enter after a search navigates to the top result) without requiring the user to press the down-arrow first.

The implementation is clean and well-scoped. Two minor points worth considering:

  • The results.length > 0 guard inside the effect is redundant — hasResults already encodes that invariant from use-search.ts.
  • Because results is in the effect's dependency array, selectedValue is reset to the first item on every API response. If the user is mid-navigation with arrow keys and a new response arrives (e.g. due to network jitter with the same query), their selection is silently reset to the top. This is a subtle UX edge case rather than a functional bug.

Confidence Score: 4/5

  • This PR is safe to merge — changes are well-contained to the sidebar component with no correctness bugs.
  • The auto-selection logic is correct and aligns with the Command component's controlled-value API. The two issues found are both style-level: a redundant guard condition and a minor UX edge case where in-flight keyboard navigation resets on each API response. Neither affects correctness or causes runtime errors.
  • No files require special attention.

Important Files Changed

Filename Overview
components/layout/sidebar/index.tsx Adds controlled value/onValueChange to the Command component and an effect to auto-select the first search result; logic is mostly sound but the redundant results.length > 0 guard inside the effect (when hasResults already guarantees it) is a minor style issue, and there's a subtle UX concern where in-flight keyboard navigation resets on each new API response.

Last reviewed commit: 6b86c76

(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!

- Auto-select first result when search query returns results
- Add controlled value state to Command component
- Improves keyboard navigation and UX when searching

Fixes kahdri feedback: first match now comes selected by default
@vercel
Copy link
Contributor

vercel bot commented Feb 17, 2026

Someone is attempting to deploy a commit to the joyco Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

1 file reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +36 to +43
React.useEffect(() => {
if (hasResults && results.length > 0) {
const firstUrl = results[0].url.split('#')[0]
setSelectedValue(firstUrl)
} else {
setSelectedValue(undefined)
}
}, [hasResults, results])
Copy link
Contributor

Choose a reason for hiding this comment

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

Redundant results.length > 0 guard

hasResults is derived as isSearching && hasLoadedResults && results.length > 0 in use-search.ts, so the inner results.length > 0 check is always true when hasResults is true. The condition can be simplified to just if (hasResults).

Suggested change
React.useEffect(() => {
if (hasResults && results.length > 0) {
const firstUrl = results[0].url.split('#')[0]
setSelectedValue(firstUrl)
} else {
setSelectedValue(undefined)
}
}, [hasResults, results])
React.useEffect(() => {
if (hasResults) {
const firstUrl = results[0].url.split('#')[0]
setSelectedValue(firstUrl)
} else {
setSelectedValue(undefined)
}
}, [hasResults, results])
Prompt To Fix With AI
This is a comment left during a code review.
Path: components/layout/sidebar/index.tsx
Line: 36:43

Comment:
**Redundant `results.length > 0` guard**

`hasResults` is derived as `isSearching && hasLoadedResults && results.length > 0` in `use-search.ts`, so the inner `results.length > 0` check is always `true` when `hasResults` is `true`. The condition can be simplified to just `if (hasResults)`.

```suggestion
  React.useEffect(() => {
    if (hasResults) {
      const firstUrl = results[0].url.split('#')[0]
      setSelectedValue(firstUrl)
    } else {
      setSelectedValue(undefined)
    }
  }, [hasResults, results])
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +36 to +43
React.useEffect(() => {
if (hasResults && results.length > 0) {
const firstUrl = results[0].url.split('#')[0]
setSelectedValue(firstUrl)
} else {
setSelectedValue(undefined)
}
}, [hasResults, results])
Copy link
Contributor

Choose a reason for hiding this comment

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

Keyboard navigation resets on each API response

When the user types a query, the effect fires once per API response to re-select the first result. If the user has already moved focus down the list with arrow keys and is mid-selection, the next debounced fetch (150 ms after each keystroke) will reset selectedValue back to the first item. For fast typists this is fine because the query keeps changing, but for any scenario where results update while the user is navigating (e.g. network latency), the selection jumps back to the top unexpectedly.

Consider only setting selectedValue when the query itself changes (i.e. also tracking query in the dependency array and resetting only on query changes, not on result updates for the same query).

Prompt To Fix With AI
This is a comment left during a code review.
Path: components/layout/sidebar/index.tsx
Line: 36:43

Comment:
**Keyboard navigation resets on each API response**

When the user types a query, the effect fires once per API response to re-select the first result. If the user has already moved focus down the list with arrow keys and is mid-selection, the next debounced fetch (150 ms after each keystroke) will reset `selectedValue` back to the first item. For fast typists this is fine because the query keeps changing, but for any scenario where results update while the user is navigating (e.g. network latency), the selection jumps back to the top unexpectedly.

Consider only setting `selectedValue` when the query itself changes (i.e. also tracking `query` in the dependency array and resetting only on query changes, not on result updates for the same query).

How can I resolve this? If you propose a fix, please make it concise.

@vercel
Copy link
Contributor

vercel bot commented Feb 17, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
joyco-hub Ready Ready Preview, Comment Feb 17, 2026 7:12pm

@matiasperz
Copy link
Contributor

@claude take over here and make this actually work, see the greptile comments and make sure we always have the first result selected even after searching

@claude
Copy link

claude bot commented Feb 17, 2026

Claude Code is working…

I'll analyze this and get back to you.

View job run

@matiasperz
Copy link
Contributor

@claude take over here and make this actually work, see the greptile comments and make sure we always have the first result selected even after searching

@claude
Copy link

claude bot commented Feb 17, 2026

Claude Code is working…

I'll analyze this and get back to you.

View job run

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.

2 participants