diff --git a/src/assets/plus.svg b/src/assets/plus.svg new file mode 100644 index 0000000..f987f5d --- /dev/null +++ b/src/assets/plus.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/upload.svg b/src/assets/upload.svg new file mode 100644 index 0000000..cd1a085 --- /dev/null +++ b/src/assets/upload.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/upload_active.svg b/src/assets/upload_active.svg new file mode 100644 index 0000000..1393336 --- /dev/null +++ b/src/assets/upload_active.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/components/molecules/comment/CommentInput.tsx b/src/components/molecules/comment/CommentInput.tsx new file mode 100644 index 0000000..62abf23 --- /dev/null +++ b/src/components/molecules/comment/CommentInput.tsx @@ -0,0 +1,91 @@ +import { + ChangeEvent, + useEffect, + useLayoutEffect, + useRef, + useState, +} from 'react'; +import { textAreaVariants } from '@/components/atoms/textArea/TextArea'; + +interface CommentInputProps { + value: string; + onChange: (value: string) => void; + placeholder?: string; + minHeight: number; + maxHeight?: number; + maxLineCount?: number; +} + +export const CommentInput = ({ + value, + onChange, + placeholder, + minHeight, + maxHeight = minHeight, + maxLineCount, + ...props +}: CommentInputProps) => { + const wrapperRef = useRef(null); + const textAreaRef = useRef(null); + const [paddingTop, setPaddingTop] = useState(null); + + const handleTextChange = (event: ChangeEvent) => { + onChange(event.target.value); + }; + + useEffect(() => { + if (!wrapperRef.current) return; + const computedStyle = window.getComputedStyle(wrapperRef.current); + setPaddingTop(parseInt(computedStyle.paddingTop, 10) || null); + }, []); + + useLayoutEffect(() => { + const textArea = textAreaRef.current; + const wrapper = wrapperRef.current; + if (!textArea || !wrapper || paddingTop === null) return; + + const { scrollHeight, clientHeight } = textArea; + textArea.style.height = `${minHeight}px`; + + // 한 줄만 있을 때는 minHeight 유지 + if (scrollHeight === clientHeight) { + wrapper.style.paddingTop = `${paddingTop}px`; + return; + } + + const lineCount = Math.floor( + scrollHeight / parseInt(window.getComputedStyle(textArea).lineHeight, 10), + ); + + if (maxLineCount && lineCount >= maxLineCount) { + textArea.style.height = `${maxHeight + paddingTop}px`; + wrapper.style.paddingTop = '0px'; + } else { + textArea.style.height = `${lineCount === 1 ? minHeight : maxHeight}px`; + wrapper.style.paddingTop = `${paddingTop}px`; + } + }, [value, paddingTop]); + + return ( +
+