diff --git a/public/svgs/icon_eye_on.svg b/public/svgs/icon_eye_on.svg new file mode 100644 index 00000000..36cf499d --- /dev/null +++ b/public/svgs/icon_eye_on.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/assets/svgs/IconEyeOn.tsx b/src/assets/svgs/IconEyeOn.tsx new file mode 100644 index 00000000..c1011c27 --- /dev/null +++ b/src/assets/svgs/IconEyeOn.tsx @@ -0,0 +1,20 @@ +import * as React from "react"; +import type { SVGProps } from "react"; +const SvgIconEyeOn = (props: SVGProps) => ( + + + + + + + + + + +); +export default SvgIconEyeOn; diff --git a/src/assets/svgs/index.tsx b/src/assets/svgs/index.tsx index 3b52f8a9..81efbf1c 100644 --- a/src/assets/svgs/index.tsx +++ b/src/assets/svgs/index.tsx @@ -8,6 +8,7 @@ export { default as IconBnk } from "./IconBnk"; export { default as IconCalendar } from "./IconCalendar"; export { default as IconCheck } from "./IconCheck"; export { default as IconEyeOff } from "./IconEyeOff"; +export { default as IconEyeOn } from "./IconEyeOn"; export { default as IconHanna } from "./IconHanna"; export { default as IconIbk } from "./IconIbk"; export { default as IconIm } from "./IconIm"; diff --git a/src/components/commons/input/textField/TextField.styled.ts b/src/components/commons/input/textField/TextField.styled.ts index c0867bf6..e921e45d 100644 --- a/src/components/commons/input/textField/TextField.styled.ts +++ b/src/components/commons/input/textField/TextField.styled.ts @@ -50,6 +50,13 @@ export const TextUnit = styled.p` ${({ theme }) => theme.fonts["body2-normal-medi"]}; `; +export const ToggleVisibilityIcon = styled.section` + position: absolute; + right: 1.6rem; + + width: 2.4rem; +`; + export const TextCap = styled.p` ${Generators.flexGenerator("row", "center", "end")} diff --git a/src/components/commons/input/textField/TextField.tsx b/src/components/commons/input/textField/TextField.tsx index 1e51ef41..a56446ab 100644 --- a/src/components/commons/input/textField/TextField.tsx +++ b/src/components/commons/input/textField/TextField.tsx @@ -1,5 +1,6 @@ -import React, { ChangeEvent, InputHTMLAttributes, useRef } from "react"; +import React, { ChangeEvent, InputHTMLAttributes, useRef, useState } from "react"; import * as S from "./TextField.styled"; +import { IconEyeOff, IconEyeOn } from "@assets/svgs"; export interface TextFieldProps extends InputHTMLAttributes { onChange: (e: React.ChangeEvent) => void; @@ -9,9 +10,11 @@ export interface TextFieldProps extends InputHTMLAttributes { unit?: "time" | "ticket" | "amount"; // 단위 : "분", "매", "원" filter?: (value: string) => string; cap?: false | true; + onToggleClick?: () => void; } const TextField = ({ + type = "input", name, value, onChange, @@ -21,11 +24,13 @@ const TextField = ({ unit, filter, cap, + onToggleClick, ...rest }: TextFieldProps) => { const label = unit === "time" ? "분" : unit === "ticket" ? "매" : "원"; const inputRef = useRef(null); + const [isPasswordVisible, setIsPasswordVisible] = useState(type !== "password"); // 비밀번호 입력값 보이기/숨기기 // 값 입력될 떄 const handleOnInput = (e: ChangeEvent) => { @@ -70,6 +75,11 @@ const TextField = ({ } }; + // 비밀번호 입력값 보이기 여부 관리 + const handlePasswordVisibility = () => { + setIsPasswordVisible((prev) => !prev); + }; + return ( @@ -80,10 +90,19 @@ const TextField = ({ onChange={handleOnInput} maxLength={maxLength} placeholder={placeholder} + type={isPasswordVisible ? "text" : "password"} // 비밀번호 보이기 여부를 위해 타입에 조건을 걸음 {...rest} /> - {!narrow && !unit && value && } + {!narrow && !unit && value && type !== "password" && ( + + )} {unit && {label}} + {type === "password" && ( + + )} {maxLength && cap && {`${(value as string).length}/${maxLength}`}} diff --git a/src/pages/test/TestPage.tsx b/src/pages/test/TestPage.tsx index 952142d9..502adb13 100644 --- a/src/pages/test/TestPage.tsx +++ b/src/pages/test/TestPage.tsx @@ -18,6 +18,7 @@ const TestPage = () => { const [round, setRound] = useState(1); const [selectedDate, setSelectedDate] = useState(null); const { showToast, isToastVisible } = useToast(); + const [pwdStatus, setPwdStatus] = useState(false); const handleChangeInput = (e: ChangeEvent) => { setInputValue(e.target.value); @@ -34,14 +35,16 @@ const TestPage = () => { const handleDateChange = (value: Dayjs | null) => { setSelectedDate(value); }; - console.log(selectedDate); + console.log(inputValue); return (