-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathInputFile.tsx
More file actions
95 lines (82 loc) · 2.73 KB
/
InputFile.tsx
File metadata and controls
95 lines (82 loc) · 2.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"use client";
import { ChangeEvent, useRef, useState, useEffect } from "react";
import Image from "next/image";
import { cls } from "@/lib/utils";
import { FaPlus as PlusImage } from "react-icons/fa6";
import { InputFileProps } from "@/types/formType";
import ImageEdit from "../../../public/icons/image_edit.svg";
const InputFile = ({ label, size, id, name, value, onChange }: InputFileProps) => {
const imageRef = useRef<HTMLImageElement>(null);
const inputRef = useRef<HTMLInputElement>(null);
const [preview, setPreview] = useState<string | null>(null);
useEffect(() => {
if (value && typeof value === "string") {
setPreview(value);
}
}, [value]);
const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
const file = e.currentTarget.files?.[0];
if (file) {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = () => {
if (reader.result && typeof reader.result === "string") {
setPreview(reader.result);
onChange(file);
}
};
}
e.currentTarget.value = "";
};
const handleClick = () => {
if (inputRef.current) {
inputRef.current.click();
}
};
return (
<div className="flex flex-col gap-2">
{label && (
<p
className={cls(
"text-black03",
size === "profile" ? "mb-8 text-xl font-bold md:mb-5 md:text-3xl" : "text-lg font-medium md:text-xl"
)}
>
{label}
</p>
)}
<div className={`relative flex ${inputFileSize.size[size]} cursor-pointer overflow-hidden rounded-md`}>
<label htmlFor={id} className="grid size-full cursor-pointer place-items-center gap-[24px] bg-[#F5F5F5]">
<PlusImage className="size-[17px] text-violet01" />
</label>
<input
id={id}
type="file"
name={name}
onChange={handleFileChange}
accept="image/*"
ref={inputRef}
className="absolute left-0 top-0 z-[2] size-full cursor-pointer opacity-0"
/>
{preview && (
<>
<span
className="absolute left-0 top-0 z-[3] flex size-full items-center justify-center bg-black bg-opacity-60 opacity-0 transition-opacity duration-300 hover:opacity-100"
onClick={handleClick}
>
<Image src={ImageEdit} alt="이미지 수정" className="size-[30px]" />
</span>
<Image ref={imageRef} src={preview} fill alt="이미지 미리보기" className="z-0 object-cover" />
</>
)}
</div>
</div>
);
};
export const inputFileSize = {
size: {
todo: "size-[76px]",
profile: "size-[100px] md:size-[182px]",
},
};
export default InputFile;