From 8d283064a099c6bd4ca26d4d3a6c1c63660e0abc Mon Sep 17 00:00:00 2001 From: Ilia Mashkov Date: Tue, 31 Mar 2026 12:54:43 +0300 Subject: [PATCH] feat(LoginForm): use component as prop pattern to add customizable input and button components --- src/features/auth/ui/LoginForm/LoginForm.tsx | 100 +++++++++++++++---- 1 file changed, 81 insertions(+), 19 deletions(-) diff --git a/src/features/auth/ui/LoginForm/LoginForm.tsx b/src/features/auth/ui/LoginForm/LoginForm.tsx index 5b1c8f7..bfe4e7f 100644 --- a/src/features/auth/ui/LoginForm/LoginForm.tsx +++ b/src/features/auth/ui/LoginForm/LoginForm.tsx @@ -1,16 +1,52 @@ import { + selectEmail, selectFormValid, + selectPassword, selectStatusIsLoading, useAuthStore, } from "../../model"; -import type { SubmitEvent, ChangeEvent } from "react"; +import { + type SubmitEvent, + type ChangeEvent, + type HTMLAttributes, + type InputHTMLAttributes, + type ButtonHTMLAttributes, + cloneElement, + type ReactElement, +} from "react"; + +export type InputAttributes = InputHTMLAttributes; +export type ButtonAttributes = ButtonHTMLAttributes; + +export interface Props { + InputComponent?: ReactElement; + ButtonComponent?: ReactElement; +} + +const DefaultInputComponent = ({ + value, + onChange, + ["aria-label"]: ariaLabel, +}: InputAttributes) => ( + +); + +const DefaultButtonComponent = ({ disabled }: ButtonAttributes) => ( + + {InputComponent ? ( + cloneElement(InputComponent, { + type: "email", + value: email, + onChange: handleEmailChange, + "aria-label": "Email", + }) + ) : ( + + )} + {InputComponent ? ( + cloneElement(InputComponent, { + type: "password", + value: password, + onChange: handlePasswordChange, + "aria-label": "Password", + }) + ) : ( + + )} + {ButtonComponent ? ( + cloneElement(ButtonComponent, { + type: "submit", + disabled: disabled, + children: "Login", + }) + ) : ( + + Login + + )} ); }