From 676d06a8a96c18d8365f0049bd8bb6f2c8246134 Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 23 Mar 2022 20:15:55 -0300 Subject: [PATCH] WIP: refactor TextField with HOC component --- src/components/forms/PasswordField.tsx | 13 ++ src/components/forms/PasswordInput.tsx | 18 +- src/components/forms/TextField.tsx | 183 ++++++++++++------ .../forms/__stories__/FormField.stories.mdx | 2 +- .../forms/__stories__/TextField.tsx | 2 +- src/components/forms/index.ts | 2 +- src/pages/signup.tsx | 4 +- 7 files changed, 155 insertions(+), 69 deletions(-) create mode 100644 src/components/forms/PasswordField.tsx diff --git a/src/components/forms/PasswordField.tsx b/src/components/forms/PasswordField.tsx new file mode 100644 index 0000000..92f00f3 --- /dev/null +++ b/src/components/forms/PasswordField.tsx @@ -0,0 +1,13 @@ +import Field, { type BaseFieldProps } from "./Field"; +import PasswordInput from "./PasswordInput"; +import { useFormContext } from "react-hook-form"; + +type PasswordFieldProps = BaseFieldProps>; + +// export default function PasswordField({ name }: PasswordFieldProps) { +// const { +// formState: { errors }, +// } = useFormContext(); + +// return
PasswordField
; +// } diff --git a/src/components/forms/PasswordInput.tsx b/src/components/forms/PasswordInput.tsx index c38751d..125d07a 100644 --- a/src/components/forms/PasswordInput.tsx +++ b/src/components/forms/PasswordInput.tsx @@ -6,10 +6,7 @@ import { } from "react-icons/ri"; import { IconButton } from "components/Button"; -type PasswordInputProps = Omit< - React.ComponentProps, - "startDecoration" | "endDecoration" -> & { +type PasswordInputProps = ElementProps & { position?: "right" | "left"; show?: boolean; hideAdornment?: boolean; @@ -28,8 +25,17 @@ export default function PasswordInput({ ); const decorationProps = { - startDecoration: position === "left" ? adornment : null, - endDecoration: position === "right" ? adornment : null, + startDecoration: ( + <> + {props?.startDecoration} + {position === "left" ? adornment : null} + + ), + endDecoration: ( + <> + {props?.endDecoration} {position === "right" ? adornment : null} + + ), }; return ( diff --git a/src/components/forms/TextField.tsx b/src/components/forms/TextField.tsx index e167c66..afbe77c 100644 --- a/src/components/forms/TextField.tsx +++ b/src/components/forms/TextField.tsx @@ -1,9 +1,10 @@ -import { ComponentProps } from "react"; +import React, { ComponentProps } from "react"; import { type RegisterOptions, useFormContext } from "react-hook-form"; import TextInput from "./TextInput"; import LengthAdornment from "./LengthAdornment"; import BaseField, { type BaseFieldProps } from "./Field"; import clsx from "clsx"; +import PasswordInput from "./PasswordInput"; type TextFieldProps = BaseFieldProps< Omit, "register"> & { @@ -12,66 +13,132 @@ type TextFieldProps = BaseFieldProps< } >; -export default function TextField({ - name, - label, - registerOptions = {}, - required, - max, - min, - maxLength, - minLength, - showLength, - value, - ...inputProps -}: TextFieldProps) { - const { disabled, onBlur, onChange } = inputProps; +function WithTextField< + T extends React.ComponentType> +>(Input: T = TextInput) { + return function TextField({ + name, + label, + required, + max, + maxLength, + min, + minLength, + value, + registerOptions, + showLength, + ...inputProps + }: TextFieldProps) { + const { disabled, onBlur, onChange } = inputProps; + const { + formState: { errors }, + register, + watch, + } = useFormContext(); - const { - formState: { errors }, - register, - watch, - } = useFormContext(); - - return ( - - - {inputProps?.endDecoration} - - } - {...inputProps} - /> - } - /> - ); + return ( + + + {inputProps?.endDecoration} + + } + {...inputProps} + /> + } + /> + ); + }; } +export const TextField = WithTextField(); +export const PasswordField = WithTextField(PasswordInput); + +// export default function TextField({ +// name, +// label, +// registerOptions = {}, +// required, +// max, +// min, +// maxLength, +// minLength, +// showLength, +// value, +// ...inputProps +// }: TextFieldProps) { +// const { disabled, onBlur, onChange } = inputProps; + +// const { +// formState: { errors }, +// register, +// watch, +// } = useFormContext(); + +// return ( +// +// +// {inputProps?.endDecoration} +// +// } +// {...inputProps} +// /> +// } +// /> +// ); +// } + type LengthFieldProps = { value?: string; maxLength?: number; diff --git a/src/components/forms/__stories__/FormField.stories.mdx b/src/components/forms/__stories__/FormField.stories.mdx index d266a9e..a13f500 100644 --- a/src/components/forms/__stories__/FormField.stories.mdx +++ b/src/components/forms/__stories__/FormField.stories.mdx @@ -1,6 +1,6 @@ import { Meta } from "@storybook/addon-docs"; import Form from "../Form"; -import TextField from "../TextField"; +import { TextField } from "../TextField"; import Button from "components/Button"; diff --git a/src/components/forms/__stories__/TextField.tsx b/src/components/forms/__stories__/TextField.tsx index 5ffede3..b5528bb 100644 --- a/src/components/forms/__stories__/TextField.tsx +++ b/src/components/forms/__stories__/TextField.tsx @@ -1,6 +1,6 @@ import { type ComponentStory, type ComponentMeta } from "@storybook/react"; import { screen, userEvent } from "@storybook/testing-library"; -import TextField from "../TextField"; +import { TextField } from "../TextField"; import Form from "../Form"; export default { diff --git a/src/components/forms/index.ts b/src/components/forms/index.ts index de74dc3..d404d56 100644 --- a/src/components/forms/index.ts +++ b/src/components/forms/index.ts @@ -3,4 +3,4 @@ export { default as TextInput } from "./TextInput"; export { default as PasswordInput, PasswordAdornment } from "./PasswordInput"; export { default as LengthAdornment } from "./LengthAdornment"; export { default as Label } from "./Label"; -export { default as TextField } from "./TextField"; +export { TextField, PasswordField } from "./TextField"; diff --git a/src/pages/signup.tsx b/src/pages/signup.tsx index 34d75c2..f55d69d 100644 --- a/src/pages/signup.tsx +++ b/src/pages/signup.tsx @@ -1,5 +1,5 @@ import { type NextPage } from "next"; -import { Form, TextField } from "components/forms"; +import { Form, TextField, PasswordField } from "components/forms"; import Button from "components/Button"; import { useToast } from "components/toast"; import { BsArrowRight as RightIcon } from "react-icons/bs"; @@ -27,7 +27,7 @@ const SignUp: NextPage = () => {

Sign Up

onSubmit={submission} className="flex flex-col gap-4"> -