StreamingMarkdown
먼저 보고, 그다음 계약을 읽습니다
스트리밍 중인 LLM 응답을 Prose 로 감싸고 끝에 깜박이는 cursor 를 얹는 얇은 래퍼.
Component intent의도와 경계 읽기
마크다운 파싱은 하지 않는다 — 이미 파싱된 children(react-markdown 결과 등)을 그대로 <Prose> 안에 렌더하고, isStreaming=true 일 때만 본문 끝에 axe-stream-cursor span 을 붙인다. 즉 '스트리밍처럼 보이게 하는 표시 층'일 뿐 파서·버퍼링·토큰 조합은 호출 측 책임이다. 루트는 Prose(axe-prose)라 산문 타이포그래피를 그대로 상속하며, maxWidth 를 100% 로 풀어 채팅 컬럼 폭에 맞춘다. 보통 단독으로 쓰기보다 AgentExecutor 가 assistant 메시지에 자동으로 사용한다.
예제
SSOT에 등록된 실제 API 기준 snippet입니다. standalone 배지만 독립 실행 단위이며, fragment는 주변 state·handler 문맥을 생략합니다.
import { StreamingMarkdown } from "@axe/ui";import Markdown from "react-markdown";<StreamingMarkdown isStreaming={isPending}> <Markdown>{partialText}</Markdown></StreamingMarkdown>import { StreamingMarkdown } from "@axe/ui";import Markdown from "react-markdown";<StreamingMarkdown isStreaming={false}> <Markdown>{finalText}</Markdown></StreamingMarkdown><div class="axe-prose axe-streaming"> <p>부분 응답 텍스트…</p> <span class="axe-stream-cursor" aria-hidden="true"></span></div>Props
TSX 소스가 진실입니다. 주요 export 컴포넌트의 public API만 노출합니다.
| 이름 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
isStreaming | boolean | — | false | true 면 children 끝에 깜박이는 cursor(axe-stream-cursor, aria-hidden)를 노출. 파싱/버퍼링은 하지 않음. |
children | React.ReactNode | — | — | 이미 파싱된 마크다운/노드. Prose 본문으로 그대로 렌더 — 문자열이면 마크다운 파싱 없이 텍스트로 나온다. |
...rest | React.HTMLAttributes<HTMLDivElement> | — | — | 나머지는 Prose 루트 <div> 로 전파. 단 style 을 넘기면 기본 style(maxWidth:100%)을 덮어씀(rest 가 뒤에 전개). |
.axe-* 클래스 계약
React 밖에서도 같은 표면을 그리는 공개 계약입니다. stable은 minor 버전 안에서 이름을 바꾸지 않습니다.
| 클래스 | 안정성 | 용도 |
|---|---|---|
.axe-stream-cursor | stable | 본문 끝 깜박이는 cursor span(장식, aria-hidden). axe-blink keyframe(1s steps) 로 점멸. |
접근성
키보드, ARIA, 구현 노트를 함께 검토합니다.
cursor span 은 aria-hidden 순수 장식 — 보조기술에 읽히지 않는다. StreamingMarkdown 자체는 live region 을 두지 않으므로, 스트리밍 진행 상태의 음성 고지는 상위(AgentExecutor 의 axe-agent-executor__streaming-hint role="status")가 담당한다.
cursor 점멸(axe-blink)은 reset.css 의 전역 prefers-reduced-motion 블록(*, ::before, ::after 의 animation-duration 강제 축소)에 걸려 모션 축소 환경에서 사실상 멈춘다 — 컴포넌트 개별 가드는 없다.