diff --git a/client/src/components/atoms/TextArea.tsx b/client/src/components/atoms/TextArea.tsx index c8f7ceaa..0d600593 100644 --- a/client/src/components/atoms/TextArea.tsx +++ b/client/src/components/atoms/TextArea.tsx @@ -1,33 +1,34 @@ import styled from "@emotion/styled"; import TextareaAutosize from "react-textarea-autosize"; +import { w, h, text, padding } from "@/styles"; export const TextAreaFixedsize = styled.textarea` - width: 100%; - height: 100%; - padding: 10px 15px; + ${w("fill")} + ${h("fill")} + ${padding.vertical(10)} + ${padding.horizontal(15)} resize: none; border: none; background: transparent; - font-size: 11px; - font-weight: 500; - color: ${props => props.theme.colors.black}; + ${text.subtitle} + ${text.black} ::placeholder { font-family: "Noto Sans KR", sans-serif; - color: ${props => props.theme.colors.gray300}; + ${text.gray300} } `; export const TextAreaAutosize = styled(TextareaAutosize)` - width: 100%; + ${w("fill")} + max-height: 100%; outline: none; resize: none; border: none; background: transparent; - font-size: 12px; - font-weight: 500; - color: ${props => props.theme.colors.black}; + ${text.body} + ${text.black} ::placeholder { font-family: "Noto Sans KR", sans-serif; - color: ${props => props.theme.colors.gray300}; + ${text.gray300} } `; diff --git a/client/src/components/molecules/ChatInput.tsx b/client/src/components/molecules/ChatInput.tsx index a16b6762..f721aa5c 100644 --- a/client/src/components/molecules/ChatInput.tsx +++ b/client/src/components/molecules/ChatInput.tsx @@ -1,20 +1,49 @@ import React, { useCallback, useMemo } from "react"; -import styled from "@emotion/styled"; +import { css } from "@emotion/react"; import { EmoticonIcon, SendIcon } from "@/assets"; -import { Box, Divider, TextAreaAutosize } from "@/components/atoms"; +import { Divider, TextAreaAutosize } from "@/components/atoms"; import { useInput } from "@/common/hooks"; +import { + w, + h, + padding, + scroll, + scrollBar, + bg, + justify, + align, + row, + gap, + border, + round, +} from "@/styles"; -const InputForm = styled.form` - display: flex; - flex-direction: row; - gap: 10px; - width: 100%; - height: 100%; - padding: 10px 15px; - background-color: ${props => props.theme.colors.white}; - border: solid 1px ${props => props.theme.colors.gray300}; - border-radius: 5px; +const inputBoxStyle = css` + ${w("fill")} + max-height: 30%; + ${padding(10)} + ${bg.white100} + ${justify.start} + ${align.start} +`; + +const formStyle = css` + ${row} + ${gap(10)} + ${w("fill")} + ${h("fill")} + ${padding.vertical(10)} + ${padding.horizontal(15)} + ${bg.white} + ${border.gray300} + ${round.md} +`; + +const textAreaScrollStyle = css` + ${scroll.y} + ${scrollBar} + overflow-y: scroll; `; interface Props { @@ -24,9 +53,12 @@ interface Props { export const ChatInput: React.FC = ({ send }) => { const { input, setValue } = useInput(); - // TODO: disable send button based on `validated` + /** TODO: disable send button based on `validated` */ const validated = useMemo(() => input.value.trim().length > 0, [input.value]); + /** @constant 클라이언트와 서버에서 사용하는 채팅 메시지의 최대 길이를 지정합니다. */ + const maxMessageLength = 500; + const sendCurrent = useCallback(() => { if (!validated) return; send(input.value.trim()); @@ -34,27 +66,31 @@ export const ChatInput: React.FC = ({ send }) => { }, [input.value, validated]); return ( - - - { - if ( - e.key === "Enter" && - !e.shiftKey && - !e.nativeEvent.isComposing - ) { - e.preventDefault(); - sendCurrent(); - } - }} - value={input.value} - onChange={input.onChange} - /> - +
+
+
+ { + if ( + e.key === "Enter" && + !e.shiftKey && + !e.nativeEvent.isComposing + ) { + e.preventDefault(); + sendCurrent(); + } + }} + value={input.value} + maxLength={maxMessageLength} + onChange={input.onChange} + /> + +
{/* TODO: Replace with button / add hover, actove effect */} - - + +
); }; diff --git a/interface/src/admin/agenda/common.ts b/interface/src/admin/agenda/common.ts index 1a71613d..2e7bfb8e 100644 --- a/interface/src/admin/agenda/common.ts +++ b/interface/src/admin/agenda/common.ts @@ -32,10 +32,10 @@ export type AdminAgenda = z.infer; * some description about admin agenda create schema goes here */ export const AdminAgendaCreate = z.object({ - title: z.string().min(1), - content: z.string().min(1), - resolution: z.string().min(1), - choices: z.array(z.string().min(1)).min(1), + title: z.string().min(1).max(255), + content: z.string().min(1).max(255), + resolution: z.string().min(1).max(255), + choices: z.array(z.string().min(1).max(255)).min(1), voters: z.object({ total: z.array(z.number()), }), diff --git a/interface/src/agenda/template/common.ts b/interface/src/agenda/template/common.ts index 79b08452..83041e8e 100644 --- a/interface/src/agenda/template/common.ts +++ b/interface/src/agenda/template/common.ts @@ -20,11 +20,11 @@ export type AgendaTemplate = z.infer; * some description about agenda template create schema goes here */ export const AgendaTemplateCreate = z.object({ - templateName: z.string(), - title: z.string(), - content: z.string(), - resolution: z.string(), - choices: z.array(z.string()), + templateName: z.string().min(1).max(255), + title: z.string().min(1).max(255), + content: z.string().min(1).max(255), + resolution: z.string().min(1).max(255), + choices: z.array(z.string().min(1).max(255)), }); export type AgendaTemplateCreate = z.infer; diff --git a/interface/src/chat/client.ts b/interface/src/chat/client.ts index 08b4d907..2e8170fa 100644 --- a/interface/src/chat/client.ts +++ b/interface/src/chat/client.ts @@ -7,7 +7,7 @@ import { Message } from "./common"; * description */ export const Send = z.object({ - message: z.string().min(1), + message: z.string().min(1).max(500), }); export type Send = z.infer; export const SendCb = Message; diff --git a/interface/src/user/tag/common.ts b/interface/src/user/tag/common.ts index 7c1db5cd..3caf9f2a 100644 --- a/interface/src/user/tag/common.ts +++ b/interface/src/user/tag/common.ts @@ -18,8 +18,8 @@ export type UserTag = z.infer; * some description about user tag create schema goes here */ export const UserTagCreate = z.object({ - title: z.string(), - description: z.string(), + title: z.string().min(1).max(255), + description: z.string().min(1).max(255), users: z.array(z.number()), }); export type UserTagCreate = z.infer;