خط زمني
مسار من الأحداث المؤرّخة، لكل حدث علامة بنبرته. يُعرض على الخادم وينعكس وحده في التخطيطات من اليمين إلى اليسار.
server - 0 KB
خط زمني
server - 0 KBمسار من الأحداث المؤرّخة، لكل حدث علامة بنبرته. يُعرض على الخادم وينعكس وحده في التخطيطات من اليمين إلى اليسار.
- DoneProject created
- DoneFirst deploy
- CurrentIn reviewToday
- Not startedLaunchNot scheduled
الشيفرة
timeline.tsx
import { Timeline } from 'topclassui/timeline'
const EVENTS = [
{ id: 'created', title: 'Project created', time: <time dateTime="2026-10-02T09:12">2 October, 09:12</time>, status: 'done' },
{ id: 'deployed', title: 'First deploy', time: <time dateTime="2026-10-04T16:40">4 October, 16:40</time>, status: 'done' },
{ id: 'review', title: 'In review', time: 'Today', status: 'current' },
{ id: 'launch', title: 'Launch', time: 'Not scheduled', status: 'todo' },
] as const
/** The drawn rail: done filled in success, the current step a dot in a ring, and a hollow todo.
* A `<time>` gives a date a machine can read; each status is also said in hidden text. */
export default function Demo() {
return <Timeline items={EVENTS} getKey={(event) => event.id} />
}
أيقونة العنصر عنصرٌ، مثل <Svg icon={check} size="xs" />، لا اسم أيقونة: لا يُشحن أي محمّل أيقونات.
كل الحالات، بدون تمرير الفأرة
6 حالات- DoneDoneA filled dot in success
- CurrentCurrentA dot in a ring, read as the current step
- Not startedTo doA hollow dot
- A tone of its ownNo status, the danger tone
- DoneAn iconTakes the tone of its status
- Not startedAn icon to do
أو استورده من الحزمة
topclassui/timeline
import { Timeline } from 'topclassui/timeline'ثبّت مرة واحدة:npm i topclassui@beta zod
أمثلة
- العنصر هو
{ title, time?, status?, tone?, icon? }، وأي حقل خاص بك، مثلidلـgetKey. - مرّر
<time dateTime="...">فيtimeلتاريخ تقرؤه الآلة، ويظهر باهتًا تحت العنوان. - العنصر
doneنقطة ممتلئة، وcurrentنقطة داخل حلقة، وtodoنقطة مفرّغة. بلا نبرة يكونdoneبنبرة success والبقية بنبرة primary، وتبقى علامةtodoمفرّغة أيًّا كانت النبرة. - يعرض الخط الزمني
itemsكما تصله وبترتيبها: لا يرتّب ولا يجلب البيانات ولا يقسّمها إلى صفحات. - عند غياب العناصر يُعرض
emptyFallbackوحده، أو لا شيء إن لم يُمرَّر.
basic
- DoneProject created
- DoneFirst deploy
- CurrentIn reviewToday
- Not startedLaunchNot scheduled
basic.tsx
import { Timeline } from 'topclassui/timeline'
const EVENTS = [
{ id: 'created', title: 'Project created', time: <time dateTime="2026-10-02T09:12">2 October, 09:12</time>, status: 'done' },
{ id: 'deployed', title: 'First deploy', time: <time dateTime="2026-10-04T16:40">4 October, 16:40</time>, status: 'done' },
{ id: 'review', title: 'In review', time: 'Today', status: 'current' },
{ id: 'launch', title: 'Launch', time: 'Not scheduled', status: 'todo' },
] as const
/** The drawn rail: done filled in success, the current step a dot in a ring, and a hollow todo.
* A `<time>` gives a date a machine can read; each status is also said in hidden text. */
export default function Demo() {
return <Timeline items={EVENTS} getKey={(event) => event.id} />
}
tones
- PrimaryA new version is ready.
- NeutralNothing has changed since Monday.
- SuccessThe invoice was paid.
- WarningThe trial ends in three days.
- DangerThe last deploy failed.
- InfoMaintenance starts at 22:00.
tones.tsx
import { Timeline } from 'topclassui/timeline'
const EVENTS = [
{ id: 'primary', tone: 'primary', title: 'Primary', time: 'A new version is ready.' },
{ id: 'neutral', tone: 'neutral', title: 'Neutral', time: 'Nothing has changed since Monday.' },
{ id: 'success', tone: 'success', title: 'Success', time: 'The invoice was paid.' },
{ id: 'warning', tone: 'warning', title: 'Warning', time: 'The trial ends in three days.' },
{ id: 'danger', tone: 'danger', title: 'Danger', time: 'The last deploy failed.' },
{ id: 'info', tone: 'info', title: 'Info', time: 'Maintenance starts at 22:00.' },
] as const
/** Every tone as a marker, so axe measures all six in each mode. */
export default function Demo() {
return <Timeline items={EVENTS} getKey={(event) => event.id} />
}
icons
- Invoice created09:12
- Payment received11:30
- Receipt delayed11:31
- Not startedReceipt sent
icons.tsx
import { check } from 'topclassui/icons/check'
import { clock } from 'topclassui/icons/clock'
import { plus } from 'topclassui/icons/plus'
import { warning } from 'topclassui/icons/warning'
import { Svg } from 'topclassui/svg'
import { Timeline } from 'topclassui/timeline'
const EVENTS = [
{ id: 'created', icon: <Svg icon={plus} size="xs" />, title: 'Invoice created', time: '09:12' },
{ id: 'paid', icon: <Svg icon={check} size="xs" />, tone: 'success', title: 'Payment received', time: '11:30' },
{ id: 'late', icon: <Svg icon={warning} size="xs" />, tone: 'warning', title: 'Receipt delayed', time: '11:31' },
{ id: 'sent', icon: <Svg icon={clock} size="xs" />, status: 'todo', title: 'Receipt sent' },
] as const
/** An icon stands in for the dot and takes the tone; the last item has no time. */
export default function Demo() {
return <Timeline items={EVENTS} getKey={(event) => event.id} />
}
long-text
- The deploy failed while uploading the static assets to the edge networkFriday 9 October 2026 at 16:40, Central European Summer Time
- https://example.com/projects/topclassui/deployments/2026-10-09/logs/build-step-four-of-six.txtKept for thirty days
- Not startedRetry
long-text.tsx
import { Timeline } from 'topclassui/timeline'
const LOG_URL = 'https://example.com/projects/topclassui/deployments/2026-10-09/logs/build-step-four-of-six.txt'
const EVENTS = [
{
id: 'failed',
tone: 'danger',
title: 'The deploy failed while uploading the static assets to the edge network',
time: 'Friday 9 October 2026 at 16:40, Central European Summer Time',
},
{ id: 'log', title: LOG_URL, time: 'Kept for thirty days' },
{ id: 'retry', status: 'todo', title: 'Retry' },
] as const
/** A narrow box: a long title wraps, the unbroken URL breaks anywhere, and the connector grows with both. */
export default function Demo() {
return (
<div className="w-64">
<Timeline items={EVENTS} getKey={(event) => event.id} />
</div>
)
}
empty
No activity yet.
empty.tsx
import { Timeline, type TimelineItem } from 'topclassui/timeline'
const NONE: readonly (TimelineItem & { id: string })[] = []
/** No items: the fallback takes the place of the list, and without one nothing renders. */
export default function Demo() {
return (
<Timeline
items={NONE}
getKey={(event) => event.id}
emptyFallback={<p className="text-sm text-muted">No activity yet.</p>}
/>
)
}
بالعربية، من اليمين إلى اليسار
- مكتملأُنشئ المشروع٢ أكتوبر، ٠٩:١٢
- مكتملوصلت الدفعة٤ أكتوبر، ١٦:٤٠
- الحاليقيد المراجعةاليوم
- لم يبدأالإطلاقلم يُحدَّد موعده
rtl.tsx
import { check } from 'topclassui/icons/check'
import { ar } from 'topclassui/labels/ar'
import { Svg } from 'topclassui/svg'
import { Timeline } from 'topclassui/timeline'
const EVENTS = [
{ id: 'created', title: 'أُنشئ المشروع', time: '٢ أكتوبر، ٠٩:١٢', status: 'done' },
{ id: 'paid', icon: <Svg icon={check} size="xs" />, title: 'وصلت الدفعة', time: '٤ أكتوبر، ١٦:٤٠', status: 'done' },
{ id: 'review', title: 'قيد المراجعة', time: 'اليوم', status: 'current' },
{ id: 'launch', title: 'الإطلاق', time: 'لم يُحدَّد موعده', status: 'todo' },
] as const
/** Right to left: the rail sits at the inline start by itself, with no direction prop.
* The Arabic labels say each status in the language of the page. */
export default function Demo() {
return (
<div dir="rtl" lang="ar">
<Timeline items={EVENTS} getKey={(event) => event.id} labels={ar} />
</div>
)
}
الخصائص
لوحة المفاتيح وإمكانية الوصول
لا شيء يُشغَّل: ليس تفاعليًا بمفرده.
- قائمة مرتّبة، مع
role="list"مكتوبًا كي يحتفظ بها Safari مع VoiceOver. - العلامة شكل ولون، فتُقال كل حالة أيضًا بكلمات مخفية من
labels، والعنصر الحالي يحملaria-current="step". - لا شيء فيه يأخذ التركيز: هو محتوى الصفحة، لا عنصر تحكم.
من اليمين إلى اليسار
يقع المسار في بداية السطر، على اليمين في العربية، بلا خاصية اتجاه. مرّر labels لتُقال كلمات الحالات بالعربية.
الخادم والمتصفح
يُعرض على الخادم ولا يرسل أي JavaScript.
الملفات: index.tsx.
على الشارة: server - 0 KB.