Conversation
📝 WalkthroughWalkthroughAdded a new Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: db027af122
ℹ️ 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".
| <Search class="absolute left-2 top-[50%] h-4 w-4 translate-y-[-50%] text-muted-foreground" /> | ||
| <Input | ||
| placeholder={isUploading ? 'Uploading...' : 'Search samples by description or image'} | ||
| class="pl-8 pr-8 {dragOver ? 'ring-2 ring-primary' : ''}" |
There was a problem hiding this comment.
Compose conditional Tailwind classes with cn()
The frontend guideline in docs/coding-guidelines/frontend.md recommends using cn() for Tailwind class composition, but this line builds a conditional class string inline. Keeping conditional styling in cn() avoids brittle string interpolation and keeps class composition consistent with the rest of the codebase.
Useful? React with 👍 / 👎.
| onkeydown: (event: KeyboardEvent) => void; | ||
| onpaste: (event: ClipboardEvent) => Promise<void>; |
There was a problem hiding this comment.
Rename event callback props to camelCase
The coding guideline specifies camelCase for props, but the public prop names here are lowercase (onkeydown, onpaste). This makes the component API inconsistent with the project’s TypeScript naming conventions and propagates non-standard names to every consumer and test.
Useful? React with 👍 / 👎.
| <button | ||
| class="absolute right-2 top-[50%] translate-y-[-50%] text-muted-foreground hover:text-foreground disabled:opacity-50" | ||
| onclick={triggerFileInput} | ||
| title="Upload image for search" |
There was a problem hiding this comment.
Add aria-label to icon-only upload button
This icon-only button relies on title for its label, but title is not a reliable accessible name across assistive technologies. Adding an explicit aria-label keeps the control consistently discoverable for screen-reader users while still allowing a tooltip via title if needed.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
🧹 Nitpick comments (3)
lightly_studio_view/src/lib/components/GridSearch/SearchInput/SearchInput.test.ts (2)
32-35: Make the drag-over style assertion more targeted.This assertion can pass even if the ring class lands on a different element. Prefer asserting class presence on
screen.getByTestId('text-embedding-search-input')directly (and optionally assert absence whendragOveris false).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lightly_studio_view/src/lib/components/GridSearch/SearchInput/SearchInput.test.ts` around lines 32 - 35, Update the test in SearchInput.test.ts so the dragOver style assertion targets the specific input element: render SearchInput with dragOver true and use screen.getByTestId('text-embedding-search-input') to assert it has the 'ring-2' and 'ring-primary' classes (and add an extra assertion that the same element does not have those classes when dragOver is false); locate the existing test named "applies ring style when dragOver is true" and replace the container.querySelector check with assertions against the element returned by getByTestId.
68-71: Add a behavior test for disabled upload button clicks.You already check disabled state; add one more check that clicking while
isUploading: truedoes not calltriggerFileInput, to lock in the interaction contract.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lightly_studio_view/src/lib/components/GridSearch/SearchInput/SearchInput.test.ts` around lines 68 - 71, Add an interaction assertion to the test that when isUploading is true clicking the upload button does not call the helper that opens the file picker: render the SearchInput with isUploading: true, simulate a click on the element found by title 'Upload image for search' (e.g., fireEvent.click or userEvent.click) and assert that the mock function triggerFileInput (the helper used in the component) was not called (expect(triggerFileInput).not.toHaveBeenCalled()) to lock in the disabled interaction contract.lightly_studio_view/src/lib/components/GridSearch/SearchInput/SearchInput.svelte (1)
26-40: Add explicit accessible labeling and button type semantics.Line 26 currently relies on placeholder text for input meaning, and Lines 35-39 define an icon-only
<button>withouttype="button". This is fragile for accessibility and can accidentally submit an enclosing form.Suggested update
<Input + aria-label="Search samples by description or image" placeholder={isUploading ? 'Uploading...' : 'Search samples by description or image'} class="pl-8 pr-8 {dragOver ? 'ring-2 ring-primary' : ''}" bind:value={queryText} {onkeydown} {onpaste} disabled={isUploading} data-testid="text-embedding-search-input" /> <button + type="button" + aria-label="Upload image for search" class="absolute right-2 top-[50%] translate-y-[-50%] text-muted-foreground hover:text-foreground disabled:opacity-50" onclick={triggerFileInput} title="Upload image for search" disabled={isUploading} >🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lightly_studio_view/src/lib/components/GridSearch/SearchInput/SearchInput.svelte` around lines 26 - 40, The input currently relies on placeholder text for its accessible name — update the Input component (bound to queryText) to include an explicit accessible label (e.g., add aria-label="Search samples by description or image" or aria-labelledby pointing to a visible label) while preserving the placeholder and disabled/isUploading behavior; and for the icon-only upload button that calls triggerFileInput, add type="button" and an appropriate aria-label (e.g., aria-label="Upload image for search") so it won't accidentally submit a form and is accessible to screen readers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In
`@lightly_studio_view/src/lib/components/GridSearch/SearchInput/SearchInput.svelte`:
- Around line 26-40: The input currently relies on placeholder text for its
accessible name — update the Input component (bound to queryText) to include an
explicit accessible label (e.g., add aria-label="Search samples by description
or image" or aria-labelledby pointing to a visible label) while preserving the
placeholder and disabled/isUploading behavior; and for the icon-only upload
button that calls triggerFileInput, add type="button" and an appropriate
aria-label (e.g., aria-label="Upload image for search") so it won't accidentally
submit a form and is accessible to screen readers.
In
`@lightly_studio_view/src/lib/components/GridSearch/SearchInput/SearchInput.test.ts`:
- Around line 32-35: Update the test in SearchInput.test.ts so the dragOver
style assertion targets the specific input element: render SearchInput with
dragOver true and use screen.getByTestId('text-embedding-search-input') to
assert it has the 'ring-2' and 'ring-primary' classes (and add an extra
assertion that the same element does not have those classes when dragOver is
false); locate the existing test named "applies ring style when dragOver is
true" and replace the container.querySelector check with assertions against the
element returned by getByTestId.
- Around line 68-71: Add an interaction assertion to the test that when
isUploading is true clicking the upload button does not call the helper that
opens the file picker: render the SearchInput with isUploading: true, simulate a
click on the element found by title 'Upload image for search' (e.g.,
fireEvent.click or userEvent.click) and assert that the mock function
triggerFileInput (the helper used in the component) was not called
(expect(triggerFileInput).not.toHaveBeenCalled()) to lock in the disabled
interaction contract.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 61e2e858-c2b6-438c-803f-1de534b7fdab
📒 Files selected for processing (2)
lightly_studio_view/src/lib/components/GridSearch/SearchInput/SearchInput.sveltelightly_studio_view/src/lib/components/GridSearch/SearchInput/SearchInput.test.ts
What has changed and why?
(Delete this: Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.)
How has it been tested?
(Delete this: Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration.)
Did you update CHANGELOG.md?
SearchInput Component Introduction
Added a new
SearchInputSvelte component to support text-based search with image upload capabilities in the GridSearch feature.Component Implementation
The
SearchInput.sveltecomponent provides:queryTextproptriggerFileInputcallbackProps Interface
queryText: string (bindable for two-way binding)isUploading: boolean (controls input disabled state and upload button availability)dragOver: boolean (applies visual ring styling to indicate drag-over state)onkeydown: KeyboardEvent handleronpaste: async ClipboardEvent handlertriggerFileInput: Callback to initiate file inputTest Coverage
Comprehensive test suite (
SearchInput.test.ts) covering:data-testid)Metrics