AI Chat
대화형 AI 표면 — 헤더·메시지 스레드·입력 + 대화 상태 매트릭스(빈·대기·생성 중·오류)와 스트리밍 시각 언어. 챗 전용 접근성(role=log·부분 텍스트 비낭독)을 갖춥니다.
마지막 업데이트 2026-06-14
데모#
상단 상태 컨트롤로 빈 화면·대기·생성 중·오류를 전환해 대화 매트릭스를 검수합니다. 추천 칩이나 입력으로 메시지를 보내면 생각 중 → 부분 텍스트 스트리밍 → 안착까지 실제로 재생됩니다(중단 가능). 실제 LLM 호출은 없습니다(UI Reference).
구성#
| 영역 | 역할 |
|---|---|
| 헤더 | 어시스턴트 정체성(Avatar·이름) + 현재 상태(상태 도트·라벨) |
| 스레드 | role="log" 메시지 로그 — 어시스턴트 좌측 정렬+Avatar, 사용자 우측 primary 버블, 타임스탬프 |
| 빈 화면 | 인사 + 추천 프롬프트 칩 — 막다른 길 대신 다음 행동 제시 |
| 생성 중 | thinking 도트 → 부분 텍스트 + 캐럿 스트리밍, 입력은 중단 버튼 |
| 오류 | FormMessage(error)(Tier 2) + 다시 시도 |
| 입력 | AI Chat Input — 전송/중단, Enter 전송·Shift+Enter 줄바꿈 |
상태#
대화는 행복 경로 하나가 아니라 상태 매트릭스로 다룹니다. 데모의 상태 컨트롤로 전환합니다.
| 상태 | 트리거 | 표현 |
|---|---|---|
| 빈 화면 | 첫 진입, 0턴 | 인사 + 추천 프롬프트 칩(클릭 시 전송) |
| 대기 | 입력 대기·응답 완료 | 대화 스레드 + 입력 활성, 헤더 “대기 중” |
| 생성 중 | 전송 직후 | thinking 도트 → 부분 텍스트 스트리밍(캐럿) + 헤더 도트 펄스 + 스레드 aria-busy, 입력은 중단 |
| 오류 | 응답 실패 | FormMessage(error)(Tier 2) + 다시 시도 |
“생각 중”은 독립 상태가 아니라 생성 중의 첫 페이즈입니다 — 부분 텍스트가 도착하면 같은 버블에서 도트가 텍스트로 교체되고, 중단하면 누적분이 잘린 채 확정됩니다.
메시지 위계 — 3-tier#
메시지 위계가 챗에서 어떻게 나타나는지.
| Tier | 범위 | 컴포넌트 | 이 패턴에서 |
|---|---|---|---|
| 1 필드 | 입력 | 전송 버튼 비활성 | 빈 메시지 전송 차단(AiChatInput 내장) — 토스트 대신 차단형 |
| 2 폼·제출 | 한 번의 전송·응답 | FormMessage | 응답 생성 실패 — role="alert" + 다시 시도 |
| 3 페이지 | 화면·세션 | Alert·Toast | 연결 끊김·서비스 점검 등 전역 장애(여기선 미사용) |
적응형 동작#
| 컨테이너 폭 | 버블 |
|---|---|
≥ 520px | 버블 최대폭 70% — 좌우 여백 확보 |
< 520px | 버블 최대폭 82cqw — 좁은 폭에서도 가독 유지 |
스레드는 컨테이너 쿼리로 자기 폭에 반응하며(뷰포트 아님), 새 메시지·스트리밍마다 자동으로 하단 스크롤합니다(포커스 이동 없음). 데모의 기기 컨트롤(데스크탑·태블릿·모바일)로 폭을 제약해 각 기기 레이아웃을 미리볼 수 있고, 터치 기기(태블릿·모바일)에서는 실제 기기처럼 스크롤바 거터를 숨깁니다.
접근성#
| 계약 | 구현 |
|---|---|
| 메시지 로그 | 메시지만 담는 role="log" + aria-live="polite" — 시간순 추가를 polite 전달(assertive는 읽던 내용을 끊어 부적합). 오류 alert·추천 칩은 로그 밖 형제로 둬 이중 낭독 방지 |
| 화자 구분 | 각 버블에 보조기술 전용 화자 접두(“나:/어시스턴트:”) — 시각은 정렬·색, 스레드 내 Avatar는 장식이라 aria-hidden |
| 스트리밍 낭독 | 부분 텍스트 버블은 aria-hidden + 스레드 aria-busy="true" — 토큰마다 낭독(잼) 방지, 완성 메시지만 1회 낭독 |
| 생각 중 | 도트는 aria-hidden, 진행은 aria-busy로 전달 |
| 오류 전달 | FormMessage(error)가 role="alert"로 즉시 낭독 |
| 입력 | aria-label="메시지 입력", Enter 전송·Shift+Enter 줄바꿈, 한글 조합 중 Enter 무시 |
| 포커스 | 전송 후 입력창 포커스 유지 — 새 메시지가 포커스를 빼앗지 않음 |
| 모션 | thinking 도트·캐럿·펄스·메시지 등장은 transform/opacity만, prefers-reduced-motion에서 정지(텍스트·상태 라벨 유지) |
사용 컴포넌트#
AiChatInput · Avatar · Button(다시 시도) · FormMessage(오류, Tier 2) ·
SegmentedButton(데모 컨트롤). 메시지 버블·스레드·추천 칩은 패턴 전용 표면이며 새 컴포넌트 없이
semantic 토큰으로 구성합니다. 실제 LLM 호출은 없습니다 — UI Reference입니다.