diff --git a/pages/index.tsx b/pages/index.tsx index b390ee55..0271c9a6 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,5 +1,17 @@ -const HomePage = () => { - return <>Hello World; +import type { NextPage } from 'next'; + +import WriteInput from '@/src/components/Input/WriteInput'; +import { useInput } from '@/src/hooks/useInput'; + +const HomePage: NextPage = () => { + const testInputProps = useInput({ + id: 'test', + defaultValue: '', + }); + + return ( + + ); }; export default HomePage; diff --git a/plopfile.mjs b/plopfile.mjs index d2e3eb12..3f197c12 100644 --- a/plopfile.mjs +++ b/plopfile.mjs @@ -1,4 +1,3 @@ -/* eslint-disable import/no-anonymous-default-export */ export default function (plop) { const getComponentName = { type: 'input', diff --git a/src/assets/icons/submit.svg b/src/assets/icons/submit.svg new file mode 100644 index 00000000..039b1dea --- /dev/null +++ b/src/assets/icons/submit.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/components/Input/WriteInput/index.tsx b/src/components/Input/WriteInput/index.tsx new file mode 100644 index 00000000..20c40fef --- /dev/null +++ b/src/components/Input/WriteInput/index.tsx @@ -0,0 +1,115 @@ +import type { ChangeEvent, HTMLAttributes, KeyboardEvent } from 'react'; +import { useMemo, useRef, useState } from 'react'; +import { assignInlineVars } from '@vanilla-extract/dynamic'; + +import { MAIN_INPUT_MAX_LENGTH } from '@/src/constants/config'; +import type { UseInputReturn } from '@/src/hooks/useInput'; +import { COLORS } from '@/src/styles/tokens'; + +import Icon from '../../SvgIcon'; +import * as style from './style.css'; + +interface WriteInputProps extends HTMLAttributes { + inputProps: UseInputReturn; + placeholder?: string; + maxLength?: number; +} + +const WriteInput = ({ + inputProps, + placeholder, + maxLength = MAIN_INPUT_MAX_LENGTH, +}: WriteInputProps) => { + const { id, value } = inputProps; + const inputRef = useRef(null); + const [textareaHeight, setTextareaHeight] = useState({ + row: 1, + lineBreak: {}, + }); + + const handleResize = (e: ChangeEvent) => { + const { scrollHeight, clientHeight, value } = e.target; + + if (value.length === 0) { + setTextareaHeight((prev) => ({ + row: 1, + lineBreak: { ...prev.lineBreak, [e.target.value.length]: false }, + })); + } + + if (scrollHeight > clientHeight) { + setTextareaHeight((prev) => ({ + row: prev.row + 1, + lineBreak: { ...prev.lineBreak, [value.length - 1]: true }, + })); + } + + if (textareaHeight.lineBreak[value.length]) { + setTextareaHeight((prev) => ({ + row: prev.row - 1, + lineBreak: { ...prev.lineBreak, [value.length]: false }, + })); + } + }; + + const handleKeydownEnter = (e: KeyboardEvent) => { + if (e.code === 'Enter') { + setTextareaHeight((prev) => ({ + row: prev.row + 1, + lineBreak: { ...prev.lineBreak, [value.length]: true }, + })); + } + }; + + const isValid = useMemo(() => value.length > 0, [value.length]); + + return ( +
+
+