WhatsNew
آخرین تغییرات سامانه — همهٔ نسخهها با تیترهای کوتاه و همیشه باز، تصویر اختیاری و تاریخ شمسی
معرفی
WhatsNewBell تریگر آخرین تغییرات، WhatsNewPanel تاریخچهٔ کامل و WhatsNewSpotlight نمایش یک انتشار مهم است.
منطق «دیدهشده» در useWhatsNew قرار دارد؛ آن را یکبار در بالای همهٔ سطحها فراخوانی کنید.
صفحهٔ کامل از ReleaseTimeline استفاده میکند.
همهٔ نسخههای منتشرشده و همهٔ تغییرهای هر نسخه همیشه دیده میشوند. هر تغییر یک تیتر کوتاه از changes.text
است. دکمهٔ «جزئیات بیشتر»، حالت جمعشده، آکاردئون و پاراگراف توضیح در این نماها وجود ندارد. نسخه و تاریخ هویت انتشارند؛
هیچ تغییر به عنوان انتشار تبدیل نمیشود. تصویر و لینک اختیاری به همان تیتر تعلق دارند.
چه زمانی استفاده کنیم
- برای اطلاع از تغییرهایی که کاربر در محصول میبیند یا استفاده میکند
- برای مرور همهٔ نسخههای قبلی و ثبت یکبارهٔ دیدهشدن خبرهای تازه
چه زمانی استفاده نکنیم
- برای اعلان کاربر مانند پایان تحلیل؛ از
NotificationCenterاستفاده کنید - برای پیام موقت یک صفحه؛ از
Bannerاستفاده کنید - برای تغییرهای داخلی مهندسی که رفتار محصول را تغییر نمیدهند
import { WhatsNewBell } from '@partodata/ui/whats-new'
// Header: the version chip, before NotificationCenter's bell. Never a second bell.
<WhatsNewBell variant="version" version="2.4" unseenCount={feed.announcedCount} onClick={() => setOpen(true)} />استفاده
در هدر از variant="version" استفاده کنید تا برچسب نسخه پنل را باز کند. نشانهٔ تازه فقط برای انتشارهای دیدهنشده است؛
زنگولهٔ اعلانهای کاربر مستقل میماند. variant="icon" برای سطح بدون مرکز اعلان مناسب است.
'use client'
import * as React from 'react'
import { useWhatsNew } from '@partodata/ui/hooks/use-whats-new'
import { WhatsNewBell, WhatsNewPanel, WhatsNewSpotlight } from '@partodata/ui/whats-new'
import { whatsNewFeed } from '@/content/whats-new'
export function ProductChanges() {
const [open, setOpen] = React.useState(false)
const trigger = React.useRef<HTMLButtonElement>(null)
const releases = useWhatsNew({ notes: whatsNewFeed.notes, productKey: whatsNewFeed.product })
return (
<>
<WhatsNewBell
ref={trigger}
variant="version"
version={releases.notes[0]?.version}
unseenCount={releases.announcedCount}
onClick={() => setOpen(true)}
/>
<WhatsNewPanel
open={open}
onOpenChange={setOpen}
notes={releases.notes}
unseenIds={releases.unseen.map((note) => note.id)}
onMarkAllSeen={releases.markAllSeen}
triggerRef={trigger}
viewAllHref="/changelog"
/>
<WhatsNewSpotlight note={releases.spotlight} onSeen={releases.markSpotlightShown} triggerRef={trigger} />
</>
)
}برای لینکهای داخلی، linkComponent را به لینک روتر محصول وصل کنید. viewAllHref مسیر تاریخچهٔ کامل است و
تغییری را مخفی یا باز نمیکند. detailsHref قدیمی در مودال منسوخ است؛ همهٔ تیترها از ابتدا دیده میشوند.
محتوای کوتاه و اولویت
هر انتشار را با نسخه، تاریخ و یک آرایهٔ changes بنویسید. تیتر باید بگوید کاربر اکنون چه کاری میتواند انجام دهد یا چه
چیزی تغییر کرده است. Markdown درونخطی برای تأکید، کد و لینک مجاز است؛ تیتر تودرتو، فهرست داخلی یا توضیح بلند ننویسید.
priority اختیاری و عدد متناهی است: عدد بزرگتر زودتر دیده میشود و مقدار پیشفرض 0 است. تساوی، ترتیب ورودی را حفظ
میکند. اگر هیچ تغییر اولویت صریح نداشته باشد، ترتیب نوع فعلی برقرار است: تغییر مهم، قابلیت جدید، بهبود، رفع اشکال.
گروهبندی نوع، اولویت صریح را به هم نمیزند. نسخهها همچنان از جدید به قدیماند و اولویت فقط داخل یک نسخه اعمال میشود.
import { defineReleaseFeed } from '@partodata/ui/release-notes'
export const whatsNewFeed = defineReleaseFeed({
product: 'monitoring',
notes: [
{
id: 'campaign-compare',
date: '2026-07-21',
version: '4.2.0',
channel: 'announce',
changes: [
{
type: 'feature',
text: 'دو کمپین را کنار هم مقایسه کنید',
priority: 20,
media: { src: '/whats-new/campaign-compare.svg', alt: 'نمودار مقایسهٔ دو کمپین' },
cta: { label: 'مقایسهٔ کمپینها', href: '/compare' },
},
{ type: 'fix', text: 'نامهای بلند در کارت کامل نمایش داده میشوند', priority: 10 },
],
},
],
})media.src و media.alt اجباریاند. تصویر کامل و بدون برش، با سقف ارتفاع و بارگذاری تنبل نمایش داده میشود؛ تیتر برای
بارگذاری تصویر منتظر نمیماند. aspectRatio نسبت عرض به ارتفاع است و پیشفرضش 16 / 9 است.
فیلدهای قدیمی details و body برای سازگاری داده حفظ شدهاند و نمایش داده نمیشوند. summary فقط در یادداشت بدون
changes، یک تیتر جایگزین میشود؛ کنار تغییرهای موجود پاراگراف اضافه نمیآید. یادداشت مهاجرتشدهٔ قدیمی عنوانش را در
changes.text نگه میدارد. برای محتوای جدید از همین تیترهای کوتاه استفاده کنید.
سطحها
پنل تاریخچه
هر نسخه یک کارت با نسخه، تاریخ و نشان «جدید» دارد؛ همهٔ انواع تغییر از ابتدا تیتر دارند. تصویر اختیاری همان تغییر با
سقف ارتفاع 8rem نمایش داده میشود. چیزی پشت شمارش بهبودها یا رفع اشکال پنهان نمیماند.
نسخهٔ 3.9.0،
ورود دومرحلهای برای همهٔ حسابها الزامی شد
قواعد هشدار روی همهٔ پلتفرمهای متصل اعمال میشوند
کلیدهای API قدیمی پایان مهر غیرفعال میشوند
بازهٔ نگهداری دادههای خام 12 ماه شد
فایلهای CSV با حروف فارسی درست در اکسل باز میشوند
نمایش انتشار مهم
مودال با «تغییرات نسخهٔ …» نامگذاری میشود و همهٔ تیترهای همان نسخه را دارد. تصویر تا 14rem ارتفاع میگیرد و بدنه
روی گوشی پیمایش میشود. اگر فقط یک CTA وجود داشته باشد در فوتر اقدام اصلی است؛ چند CTA کنار تیترهای خود میمانند.
دکمهٔ «متوجه شدم» و ✕ و Escape مودال را میبندند.
مودال فقط برای ریلیزهای بزرگ است و حداکثر ماهی یکبار. بهمحض نمایش، «دیدهشده» علامت میخورد — نه هنگام بستن.
نشان نسخه
پیشفرض dot است؛ شمارنده را فقط برای چند خبر مستقل به کار ببرید. نشان عددی بالای 9 به «9+» خلاصه میشود و مقدار
کامل در نام دسترسیپذیر باقی میماند.
پیشفرض dot است، نه شمارنده. عدد یعنی صفی که باید خالی شود؛ نقطه یعنی چیز خوبی منتشر شده است.
کانال انتشار و دیدهشدن
silent خبر را در تاریخچه نگه میدارد؛ announce نشان نسخه را روشن میکند؛ spotlight علاوه بر آن یک مودال باز
میکند و حداکثر یکبار در 30 روز مجاز است. همهٔ کانالها در تاریخچه دیده میشوند. یادداشت آینده کنار گذاشته میشود.
شناسهٔ id تغییرناپذیر، کلید دیدهشدن است. هوک را دوبار فراخوانی نکنید. اولین بازدید ساکت است؛ بازشدن پنل واترمارک را
جلو میبرد و مودال هنگام نمایش ثبت میشود، نه هنگام بستن. هویت ذخیرهسازی را از productKey پایدار بگیرید.
در حالت کنترلشده هر دو وضعیت واترمارک و مودال دیدهشده را وصل کنید؛ راهنمای هوک را ببینید.
Props
WhatsNewBell
بقیهٔ propهای <button> روی عنصر ریشه پخش میشوند و ref هم به همان میرسد. زنگوله یک Button فقطآیکون
(ghost) روی نردبان کنترلهاست: بدون Provider مربعی 30 پیکسلی و داخل ردیفی با ControlSizeProvider همقد همان ردیف،
با همان رنگ آیکون و outline فوکوس بقیهٔ دکمههای نوار بالا (تا 3٫x دکمهای دستساز و 36 پیکسلی بود).
WhatsNewPanel
WhatsNewSpotlight
useWhatsNew
خروجی هوک: notes (منتشرشدهها) · unseen · announced · announcedCount · hasUnseen ·
spotlight · lastSeenId · isFirstVisit · isReady · markSeen · markAllSeen ·
markSpotlightShown. شرح کامل هر کدام در صفحهٔ هوک آمده.
دو موردش خلاف انتظار است و ارزش گفتن دارد: unseen شامل یادداشتهای silent هم هست (آنها
در پنل نشانهٔ دیدهنشده میگیرند ولی زنگوله را روشن نمیکنند — برای همین announcedCount را به
WhatsNewBell بدهید، نه unseen.length)، و announced مودالی را که همین حالا نشان داده شده
حذف میکند (یادداشتی که در مودال دیده شده دیگر نباید روی زنگوله هم مطالبهٔ توجه کند، ولی چون
هنوز بالای واترمارک است در پنل دیدهنشده میماند).
مودال را با markSpotlightShown علامت بزنید، نه markSeen
markSeen واترمارک را جلو میبرد، یعنی هر یادداشت قدیمیتر را هم خواندهشده علامت میزند — درحالیکه مودال فقط
یکی از آنها را نشان داده است. در فهرستی مثل [مودال، اعلان، …] که هر دو دیدهنشدهاند، این کار اعلانی را که کاربر هرگز
ندید بیصدا مصرف میکرد. markSpotlightShown فقط ثبت میکند که کدام مودال نمایش داده شده و به واترمارک دست نمیزند.
دسترسیپذیری
- هر نسخه یک
<article>با عنوان نسخه و تاریخ است؛ هر تغییر یک<li>با تیتر کوتاه. هیچ تغییر سرتیتر تودرتو نمیشود. - گروه نوع با واژه و آیکون معرفی میشود؛ معنا فقط از رنگ منتقل نمیشود. اولویت صریح ترتیب خواندن DOM را هم تعیین میکند.
- تصاویر
altدارند. تیترها و لینکهایشان حتی پیش از بارگذاری تصویر دیده میشوند. - تاریخ در
<time dateTime>میلادیِ ماشینخوان است و در فارسی شمسی نمایش داده میشود؛ ارقام DOM لاتین باقی میمانند. - پنل فوکوس را حبس میکند و
Escapeآن را میبندد. مودال روی عنوانش باز میشود؛ بدنهٔ پیمایشپذیر توقفTabنامدار دارد. triggerRefفوکوس را پس از بستن به کنترل بازکننده بازمیگرداند. حذف disclosure، توقفهای اضافی «جزئیات» را حذف میکند.
کامپوننتهای مرتبط
- ReleaseTimeline: همین تیترها در صفحهٔ تاریخچهٔ کامل
- useWhatsNew: کانال، بودجهٔ مودال و وضعیت دیدهشدن
- اعلام تغییرات محصول: انتخاب خبر مناسب و نگارش تیتر
- NotificationCenter: اعلان کاربر و نتیجهٔ عملیات