Yugen UI

NotificationCenter

NotificationCenter là chuông thông báo kèm số chưa đọc, mở bảng thông báo nhóm theo ngày — Popover trên desktop, bottom sheet trên mobile.

Mỗi thông báo có avatar hoặc icon theo intent, tiêu đề, nội dung, thời gian tương đối, chấm chưa đọc (kèm chữ ẩn) và hành động Đánh dấu đã đọc / Bỏ. Lọc Tất cả / Chưa đọc, Đánh dấu tất cả đã đọc, trạng thái trống (Empty), đang tải (SkeletonList qua useSpinDelay) và lỗi (ErrorState có Thử lại). Thời gian tính sau khi mount hoặc theo prop now — không lệch hydration. Thông báo mới được đọc polite qua useAnnounce. useNotifications() là kho nhỏ cho demo.
Yugen Labs · thử nghiệmComponent này nằm ngoài SemVer: API có thể đổi ở một bản minor, và thay đổi sẽ được ghi trong Có gì mới. Chính sách phiên bản

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 { NotificationCenter, useNotifications, type NotificationItem } 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.

Đang tải & lỗi

Khung xương chỉ hiện khi chờ > 300ms; lỗi có nút Thử lại khi truyền onRetry.

Cách dùng

Nên
  • Viết tiêu đề nói rõ ai làm gì; nội dung chi tiết để ở body.
  • Cho bấm vào thông báo để tới đúng nơi và tự đánh dấu đã đọc.
  • Dùng intent warning / error chỉ cho việc cần người dùng xử lý.
Không nên
  • Không dùng NotificationCenter cho phản hồi tức thời của thao tác — dùng Toast.
  • Không đếm cả thông báo đã đọc trên chuông.
  • Không tính “bây giờ” trong render trên server — truyền now hoặc để component tự lấy sau khi mount.

Props

Prop · KiểuMặc địnhMô tả
itemsNotificationItem[]Mặc định: —{ id, title, body?, time, read?, author?, icon?, intent?, href? }.
onMarkRead / onMarkAllRead / onDismiss(id) => void / () => void / (id) => voidMặc định: —Hành động (controlled).
onItemClick(item) => voidMặc định: —Bấm thông báo; tự gọi onMarkRead nếu chưa đọc.
loading / error / onRetryboolean / ReactNode / () => voidMặc định: —Trạng thái tải và lỗi.
nowDate | numberMặc định: —Mốc thời gian cố định (SSR, test).
open / defaultOpen / onOpenChangebooleanMặc định: —Trạng thái bảng.
mode / breakpoint"auto" | "popover" | "sheet" / "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | numberMặc định: "auto" / "3xl"Popover hay bottom sheet; breakpoint dùng token như Sheet (số px đã lỗi thời, bỏ ở 1.0).
title / footer / announcestring / ReactNode / booleanMặc định: "Notifications" / — / trueTiêu đề, chân bảng, đọc thông báo mới.
useNotifications(initial){ items, unreadCount, add, markRead, markAllRead, dismiss, clear, bind }Mặc định: —Kho nhỏ cho demo; trải bind vào NotificationCenter.

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

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

Tiêu đề bảng, tên nút chuông và tên danh sách (khi không truyền title).

Mặc định (tiếng Anh)"Notifications"messagesVi"Thông báo"
triggerUnread(title: string, unread: number) => string

Tên nút chuông khi còn thông báo chưa đọc.

Mặc định (tiếng Anh)(title, unread) => `${title}, ${unread} unread`messagesVi(title, unread) => `${title}, ${unread} chưa đọc`
closestring

Nhãn nút đóng bottom sheet.

Mặc định (tiếng Anh)"Close"messagesVi"Đóng"
markAllReadstringMặc định (tiếng Anh)"Mark all as read"messagesVi"Đánh dấu tất cả đã đọc"
filterstring

Tên nhóm tab lọc.

Mặc định (tiếng Anh)"Filter notifications"messagesVi"Lọc thông báo"
allstringMặc định (tiếng Anh)"All"messagesVi"Tất cả"
unreadstring

Tab "chưa đọc" (số lượng được nối thêm phía sau).

Mặc định (tiếng Anh)"Unread"messagesVi"Chưa đọc"
loadErrorstring

Tiêu đề ErrorState khi tải lỗi.

Mặc định (tiếng Anh)"Couldn't load notifications"messagesVi"Không tải được thông báo"
emptyTitlestringMặc định (tiếng Anh)"No notifications yet"messagesVi"Chưa có thông báo"
emptyDescriptionstringMặc định (tiếng Anh)"New notifications will appear here."messagesVi"Thông báo mới sẽ xuất hiện ở đây."
emptyUnreadTitlestringMặc định (tiếng Anh)"You're all caught up"messagesVi"Bạn đã đọc hết"
emptyUnreadDescriptionstringMặc định (tiếng Anh)"No unread notifications."messagesVi"Không còn thông báo chưa đọc."
unreadSuffixstring

Chữ ẩn nối sau tiêu đề mục chưa đọc, cho trình đọc màn hình.

Mặc định (tiếng Anh)", unread"messagesVi", chưa đọc"
markReadstring

Tooltip nút đánh dấu đã đọc.

Mặc định (tiếng Anh)"Mark as read"messagesVi"Đánh dấu đã đọc"
markReadItem(title: string) => string

Tên nút đánh dấu đã đọc của một mục.

Mặc định (tiếng Anh)(title) => `Mark as read: ${title}`messagesVi(title) => `Đánh dấu đã đọc: ${title}`
dismissstring

Tooltip nút bỏ thông báo.

Mặc định (tiếng Anh)"Dismiss"messagesVi"Bỏ thông báo"
dismissItem(title: string) => string

Tên nút bỏ thông báo của một mục.

Mặc định (tiếng Anh)(title) => `Dismiss: ${title}`messagesVi(title) => `Bỏ thông báo: ${title}`
announceOne(title: string) => string

Đọc qua live region khi có một thông báo mới.

Mặc định (tiếng Anh)(title) => `New notification: ${title}`messagesVi(title) => `Thông báo mới: ${title}`
announceMany(count: number) => string

Đọc qua live region khi có nhiều thông báo mới.

Mặc định (tiếng Anh)(count) => (count === 1 ? "1 new notification" : `${count} new notifications`)messagesVi(count) => `${count} thông báo mới`
justNowstringMặc định (tiếng Anh)"Just now"messagesVi"Vừa xong"
minutesAgo(minutes: number) => stringMặc định (tiếng Anh)(minutes) => (minutes === 1 ? "1 minute ago" : `${minutes} minutes ago`)messagesVi(minutes) => `${minutes} phút trước`
hoursAgo(hours: number) => stringMặc định (tiếng Anh)(hours) => (hours === 1 ? "1 hour ago" : `${hours} hours ago`)messagesVi(hours) => `${hours} giờ trước`
todaystringMặc định (tiếng Anh)"Today"messagesVi"Hôm nay"
yesterdaystringMặc định (tiếng Anh)"Yesterday"messagesVi"Hôm qua"