Skip to content

feat: introduce ActiveSearchDisplay#833

Closed
ikondrat wants to merge 1 commit intomainfrom
kondrat-introduce-ActiveSearchDisplay
Closed

feat: introduce ActiveSearchDisplay#833
ikondrat wants to merge 1 commit intomainfrom
kondrat-introduce-ActiveSearchDisplay

Conversation

@ikondrat
Copy link
Copy Markdown
Contributor

@ikondrat ikondrat commented Mar 25, 2026

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?

  • Yes
  • Not needed (internal change)

Overview

This PR introduces a new ActiveSearchDisplay Svelte component that provides an inline search status display for the GridSearch functionality. The component conditionally renders either active image information or submitted query text, with associated clear actions and visual feedback for drag-over interactions.

Changes

New Component: ActiveSearchDisplay.svelte

  • Renders an inline search status bar with conditional display logic
  • Accepts props for active image state, query text, optional preview URL, drag-over state, and clear callbacks
  • Displays either:
    • Image/preview thumbnail with filename and clear button
    • Search icon placeholder when no preview URL is available
    • Submitted query text with clear button
  • Applies ring highlight styling when dragOver is true
  • Implements accessible UI with appropriate title attributes and test identifiers

Props interface:

  • activeImage: string | null - Currently active image filename
  • submittedQueryText: string - Submitted search query text
  • previewUrl: string | null - Optional preview image URL
  • dragOver: boolean - Drag-over state for visual feedback
  • onClearImage: () => void - Callback for clearing active image
  • onClearText: () => void - Callback for clearing query text

Test Suite: ActiveSearchDisplay.test.ts

  • Comprehensive test coverage validating component behavior
  • Tests conditional rendering of submitted text and active image filename
  • Verifies preview image rendering with correct alt text and src attributes
  • Tests SVG icon display fallback when no preview URL is provided
  • Validates styling behavior with drag-over state (ring CSS classes)
  • Validates callback invocation on user interactions:
    • Clear button click triggers appropriate callbacks for both image and text clearing
    • Query text interactions properly invoke onClearText callback
  • Verifies accessibility metadata (clear button title attribute)

Impact

  • Lines changed: +151 (-0)
  • New files: 2 (component + tests)
  • Estimated code review effort: Medium

This component extends the GridSearch functionality with proper state display and user interaction handling, fully covered by tests.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 25, 2026

📝 Walkthrough

Walkthrough

A new Svelte component ActiveSearchDisplay is introduced alongside comprehensive test coverage. The component renders a search status bar displaying either an active image with thumbnail/icon or submitted query text, with callbacks for clearing each state and drag-over styling support.

Changes

Cohort / File(s) Summary
Search Status Bar Component
lightly_studio_view/src/lib/components/GridSearch/ActiveSearchDisplay/ActiveSearchDisplay.svelte, lightly_studio_view/src/lib/components/GridSearch/ActiveSearchDisplay/ActiveSearchDisplay.test.ts
New component with conditional rendering of image thumbnail/icon or query text, clear buttons for each state, drag-over styling, and comprehensive test suite validating UI behavior, callbacks, and accessibility attributes.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description contains only placeholder template text with no actual content about changes, testing, or changelog updates. Replace template placeholders with concrete descriptions: summarize the new ActiveSearchDisplay component, explain its purpose and integration, describe the test coverage, and indicate whether CHANGELOG.md was updated.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: introducing a new ActiveSearchDisplay component, which matches the added component files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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 kondrat-introduce-ActiveSearchDisplay

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.

Copy link
Copy Markdown

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

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: 4829feb879

ℹ️ 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 on lines +37 to +40
<button
class="ml-auto hover:text-foreground"
onclick={onClearImage}
title="Clear search"
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 Set clear button type explicitly

Both clear controls are plain <button> elements without type="button", so if this component is rendered inside a form they will submit the form by default when clicked. That can trigger unintended navigation or requests while the user is only trying to clear search state; set type="button" on these icon buttons to keep behavior predictable.

Useful? React with 👍 / 👎.

Comment on lines +24 to +26
class="flex h-10 w-full items-center rounded-md border border-input bg-background px-3 py-2 pl-8 text-sm {dragOver
? 'ring-2 ring-primary'
: ''}"
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 Use cn() for conditional Tailwind classes

The class list is built with inline string interpolation, but the frontend guidelines in docs/coding-guidelines/frontend.md ask to compose conditional Tailwind classes with cn() from $lib/utils. Switching to cn() here will keep class composition consistent with project style and reduce fragile string formatting in class attributes.

Useful? React with 👍 / 👎.

</button>
<button
class="ml-auto hover:text-foreground"
onclick={onClearImage}
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 Rename callback to match text-mode clear behavior

In text mode, the X clear control calls onClearImage, which makes the API misleading because this handler is also responsible for clearing text-only searches. This naming mismatch increases the chance of incorrect wiring by future callers; use a neutral callback name (for example onClearSearch) or call onClearText in this branch.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
lightly_studio_view/src/lib/components/GridSearch/ActiveSearchDisplay/ActiveSearchDisplay.svelte (1)

53-60: Consider renaming onClearImage to onClear for semantic clarity.

In the text-only branch (no activeImage), the clear button calls onClearImage, which is semantically confusing since there's no image to clear. Based on the parent layout's usage pattern (context snippet 1), this callback is meant to perform a "full clear" regardless of state.

Renaming onClearImage to onClear or onClearSearch would better communicate its purpose as the general clear action.

♻️ Suggested refactor
 interface Props {
     activeImage: string | null;
     submittedQueryText: string;
     previewUrl: string | null;
     dragOver: boolean;
-    onClearImage: () => void;
+    onClear: () => void;
     onClearText: () => void;
 }

 let {
     activeImage,
     submittedQueryText,
     previewUrl,
     dragOver,
-    onClearImage,
+    onClear,
     onClearText
 }: Props = $props();

Then update both clear buttons to use onclick={onClear}.

🤖 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/ActiveSearchDisplay/ActiveSearchDisplay.svelte`
around lines 53 - 60, Rename the prop/callback onClearImage to a semantically
clearer name (e.g., onClear or onClearSearch) across the component and update
all usages; change the prop definition/acceptance and every place that
referenced onClearImage (including both clear buttons’ onclick handlers) to the
new name so the handler represents a full clear action even when activeImage is
falsy, and update any parent component prop passed into ActiveSearchDisplay to
match the new identifier.
lightly_studio_view/src/lib/components/GridSearch/ActiveSearchDisplay/ActiveSearchDisplay.test.ts (1)

5-13: Consider resetting mocks in beforeEach for test isolation.

The defaultProps object contains vi.fn() mocks that persist across all tests. While current tests that assert on callbacks create fresh mocks, this pattern could lead to flaky tests if future assertions rely on defaultProps.onClearImage or defaultProps.onClearText call counts.

♻️ Suggested improvement for test isolation
 describe('ActiveSearchDisplay', () => {
-    const defaultProps = {
+    let defaultProps: {
+        activeImage: string | null;
+        submittedQueryText: string;
+        previewUrl: string | null;
+        dragOver: boolean;
+        onClearImage: ReturnType<typeof vi.fn>;
+        onClearText: ReturnType<typeof vi.fn>;
+    };
+
+    beforeEach(() => {
+        defaultProps = {
             activeImage: null,
             submittedQueryText: '',
             previewUrl: null,
             dragOver: false,
             onClearImage: vi.fn(),
             onClearText: vi.fn()
         };
+    });
🤖 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/ActiveSearchDisplay/ActiveSearchDisplay.test.ts`
around lines 5 - 13, The tests reuse the defaultProps object with vi.fn() mocks
which can leak call state between tests; add a beforeEach that calls
vi.clearAllMocks() and re-initializes defaultProps so onClearImage and
onClearText are fresh functions before each test (e.g., reassign defaultProps =
{ ..., onClearImage: vi.fn(), onClearText: vi.fn(), ... }) and update any tests
that referenced the original object to use the new instance to ensure isolation
for ActiveSearchDisplay tests.
🤖 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/ActiveSearchDisplay/ActiveSearchDisplay.svelte`:
- Around line 53-60: Rename the prop/callback onClearImage to a semantically
clearer name (e.g., onClear or onClearSearch) across the component and update
all usages; change the prop definition/acceptance and every place that
referenced onClearImage (including both clear buttons’ onclick handlers) to the
new name so the handler represents a full clear action even when activeImage is
falsy, and update any parent component prop passed into ActiveSearchDisplay to
match the new identifier.

In
`@lightly_studio_view/src/lib/components/GridSearch/ActiveSearchDisplay/ActiveSearchDisplay.test.ts`:
- Around line 5-13: The tests reuse the defaultProps object with vi.fn() mocks
which can leak call state between tests; add a beforeEach that calls
vi.clearAllMocks() and re-initializes defaultProps so onClearImage and
onClearText are fresh functions before each test (e.g., reassign defaultProps =
{ ..., onClearImage: vi.fn(), onClearText: vi.fn(), ... }) and update any tests
that referenced the original object to use the new instance to ensure isolation
for ActiveSearchDisplay tests.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: adbed708-3bd7-4cf1-b5f7-a5b1802ab773

📥 Commits

Reviewing files that changed from the base of the PR and between 57a298d and 4829feb.

📒 Files selected for processing (2)
  • lightly_studio_view/src/lib/components/GridSearch/ActiveSearchDisplay/ActiveSearchDisplay.svelte
  • lightly_studio_view/src/lib/components/GridSearch/ActiveSearchDisplay/ActiveSearchDisplay.test.ts

@ikondrat ikondrat closed this Apr 7, 2026
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