Yugen UI

StreamingMarkdown

StreamingMarkdown hiển thị câu trả lời Markdown của AI ngay khi từng token về — không nháy ký hiệu thô, không chèn HTML, và không render lại cả bài mỗi lần có chữ mới.

Bộ phân tích tự viết (parseMarkdown, xuất riêng để test) dựng React element trực tiếp: đoạn văn, heading (lệch cấp qua headingOffset — không bao giờ sinh h1), đậm / nghiêng / gạch / code inline, link chỉ http · https · mailto (http / https mở tab mới, rel noreferrer noopener), danh sách lồng và việc cần làm, trích dẫn, bảng GFM có căn lề, đường kẻ và khối code dùng CodeBlock. Khi streaming: fence chưa đóng là khối code đang viết, ** / link / [1] dở dang không lộ ký hiệu, có con trỏ (đứng yên khi giảm chuyển động) và aria-busy; các khối đã ổn định giữ nguyên object nên React.memo bỏ qua render lại.

Import

Cài từ npm, chép mã nguồn vào dự án bằng @yugen-ui/cli hoặc shadcn CLI, hoặc import thẳng khi làm việc trong repo này.

TSX
// npm install yugen-uiimport { StreamingMarkdown, parseMarkdown } from "yugen-ui";

Biến thể

Mỗi ô là một mẫu độc lập: hover để Copy, hoặc bấm Code để xem mã nguồn.

Việc cần làm
  • Đã xong:
    Thêm token màu
  • Đã xong:
    Kiểm tra tương phản
  • Chưa xong:
    Viết tài liệu

Link không an toàn như bấm vào đây chỉ còn là chữ.

Việc cần làm & link không an toàn

Mục - [x] có icon + chữ ẩn “Đã xong”; link javascript: bị loại, chỉ còn nhãn.

Ghi chú: token colorBrandBackground đổi theo data-brand.

  • Light: Brand80
  • Dark: Brand70

Cỡ nhỏ

size="small" dùng caption1 — hợp cho chú thích, khối suy luận, thẻ trong panel.

Cách dùng

Nên
  • Truyền nguyên chuỗi đang dài dần và bật streaming tới khi nhận token cuối — component tự xử lý cú pháp dở dang.
  • Đặt headingOffset theo cấp tiêu đề của trang chứa (mặc định 2: # → h3).
  • Trong MessageBubble streaming, đặt caret={false} để không có hai con trỏ.
Không nên
  • Không tự nối HTML hay dùng dangerouslySetInnerHTML cho câu trả lời của model.
  • Không bật announceWhenDone khi đã nằm trong MessageScroller (sẽ đọc hai lần).
  • Không kỳ vọng đủ CommonMark: không có HTML thô, ảnh, link tham chiếu, code thụt lề.

Props

Prop · KiểuMặc địnhMô tả
childrenstringMặc định: —Nội dung Markdown.
streamingbooleanMặc định: falseChịu cú pháp dở dang, hiện con trỏ, aria-busy.
headingOffsetnumberMặc định: 2Cộng vào cấp heading; luôn ≥ h2.
citationsCitationSource[]Mặc định: —Nguồn cho [1] / [^1] → chip Citation. Thẻ xem nhanh của chip nạp lúc cần, ngay sau khi chip đầu tiên hiện.
breaksbooleanMặc định: trueXuống dòng đơn thành <br>.
caretbooleanMặc định: trueCon trỏ khi streaming.
size"small" | "medium"Mặc định: "medium"caption1 hoặc body1.
announceWhenDonebooleanMặc định: falseĐọc văn bản thuần qua live region khi stream xong.
parseMarkdown(text, { streaming })MdRootMặc định: —Bộ phân tích thuần; kèm sanitizeHref, markdownToPlainText.

Messages

Chữ có sẵn của component: nhãn, aria-label, thông báo cho trình đọc màn hình.

Mặc định là tiếng Anh. Đổi qua prop messages của YugenProvider, theo namespace bên dưới; messagesVi chứa bản tiếng Việt. Xem Ngôn ngữ giao diện.

messages.streamingMarkdown

Khoá · KiểuMặc định (tiếng Anh)messagesVi
newTabstring

Chữ ẩn sau link mở tab mới.

Mặc định (tiếng Anh)"(opens in new tab)"messagesVi"(mở tab mới)"
taskDonestring

Chữ ẩn trước mục danh sách việc đã xong / chưa xong.

Mặc định (tiếng Anh)"Done:"messagesVi"Đã xong:"
taskTodostringMặc định (tiếng Anh)"Not done:"messagesVi"Chưa xong:"
tablestring

Tên vùng cuộn của bảng.

Mặc định (tiếng Anh)"Table"messagesVi"Bảng"