mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-03 05:10:16 +03:00
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 <img width="1594" height="600" alt="image" src="https://github.com/user-attachments/assets/f3710cad-f1a6-4aa1-9c2a-f3f474fd2dd6" /> ### Old <img width="1584" height="618" alt="image" src="https://github.com/user-attachments/assets/2d9c26a8-2d68-4d86-9d51-b12f90b17fe0" /> <!-- Please provide a summary of the changes, including: - What was changed - Why the change was made - Any challenges encountered Closes #(issue_number) --> --- ## 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.
This commit is contained in:
@@ -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(<MantineProvider>{ui}</MantineProvider>);
|
||||
}
|
||||
|
||||
describe("TextInput", () => {
|
||||
it("renders input with value and placeholder", () => {
|
||||
renderWithMantine(
|
||||
<TextInput
|
||||
id="test-input"
|
||||
name="test-input"
|
||||
value="hello"
|
||||
onChange={vi.fn()}
|
||||
placeholder="Type here..."
|
||||
/>,
|
||||
);
|
||||
|
||||
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(
|
||||
<TextInput
|
||||
id="test-input"
|
||||
name="test-input"
|
||||
value="search text"
|
||||
onChange={onChange}
|
||||
showClearButton={true}
|
||||
/>,
|
||||
);
|
||||
|
||||
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(
|
||||
<TextInput
|
||||
id="test-input"
|
||||
name="test-input"
|
||||
value=""
|
||||
onChange={vi.fn()}
|
||||
showClearButton={true}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.queryByRole("button", { name: /clear input/i }),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not show clear button when showClearButton is false", () => {
|
||||
renderWithMantine(
|
||||
<TextInput
|
||||
id="test-input"
|
||||
name="test-input"
|
||||
value="some text"
|
||||
onChange={vi.fn()}
|
||||
showClearButton={false}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.queryByRole("button", { name: /clear input/i }),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -119,12 +119,25 @@ export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(
|
||||
/>
|
||||
{shouldShowClearButton && (
|
||||
<ActionIcon
|
||||
variant="tertiary"
|
||||
variant="quiet"
|
||||
accent="neutral"
|
||||
shape="circle"
|
||||
className={styles.clearButton}
|
||||
style={
|
||||
{
|
||||
"--ai-size": "1.25rem",
|
||||
width: "1.25rem",
|
||||
height: "1.25rem",
|
||||
} as React.CSSProperties
|
||||
}
|
||||
onClick={handleClear}
|
||||
aria-label={t("textInput.clear", "Clear input")}
|
||||
>
|
||||
<LocalIcon icon="close-rounded" width="1.25rem" height="1.25rem" />
|
||||
<LocalIcon
|
||||
icon="close-rounded"
|
||||
width="0.875rem"
|
||||
height="0.875rem"
|
||||
/>
|
||||
</ActionIcon>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user