feat(RegisterForm): add custom input and button components support with component as prop pattern

This commit is contained in:
Ilia Mashkov
2026-04-02 12:46:45 +03:00
parent e7ac79049d
commit 4d95159c4f

View File

@@ -1,22 +1,45 @@
import { useState, type ChangeEvent, type SubmitEvent } from "react";
import { import {
cloneElement,
useState,
type ChangeEvent,
type ReactElement,
type SubmitEvent,
} from "react";
import {
selectEmail,
selectFormValid, selectFormValid,
selectPassword,
selectStatusIsLoading, selectStatusIsLoading,
useAuthStore, useAuthStore,
} from "../../model"; } from "../../model";
import {
DefaultInputComponent,
type InputAttributes,
} from "../DefaultInput/DefaultInput";
import {
DefaultButtonComponent,
type ButtonAttributes,
} from "../DefaultButton/DefaultButton";
export interface Props {
InputComponent?: ReactElement<InputAttributes>;
ButtonComponent?: ReactElement<ButtonAttributes>;
}
/** /**
* Register form component * Register form component
*/ */
export function RegisterForm() { export function RegisterForm({ InputComponent, ButtonComponent }: Props) {
const { formData, setEmail, setPassword, register } = useAuthStore(); const { setEmail, setPassword, register } = useAuthStore();
const email = useAuthStore(selectEmail);
const password = useAuthStore(selectPassword);
const [confirmedPassword, setConfirmedPassword] = useState(""); const [confirmedPassword, setConfirmedPassword] = useState("");
const formValid = useAuthStore(selectFormValid); const formValid = useAuthStore(selectFormValid);
const isLoading = useAuthStore(selectStatusIsLoading); const isLoading = useAuthStore(selectStatusIsLoading);
const passwordMatch = formData?.password?.value === confirmedPassword; const passwordMatch = password === confirmedPassword;
const disabled = isLoading || !formValid || !passwordMatch; const disabled = isLoading || !formValid || !passwordMatch;
const handleEmailChange = (e: ChangeEvent<HTMLInputElement>) => { const handleEmailChange = (e: ChangeEvent<HTMLInputElement>) => {
@@ -38,27 +61,63 @@ export function RegisterForm() {
return ( return (
<form aria-label="Register Form" onSubmit={handleSubmit}> <form aria-label="Register Form" onSubmit={handleSubmit}>
<input {/* EMAIL */}
{InputComponent ? (
cloneElement(InputComponent, {
value: email,
onChange: handleEmailChange,
"aria-label": "Email",
})
) : (
<DefaultInputComponent
type="email" type="email"
aria-label="Email" value={email}
value={formData?.email?.value ?? ""}
onChange={handleEmailChange} onChange={handleEmailChange}
aria-label="Email"
/> />
<input )}
{/* PASSWORD */}
{InputComponent ? (
cloneElement(InputComponent, {
value: password,
onChange: handlePasswordChange,
"aria-label": "Password",
})
) : (
<DefaultInputComponent
type="password" type="password"
aria-label="Password" value={password}
value={formData?.password?.value ?? ""}
onChange={handlePasswordChange} onChange={handlePasswordChange}
aria-label="Password"
/> />
<input )}
{/* PASSWORD */}
{InputComponent ? (
cloneElement(InputComponent, {
value: confirmedPassword,
onChange: handleConfirmChange,
"aria-label": "Confirm",
})
) : (
<DefaultInputComponent
type="password" type="password"
aria-label="Confirm"
value={confirmedPassword} value={confirmedPassword}
onChange={handleConfirmChange} onChange={handleConfirmChange}
aria-label="Confirm"
/> />
<button type="submit" aria-label="Register" disabled={disabled}> )}
{/* BUTTON */}
{ButtonComponent ? (
cloneElement(ButtonComponent, {
type: "submit",
disabled: disabled,
})
) : (
<DefaultButtonComponent disabled={disabled}>
Register Register
</button> </DefaultButtonComponent>
)}
</form> </form>
); );
} }