본문으로 건너뛰기
채팅 · AI / streaming-markdown

StreamingMarkdown

스트리밍 중인 LLM 응답을 Prose 로 감싸고 끝에 깜박이는 cursor 를 얹는 얇은 래퍼.
채팅 · AIstreaming-markdownStatic specimenstreaming markdown스트리밍cursor커서
01 · Specimen

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

스트리밍 중인 LLM 응답을 Prose 로 감싸고 끝에 깜박이는 cursor 를 얹는 얇은 래퍼.

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

마크다운 파싱은 하지 않는다 — 이미 파싱된 children(react-markdown 결과 등)을 그대로 <Prose> 안에 렌더하고, isStreaming=true 일 때만 본문 끝에 axe-stream-cursor span 을 붙인다. 즉 '스트리밍처럼 보이게 하는 표시 층'일 뿐 파서·버퍼링·토큰 조합은 호출 측 책임이다. 루트는 Prose(axe-prose)라 산문 타이포그래피를 그대로 상속하며, maxWidth 를 100% 로 풀어 채팅 컬럼 폭에 맞춘다. 보통 단독으로 쓰기보다 AgentExecutor 가 assistant 메시지에 자동으로 사용한다.

02 · Use

예제

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

01기본 (스트리밍 중)tsxfragment
기본 (스트리밍 중)
import { StreamingMarkdown } from "@axe/ui";import Markdown from "react-markdown";<StreamingMarkdown isStreaming={isPending}>  <Markdown>{partialText}</Markdown></StreamingMarkdown>
02완료 상태 (cursor 없음)tsxfragment
완료 상태 (cursor 없음)
import { StreamingMarkdown } from "@axe/ui";import Markdown from "react-markdown";<StreamingMarkdown isStreaming={false}>  <Markdown>{finalText}</Markdown></StreamingMarkdown>
03CSS-only (비-React)htmlfragment
CSS-only (비-React)
<div class="axe-prose axe-streaming">  <p>부분 응답 텍스트…</p>  <span class="axe-stream-cursor" aria-hidden="true"></span></div>
03 · React

Props

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

이름타입필수기본값설명
isStreamingbooleanfalsetrue 면 children 끝에 깜박이는 cursor(axe-stream-cursor, aria-hidden)를 노출. 파싱/버퍼링은 하지 않음.
childrenReact.ReactNode이미 파싱된 마크다운/노드. Prose 본문으로 그대로 렌더 — 문자열이면 마크다운 파싱 없이 텍스트로 나온다.
...restReact.HTMLAttributes<HTMLDivElement>나머지는 Prose 루트 <div> 로 전파. 단 style 을 넘기면 기본 style(maxWidth:100%)을 덮어씀(rest 가 뒤에 전개).
04 · Any stack

.axe-* 클래스 계약

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

클래스안정성용도
.axe-stream-cursorstable본문 끝 깜박이는 cursor span(장식, aria-hidden). axe-blink keyframe(1s steps) 로 점멸.
비-React 소비 노트
루트에 붙는 axe-streaming 은 스타일 규칙이 없는 마커 클래스이므로, 실제 시각 계약은 Prose 의 axe-prose + cursor 의 axe-stream-cursor 뿐이다. CSS-only 로 재현하려면 axe-prose 래퍼 안에 본문을 넣고 끝에 <span class="axe-stream-cursor">를 붙이면 된다(파싱/스트리밍은 서버 렌더 측 책임).
05 · Inclusive

접근성

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

ARIA

cursor span 은 aria-hidden 순수 장식 — 보조기술에 읽히지 않는다. StreamingMarkdown 자체는 live region 을 두지 않으므로, 스트리밍 진행 상태의 음성 고지는 상위(AgentExecutor 의 axe-agent-executor__streaming-hint role="status")가 담당한다.

Notes

cursor 점멸(axe-blink)은 reset.css 의 전역 prefers-reduced-motion 블록(*, ::before, ::after 의 animation-duration 강제 축소)에 걸려 모션 축소 환경에서 사실상 멈춘다 — 컴포넌트 개별 가드는 없다.

06 · Judgment

권장 · 지양

권장
  • 마크다운 파싱은 호출 측(react-markdown 등)에서 하고 그 결과를 children 으로 넘긴다.
  • isStreaming 은 마지막 assistant 메시지의 진행 여부와 1:1 로 연동한다.
지양
  • 문자열을 그대로 넘기면 마크다운이 파싱되지 않는다 — 원문 텍스트로 보인다.
  • 진행 고지를 이 컴포넌트에 기대지 말 것 — live region 은 상위(AgentExecutor)가 준다.
검색창을 열면 컴포넌트 인덱스를 불러옵니다.