본문으로 건너뛰기
입력 / chat-input

ChatInput

Enter 전송·자동 높이 조절·툴바 슬롯을 갖춘 AI 채팅 입력창.
입력chat-inputStatic specimenchat input채팅 입력textareaprompt
01 · Specimen

먼저 보고, 그다음 계약을 읽습니다

Enter 전송·자동 높이 조절·툴바 슬롯을 갖춘 AI 채팅 입력창.

Workbench 불러오는 중…
Component intent의도와 경계 읽기

uncontrolled <textarea> 를 감싼 forwardRef 컴포넌트로, 값은 내부 ref 로만 읽는다(defaultValue 로 초기화, onSubmit 은 trim 된 문자열을 넘긴 뒤 자동으로 비운다). Enter 로 전송하고 Shift+Enter 로 줄바꿈하며, 한국어 IME 조합 중(isComposing)에는 전송을 막는다. 입력에 따라 높이가 최대 240px 까지 자동으로 늘어난다(autosize). ref 는 DOM 이 아니라 ChatInputHandle({ focus(), clear() })을 노출해 외부에서 포커스·비우기를 명령형으로 제어한다. toolbarLeft/toolbarRight 슬롯으로 첨부·모드 선택·전송 버튼을 배치하고, 소비자가 넘긴 onKeyDown 이 preventDefault 하면 내부 Enter-to-send 를 건너뛰는 escape hatch 를 둔다.

02 · Use

예제

SSOT에 등록된 실제 API 기준 snippet입니다. standalone 배지만 독립 실행 단위이며, fragment는 주변 state·handler 문맥을 생략합니다.

01기본 — 전송 버튼 슬롯tsxfragment
기본 — 전송 버튼 슬롯
import { ChatInput, Button } from "@axe/ui";import { useRef } from "react";import type { ChatInputHandle } from "@axe/ui";function Composer({ onSend }: { onSend: (text: string) => void }) {  const ref = useRef<ChatInputHandle>(null);  return (    <ChatInput      ref={ref}      onSubmit={onSend}      toolbarRight={        <Button variant="primary" onClick={() => ref.current?.focus()}>          보내기        </Button>      }    />  );}
02CSS-only 껍데기 (비-React, 동작 없음)htmlfragment
CSS-only 껍데기 (비-React, 동작 없음)
<div class="axe-chat-input">  <textarea class="axe-chat-input__textarea" rows="1"            aria-label="메시지 입력" placeholder="메시지를 입력하세요…"></textarea>  <div class="axe-chat-input__toolbar">    <div><!-- toolbarLeft --></div>    <div><span class="axe-chat-input__hint">↵ 보내기 · ⇧↵ 줄바꿈</span></div>  </div></div>
03 · React

Props

TSX 소스가 진실입니다. 주요 export 컴포넌트의 public API만 노출합니다.

이름타입필수기본값설명
placeholderstring"메시지를 입력하세요…"textarea placeholder — i18n 친화.
onSubmit(value: string) => void전송 트리거 — Enter(Shift+Enter 는 줄바꿈)와 외부 버튼 양쪽에서 호출. 빈 값(trim 후)은 전송하지 않으며 전송 후 입력이 비워진다.
toolbarLeftReact.ReactNode툴바 좌측 슬롯 — 첨부·모드 선택 등.
toolbarRightReact.ReactNode툴바 우측 슬롯 — 전송 버튼 등(없으면 hint 만 표시).
hintReact.ReactNode"↵ 보내기 · ⇧↵ 줄바꿈"툴바 우측 힌트 텍스트. false/null 이면 미표시.
refReact.Ref<ChatInputHandle>DOM 이 아니라 명령형 핸들을 노출 — { focus(): void; clear(): void }.
...restOmit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, "onSubmit">defaultValue·aria-label·onKeyDown·onInput 등은 내부 textarea 로 전파(내부 핸들러와 체이닝). className 은 루트 .axe-chat-input 과 병합.
04 · Any stack

.axe-* 클래스 계약

React 밖에서도 같은 표면을 그리는 공개 계약입니다. stable은 minor 버전 안에서 이름을 바꾸지 않습니다.

클래스안정성용도
.axe-chat-inputstable입력창 루트(세로 flex, 토큰 테두리/배경). :focus-within 에서 accent 테두리 + var(--ring).
.axe-chat-input__textareastable실제 <textarea> — 테두리 0·투명 배경·resize:none, autosize 대상.
.axe-chat-input__toolbarstable하단 툴바 행(space-between 으로 좌/우 슬롯 배치).
.axe-chat-input__hintstable우측 힌트 텍스트(mono·tertiary·xs).
비-React 소비 노트
시각 껍데기(테두리·툴바·힌트·focus-within 링)는 .axe-chat-input__* 마크업만으로 재현되지만, Enter-to-send·autosize·IME 가드·clear() 는 모두 JS 동작이라 CSS-only 로는 재현되지 않는다.
05 · Inclusive

접근성

키보드, ARIA, 구현 노트를 함께 검토합니다.

Keyboard
  • Enter 로 전송(값이 비어있으면 무시)
  • Shift+Enter 로 줄바꿈
  • IME 조합 중 Enter 는 전송하지 않고 한글 확정에 사용
ARIA

textarea 에 aria-label 을 넘기지 않으면 "메시지 입력" 으로 기본화. 그 외 role 은 네이티브 <textarea> 를 그대로 사용.

Notes

소비자 onKeyDown 이 먼저 호출되고, 그것이 preventDefault 하면 내부 Enter-to-send 를 건너뛴다(커스텀 키 처리용 escape hatch). onInput 은 항상 autosize 를 수행한 뒤 소비자 onInput 도 호출한다.

06 · Judgment

권장 · 지양

권장
  • 전송 버튼은 toolbarRight 에 두고, 클릭 시 소비자 쪽에서도 값을 얻고 싶으면 ref 로 관리할 것.
  • 커스텀 키 처리가 필요하면 onKeyDown 에서 preventDefault 로 내부 Enter-to-send 를 끌 것.
지양
  • controlled value/onChange 를 기대하지 말 것 — uncontrolled 이며 값은 ref 로 읽는다.
  • 전송 후 수동으로 비우려 하지 말 것 — onSubmit 성공 시 자동으로 비워진다.
검색창을 열면 컴포넌트 인덱스를 불러옵니다.