-
+
+
+
Edit src/App.tsx and save to test HMR
diff --git a/src/InputClickEdit/InputClickEdit.test.tsx b/src/InputClickEdit/InputClickEdit.test.tsx
index 2fed3de..f3eb906 100644
--- a/src/InputClickEdit/InputClickEdit.test.tsx
+++ b/src/InputClickEdit/InputClickEdit.test.tsx
@@ -1,5 +1,148 @@
+import { render, screen, fireEvent } from "@testing-library/react";
+import { vi } from "vitest";
+import { InputClickEdit } from "./InputClickEdit";
+
describe("InputClickEdit", () => {
- it("assert true", () => {
- expect(true).toBeTruthy();
+ describe("Rendering", () => {
+ it("should render with default props", () => {
+ render(
);
+ expect(screen.getByText("Edit")).toBeInTheDocument();
+ });
+
+ it("should render with initial value", () => {
+ render(
);
+ expect(screen.getByText("Test Value")).toBeInTheDocument();
+ });
+
+ it("should render with label when provided", () => {
+ render(
);
+ const label = screen.getByText("Name");
+ expect(label).toBeInTheDocument();
+ expect(label.closest("label")).toContainElement(
+ screen.getByRole("textbox")
+ );
+ });
+ });
+
+ describe("Editing Mode", () => {
+ it("should enter edit mode when edit button is clicked", () => {
+ render(
);
+ fireEvent.click(screen.getByText("Edit"));
+ expect(screen.getByRole("textbox")).toBeInTheDocument();
+ expect(screen.getByText("Save")).toBeInTheDocument();
+ });
+
+ it("should start in edit mode when isEditing is true", () => {
+ render(
);
+ expect(screen.getByRole("textbox")).toBeInTheDocument();
+ });
+
+ it("should exit edit mode when save button is clicked", () => {
+ render(
);
+ fireEvent.click(screen.getByText("Edit"));
+ fireEvent.click(screen.getByText("Save"));
+ expect(screen.queryByRole("textbox")).not.toBeInTheDocument();
+ });
+ });
+
+ describe("Callbacks", () => {
+ it("should call onEditButtonClick when edit button is clicked", () => {
+ const onEditButtonClick = vi.fn();
+ render(
);
+ fireEvent.click(screen.getByText("Edit"));
+ expect(onEditButtonClick).toHaveBeenCalled();
+ });
+
+ it("should call onInputChange when input value changes", () => {
+ const onInputChange = vi.fn();
+ render(
);
+ fireEvent.change(screen.getByRole("textbox"), {
+ target: { value: "New Value" },
+ });
+ expect(onInputChange).toHaveBeenCalledWith("New Value");
+ });
+
+ it("should call onSaveButtonClick when save button is clicked", () => {
+ const onSaveButtonClick = vi.fn();
+ render(
+
+ );
+ fireEvent.click(screen.getByText("Save"));
+ expect(onSaveButtonClick).toHaveBeenCalled();
+ });
+ });
+
+ describe("Icons", () => {
+ it("should show icons when showIcons is true", () => {
+ render(
);
+ expect(screen.getByTestId("edit-icon")).toBeInTheDocument();
+ });
+
+ it("should position icons correctly based on iconPosition", () => {
+ const { getByTestId, rerender } = render(
+
+ );
+
+ const buttonWrapper = getByTestId("action-button");
+ expect(buttonWrapper.className).toContain("buttonReverse");
+
+ rerender(
);
+ expect(buttonWrapper.className).not.toContain("buttonReverse");
+ });
+
+ it("should render custom icons when provided", () => {
+ const CustomEditIcon = () =>
✎;
+ const CustomSaveIcon = () =>
✎;
+
+ const { rerender } = render(
+
+ );
+ expect(screen.getByTestId("custom-edit")).toBeInTheDocument();
+ expect(screen.queryByTestId("custom-save")).not.toBeInTheDocument();
+
+ rerender(
+
+ );
+
+ expect(screen.queryByTestId("custom-edit")).not.toBeInTheDocument();
+ expect(screen.getByTestId("custom-save")).toBeInTheDocument();
+ });
+ });
+
+ describe("Styling", () => {
+ it("should apply custom class names", () => {
+ const { container } = render(
+
+ );
+ expect(container.querySelector(".custom-wrapper")).toBeInTheDocument();
+ expect(container.querySelector(".custom-edit-btn")).toBeInTheDocument();
+ });
+ });
+
+ describe("Input Types", () => {
+ it("should render different input types", () => {
+ render(
);
+ expect(screen.getByRole("spinbutton")).toBeInTheDocument();
+ });
+ });
+
+ describe("Custom Labels", () => {
+ it("should render custom button labels", () => {
+ render(
+
+ );
+ expect(screen.getByText("Modify")).toBeInTheDocument();
+ });
});
});
diff --git a/src/InputClickEdit/InputClickEdit.tsx b/src/InputClickEdit/InputClickEdit.tsx
index b51c42e..3d592ea 100644
--- a/src/InputClickEdit/InputClickEdit.tsx
+++ b/src/InputClickEdit/InputClickEdit.tsx
@@ -1,4 +1,4 @@
-import { useState } from "react";
+import { useState, useEffect } from "react";
import { LuPencil } from "react-icons/lu";
import { LuCheck } from "react-icons/lu";
import cn from "classnames";
@@ -7,7 +7,7 @@ import styles from "./InputClickEdit.module.css";
type InputClickEditProps = {
className?: string;
- isEditing: boolean;
+ isEditing?: boolean;
inputClassName?: string;
editButtonClassName?: string;
saveButtonClassName?: string;
@@ -18,8 +18,8 @@ type InputClickEditProps = {
label?: string;
inputType?: string;
showIcons?: boolean;
- editIcon?: React.ReactNode;
- saveIcon?: React.ReactNode;
+ editIcon?: React.ElementType;
+ saveIcon?: React.ElementType;
iconPosition?: "left" | "right";
iconsOnly?: boolean;
onEditButtonClick?: () => void;
@@ -40,8 +40,8 @@ const InputClickEdit = ({
editButtonLabel = "Edit",
label = "",
showIcons = false,
- saveIcon =
,
- editIcon =
,
+ saveIcon,
+ editIcon,
iconsOnly = false,
iconPosition = "left",
onEditButtonClick = () => {},
@@ -49,6 +49,9 @@ const InputClickEdit = ({
onSaveButtonClick = () => {},
}: InputClickEditProps) => {
const [editing, setEditing] = useState
(isEditing);
+ useEffect(() => {
+ setEditing(isEditing);
+ }, [isEditing]);
const onEditClick = () => {
setEditing(true);
onEditButtonClick?.();
@@ -74,6 +77,9 @@ const InputClickEdit = ({
[styles.buttonReverse]: iconPosition === "right",
};
+ const EditIcon = editIcon || LuPencil;
+ const SaveIcon = saveIcon || LuCheck;
+
return (
{editing ? (
@@ -87,11 +93,12 @@ const InputClickEdit = ({
)}
@@ -99,11 +106,12 @@ const InputClickEdit = ({
{value}