Skip to content

Commit

Permalink
feat: undo using react-hook-form
Browse files Browse the repository at this point in the history
  • Loading branch information
ChaeyeonAhn committed Sep 30, 2024
1 parent a2f6a0a commit f40977a
Showing 1 changed file with 33 additions and 56 deletions.
89 changes: 33 additions & 56 deletions packages/web/src/common/components/Forms/PhoneInput.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
--- 사용 방법 (예시) ---
<PhoneInput
<NewPhoneInput
label="전화번호"
placeholder="010-XXXX-XXXX"
value={phone}
Expand All @@ -20,20 +20,19 @@ import React, {
} from "react";

import isPropValid from "@emotion/is-prop-valid";

import { FormProvider, useForm } from "react-hook-form";

import styled, { css } from "styled-components";

import ErrorMessage from "@sparcs-students/web/common/components/Forms/_atomic/ErrorMessage";
import Label from "@sparcs-students/web/common/components/Forms/_atomic/Label";
import ErrorMessage from "./_atomic/ErrorMessage";
import Label from "./_atomic/Label";

export interface PhoneInputProps
extends InputHTMLAttributes<HTMLInputElement | HTMLTextAreaElement> {
label?: string;
placeholder: string;
disabled?: boolean;
value?: string;
handleChange?: (value: string) => void;
setErrorStatus?: (hasError: boolean) => void;
onChange?: ChangeEventHandler<HTMLInputElement>;
}

Expand Down Expand Up @@ -85,27 +84,17 @@ const InputWrapper = styled.div`
`;

// Component
const PhoneInput2: React.FC<
PhoneInputProps & {
setErrorStatus?: (hasError: boolean) => void;
optional?: boolean;
}
> = ({
const PhoneInput: React.FC<PhoneInputProps> = ({
label = "",
placeholder,
disabled = false,
value = "",
handleChange = () => {}, // setValue
onChange = undefined, // display results (complicated)
setErrorStatus = () => {},
optional = false,
onChange = undefined, // display results (complicated)
...props
}) => {
const formCtx = useForm({
defaultValues: {
phoneNumber: "",
},
});
const [error, setError] = useState("");
const [touched, setTouched] = useState(false);
const inputRef = useRef<HTMLInputElement | null>(null);
const cursorRef = useRef<number>(0);
Expand All @@ -116,33 +105,32 @@ const PhoneInput2: React.FC<
}
}, [value]);

useEffect(() => {
const hasError = !!error;
if (setErrorStatus) {
setErrorStatus(hasError);
}
}, [error, setErrorStatus]);

useEffect(() => {
if (touched) {
const isValidFormat =
/^(\d{3}-\d{4}-\d{4})$/.test(value) ||
/^\d*$/.test(value.replace(/-/g, ""));

if (!optional && !value) {
formCtx.setError("phoneNumber", {
message: "필수로 채워야 하는 항목입니다",
});
if (!value) {
setError("필수로 채워야 하는 항목입니다");
} else if (!isValidFormat) {
formCtx.setError("phoneNumber", {
message: "숫자만 입력 가능합니다",
});
setError("숫자만 입력 가능합니다");
} else if (
value.replace(/-/g, "").length !== 11 ||
value.slice(0, 3) !== "010"
) {
formCtx.setError("phoneNumber", {
message: "유효하지 않은 전화번호입니다",
});
setError("유효하지 않은 전화번호입니다");
} else {
formCtx.clearErrors("phoneNumber");
setError("");
}
setErrorStatus(!!formCtx.formState.errors.phoneNumber);
}
}, [value, touched, formCtx]);
}, [value, touched]);

const handleBlur = () => {
setTouched(true);
Expand All @@ -151,15 +139,13 @@ const PhoneInput2: React.FC<
const formatValue = (nums: string) => {
const digits = nums.replace(/\D/g, "");
let formattedInput = "";

if (digits.length <= 3) {
formattedInput = digits;
} else if (digits.length <= 7) {
formattedInput = `${digits.slice(0, 3)}-${digits.slice(3)}`;
} else if (digits.length <= 11) {
formattedInput = `${digits.slice(0, 3)}-${digits.slice(3, 7)}-${digits.slice(7)}`;
}

return formattedInput;
};

Expand Down Expand Up @@ -191,29 +177,20 @@ const PhoneInput2: React.FC<
<InputWrapper>
{label && <Label>{label}</Label>}
<InputWrapper>
<FormProvider {...formCtx}>
<Input
{...formCtx.register("phoneNumber", {
required: true,
onBlur: handleBlur,
})}
placeholder={placeholder}
onChange={onChange ?? handlePhoneValueChange}
disabled={disabled}
value={formatValue(value)}
hasError={!!formCtx.formState.errors.phoneNumber}
ref={inputRef}
{...props}
/>
{formCtx.formState.errors.phoneNumber && (
<ErrorMessage>
{formCtx.formState.errors.phoneNumber.message}
</ErrorMessage>
)}
</FormProvider>
<Input
placeholder={placeholder}
hasError={!!error}
disabled={disabled}
value={formatValue(value)}
onChange={onChange ?? handlePhoneValueChange}
onBlur={handleBlur}
ref={inputRef}
{...props}
/>
{error && <ErrorMessage>{error}</ErrorMessage>}
</InputWrapper>
</InputWrapper>
);
};

export default PhoneInput2;
export default PhoneInput;

0 comments on commit f40977a

Please sign in to comment.