Yugen UI

AsyncContent & ErrorState

Một chỗ cho mọi trạng thái của dữ liệu bất đồng bộ — chưa tải, đang tải, có dữ liệu, rỗng, lỗi — với khung xương không nháy và lỗi luôn có lối thoát.

AsyncContent nhận status và hiển thị đúng một trạng thái. Đang tải dùng useSpinDelay: phản hồi nhanh hơn 300ms thì giữ nguyên trạng thái trước, không có khung xương nháy lên. Lỗi mặc định là ErrorState (role="alert") với nút Thử lại tự vào trạng thái loading; rỗng mặc định là Empty. Nếu nút đang được focus bị thay, focus ở lại trong vùng thay vì rơi về đầu trang.

Bấm “Tải thành viên” để bắt đầu.

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 { AsyncContent, ErrorState, type AsyncStatus } 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.

Mất kết nối

Không tải được bình luận. Kiểm tra mạng rồi thử lại.

ErrorState với thử lại

onRetry trả về Promise → nút Thử lại tự hiện spinner tới khi xong; focus không rời nút.

Không tải được biểu đồ

Dữ liệu tuần này tạm thời chưa có.

ErrorState gọn

size="small" cho thẻ, panel, dòng trong danh sách.

Không có kết quả

Trạng thái rỗng tuỳ biến

Rỗng không phải lỗi: nói vì sao trống và gợi ý bước tiếp theo.

Cách dùng

Nên
  • Phân biệt rõ rỗng và lỗi — rỗng là kết quả hợp lệ, lỗi cần lối thoát.
  • Lỗi nói chuyện gì đã xảy ra và cho thử lại ngay tại chỗ.
  • Truyền skeleton khớp bố cục nội dung thật.
Không nên
  • Không để vùng trắng trơn khi lỗi hoặc rỗng.
  • Không hiện thông báo kỹ thuật (mã lỗi, stack) làm tiêu đề.
  • Không dùng role="alert" cho lỗi tải lần đầu của nhiều vùng cùng lúc — sẽ đọc dồn dập.

Props

Prop · KiểuMặc địnhMô tả
status"idle" | "loading" | "success" | "error" | "empty"Mặc định: —Trạng thái cần hiển thị.
childrenReactNode | () => ReactNodeMặc định: —Nội dung khi success; dạng hàm chỉ được gọi khi success.
skeletonReactNodeMặc định: SkeletonText 3 dòngHiển thị khi loading (sau delay).
errorReactNode | ({ retry, retrying }) => ReactNodeMặc định: ErrorStateThay giao diện lỗi.
empty / idleReactNodeMặc định: —Giao diện rỗng (mặc định Empty) / chưa tải (mặc định trống).
onRetry() => void | PromiseMặc định: —Truyền cho nút Thử lại của ErrorState mặc định.
delay / minDurationnumberMặc định: 300 / 500Chờ bao lâu mới hiện loader / đã hiện thì giữ tối thiểu bao lâu (ms) — xem useSpinDelay.
loadingLabelstringMặc định: "Loading…"Câu đọc cho trình đọc màn hình khi khung xương hiện.
ErrorState.title / description / iconReactNodeMặc định: —Nội dung lỗi; có giá trị mặc định tiếng Việt.
ErrorState.onRetry / retrying / retryLabel() => void | Promise · boolean · ReactNodeMặc định: —Nút Thử lại; Promise hoặc retrying → nút ở trạng thái loading.
ErrorState.secondaryActionReactNodeMặc định: —Hành động phụ (Báo lỗi, Quay lại…).
ErrorState.variant / size"default" | "alert" · "small" | "medium"Mặc định: "default" · "medium"alert thêm role="alert"; small là một dòng gọn.

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.errorState

Khoá · KiểuMặc định (tiếng Anh)messagesVi
titlestringMặc định (tiếng Anh)"Couldn't load content"messagesVi"Không tải được nội dung"
descriptionstringMặc định (tiếng Anh)"Something went wrong while connecting to the server. Check your connection and try again."messagesVi"Đã có lỗi khi kết nối tới máy chủ. Kiểm tra mạng rồi thử lại."
retrystring

Nút thử lại (khi có onRetry).

Mặc định (tiếng Anh)"Retry"messagesVi"Thử lại"

messages.asyncContent

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

Câu đọc cho trình đọc màn hình khi khung xương hiện.

Mặc định (tiếng Anh)"Loading…"messagesVi"Đang tải…"
emptyTitlestring

Tiêu đề / mô tả của trạng thái rỗng mặc định.

Mặc định (tiếng Anh)"No data yet"messagesVi"Chưa có dữ liệu"
emptyDescriptionstringMặc định (tiếng Anh)"New content will appear here."messagesVi"Khi có nội dung mới, chúng sẽ xuất hiện ở đây."