From 4e5b1102b668cad9ac9dd6ee2b45db7b42539281 Mon Sep 17 00:00:00 2001 From: brios <127139797+balazs-szucs@users.noreply.github.com> Date: Thu, 20 Aug 2026 21:21:50 +0000 Subject: [PATCH] refactor(search): improve TextInput clear button styling and add component unit tests (#7578) # Description of Changes FIxes minor stylistic problem about the search bar. Mainly the X and the spacing on the result's icons vs text. ### New image ### Old image --- ## Checklist ### General - [X] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [X] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [X] I have performed a self-review of my own code - [X] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### Translations (if applicable) - [ ] I ran [`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [X] I have run `task check` to verify linters, typechecks, and tests pass - [X] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing) for more details. --- .../core/components/shared/TextInput.test.tsx | 79 +++++++++++++++++++ .../src/core/components/shared/TextInput.tsx | 17 +++- .../shared/superSearch/SuperSearch.css | 16 +++- .../shared/textInput/TextInput.module.css | 27 ++++--- 4 files changed, 124 insertions(+), 15 deletions(-) create mode 100644 frontend/editor/src/core/components/shared/TextInput.test.tsx diff --git a/frontend/editor/src/core/components/shared/TextInput.test.tsx b/frontend/editor/src/core/components/shared/TextInput.test.tsx new file mode 100644 index 0000000000..d0dd2c9564 --- /dev/null +++ b/frontend/editor/src/core/components/shared/TextInput.test.tsx @@ -0,0 +1,79 @@ +import { render, screen, fireEvent } from "@testing-library/react"; +import { describe, it, expect, vi } from "vitest"; +import { TextInput } from "@app/components/shared/TextInput"; +import { MantineProvider } from "@mantine/core"; + +function renderWithMantine(ui: React.ReactElement) { + return render({ui}); +} + +describe("TextInput", () => { + it("renders input with value and placeholder", () => { + renderWithMantine( + , + ); + + const input = screen.getByPlaceholderText("Type here..."); + expect(input).toBeInTheDocument(); + expect(input).toHaveValue("hello"); + }); + + it("shows clear button when there is a value and triggers clear on click", () => { + const onChange = vi.fn(); + renderWithMantine( + , + ); + + const clearButton = screen.getByRole("button", { + name: /(?:clear|textInput\.clear)/i, + }); + expect(clearButton).toBeInTheDocument(); + + fireEvent.click(clearButton); + expect(onChange).toHaveBeenCalledWith(""); + }); + + it("does not show clear button when value is empty", () => { + renderWithMantine( + , + ); + + expect( + screen.queryByRole("button", { name: /clear input/i }), + ).not.toBeInTheDocument(); + }); + + it("does not show clear button when showClearButton is false", () => { + renderWithMantine( + , + ); + + expect( + screen.queryByRole("button", { name: /clear input/i }), + ).not.toBeInTheDocument(); + }); +}); diff --git a/frontend/editor/src/core/components/shared/TextInput.tsx b/frontend/editor/src/core/components/shared/TextInput.tsx index 7d927bb011..41a4223a4c 100644 --- a/frontend/editor/src/core/components/shared/TextInput.tsx +++ b/frontend/editor/src/core/components/shared/TextInput.tsx @@ -119,12 +119,25 @@ export const TextInput = forwardRef( /> {shouldShowClearButton && ( - + )} diff --git a/frontend/editor/src/core/components/shared/superSearch/SuperSearch.css b/frontend/editor/src/core/components/shared/superSearch/SuperSearch.css index 6920c37be4..a815d88fca 100644 --- a/frontend/editor/src/core/components/shared/superSearch/SuperSearch.css +++ b/frontend/editor/src/core/components/shared/superSearch/SuperSearch.css @@ -209,9 +209,6 @@ } .super-search-item { - display: flex; - align-items: center; - gap: 0.5rem; width: 100%; padding: 0.45rem 0.5rem; border: none; @@ -227,6 +224,18 @@ background: var(--c-hover); } +.super-search-item .mantine-Button-inner { + width: 100%; +} + +.super-search-item .mantine-Button-label { + display: flex; + align-items: center; + gap: 0.75rem; + width: 100%; + overflow: visible; +} + .super-search-item-icon { display: flex; align-items: center; @@ -241,6 +250,7 @@ display: flex; flex-direction: column; min-width: 0; + flex: 1 1 auto; } .super-search-item-title { diff --git a/frontend/editor/src/core/components/shared/textInput/TextInput.module.css b/frontend/editor/src/core/components/shared/textInput/TextInput.module.css index b5131b014f..0b6a38c7af 100644 --- a/frontend/editor/src/core/components/shared/textInput/TextInput.module.css +++ b/frontend/editor/src/core/components/shared/textInput/TextInput.module.css @@ -52,22 +52,29 @@ .clearButton { position: absolute; - right: 8px; + right: 6px; top: 50%; transform: translateY(-50%); - background: none; - border: none; - cursor: pointer; - padding: 4px; - border-radius: 4px; - display: flex; + --ai-size: 1.35rem !important; + width: 1.35rem !important; + height: 1.35rem !important; + min-width: 1.35rem !important; + min-height: 1.35rem !important; + padding: 0 !important; + display: inline-flex; align-items: center; justify-content: center; - font-size: 16px; - transition: background-color 0.2s ease; + border-radius: var(--radius-full, 9999px); + background: transparent; + border: none; + cursor: pointer; color: var(--c-text-subtle); + transition: + background-color 0.15s ease, + color 0.15s ease; } .clearButton:hover { - background-color: var(--c-hover); + color: var(--c-text); + background-color: var(--c-hover) !important; }